-
Notifications
You must be signed in to change notification settings - Fork 5
Expand file tree
/
Copy pathmeta-automation-descriptors.test.ts
More file actions
93 lines (83 loc) · 4.19 KB
/
Copy pathmeta-automation-descriptors.test.ts
File metadata and controls
93 lines (83 loc) · 4.19 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.
/**
* The final six #3563 gap closures (PR-5): meta published/drafts/FSM and the
* automation descriptor/status routes. With these, every should-be-SDK
* dispatcher route has an SDK expression and the ledger's gap ratchet is 0.
*/
import { describe, it, expect, vi } from 'vitest';
import { ObjectStackClient } from './index';
function createMockClient(body: any, status = 200) {
const fetchMock = vi.fn().mockResolvedValue({
ok: status >= 200 && status < 300,
status,
statusText: status === 200 ? 'OK' : 'Error',
json: async () => body,
headers: new Headers()
});
const client = new ObjectStackClient({
baseUrl: 'http://localhost:3000',
fetch: fetchMock
});
return { client, fetchMock };
}
describe('client.meta (#3563 PR-5)', () => {
it('getPublished passes compound names through unencoded', async () => {
const { client, fetchMock } = createMockClient({ success: true, data: { name: 'all_leads' } });
await client.meta.getPublished('lead', 'views/all_leads');
expect(String(fetchMock.mock.calls[0][0])).toBe(
'http://localhost:3000/api/v1/meta/lead/views/all_leads/published',
);
});
it('listDrafts builds the packageId/type query and omits empties', async () => {
const { client, fetchMock } = createMockClient({ success: true, data: { drafts: [] } });
await client.meta.listDrafts({ packageId: 'com.acme.crm', type: 'object' });
expect(String(fetchMock.mock.calls[0][0])).toBe(
'http://localhost:3000/api/v1/meta/_drafts?packageId=com.acme.crm&type=object',
);
await client.meta.listDrafts();
expect(String(fetchMock.mock.calls[1][0])).toBe('http://localhost:3000/api/v1/meta/_drafts');
});
it('getLegalNextStates hits the FSM route and forwards from=', async () => {
const { client, fetchMock } = createMockClient({
success: true,
data: { object: 'crm_lead', field: 'status', from: 'new', next: ['contacted'] },
});
const out = await client.meta.getLegalNextStates('crm_lead', 'status', 'new');
expect(String(fetchMock.mock.calls[0][0])).toBe(
'http://localhost:3000/api/v1/meta/objects/crm_lead/state/status?from=new',
);
expect(out.next).toEqual(['contacted']);
// Omitted `from` → no query; the server answers next: null.
await client.meta.getLegalNextStates('crm_lead', 'status');
expect(String(fetchMock.mock.calls[1][0])).toBe(
'http://localhost:3000/api/v1/meta/objects/crm_lead/state/status',
);
});
});
describe('client.automation descriptors (#3563 PR-5)', () => {
it('listActions forwards the paradigm/source/category filters', async () => {
const { client, fetchMock } = createMockClient({ success: true, data: { actions: [], total: 0 } });
await client.automation.listActions({ paradigm: 'flow', category: 'crud' });
expect(String(fetchMock.mock.calls[0][0])).toBe(
'http://localhost:3000/api/v1/automation/actions?paradigm=flow&category=crud',
);
await client.automation.listActions();
expect(String(fetchMock.mock.calls[1][0])).toBe('http://localhost:3000/api/v1/automation/actions');
});
it('listConnectors forwards the type filter', async () => {
const { client, fetchMock } = createMockClient({ success: true, data: { connectors: [], total: 0 } });
await client.automation.listConnectors({ type: 'rest' });
expect(String(fetchMock.mock.calls[0][0])).toBe(
'http://localhost:3000/api/v1/automation/connectors?type=rest',
);
});
it('getRuntimeStatus GETs the underscore-guarded _status route', async () => {
const { client, fetchMock } = createMockClient({
success: true,
data: { flows: [{ name: 'f1', enabled: true, bound: true }], total: 1 },
});
const out = await client.automation.getRuntimeStatus();
expect(String(fetchMock.mock.calls[0][0])).toBe('http://localhost:3000/api/v1/automation/_status');
expect(out.flows[0].bound).toBe(true);
});
});