Slug-based scenarios, quests and offers per the environments contract; regenerated models; e2e seed passes environment to admin mirrors
Claude-Session: https://claude.ai/code/session_01SMCvdwDmuxoaqGgvGBLk1V
This commit is contained in:
@@ -24,7 +24,7 @@ describe('E2E: boundary nodes (server-side continuation)', () => {
|
||||
stores: [{
|
||||
slug: 'starter',
|
||||
name: 'Starter',
|
||||
offers: [{ id: 'pack_1', name: 'Starter Pack' }],
|
||||
offers: [{ id: 'pack_1', slug: 'pack-1', name: 'Starter Pack' }],
|
||||
}],
|
||||
});
|
||||
gateway.install();
|
||||
@@ -35,12 +35,12 @@ describe('E2E: boundary nodes (server-side continuation)', () => {
|
||||
|
||||
it('purchase crosses the boundary → callback fires and continues the scenario', async () => {
|
||||
const offerEffect = effect('store', { storeSlug: 'starter', message: 'Buy the starter pack!' }, {
|
||||
scenarioId: 'offer_flow',
|
||||
scenarioSlug: 'offer_flow',
|
||||
runId: 'offer_flow-run',
|
||||
nodeId: 'offer',
|
||||
});
|
||||
const reward = effect('notification', { message: 'Reward granted: 500 gems!' }, {
|
||||
scenarioId: 'offer_flow',
|
||||
scenarioSlug: 'offer_flow',
|
||||
runId: 'offer_flow-run',
|
||||
nodeId: 'reward',
|
||||
});
|
||||
@@ -52,7 +52,7 @@ describe('E2E: boundary nodes (server-side continuation)', () => {
|
||||
let offer: StoreOfferEffect | undefined;
|
||||
client.effects.onStoreOffer((e) => { offer = e; });
|
||||
client.effects.onNotification((e) => { messages.push(e.message); });
|
||||
client.effects.onScenarioCompleted((e) => { completed.push(e.scenarioId); });
|
||||
client.effects.onScenarioCompleted((e) => { completed.push(e.scenarioSlug); });
|
||||
|
||||
const token = (await client.auth.loginWithDevice()).accessToken;
|
||||
await vi.waitFor(() => expect(offer).toBeDefined());
|
||||
@@ -61,7 +61,7 @@ describe('E2E: boundary nodes (server-side continuation)', () => {
|
||||
|
||||
const callback = gateway.recorded.find((r) => r.path === '/sdk/v1/scenarios/callback');
|
||||
expect(callback?.body).toEqual({
|
||||
scenarioId: 'offer_flow',
|
||||
scenarioSlug: 'offer_flow',
|
||||
nodeId: 'offer',
|
||||
handle: 'onPurchase',
|
||||
runId: 'offer_flow-run',
|
||||
@@ -75,12 +75,12 @@ describe('E2E: boundary nodes (server-side continuation)', () => {
|
||||
|
||||
it('decline posts callback and continues with the server-supplied next effect', async () => {
|
||||
const offerEffect = effect('store', { storeSlug: 'starter', message: 'Buy the starter pack!' }, {
|
||||
scenarioId: 'offer_flow',
|
||||
scenarioSlug: 'offer_flow',
|
||||
runId: 'offer_flow-run',
|
||||
nodeId: 'offer',
|
||||
});
|
||||
const consolation = effect('notification', { message: 'Maybe next time!' }, {
|
||||
scenarioId: 'offer_flow',
|
||||
scenarioSlug: 'offer_flow',
|
||||
runId: 'offer_flow-run',
|
||||
nodeId: 'consolation',
|
||||
});
|
||||
@@ -102,7 +102,7 @@ describe('E2E: boundary nodes (server-side continuation)', () => {
|
||||
|
||||
it('a failing callback does not fail or crash the run', async () => {
|
||||
const offerEffect = effect('store', { storeSlug: 'starter' }, {
|
||||
scenarioId: 'offer_flow',
|
||||
scenarioSlug: 'offer_flow',
|
||||
runId: 'offer_flow-run',
|
||||
nodeId: 'offer',
|
||||
});
|
||||
|
||||
@@ -18,29 +18,29 @@ function makeClient(): RudderClient {
|
||||
|
||||
function offerScenario(now: number) {
|
||||
const waitIntro = effect('wait', {}, {
|
||||
scenarioId: 'offer_flow',
|
||||
scenarioSlug: 'offer_flow',
|
||||
runId: 'offer_flow-run',
|
||||
nodeId: 'wait_intro',
|
||||
waitDeadline: new Date(now + MINUTE).toISOString(),
|
||||
});
|
||||
const offer = effect('store', { storeSlug: 'starter', offerId: 'pack_1', message: 'Limited starter pack!' }, {
|
||||
scenarioId: 'offer_flow',
|
||||
const offer = effect('store', { storeSlug: 'starter', offerSlug: 'pack-1', message: 'Limited starter pack!' }, {
|
||||
scenarioSlug: 'offer_flow',
|
||||
runId: 'offer_flow-run',
|
||||
nodeId: 'offer',
|
||||
});
|
||||
const waitReminder = effect('wait', {}, {
|
||||
scenarioId: 'offer_flow',
|
||||
scenarioSlug: 'offer_flow',
|
||||
runId: 'offer_flow-run',
|
||||
nodeId: 'wait_reminder',
|
||||
waitDeadline: new Date(now + 2 * MINUTE).toISOString(),
|
||||
});
|
||||
const reminder = effect('notification', { message: 'Your offer is still available!' }, {
|
||||
scenarioId: 'offer_flow',
|
||||
scenarioSlug: 'offer_flow',
|
||||
runId: 'offer_flow-run',
|
||||
nodeId: 'reminder',
|
||||
});
|
||||
const thanks = effect('notification', { message: 'Thanks for your purchase!' }, {
|
||||
scenarioId: 'offer_flow',
|
||||
scenarioSlug: 'offer_flow',
|
||||
runId: 'offer_flow-run',
|
||||
nodeId: 'thanks',
|
||||
});
|
||||
@@ -58,7 +58,7 @@ describe('E2E: player offer journey', () => {
|
||||
stores: [{
|
||||
slug: 'starter',
|
||||
name: 'Starter',
|
||||
offers: [{ id: 'pack_1', name: 'Starter Pack' }],
|
||||
offers: [{ id: 'pack_1', slug: 'pack-1', name: 'Starter Pack' }],
|
||||
}],
|
||||
});
|
||||
gateway.install();
|
||||
@@ -139,7 +139,7 @@ describe('E2E: player offer journey', () => {
|
||||
expect(purchase.success).toBe(true);
|
||||
|
||||
expect(gateway.purchases).toEqual([
|
||||
{ storeSlug: 'starter', offerId: 'pack_1', idempotencyKey: 'idem-key-123', authToken: accessToken },
|
||||
{ storeSlug: 'starter', offerSlug: 'pack-1', idempotencyKey: 'idem-key-123', authToken: accessToken },
|
||||
]);
|
||||
|
||||
expect(notifications).toHaveLength(1);
|
||||
|
||||
@@ -24,17 +24,17 @@ describe('E2E: pending effects resume after a new login', () => {
|
||||
stubDeterministicUuid();
|
||||
vi.useFakeTimers();
|
||||
gateway = createFakeGateway({
|
||||
stores: [{ slug: 'starter', name: 'Starter', offers: [{ id: 'pack_1', name: 'Pack' }] }],
|
||||
stores: [{ slug: 'starter', name: 'Starter', offers: [{ id: 'pack_1', slug: 'pack-1', name: 'Pack' }] }],
|
||||
});
|
||||
const now = Date.now();
|
||||
const wait = effect('wait', {}, {
|
||||
scenarioId: 'offer_flow',
|
||||
scenarioSlug: 'offer_flow',
|
||||
runId: 'offer_flow-run',
|
||||
nodeId: 'wait_intro',
|
||||
waitDeadline: new Date(now + MINUTE).toISOString(),
|
||||
});
|
||||
const offer = effect('store', { message: 'Limited starter pack!', storeSlug: 'starter' }, {
|
||||
scenarioId: 'offer_flow',
|
||||
scenarioSlug: 'offer_flow',
|
||||
runId: 'offer_flow-run',
|
||||
nodeId: 'offer',
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user