@objectstack/objectql 4.0.3 → 4.0.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.mts +500 -1111
- package/dist/index.d.ts +500 -1111
- package/dist/index.js +1364 -279
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1359 -279
- package/dist/index.mjs.map +1 -1
- package/package.json +32 -6
- package/.turbo/turbo-build.log +0 -22
- package/CHANGELOG.md +0 -711
- package/src/engine.test.ts +0 -599
- package/src/engine.ts +0 -1548
- package/src/index.ts +0 -41
- package/src/kernel-factory.ts +0 -48
- package/src/metadata-facade.ts +0 -96
- package/src/plugin.integration.test.ts +0 -995
- package/src/plugin.ts +0 -534
- package/src/protocol-data.test.ts +0 -245
- package/src/protocol-discovery.test.ts +0 -213
- package/src/protocol-feed.test.ts +0 -303
- package/src/protocol-meta.test.ts +0 -440
- package/src/protocol.ts +0 -1235
- package/src/registry.test.ts +0 -494
- package/src/registry.ts +0 -716
- package/src/util.test.ts +0 -226
- package/src/util.ts +0 -219
- package/tsconfig.json +0 -10
|
@@ -1,245 +0,0 @@
|
|
|
1
|
-
// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.
|
|
2
|
-
|
|
3
|
-
import { describe, it, expect, vi, beforeEach } from 'vitest';
|
|
4
|
-
import { ObjectStackProtocolImplementation } from './protocol.js';
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* Tests for the Protocol Implementation's data methods (findData, getData).
|
|
8
|
-
* Validates that expand/populate/select parameters are correctly normalized
|
|
9
|
-
* and forwarded to the underlying engine.
|
|
10
|
-
*/
|
|
11
|
-
describe('ObjectStackProtocolImplementation - Data Operations', () => {
|
|
12
|
-
let protocol: ObjectStackProtocolImplementation;
|
|
13
|
-
let mockEngine: any;
|
|
14
|
-
|
|
15
|
-
beforeEach(() => {
|
|
16
|
-
mockEngine = {
|
|
17
|
-
find: vi.fn().mockResolvedValue([]),
|
|
18
|
-
findOne: vi.fn().mockResolvedValue(null),
|
|
19
|
-
};
|
|
20
|
-
protocol = new ObjectStackProtocolImplementation(mockEngine);
|
|
21
|
-
});
|
|
22
|
-
|
|
23
|
-
// ═══════════════════════════════════════════════════════════════
|
|
24
|
-
// findData — expand/populate normalization
|
|
25
|
-
// ═══════════════════════════════════════════════════════════════
|
|
26
|
-
|
|
27
|
-
describe('findData', () => {
|
|
28
|
-
it('should normalize $expand (OData) string to expand Record', async () => {
|
|
29
|
-
await protocol.findData({ object: 'order_item', query: { $expand: 'order,product' } });
|
|
30
|
-
|
|
31
|
-
expect(mockEngine.find).toHaveBeenCalledWith(
|
|
32
|
-
'order_item',
|
|
33
|
-
expect.objectContaining({
|
|
34
|
-
expand: { order: { object: 'order' }, product: { object: 'product' } },
|
|
35
|
-
}),
|
|
36
|
-
);
|
|
37
|
-
// $expand should be deleted from options
|
|
38
|
-
const callArgs = mockEngine.find.mock.calls[0][1];
|
|
39
|
-
expect(callArgs.$expand).toBeUndefined();
|
|
40
|
-
});
|
|
41
|
-
|
|
42
|
-
it('should normalize $expand (OData) with different fields to expand Record', async () => {
|
|
43
|
-
await protocol.findData({ object: 'task', query: { $expand: 'assignee,project' } });
|
|
44
|
-
|
|
45
|
-
expect(mockEngine.find).toHaveBeenCalledWith(
|
|
46
|
-
'task',
|
|
47
|
-
expect.objectContaining({
|
|
48
|
-
expand: { assignee: { object: 'assignee' }, project: { object: 'project' } },
|
|
49
|
-
}),
|
|
50
|
-
);
|
|
51
|
-
});
|
|
52
|
-
|
|
53
|
-
it('should normalize populate array to expand Record', async () => {
|
|
54
|
-
await protocol.findData({ object: 'task', query: { populate: ['assignee'] } });
|
|
55
|
-
|
|
56
|
-
expect(mockEngine.find).toHaveBeenCalledWith(
|
|
57
|
-
'task',
|
|
58
|
-
expect.objectContaining({
|
|
59
|
-
expand: { assignee: { object: 'assignee' } },
|
|
60
|
-
}),
|
|
61
|
-
);
|
|
62
|
-
});
|
|
63
|
-
|
|
64
|
-
it('should normalize populate string to expand Record', async () => {
|
|
65
|
-
await protocol.findData({ object: 'task', query: { populate: 'assignee,project' } });
|
|
66
|
-
|
|
67
|
-
expect(mockEngine.find).toHaveBeenCalledWith(
|
|
68
|
-
'task',
|
|
69
|
-
expect.objectContaining({
|
|
70
|
-
expand: { assignee: { object: 'assignee' }, project: { object: 'project' } },
|
|
71
|
-
}),
|
|
72
|
-
);
|
|
73
|
-
});
|
|
74
|
-
|
|
75
|
-
it('should prefer populate names over expand string when both provided', async () => {
|
|
76
|
-
await protocol.findData({
|
|
77
|
-
object: 'task',
|
|
78
|
-
query: { populate: ['assignee'], expand: 'project' },
|
|
79
|
-
});
|
|
80
|
-
|
|
81
|
-
// populate names take precedence; the non-object expand string is
|
|
82
|
-
// cleaned up first, then populate-derived names create the Record.
|
|
83
|
-
const callArgs = mockEngine.find.mock.calls[0][1];
|
|
84
|
-
expect(callArgs.populate).toBeUndefined();
|
|
85
|
-
expect(callArgs.$expand).toBeUndefined();
|
|
86
|
-
expect(callArgs.expand).toEqual({ assignee: { object: 'assignee' } });
|
|
87
|
-
});
|
|
88
|
-
|
|
89
|
-
it('should pass expand Record object through as-is', async () => {
|
|
90
|
-
await protocol.findData({
|
|
91
|
-
object: 'task',
|
|
92
|
-
query: { expand: { owner: { object: 'owner' }, team: { object: 'team' } } },
|
|
93
|
-
});
|
|
94
|
-
|
|
95
|
-
expect(mockEngine.find).toHaveBeenCalledWith(
|
|
96
|
-
'task',
|
|
97
|
-
expect.objectContaining({
|
|
98
|
-
expand: { owner: { object: 'owner' }, team: { object: 'team' } },
|
|
99
|
-
}),
|
|
100
|
-
);
|
|
101
|
-
});
|
|
102
|
-
|
|
103
|
-
it('should normalize select string to fields array', async () => {
|
|
104
|
-
await protocol.findData({ object: 'task', query: { select: 'name,status,assignee' } });
|
|
105
|
-
|
|
106
|
-
expect(mockEngine.find).toHaveBeenCalledWith(
|
|
107
|
-
'task',
|
|
108
|
-
expect.objectContaining({
|
|
109
|
-
fields: ['name', 'status', 'assignee'],
|
|
110
|
-
}),
|
|
111
|
-
);
|
|
112
|
-
});
|
|
113
|
-
|
|
114
|
-
it('should pass numeric pagination params correctly', async () => {
|
|
115
|
-
await protocol.findData({ object: 'task', query: { top: '10', skip: '20' } });
|
|
116
|
-
|
|
117
|
-
expect(mockEngine.find).toHaveBeenCalledWith(
|
|
118
|
-
'task',
|
|
119
|
-
expect.objectContaining({
|
|
120
|
-
limit: 10,
|
|
121
|
-
offset: 20,
|
|
122
|
-
}),
|
|
123
|
-
);
|
|
124
|
-
});
|
|
125
|
-
|
|
126
|
-
it('should work with no query options', async () => {
|
|
127
|
-
await protocol.findData({ object: 'task' });
|
|
128
|
-
|
|
129
|
-
expect(mockEngine.find).toHaveBeenCalledWith('task', {});
|
|
130
|
-
});
|
|
131
|
-
|
|
132
|
-
it('should return records and standard response shape', async () => {
|
|
133
|
-
mockEngine.find.mockResolvedValue([{ id: 't1', name: 'Task 1' }]);
|
|
134
|
-
|
|
135
|
-
const result = await protocol.findData({ object: 'task', query: {} });
|
|
136
|
-
|
|
137
|
-
expect(result).toEqual(
|
|
138
|
-
expect.objectContaining({
|
|
139
|
-
object: 'task',
|
|
140
|
-
records: [{ id: 't1', name: 'Task 1' }],
|
|
141
|
-
total: 1,
|
|
142
|
-
}),
|
|
143
|
-
);
|
|
144
|
-
});
|
|
145
|
-
});
|
|
146
|
-
|
|
147
|
-
// ═══════════════════════════════════════════════════════════════
|
|
148
|
-
// getData — expand/select normalization
|
|
149
|
-
// ═══════════════════════════════════════════════════════════════
|
|
150
|
-
|
|
151
|
-
describe('getData', () => {
|
|
152
|
-
it('should convert expand string to expand Record', async () => {
|
|
153
|
-
mockEngine.findOne.mockResolvedValue({ id: 'oi_1', name: 'Item 1' });
|
|
154
|
-
|
|
155
|
-
await protocol.getData({ object: 'order_item', id: 'oi_1', expand: 'order,product' });
|
|
156
|
-
|
|
157
|
-
expect(mockEngine.findOne).toHaveBeenCalledWith(
|
|
158
|
-
'order_item',
|
|
159
|
-
expect.objectContaining({
|
|
160
|
-
where: { id: 'oi_1' },
|
|
161
|
-
expand: { order: { object: 'order' }, product: { object: 'product' } },
|
|
162
|
-
}),
|
|
163
|
-
);
|
|
164
|
-
});
|
|
165
|
-
|
|
166
|
-
it('should convert expand array to expand Record', async () => {
|
|
167
|
-
mockEngine.findOne.mockResolvedValue({ id: 't1' });
|
|
168
|
-
|
|
169
|
-
await protocol.getData({ object: 'task', id: 't1', expand: ['assignee', 'project'] });
|
|
170
|
-
|
|
171
|
-
expect(mockEngine.findOne).toHaveBeenCalledWith(
|
|
172
|
-
'task',
|
|
173
|
-
expect.objectContaining({
|
|
174
|
-
where: { id: 't1' },
|
|
175
|
-
expand: { assignee: { object: 'assignee' }, project: { object: 'project' } },
|
|
176
|
-
}),
|
|
177
|
-
);
|
|
178
|
-
});
|
|
179
|
-
|
|
180
|
-
it('should convert select string to fields array', async () => {
|
|
181
|
-
mockEngine.findOne.mockResolvedValue({ id: 't1', name: 'Test' });
|
|
182
|
-
|
|
183
|
-
await protocol.getData({ object: 'task', id: 't1', select: 'name,status' });
|
|
184
|
-
|
|
185
|
-
expect(mockEngine.findOne).toHaveBeenCalledWith(
|
|
186
|
-
'task',
|
|
187
|
-
expect.objectContaining({
|
|
188
|
-
where: { id: 't1' },
|
|
189
|
-
fields: ['name', 'status'],
|
|
190
|
-
}),
|
|
191
|
-
);
|
|
192
|
-
});
|
|
193
|
-
|
|
194
|
-
it('should pass both expand and fields together', async () => {
|
|
195
|
-
mockEngine.findOne.mockResolvedValue({ id: 'oi_1' });
|
|
196
|
-
|
|
197
|
-
await protocol.getData({
|
|
198
|
-
object: 'order_item',
|
|
199
|
-
id: 'oi_1',
|
|
200
|
-
expand: 'order',
|
|
201
|
-
select: ['name', 'total'],
|
|
202
|
-
});
|
|
203
|
-
|
|
204
|
-
expect(mockEngine.findOne).toHaveBeenCalledWith(
|
|
205
|
-
'order_item',
|
|
206
|
-
expect.objectContaining({
|
|
207
|
-
where: { id: 'oi_1' },
|
|
208
|
-
expand: { order: { object: 'order' } },
|
|
209
|
-
fields: ['name', 'total'],
|
|
210
|
-
}),
|
|
211
|
-
);
|
|
212
|
-
});
|
|
213
|
-
|
|
214
|
-
it('should work without expand or select', async () => {
|
|
215
|
-
mockEngine.findOne.mockResolvedValue({ id: 't1' });
|
|
216
|
-
|
|
217
|
-
await protocol.getData({ object: 'task', id: 't1' });
|
|
218
|
-
|
|
219
|
-
expect(mockEngine.findOne).toHaveBeenCalledWith(
|
|
220
|
-
'task',
|
|
221
|
-
{ where: { id: 't1' } },
|
|
222
|
-
);
|
|
223
|
-
});
|
|
224
|
-
|
|
225
|
-
it('should return standard GetDataResponse shape', async () => {
|
|
226
|
-
mockEngine.findOne.mockResolvedValue({ id: 'oi_1', name: 'Item 1' });
|
|
227
|
-
|
|
228
|
-
const result = await protocol.getData({ object: 'order_item', id: 'oi_1' });
|
|
229
|
-
|
|
230
|
-
expect(result).toEqual({
|
|
231
|
-
object: 'order_item',
|
|
232
|
-
id: 'oi_1',
|
|
233
|
-
record: { id: 'oi_1', name: 'Item 1' },
|
|
234
|
-
});
|
|
235
|
-
});
|
|
236
|
-
|
|
237
|
-
it('should throw when record not found', async () => {
|
|
238
|
-
mockEngine.findOne.mockResolvedValue(null);
|
|
239
|
-
|
|
240
|
-
await expect(
|
|
241
|
-
protocol.getData({ object: 'task', id: 'missing_id' })
|
|
242
|
-
).rejects.toThrow('not found');
|
|
243
|
-
});
|
|
244
|
-
});
|
|
245
|
-
});
|
|
@@ -1,213 +0,0 @@
|
|
|
1
|
-
// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.
|
|
2
|
-
|
|
3
|
-
import { describe, it, expect, beforeEach } from 'vitest';
|
|
4
|
-
import { ObjectStackProtocolImplementation } from './protocol.js';
|
|
5
|
-
import { ObjectQL } from './engine.js';
|
|
6
|
-
|
|
7
|
-
describe('ObjectStackProtocolImplementation - Dynamic Service Discovery', () => {
|
|
8
|
-
let protocol: ObjectStackProtocolImplementation;
|
|
9
|
-
let engine: ObjectQL;
|
|
10
|
-
|
|
11
|
-
beforeEach(() => {
|
|
12
|
-
engine = new ObjectQL();
|
|
13
|
-
});
|
|
14
|
-
|
|
15
|
-
it('should return unavailable auth service when no services registered', async () => {
|
|
16
|
-
// Create protocol without service registry
|
|
17
|
-
protocol = new ObjectStackProtocolImplementation(engine);
|
|
18
|
-
|
|
19
|
-
const discovery = await protocol.getDiscovery();
|
|
20
|
-
|
|
21
|
-
expect(discovery.services.auth).toBeDefined();
|
|
22
|
-
expect(discovery.services.auth.enabled).toBe(false);
|
|
23
|
-
expect(discovery.services.auth.status).toBe('unavailable');
|
|
24
|
-
expect(discovery.services.auth.message).toContain('plugin-auth');
|
|
25
|
-
// capabilities removed — derive from services
|
|
26
|
-
expect(discovery.services.workflow).toBeDefined();
|
|
27
|
-
expect(discovery.services.workflow.enabled).toBe(false);
|
|
28
|
-
});
|
|
29
|
-
|
|
30
|
-
it('should return available auth service when auth is registered', async () => {
|
|
31
|
-
// Mock service registry with auth service
|
|
32
|
-
const mockServices = new Map<string, any>();
|
|
33
|
-
mockServices.set('auth', { /* mock auth service */ });
|
|
34
|
-
|
|
35
|
-
protocol = new ObjectStackProtocolImplementation(engine, () => mockServices);
|
|
36
|
-
|
|
37
|
-
const discovery = await protocol.getDiscovery();
|
|
38
|
-
|
|
39
|
-
expect(discovery.services.auth).toBeDefined();
|
|
40
|
-
expect(discovery.services.auth.enabled).toBe(true);
|
|
41
|
-
expect(discovery.services.auth.status).toBe('available');
|
|
42
|
-
expect(discovery.services.auth.route).toBe('/api/v1/auth');
|
|
43
|
-
expect(discovery.services.auth.provider).toBe('plugin-auth');
|
|
44
|
-
expect(discovery.routes.auth).toBe('/api/v1/auth');
|
|
45
|
-
});
|
|
46
|
-
|
|
47
|
-
it('should return available automation service when registered', async () => {
|
|
48
|
-
const mockServices = new Map<string, any>();
|
|
49
|
-
mockServices.set('automation', { /* mock automation service */ });
|
|
50
|
-
|
|
51
|
-
protocol = new ObjectStackProtocolImplementation(engine, () => mockServices);
|
|
52
|
-
|
|
53
|
-
const discovery = await protocol.getDiscovery();
|
|
54
|
-
|
|
55
|
-
expect(discovery.services.automation).toBeDefined();
|
|
56
|
-
expect(discovery.services.automation.enabled).toBe(true);
|
|
57
|
-
expect(discovery.services.automation.status).toBe('available');
|
|
58
|
-
});
|
|
59
|
-
|
|
60
|
-
it('should return multiple available services when registered', async () => {
|
|
61
|
-
const mockServices = new Map<string, any>();
|
|
62
|
-
mockServices.set('auth', {});
|
|
63
|
-
mockServices.set('realtime', {});
|
|
64
|
-
mockServices.set('ai', {});
|
|
65
|
-
|
|
66
|
-
protocol = new ObjectStackProtocolImplementation(engine, () => mockServices);
|
|
67
|
-
|
|
68
|
-
const discovery = await protocol.getDiscovery();
|
|
69
|
-
|
|
70
|
-
// Check auth
|
|
71
|
-
expect(discovery.services.auth.enabled).toBe(true);
|
|
72
|
-
expect(discovery.services.auth.status).toBe('available');
|
|
73
|
-
|
|
74
|
-
// Check realtime
|
|
75
|
-
expect(discovery.services.realtime.enabled).toBe(true);
|
|
76
|
-
expect(discovery.services.realtime.status).toBe('available');
|
|
77
|
-
|
|
78
|
-
// Check AI
|
|
79
|
-
expect(discovery.services.ai.enabled).toBe(true);
|
|
80
|
-
expect(discovery.services.ai.status).toBe('available');
|
|
81
|
-
|
|
82
|
-
// Routes should include available services
|
|
83
|
-
expect(discovery.routes.auth).toBe('/api/v1/auth');
|
|
84
|
-
expect(discovery.routes.realtime).toBe('/api/v1/realtime');
|
|
85
|
-
expect(discovery.routes.ai).toBe('/api/v1/ai');
|
|
86
|
-
});
|
|
87
|
-
|
|
88
|
-
it('should always show core services as available', async () => {
|
|
89
|
-
protocol = new ObjectStackProtocolImplementation(engine);
|
|
90
|
-
|
|
91
|
-
const discovery = await protocol.getDiscovery();
|
|
92
|
-
|
|
93
|
-
// Core services should always be available
|
|
94
|
-
expect(discovery.services.metadata.enabled).toBe(true);
|
|
95
|
-
expect(discovery.services.metadata.status).toBe('available');
|
|
96
|
-
expect(discovery.services.data.enabled).toBe(true);
|
|
97
|
-
expect(discovery.services.data.status).toBe('available');
|
|
98
|
-
expect(discovery.services.analytics.enabled).toBe(true);
|
|
99
|
-
expect(discovery.services.analytics.status).toBe('available');
|
|
100
|
-
});
|
|
101
|
-
|
|
102
|
-
it('should map file-storage service to storage route', async () => {
|
|
103
|
-
const mockServices = new Map<string, any>();
|
|
104
|
-
mockServices.set('file-storage', {});
|
|
105
|
-
|
|
106
|
-
protocol = new ObjectStackProtocolImplementation(engine, () => mockServices);
|
|
107
|
-
|
|
108
|
-
const discovery = await protocol.getDiscovery();
|
|
109
|
-
|
|
110
|
-
expect(discovery.services['file-storage'].enabled).toBe(true);
|
|
111
|
-
expect(discovery.services['file-storage'].status).toBe('available');
|
|
112
|
-
expect(discovery.routes.storage).toBe('/api/v1/storage');
|
|
113
|
-
});
|
|
114
|
-
|
|
115
|
-
it('should use consistent /api/v1/ route prefix for all services', async () => {
|
|
116
|
-
const mockServices = new Map<string, any>();
|
|
117
|
-
mockServices.set('auth', {});
|
|
118
|
-
mockServices.set('automation', {});
|
|
119
|
-
mockServices.set('ai', {});
|
|
120
|
-
|
|
121
|
-
protocol = new ObjectStackProtocolImplementation(engine, () => mockServices);
|
|
122
|
-
|
|
123
|
-
const discovery = await protocol.getDiscovery();
|
|
124
|
-
|
|
125
|
-
// All routes should use consistent /api/v1/ prefix
|
|
126
|
-
expect(discovery.routes.data).toBe('/api/v1/data');
|
|
127
|
-
expect(discovery.routes.metadata).toBe('/api/v1/meta');
|
|
128
|
-
expect(discovery.routes.auth).toBe('/api/v1/auth');
|
|
129
|
-
expect(discovery.routes.automation).toBe('/api/v1/automation');
|
|
130
|
-
expect(discovery.routes.ai).toBe('/api/v1/ai');
|
|
131
|
-
expect(discovery.routes.analytics).toBe('/api/v1/analytics');
|
|
132
|
-
|
|
133
|
-
// Service routes should match the routes map
|
|
134
|
-
expect(discovery.services.data.route).toBe('/api/v1/data');
|
|
135
|
-
expect(discovery.services.metadata.route).toBe('/api/v1/meta');
|
|
136
|
-
expect(discovery.services.auth.route).toBe('/api/v1/auth');
|
|
137
|
-
expect(discovery.services.analytics.route).toBe('/api/v1/analytics');
|
|
138
|
-
});
|
|
139
|
-
|
|
140
|
-
it('should return capabilities field populated from registered services', async () => {
|
|
141
|
-
const mockServices = new Map<string, any>();
|
|
142
|
-
mockServices.set('workflow', {});
|
|
143
|
-
|
|
144
|
-
protocol = new ObjectStackProtocolImplementation(engine, () => mockServices);
|
|
145
|
-
const discovery = await protocol.getDiscovery();
|
|
146
|
-
|
|
147
|
-
// capabilities field should now exist in the response
|
|
148
|
-
expect(discovery.capabilities).toBeDefined();
|
|
149
|
-
// workflow is registered but doesn't map to a well-known capability directly
|
|
150
|
-
expect(discovery.services.workflow.enabled).toBe(true);
|
|
151
|
-
// All well-known capabilities should be disabled since workflow doesn't map to any
|
|
152
|
-
expect(discovery.capabilities!.feed).toEqual({ enabled: false });
|
|
153
|
-
expect(discovery.capabilities!.comments).toEqual({ enabled: false });
|
|
154
|
-
expect(discovery.capabilities!.automation).toEqual({ enabled: false });
|
|
155
|
-
expect(discovery.capabilities!.cron).toEqual({ enabled: false });
|
|
156
|
-
expect(discovery.capabilities!.search).toEqual({ enabled: false });
|
|
157
|
-
expect(discovery.capabilities!.export).toEqual({ enabled: false });
|
|
158
|
-
expect(discovery.capabilities!.chunkedUpload).toEqual({ enabled: false });
|
|
159
|
-
});
|
|
160
|
-
|
|
161
|
-
it('should set all capabilities to false when no services are registered', async () => {
|
|
162
|
-
protocol = new ObjectStackProtocolImplementation(engine);
|
|
163
|
-
const discovery = await protocol.getDiscovery();
|
|
164
|
-
|
|
165
|
-
expect(discovery.capabilities).toBeDefined();
|
|
166
|
-
expect(discovery.capabilities!.feed).toEqual({ enabled: false });
|
|
167
|
-
expect(discovery.capabilities!.comments).toEqual({ enabled: false });
|
|
168
|
-
expect(discovery.capabilities!.automation).toEqual({ enabled: false });
|
|
169
|
-
expect(discovery.capabilities!.cron).toEqual({ enabled: false });
|
|
170
|
-
expect(discovery.capabilities!.search).toEqual({ enabled: false });
|
|
171
|
-
expect(discovery.capabilities!.export).toEqual({ enabled: false });
|
|
172
|
-
expect(discovery.capabilities!.chunkedUpload).toEqual({ enabled: false });
|
|
173
|
-
});
|
|
174
|
-
|
|
175
|
-
it('should dynamically set capabilities based on registered services', async () => {
|
|
176
|
-
const mockServices = new Map<string, any>();
|
|
177
|
-
mockServices.set('feed', {});
|
|
178
|
-
mockServices.set('automation', {});
|
|
179
|
-
mockServices.set('search', {});
|
|
180
|
-
mockServices.set('file-storage', {});
|
|
181
|
-
|
|
182
|
-
protocol = new ObjectStackProtocolImplementation(engine, () => mockServices);
|
|
183
|
-
const discovery = await protocol.getDiscovery();
|
|
184
|
-
|
|
185
|
-
expect(discovery.capabilities!.feed).toEqual({ enabled: true });
|
|
186
|
-
expect(discovery.capabilities!.comments).toEqual({ enabled: true });
|
|
187
|
-
expect(discovery.capabilities!.automation).toEqual({ enabled: true });
|
|
188
|
-
expect(discovery.capabilities!.cron).toEqual({ enabled: false });
|
|
189
|
-
expect(discovery.capabilities!.search).toEqual({ enabled: true });
|
|
190
|
-
expect(discovery.capabilities!.export).toEqual({ enabled: true });
|
|
191
|
-
expect(discovery.capabilities!.chunkedUpload).toEqual({ enabled: true });
|
|
192
|
-
});
|
|
193
|
-
|
|
194
|
-
it('should enable cron capability when job service is registered', async () => {
|
|
195
|
-
const mockServices = new Map<string, any>();
|
|
196
|
-
mockServices.set('job', {});
|
|
197
|
-
|
|
198
|
-
protocol = new ObjectStackProtocolImplementation(engine, () => mockServices);
|
|
199
|
-
const discovery = await protocol.getDiscovery();
|
|
200
|
-
|
|
201
|
-
expect(discovery.capabilities!.cron).toEqual({ enabled: true });
|
|
202
|
-
});
|
|
203
|
-
|
|
204
|
-
it('should enable export capability when queue service is registered', async () => {
|
|
205
|
-
const mockServices = new Map<string, any>();
|
|
206
|
-
mockServices.set('queue', {});
|
|
207
|
-
|
|
208
|
-
protocol = new ObjectStackProtocolImplementation(engine, () => mockServices);
|
|
209
|
-
const discovery = await protocol.getDiscovery();
|
|
210
|
-
|
|
211
|
-
expect(discovery.capabilities!.export).toEqual({ enabled: true });
|
|
212
|
-
});
|
|
213
|
-
});
|