feat: modules and resources domains, drop removed domains, regenerated models
This commit is contained in:
+41
-57
@@ -135,83 +135,67 @@ describe('transport error mapping', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('lazy scenario runtime', () => {
|
||||
beforeEach(() => {
|
||||
localStorage.clear();
|
||||
});
|
||||
|
||||
describe('modules and resources', () => {
|
||||
afterEach(() => {
|
||||
vi.unstubAllGlobals();
|
||||
});
|
||||
|
||||
it('does not create the scenario runtime until first use', async () => {
|
||||
it('modules.call posts to /sdk/v1/modules/:module/:fn', async () => {
|
||||
const client = new RudderClient({
|
||||
baseUrl: 'https://api.example.com',
|
||||
projectKey: 'proj_123',
|
||||
runtime: { loginEvent: null },
|
||||
tokenStore: createFakeTokenStore(),
|
||||
});
|
||||
const internals = client as unknown as {
|
||||
scenarioRuntime: unknown;
|
||||
ensureScenarioRuntime(): Promise<unknown>;
|
||||
};
|
||||
expect(internals.scenarioRuntime).toBeNull();
|
||||
await internals.ensureScenarioRuntime();
|
||||
expect(internals.scenarioRuntime).not.toBeNull();
|
||||
const fetchMock = vi.fn().mockResolvedValue(
|
||||
new Response(JSON.stringify({ result: { ok: true }, log: [] }), { status: 200 }),
|
||||
);
|
||||
vi.stubGlobal('fetch', fetchMock);
|
||||
|
||||
const result = await client.modules.call('quests', 'list', { limit: 10 });
|
||||
|
||||
expect(result).toEqual({ result: { ok: true }, log: [] });
|
||||
const [url, init] = fetchMock.mock.calls[0];
|
||||
expect(new URL(String(url)).pathname).toBe('/sdk/v1/modules/quests/list');
|
||||
expect(JSON.parse(String(init.body))).toEqual({ args: { limit: 10 } });
|
||||
});
|
||||
|
||||
it('delivers effects to handlers subscribed before the runtime is ready', async () => {
|
||||
it('resources(slug) lists and mutates rows', async () => {
|
||||
const client = new RudderClient({
|
||||
baseUrl: 'https://api.example.com',
|
||||
projectKey: 'proj_123',
|
||||
runtime: {},
|
||||
tokenStore: createFakeTokenStore(),
|
||||
});
|
||||
|
||||
const notifications: string[] = [];
|
||||
client.effects.onNotification((effect) => {
|
||||
notifications.push(effect.message);
|
||||
return effect.done();
|
||||
});
|
||||
|
||||
vi.stubGlobal('fetch', vi.fn().mockImplementation((url: string, init?: RequestInit) => {
|
||||
const row = { id: 'row-1', data: { name: 'Sword' }, version: 1 };
|
||||
const fetchMock = vi.fn().mockImplementation((url: string, init?: RequestInit) => {
|
||||
const path = new URL(url).pathname;
|
||||
if (path === '/sdk/v1/authorization/device') {
|
||||
return Promise.resolve(new Response(
|
||||
JSON.stringify({ accessToken: 'at', refreshToken: 'rt' }),
|
||||
{ status: 200 },
|
||||
));
|
||||
const method = (init?.method ?? 'GET').toUpperCase();
|
||||
if (method === 'GET' && path === '/sdk/v1/resources/items') {
|
||||
return Promise.resolve(new Response(JSON.stringify({ items: [row], total: 1 }), { status: 200 }));
|
||||
}
|
||||
if (path === '/sdk/v1/scenarios/trigger') {
|
||||
return Promise.resolve(new Response(JSON.stringify({
|
||||
effects: [{
|
||||
runId: 'run-1',
|
||||
scenarioSlug: 'scenario-1',
|
||||
nodeId: 'start',
|
||||
type: 'notification',
|
||||
data: { message: 'Welcome!' },
|
||||
}],
|
||||
}), { status: 200 }));
|
||||
if (method === 'GET' && path === '/sdk/v1/resources/items/row-1') {
|
||||
return Promise.resolve(new Response(JSON.stringify(row), { status: 200 }));
|
||||
}
|
||||
if (path === '/sdk/v1/scenarios/pending') {
|
||||
return Promise.resolve(new Response(JSON.stringify({ effects: [] }), { status: 200 }));
|
||||
if (method === 'POST' && path === '/sdk/v1/resources/items') {
|
||||
return Promise.resolve(new Response(JSON.stringify(row), { status: 200 }));
|
||||
}
|
||||
if (path === '/sdk/v1/remote-configs') {
|
||||
return Promise.resolve(new Response(JSON.stringify({ configs: {} }), { status: 200 }));
|
||||
if (method === 'PATCH' && path === '/sdk/v1/resources/items/row-1') {
|
||||
return Promise.resolve(new Response(JSON.stringify({ ...row, version: 2 }), { status: 200 }));
|
||||
}
|
||||
if (path === '/sdk/v1/stores') {
|
||||
return Promise.resolve(new Response(JSON.stringify({ stores: [], total: 0 }), { status: 200 }));
|
||||
if (method === 'DELETE' && path === '/sdk/v1/resources/items/row-1') {
|
||||
return Promise.resolve(new Response(null, { status: 204 }));
|
||||
}
|
||||
if (path === '/sdk/v1/catalog') {
|
||||
return Promise.resolve(new Response(JSON.stringify({ items: [] }), { status: 200 }));
|
||||
}
|
||||
if (path === '/sdk/v1/sync') {
|
||||
return Promise.resolve(new Response(JSON.stringify({}), { status: 200 }));
|
||||
}
|
||||
void init;
|
||||
return Promise.resolve(new Response(JSON.stringify({ player: null, wallets: [] }), { status: 200 }));
|
||||
}));
|
||||
return Promise.resolve(new Response('unhandled', { status: 500 }));
|
||||
});
|
||||
vi.stubGlobal('fetch', fetchMock);
|
||||
|
||||
await client.auth.loginWithDevice();
|
||||
await vi.waitFor(() => expect(notifications).toEqual(['Welcome!']));
|
||||
client.dispose();
|
||||
const handle = client.resources('items');
|
||||
expect(await handle.list()).toEqual({ items: [row], total: 1 });
|
||||
expect(await handle.get('row-1')).toEqual(row);
|
||||
expect(await handle.create({ data: { name: 'Sword' } })).toEqual(row);
|
||||
expect(await handle.update('row-1', { data: { name: 'Sword' }, version: 1 })).toEqual({
|
||||
...row,
|
||||
version: 2,
|
||||
});
|
||||
expect(await handle.delete('row-1')).toBeUndefined();
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user