@friggframework/devtools 2.0.0--canary.545.e256e95.0 → 2.0.0--canary.553.dc5f898.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.
Files changed (129) hide show
  1. package/frigg-cli/README.md +1 -1
  2. package/frigg-cli/__tests__/unit/commands/build.test.js +1 -1
  3. package/frigg-cli/__tests__/unit/commands/doctor.test.js +2 -0
  4. package/frigg-cli/__tests__/unit/commands/install.test.js +19 -23
  5. package/frigg-cli/__tests__/unit/dependencies.test.js +2 -2
  6. package/frigg-cli/build-command/index.js +11 -123
  7. package/frigg-cli/deploy-command/index.js +1 -83
  8. package/frigg-cli/doctor-command/index.js +16 -37
  9. package/frigg-cli/generate-iam-command.js +1 -21
  10. package/frigg-cli/index.js +6 -21
  11. package/frigg-cli/index.test.js +2 -7
  12. package/frigg-cli/init-command/backend-first-handler.js +42 -124
  13. package/frigg-cli/init-command/index.js +1 -2
  14. package/frigg-cli/init-command/template-handler.js +3 -13
  15. package/frigg-cli/install-command/backend-js.js +3 -3
  16. package/frigg-cli/install-command/environment-variables.js +19 -16
  17. package/frigg-cli/install-command/environment-variables.test.js +13 -12
  18. package/frigg-cli/install-command/index.js +9 -14
  19. package/frigg-cli/install-command/integration-file.js +3 -3
  20. package/frigg-cli/install-command/logger.js +12 -0
  21. package/frigg-cli/install-command/validate-package.js +9 -5
  22. package/frigg-cli/jest.config.js +1 -4
  23. package/frigg-cli/repair-command/index.js +128 -121
  24. package/frigg-cli/start-command/index.js +2 -324
  25. package/frigg-cli/ui-command/index.js +36 -58
  26. package/frigg-cli/utils/repo-detection.js +37 -85
  27. package/infrastructure/create-frigg-infrastructure.js +0 -93
  28. package/infrastructure/docs/iam-policy-templates.md +1 -1
  29. package/infrastructure/domains/integration/integration-builder.js +3 -2
  30. package/infrastructure/domains/integration/integration-builder.test.js +54 -2
  31. package/infrastructure/domains/networking/vpc-builder.test.js +4 -2
  32. package/infrastructure/domains/networking/vpc-resolver.test.js +1 -1
  33. package/infrastructure/domains/shared/resource-discovery.js +5 -5
  34. package/infrastructure/domains/shared/types/app-definition.js +0 -35
  35. package/infrastructure/domains/shared/types/discovery-result.test.js +1 -1
  36. package/infrastructure/domains/shared/utilities/base-definition-factory.js +1 -10
  37. package/infrastructure/domains/shared/utilities/base-definition-factory.test.js +2 -2
  38. package/infrastructure/infrastructure-composer.js +0 -2
  39. package/infrastructure/infrastructure-composer.test.js +6 -5
  40. package/management-ui/README.md +109 -245
  41. package/package.json +7 -8
  42. package/frigg-cli/__tests__/application/use-cases/AddApiModuleToIntegrationUseCase.test.js +0 -326
  43. package/frigg-cli/__tests__/application/use-cases/CreateApiModuleUseCase.test.js +0 -337
  44. package/frigg-cli/__tests__/domain/entities/ApiModule.test.js +0 -373
  45. package/frigg-cli/__tests__/domain/entities/AppDefinition.test.js +0 -313
  46. package/frigg-cli/__tests__/domain/services/IntegrationValidator.test.js +0 -269
  47. package/frigg-cli/__tests__/domain/value-objects/IntegrationName.test.js +0 -82
  48. package/frigg-cli/__tests__/infrastructure/adapters/IntegrationJsUpdater.test.js +0 -408
  49. package/frigg-cli/__tests__/infrastructure/repositories/FileSystemApiModuleRepository.test.js +0 -583
  50. package/frigg-cli/__tests__/infrastructure/repositories/FileSystemAppDefinitionRepository.test.js +0 -314
  51. package/frigg-cli/__tests__/infrastructure/repositories/FileSystemIntegrationRepository.test.js +0 -383
  52. package/frigg-cli/__tests__/unit/commands/init.test.js +0 -406
  53. package/frigg-cli/__tests__/unit/commands/provider-dispatch.test.js +0 -383
  54. package/frigg-cli/__tests__/unit/commands/repair.test.js +0 -275
  55. package/frigg-cli/__tests__/unit/start-command/application/RunPreflightChecksUseCase.test.js +0 -411
  56. package/frigg-cli/__tests__/unit/start-command/infrastructure/DatabaseAdapter.test.js +0 -405
  57. package/frigg-cli/__tests__/unit/start-command/infrastructure/DockerAdapter.test.js +0 -496
  58. package/frigg-cli/__tests__/unit/start-command/presentation/InteractivePromptAdapter.test.js +0 -474
  59. package/frigg-cli/__tests__/unit/utils/output.test.js +0 -196
  60. package/frigg-cli/application/use-cases/AddApiModuleToIntegrationUseCase.js +0 -93
  61. package/frigg-cli/application/use-cases/CreateApiModuleUseCase.js +0 -93
  62. package/frigg-cli/application/use-cases/CreateIntegrationUseCase.js +0 -103
  63. package/frigg-cli/container.js +0 -172
  64. package/frigg-cli/docs/OUTPUT_MIGRATION_GUIDE.md +0 -286
  65. package/frigg-cli/domain/entities/ApiModule.js +0 -272
  66. package/frigg-cli/domain/entities/AppDefinition.js +0 -227
  67. package/frigg-cli/domain/entities/Integration.js +0 -198
  68. package/frigg-cli/domain/exceptions/DomainException.js +0 -24
  69. package/frigg-cli/domain/ports/IApiModuleRepository.js +0 -53
  70. package/frigg-cli/domain/ports/IAppDefinitionRepository.js +0 -43
  71. package/frigg-cli/domain/ports/IIntegrationRepository.js +0 -61
  72. package/frigg-cli/domain/services/IntegrationValidator.js +0 -185
  73. package/frigg-cli/domain/value-objects/IntegrationId.js +0 -42
  74. package/frigg-cli/domain/value-objects/IntegrationName.js +0 -60
  75. package/frigg-cli/domain/value-objects/SemanticVersion.js +0 -70
  76. package/frigg-cli/infrastructure/UnitOfWork.js +0 -46
  77. package/frigg-cli/infrastructure/adapters/BackendJsUpdater.js +0 -197
  78. package/frigg-cli/infrastructure/adapters/FileSystemAdapter.js +0 -224
  79. package/frigg-cli/infrastructure/adapters/IntegrationJsUpdater.js +0 -249
  80. package/frigg-cli/infrastructure/adapters/SchemaValidator.js +0 -92
  81. package/frigg-cli/infrastructure/repositories/FileSystemApiModuleRepository.js +0 -373
  82. package/frigg-cli/infrastructure/repositories/FileSystemAppDefinitionRepository.js +0 -116
  83. package/frigg-cli/infrastructure/repositories/FileSystemIntegrationRepository.js +0 -277
  84. package/frigg-cli/package-lock.json +0 -16226
  85. package/frigg-cli/start-command/application/RunPreflightChecksUseCase.js +0 -376
  86. package/frigg-cli/start-command/infrastructure/DatabaseAdapter.js +0 -591
  87. package/frigg-cli/start-command/infrastructure/DockerAdapter.js +0 -306
  88. package/frigg-cli/start-command/presentation/InteractivePromptAdapter.js +0 -329
  89. package/frigg-cli/templates/backend/.env.example +0 -62
  90. package/frigg-cli/templates/backend/.eslintrc.json +0 -12
  91. package/frigg-cli/templates/backend/.prettierrc +0 -6
  92. package/frigg-cli/templates/backend/docker-compose.yml +0 -22
  93. package/frigg-cli/templates/backend/index.js +0 -96
  94. package/frigg-cli/templates/backend/infrastructure.js +0 -12
  95. package/frigg-cli/templates/backend/jest.config.js +0 -17
  96. package/frigg-cli/templates/backend/package.json +0 -50
  97. package/frigg-cli/templates/backend/src/api-modules/.gitkeep +0 -10
  98. package/frigg-cli/templates/backend/src/base/.gitkeep +0 -7
  99. package/frigg-cli/templates/backend/src/integrations/.gitkeep +0 -10
  100. package/frigg-cli/templates/backend/src/integrations/ExampleIntegration.js +0 -65
  101. package/frigg-cli/templates/backend/src/utils/.gitkeep +0 -7
  102. package/frigg-cli/templates/backend/test/setup.js +0 -30
  103. package/frigg-cli/templates/backend/ui-extensions/.gitkeep +0 -0
  104. package/frigg-cli/templates/backend/ui-extensions/README.md +0 -77
  105. package/frigg-cli/utils/__tests__/provider-helper.test.js +0 -55
  106. package/frigg-cli/utils/__tests__/repo-detection.test.js +0 -436
  107. package/frigg-cli/utils/output.js +0 -382
  108. package/frigg-cli/utils/provider-helper.js +0 -75
  109. package/frigg-cli/validate-command/__tests__/adapters/validate-command.test.js +0 -205
  110. package/frigg-cli/validate-command/__tests__/application/validate-app-use-case.test.js +0 -104
  111. package/frigg-cli/validate-command/__tests__/domain/fix-suggestion.test.js +0 -153
  112. package/frigg-cli/validate-command/__tests__/domain/validation-error.test.js +0 -162
  113. package/frigg-cli/validate-command/__tests__/domain/validation-result.test.js +0 -152
  114. package/frigg-cli/validate-command/__tests__/infrastructure/api-module-validator.test.js +0 -332
  115. package/frigg-cli/validate-command/__tests__/infrastructure/app-definition-validator.test.js +0 -191
  116. package/frigg-cli/validate-command/__tests__/infrastructure/integration-class-validator.test.js +0 -146
  117. package/frigg-cli/validate-command/__tests__/infrastructure/template-validation.test.js +0 -155
  118. package/frigg-cli/validate-command/adapters/cli/validate-command.js +0 -199
  119. package/frigg-cli/validate-command/application/use-cases/validate-app-use-case.js +0 -35
  120. package/frigg-cli/validate-command/domain/entities/validation-result.js +0 -74
  121. package/frigg-cli/validate-command/domain/value-objects/fix-suggestion.js +0 -74
  122. package/frigg-cli/validate-command/domain/value-objects/validation-error.js +0 -68
  123. package/frigg-cli/validate-command/infrastructure/validators/api-module-validator.js +0 -181
  124. package/frigg-cli/validate-command/infrastructure/validators/app-definition-validator.js +0 -145
  125. package/frigg-cli/validate-command/infrastructure/validators/integration-class-validator.js +0 -113
  126. package/infrastructure/domains/admin-scripts/admin-script-builder.js +0 -200
  127. package/infrastructure/domains/admin-scripts/admin-script-builder.test.js +0 -499
  128. package/infrastructure/domains/admin-scripts/index.js +0 -5
  129. package/infrastructure/jest.config.js +0 -16
