mirror of
https://github.com/djdevin/recflare.git
synced 2026-10-27 07:58:55 -07:00
[2026] consumables
This commit is contained in:
@@ -42,6 +42,7 @@ import { censorSwears } from '../../api/src/sanitize'
|
||||
import { BalanceAddType } from '../../notify/src/notification-payloads'
|
||||
import { NotificationType } from '../../notify/src/notification-types'
|
||||
import adCarouselItems from '../static/ad-carousel-items.json'
|
||||
import consumableDefinitions from '../static/consumables.json'
|
||||
import defaultAvatarItems from '../static/default-avatar-items.json'
|
||||
import defaultAvatar from '../static/default-avatar.json'
|
||||
import defaultBaseAvatarItems from '../static/default-base-avatar-items.json'
|
||||
@@ -4976,19 +4977,19 @@ const app = new Hono<App>({ strict: false })
|
||||
)
|
||||
|
||||
// The consumable DEFINITIONS the client knows how to use (`?supportedVersion=2`), as
|
||||
// opposed to the ones a player owns. A stub: none are served yet, so the list is empty.
|
||||
// A real row is `{ ConsumableItemDesc, InitialCount, CreatedAt, ThumbnailImageName,
|
||||
// FriendlyName, RoomieCategory, ConsumableToolName, ConfigurationData }`, where
|
||||
// `ConfigurationData` is JSON escaped into a STRING (`"{\"MeshConfigurationData\":null,…}"`).
|
||||
// opposed to the ones a player owns. Served verbatim from `static/consumables.json`, the
|
||||
// live game's list; `supportedVersion` is accepted and unused. A row's `ConfigurationData`
|
||||
// is JSON escaped into a STRING (`"{\"MeshConfigurationData\":null,…}"`), or null.
|
||||
.get(
|
||||
'/api/consumables/v1/all',
|
||||
describeRoute({
|
||||
tags: ['Consumables'],
|
||||
summary: 'All consumable definitions (stub)',
|
||||
description: 'Always [] — no consumable definitions are served yet.',
|
||||
responses: { 200: json(JsonArray, 'The consumable definitions (always empty)') },
|
||||
summary: 'All consumable definitions',
|
||||
description:
|
||||
'Every consumable definition, verbatim from static/consumables.json. supportedVersion is ignored.',
|
||||
responses: { 200: json(JsonArray, 'The consumable definitions') },
|
||||
}),
|
||||
(c) => c.json([])
|
||||
(c) => c.json(consumableDefinitions)
|
||||
)
|
||||
|
||||
// Unlocked consumables. [Authorize]. The consumables the player has bought (from
|
||||
|
||||
@@ -3772,10 +3772,20 @@ describe('econ endpoints', () => {
|
||||
}
|
||||
})
|
||||
|
||||
test('GET /api/consumables/v1/all is a stub: returns []', async () => {
|
||||
test('GET /api/consumables/v1/all serves the consumable definitions', async () => {
|
||||
const res = await exports.default.fetch(`${ORIGIN}/api/consumables/v1/all?supportedVersion=2`)
|
||||
expect(res.status).toBe(200)
|
||||
expect(await res.json()).toEqual([])
|
||||
const body = await res.json<Array<Record<string, unknown>>>()
|
||||
expect(body.length).toBeGreaterThan(0)
|
||||
expect(body[0]).toMatchObject({
|
||||
ConsumableItemId: 1,
|
||||
ConsumableItemDesc: 'frOMH6WxDEG1fBqC4_83vg',
|
||||
FriendlyName: 'Black & White Camera Film',
|
||||
})
|
||||
// ConfigurationData is JSON escaped into a string (or null), never a nested object.
|
||||
for (const item of body) {
|
||||
expect(item.ConfigurationData === null || typeof item.ConfigurationData === 'string').toBe(true)
|
||||
}
|
||||
})
|
||||
|
||||
test('GET /api/consumables/v2/getUnlocked 401s without a token, returns []', async () => {
|
||||
|
||||
Reference in New Issue
Block a user