@masonator/coolify-mcp 0.1.0 → 0.1.1
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/README.md +129 -281
- package/dist/__tests__/coolify-client.test.js +242 -98
- package/dist/__tests__/mcp-server.test.js +143 -68
- package/dist/__tests__/resources/application-resources.test.d.ts +1 -0
- package/dist/__tests__/resources/application-resources.test.js +36 -0
- package/dist/__tests__/resources/database-resources.test.d.ts +1 -0
- package/dist/__tests__/resources/database-resources.test.js +72 -0
- package/dist/__tests__/resources/deployment-resources.test.d.ts +1 -0
- package/dist/__tests__/resources/deployment-resources.test.js +47 -0
- package/dist/__tests__/resources/service-resources.test.d.ts +1 -0
- package/dist/__tests__/resources/service-resources.test.js +81 -0
- package/dist/lib/coolify-client.d.ts +18 -6
- package/dist/lib/coolify-client.js +65 -15
- package/dist/lib/mcp-server.d.ts +24 -15
- package/dist/lib/mcp-server.js +270 -46
- package/dist/lib/resource.d.ts +13 -0
- package/dist/lib/resource.js +29 -0
- package/dist/resources/application-resources.d.ts +14 -0
- package/dist/resources/application-resources.js +59 -0
- package/dist/resources/database-resources.d.ts +17 -0
- package/dist/resources/database-resources.js +55 -0
- package/dist/resources/deployment-resources.d.ts +12 -0
- package/dist/resources/deployment-resources.js +48 -0
- package/dist/resources/index.d.ts +4 -0
- package/dist/resources/index.js +20 -0
- package/dist/resources/service-resources.d.ts +15 -0
- package/dist/resources/service-resources.js +55 -0
- package/dist/types/coolify.d.ts +163 -4
- package/package.json +4 -2
|
@@ -198,128 +198,272 @@ describe('CoolifyClient', () => {
|
|
|
198
198
|
describe('Environment Management', () => {
|
|
199
199
|
const mockEnvironment = {
|
|
200
200
|
id: 1,
|
|
201
|
-
uuid: '
|
|
202
|
-
name: '
|
|
203
|
-
project_uuid: '
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
updated_at: '2024-03-19T12:00:00Z',
|
|
201
|
+
uuid: 'jw0gwo4sowkoowswssk0gkc4',
|
|
202
|
+
name: 'production',
|
|
203
|
+
project_uuid: 'ikokwc8sk00wk8sg8gkwoscw',
|
|
204
|
+
created_at: '2025-02-11T11:37:33.000000Z',
|
|
205
|
+
updated_at: '2025-02-11T11:37:33.000000Z',
|
|
207
206
|
};
|
|
208
207
|
beforeEach(() => {
|
|
209
208
|
mockFetch.mockClear();
|
|
210
209
|
});
|
|
211
|
-
describe('
|
|
212
|
-
it('should fetch
|
|
210
|
+
describe('getProjectEnvironment', () => {
|
|
211
|
+
it('should fetch environment by project UUID and name/UUID successfully', async () => {
|
|
213
212
|
mockFetch.mockResolvedValueOnce({
|
|
214
213
|
ok: true,
|
|
215
|
-
json: () => Promise.resolve(
|
|
214
|
+
json: () => Promise.resolve(mockEnvironment),
|
|
216
215
|
});
|
|
217
|
-
const result = await client.
|
|
218
|
-
expect(result).toEqual(
|
|
219
|
-
expect(mockFetch).toHaveBeenCalledWith('http://test.coolify.io/api/v1/
|
|
216
|
+
const result = await client.getProjectEnvironment('ikokwc8sk00wk8sg8gkwoscw', 'production');
|
|
217
|
+
expect(result).toEqual(mockEnvironment);
|
|
218
|
+
expect(mockFetch).toHaveBeenCalledWith('http://test.coolify.io/api/v1/projects/ikokwc8sk00wk8sg8gkwoscw/production', expect.objectContaining({
|
|
220
219
|
headers: expect.objectContaining({
|
|
221
220
|
Authorization: 'Bearer test-token',
|
|
222
221
|
'Content-Type': 'application/json',
|
|
223
222
|
}),
|
|
224
223
|
}));
|
|
225
224
|
});
|
|
226
|
-
it('should
|
|
225
|
+
it('should handle not found error', async () => {
|
|
226
|
+
const errorResponse = {
|
|
227
|
+
error: 'Not Found',
|
|
228
|
+
status: 404,
|
|
229
|
+
message: 'Environment not found',
|
|
230
|
+
};
|
|
227
231
|
mockFetch.mockResolvedValueOnce({
|
|
228
|
-
ok:
|
|
229
|
-
json: () => Promise.resolve(
|
|
232
|
+
ok: false,
|
|
233
|
+
json: () => Promise.resolve(errorResponse),
|
|
230
234
|
});
|
|
231
|
-
|
|
232
|
-
expect(result).toEqual([mockEnvironment]);
|
|
233
|
-
expect(mockFetch).toHaveBeenCalledWith('http://test.coolify.io/api/v1/environments?project_uuid=project-test-id', expect.objectContaining({
|
|
234
|
-
headers: expect.objectContaining({
|
|
235
|
-
Authorization: 'Bearer test-token',
|
|
236
|
-
'Content-Type': 'application/json',
|
|
237
|
-
}),
|
|
238
|
-
}));
|
|
235
|
+
await expect(client.getProjectEnvironment('invalid-project', 'invalid-env')).rejects.toThrow('Environment not found');
|
|
239
236
|
});
|
|
240
237
|
});
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
238
|
+
});
|
|
239
|
+
describe('deployApplication', () => {
|
|
240
|
+
it('should deploy an application', async () => {
|
|
241
|
+
const mockDeployment = {
|
|
242
|
+
id: 1,
|
|
243
|
+
uuid: 'test-deployment-uuid',
|
|
244
|
+
application_uuid: 'test-app-uuid',
|
|
245
|
+
status: 'running',
|
|
246
|
+
created_at: '2024-03-20T12:00:00Z',
|
|
247
|
+
updated_at: '2024-03-20T12:00:00Z',
|
|
248
|
+
};
|
|
249
|
+
mockFetch.mockResolvedValueOnce({
|
|
250
|
+
ok: true,
|
|
251
|
+
json: () => Promise.resolve(mockDeployment),
|
|
255
252
|
});
|
|
253
|
+
const result = await client.deployApplication('test-app-uuid');
|
|
254
|
+
expect(result).toEqual(mockDeployment);
|
|
255
|
+
expect(mockFetch).toHaveBeenCalledWith('http://test.coolify.io/api/v1/applications/test-app-uuid/deploy', expect.objectContaining({
|
|
256
|
+
method: 'POST',
|
|
257
|
+
headers: expect.objectContaining({
|
|
258
|
+
Authorization: 'Bearer test-token',
|
|
259
|
+
'Content-Type': 'application/json',
|
|
260
|
+
}),
|
|
261
|
+
}));
|
|
256
262
|
});
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
ok: true,
|
|
267
|
-
json: () => Promise.resolve(mockResponse),
|
|
268
|
-
});
|
|
269
|
-
const result = await client.createEnvironment(createRequest);
|
|
270
|
-
expect(result).toEqual(mockResponse);
|
|
271
|
-
expect(mockFetch).toHaveBeenCalledWith('http://test.coolify.io/api/v1/environments', expect.objectContaining({
|
|
272
|
-
method: 'POST',
|
|
273
|
-
body: JSON.stringify(createRequest),
|
|
274
|
-
headers: expect.objectContaining({
|
|
275
|
-
Authorization: 'Bearer test-token',
|
|
276
|
-
'Content-Type': 'application/json',
|
|
277
|
-
}),
|
|
278
|
-
}));
|
|
263
|
+
it('should handle errors when deploying an application', async () => {
|
|
264
|
+
const errorResponse = {
|
|
265
|
+
error: 'Error',
|
|
266
|
+
status: 500,
|
|
267
|
+
message: 'Failed to deploy application',
|
|
268
|
+
};
|
|
269
|
+
mockFetch.mockResolvedValueOnce({
|
|
270
|
+
ok: false,
|
|
271
|
+
json: () => Promise.resolve(errorResponse),
|
|
279
272
|
});
|
|
273
|
+
await expect(client.deployApplication('test-app-uuid')).rejects.toThrow('Failed to deploy application');
|
|
280
274
|
});
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
275
|
+
});
|
|
276
|
+
describe('Database Management', () => {
|
|
277
|
+
const mockDatabase = {
|
|
278
|
+
id: 1,
|
|
279
|
+
uuid: 'test-db-uuid',
|
|
280
|
+
name: 'test-db',
|
|
281
|
+
description: 'Test database',
|
|
282
|
+
type: 'postgresql',
|
|
283
|
+
status: 'running',
|
|
284
|
+
created_at: '2024-03-06T12:00:00Z',
|
|
285
|
+
updated_at: '2024-03-06T12:00:00Z',
|
|
286
|
+
is_public: false,
|
|
287
|
+
image: 'postgres:latest',
|
|
288
|
+
postgres_user: 'postgres',
|
|
289
|
+
postgres_password: 'test123',
|
|
290
|
+
postgres_db: 'testdb',
|
|
291
|
+
};
|
|
292
|
+
beforeEach(() => {
|
|
293
|
+
mockFetch.mockClear();
|
|
294
|
+
});
|
|
295
|
+
it('should list databases', async () => {
|
|
296
|
+
mockFetch.mockResolvedValueOnce({
|
|
297
|
+
ok: true,
|
|
298
|
+
json: () => Promise.resolve([mockDatabase]),
|
|
304
299
|
});
|
|
300
|
+
const result = await client.listDatabases();
|
|
301
|
+
expect(result).toEqual([mockDatabase]);
|
|
302
|
+
expect(mockFetch).toHaveBeenCalledWith('http://test.coolify.io/api/v1/databases', expect.objectContaining({
|
|
303
|
+
headers: {
|
|
304
|
+
'Content-Type': 'application/json',
|
|
305
|
+
Authorization: 'Bearer test-token',
|
|
306
|
+
},
|
|
307
|
+
}));
|
|
305
308
|
});
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
309
|
+
it('should get database details', async () => {
|
|
310
|
+
mockFetch.mockResolvedValueOnce({
|
|
311
|
+
ok: true,
|
|
312
|
+
json: () => Promise.resolve(mockDatabase),
|
|
313
|
+
});
|
|
314
|
+
const result = await client.getDatabase('test-db-uuid');
|
|
315
|
+
expect(result).toEqual(mockDatabase);
|
|
316
|
+
expect(mockFetch).toHaveBeenCalledWith('http://test.coolify.io/api/v1/databases/test-db-uuid', expect.objectContaining({
|
|
317
|
+
headers: {
|
|
318
|
+
'Content-Type': 'application/json',
|
|
319
|
+
Authorization: 'Bearer test-token',
|
|
320
|
+
},
|
|
321
|
+
}));
|
|
322
|
+
});
|
|
323
|
+
it('should update database', async () => {
|
|
324
|
+
const updateData = {
|
|
325
|
+
name: 'updated-db',
|
|
326
|
+
description: 'Updated description',
|
|
327
|
+
};
|
|
328
|
+
mockFetch.mockResolvedValueOnce({
|
|
329
|
+
ok: true,
|
|
330
|
+
json: () => Promise.resolve({ ...mockDatabase, ...updateData }),
|
|
331
|
+
});
|
|
332
|
+
const result = await client.updateDatabase('test-db-uuid', updateData);
|
|
333
|
+
expect(result).toEqual({ ...mockDatabase, ...updateData });
|
|
334
|
+
expect(mockFetch).toHaveBeenCalledWith('http://test.coolify.io/api/v1/databases/test-db-uuid', expect.objectContaining({
|
|
335
|
+
method: 'PATCH',
|
|
336
|
+
body: JSON.stringify(updateData),
|
|
337
|
+
headers: {
|
|
338
|
+
'Content-Type': 'application/json',
|
|
339
|
+
Authorization: 'Bearer test-token',
|
|
340
|
+
},
|
|
341
|
+
}));
|
|
342
|
+
});
|
|
343
|
+
it('should delete database', async () => {
|
|
344
|
+
const mockResponse = { message: 'Database deleted' };
|
|
345
|
+
mockFetch.mockResolvedValueOnce({
|
|
346
|
+
ok: true,
|
|
347
|
+
json: () => Promise.resolve(mockResponse),
|
|
348
|
+
});
|
|
349
|
+
const result = await client.deleteDatabase('test-db-uuid', {
|
|
350
|
+
deleteConfigurations: true,
|
|
351
|
+
deleteVolumes: true,
|
|
322
352
|
});
|
|
353
|
+
expect(result).toEqual(mockResponse);
|
|
354
|
+
expect(mockFetch).toHaveBeenCalledWith('http://test.coolify.io/api/v1/databases/test-db-uuid?delete_configurations=true&delete_volumes=true', expect.objectContaining({
|
|
355
|
+
method: 'DELETE',
|
|
356
|
+
headers: {
|
|
357
|
+
'Content-Type': 'application/json',
|
|
358
|
+
Authorization: 'Bearer test-token',
|
|
359
|
+
},
|
|
360
|
+
}));
|
|
361
|
+
});
|
|
362
|
+
it('should handle database errors', async () => {
|
|
363
|
+
const errorMessage = 'Database not found';
|
|
364
|
+
mockFetch.mockRejectedValue(new Error(errorMessage));
|
|
365
|
+
await expect(client.getDatabase('invalid-uuid')).rejects.toThrow(errorMessage);
|
|
366
|
+
});
|
|
367
|
+
});
|
|
368
|
+
describe('Service Management', () => {
|
|
369
|
+
const mockService = {
|
|
370
|
+
id: 1,
|
|
371
|
+
uuid: 'test-service-uuid',
|
|
372
|
+
name: 'test-service',
|
|
373
|
+
description: 'Test service',
|
|
374
|
+
type: 'code-server',
|
|
375
|
+
status: 'running',
|
|
376
|
+
created_at: '2024-03-06T12:00:00Z',
|
|
377
|
+
updated_at: '2024-03-06T12:00:00Z',
|
|
378
|
+
project_uuid: 'test-project-uuid',
|
|
379
|
+
environment_name: 'production',
|
|
380
|
+
environment_uuid: 'test-env-uuid',
|
|
381
|
+
server_uuid: 'test-server-uuid',
|
|
382
|
+
domains: ['test-service.example.com'],
|
|
383
|
+
};
|
|
384
|
+
beforeEach(() => {
|
|
385
|
+
mockFetch.mockClear();
|
|
386
|
+
});
|
|
387
|
+
it('should list services', async () => {
|
|
388
|
+
mockFetch.mockResolvedValueOnce({
|
|
389
|
+
ok: true,
|
|
390
|
+
json: () => Promise.resolve([mockService]),
|
|
391
|
+
});
|
|
392
|
+
const result = await client.listServices();
|
|
393
|
+
expect(result).toEqual([mockService]);
|
|
394
|
+
expect(mockFetch).toHaveBeenCalledWith('http://test.coolify.io/api/v1/services', expect.objectContaining({
|
|
395
|
+
headers: {
|
|
396
|
+
'Content-Type': 'application/json',
|
|
397
|
+
Authorization: 'Bearer test-token',
|
|
398
|
+
},
|
|
399
|
+
}));
|
|
400
|
+
});
|
|
401
|
+
it('should get service details', async () => {
|
|
402
|
+
mockFetch.mockResolvedValueOnce({
|
|
403
|
+
ok: true,
|
|
404
|
+
json: () => Promise.resolve(mockService),
|
|
405
|
+
});
|
|
406
|
+
const result = await client.getService('test-service-uuid');
|
|
407
|
+
expect(result).toEqual(mockService);
|
|
408
|
+
expect(mockFetch).toHaveBeenCalledWith('http://test.coolify.io/api/v1/services/test-service-uuid', expect.objectContaining({
|
|
409
|
+
headers: {
|
|
410
|
+
'Content-Type': 'application/json',
|
|
411
|
+
Authorization: 'Bearer test-token',
|
|
412
|
+
},
|
|
413
|
+
}));
|
|
414
|
+
});
|
|
415
|
+
it('should create service', async () => {
|
|
416
|
+
const createData = {
|
|
417
|
+
type: 'code-server',
|
|
418
|
+
name: 'test-service',
|
|
419
|
+
description: 'Test service',
|
|
420
|
+
project_uuid: 'test-project-uuid',
|
|
421
|
+
environment_name: 'production',
|
|
422
|
+
server_uuid: 'test-server-uuid',
|
|
423
|
+
instant_deploy: true,
|
|
424
|
+
};
|
|
425
|
+
const mockResponse = {
|
|
426
|
+
uuid: 'test-service-uuid',
|
|
427
|
+
domains: ['test-service.example.com'],
|
|
428
|
+
};
|
|
429
|
+
mockFetch.mockResolvedValueOnce({
|
|
430
|
+
ok: true,
|
|
431
|
+
json: () => Promise.resolve(mockResponse),
|
|
432
|
+
});
|
|
433
|
+
const result = await client.createService(createData);
|
|
434
|
+
expect(result).toEqual(mockResponse);
|
|
435
|
+
expect(mockFetch).toHaveBeenCalledWith('http://test.coolify.io/api/v1/services', expect.objectContaining({
|
|
436
|
+
method: 'POST',
|
|
437
|
+
body: JSON.stringify(createData),
|
|
438
|
+
headers: {
|
|
439
|
+
'Content-Type': 'application/json',
|
|
440
|
+
Authorization: 'Bearer test-token',
|
|
441
|
+
},
|
|
442
|
+
}));
|
|
443
|
+
});
|
|
444
|
+
it('should delete service', async () => {
|
|
445
|
+
const mockResponse = { message: 'Service deleted' };
|
|
446
|
+
mockFetch.mockResolvedValueOnce({
|
|
447
|
+
ok: true,
|
|
448
|
+
json: () => Promise.resolve(mockResponse),
|
|
449
|
+
});
|
|
450
|
+
const result = await client.deleteService('test-service-uuid', {
|
|
451
|
+
deleteConfigurations: true,
|
|
452
|
+
deleteVolumes: true,
|
|
453
|
+
});
|
|
454
|
+
expect(result).toEqual(mockResponse);
|
|
455
|
+
expect(mockFetch).toHaveBeenCalledWith('http://test.coolify.io/api/v1/services/test-service-uuid?delete_configurations=true&delete_volumes=true', expect.objectContaining({
|
|
456
|
+
method: 'DELETE',
|
|
457
|
+
headers: {
|
|
458
|
+
'Content-Type': 'application/json',
|
|
459
|
+
Authorization: 'Bearer test-token',
|
|
460
|
+
},
|
|
461
|
+
}));
|
|
462
|
+
});
|
|
463
|
+
it('should handle service errors', async () => {
|
|
464
|
+
const errorMessage = 'Service not found';
|
|
465
|
+
mockFetch.mockRejectedValue(new Error(errorMessage));
|
|
466
|
+
await expect(client.getService('invalid-uuid')).rejects.toThrow(errorMessage);
|
|
323
467
|
});
|
|
324
468
|
});
|
|
325
469
|
});
|
|
@@ -118,10 +118,11 @@ describe('CoolifyMcpServer', () => {
|
|
|
118
118
|
const mockEnvironment = {
|
|
119
119
|
id: 1,
|
|
120
120
|
uuid: 'test-env-uuid',
|
|
121
|
-
name: 'test-
|
|
121
|
+
name: 'test-env',
|
|
122
122
|
project_uuid: 'test-project-uuid',
|
|
123
|
-
|
|
124
|
-
|
|
123
|
+
variables: { KEY: 'value' },
|
|
124
|
+
created_at: '2024-03-06T12:00:00Z',
|
|
125
|
+
updated_at: '2024-03-06T12:00:00Z',
|
|
125
126
|
};
|
|
126
127
|
const spy = globals_1.jest
|
|
127
128
|
.spyOn(server['client'], 'getProjectEnvironment')
|
|
@@ -130,80 +131,154 @@ describe('CoolifyMcpServer', () => {
|
|
|
130
131
|
expect(spy).toHaveBeenCalledWith('test-project-uuid', 'test-env-uuid');
|
|
131
132
|
});
|
|
132
133
|
});
|
|
133
|
-
describe('
|
|
134
|
-
|
|
134
|
+
describe('deploy_application', () => {
|
|
135
|
+
it('should deploy an application', async () => {
|
|
136
|
+
const mockDeployment = {
|
|
137
|
+
id: 1,
|
|
138
|
+
uuid: 'test-deployment-uuid',
|
|
139
|
+
application_uuid: 'test-app-uuid',
|
|
140
|
+
status: 'running',
|
|
141
|
+
created_at: '2024-03-20T12:00:00Z',
|
|
142
|
+
updated_at: '2024-03-20T12:00:00Z',
|
|
143
|
+
};
|
|
144
|
+
globals_1.jest.spyOn(server['client'], 'deployApplication').mockResolvedValue(mockDeployment);
|
|
145
|
+
const result = await server.deploy_application({ uuid: 'test-app-uuid' });
|
|
146
|
+
expect(result).toEqual(mockDeployment);
|
|
147
|
+
expect(server['client'].deployApplication).toHaveBeenCalledWith('test-app-uuid');
|
|
148
|
+
});
|
|
149
|
+
it('should handle errors when deploying an application', async () => {
|
|
150
|
+
const error = new Error('Failed to deploy application');
|
|
151
|
+
globals_1.jest.spyOn(server['client'], 'deployApplication').mockRejectedValue(error);
|
|
152
|
+
await expect(server.deploy_application({ uuid: 'test-app-uuid' })).rejects.toThrow('Failed to deploy application');
|
|
153
|
+
});
|
|
154
|
+
});
|
|
155
|
+
describe('Database Management', () => {
|
|
156
|
+
const mockDatabase = {
|
|
135
157
|
id: 1,
|
|
136
|
-
uuid: 'test-
|
|
137
|
-
name: 'test-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
158
|
+
uuid: 'test-db-uuid',
|
|
159
|
+
name: 'test-db',
|
|
160
|
+
description: 'Test database',
|
|
161
|
+
type: 'postgresql',
|
|
162
|
+
status: 'running',
|
|
163
|
+
created_at: '2024-03-06T12:00:00Z',
|
|
164
|
+
updated_at: '2024-03-06T12:00:00Z',
|
|
165
|
+
is_public: false,
|
|
166
|
+
image: 'postgres:latest',
|
|
167
|
+
postgres_user: 'postgres',
|
|
168
|
+
postgres_password: 'test123',
|
|
169
|
+
postgres_db: 'testdb',
|
|
142
170
|
};
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
await server.list_environments({});
|
|
149
|
-
expect(spy).toHaveBeenCalledWith(undefined);
|
|
150
|
-
});
|
|
151
|
-
it('should call client listEnvironments with project UUID', async () => {
|
|
152
|
-
const spy = globals_1.jest
|
|
153
|
-
.spyOn(server['client'], 'listEnvironments')
|
|
154
|
-
.mockResolvedValue([mockEnvironment]);
|
|
155
|
-
await server.list_environments({ project_uuid: 'test-project-uuid' });
|
|
156
|
-
expect(spy).toHaveBeenCalledWith('test-project-uuid');
|
|
157
|
-
});
|
|
171
|
+
it('should list databases', async () => {
|
|
172
|
+
const spy = globals_1.jest.spyOn(server['client'], 'listDatabases').mockResolvedValue([mockDatabase]);
|
|
173
|
+
const result = await server.list_databases();
|
|
174
|
+
expect(result).toEqual([mockDatabase]);
|
|
175
|
+
expect(spy).toHaveBeenCalled();
|
|
158
176
|
});
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
await server.get_environment({ uuid: 'test-env-uuid' });
|
|
165
|
-
expect(spy).toHaveBeenCalledWith('test-env-uuid');
|
|
166
|
-
});
|
|
177
|
+
it('should get database details', async () => {
|
|
178
|
+
const spy = globals_1.jest.spyOn(server['client'], 'getDatabase').mockResolvedValue(mockDatabase);
|
|
179
|
+
const result = await server.get_database('test-db-uuid');
|
|
180
|
+
expect(result).toEqual(mockDatabase);
|
|
181
|
+
expect(spy).toHaveBeenCalledWith('test-db-uuid');
|
|
167
182
|
});
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
183
|
+
it('should update database', async () => {
|
|
184
|
+
const updateData = {
|
|
185
|
+
name: 'updated-db',
|
|
186
|
+
description: 'Updated description',
|
|
187
|
+
};
|
|
188
|
+
const spy = globals_1.jest
|
|
189
|
+
.spyOn(server['client'], 'updateDatabase')
|
|
190
|
+
.mockResolvedValue({ ...mockDatabase, ...updateData, type: 'postgresql' });
|
|
191
|
+
const result = await server.update_database('test-db-uuid', updateData);
|
|
192
|
+
expect(result).toEqual({
|
|
193
|
+
...mockDatabase,
|
|
194
|
+
...updateData,
|
|
195
|
+
type: 'postgresql',
|
|
181
196
|
});
|
|
197
|
+
expect(spy).toHaveBeenCalledWith('test-db-uuid', updateData);
|
|
182
198
|
});
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
});
|
|
195
|
-
expect(spy).toHaveBeenCalledWith('test-env-uuid', updateRequest);
|
|
199
|
+
it('should delete database', async () => {
|
|
200
|
+
const mockResponse = { message: 'Database deleted' };
|
|
201
|
+
const spy = globals_1.jest.spyOn(server['client'], 'deleteDatabase').mockResolvedValue(mockResponse);
|
|
202
|
+
const result = await server.delete_database('test-db-uuid', {
|
|
203
|
+
deleteConfigurations: true,
|
|
204
|
+
deleteVolumes: true,
|
|
205
|
+
});
|
|
206
|
+
expect(result).toEqual(mockResponse);
|
|
207
|
+
expect(spy).toHaveBeenCalledWith('test-db-uuid', {
|
|
208
|
+
deleteConfigurations: true,
|
|
209
|
+
deleteVolumes: true,
|
|
196
210
|
});
|
|
197
211
|
});
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
212
|
+
it('should handle database errors', async () => {
|
|
213
|
+
const errorMessage = 'Database not found';
|
|
214
|
+
globals_1.jest.spyOn(server['client'], 'getDatabase').mockRejectedValue(new Error(errorMessage));
|
|
215
|
+
await expect(server.get_database('invalid-uuid')).rejects.toThrow(errorMessage);
|
|
216
|
+
});
|
|
217
|
+
});
|
|
218
|
+
describe('Service Management', () => {
|
|
219
|
+
const mockService = {
|
|
220
|
+
id: 1,
|
|
221
|
+
uuid: 'test-service-uuid',
|
|
222
|
+
name: 'test-service',
|
|
223
|
+
description: 'Test service',
|
|
224
|
+
type: 'code-server',
|
|
225
|
+
status: 'running',
|
|
226
|
+
created_at: '2024-03-06T12:00:00Z',
|
|
227
|
+
updated_at: '2024-03-06T12:00:00Z',
|
|
228
|
+
project_uuid: 'test-project-uuid',
|
|
229
|
+
environment_name: 'production',
|
|
230
|
+
environment_uuid: 'test-env-uuid',
|
|
231
|
+
server_uuid: 'test-server-uuid',
|
|
232
|
+
domains: ['test-service.example.com'],
|
|
233
|
+
};
|
|
234
|
+
it('should list services', async () => {
|
|
235
|
+
const spy = globals_1.jest.spyOn(server['client'], 'listServices').mockResolvedValue([mockService]);
|
|
236
|
+
const result = await server.list_services();
|
|
237
|
+
expect(result).toEqual([mockService]);
|
|
238
|
+
expect(spy).toHaveBeenCalled();
|
|
239
|
+
});
|
|
240
|
+
it('should get service details', async () => {
|
|
241
|
+
const spy = globals_1.jest.spyOn(server['client'], 'getService').mockResolvedValue(mockService);
|
|
242
|
+
const result = await server.get_service('test-service-uuid');
|
|
243
|
+
expect(result).toEqual(mockService);
|
|
244
|
+
expect(spy).toHaveBeenCalledWith('test-service-uuid');
|
|
245
|
+
});
|
|
246
|
+
it('should create service', async () => {
|
|
247
|
+
const createData = {
|
|
248
|
+
type: 'code-server',
|
|
249
|
+
name: 'test-service',
|
|
250
|
+
description: 'Test service',
|
|
251
|
+
project_uuid: 'test-project-uuid',
|
|
252
|
+
environment_name: 'production',
|
|
253
|
+
server_uuid: 'test-server-uuid',
|
|
254
|
+
instant_deploy: true,
|
|
255
|
+
};
|
|
256
|
+
const mockResponse = {
|
|
257
|
+
uuid: 'test-service-uuid',
|
|
258
|
+
domains: ['test-service.example.com'],
|
|
259
|
+
};
|
|
260
|
+
const spy = globals_1.jest.spyOn(server['client'], 'createService').mockResolvedValue(mockResponse);
|
|
261
|
+
const result = await server.create_service(createData);
|
|
262
|
+
expect(result).toEqual(mockResponse);
|
|
263
|
+
expect(spy).toHaveBeenCalledWith(createData);
|
|
264
|
+
});
|
|
265
|
+
it('should delete service', async () => {
|
|
266
|
+
const mockResponse = { message: 'Service deleted' };
|
|
267
|
+
const spy = globals_1.jest.spyOn(server['client'], 'deleteService').mockResolvedValue(mockResponse);
|
|
268
|
+
const result = await server.delete_service('test-service-uuid', {
|
|
269
|
+
deleteConfigurations: true,
|
|
270
|
+
deleteVolumes: true,
|
|
271
|
+
});
|
|
272
|
+
expect(result).toEqual(mockResponse);
|
|
273
|
+
expect(spy).toHaveBeenCalledWith('test-service-uuid', {
|
|
274
|
+
deleteConfigurations: true,
|
|
275
|
+
deleteVolumes: true,
|
|
206
276
|
});
|
|
207
277
|
});
|
|
278
|
+
it('should handle service errors', async () => {
|
|
279
|
+
const errorMessage = 'Service not found';
|
|
280
|
+
globals_1.jest.spyOn(server['client'], 'getService').mockRejectedValue(new Error(errorMessage));
|
|
281
|
+
await expect(server.get_service('invalid-uuid')).rejects.toThrow(errorMessage);
|
|
282
|
+
});
|
|
208
283
|
});
|
|
209
284
|
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const application_resources_js_1 = require("../../resources/application-resources.js");
|
|
4
|
+
const coolify_client_js_1 = require("../../lib/coolify-client.js");
|
|
5
|
+
jest.mock('../../lib/coolify-client.js');
|
|
6
|
+
describe('ApplicationResources', () => {
|
|
7
|
+
let resources;
|
|
8
|
+
let mockClient;
|
|
9
|
+
beforeEach(() => {
|
|
10
|
+
mockClient = new coolify_client_js_1.CoolifyClient({
|
|
11
|
+
baseUrl: 'http://test.coolify.io',
|
|
12
|
+
accessToken: 'test-token',
|
|
13
|
+
});
|
|
14
|
+
resources = new application_resources_js_1.ApplicationResources(mockClient);
|
|
15
|
+
});
|
|
16
|
+
describe('listApplications', () => {
|
|
17
|
+
it('should throw not implemented error', async () => {
|
|
18
|
+
await expect(resources.listApplications()).rejects.toThrow('Not implemented');
|
|
19
|
+
});
|
|
20
|
+
});
|
|
21
|
+
describe('getApplication', () => {
|
|
22
|
+
it('should throw not implemented error', async () => {
|
|
23
|
+
await expect(resources.getApplication('test-id')).rejects.toThrow('Not implemented');
|
|
24
|
+
});
|
|
25
|
+
});
|
|
26
|
+
describe('createApplication', () => {
|
|
27
|
+
it('should throw not implemented error', async () => {
|
|
28
|
+
await expect(resources.createApplication({ name: 'test-app' })).rejects.toThrow('Not implemented');
|
|
29
|
+
});
|
|
30
|
+
});
|
|
31
|
+
describe('deleteApplication', () => {
|
|
32
|
+
it('should throw not implemented error', async () => {
|
|
33
|
+
await expect(resources.deleteApplication('test-id')).rejects.toThrow('Not implemented');
|
|
34
|
+
});
|
|
35
|
+
});
|
|
36
|
+
});
|