@@ -1,496 +0,0 @@
1
- /**
2
- * DockerAdapter Tests
3
- * Infrastructure adapter for Docker operations - used by pre-flight checks
4
- *
5
- * Tests follow TDD pattern - written BEFORE implementation
6
- */
7
-
8
- // Mock child_process before importing
9
- jest.mock('child_process', () => ({
10
- exec: jest.fn(),
11
- spawn: jest.fn()
12
- }));
13
-
14
- // Mock fs for docker-compose file detection
15
- jest.mock('fs', () => ({
16
- existsSync: jest.fn(),
17
- promises: {
18
- access: jest.fn()
19
- }
20
- }));
21
-
22
- const { exec, spawn } = require('child_process');
23
- const fs = require('fs');
24
- const path = require('path');
25
-
26
- // Import after mocks are set up
27
- const { DockerAdapter } = require('../../../../start-command/infrastructure/DockerAdapter');
28
-
29
- describe('DockerAdapter', () => {
30
- let adapter;
31
-
32
- beforeEach(() => {
33
- jest.clearAllMocks();
34
- adapter = new DockerAdapter();
35
- });
36
-
37
- describe('isDockerInstalled()', () => {
38
- it('should return true when docker CLI is available', async () => {
39
- exec.mockImplementation((cmd, callback) => {
40
- callback(null, 'Docker version 24.0.7, build afdd53b', '');
41
- });
42
-
43
- const result = await adapter.isDockerInstalled();
44
-
45
- expect(result).toBe(true);
46
- expect(exec).toHaveBeenCalledWith('docker --version', expect.any(Function));
47
- });
48
-
49
- it('should return false when docker CLI is not found', async () => {
50
- exec.mockImplementation((cmd, callback) => {
51
- const error = new Error('command not found: docker');
52
- error.code = 127;
53
- callback(error, '', 'command not found: docker');
54
- });
55
-
56
- const result = await adapter.isDockerInstalled();
57
-
58
- expect(result).toBe(false);
59
- });
60
-
61
- it('should return false when docker command fails', async () => {
62
- exec.mockImplementation((cmd, callback) => {
63
- callback(new Error('Docker not installed'), '', '');
64
- });
65
-
66
- const result = await adapter.isDockerInstalled();
67
-
68
- expect(result).toBe(false);
69
- });
70
- });
71
-
72
- describe('isDockerRunning()', () => {
73
- it('should return true when Docker daemon is running', async () => {
74
- exec.mockImplementation((cmd, callback) => {
75
- callback(null, '', '');
76
- });
77
-
78
- const result = await adapter.isDockerRunning();
79
-
80
- expect(result).toBe(true);
81
- expect(exec).toHaveBeenCalledWith('docker info', expect.any(Function));
82
- });
83
-
84
- it('should return false when Docker daemon is not running', async () => {
85
- exec.mockImplementation((cmd, callback) => {
86
- const error = new Error('Cannot connect to the Docker daemon');
87
- callback(error, '', 'Cannot connect to the Docker daemon');
88
- });
89
-
90
- const result = await adapter.isDockerRunning();
91
-
92
- expect(result).toBe(false);
93
- });
94
-
95
- it('should return false when docker info command times out', async () => {
96
- exec.mockImplementation((cmd, callback) => {
97
- const error = new Error('ETIMEDOUT');
98
- error.code = 'ETIMEDOUT';
99
- callback(error, '', '');
100
- });
101
-
102
- const result = await adapter.isDockerRunning();
103
-
104
- expect(result).toBe(false);
105
- });
106
- });
107
-
108
- describe('findDockerComposeFile()', () => {
109
- const projectPath = '/test/project';
110
-
111
- it('should find docker-compose.yml in project root', async () => {
112
- fs.existsSync.mockImplementation((filePath) => {
113
- return filePath === path.join(projectPath, 'docker-compose.yml');
114
- });
115
-
116
- const result = await adapter.findDockerComposeFile(projectPath);
117
-
118
- expect(result).toBe(path.join(projectPath, 'docker-compose.yml'));
119
- });
120
-
121
- it('should find docker-compose.yaml in project root', async () => {
122
- fs.existsSync.mockImplementation((filePath) => {
123
- return filePath === path.join(projectPath, 'docker-compose.yaml');
124
- });
125
-
126
- const result = await adapter.findDockerComposeFile(projectPath);
127
-
128
- expect(result).toBe(path.join(projectPath, 'docker-compose.yaml'));
129
- });
130
-
131
- it('should find compose.yml in project root', async () => {
132
- fs.existsSync.mockImplementation((filePath) => {
133
- return filePath === path.join(projectPath, 'compose.yml');
134
- });
135
-
136
- const result = await adapter.findDockerComposeFile(projectPath);
137
-
138
- expect(result).toBe(path.join(projectPath, 'compose.yml'));
139
- });
140
-
141
- it('should find compose.yaml in project root', async () => {
142
- fs.existsSync.mockImplementation((filePath) => {
143
- return filePath === path.join(projectPath, 'compose.yaml');
144
- });
145
-
146
- const result = await adapter.findDockerComposeFile(projectPath);
147
-
148
- expect(result).toBe(path.join(projectPath, 'compose.yaml'));
149
- });
150
-
151
- it('should return null when no docker-compose file exists', async () => {
152
- fs.existsSync.mockReturnValue(false);
153
-
154
- const result = await adapter.findDockerComposeFile(projectPath);
155
-
156
- expect(result).toBeNull();
157
- });
158
-
159
- it('should prefer docker-compose.yml over other variants', async () => {
160
- // All variants exist
161
- fs.existsSync.mockReturnValue(true);
162
-
163
- const result = await adapter.findDockerComposeFile(projectPath);
164
-
165
- // Should return the first one checked (docker-compose.yml)
166
- expect(result).toBe(path.join(projectPath, 'docker-compose.yml'));
167
- });
168
-
169
- it('should search in parent directory if not found in project path', async () => {
170
- const backendPath = '/test/project/backend';
171
- fs.existsSync.mockImplementation((filePath) => {
172
- // Only exists in parent directory
173
- return filePath === path.join('/test/project', 'docker-compose.yml');
174
- });
175
-
176
- const result = await adapter.findDockerComposeFile(backendPath);
177
-
178
- expect(result).toBe(path.join('/test/project', 'docker-compose.yml'));
179
- });
180
- });
181
-
182
- describe('startDockerCompose()', () => {
183
- const composePath = '/test/project/docker-compose.yml';
184
-
185
- it('should run docker compose up -d successfully', async () => {
186
- exec.mockImplementation((cmd, opts, callback) => {
187
- if (typeof opts === 'function') {
188
- callback = opts;
189
- }
190
- callback(null, 'Container started', '');
191
- });
192
-
193
- const result = await adapter.startDockerCompose(composePath);
194
-
195
- expect(result.success).toBe(true);
196
- expect(exec).toHaveBeenCalledWith(
197
- expect.stringContaining('docker compose'),
198
- expect.any(Object),
199
- expect.any(Function)
200
- );
201
- });
202
-
203
- it('should use correct docker-compose file path', async () => {
204
- exec.mockImplementation((cmd, opts, callback) => {
205
- if (typeof opts === 'function') {
206
- callback = opts;
207
- }
208
- callback(null, '', '');
209
- });
210
-
211
- await adapter.startDockerCompose(composePath);
212
-
213
- expect(exec).toHaveBeenCalledWith(
214
- expect.stringContaining(`-f ${composePath}`),
215
- expect.any(Object),
216
- expect.any(Function)
217
- );
218
- });
219
-
220
- it('should return error when docker compose fails', async () => {
221
- exec.mockImplementation((cmd, opts, callback) => {
222
- if (typeof opts === 'function') {
223
- callback = opts;
224
- }
225
- const error = new Error('Service failed to start');
226
- callback(error, '', 'Service failed to start');
227
- });
228
-
229
- const result = await adapter.startDockerCompose(composePath);
230
-
231
- expect(result.success).toBe(false);
232
- expect(result.error).toContain('Service failed to start');
233
- });
234
-
235
- it('should run in detached mode by default', async () => {
236
- exec.mockImplementation((cmd, opts, callback) => {
237
- if (typeof opts === 'function') {
238
- callback = opts;
239
- }
240
- callback(null, '', '');
241
- });
242
-
243
- await adapter.startDockerCompose(composePath);
244
-
245
- expect(exec).toHaveBeenCalledWith(
246
- expect.stringContaining('up -d'),
247
- expect.any(Object),
248
- expect.any(Function)
249
- );
250
- });
251
-
252
- it('should set working directory to compose file directory', async () => {
253
- exec.mockImplementation((cmd, opts, callback) => {
254
- if (typeof opts === 'function') {
255
- callback = opts;
256
- }
257
- callback(null, '', '');
258
- });
259
-
260
- await adapter.startDockerCompose(composePath);
261
-
262
- expect(exec).toHaveBeenCalledWith(
263
- expect.any(String),
264
- expect.objectContaining({
265
- cwd: path.dirname(composePath)
266
- }),
267
- expect.any(Function)
268
- );
269
- });
270
- });
271
-
272
- describe('stopDockerCompose()', () => {
273
- const composePath = '/test/project/docker-compose.yml';
274
-
275
- it('should run docker compose down successfully', async () => {
276
- exec.mockImplementation((cmd, opts, callback) => {
277
- if (typeof opts === 'function') {
278
- callback = opts;
279
- }
280
- callback(null, 'Containers stopped', '');
281
- });
282
-
283
- const result = await adapter.stopDockerCompose(composePath);
284
-
285
- expect(result.success).toBe(true);
286
- expect(exec).toHaveBeenCalledWith(
287
- expect.stringContaining('docker compose'),
288
- expect.any(Object),
289
- expect.any(Function)
290
- );
291
- expect(exec).toHaveBeenCalledWith(
292
- expect.stringContaining('down'),
293
- expect.any(Object),
294
- expect.any(Function)
295
- );
296
- });
297
-
298
- it('should return error when docker compose down fails', async () => {
299
- exec.mockImplementation((cmd, opts, callback) => {
300
- if (typeof opts === 'function') {
301
- callback = opts;
302
- }
303
- callback(new Error('Failed to stop'), '', 'Failed to stop');
304
- });
305
-
306
- const result = await adapter.stopDockerCompose(composePath);
307
-
308
- expect(result.success).toBe(false);
309
- expect(result.error).toContain('Failed to stop');
310
- });
311
- });
312
-
313
- describe('startDockerDesktop()', () => {
314
- it('should open Docker Desktop on macOS', async () => {
315
- const originalPlatform = process.platform;
316
- Object.defineProperty(process, 'platform', { value: 'darwin' });
317
-
318
- exec.mockImplementation((cmd, callback) => {
319
- callback(null, '', '');
320
- });
321
-
322
- const result = await adapter.startDockerDesktop();
323
-
324
- expect(result.success).toBe(true);
325
- expect(exec).toHaveBeenCalledWith(
326
- expect.stringContaining('open'),
327
- expect.any(Function)
328
- );
329
-
330
- Object.defineProperty(process, 'platform', { value: originalPlatform });
331
- });
332
-
333
- it('should start Docker Desktop on Windows', async () => {
334
- const originalPlatform = process.platform;
335
- Object.defineProperty(process, 'platform', { value: 'win32' });
336
-
337
- exec.mockImplementation((cmd, callback) => {
338
- callback(null, '', '');
339
- });
340
-
341
- const result = await adapter.startDockerDesktop();
342
-
343
- expect(result.success).toBe(true);
344
- expect(exec).toHaveBeenCalledWith(
345
- expect.stringContaining('Docker Desktop'),
346
- expect.any(Function)
347
- );
348
-
349
- Object.defineProperty(process, 'platform', { value: originalPlatform });
350
- });
351
-
352
- it('should start docker service on Linux', async () => {
353
- const originalPlatform = process.platform;
354
- Object.defineProperty(process, 'platform', { value: 'linux' });
355
-
356
- exec.mockImplementation((cmd, callback) => {
357
- callback(null, '', '');
358
- });
359
-
360
- const result = await adapter.startDockerDesktop();
361
-
362
- expect(result.success).toBe(true);
363
- expect(exec).toHaveBeenCalledWith(
364
- expect.stringMatching(/systemctl|service/),
365
- expect.any(Function)
366
- );
367
-
368
- Object.defineProperty(process, 'platform', { value: originalPlatform });
369
- });
370
-
371
- it('should return error when Docker Desktop fails to start', async () => {
372
- exec.mockImplementation((cmd, callback) => {
373
- callback(new Error('Failed to start Docker Desktop'), '', '');
374
- });
375
-
376
- const result = await adapter.startDockerDesktop();
377
-
378
- expect(result.success).toBe(false);
379
- expect(result.error).toBeDefined();
380
- });
381
- });
382
-
383
- describe('getDockerComposeServices()', () => {
384
- const composePath = '/test/project/docker-compose.yml';
385
-
386
- it('should list running services', async () => {
387
- exec.mockImplementation((cmd, opts, callback) => {
388
- if (typeof opts === 'function') {
389
- callback = opts;
390
- }
391
- callback(null, 'mongodb\nredis\n', '');
392
- });
393
-
394
- const result = await adapter.getDockerComposeServices(composePath);
395
-
396
- expect(result).toEqual(['mongodb', 'redis']);
397
- });
398
-
399
- it('should return empty array when no services running', async () => {
400
- exec.mockImplementation((cmd, opts, callback) => {
401
- if (typeof opts === 'function') {
402
- callback = opts;
403
- }
404
- callback(null, '', '');
405
- });
406
-
407
- const result = await adapter.getDockerComposeServices(composePath);
408
-
409
- expect(result).toEqual([]);
410
- });
411
-
412
- it('should handle docker compose ps command failure', async () => {
413
- exec.mockImplementation((cmd, opts, callback) => {
414
- if (typeof opts === 'function') {
415
- callback = opts;
416
- }
417
- callback(new Error('Failed'), '', '');
418
- });
419
-
420
- const result = await adapter.getDockerComposeServices(composePath);
421
-
422
- expect(result).toEqual([]);
423
- });
424
- });
425
-
426
- describe('isServiceRunning()', () => {
427
- const composePath = '/test/project/docker-compose.yml';
428
-
429
- it('should return true when specific service is running', async () => {
430
- exec.mockImplementation((cmd, opts, callback) => {
431
- if (typeof opts === 'function') {
432
- callback = opts;
433
- }
434
- // docker compose ps --services --filter "status=running"
435
- callback(null, 'mongodb\nredis\n', '');
436
- });
437
-
438
- const result = await adapter.isServiceRunning(composePath, 'mongodb');
439
-
440
- expect(result).toBe(true);
441
- });
442
-
443
- it('should return false when service is not running', async () => {
444
- exec.mockImplementation((cmd, opts, callback) => {
445
- if (typeof opts === 'function') {
446
- callback = opts;
447
- }
448
- callback(null, 'redis\n', '');
449
- });
450
-
451
- const result = await adapter.isServiceRunning(composePath, 'mongodb');
452
-
453
- expect(result).toBe(false);
454
- });
455
- });
456
-
457
- describe('waitForDockerReady()', () => {
458
- it('should resolve when Docker becomes ready', async () => {
459
- let callCount = 0;
460
- exec.mockImplementation((cmd, callback) => {
461
- callCount++;
462
- if (callCount >= 3) {
463
- // Docker is ready on third try
464
- callback(null, '', '');
465
- } else {
466
- callback(new Error('Not ready'), '', '');
467
- }
468
- });
469
-
470
- const result = await adapter.waitForDockerReady({ maxAttempts: 5, intervalMs: 10 });
471
-
472
- expect(result).toBe(true);
473
- expect(callCount).toBe(3);
474
- });
475
-
476
- it('should return false after max attempts exceeded', async () => {
477
- exec.mockImplementation((cmd, callback) => {
478
- callback(new Error('Not ready'), '', '');
479
- });
480
-
481
- const result = await adapter.waitForDockerReady({ maxAttempts: 3, intervalMs: 10 });
482
-
483
- expect(result).toBe(false);
484
- });
485
-
486
- it('should use default options when not specified', async () => {
487
- exec.mockImplementation((cmd, callback) => {
488
- callback(null, '', '');
489
- });
490
-
491
- const result = await adapter.waitForDockerReady();
492
-
493
- expect(result).toBe(true);
494
- });
495
- });
496
- });