@friggframework/devtools 2.0.0--canary.522.cbd3d5a.0 → 2.0.0--canary.517.21b69ac.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 (247) hide show
  1. package/.eslintrc.json +3 -0
  2. package/CHANGELOG.md +132 -0
  3. package/frigg-cli/README.md +1 -1
  4. package/frigg-cli/__tests__/unit/commands/doctor.test.js +2 -0
  5. package/frigg-cli/__tests__/unit/commands/install.test.js +17 -21
  6. package/frigg-cli/doctor-command/index.js +16 -17
  7. package/frigg-cli/index.js +6 -21
  8. package/frigg-cli/index.test.js +1 -7
  9. package/frigg-cli/init-command/backend-first-handler.js +42 -124
  10. package/frigg-cli/init-command/index.js +1 -2
  11. package/frigg-cli/init-command/template-handler.js +3 -13
  12. package/frigg-cli/install-command/backend-js.js +3 -3
  13. package/frigg-cli/install-command/environment-variables.js +19 -16
  14. package/frigg-cli/install-command/environment-variables.test.js +13 -12
  15. package/frigg-cli/install-command/index.js +9 -14
  16. package/frigg-cli/install-command/integration-file.js +3 -3
  17. package/frigg-cli/install-command/logger.js +12 -0
  18. package/frigg-cli/install-command/validate-package.js +9 -5
  19. package/frigg-cli/jest.config.js +1 -4
  20. package/frigg-cli/repair-command/index.js +128 -101
  21. package/frigg-cli/start-command/index.js +2 -246
  22. package/frigg-cli/ui-command/index.js +36 -58
  23. package/frigg-cli/utils/repo-detection.js +37 -85
  24. package/infrastructure/docs/iam-policy-templates.md +1 -1
  25. package/infrastructure/domains/networking/vpc-builder.test.js +4 -2
  26. package/infrastructure/domains/networking/vpc-resolver.test.js +1 -1
  27. package/infrastructure/domains/shared/cloudformation-discovery.test.js +7 -4
  28. package/infrastructure/domains/shared/resource-discovery.js +5 -5
  29. package/infrastructure/domains/shared/types/discovery-result.test.js +1 -1
  30. package/infrastructure/domains/shared/utilities/base-definition-factory.js +2 -25
  31. package/infrastructure/domains/shared/utilities/base-definition-factory.test.js +2 -2
  32. package/infrastructure/infrastructure-composer.test.js +2 -2
  33. package/layers/prisma/.build-complete +3 -0
  34. package/layers/prisma/nodejs/package.json +8 -0
  35. package/management-ui/.eslintrc.js +22 -0
  36. package/management-ui/README.md +109 -245
  37. package/management-ui/components.json +21 -0
  38. package/management-ui/docs/phase2-integration-guide.md +320 -0
  39. package/management-ui/index.html +13 -0
  40. package/management-ui/package.json +76 -0
  41. package/management-ui/packages/devtools/frigg-cli/ui-command/index.js +302 -0
  42. package/management-ui/postcss.config.js +6 -0
  43. package/management-ui/server/api/backend.js +256 -0
  44. package/management-ui/server/api/cli.js +315 -0
  45. package/management-ui/server/api/codegen.js +663 -0
  46. package/management-ui/server/api/connections.js +857 -0
  47. package/management-ui/server/api/discovery.js +185 -0
  48. package/management-ui/server/api/environment/index.js +1 -0
  49. package/management-ui/server/api/environment/router.js +378 -0
  50. package/management-ui/server/api/environment.js +328 -0
  51. package/management-ui/server/api/integrations.js +876 -0
  52. package/management-ui/server/api/logs.js +248 -0
  53. package/management-ui/server/api/monitoring.js +282 -0
  54. package/management-ui/server/api/open-ide.js +31 -0
  55. package/management-ui/server/api/project.js +1029 -0
  56. package/management-ui/server/api/users/sessions.js +371 -0
  57. package/management-ui/server/api/users/simulation.js +254 -0
  58. package/management-ui/server/api/users.js +362 -0
  59. package/management-ui/server/api-contract.md +275 -0
  60. package/management-ui/server/index.js +873 -0
  61. package/management-ui/server/middleware/errorHandler.js +93 -0
  62. package/management-ui/server/middleware/security.js +32 -0
  63. package/management-ui/server/processManager.js +296 -0
  64. package/management-ui/server/server.js +346 -0
  65. package/management-ui/server/services/aws-monitor.js +413 -0
  66. package/management-ui/server/services/npm-registry.js +347 -0
  67. package/management-ui/server/services/template-engine.js +538 -0
  68. package/management-ui/server/utils/cliIntegration.js +220 -0
  69. package/management-ui/server/utils/environment/auditLogger.js +471 -0
  70. package/management-ui/server/utils/environment/awsParameterStore.js +275 -0
  71. package/management-ui/server/utils/environment/encryption.js +278 -0
  72. package/management-ui/server/utils/environment/envFileManager.js +286 -0
  73. package/management-ui/server/utils/import-commonjs.js +28 -0
  74. package/management-ui/server/utils/response.js +83 -0
  75. package/management-ui/server/websocket/handler.js +325 -0
  76. package/management-ui/src/App.jsx +25 -0
  77. package/management-ui/src/assets/FriggLogo.svg +1 -0
  78. package/management-ui/src/components/AppRouter.jsx +65 -0
  79. package/management-ui/src/components/Button.jsx +70 -0
  80. package/management-ui/src/components/Card.jsx +97 -0
  81. package/management-ui/src/components/EnvironmentCompare.jsx +400 -0
  82. package/management-ui/src/components/EnvironmentEditor.jsx +372 -0
  83. package/management-ui/src/components/EnvironmentImportExport.jsx +469 -0
  84. package/management-ui/src/components/EnvironmentSchema.jsx +491 -0
  85. package/management-ui/src/components/EnvironmentSecurity.jsx +463 -0
  86. package/management-ui/src/components/ErrorBoundary.jsx +73 -0
  87. package/management-ui/src/components/IntegrationCard.jsx +481 -0
  88. package/management-ui/src/components/IntegrationCardEnhanced.jsx +770 -0
  89. package/management-ui/src/components/IntegrationExplorer.jsx +379 -0
  90. package/management-ui/src/components/IntegrationStatus.jsx +336 -0
  91. package/management-ui/src/components/Layout.jsx +716 -0
  92. package/management-ui/src/components/LoadingSpinner.jsx +113 -0
  93. package/management-ui/src/components/RepositoryPicker.jsx +248 -0
  94. package/management-ui/src/components/SessionMonitor.jsx +350 -0
  95. package/management-ui/src/components/StatusBadge.jsx +208 -0
  96. package/management-ui/src/components/UserContextSwitcher.jsx +212 -0
  97. package/management-ui/src/components/UserSimulation.jsx +327 -0
  98. package/management-ui/src/components/Welcome.jsx +434 -0
  99. package/management-ui/src/components/codegen/APIEndpointGenerator.jsx +637 -0
  100. package/management-ui/src/components/codegen/APIModuleSelector.jsx +227 -0
  101. package/management-ui/src/components/codegen/CodeGenerationWizard.jsx +247 -0
  102. package/management-ui/src/components/codegen/CodePreviewEditor.jsx +316 -0
  103. package/management-ui/src/components/codegen/DynamicModuleForm.jsx +271 -0
  104. package/management-ui/src/components/codegen/FormBuilder.jsx +737 -0
  105. package/management-ui/src/components/codegen/IntegrationGenerator.jsx +855 -0
  106. package/management-ui/src/components/codegen/ProjectScaffoldWizard.jsx +797 -0
  107. package/management-ui/src/components/codegen/SchemaBuilder.jsx +303 -0
  108. package/management-ui/src/components/codegen/TemplateSelector.jsx +586 -0
  109. package/management-ui/src/components/codegen/index.js +10 -0
  110. package/management-ui/src/components/connections/ConnectionConfigForm.jsx +362 -0
  111. package/management-ui/src/components/connections/ConnectionHealthMonitor.jsx +182 -0
  112. package/management-ui/src/components/connections/ConnectionTester.jsx +200 -0
  113. package/management-ui/src/components/connections/EntityRelationshipMapper.jsx +292 -0
  114. package/management-ui/src/components/connections/OAuthFlow.jsx +204 -0
  115. package/management-ui/src/components/connections/index.js +5 -0
  116. package/management-ui/src/components/index.js +21 -0
  117. package/management-ui/src/components/monitoring/APIGatewayMetrics.jsx +222 -0
  118. package/management-ui/src/components/monitoring/LambdaMetrics.jsx +169 -0
  119. package/management-ui/src/components/monitoring/MetricsChart.jsx +197 -0
  120. package/management-ui/src/components/monitoring/MonitoringDashboard.jsx +393 -0
  121. package/management-ui/src/components/monitoring/SQSMetrics.jsx +246 -0
  122. package/management-ui/src/components/monitoring/index.js +6 -0
  123. package/management-ui/src/components/monitoring/monitoring.css +218 -0
  124. package/management-ui/src/components/theme-provider.jsx +52 -0
  125. package/management-ui/src/components/theme-toggle.jsx +39 -0
  126. package/management-ui/src/components/ui/badge.tsx +36 -0
  127. package/management-ui/src/components/ui/button.test.jsx +56 -0
  128. package/management-ui/src/components/ui/button.tsx +57 -0
  129. package/management-ui/src/components/ui/card.tsx +76 -0
  130. package/management-ui/src/components/ui/dropdown-menu.tsx +199 -0
  131. package/management-ui/src/components/ui/select.tsx +157 -0
  132. package/management-ui/src/components/ui/skeleton.jsx +15 -0
  133. package/management-ui/src/hooks/useFrigg.jsx +387 -0
  134. package/management-ui/src/hooks/useSocket.jsx +58 -0
  135. package/management-ui/src/index.css +193 -0
  136. package/management-ui/src/lib/utils.ts +6 -0
  137. package/management-ui/src/main.jsx +10 -0
  138. package/management-ui/src/pages/CodeGeneration.jsx +14 -0
  139. package/management-ui/src/pages/Connections.jsx +252 -0
  140. package/management-ui/src/pages/ConnectionsEnhanced.jsx +633 -0
  141. package/management-ui/src/pages/Dashboard.jsx +311 -0
  142. package/management-ui/src/pages/Environment.jsx +314 -0
  143. package/management-ui/src/pages/IntegrationConfigure.jsx +669 -0
  144. package/management-ui/src/pages/IntegrationDiscovery.jsx +567 -0
  145. package/management-ui/src/pages/IntegrationTest.jsx +742 -0
  146. package/management-ui/src/pages/Integrations.jsx +253 -0
  147. package/management-ui/src/pages/Monitoring.jsx +17 -0
  148. package/management-ui/src/pages/Simulation.jsx +155 -0
  149. package/management-ui/src/pages/Users.jsx +492 -0
  150. package/management-ui/src/services/api.js +41 -0
  151. package/management-ui/src/services/apiModuleService.js +193 -0
  152. package/management-ui/src/services/websocket-handlers.js +120 -0
  153. package/management-ui/src/test/api/project.test.js +273 -0
  154. package/management-ui/src/test/components/Welcome.test.jsx +378 -0
  155. package/management-ui/src/test/mocks/server.js +178 -0
  156. package/management-ui/src/test/setup.js +61 -0
  157. package/management-ui/src/test/utils/test-utils.jsx +134 -0
  158. package/management-ui/src/utils/repository.js +98 -0
  159. package/management-ui/src/utils/repository.test.js +118 -0
  160. package/management-ui/src/workflows/phase2-integration-workflows.js +884 -0
  161. package/management-ui/tailwind.config.js +63 -0
  162. package/management-ui/tsconfig.json +37 -0
  163. package/management-ui/tsconfig.node.json +10 -0
  164. package/management-ui/vite.config.js +26 -0
  165. package/management-ui/vitest.config.js +38 -0
  166. package/package.json +7 -17
  167. package/frigg-cli/__tests__/application/use-cases/AddApiModuleToIntegrationUseCase.test.js +0 -326
  168. package/frigg-cli/__tests__/application/use-cases/CreateApiModuleUseCase.test.js +0 -337
  169. package/frigg-cli/__tests__/domain/entities/ApiModule.test.js +0 -373
  170. package/frigg-cli/__tests__/domain/entities/AppDefinition.test.js +0 -313
  171. package/frigg-cli/__tests__/domain/services/IntegrationValidator.test.js +0 -269
  172. package/frigg-cli/__tests__/domain/value-objects/IntegrationName.test.js +0 -82
  173. package/frigg-cli/__tests__/infrastructure/adapters/IntegrationJsUpdater.test.js +0 -408
  174. package/frigg-cli/__tests__/infrastructure/repositories/FileSystemApiModuleRepository.test.js +0 -583
  175. package/frigg-cli/__tests__/infrastructure/repositories/FileSystemAppDefinitionRepository.test.js +0 -314
  176. package/frigg-cli/__tests__/infrastructure/repositories/FileSystemIntegrationRepository.test.js +0 -430
  177. package/frigg-cli/__tests__/unit/commands/init.test.js +0 -406
  178. package/frigg-cli/__tests__/unit/commands/repair.test.js +0 -275
  179. package/frigg-cli/__tests__/unit/start-command/application/RunPreflightChecksUseCase.test.js +0 -411
  180. package/frigg-cli/__tests__/unit/start-command/infrastructure/DatabaseAdapter.test.js +0 -405
  181. package/frigg-cli/__tests__/unit/start-command/infrastructure/DockerAdapter.test.js +0 -496
  182. package/frigg-cli/__tests__/unit/start-command/presentation/InteractivePromptAdapter.test.js +0 -474
  183. package/frigg-cli/__tests__/unit/utils/output.test.js +0 -196
  184. package/frigg-cli/application/use-cases/AddApiModuleToIntegrationUseCase.js +0 -93
  185. package/frigg-cli/application/use-cases/CreateApiModuleUseCase.js +0 -93
  186. package/frigg-cli/application/use-cases/CreateIntegrationUseCase.js +0 -103
  187. package/frigg-cli/container.js +0 -172
  188. package/frigg-cli/docs/OUTPUT_MIGRATION_GUIDE.md +0 -286
  189. package/frigg-cli/domain/entities/ApiModule.js +0 -272
  190. package/frigg-cli/domain/entities/AppDefinition.js +0 -227
  191. package/frigg-cli/domain/entities/Integration.js +0 -198
  192. package/frigg-cli/domain/exceptions/DomainException.js +0 -24
  193. package/frigg-cli/domain/ports/IApiModuleRepository.js +0 -53
  194. package/frigg-cli/domain/ports/IAppDefinitionRepository.js +0 -43
  195. package/frigg-cli/domain/ports/IIntegrationRepository.js +0 -61
  196. package/frigg-cli/domain/services/IntegrationValidator.js +0 -185
  197. package/frigg-cli/domain/value-objects/IntegrationId.js +0 -42
  198. package/frigg-cli/domain/value-objects/IntegrationName.js +0 -60
  199. package/frigg-cli/domain/value-objects/SemanticVersion.js +0 -70
  200. package/frigg-cli/infrastructure/UnitOfWork.js +0 -46
  201. package/frigg-cli/infrastructure/adapters/BackendJsUpdater.js +0 -197
  202. package/frigg-cli/infrastructure/adapters/FileSystemAdapter.js +0 -224
  203. package/frigg-cli/infrastructure/adapters/IntegrationJsUpdater.js +0 -249
  204. package/frigg-cli/infrastructure/adapters/SchemaValidator.js +0 -92
  205. package/frigg-cli/infrastructure/repositories/FileSystemApiModuleRepository.js +0 -373
  206. package/frigg-cli/infrastructure/repositories/FileSystemAppDefinitionRepository.js +0 -116
  207. package/frigg-cli/infrastructure/repositories/FileSystemIntegrationRepository.js +0 -277
  208. package/frigg-cli/package-lock.json +0 -16226
  209. package/frigg-cli/start-command/application/RunPreflightChecksUseCase.js +0 -376
  210. package/frigg-cli/start-command/infrastructure/DatabaseAdapter.js +0 -591
  211. package/frigg-cli/start-command/infrastructure/DockerAdapter.js +0 -306
  212. package/frigg-cli/start-command/presentation/InteractivePromptAdapter.js +0 -329
  213. package/frigg-cli/templates/backend/.env.example +0 -62
  214. package/frigg-cli/templates/backend/.eslintrc.json +0 -12
  215. package/frigg-cli/templates/backend/.prettierrc +0 -6
  216. package/frigg-cli/templates/backend/docker-compose.yml +0 -22
  217. package/frigg-cli/templates/backend/index.js +0 -96
  218. package/frigg-cli/templates/backend/infrastructure.js +0 -12
  219. package/frigg-cli/templates/backend/jest.config.js +0 -17
  220. package/frigg-cli/templates/backend/package.json +0 -50
  221. package/frigg-cli/templates/backend/src/api-modules/.gitkeep +0 -10
  222. package/frigg-cli/templates/backend/src/base/.gitkeep +0 -7
  223. package/frigg-cli/templates/backend/src/integrations/.gitkeep +0 -10
  224. package/frigg-cli/templates/backend/src/integrations/ExampleIntegration.js +0 -65
  225. package/frigg-cli/templates/backend/src/utils/.gitkeep +0 -7
  226. package/frigg-cli/templates/backend/test/setup.js +0 -30
  227. package/frigg-cli/templates/backend/ui-extensions/.gitkeep +0 -0
  228. package/frigg-cli/templates/backend/ui-extensions/README.md +0 -77
  229. package/frigg-cli/utils/__tests__/repo-detection.test.js +0 -436
  230. package/frigg-cli/utils/output.js +0 -382
  231. package/frigg-cli/validate-command/__tests__/adapters/validate-command.test.js +0 -205
  232. package/frigg-cli/validate-command/__tests__/application/validate-app-use-case.test.js +0 -104
  233. package/frigg-cli/validate-command/__tests__/domain/fix-suggestion.test.js +0 -153
  234. package/frigg-cli/validate-command/__tests__/domain/validation-error.test.js +0 -162
  235. package/frigg-cli/validate-command/__tests__/domain/validation-result.test.js +0 -152
  236. package/frigg-cli/validate-command/__tests__/infrastructure/api-module-validator.test.js +0 -332
  237. package/frigg-cli/validate-command/__tests__/infrastructure/app-definition-validator.test.js +0 -191
  238. package/frigg-cli/validate-command/__tests__/infrastructure/integration-class-validator.test.js +0 -146
  239. package/frigg-cli/validate-command/__tests__/infrastructure/template-validation.test.js +0 -155
  240. package/frigg-cli/validate-command/adapters/cli/validate-command.js +0 -199
  241. package/frigg-cli/validate-command/application/use-cases/validate-app-use-case.js +0 -35
  242. package/frigg-cli/validate-command/domain/entities/validation-result.js +0 -74
  243. package/frigg-cli/validate-command/domain/value-objects/fix-suggestion.js +0 -74
  244. package/frigg-cli/validate-command/domain/value-objects/validation-error.js +0 -68
  245. package/frigg-cli/validate-command/infrastructure/validators/api-module-validator.js +0 -181
  246. package/frigg-cli/validate-command/infrastructure/validators/app-definition-validator.js +0 -128
  247. package/frigg-cli/validate-command/infrastructure/validators/integration-class-validator.js +0 -113
