Skip to content

Commit

Permalink
ensure update schedule function can update scores
Browse files Browse the repository at this point in the history
  • Loading branch information
tobyrushton committed Jan 23, 2024
1 parent 5b7f527 commit 0a42c67
Show file tree
Hide file tree
Showing 4 changed files with 155 additions and 40 deletions.
97 changes: 80 additions & 17 deletions __tests__/server/functions/update-schedule.test.ts
Original file line number Diff line number Diff line change
@@ -1,36 +1,40 @@
import { updateSchedule } from '../../../src/server/functions/update-schedule'
import { prismaMock } from '../../singleton'
import { scrapeSchedule } from '../../../src/server/scrapes/scrape-schedule'
import { getDateOfGame } from '@/lib/getDateOfGame'

jest.mock('../../../src/server/scrapes/scrape-schedule', () => ({
__esModule: true,
scrapeSchedule: jest.fn(),
}))

const mockTeamsInDb = [
{ id: '1', name: 'Team A', logo_url: '' },
{ id: '2', name: 'Team B', logo_url: '' },
]

describe('updateSchedule', () => {
beforeEach(() => {
jest.clearAllMocks()
jest.useFakeTimers().setSystemTime(new Date('2024-01-01'))
})

it('should update the schedule in the database if there are new games', async () => {
const mockSchedule = [
{ date: '2022-01-01', opponent_name: 'Team A', home: true },
{ date: '2022-01-02', opponent_name: 'Team B', home: false },
{ date: '01/01', opponent_name: 'Team A', home: true },
{ date: '01/02', opponent_name: 'Team B', home: false },
{ date: '01/03', opponent_name: 'Team B', home: true },
]
const mockScheduleInDb = [
{
id: '1',
date: '2022-01-01',
date: new Date('2024-01-01').toISOString(),
opponent_id: '1',
home: true,
opponent_score: 101,
home_score: 123,
},
]
const mockTeamsInDb = [
{ id: '1', name: 'Team A', logo_url: '' },
{ id: '2', name: 'Team B', logo_url: '' },
]

// Mock the return values of the mocked functions
;(scrapeSchedule as jest.Mock).mockResolvedValue(mockSchedule)
Expand All @@ -46,30 +50,39 @@ describe('updateSchedule', () => {
expect(scrapeSchedule).toHaveBeenCalled()
expect(prismaMock.game.findMany).toHaveBeenCalled()
expect(prismaMock.team.findMany).toHaveBeenCalled()
expect(prismaMock.game.createMany).toHaveBeenCalledWith({
data: [
expect(prismaMock.game.create).toHaveBeenCalledWith({
data:
{
opponent_id: '2',
date: '2022-01-02',
date: new Date('2024-01-02').toISOString(),
home: false,
opponent_score: -1,
home_score: -1,
},
],
})
expect(prismaMock.game.create).toHaveBeenCalledWith({
data:
{
opponent_id: '2',
date: new Date('2024-01-03').toISOString(),
home: true,
opponent_score: -1,
home_score: -1,
},
})
})

it('should not update the schedule in the database if there are no new games', async () => {
const mockSchedule = [
{
date: '2022-01-01',
date: '01/01',
opponent_name: 'Team A',
home: true,
opponent_score: 101,
home_score: 123,
},
{
date: '2022-01-02',
date: '01/01',
opponent_name: 'Team B',
home: false,
opponent_score: 120,
Expand All @@ -84,13 +97,55 @@ describe('updateSchedule', () => {
id: index.toString(),
opponent_id: index.toString(),
...rest,
date: getDateOfGame(game.date).toISOString(),
}
}),
]

const mockTeamsInDb = [
{ id: '1', name: 'Team A', logo_url: '' },
{ id: '2', name: 'Team B', logo_url: '' },
// Mock the return values of the mocked functions
;(scrapeSchedule as jest.Mock).mockResolvedValue(mockSchedule)
prismaMock.game.findMany.mockResolvedValue(mockScheduleInDb)
prismaMock.team.findMany.mockResolvedValue(mockTeamsInDb)

await updateSchedule()

// Verify that the functions were called with the expected arguments
expect(scrapeSchedule).toHaveBeenCalled()
expect(prismaMock.game.findMany).toHaveBeenCalled()
expect(prismaMock.team.findMany).toHaveBeenCalled()
expect(prismaMock.game.create).not.toHaveBeenCalled()
})

it('should update game if changed', async () => {
const mockSchedule = [
{
date: '01/01',
opponent_name: 'Team A',
home: true,
opponent_score: 101,
home_score: 123,
},
{
date: '01/02',
opponent_name: 'Team B',
home: false,
opponent_score: 120,
home_score: 134,
},
]

const mockScheduleInDb = [
...mockSchedule.map((game, index) => {
return {
id: index.toString(),
opponent_id: index.toString(),
date: getDateOfGame(game.date).toISOString(),
home_score: -1,
opponent_score: -1,
home: game.home,
opponent_name: game.opponent_name,
}
}),
]

// Mock the return values of the mocked functions
Expand All @@ -104,6 +159,14 @@ describe('updateSchedule', () => {
expect(scrapeSchedule).toHaveBeenCalled()
expect(prismaMock.game.findMany).toHaveBeenCalled()
expect(prismaMock.team.findMany).toHaveBeenCalled()
expect(prismaMock.game.createMany).not.toHaveBeenCalled()
mockSchedule.forEach((game, index) => {
expect(prismaMock.game.update).toHaveBeenCalledWith({
where: { id: index.toString() },
data: {
...game,
date: getDateOfGame(game.date).toISOString(),
},
})
})
})
})
16 changes: 16 additions & 0 deletions src/lib/scheduleGameIsEqual.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
interface IGameNoIds extends Omit<team.IGame, 'id' | 'opponent_id'> {}

/**
* Checks if two schedule games are equal.
* @param game1 - The first game to compare.
* @param game2 - The second game to compare.
* @returns True if the games are equal, false otherwise.
*/
export const scheduleGameIsEqual = (
game1: IGameNoIds,
game2: IGameNoIds
): boolean =>
game1.date === game2.date &&
game1.home === game2.home &&
game1.home_score === game2.home_score &&
game1.opponent_score === game2.opponent_score
80 changes: 59 additions & 21 deletions src/server/functions/update-schedule.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { scheduleGameIsEqual } from '@/lib/scheduleGameIsEqual'
import { getDateOfGame } from '@/lib/getDateOfGame'
import prisma from '../db/client'
import { scrapeSchedule } from '../scrapes/scrape-schedule'

Expand All @@ -12,27 +14,63 @@ export const updateSchedule = async (): Promise<void> => {
prisma.team.findMany(),
])

// if the schedule in the db is less than the schedule scraped
// then we need to add the new schedule
if (scheduleInDb.length < schedule.length) {
const newSchedule = schedule.filter(
game => !scheduleInDb.some(gameInDb => gameInDb.date === game.date)
const newGamesNotInDb = schedule.filter(
game =>
!scheduleInDb.some(
gameInDb =>
getDateOfGame(game.date).toISOString() === gameInDb.date
)
)

const gamesToUpdate = schedule.filter(game =>
scheduleInDb.some(
gameInDb =>
getDateOfGame(game.date).toISOString() === gameInDb.date &&
!scheduleGameIsEqual(
{ opponent_score: -1, home_score: -1, ...game },
gameInDb
)
)
)

if (gamesToUpdate.length > 0)
await Promise.all(
gamesToUpdate.map(async game => {
const gameId = scheduleInDb.find(
gameInDb =>
getDateOfGame(game.date).toISOString() === gameInDb.date
)?.id

if (!gameId) return

await prisma.game.update({
where: { id: gameId },
data: {
...game,
date: getDateOfGame(game.date).toISOString(),
},
})
})
)

const newScheduleWithTeamIds = newSchedule.map(game => {
const opponent_id = teamsInDb.find(
team => team.name === game.opponent_name
)?.id as string

// scores are undefined if the game is in the future so score is set to -1
return {
opponent_id,
date: game.date,
home: game.home,
opponent_score: game.opponent_score ?? -1,
home_score: game.home_score ?? -1,
}
})
await prisma.game.createMany({ data: newScheduleWithTeamIds })
}
if (newGamesNotInDb.length > 0)
await Promise.all(
newGamesNotInDb.map(async game => {
const opponent_id = teamsInDb.find(
team => team.name === game.opponent_name
)?.id

if (!opponent_id) return

await prisma.game.create({
data: {
opponent_id,
date: getDateOfGame(game.date).toISOString(),
home: game.home,
opponent_score: game.opponent_score ?? -1,
home_score: game.home_score ?? -1,
},
})
})
)
}
2 changes: 0 additions & 2 deletions src/typings/team.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,6 @@ namespace team {
date: string
home: boolean
opponent_id: number
opponent_name: string
opponent_logo_url: string
opponent_score: number
home_score: number
}
Expand Down

0 comments on commit 0a42c67

Please sign in to comment.