import { describe, it, expect, beforeAll, vi } from 'vitest'; import { adminApi, loadArtifact, makeProdClient } from './_setup/harness.js'; import type { SeedArtifact } from './_setup/types.js'; import type { NotificationEffect, StoreOfferEffect } from '../../src/index.js'; import { getScenarioRuntime } from '../../src/client/RudderClient.js'; describe('e2e-prod: scenarios', () => { let artifact: SeedArtifact; beforeAll(() => { artifact = loadArtifact(); }); it('runs onboarding: notification -> rc override -> store -> boundary callback -> notification', async () => { const notifications: NotificationEffect[] = []; let storeOffer: StoreOfferEffect | undefined; let runCompleted = false; const client = makeProdClient(artifact, { loginEvent: artifact.scenario.event, }); client.effects.onNotification((effect) => { notifications.push(effect); }); client.effects.onStoreOffer((effect) => { storeOffer = effect; }); const runtime = await getScenarioRuntime(client); client.effects.onScenarioCompleted(() => { runCompleted = true; }); await client.auth.loginWithDevice({ region: 'en', language: 'en' }); // The boundary buy uses the paid offer — fund the wallet so the purchase succeeds. const playerId = (await client.player.reload()).player!.id!; await adminApi(artifact).post( `/platform/v1/projects/${artifact.projectId}/players/${playerId}/wallet/adjust`, { currencyCode: artifact.store.paidPrice.currency, amount: artifact.store.paidPrice.amount, reason: 'e2e scenario funding', }, ); // First notification dispatched. await vi.waitFor(() => expect(notifications.length).toBe(1), { timeout: 10_000 }); await notifications[0].done(); await vi.waitFor(() => expect(storeOffer).toBeDefined(), { timeout: 10_000 }); await client.remoteConfig.reload(); expect(client.remoteConfig.get('spawn_rate', 0)).toBeCloseTo( artifact.remoteConfigs.spawnRateOverride, ); // Buy crosses the server boundary (POST /sdk/v1/scenarios/callback) -> second notification. const offer = storeOffer!.offers.find((o) => o.name === artifact.store.paidOfferName)!; await storeOffer!.buy(offer); await vi.waitFor(() => expect(notifications.length).toBe(2), { timeout: 15_000 }); await notifications[1].done(); await vi.waitFor(() => expect(runtime.isRunning).toBe(false), { timeout: 10_000 }); expect(runCompleted).toBe(true); }); });