@opencontextprotocol/agent 0.1.0
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/LICENSE +21 -0
- package/README.md +198 -0
- package/dist/src/agent.d.ts +112 -0
- package/dist/src/agent.d.ts.map +1 -0
- package/dist/src/agent.js +358 -0
- package/dist/src/agent.js.map +1 -0
- package/dist/src/context.d.ts +108 -0
- package/dist/src/context.d.ts.map +1 -0
- package/dist/src/context.js +196 -0
- package/dist/src/context.js.map +1 -0
- package/dist/src/errors.d.ts +40 -0
- package/dist/src/errors.d.ts.map +1 -0
- package/dist/src/errors.js +63 -0
- package/dist/src/errors.js.map +1 -0
- package/dist/src/headers.d.ts +63 -0
- package/dist/src/headers.d.ts.map +1 -0
- package/dist/src/headers.js +238 -0
- package/dist/src/headers.js.map +1 -0
- package/dist/src/http_client.d.ts +82 -0
- package/dist/src/http_client.d.ts.map +1 -0
- package/dist/src/http_client.js +181 -0
- package/dist/src/http_client.js.map +1 -0
- package/dist/src/index.d.ts +25 -0
- package/dist/src/index.d.ts.map +1 -0
- package/dist/src/index.js +35 -0
- package/dist/src/index.js.map +1 -0
- package/dist/src/registry.d.ts +52 -0
- package/dist/src/registry.d.ts.map +1 -0
- package/dist/src/registry.js +164 -0
- package/dist/src/registry.js.map +1 -0
- package/dist/src/schema_discovery.d.ts +149 -0
- package/dist/src/schema_discovery.d.ts.map +1 -0
- package/dist/src/schema_discovery.js +707 -0
- package/dist/src/schema_discovery.js.map +1 -0
- package/dist/src/schemas/ocp-context.json +138 -0
- package/dist/src/storage.d.ts +110 -0
- package/dist/src/storage.d.ts.map +1 -0
- package/dist/src/storage.js +399 -0
- package/dist/src/storage.js.map +1 -0
- package/dist/src/validation.d.ts +169 -0
- package/dist/src/validation.d.ts.map +1 -0
- package/dist/src/validation.js +92 -0
- package/dist/src/validation.js.map +1 -0
- package/dist/tests/agent.test.d.ts +5 -0
- package/dist/tests/agent.test.d.ts.map +1 -0
- package/dist/tests/agent.test.js +536 -0
- package/dist/tests/agent.test.js.map +1 -0
- package/dist/tests/context.test.d.ts +5 -0
- package/dist/tests/context.test.d.ts.map +1 -0
- package/dist/tests/context.test.js +285 -0
- package/dist/tests/context.test.js.map +1 -0
- package/dist/tests/headers.test.d.ts +5 -0
- package/dist/tests/headers.test.d.ts.map +1 -0
- package/dist/tests/headers.test.js +356 -0
- package/dist/tests/headers.test.js.map +1 -0
- package/dist/tests/http_client.test.d.ts +5 -0
- package/dist/tests/http_client.test.d.ts.map +1 -0
- package/dist/tests/http_client.test.js +373 -0
- package/dist/tests/http_client.test.js.map +1 -0
- package/dist/tests/registry.test.d.ts +5 -0
- package/dist/tests/registry.test.d.ts.map +1 -0
- package/dist/tests/registry.test.js +232 -0
- package/dist/tests/registry.test.js.map +1 -0
- package/dist/tests/schema_discovery.test.d.ts +5 -0
- package/dist/tests/schema_discovery.test.d.ts.map +1 -0
- package/dist/tests/schema_discovery.test.js +1074 -0
- package/dist/tests/schema_discovery.test.js.map +1 -0
- package/dist/tests/storage.test.d.ts +5 -0
- package/dist/tests/storage.test.d.ts.map +1 -0
- package/dist/tests/storage.test.js +414 -0
- package/dist/tests/storage.test.js.map +1 -0
- package/dist/tests/validation.test.d.ts +5 -0
- package/dist/tests/validation.test.d.ts.map +1 -0
- package/dist/tests/validation.test.js +254 -0
- package/dist/tests/validation.test.js.map +1 -0
- package/package.json +51 -0
|
@@ -0,0 +1,373 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tests for OCP HTTP client functionality.
|
|
3
|
+
*/
|
|
4
|
+
import { describe, test, expect, beforeEach, jest } from '@jest/globals';
|
|
5
|
+
import { OCPHTTPClient, _wrapApi } from '../src/http_client.js';
|
|
6
|
+
import { AgentContext } from '../src/context.js';
|
|
7
|
+
import { createOCPHeaders } from '../src/headers.js';
|
|
8
|
+
// Mock fetch globally
|
|
9
|
+
global.fetch = jest.fn();
|
|
10
|
+
describe('OCP HTTP Client', () => {
|
|
11
|
+
let context;
|
|
12
|
+
beforeEach(() => {
|
|
13
|
+
context = new AgentContext({ agent_type: 'test_agent', user: 'test_user' });
|
|
14
|
+
context.updateGoal('testing http client');
|
|
15
|
+
jest.clearAllMocks();
|
|
16
|
+
});
|
|
17
|
+
describe('OCPHTTPClient Initialization', () => {
|
|
18
|
+
test('init without http client', () => {
|
|
19
|
+
const ocpClient = new OCPHTTPClient(context);
|
|
20
|
+
expect(ocpClient['context']).toBe(context);
|
|
21
|
+
expect(ocpClient['context'].agent_type).toBe('test_agent');
|
|
22
|
+
});
|
|
23
|
+
test('init auto update context false', () => {
|
|
24
|
+
// Note: JavaScript implementation doesn't have auto_update_context parameter yet
|
|
25
|
+
// This test would need to be updated if that feature is added
|
|
26
|
+
const ocpClient = new OCPHTTPClient(context);
|
|
27
|
+
expect(ocpClient).toBeDefined();
|
|
28
|
+
});
|
|
29
|
+
});
|
|
30
|
+
describe('Header Preparation', () => {
|
|
31
|
+
test('prepare headers no existing', () => {
|
|
32
|
+
const ocpClient = new OCPHTTPClient(context);
|
|
33
|
+
const headers = ocpClient['_prepareHeaders']();
|
|
34
|
+
// Should include OCP headers
|
|
35
|
+
const expectedHeaders = createOCPHeaders(context);
|
|
36
|
+
expect(headers).toEqual(expectedHeaders);
|
|
37
|
+
});
|
|
38
|
+
test('prepare headers with existing', () => {
|
|
39
|
+
const ocpClient = new OCPHTTPClient(context);
|
|
40
|
+
const existingHeaders = { 'Custom-Header': 'value', 'Authorization': 'Bearer token' };
|
|
41
|
+
const headers = ocpClient['_prepareHeaders'](existingHeaders);
|
|
42
|
+
// Should merge existing and OCP headers
|
|
43
|
+
const expectedHeaders = createOCPHeaders(context);
|
|
44
|
+
Object.assign(expectedHeaders, existingHeaders);
|
|
45
|
+
expect(headers).toEqual(expectedHeaders);
|
|
46
|
+
});
|
|
47
|
+
test('prepare headers override ocp', () => {
|
|
48
|
+
const ocpClient = new OCPHTTPClient(context);
|
|
49
|
+
// Get OCP headers to know what to override
|
|
50
|
+
const ocpHeaders = createOCPHeaders(context);
|
|
51
|
+
const ocpHeaderKey = Object.keys(ocpHeaders)[0];
|
|
52
|
+
const existingHeaders = { [ocpHeaderKey]: 'overridden_value' };
|
|
53
|
+
const headers = ocpClient['_prepareHeaders'](existingHeaders);
|
|
54
|
+
// OCP header should actually override existing header (based on implementation)
|
|
55
|
+
// The implementation does: {...ocpHeaders, ...additionalHeaders} which means additional wins
|
|
56
|
+
expect(headers[ocpHeaderKey]).toBe('overridden_value');
|
|
57
|
+
});
|
|
58
|
+
});
|
|
59
|
+
describe('Interaction Logging', () => {
|
|
60
|
+
test('log interaction enabled', () => {
|
|
61
|
+
const ocpClient = new OCPHTTPClient(context);
|
|
62
|
+
// Mock the context.addInteraction method
|
|
63
|
+
const addInteractionSpy = jest.spyOn(context, 'addInteraction');
|
|
64
|
+
// Call private method
|
|
65
|
+
const mockResponse = { status: 200 };
|
|
66
|
+
ocpClient['_logInteraction']('GET', 'https://api.example.com/users', mockResponse);
|
|
67
|
+
// Should log interaction
|
|
68
|
+
expect(addInteractionSpy).toHaveBeenCalledWith('api_call_get', 'GET /users', 'HTTP 200', {
|
|
69
|
+
method: 'GET',
|
|
70
|
+
url: 'https://api.example.com/users',
|
|
71
|
+
domain: 'api.example.com',
|
|
72
|
+
status_code: 200,
|
|
73
|
+
success: true,
|
|
74
|
+
});
|
|
75
|
+
addInteractionSpy.mockRestore();
|
|
76
|
+
});
|
|
77
|
+
test('log interaction disabled', () => {
|
|
78
|
+
// Test with auto_update_context disabled
|
|
79
|
+
const ocpClient = new OCPHTTPClient(context, false);
|
|
80
|
+
const addInteractionSpy = jest.spyOn(context, 'addInteraction');
|
|
81
|
+
ocpClient['_logInteraction']('POST', 'https://api.example.com/data', undefined);
|
|
82
|
+
// Should not log when disabled
|
|
83
|
+
expect(addInteractionSpy).not.toHaveBeenCalled();
|
|
84
|
+
addInteractionSpy.mockRestore();
|
|
85
|
+
});
|
|
86
|
+
test('log interaction different status formats', () => {
|
|
87
|
+
const ocpClient = new OCPHTTPClient(context);
|
|
88
|
+
const addInteractionSpy = jest.spyOn(context, 'addInteraction');
|
|
89
|
+
// Test with status code
|
|
90
|
+
const mock404Response = { status: 404 };
|
|
91
|
+
ocpClient['_logInteraction']('GET', 'https://api.example.com/missing', mock404Response);
|
|
92
|
+
// Test with different status
|
|
93
|
+
const mock201Response = { status: 201 };
|
|
94
|
+
ocpClient['_logInteraction']('POST', 'https://api.example.com/create', mock201Response);
|
|
95
|
+
// Test with undefined
|
|
96
|
+
ocpClient['_logInteraction']('PUT', 'https://api.example.com/update', undefined);
|
|
97
|
+
// Verify calls
|
|
98
|
+
expect(addInteractionSpy).toHaveBeenNthCalledWith(1, 'api_call_get', 'GET /missing', 'HTTP 404', {
|
|
99
|
+
method: 'GET',
|
|
100
|
+
url: 'https://api.example.com/missing',
|
|
101
|
+
domain: 'api.example.com',
|
|
102
|
+
status_code: 404,
|
|
103
|
+
success: false,
|
|
104
|
+
});
|
|
105
|
+
expect(addInteractionSpy).toHaveBeenNthCalledWith(2, 'api_call_post', 'POST /create', 'HTTP 201', {
|
|
106
|
+
method: 'POST',
|
|
107
|
+
url: 'https://api.example.com/create',
|
|
108
|
+
domain: 'api.example.com',
|
|
109
|
+
status_code: 201,
|
|
110
|
+
success: true,
|
|
111
|
+
});
|
|
112
|
+
expect(addInteractionSpy).toHaveBeenNthCalledWith(3, 'api_call_put', 'PUT /update', undefined, {
|
|
113
|
+
method: 'PUT',
|
|
114
|
+
url: 'https://api.example.com/update',
|
|
115
|
+
domain: 'api.example.com',
|
|
116
|
+
success: false,
|
|
117
|
+
});
|
|
118
|
+
addInteractionSpy.mockRestore();
|
|
119
|
+
});
|
|
120
|
+
});
|
|
121
|
+
describe('Request Method', () => {
|
|
122
|
+
test('request method', async () => {
|
|
123
|
+
const ocpClient = new OCPHTTPClient(context);
|
|
124
|
+
// Mock fetch response
|
|
125
|
+
const mockResponse = {
|
|
126
|
+
status: 200,
|
|
127
|
+
statusText: 'OK',
|
|
128
|
+
ok: true,
|
|
129
|
+
headers: new Headers(),
|
|
130
|
+
text: async () => JSON.stringify({ success: true }),
|
|
131
|
+
};
|
|
132
|
+
global.fetch.mockResolvedValue(mockResponse);
|
|
133
|
+
// Mock context interaction (without calling the real method)
|
|
134
|
+
const addInteractionMock = jest.fn();
|
|
135
|
+
const originalAddInteraction = context.addInteraction;
|
|
136
|
+
context.addInteraction = addInteractionMock;
|
|
137
|
+
// Make request
|
|
138
|
+
const result = await ocpClient.request('GET', 'https://api.example.com/test', {
|
|
139
|
+
params: { q: 'search' },
|
|
140
|
+
timeout: 30000,
|
|
141
|
+
});
|
|
142
|
+
// Verify fetch was called
|
|
143
|
+
expect(global.fetch).toHaveBeenCalledTimes(1);
|
|
144
|
+
const fetchCall = global.fetch.mock.calls[0];
|
|
145
|
+
// Check URL has query params
|
|
146
|
+
expect(fetchCall[0].toString()).toContain('q=search');
|
|
147
|
+
// Check options
|
|
148
|
+
expect(fetchCall[1]?.method).toBe('GET');
|
|
149
|
+
expect(fetchCall[1]?.headers).toBeDefined();
|
|
150
|
+
// Verify OCP headers were added
|
|
151
|
+
const headers = fetchCall[1]?.headers;
|
|
152
|
+
const expectedOcpHeaders = createOCPHeaders(context);
|
|
153
|
+
for (const [key, value] of Object.entries(expectedOcpHeaders)) {
|
|
154
|
+
expect(headers[key]).toBe(value);
|
|
155
|
+
}
|
|
156
|
+
// Verify interaction was logged
|
|
157
|
+
expect(addInteractionMock).toHaveBeenCalledTimes(1);
|
|
158
|
+
// Verify response was returned
|
|
159
|
+
expect(result.status).toBe(200);
|
|
160
|
+
// Restore original method
|
|
161
|
+
context.addInteraction = originalAddInteraction;
|
|
162
|
+
});
|
|
163
|
+
});
|
|
164
|
+
describe('HTTP Methods', () => {
|
|
165
|
+
test('http methods', async () => {
|
|
166
|
+
const ocpClient = new OCPHTTPClient(context);
|
|
167
|
+
const mockResponse = {
|
|
168
|
+
status: 200,
|
|
169
|
+
statusText: 'OK',
|
|
170
|
+
ok: true,
|
|
171
|
+
headers: new Headers(),
|
|
172
|
+
text: async () => '{}',
|
|
173
|
+
};
|
|
174
|
+
global.fetch.mockResolvedValue(mockResponse);
|
|
175
|
+
// Test each HTTP method
|
|
176
|
+
const methods = [
|
|
177
|
+
['get', 'GET'],
|
|
178
|
+
['post', 'POST'],
|
|
179
|
+
['put', 'PUT'],
|
|
180
|
+
['delete', 'DELETE'],
|
|
181
|
+
['patch', 'PATCH'],
|
|
182
|
+
];
|
|
183
|
+
for (const [methodName, httpMethod] of methods) {
|
|
184
|
+
global.fetch.mockClear();
|
|
185
|
+
const methodFunc = ocpClient[methodName];
|
|
186
|
+
await methodFunc.call(ocpClient, 'https://api.example.com/endpoint', {
|
|
187
|
+
json: { test: 'data' },
|
|
188
|
+
});
|
|
189
|
+
// Verify correct HTTP method was used
|
|
190
|
+
expect(global.fetch).toHaveBeenCalledTimes(1);
|
|
191
|
+
const fetchCall = global.fetch.mock.calls[0];
|
|
192
|
+
expect(fetchCall[1]?.method).toBe(httpMethod);
|
|
193
|
+
}
|
|
194
|
+
});
|
|
195
|
+
});
|
|
196
|
+
});
|
|
197
|
+
describe('Wrap API', () => {
|
|
198
|
+
let context;
|
|
199
|
+
beforeEach(() => {
|
|
200
|
+
context = new AgentContext({ agent_type: 'test_agent' });
|
|
201
|
+
jest.clearAllMocks();
|
|
202
|
+
});
|
|
203
|
+
test('wrap api basic', () => {
|
|
204
|
+
const apiClient = _wrapApi('https://api.example.com', context);
|
|
205
|
+
expect(apiClient).toBeDefined();
|
|
206
|
+
expect(apiClient.request).toBeDefined();
|
|
207
|
+
});
|
|
208
|
+
test('wrap api with auth token', () => {
|
|
209
|
+
const apiClient = _wrapApi('https://api.github.com', context, { 'Authorization': 'token ghp_123456' });
|
|
210
|
+
expect(apiClient).toBeDefined();
|
|
211
|
+
});
|
|
212
|
+
test('wrap api with bearer token', () => {
|
|
213
|
+
const apiClient = _wrapApi('https://api.example.com', context, { 'Authorization': 'Bearer jwt_token_here' });
|
|
214
|
+
expect(apiClient).toBeDefined();
|
|
215
|
+
});
|
|
216
|
+
test('wrap api with basic auth', () => {
|
|
217
|
+
const apiClient = _wrapApi('https://api.example.com', context, { 'Authorization': 'Basic dXNlcjpwYXNz' });
|
|
218
|
+
expect(apiClient).toBeDefined();
|
|
219
|
+
});
|
|
220
|
+
test('wrap api with plain token', () => {
|
|
221
|
+
const apiClient = _wrapApi('https://api.example.com', context, { 'Authorization': 'token abc123def456' });
|
|
222
|
+
expect(apiClient).toBeDefined();
|
|
223
|
+
});
|
|
224
|
+
test('wrap api with custom headers', () => {
|
|
225
|
+
const customHeaders = {
|
|
226
|
+
'User-Agent': 'MyApp/1.0',
|
|
227
|
+
'Accept': 'application/vnd.api+json',
|
|
228
|
+
};
|
|
229
|
+
const apiClient = _wrapApi('https://api.example.com', context, customHeaders);
|
|
230
|
+
expect(apiClient).toBeDefined();
|
|
231
|
+
});
|
|
232
|
+
test('wrap api base url normalization', () => {
|
|
233
|
+
// Test trailing slash removal - this is implementation dependent
|
|
234
|
+
const apiClient = _wrapApi('https://api.example.com/', context);
|
|
235
|
+
expect(apiClient).toBeDefined();
|
|
236
|
+
});
|
|
237
|
+
test('wrap api relative url handling', async () => {
|
|
238
|
+
const apiClient = _wrapApi('https://api.example.com', context);
|
|
239
|
+
const mockResponse = {
|
|
240
|
+
status: 200,
|
|
241
|
+
statusText: 'OK',
|
|
242
|
+
ok: true,
|
|
243
|
+
headers: new Headers(),
|
|
244
|
+
text: async () => '{}',
|
|
245
|
+
};
|
|
246
|
+
global.fetch.mockResolvedValue(mockResponse);
|
|
247
|
+
// Test relative URL
|
|
248
|
+
await apiClient.request('GET', '/users');
|
|
249
|
+
// Verify full URL was constructed
|
|
250
|
+
expect(global.fetch).toHaveBeenCalledTimes(1);
|
|
251
|
+
const fetchCall = global.fetch.mock.calls[0];
|
|
252
|
+
expect(fetchCall[0].toString()).toContain('https://api.example.com/users');
|
|
253
|
+
});
|
|
254
|
+
test('wrap api absolute url handling', async () => {
|
|
255
|
+
const apiClient = _wrapApi('https://api.example.com', context);
|
|
256
|
+
const mockResponse = {
|
|
257
|
+
status: 200,
|
|
258
|
+
statusText: 'OK',
|
|
259
|
+
ok: true,
|
|
260
|
+
headers: new Headers(),
|
|
261
|
+
text: async () => '{}',
|
|
262
|
+
};
|
|
263
|
+
global.fetch.mockResolvedValue(mockResponse);
|
|
264
|
+
// Test absolute URL
|
|
265
|
+
await apiClient.request('POST', 'https://other-api.com/webhook');
|
|
266
|
+
// Verify URL was passed through unchanged
|
|
267
|
+
const fetchCall = global.fetch.mock.calls[0];
|
|
268
|
+
expect(fetchCall[0].toString()).toContain('https://other-api.com/webhook');
|
|
269
|
+
});
|
|
270
|
+
});
|
|
271
|
+
describe('HTTP Client Integration', () => {
|
|
272
|
+
beforeEach(() => {
|
|
273
|
+
jest.clearAllMocks();
|
|
274
|
+
});
|
|
275
|
+
test('end to end workflow', async () => {
|
|
276
|
+
// Create context
|
|
277
|
+
const context = new AgentContext({
|
|
278
|
+
agent_type: 'integration_test',
|
|
279
|
+
user: 'tester',
|
|
280
|
+
});
|
|
281
|
+
context.updateGoal('test full workflow');
|
|
282
|
+
// Setup mock response
|
|
283
|
+
const mockResponse = {
|
|
284
|
+
status: 200,
|
|
285
|
+
statusText: 'OK',
|
|
286
|
+
ok: true,
|
|
287
|
+
headers: new Headers(),
|
|
288
|
+
text: async () => JSON.stringify({ success: true }),
|
|
289
|
+
};
|
|
290
|
+
global.fetch.mockResolvedValue(mockResponse);
|
|
291
|
+
// Create OCP client
|
|
292
|
+
const client = new OCPHTTPClient(context);
|
|
293
|
+
// Mock context interaction (without calling the real method)
|
|
294
|
+
const addInteractionMock = jest.fn();
|
|
295
|
+
const originalAddInteraction = context.addInteraction;
|
|
296
|
+
context.addInteraction = addInteractionMock;
|
|
297
|
+
// Make request
|
|
298
|
+
const response = await client.get('https://api.example.com/users', {
|
|
299
|
+
params: { page: 1, limit: 10 },
|
|
300
|
+
});
|
|
301
|
+
// Verify fetch was called correctly
|
|
302
|
+
expect(global.fetch).toHaveBeenCalledTimes(1);
|
|
303
|
+
const fetchCall = global.fetch.mock.calls[0];
|
|
304
|
+
expect(fetchCall[0].toString()).toContain('https://api.example.com/users');
|
|
305
|
+
expect(fetchCall[0].toString()).toContain('page=1');
|
|
306
|
+
expect(fetchCall[0].toString()).toContain('limit=10');
|
|
307
|
+
// Verify OCP headers were included
|
|
308
|
+
const headers = fetchCall[1]?.headers;
|
|
309
|
+
const expectedHeaders = createOCPHeaders(context);
|
|
310
|
+
for (const [key, value] of Object.entries(expectedHeaders)) {
|
|
311
|
+
expect(headers[key]).toBe(value);
|
|
312
|
+
}
|
|
313
|
+
// Verify interaction was logged
|
|
314
|
+
expect(addInteractionMock).toHaveBeenCalledTimes(1);
|
|
315
|
+
const interactionCall = addInteractionMock.mock.calls[0];
|
|
316
|
+
expect(interactionCall[0]).toBe('api_call_get');
|
|
317
|
+
expect(interactionCall[1]).toBe('GET /users');
|
|
318
|
+
expect(interactionCall[2]).toBe('HTTP 200');
|
|
319
|
+
// Verify response
|
|
320
|
+
expect(response.status).toBe(200);
|
|
321
|
+
// Restore original method
|
|
322
|
+
context.addInteraction = originalAddInteraction;
|
|
323
|
+
});
|
|
324
|
+
test('multiple requests context tracking', async () => {
|
|
325
|
+
const context = new AgentContext({ agent_type: 'multi_test' });
|
|
326
|
+
// Create responses for different requests
|
|
327
|
+
const responses = [
|
|
328
|
+
{
|
|
329
|
+
status: 200,
|
|
330
|
+
statusText: 'OK',
|
|
331
|
+
ok: true,
|
|
332
|
+
headers: new Headers(),
|
|
333
|
+
text: async () => '{}',
|
|
334
|
+
},
|
|
335
|
+
{
|
|
336
|
+
status: 201,
|
|
337
|
+
statusText: 'Created',
|
|
338
|
+
ok: true,
|
|
339
|
+
headers: new Headers(),
|
|
340
|
+
text: async () => '{}',
|
|
341
|
+
},
|
|
342
|
+
{
|
|
343
|
+
status: 404,
|
|
344
|
+
statusText: 'Not Found',
|
|
345
|
+
ok: false,
|
|
346
|
+
headers: new Headers(),
|
|
347
|
+
text: async () => '{}',
|
|
348
|
+
},
|
|
349
|
+
];
|
|
350
|
+
global.fetch
|
|
351
|
+
.mockResolvedValueOnce(responses[0])
|
|
352
|
+
.mockResolvedValueOnce(responses[1])
|
|
353
|
+
.mockResolvedValueOnce(responses[2]);
|
|
354
|
+
const client = new OCPHTTPClient(context);
|
|
355
|
+
const addInteractionSpy = jest.spyOn(context, 'addInteraction');
|
|
356
|
+
// Make multiple requests
|
|
357
|
+
await client.get('https://api.example.com/users');
|
|
358
|
+
await client.post('https://api.example.com/users', { json: { name: 'test' } });
|
|
359
|
+
await client.delete('https://api.example.com/users/999');
|
|
360
|
+
// Verify all interactions were logged
|
|
361
|
+
expect(addInteractionSpy).toHaveBeenCalledTimes(3);
|
|
362
|
+
// Check interaction details
|
|
363
|
+
const calls = addInteractionSpy.mock.calls;
|
|
364
|
+
expect(calls[0][0]).toBe('api_call_get');
|
|
365
|
+
expect(calls[0][2]).toBe('HTTP 200');
|
|
366
|
+
expect(calls[1][0]).toBe('api_call_post');
|
|
367
|
+
expect(calls[1][2]).toBe('HTTP 201');
|
|
368
|
+
expect(calls[2][0]).toBe('api_call_delete');
|
|
369
|
+
expect(calls[2][2]).toBe('HTTP 404');
|
|
370
|
+
addInteractionSpy.mockRestore();
|
|
371
|
+
});
|
|
372
|
+
});
|
|
373
|
+
//# sourceMappingURL=http_client.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"http_client.test.js","sourceRoot":"","sources":["../../tests/http_client.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"registry.test.d.ts","sourceRoot":"","sources":["../../tests/registry.test.ts"],"names":[],"mappings":"AAAA;;GAEG"}
|
|
@@ -0,0 +1,232 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tests for OCP Registry functionality.
|
|
3
|
+
*/
|
|
4
|
+
import { describe, test, expect, beforeEach, afterEach, jest } from '@jest/globals';
|
|
5
|
+
import { OCPRegistry } from '../src/registry.js';
|
|
6
|
+
import { RegistryUnavailable, APINotFound } from '../src/errors.js';
|
|
7
|
+
// Mock fetch globally
|
|
8
|
+
global.fetch = jest.fn();
|
|
9
|
+
describe('OCP Registry', () => {
|
|
10
|
+
let originalEnv;
|
|
11
|
+
beforeEach(() => {
|
|
12
|
+
jest.clearAllMocks();
|
|
13
|
+
// Save original environment
|
|
14
|
+
originalEnv = { ...process.env };
|
|
15
|
+
});
|
|
16
|
+
afterEach(() => {
|
|
17
|
+
// Restore original environment
|
|
18
|
+
process.env = originalEnv;
|
|
19
|
+
});
|
|
20
|
+
const sampleApiEntry = {
|
|
21
|
+
name: 'httpbin',
|
|
22
|
+
display_name: 'HTTPBin Testing Service',
|
|
23
|
+
description: 'HTTP testing service',
|
|
24
|
+
openapi_url: 'https://httpbin.org/spec.json',
|
|
25
|
+
base_url: 'https://httpbin.org/',
|
|
26
|
+
category: 'development',
|
|
27
|
+
auth_config: {
|
|
28
|
+
type: 'none',
|
|
29
|
+
header_name: null,
|
|
30
|
+
instructions: 'No authentication required',
|
|
31
|
+
},
|
|
32
|
+
tags: ['testing', 'debugging'],
|
|
33
|
+
tool_count: 2,
|
|
34
|
+
tools: [
|
|
35
|
+
{
|
|
36
|
+
name: 'get_get',
|
|
37
|
+
description: 'Returns GET request data',
|
|
38
|
+
method: 'GET',
|
|
39
|
+
path: '/get',
|
|
40
|
+
parameters: {},
|
|
41
|
+
response_schema: {},
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
name: 'post_post',
|
|
45
|
+
description: 'Returns POST request data',
|
|
46
|
+
method: 'POST',
|
|
47
|
+
path: '/post',
|
|
48
|
+
parameters: {},
|
|
49
|
+
response_schema: {},
|
|
50
|
+
},
|
|
51
|
+
],
|
|
52
|
+
};
|
|
53
|
+
describe('Registry Initialization', () => {
|
|
54
|
+
test('init default url', () => {
|
|
55
|
+
const registry = new OCPRegistry();
|
|
56
|
+
expect(registry.registryUrl).toBe('https://opencontextprotocol.io/api/v1');
|
|
57
|
+
});
|
|
58
|
+
test('init custom url', () => {
|
|
59
|
+
const registry = new OCPRegistry('https://custom-registry.com');
|
|
60
|
+
expect(registry.registryUrl).toBe('https://custom-registry.com');
|
|
61
|
+
});
|
|
62
|
+
test('init env var', () => {
|
|
63
|
+
process.env.OCP_REGISTRY_URL = 'https://env-registry.com';
|
|
64
|
+
const registry = new OCPRegistry();
|
|
65
|
+
expect(registry.registryUrl).toBe('https://env-registry.com');
|
|
66
|
+
});
|
|
67
|
+
test('init invalid url', () => {
|
|
68
|
+
expect(() => new OCPRegistry('invalid-url')).toThrow('Invalid registry URL');
|
|
69
|
+
});
|
|
70
|
+
});
|
|
71
|
+
describe('Get API Spec', () => {
|
|
72
|
+
test('get api spec success', async () => {
|
|
73
|
+
const registry = new OCPRegistry('https://test-registry.ocp.dev');
|
|
74
|
+
// Mock fetch
|
|
75
|
+
global.fetch.mockResolvedValue({
|
|
76
|
+
ok: true,
|
|
77
|
+
status: 200,
|
|
78
|
+
json: async () => sampleApiEntry,
|
|
79
|
+
});
|
|
80
|
+
const apiSpec = await registry.getApiSpec('httpbin');
|
|
81
|
+
expect(apiSpec.title).toBe('HTTPBin Testing Service');
|
|
82
|
+
expect(apiSpec.base_url).toBe('https://httpbin.org/');
|
|
83
|
+
expect(apiSpec.tools.length).toBe(2);
|
|
84
|
+
expect(apiSpec.tools[0].name).toBe('get_get');
|
|
85
|
+
expect(apiSpec.tools[1].name).toBe('post_post');
|
|
86
|
+
});
|
|
87
|
+
test('get api spec with base url override', async () => {
|
|
88
|
+
const registry = new OCPRegistry('https://test-registry.ocp.dev');
|
|
89
|
+
global.fetch.mockResolvedValue({
|
|
90
|
+
ok: true,
|
|
91
|
+
status: 200,
|
|
92
|
+
json: async () => sampleApiEntry,
|
|
93
|
+
});
|
|
94
|
+
const apiSpec = await registry.getApiSpec('httpbin', 'https://custom.httpbin.org');
|
|
95
|
+
expect(apiSpec.base_url).toBe('https://custom.httpbin.org');
|
|
96
|
+
});
|
|
97
|
+
test('get api spec not found', async () => {
|
|
98
|
+
const registry = new OCPRegistry('https://test-registry.ocp.dev');
|
|
99
|
+
let callCount = 0;
|
|
100
|
+
global.fetch.mockImplementation(async (url) => {
|
|
101
|
+
callCount++;
|
|
102
|
+
if (callCount === 1) {
|
|
103
|
+
// First call: API not found
|
|
104
|
+
return {
|
|
105
|
+
ok: false,
|
|
106
|
+
status: 404,
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
else {
|
|
110
|
+
// Second call: Search returns suggestions
|
|
111
|
+
return {
|
|
112
|
+
ok: true,
|
|
113
|
+
status: 200,
|
|
114
|
+
json: async () => ({ results: [{ name: 'httpbin' }] }),
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
});
|
|
118
|
+
await expect(registry.getApiSpec('nonexistent')).rejects.toThrow(APINotFound);
|
|
119
|
+
try {
|
|
120
|
+
await registry.getApiSpec('nonexistent');
|
|
121
|
+
}
|
|
122
|
+
catch (error) {
|
|
123
|
+
expect(error.apiName).toBe('nonexistent');
|
|
124
|
+
expect(error.suggestions).toContain('httpbin');
|
|
125
|
+
}
|
|
126
|
+
});
|
|
127
|
+
test('get api spec registry unavailable', async () => {
|
|
128
|
+
const registry = new OCPRegistry('https://test-registry.ocp.dev');
|
|
129
|
+
global.fetch.mockRejectedValue(new Error('Connection failed'));
|
|
130
|
+
await expect(registry.getApiSpec('httpbin')).rejects.toThrow(RegistryUnavailable);
|
|
131
|
+
try {
|
|
132
|
+
await registry.getApiSpec('httpbin');
|
|
133
|
+
}
|
|
134
|
+
catch (error) {
|
|
135
|
+
expect(error.registryUrl).toContain('test-registry.ocp.dev');
|
|
136
|
+
}
|
|
137
|
+
});
|
|
138
|
+
});
|
|
139
|
+
describe('Search APIs', () => {
|
|
140
|
+
test('search apis success', async () => {
|
|
141
|
+
const registry = new OCPRegistry('https://test-registry.ocp.dev');
|
|
142
|
+
const searchResponse = {
|
|
143
|
+
results: [{ name: 'github' }, { name: 'gitlab' }],
|
|
144
|
+
};
|
|
145
|
+
global.fetch.mockResolvedValue({
|
|
146
|
+
ok: true,
|
|
147
|
+
status: 200,
|
|
148
|
+
json: async () => searchResponse,
|
|
149
|
+
});
|
|
150
|
+
const results = await registry.searchApis('git');
|
|
151
|
+
expect(results).toEqual(['github', 'gitlab']);
|
|
152
|
+
});
|
|
153
|
+
test('search apis failure', async () => {
|
|
154
|
+
const registry = new OCPRegistry('https://test-registry.ocp.dev');
|
|
155
|
+
global.fetch.mockRejectedValue(new Error('Connection failed'));
|
|
156
|
+
const results = await registry.searchApis('git');
|
|
157
|
+
// Should return empty array on failure
|
|
158
|
+
expect(results).toEqual([]);
|
|
159
|
+
});
|
|
160
|
+
});
|
|
161
|
+
describe('List APIs', () => {
|
|
162
|
+
test('list apis success', async () => {
|
|
163
|
+
const registry = new OCPRegistry('https://test-registry.ocp.dev');
|
|
164
|
+
const apiList = [{ name: 'github' }, { name: 'stripe' }, { name: 'httpbin' }];
|
|
165
|
+
global.fetch.mockResolvedValue({
|
|
166
|
+
ok: true,
|
|
167
|
+
status: 200,
|
|
168
|
+
json: async () => apiList,
|
|
169
|
+
});
|
|
170
|
+
const results = await registry.listApis();
|
|
171
|
+
expect(results).toEqual(['github', 'stripe', 'httpbin']);
|
|
172
|
+
});
|
|
173
|
+
test('list apis failure', async () => {
|
|
174
|
+
const registry = new OCPRegistry('https://test-registry.ocp.dev');
|
|
175
|
+
global.fetch.mockRejectedValue(new Error('Connection failed'));
|
|
176
|
+
const results = await registry.listApis();
|
|
177
|
+
// Should return empty array on failure
|
|
178
|
+
expect(results).toEqual([]);
|
|
179
|
+
});
|
|
180
|
+
});
|
|
181
|
+
describe('Internal Methods', () => {
|
|
182
|
+
test('entry to spec conversion', async () => {
|
|
183
|
+
const registry = new OCPRegistry('https://test-registry.ocp.dev');
|
|
184
|
+
const apiSpec = await registry._entryToSpec(sampleApiEntry);
|
|
185
|
+
expect(apiSpec.title).toBe('HTTPBin Testing Service');
|
|
186
|
+
expect(apiSpec.version).toBe('1.0.0');
|
|
187
|
+
expect(apiSpec.base_url).toBe('https://httpbin.org/');
|
|
188
|
+
// Check tools conversion
|
|
189
|
+
expect(apiSpec.tools.length).toBe(2);
|
|
190
|
+
const tool1 = apiSpec.tools[0];
|
|
191
|
+
expect(tool1.name).toBe('get_get');
|
|
192
|
+
expect(tool1.method).toBe('GET');
|
|
193
|
+
expect(tool1.path).toBe('/get');
|
|
194
|
+
});
|
|
195
|
+
test('get suggestions exact match', async () => {
|
|
196
|
+
const registry = new OCPRegistry('https://test-registry.ocp.dev');
|
|
197
|
+
global.fetch.mockResolvedValue({
|
|
198
|
+
ok: true,
|
|
199
|
+
status: 200,
|
|
200
|
+
json: async () => ({ results: [{ name: 'github' }] }),
|
|
201
|
+
});
|
|
202
|
+
const suggestions = await registry._getSuggestions('github');
|
|
203
|
+
expect(suggestions).toEqual(['github']);
|
|
204
|
+
});
|
|
205
|
+
test('get suggestions partial match', async () => {
|
|
206
|
+
const registry = new OCPRegistry('https://test-registry.ocp.dev');
|
|
207
|
+
let callCount = 0;
|
|
208
|
+
global.fetch.mockImplementation(async (url) => {
|
|
209
|
+
callCount++;
|
|
210
|
+
if (callCount === 1) {
|
|
211
|
+
// First call returns no results
|
|
212
|
+
return {
|
|
213
|
+
ok: true,
|
|
214
|
+
status: 200,
|
|
215
|
+
json: async () => ({ results: [] }),
|
|
216
|
+
};
|
|
217
|
+
}
|
|
218
|
+
else {
|
|
219
|
+
// Second call with partial query returns results
|
|
220
|
+
return {
|
|
221
|
+
ok: true,
|
|
222
|
+
status: 200,
|
|
223
|
+
json: async () => ({ results: [{ name: 'github' }] }),
|
|
224
|
+
};
|
|
225
|
+
}
|
|
226
|
+
});
|
|
227
|
+
const suggestions = await registry._getSuggestions('unknown');
|
|
228
|
+
expect(suggestions).toEqual(['github']);
|
|
229
|
+
});
|
|
230
|
+
});
|
|
231
|
+
});
|
|
232
|
+
//# sourceMappingURL=registry.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"registry.test.js","sourceRoot":"","sources":["../../tests/registry.test.ts"],"names":[],"mappings":"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"}
|