From a1ebc66c5b40e99c5766e9a9b03eef235ad5a0ea Mon Sep 17 00:00:00 2001 From: Ceej Date: Sat, 3 Oct 2020 09:58:35 -0700 Subject: [PATCH] Add getHistoricalTeamsAtWeek to Client for pre-2018 seasons --- src/client/client.js | 39 +++++++++++ src/client/client.test.js | 140 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 179 insertions(+) diff --git a/src/client/client.js b/src/client/client.js index 7106eec..33f8f5d 100644 --- a/src/client/client.js +++ b/src/client/client.js @@ -224,6 +224,45 @@ class Client { }); } + /** + * Returns an array of Team object representing each fantasy football team in a pre-2018 FF + * league. + * + * NOTE: This route will error for the current season, as ESPN only exposes this data for previous + * seasons. + * + * @param {object} options Required options object. + * @param {number} options.seasonId The season to grab data from. This value must be before 2018 + * @param {number} options.scoringPeriodId The scoring period in which to grab teams from. + * @returns {Team[]} The list of teams. + */ + getHistoricalTeamsAtWeek({ seasonId, scoringPeriodId }) { + const route = this.constructor._buildRoute({ + base: `${this.leagueId}`, + params: `?scoringPeriodId=${scoringPeriodId}&seasonId=${seasonId}` + + '&view=mMatchupScore&view=mScoreboard&view=mSettings&view=mTopPerformers&view=mTeam' + }); + + const axiosConfig = this._buildAxiosConfig({ + baseURL: 'https://fantasy.espn.com/apis/v3/games/ffl/leagueHistory/' + }); + + return axios.get(route, axiosConfig).then((response) => { + // Join member (owner) information with team data before dumping into builder + const teams = _.get(response.data, 'teams'); + const members = _.get(response.data, 'members'); + + const mergedData = teams.map((team) => { + const owner = members.find((member) => member.id === team.primaryOwner); + return { owner, ...team }; // Don't spread owner to prevent id and other attributes clashing + }); + + return _.map(mergedData, (team) => ( + Team.buildFromServer(team, { leagueId: this.leagueId, seasonId }) + )); + }); + } + /** * Returns all NFL games that occur in the passed timeframe. NOTE: Date format must be "YYYYMMDD". * diff --git a/src/client/client.test.js b/src/client/client.test.js index d66def7..18b84c3 100644 --- a/src/client/client.test.js +++ b/src/client/client.test.js @@ -724,6 +724,146 @@ describe('Client', () => { }); }); + describe('getHistoricalTeamsAtWeek', () => { + let client; + let leagueId; + let scoringPeriodId; + let seasonId; + + beforeEach(() => { + leagueId = 213213; + scoringPeriodId = 3; + seasonId = 2017; + + client = new Client({ leagueId }); + + jest.spyOn(axios, 'get').mockImplementation(); + }); + + test('calls axios.get with the correct params', () => { + const routeBase = `${leagueId}`; + const routeParams = `?scoringPeriodId=${scoringPeriodId}&seasonId=${seasonId}&view=mMatchupScore&view=mScoreboard&view=mSettings&view=mTopPerformers&view=mTeam`; + const route = `${routeBase}${routeParams}`; + const config = {}; + jest.spyOn(client, '_buildAxiosConfig').mockReturnValue(config); + axios.get.mockReturnValue(q()); + + client.getHistoricalTeamsAtWeek({ seasonId, scoringPeriodId }); + expect(axios.get).toBeCalledWith(route, config); + }); + + describe('before the promise resolves', () => { + test('does not invoke callback', () => { + jest.spyOn(Team, 'buildFromServer').mockImplementation(); + axios.get.mockReturnValue(q()); + + client.getHistoricalTeamsAtWeek({ seasonId, scoringPeriodId }); + expect(Team.buildFromServer).not.toBeCalled(); + }); + }); + + describe('after the promise resolves', () => { + test('maps response data into Teams', async () => { + const response = { + data: { + members: [{ + firstName: 'Owner', + id: '{BAD5167F-96F5-40FF-AFF0-4D2CC92F4057}', + lastName: 'Dude' + }, { + firstName: 'Owner', + id: '{BAD5167F-96F5-40FF-AFF0-4D2CC92F4058}', + lastName: 'Dude' + }, { + firstName: 'Owner', + id: '{BAD5167F-96F5-40FF-AFF0-4D2CC92F4059}', + lastName: 'Dude' + }], + teams: [{ + abbrev: 'SWAG', + location: 'First ', + nickname: 'Last', + primaryOwner: '{BAD5167F-96F5-40FF-AFF0-4D2CC92F4058}', + record: { + overall: { + wins: 3, + losses: 11 + } + }, + roster: { + entries: [{ + playerPoolEntry: { + firstName: 'Joe', + lastName: 'Montana' + } + }] + } + }, { + abbrev: 'JS', + location: 'First ', + nickname: 'Last', + primaryOwner: '{BAD5167F-96F5-40FF-AFF0-4D2CC92F4059}', + record: { + overall: { + wins: 5, + losses: 11 + } + }, + roster: { + entries: [{ + playerPoolEntry: { + firstName: 'Joe', + lastName: 'Smith' + } + }] + } + }, { + abbrev: 'SWAG', + location: 'First ', + nickname: 'Last', + primaryOwner: '{BAD5167F-96F5-40FF-AFF0-4D2CC92F4057}', + record: { + overall: { + wins: 11, + losses: 8 + } + }, + roster: { + entries: [{ + playerPoolEntry: { + firstName: 'Joe', + lastName: 'Brown' + } + }] + } + }] + } + }; + + const promise = q(response); + axios.get.mockReturnValue(promise); + + const teams = await client.getHistoricalTeamsAtWeek({ seasonId, scoringPeriodId }); + + expect.hasAssertions(); + expect(teams.length).toBe(3); + _.forEach(teams, (team, index) => { + expect(team).toBeInstanceOf(Team); + expect(team.abbreviation).toBe(response.data.teams[index].abbrev); + + expect(team.wins).toBe(response.data.teams[index].record.overall.wins); + expect(team.losses).toBe(response.data.teams[index].record.overall.losses); + + expect(team.roster).toEqual(expect.any(Array)); + expect(team.roster[0]).toBeInstanceOf(Player); + expect(team.roster[0].firstName).toBe( + response.data.teams[index].roster.entries[0].playerPoolEntry.firstName + ); + }); + }); + }); + }); + describe('getNFLGamesForPeriod', () => { let client; let endDate;