Files
galaxy-game/ui/frontend/tests/account-decode.test.ts
T
Ilia Denisov 009ea560f9
Tests · Go / test (push) Successful in 2m17s
Tests · UI / test (push) Waiting to run
feat(lobby): F8-04b hierarchical sidebar + paid-tier gate for create-game
Reshape the lobby UI from a single Overview into a two-level sidebar
(games · profile · DEV synthetic-reports) with four games sub-panels
(active-past · recruitment · invitations · private-games). Move the
`create new game` button into the private-games panel, merge the
applications section into recruitment cards as status chips, and add
DEV-only synthetic-report loader as a top-level screen.

Add a paid-tier gate at backend `lobby.game.create`: free callers get
`403 forbidden` before the lobby service is invoked. The UI hides the
private-games sub-panel + create button on free tier (DEV affordances
flag overrides). Update every integration test that creates a game to
use a new `testenv.PromoteToPaid` helper; add a new
`TestLobbyFlow_FreeUserCreateGameForbidden`.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-26 23:53:53 +02:00

89 lines
3.4 KiB
TypeScript

// Unit tests for `decodeAccountView` — F8-04b adds an `entitlement`
// projection on the TS Account, sourced from the FBS
// `EntitlementSnapshot.is_paid` field. The decode must default to
// `false` when the snapshot is absent, never throw on null.
import { Builder, ByteBuffer } from "flatbuffers";
import { describe, expect, test } from "vitest";
import { decodeAccountView } from "../src/api/account";
import {
AccountView,
EntitlementSnapshot,
} from "../src/proto/galaxy/fbs/user";
function buildAccountView(opts: {
isPaid?: boolean;
includeEntitlement: boolean;
}): AccountView {
const builder = new Builder(256);
const userIdOff = builder.createString("user-1");
const emailOff = builder.createString("user@example.com");
const userNameOff = builder.createString("Player-1");
const displayNameOff = builder.createString("Display");
const langOff = builder.createString("en-US");
const tzOff = builder.createString("UTC");
const countryOff = builder.createString("US");
let entitlementOff = 0;
if (opts.includeEntitlement) {
const planOff = builder.createString("free");
const sourceOff = builder.createString("default");
const reasonOff = builder.createString("init");
EntitlementSnapshot.startEntitlementSnapshot(builder);
EntitlementSnapshot.addPlanCode(builder, planOff);
EntitlementSnapshot.addIsPaid(builder, opts.isPaid ?? false);
EntitlementSnapshot.addSource(builder, sourceOff);
EntitlementSnapshot.addReasonCode(builder, reasonOff);
entitlementOff = EntitlementSnapshot.endEntitlementSnapshot(builder);
}
AccountView.startAccountView(builder);
AccountView.addUserId(builder, userIdOff);
AccountView.addEmail(builder, emailOff);
AccountView.addUserName(builder, userNameOff);
AccountView.addDisplayName(builder, displayNameOff);
AccountView.addPreferredLanguage(builder, langOff);
AccountView.addTimeZone(builder, tzOff);
AccountView.addDeclaredCountry(builder, countryOff);
if (entitlementOff !== 0) {
AccountView.addEntitlement(builder, entitlementOff);
}
const viewOff = AccountView.endAccountView(builder);
builder.finish(viewOff);
return AccountView.getRootAsAccountView(new ByteBuffer(builder.asUint8Array()));
}
describe("decodeAccountView", () => {
test("extracts entitlement.isPaid=true from FBS EntitlementSnapshot", () => {
const view = buildAccountView({ includeEntitlement: true, isPaid: true });
const account = decodeAccountView(view);
expect(account.entitlement.isPaid).toBe(true);
});
test("extracts entitlement.isPaid=false from FBS EntitlementSnapshot", () => {
const view = buildAccountView({ includeEntitlement: true, isPaid: false });
const account = decodeAccountView(view);
expect(account.entitlement.isPaid).toBe(false);
});
test("defaults entitlement.isPaid to false when snapshot is absent", () => {
const view = buildAccountView({ includeEntitlement: false });
const account = decodeAccountView(view);
expect(account.entitlement.isPaid).toBe(false);
});
test("populates other Account fields verbatim", () => {
const view = buildAccountView({ includeEntitlement: true, isPaid: true });
const account = decodeAccountView(view);
expect(account.userId).toBe("user-1");
expect(account.email).toBe("user@example.com");
expect(account.userName).toBe("Player-1");
expect(account.displayName).toBe("Display");
expect(account.preferredLanguage).toBe("en-US");
expect(account.timeZone).toBe("UTC");
expect(account.declaredCountry).toBe("US");
});
});