import { BoxrecRole } from "boxrec-requests/dist/boxrec-requests.constants" ; import { getHeaderColumnText , trimRemoveLineBreaks } from "../../helpers" ; import { BoxrecParseBoutsParseBouts } from "../event/boxrec.parse.bouts.parseBouts" ; import { BoxrecProfileRole , BoxrecProfileTable } from "./boxrec.profile.constants" ; const profileTableEl = ".profileTable" ; export abstract class BoxrecPageProfile extends BoxrecParseBoutsParseBouts { returns { string | null } get birthName ( ) : string | null { const birthName = this . parseProfileTableData ( BoxrecProfileTable . birthName ) ; if ( birthName ) { return birthName ; } return null ; } returns { string | null } get birthPlace ( ) : string | null { const birthPlace = this . parseProfileTableData ( BoxrecProfileTable . birthPlace ) ; if ( birthPlace ) { return this . $ ( `<div>${ birthPlace }</div>` ) . text ( ) || "" ; } return null ; } example returns { string | null } get born ( ) : string | null { const born = this . parseProfileTableData ( BoxrecProfileTable . born ) ; if ( born ) { const regex = /(\d{4}\-\d{2}\-\d{2})/ ; const bornMatch = born . match ( regex ) ; if ( bornMatch ) { return bornMatch [ 1 ] ; } } return null ; } /**
     * Returns the date of the death
     */ get death ( ) : string | null { const death = this . parseProfileTableData ( BoxrecProfileTable . death ) ; if ( death ) { const splitDeath = death . split ( "/" ) ; if ( splitDeath . length > 0 ) { return splitDeath [ 0 ] . trim ( ) ; } } return null ; } returns { number | null } get globalId ( ) : number | null { const tr = this . $ ( profileTableEl ) . find ( "h2" ) ; const id = tr . text ( ) . match ( /\d+/ ) ; if ( id ) { const globalId = parseInt ( id [ 0 ] as string , 10 ) ; if ( ! isNaN ( globalId ) ) { return globalId ; } } return null ; } returns { Object } get metadata ( ) : object | null { const metadata = this . $ ( "script[type='application/ld+json']" ) . html ( ) ; if ( metadata ) { JSON . parse ( metadata ) ; } return null ; } returns { string } get name ( ) : string { return this . $ ( profileTableEl ) . find ( "h1" ) . text ( ) ; } returns { string [ ] [ ] } get otherInfo ( ) : string [ ] [ ] { return this . parseOtherInfo ( ) ; } get picture ( ) : string { return this . $ ( ".profileTablePhoto img" ) . attr ( "src" ) ; } returns { string | null } get residence ( ) : string | null { const residence = this . parseProfileTableData ( BoxrecProfileTable . residence ) ; if ( residence ) { return this . $ ( `<div>${ residence }</div>` ) . text ( ) || "" ; } return null ; } /**
     * Returns the Boxrec Role value because the values in the HTML might change and not the text
     * ex. proboxer -> Pro Boxing.  therefore to keep tests passing, return the `proboxer` role
     */ get role ( ) : BoxrecProfileRole [ ] { const rolesWithLinks = [ ] ; const parentEl = this . $ ( profileTableEl ) . find ( "h2" ) . parent ( ) ; const profileOneRole = parentEl . find ( ".profileP" ) ; const currentRole = parentEl . find ( ".profileIcon" ) ; if ( currentRole . length || profileOneRole . length ) { const canonicalLinkMatches = this . $ ( "link[rel='canonical']" ) . attr ( "href" ) . match ( /\/en\/(\w+)\/\d+/ ) ; if ( canonicalLinkMatches && canonicalLinkMatches . length ) { rolesWithLinks . push ( { id : this . globalId , name : canonicalLinkMatches [ 1 ] as BoxrecRole , } ) ; } else { throw new Error ( `Could not get BoxRec role?: ${ this . globalId }` ) ; } } parentEl . find ( "a" ) . each ( ( index , elem ) => { const hrefMatches = elem . attribs . href . match ( /(\d+)$/ ) ; const type = trimRemoveLineBreaks ( this . $ ( elem ) . text ( ) ) ; if ( hrefMatches && type ) { rolesWithLinks . push ( { id : parseInt ( hrefMatches [ 1 ] , 10 ) , name : type as BoxrecRole , } ) ; } } ) . get ( ) ; rolesWithLinks . sort ( ( a , b ) => { if ( a . name > b . name ) { return 1 ; } if ( a . name < b . name ) { return - 1 ; } return 0 ; } ) ; return rolesWithLinks ; } /**
     * Returns an array of social media links
     * Due to social media platforms changing, this returns an array and not an object
     */ get socialMedia ( ) : string [ ] { const tableColumns = this . $ ( `.profileTable table` ) . find ( `td:contains(youtube.com), td a[href*='youtube.com'],
                td:contains(facebook.com), td a[href*='facebook.com'],
                td:contains(twitter.com), td a[href*='twitter.com']` ) ; if ( tableColumns . length ) { return tableColumns . map ( ( index , elem ) => { const attr = this . $ ( elem ) . attr ( "href" ) ; return attr ? trimRemoveLineBreaks ( attr ) : trimRemoveLineBreaks ( this . $ ( elem ) . text ( ) ) ; } ) . get ( ) ; } return [ ] ; } example returns { string | null } get status ( ) : string | null { const status = this . parseProfileTableData ( BoxrecProfileTable . status ) ; if ( status ) { return status ; } return null ; } private get profileTableBody ( ) : Cheerio { return this . $ ( profileTableEl ) . find ( `table.rowTable tbody` ) ; } param boutsListArr param { { new ( boxrecBodyBout : string , additionalData : ( string | null ) ) : U } } type hidden returns { U [ ] } protected getBouts < U > ( boutsListArr , type ) { const headerColumns = getHeaderColumnText ( this . $ ( ".dataTable" ) ) ; return boutsListArr . map ( ( val ) => new type ( headerColumns , val [ 0 ] , val [ 1 ] ) ) ; } hidden protected parseProfileTableData ( keyToRetrieve ? ) { const tableRow = this . profileTableBody . find ( `tr:contains("${ keyToRetrieve }")` ) ; const val = tableRow . find ( "td:nth-child(2)" ) . html ( ) ; if ( keyToRetrieve && val ) { return val . trim ( ) ; } } private parseOtherInfo ( ) { const otherInfo = [ ] ; const knownTableColumnKeys = Object . values ( BoxrecProfileTable ) ; this . profileTableBody . find ( "tr" ) . each ( ( i , elem ) => { const val = this . $ ( elem ) . find ( "td:nth-child(2)" ) . html ( ) ; const key = trimRemoveLineBreaks ( this . $ ( elem ) . find ( "td:nth-child(1)" ) . text ( ) ) ; if ( key && val && key . substr ( 0 , 2 ) !== "ID" && ! knownTableColumnKeys . includes ( key ) ) { otherInfo . push ( [ key , val ] ) ; } } ) ; return otherInfo ; } }