mirror of
https://github.com/Such-Software/wownerogue.git
synced 2026-10-20 15:48:33 +02:00
Migration 024 adds a server-authoritative cosmetic_catalog table (seeds today's 4 packs). New CatalogService loads it (cached, falls back to a built-in default when the table is absent). entitlements.snapshotForUser is rewritten to the three-way unlock rule — a pack unlocks via: it's free, an explicit grant, lifetime spend >= its threshold, OR premium tier >= its tier. This kills the old bug where ANY purchase (total_credits_purchased>0 -> level 'credits') unlocked EVERY premium pack, and makes '1 credit -> skin A, 10-pack -> pack B' expressible. Credit-buying no longer auto-promotes to a premium tier. Snapshot now ships a catalog summary to the client (the seed for killing the client-side split-brain next). identityService loads + passes the catalog. +13 tests (catalogEntitlements_ultra), suite 48/343 green. First stone of the P1 foundation (branch feat/credits-catalog-foundation). Next: client consumes the served catalog (retires RK.PACKS), direct payment -> mint 1 credit, then the buy modal reflects the unified model.
49 lines
2.4 KiB
JavaScript
49 lines
2.4 KiB
JavaScript
const Appearance = require('../src/multiplayer/appearance');
|
|
const Entitlements = require('../src/multiplayer/entitlements');
|
|
|
|
describe('cosmetic entitlements', () => {
|
|
test('free users cannot select premium generated skins or 3D avatars', () => {
|
|
const entitlements = Entitlements.snapshotForUser({ credits: 0, total_credits_purchased: 0 });
|
|
|
|
expect(Entitlements.canUsePack(entitlements, 'generated-skins')).toBe(false);
|
|
expect(Entitlements.canUsePack(entitlements, 'kenney-3d-characters')).toBe(false);
|
|
expect(Entitlements.normalizeAppearance({ avatar: 'monero-knight' }, entitlements).avatar).toBe('default');
|
|
expect(Entitlements.normalizeAppearance({ avatar: 'kenney-survivor-male' }, entitlements).avatar).toBe('default');
|
|
});
|
|
|
|
test('any credits purchase unlocks the preview premium packs', () => {
|
|
const entitlements = Entitlements.snapshotForUser({ credits: 7, total_credits_purchased: 10 });
|
|
|
|
expect(entitlements.premium).toBe(true);
|
|
expect(entitlements.level).toBe('free'); // spend unlocks packs by threshold, but isn't a premium tier
|
|
expect(entitlements.packs['generated-skins']).toBe(true);
|
|
expect(entitlements.packs['iso-dungeon']).toBe(true);
|
|
expect(entitlements.packs['kenney-3d-characters']).toBe(true);
|
|
expect(Entitlements.normalizeAppearance({ avatar: 'monero-knight' }, entitlements).avatar).toBe('monero-knight');
|
|
});
|
|
|
|
test('explicit pack grants can unlock one pack without unlocking all packs', () => {
|
|
const entitlements = Entitlements.snapshotForUser(
|
|
{ credits: 0, total_credits_purchased: 0 },
|
|
[{ pack_id: 'generated-skins' }]
|
|
);
|
|
|
|
expect(entitlements.premium).toBe(true);
|
|
expect(entitlements.packs['generated-skins']).toBe(true);
|
|
expect(entitlements.packs['kenney-3d-characters']).toBe(false);
|
|
expect(Entitlements.normalizeAppearance({ avatar: 'monero-knight' }, entitlements).avatar).toBe('monero-knight');
|
|
expect(Entitlements.normalizeAppearance({ avatar: 'kenney-survivor-male' }, entitlements).avatar).toBe('default');
|
|
});
|
|
|
|
test('appearance catalog reports all premium avatar ids, including 3D models', () => {
|
|
expect(Appearance.premiumAvatarIds()).toEqual(expect.arrayContaining([
|
|
'monero-knight',
|
|
'wownero-rogue',
|
|
'cypher-operative',
|
|
'kenney-survivor-male',
|
|
'kenney-survivor-female'
|
|
]));
|
|
expect(Appearance.avatarPack('kenney-survivor-male')).toBe('kenney-3d-characters');
|
|
});
|
|
});
|