Skip to content

Commit 84ca7dc

Browse files
committed
update some apis to use the continuity timestamp
1 parent b70d304 commit 84ca7dc

File tree

8 files changed

+124
-2
lines changed

8 files changed

+124
-2
lines changed

src/services/api/game-feedback-api.service.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,9 @@ export default class GameFeedbackAPIService extends APIService {
4040
const feedback = new GameFeedback(category, req.ctx.state.playerAlias)
4141
feedback.comment = comment
4242
feedback.anonymised = category.anonymised
43+
if (req.ctx.state.continuityDate) {
44+
feedback.createdAt = req.ctx.state.continuityDate
45+
}
4346

4447
await em.persistAndFlush(feedback)
4548

src/services/api/game-stat-api.service.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,10 @@ export default class GameStatAPIService extends APIService {
5252

5353
if (!playerStat) {
5454
playerStat = new PlayerGameStat(req.ctx.state.player, req.ctx.state.stat)
55+
if (req.ctx.state.continuityDate) {
56+
playerStat.createdAt = req.ctx.state.continuityDate
57+
}
58+
5559
em.persist(playerStat)
5660
}
5761

src/services/api/leaderboard-api.service.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,9 @@ export default class LeaderboardAPIService extends APIService {
3737
const entry = new LeaderboardEntry(req.ctx.state.leaderboard)
3838
entry.playerAlias = req.ctx.state.playerAlias
3939
entry.score = req.body.score
40+
if (req.ctx.state.continuityDate) {
41+
entry.createdAt = req.ctx.state.continuityDate
42+
}
4043

4144
await em.persistAndFlush(entry)
4245

@@ -67,7 +70,7 @@ export default class LeaderboardAPIService extends APIService {
6770

6871
if ((leaderboard.sortMode === LeaderboardSortMode.ASC && score < entry.score) || (leaderboard.sortMode === LeaderboardSortMode.DESC && score > entry.score)) {
6972
entry.score = score
70-
entry.createdAt = new Date()
73+
entry.createdAt = req.ctx.state.continuityDate ?? new Date()
7174
await em.flush()
7275

7376
updated = true

src/services/player.service.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,10 @@ export default class PlayerService extends Service {
8484
const game = await em.getRepository(Game).findOne(req.ctx.state.game)
8585

8686
const player = new Player(game)
87+
if (req.ctx.state.continuityDate) {
88+
player.createdAt = req.ctx.state.continuityDate
89+
}
90+
8791
if (aliases) {
8892
for await (const alias of aliases) {
8993
if (await em.getRepository(PlayerAlias).count({ service: alias.service, identifier: alias.identifier }) > 0) {
@@ -98,6 +102,10 @@ export default class PlayerService extends Service {
98102
const alias = new PlayerAlias()
99103
alias.service = item.service
100104
alias.identifier = item.identifier
105+
if (req.ctx.state.continuityDate) {
106+
alias.createdAt = req.ctx.state.continuityDate
107+
}
108+
101109
return alias
102110
}))
103111
}

tests/services/_api/game-feedback-api/post.test.ts

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import { APIKeyScope } from '../../../../src/entities/api-key'
44
import createAPIKeyAndToken from '../../../utils/createAPIKeyAndToken'
55
import GameFeedbackCategoryFactory from '../../../fixtures/GameFeedbackCategoryFactory'
66
import PlayerFactory from '../../../fixtures/PlayerFactory'
7+
import { subHours } from 'date-fns'
78

89
describe('Game feedback API service - post', () => {
910
it('should create feedback if the scope is valid', async () => {
@@ -76,4 +77,25 @@ describe('Game feedback API service - post', () => {
7677

7778
expect(res.body).toStrictEqual({ message: 'Feedback category not found' })
7879
})
80+
81+
it('should set the createdAt for the feedback to the continuity date', async () => {
82+
const [apiKey, token] = await createAPIKeyAndToken([APIKeyScope.WRITE_GAME_FEEDBACK])
83+
84+
const feedbackCategory = await new GameFeedbackCategoryFactory(apiKey.game).one()
85+
const player = await new PlayerFactory([apiKey.game]).one()
86+
87+
await (<EntityManager>global.em).persistAndFlush([feedbackCategory, player])
88+
89+
const continuityDate = subHours(new Date(), 1)
90+
91+
const res = await request(global.app)
92+
.post(`/v1/game-feedback/categories/${feedbackCategory.internalName}`)
93+
.send({ comment: 'This is my comment' })
94+
.auth(token, { type: 'bearer' })
95+
.set('x-talo-alias', String(player.aliases[0].id))
96+
.set('x-talo-continuity-timestamp', String(continuityDate.getTime()))
97+
.expect(200)
98+
99+
expect(res.body.feedback.createdAt).toBe(continuityDate.toISOString())
100+
})
79101
})

tests/services/_api/game-stat-api/put.test.ts

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import GameStat from '../../../../src/entities/game-stat'
77
import PlayerGameStatFactory from '../../../fixtures/PlayerGameStatFactory'
88
import createAPIKeyAndToken from '../../../utils/createAPIKeyAndToken'
99
import Game from '../../../../src/entities/game'
10+
import { subHours } from 'date-fns'
1011

1112
describe('Game stats API service - put', () => {
1213
const createStat = async (game: Game, props: Partial<GameStat>) => {
@@ -228,4 +229,23 @@ describe('Game stats API service - put', () => {
228229

229230
expect(res.body).toStrictEqual({ message: 'Stat not found' })
230231
})
232+
233+
it('should set the createdAt of the player stat to the continuity date', async () => {
234+
const [apiKey, token] = await createAPIKeyAndToken([APIKeyScope.WRITE_GAME_STATS])
235+
const stat = await createStat(apiKey.game, { maxValue: 999, maxChange: 99 })
236+
const player = await new PlayerFactory([apiKey.game]).one()
237+
await (<EntityManager>global.em).persistAndFlush(player)
238+
239+
const continuityDate = subHours(new Date(), 1)
240+
241+
const res = await request(global.app)
242+
.put(`/v1/game-stats/${stat.internalName}`)
243+
.send({ change: 10 })
244+
.auth(token, { type: 'bearer' })
245+
.set('x-talo-player', player.id)
246+
.set('x-talo-continuity-timestamp', String(continuityDate.getTime()))
247+
.expect(200)
248+
249+
expect(res.body.playerStat.createdAt).toBe(continuityDate.toISOString())
250+
})
231251
})

tests/services/_api/leaderboard-api/post.test.ts

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -220,4 +220,50 @@ describe('Leaderboard API service - post', () => {
220220

221221
expect(res.body.entry.position).toBe(0)
222222
})
223+
224+
it('should set the createdAt for the entry to the continuity date', async () => {
225+
const [apiKey, token] = await createAPIKeyAndToken([APIKeyScope.WRITE_LEADERBOARDS])
226+
const player = await new PlayerFactory([apiKey.game]).one()
227+
const leaderboard = await new LeaderboardFactory([apiKey.game]).one()
228+
await (<EntityManager>global.em).persistAndFlush([player, leaderboard])
229+
230+
const continuityDate = subHours(new Date(), 1)
231+
232+
const res = await request(global.app)
233+
.post(`/v1/leaderboards/${leaderboard.internalName}/entries`)
234+
.send({ score: 300 })
235+
.auth(token, { type: 'bearer' })
236+
.set('x-talo-alias', String(player.aliases[0].id))
237+
.set('x-talo-continuity-timestamp', String(continuityDate.getTime()))
238+
.expect(200)
239+
240+
expect(new Date(res.body.entry.createdAt).getHours()).toBe(continuityDate.getHours())
241+
})
242+
243+
it('should update an existing entry\'s created at to the continuity date for unique leaderboards', async () => {
244+
const [apiKey, token] = await createAPIKeyAndToken([APIKeyScope.WRITE_LEADERBOARDS])
245+
const player = await new PlayerFactory([apiKey.game]).one()
246+
const leaderboard = await new LeaderboardFactory([apiKey.game]).state(() => ({ unique: true, sortMode: LeaderboardSortMode.DESC })).one()
247+
248+
const originalDate = subHours(new Date(), 2)
249+
const continuityDate = subHours(new Date(), 1)
250+
251+
const entry = await new LeaderboardEntryFactory(leaderboard, [player]).state(() => ({
252+
score: 100,
253+
createdAt: originalDate,
254+
playerAlias: player.aliases[0]
255+
})).one()
256+
257+
await (<EntityManager>global.em).persistAndFlush([player, leaderboard, entry])
258+
259+
const res = await request(global.app)
260+
.post(`/v1/leaderboards/${leaderboard.internalName}/entries`)
261+
.send({ score: 300 })
262+
.auth(token, { type: 'bearer' })
263+
.set('x-talo-alias', String(player.aliases[0].id))
264+
.set('x-talo-continuity-timestamp', String(continuityDate.getTime()))
265+
.expect(200)
266+
267+
expect(new Date(res.body.entry.createdAt).getHours()).toBe(continuityDate.getHours())
268+
})
223269
})

tests/services/_api/player-api/identify.test.ts

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import { Collection, EntityManager } from '@mikro-orm/mysql'
22
import request from 'supertest'
33
import { APIKeyScope } from '../../../../src/entities/api-key'
44
import PlayerFactory from '../../../fixtures/PlayerFactory'
5-
import { isToday } from 'date-fns'
5+
import { isToday, subHours } from 'date-fns'
66
import PlayerGroupFactory from '../../../fixtures/PlayerGroupFactory'
77
import PlayerGroupRule, { PlayerGroupRuleName, PlayerGroupRuleCastType } from '../../../../src/entities/player-group-rule'
88
import PlayerProp from '../../../../src/entities/player-prop'
@@ -124,4 +124,20 @@ describe('Player API service - identify', () => {
124124

125125
expect(res.body).toStrictEqual({ message: 'Player not found: Talo aliases must be created using the /v1/players/auth API' })
126126
})
127+
128+
it('should set the createdAt for the player and aliases to the continuity date', async () => {
129+
const [, token] = await createAPIKeyAndToken([APIKeyScope.READ_PLAYERS, APIKeyScope.WRITE_PLAYERS])
130+
131+
const continuityDate = subHours(new Date(), 1)
132+
133+
const res = await request(global.app)
134+
.get('/v1/players/identify')
135+
.query({ service: 'steam', identifier: 'bizboz' })
136+
.auth(token, { type: 'bearer' })
137+
.set('x-talo-continuity-timestamp', String(continuityDate.getTime()))
138+
.expect(200)
139+
140+
expect(res.body.alias.createdAt).toBe(continuityDate.toISOString())
141+
expect(res.body.alias.player.createdAt).toBe(continuityDate.toISOString())
142+
})
127143
})

0 commit comments

Comments
 (0)