[platformnotifications] fix endpoint

This commit is contained in:
Devin Zuczek
2026-08-24 18:51:09 -04:00
parent 55ac92670f
commit b8d5103d57
2 changed files with 34 additions and 19 deletions
@@ -21,9 +21,9 @@ function unauthorized(c: Context<App>) {
}
/**
* The notification categories `GET /config/categories` serves — a STUB standing in for the
* real list until something here actually defines categories and stores preferences against
* them.
* The notification categories `GET /config/categories` serves as its `Results` — a STUB
* standing in for the real list until something here actually defines categories and stores
* preferences against them.
*
* `CategoryId` is the client's own id for the category, `Importance` its ranking (0 being
* the lowest observed), and `IsMuteable` whether the player may switch it off at all. The
@@ -74,9 +74,15 @@ const app = new Hono<App>()
})
// The notification categories a player can be shown toggles for — the "what may we notify
// you about" list. A bare array of PascalCase categories, no envelope. No auth: the list
// is server-side config, the same for every player, and a caller's own preferences are
// the per-account routes above.
// you about" list. A `{ Results, TotalResults }` PAGE of PascalCase categories, the same
// envelope the other paged reads on this server use — not the bare array this once
// served. No auth: the list is server-side config, the same for every player, and a
// caller's own preferences are the per-account routes above.
//
// `TotalResults` counts the whole list rather than the page, and there is only ever one
// page here — nothing pages a list this short — so it is the array's own length. Counting
// it rather than writing the number keeps the two from disagreeing when a category is
// added.
//
// STUB. Nothing here defines categories or stores a preference against one, so this is
// one hand-written entry standing in for the real list — the toggle it draws does
@@ -84,7 +90,10 @@ const app = new Hono<App>()
// the field the client renders, so the stub is visible in-game instead of looking like
// a real (and broken) setting. `Name` is left clean in case the client keys off it.
.get('/config/categories', async (c) => {
return c.json(NOTIFICATION_CATEGORIES)
return c.json({
Results: NOTIFICATION_CATEGORIES,
TotalResults: NOTIFICATION_CATEGORIES.length,
})
})
// The caller's CRM configuration — the campaign/messaging settings the client fetches on
@@ -75,27 +75,33 @@ it('401s the gameplay-invites check without a bearer token', async () => {
})
it('serves the stub notification categories', async () => {
// A bare array of PascalCase categories, and no auth — the list is server-side config
// rather than anything per-player.
// A `{ Results, TotalResults }` page of PascalCase categories — not a bare array — and no
// auth: the list is server-side config rather than anything per-player.
const res = await SELF.fetch(`${ORIGIN}/config/categories`)
expect(res.status).toBe(200)
const categories = (await res.json()) as Array<{
const page = (await res.json()) as {
Results: Array<{
CategoryId: number
Importance: number
Name: string
Description: string
IsMuteable: boolean
}>
expect(categories).toHaveLength(1)
expect(categories[0]).toMatchObject({
TotalResults: number
}
expect(page.Results).toHaveLength(1)
expect(page.Results[0]).toMatchObject({
CategoryId: 2,
Importance: 0,
Name: 'Friends',
IsMuteable: true,
})
// The total counts the whole list, and this list is served in one page — so it has to
// agree with what came back rather than being a number of its own.
expect(page.TotalResults).toBe(page.Results.length)
// The stub marker is in the DISPLAYED text, so a category that does nothing says so
// in-game rather than looking like a real setting. Keep it there while this is a stub.
expect(categories[0].Description).toContain('STUB')
expect(page.Results[0].Description).toContain('STUB')
})
it('serves the callers notification preferences', async () => {