@@ -1,411 +0,0 @@
1
- /**
2
- * RunPreflightChecksUseCase Tests
3
- * Orchestrates pre-flight checks before starting Frigg
4
- *
5
- * Tests follow TDD pattern - written BEFORE implementation
6
- */
7
-
8
- const { RunPreflightChecksUseCase } = require('../../../../start-command/application/RunPreflightChecksUseCase');
9
-
10
- describe('RunPreflightChecksUseCase', () => {
11
- let useCase;
12
- let mockDockerAdapter;
13
- let mockDatabaseAdapter;
14
-
15
- beforeEach(() => {
16
- jest.clearAllMocks();
17
-
18
- // Reset environment
19
- delete process.env.DATABASE_URL;
20
-
21
- mockDockerAdapter = {
22
- isDockerInstalled: jest.fn(),
23
- isDockerRunning: jest.fn(),
24
- findDockerComposeFile: jest.fn(),
25
- startDockerDesktop: jest.fn(),
26
- startDockerCompose: jest.fn(),
27
- waitForDockerReady: jest.fn(),
28
- waitForLocalStack: jest.fn()
29
- };
30
-
31
- mockDatabaseAdapter = {
32
- getDatabaseType: jest.fn(),
33
- isDatabaseReachable: jest.fn(),
34
- getConnectionDetails: jest.fn()
35
- };
36
-
37
- useCase = new RunPreflightChecksUseCase({
38
- dockerAdapter: mockDockerAdapter,
39
- databaseAdapter: mockDatabaseAdapter
40
- });
41
- });
42
-
43
- describe('execute() - All checks pass', () => {
44
- beforeEach(() => {
45
- process.env.DATABASE_URL = 'mongodb://localhost:27017/frigg';
46
- mockDockerAdapter.isDockerInstalled.mockResolvedValue(true);
47
- mockDockerAdapter.isDockerRunning.mockResolvedValue(true);
48
- mockDockerAdapter.findDockerComposeFile.mockResolvedValue('/test/docker-compose.yml');
49
- mockDockerAdapter.waitForLocalStack.mockResolvedValue({ ready: true });
50
- mockDatabaseAdapter.getDatabaseType.mockReturnValue('mongodb');
51
- mockDatabaseAdapter.isDatabaseReachable.mockResolvedValue({ reachable: true });
52
- mockDatabaseAdapter.getConnectionDetails.mockReturnValue({
53
- type: 'mongodb',
54
- host: 'localhost',
55
- port: 27017,
56
- database: 'frigg'
57
- });
58
- });
59
-
60
- it('should return all checks passed when everything is ready', async () => {
61
- const result = await useCase.execute({ projectPath: '/test/project' });
62
-
63
- expect(result.allPassed).toBe(true);
64
- // 5 checks: DATABASE_URL, docker_installed, docker_running, database_reachable, localstack_reachable
65
- expect(result.checks).toHaveLength(5);
66
- });
67
-
68
- it('should include DATABASE_URL check result', async () => {
69
- const result = await useCase.execute({ projectPath: '/test/project' });
70
-
71
- const dbUrlCheck = result.checks.find(c => c.name === 'database_url');
72
- expect(dbUrlCheck.status).toBe('passed');
73
- });
74
-
75
- it('should include Docker installed check result', async () => {
76
- const result = await useCase.execute({ projectPath: '/test/project' });
77
-
78
- const dockerCheck = result.checks.find(c => c.name === 'docker_installed');
79
- expect(dockerCheck.status).toBe('passed');
80
- });
81
-
82
- it('should include Docker running check result', async () => {
83
- const result = await useCase.execute({ projectPath: '/test/project' });
84
-
85
- const dockerRunningCheck = result.checks.find(c => c.name === 'docker_running');
86
- expect(dockerRunningCheck.status).toBe('passed');
87
- });
88
-
89
- it('should include database reachable check result', async () => {
90
- const result = await useCase.execute({ projectPath: '/test/project' });
91
-
92
- const dbCheck = result.checks.find(c => c.name === 'database_reachable');
93
- expect(dbCheck.status).toBe('passed');
94
- });
95
- });
96
-
97
- describe('execute() - DATABASE_URL check', () => {
98
- it('should fail when DATABASE_URL is not set', async () => {
99
- delete process.env.DATABASE_URL;
100
-
101
- const result = await useCase.execute({ projectPath: '/test/project' });
102
-
103
- expect(result.allPassed).toBe(false);
104
- const dbUrlCheck = result.checks.find(c => c.name === 'database_url');
105
- expect(dbUrlCheck.status).toBe('failed');
106
- expect(dbUrlCheck.message).toContain('DATABASE_URL');
107
- });
108
-
109
- it('should provide resolution option for missing DATABASE_URL', async () => {
110
- delete process.env.DATABASE_URL;
111
-
112
- const result = await useCase.execute({ projectPath: '/test/project' });
113
-
114
- const dbUrlCheck = result.checks.find(c => c.name === 'database_url');
115
- expect(dbUrlCheck.canResolve).toBe(true);
116
- expect(dbUrlCheck.resolution.type).toBe('create_env');
117
- });
118
-
119
- it('should pass when DATABASE_URL is set', async () => {
120
- process.env.DATABASE_URL = 'mongodb://localhost:27017/frigg';
121
- mockDatabaseAdapter.getDatabaseType.mockReturnValue('mongodb');
122
-
123
- const result = await useCase.execute({ projectPath: '/test/project' });
124
-
125
- const dbUrlCheck = result.checks.find(c => c.name === 'database_url');
126
- expect(dbUrlCheck.status).toBe('passed');
127
- });
128
- });
129
-
130
- describe('execute() - Docker installed check', () => {
131
- beforeEach(() => {
132
- process.env.DATABASE_URL = 'mongodb://localhost:27017/frigg';
133
- mockDatabaseAdapter.getDatabaseType.mockReturnValue('mongodb');
134
- });
135
-
136
- it('should fail when Docker is not installed', async () => {
137
- mockDockerAdapter.isDockerInstalled.mockResolvedValue(false);
138
-
139
- const result = await useCase.execute({ projectPath: '/test/project' });
140
-
141
- const dockerCheck = result.checks.find(c => c.name === 'docker_installed');
142
- expect(dockerCheck.status).toBe('failed');
143
- expect(dockerCheck.message).toContain('Docker is not installed');
144
- });
145
-
146
- it('should not provide auto-resolution for Docker not installed', async () => {
147
- mockDockerAdapter.isDockerInstalled.mockResolvedValue(false);
148
-
149
- const result = await useCase.execute({ projectPath: '/test/project' });
150
-
151
- const dockerCheck = result.checks.find(c => c.name === 'docker_installed');
152
- expect(dockerCheck.canResolve).toBe(false);
153
- expect(dockerCheck.resolution.type).toBe('manual');
154
- expect(dockerCheck.resolution.instructions).toBeDefined();
155
- });
156
-
157
- it('should pass when Docker is installed', async () => {
158
- mockDockerAdapter.isDockerInstalled.mockResolvedValue(true);
159
- mockDockerAdapter.isDockerRunning.mockResolvedValue(true);
160
- mockDockerAdapter.waitForLocalStack.mockResolvedValue({ ready: true });
161
- mockDatabaseAdapter.isDatabaseReachable.mockResolvedValue({ reachable: true });
162
-
163
- const result = await useCase.execute({ projectPath: '/test/project' });
164
-
165
- const dockerCheck = result.checks.find(c => c.name === 'docker_installed');
166
- expect(dockerCheck.status).toBe('passed');
167
- });
168
- });
169
-
170
- describe('execute() - Docker running check', () => {
171
- beforeEach(() => {
172
- process.env.DATABASE_URL = 'mongodb://localhost:27017/frigg';
173
- mockDatabaseAdapter.getDatabaseType.mockReturnValue('mongodb');
174
- mockDockerAdapter.isDockerInstalled.mockResolvedValue(true);
175
- mockDockerAdapter.waitForLocalStack.mockResolvedValue({ ready: true });
176
- });
177
-
178
- it('should fail when Docker daemon is not running', async () => {
179
- mockDockerAdapter.isDockerRunning.mockResolvedValue(false);
180
-
181
- const result = await useCase.execute({ projectPath: '/test/project' });
182
-
183
- const dockerRunningCheck = result.checks.find(c => c.name === 'docker_running');
184
- expect(dockerRunningCheck.status).toBe('failed');
185
- expect(dockerRunningCheck.message).toContain('Docker is not running');
186
- });
187
-
188
- it('should provide resolution option to start Docker', async () => {
189
- mockDockerAdapter.isDockerRunning.mockResolvedValue(false);
190
-
191
- const result = await useCase.execute({ projectPath: '/test/project' });
192
-
193
- const dockerRunningCheck = result.checks.find(c => c.name === 'docker_running');
194
- expect(dockerRunningCheck.canResolve).toBe(true);
195
- expect(dockerRunningCheck.resolution.type).toBe('start_docker');
196
- });
197
-
198
- it('should pass when Docker is running', async () => {
199
- mockDockerAdapter.isDockerRunning.mockResolvedValue(true);
200
- mockDockerAdapter.waitForLocalStack.mockResolvedValue({ ready: true });
201
- mockDatabaseAdapter.isDatabaseReachable.mockResolvedValue({ reachable: true });
202
-
203
- const result = await useCase.execute({ projectPath: '/test/project' });
204
-
205
- const dockerRunningCheck = result.checks.find(c => c.name === 'docker_running');
206
- expect(dockerRunningCheck.status).toBe('passed');
207
- });
208
- });
209
-
210
- describe('execute() - Database reachable check', () => {
211
- beforeEach(() => {
212
- process.env.DATABASE_URL = 'mongodb://localhost:27017/frigg';
213
- mockDatabaseAdapter.getDatabaseType.mockReturnValue('mongodb');
214
- mockDockerAdapter.isDockerInstalled.mockResolvedValue(true);
215
- mockDockerAdapter.isDockerRunning.mockResolvedValue(true);
216
- mockDockerAdapter.waitForLocalStack.mockResolvedValue({ ready: true });
217
- });
218
-
219
- it('should fail when database is not reachable', async () => {
220
- mockDatabaseAdapter.isDatabaseReachable.mockResolvedValue({
221
- reachable: false,
222
- error: 'ECONNREFUSED'
223
- });
224
- mockDockerAdapter.findDockerComposeFile.mockResolvedValue('/test/docker-compose.yml');
225
-
226
- const result = await useCase.execute({ projectPath: '/test/project' });
227
-
228
- const dbCheck = result.checks.find(c => c.name === 'database_reachable');
229
- expect(dbCheck.status).toBe('failed');
230
- expect(dbCheck.message).toContain('Database is not reachable');
231
- });
232
-
233
- it('should provide docker-compose resolution when file exists', async () => {
234
- mockDatabaseAdapter.isDatabaseReachable.mockResolvedValue({
235
- reachable: false,
236
- error: 'ECONNREFUSED'
237
- });
238
- mockDockerAdapter.findDockerComposeFile.mockResolvedValue('/test/docker-compose.yml');
239
-
240
- const result = await useCase.execute({ projectPath: '/test/project' });
241
-
242
- const dbCheck = result.checks.find(c => c.name === 'database_reachable');
243
- expect(dbCheck.canResolve).toBe(true);
244
- expect(dbCheck.resolution.type).toBe('start_docker_compose');
245
- expect(dbCheck.resolution.composePath).toBe('/test/docker-compose.yml');
246
- });
247
-
248
- it('should suggest manual setup when no docker-compose exists', async () => {
249
- mockDatabaseAdapter.isDatabaseReachable.mockResolvedValue({
250
- reachable: false,
251
- error: 'ECONNREFUSED'
252
- });
253
- mockDockerAdapter.findDockerComposeFile.mockResolvedValue(null);
254
-
255
- const result = await useCase.execute({ projectPath: '/test/project' });
256
-
257
- const dbCheck = result.checks.find(c => c.name === 'database_reachable');
258
- expect(dbCheck.canResolve).toBe(false);
259
- expect(dbCheck.resolution.type).toBe('manual');
260
- });
261
-
262
- it('should pass when database is reachable', async () => {
263
- mockDatabaseAdapter.isDatabaseReachable.mockResolvedValue({ reachable: true });
264
-
265
- const result = await useCase.execute({ projectPath: '/test/project' });
266
-
267
- const dbCheck = result.checks.find(c => c.name === 'database_reachable');
268
- expect(dbCheck.status).toBe('passed');
269
- });
270
- });
271
-
272
- describe('execute() - LocalStack reachable check', () => {
273
- beforeEach(() => {
274
- process.env.DATABASE_URL = 'mongodb://localhost:27017/frigg';
275
- mockDatabaseAdapter.getDatabaseType.mockReturnValue('mongodb');
276
- mockDockerAdapter.isDockerInstalled.mockResolvedValue(true);
277
- mockDockerAdapter.isDockerRunning.mockResolvedValue(true);
278
- mockDatabaseAdapter.isDatabaseReachable.mockResolvedValue({ reachable: true });
279
- });
280
-
281
- it('should fail when LocalStack is not reachable', async () => {
282
- mockDockerAdapter.waitForLocalStack.mockResolvedValue({ ready: false });
283
- mockDockerAdapter.findDockerComposeFile.mockResolvedValue('/test/docker-compose.yml');
284
-
285
- const result = await useCase.execute({ projectPath: '/test/project' });
286
-
287
- const localstackCheck = result.checks.find(c => c.name === 'localstack_reachable');
288
- expect(localstackCheck.status).toBe('failed');
289
- expect(localstackCheck.message).toContain('LocalStack is not reachable');
290
- });
291
-
292
- it('should provide docker-compose resolution when LocalStack is not reachable', async () => {
293
- mockDockerAdapter.waitForLocalStack.mockResolvedValue({ ready: false });
294
- mockDockerAdapter.findDockerComposeFile.mockResolvedValue('/test/docker-compose.yml');
295
-
296
- const result = await useCase.execute({ projectPath: '/test/project' });
297
-
298
- const localstackCheck = result.checks.find(c => c.name === 'localstack_reachable');
299
- expect(localstackCheck.canResolve).toBe(true);
300
- expect(localstackCheck.resolution.type).toBe('start_docker_compose');
301
- });
302
-
303
- it('should pass when LocalStack is reachable', async () => {
304
- mockDockerAdapter.waitForLocalStack.mockResolvedValue({ ready: true });
305
-
306
- const result = await useCase.execute({ projectPath: '/test/project' });
307
-
308
- const localstackCheck = result.checks.find(c => c.name === 'localstack_reachable');
309
- expect(localstackCheck.status).toBe('passed');
310
- });
311
-
312
- it('should skip LocalStack check when AWS_ENDPOINT points to real AWS', async () => {
313
- process.env.AWS_ENDPOINT = 'https://sqs.us-east-1.amazonaws.com';
314
- mockDockerAdapter.waitForLocalStack.mockResolvedValue({ ready: true });
315
-
316
- const result = await useCase.execute({ projectPath: '/test/project' });
317
-
318
- // Should not include LocalStack check when using real AWS
319
- const localstackCheck = result.checks.find(c => c.name === 'localstack_reachable');
320
- expect(localstackCheck).toBeUndefined();
321
-
322
- delete process.env.AWS_ENDPOINT;
323
- });
324
- });
325
-
326
- describe('execute() - Short-circuit behavior', () => {
327
- it('should skip Docker checks if DATABASE_URL is missing', async () => {
328
- delete process.env.DATABASE_URL;
329
-
330
- await useCase.execute({ projectPath: '/test/project' });
331
-
332
- // Docker checks should not be called since DATABASE_URL failed
333
- expect(mockDockerAdapter.isDockerInstalled).not.toHaveBeenCalled();
334
- });
335
-
336
- it('should skip Docker running check if Docker not installed', async () => {
337
- process.env.DATABASE_URL = 'mongodb://localhost:27017/frigg';
338
- mockDatabaseAdapter.getDatabaseType.mockReturnValue('mongodb');
339
- mockDockerAdapter.isDockerInstalled.mockResolvedValue(false);
340
-
341
- await useCase.execute({ projectPath: '/test/project' });
342
-
343
- expect(mockDockerAdapter.isDockerRunning).not.toHaveBeenCalled();
344
- });
345
-
346
- it('should skip database reachable check if Docker not running', async () => {
347
- process.env.DATABASE_URL = 'mongodb://localhost:27017/frigg';
348
- mockDatabaseAdapter.getDatabaseType.mockReturnValue('mongodb');
349
- mockDockerAdapter.isDockerInstalled.mockResolvedValue(true);
350
- mockDockerAdapter.isDockerRunning.mockResolvedValue(false);
351
-
352
- await useCase.execute({ projectPath: '/test/project' });
353
-
354
- expect(mockDatabaseAdapter.isDatabaseReachable).not.toHaveBeenCalled();
355
- });
356
- });
357
-
358
- describe('getFailedChecks()', () => {
359
- it('should return only failed checks', async () => {
360
- process.env.DATABASE_URL = 'mongodb://localhost:27017/frigg';
361
- mockDatabaseAdapter.getDatabaseType.mockReturnValue('mongodb');
362
- mockDockerAdapter.isDockerInstalled.mockResolvedValue(true);
363
- mockDockerAdapter.isDockerRunning.mockResolvedValue(false);
364
-
365
- const result = await useCase.execute({ projectPath: '/test/project' });
366
- const failed = useCase.getFailedChecks(result);
367
-
368
- expect(failed).toHaveLength(1);
369
- expect(failed[0].name).toBe('docker_running');
370
- });
371
- });
372
-
373
- describe('getResolvableChecks()', () => {
374
- it('should return only checks that can be auto-resolved', async () => {
375
- process.env.DATABASE_URL = 'mongodb://localhost:27017/frigg';
376
- mockDatabaseAdapter.getDatabaseType.mockReturnValue('mongodb');
377
- mockDockerAdapter.isDockerInstalled.mockResolvedValue(true);
378
- mockDockerAdapter.isDockerRunning.mockResolvedValue(false);
379
-
380
- const result = await useCase.execute({ projectPath: '/test/project' });
381
- const resolvable = useCase.getResolvableChecks(result);
382
-
383
- expect(resolvable).toHaveLength(1);
384
- expect(resolvable[0].canResolve).toBe(true);
385
- });
386
- });
387
-
388
- describe('Check result structure', () => {
389
- it('should include all required fields in check results', async () => {
390
- delete process.env.DATABASE_URL;
391
-
392
- const result = await useCase.execute({ projectPath: '/test/project' });
393
-
394
- const check = result.checks[0];
395
- expect(check).toHaveProperty('name');
396
- expect(check).toHaveProperty('status');
397
- expect(check).toHaveProperty('message');
398
- expect(check).toHaveProperty('canResolve');
399
- expect(check).toHaveProperty('resolution');
400
- });
401
-
402
- it('should include resolution details for failed checks', async () => {
403
- delete process.env.DATABASE_URL;
404
-
405
- const result = await useCase.execute({ projectPath: '/test/project' });
406
-
407
- const check = result.checks.find(c => c.name === 'database_url');
408
- expect(check.resolution).toHaveProperty('type');
409
- });
410
- });
411
- });