create-fluxstack 1.0.13 → 1.0.15

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 (214) hide show
  1. package/.env.example +29 -29
  2. package/app/client/README.md +69 -69
  3. package/app/client/index.html +14 -13
  4. package/app/client/src/App.tsx +157 -524
  5. package/app/client/src/components/ErrorBoundary.tsx +107 -0
  6. package/app/client/src/components/ErrorDisplay.css +365 -0
  7. package/app/client/src/components/ErrorDisplay.tsx +258 -0
  8. package/app/client/src/components/FluxStackConfig.tsx +1321 -0
  9. package/app/client/src/components/HybridLiveCounter.tsx +140 -0
  10. package/app/client/src/components/LiveClock.tsx +286 -0
  11. package/app/client/src/components/MainLayout.tsx +390 -0
  12. package/app/client/src/components/SidebarNavigation.tsx +391 -0
  13. package/app/client/src/components/StateDemo.tsx +178 -0
  14. package/app/client/src/components/SystemMonitor.tsx +1038 -0
  15. package/app/client/src/components/Teste.tsx +104 -0
  16. package/app/client/src/components/UserProfile.tsx +809 -0
  17. package/app/client/src/hooks/useAuth.ts +39 -0
  18. package/app/client/src/hooks/useNotifications.ts +56 -0
  19. package/app/client/src/lib/eden-api.ts +189 -53
  20. package/app/client/src/lib/errors.ts +340 -0
  21. package/app/client/src/lib/hooks/useErrorHandler.ts +258 -0
  22. package/app/client/src/lib/index.ts +45 -0
  23. package/app/client/src/main.tsx +3 -2
  24. package/app/client/src/pages/ApiDocs.tsx +182 -0
  25. package/app/client/src/pages/Demo.tsx +174 -0
  26. package/app/client/src/pages/HybridLive.tsx +263 -0
  27. package/app/client/src/pages/Overview.tsx +155 -0
  28. package/app/client/src/store/README.md +43 -0
  29. package/app/client/src/store/index.ts +16 -0
  30. package/app/client/src/store/slices/uiSlice.ts +151 -0
  31. package/app/client/src/store/slices/userSlice.ts +161 -0
  32. package/app/client/src/test/README.md +257 -0
  33. package/app/client/src/test/setup.ts +70 -0
  34. package/app/client/src/test/types.ts +12 -0
  35. package/app/client/src/vite-env.d.ts +1 -1
  36. package/app/client/tsconfig.app.json +44 -43
  37. package/app/client/tsconfig.json +7 -7
  38. package/app/client/tsconfig.node.json +25 -25
  39. package/app/client/zustand-setup.md +65 -0
  40. package/app/server/controllers/users.controller.ts +68 -68
  41. package/app/server/index.ts +9 -1
  42. package/app/server/live/CounterComponent.ts +191 -0
  43. package/app/server/live/FluxStackConfig.ts +529 -0
  44. package/app/server/live/LiveClockComponent.ts +214 -0
  45. package/app/server/live/SidebarNavigation.ts +156 -0
  46. package/app/server/live/SystemMonitor.ts +594 -0
  47. package/app/server/live/SystemMonitorIntegration.ts +151 -0
  48. package/app/server/live/TesteComponent.ts +87 -0
  49. package/app/server/live/UserProfileComponent.ts +135 -0
  50. package/app/server/live/register-components.ts +28 -0
  51. package/app/server/middleware/auth.ts +136 -0
  52. package/app/server/middleware/errorHandling.ts +250 -0
  53. package/app/server/middleware/index.ts +10 -0
  54. package/app/server/middleware/rateLimit.ts +193 -0
  55. package/app/server/middleware/requestLogging.ts +215 -0
  56. package/app/server/middleware/validation.ts +270 -0
  57. package/app/server/routes/index.ts +14 -2
  58. package/app/server/routes/upload.ts +92 -0
  59. package/app/server/routes/users.routes.ts +2 -9
  60. package/app/server/services/NotificationService.ts +302 -0
  61. package/app/server/services/UserService.ts +222 -0
  62. package/app/server/services/index.ts +46 -0
  63. package/core/cli/commands/plugin-deps.ts +263 -0
  64. package/core/cli/generators/README.md +339 -0
  65. package/core/cli/generators/component.ts +770 -0
  66. package/core/cli/generators/controller.ts +299 -0
  67. package/core/cli/generators/index.ts +144 -0
  68. package/core/cli/generators/interactive.ts +228 -0
  69. package/core/cli/generators/prompts.ts +83 -0
  70. package/core/cli/generators/route.ts +513 -0
  71. package/core/cli/generators/service.ts +465 -0
  72. package/core/cli/generators/template-engine.ts +154 -0
  73. package/core/cli/generators/types.ts +71 -0
  74. package/core/cli/generators/utils.ts +192 -0
  75. package/core/cli/index.ts +69 -0
  76. package/core/cli/plugin-discovery.ts +16 -85
  77. package/core/client/fluxstack.ts +17 -0
  78. package/core/client/hooks/index.ts +7 -0
  79. package/core/client/hooks/state-validator.ts +130 -0
  80. package/core/client/hooks/useAuth.ts +49 -0
  81. package/core/client/hooks/useChunkedUpload.ts +258 -0
  82. package/core/client/hooks/useHybridLiveComponent.ts +967 -0
  83. package/core/client/hooks/useWebSocket.ts +373 -0
  84. package/core/client/index.ts +47 -0
  85. package/core/client/state/createStore.ts +193 -0
  86. package/core/client/state/index.ts +15 -0
  87. package/core/config/env-dynamic.ts +1 -1
  88. package/core/config/env.ts +2 -1
  89. package/core/config/runtime-config.ts +3 -3
  90. package/core/config/schema.ts +84 -49
  91. package/core/framework/server.ts +30 -0
  92. package/core/index.ts +25 -0
  93. package/core/live/ComponentRegistry.ts +399 -0
  94. package/core/live/types.ts +164 -0
  95. package/core/plugins/built-in/live-components/commands/create-live-component.ts +1201 -0
  96. package/core/plugins/built-in/live-components/index.ts +27 -0
  97. package/core/plugins/built-in/logger/index.ts +1 -1
  98. package/core/plugins/built-in/monitoring/index.ts +1 -1
  99. package/core/plugins/built-in/static/index.ts +1 -1
  100. package/core/plugins/built-in/swagger/index.ts +1 -1
  101. package/core/plugins/built-in/vite/index.ts +1 -1
  102. package/core/plugins/dependency-manager.ts +384 -0
  103. package/core/plugins/index.ts +5 -1
  104. package/core/plugins/manager.ts +7 -3
  105. package/core/plugins/registry.ts +88 -10
  106. package/core/plugins/types.ts +11 -11
  107. package/core/server/framework.ts +43 -0
  108. package/core/server/index.ts +11 -1
  109. package/core/server/live/ComponentRegistry.ts +1017 -0
  110. package/core/server/live/FileUploadManager.ts +272 -0
  111. package/core/server/live/LiveComponentPerformanceMonitor.ts +930 -0
  112. package/core/server/live/SingleConnectionManager.ts +0 -0
  113. package/core/server/live/StateSignature.ts +644 -0
  114. package/core/server/live/WebSocketConnectionManager.ts +688 -0
  115. package/core/server/live/websocket-plugin.ts +435 -0
  116. package/core/server/middleware/errorHandling.ts +141 -0
  117. package/core/server/middleware/index.ts +16 -0
  118. package/core/server/plugins/static-files-plugin.ts +232 -0
  119. package/core/server/services/BaseService.ts +95 -0
  120. package/core/server/services/ServiceContainer.ts +144 -0
  121. package/core/server/services/index.ts +9 -0
  122. package/core/templates/create-project.ts +196 -33
  123. package/core/testing/index.ts +10 -0
  124. package/core/testing/setup.ts +74 -0
  125. package/core/types/build.ts +38 -14
  126. package/core/types/types.ts +319 -0
  127. package/core/utils/env-runtime.ts +7 -0
  128. package/core/utils/errors/handlers.ts +264 -39
  129. package/core/utils/errors/index.ts +528 -18
  130. package/core/utils/errors/middleware.ts +114 -0
  131. package/core/utils/logger/formatters.ts +222 -0
  132. package/core/utils/logger/index.ts +167 -48
  133. package/core/utils/logger/middleware.ts +253 -0
  134. package/core/utils/logger/performance.ts +384 -0
  135. package/core/utils/logger/transports.ts +365 -0
  136. package/create-fluxstack.ts +296 -296
  137. package/fluxstack.config.ts +17 -1
  138. package/package-template.json +66 -66
  139. package/package.json +31 -6
  140. package/public/README.md +16 -0
  141. package/vite.config.ts +29 -14
  142. package/.claude/settings.local.json +0 -74
  143. package/.github/workflows/ci-build-tests.yml +0 -480
  144. package/.github/workflows/dependency-management.yml +0 -324
  145. package/.github/workflows/release-validation.yml +0 -355
  146. package/.kiro/specs/fluxstack-architecture-optimization/design.md +0 -700
  147. package/.kiro/specs/fluxstack-architecture-optimization/requirements.md +0 -127
  148. package/.kiro/specs/fluxstack-architecture-optimization/tasks.md +0 -330
  149. package/CLAUDE.md +0 -200
  150. package/Dockerfile +0 -58
  151. package/Dockerfile.backend +0 -52
  152. package/Dockerfile.frontend +0 -54
  153. package/README-Docker.md +0 -85
  154. package/ai-context/00-QUICK-START.md +0 -86
  155. package/ai-context/README.md +0 -88
  156. package/ai-context/development/eden-treaty-guide.md +0 -362
  157. package/ai-context/development/patterns.md +0 -382
  158. package/ai-context/development/plugins-guide.md +0 -572
  159. package/ai-context/examples/crud-complete.md +0 -626
  160. package/ai-context/project/architecture.md +0 -399
  161. package/ai-context/project/overview.md +0 -213
  162. package/ai-context/recent-changes/eden-treaty-refactor.md +0 -281
  163. package/ai-context/recent-changes/type-inference-fix.md +0 -223
  164. package/ai-context/reference/environment-vars.md +0 -384
  165. package/ai-context/reference/troubleshooting.md +0 -407
  166. package/app/client/src/components/TestPage.tsx +0 -453
  167. package/bun.lock +0 -1063
  168. package/bunfig.toml +0 -16
  169. package/core/__tests__/integration.test.ts +0 -227
  170. package/core/build/index.ts +0 -186
  171. package/core/config/__tests__/config-loader.test.ts +0 -554
  172. package/core/config/__tests__/config-merger.test.ts +0 -657
  173. package/core/config/__tests__/env-converter.test.ts +0 -372
  174. package/core/config/__tests__/env-processor.test.ts +0 -431
  175. package/core/config/__tests__/env.test.ts +0 -452
  176. package/core/config/__tests__/integration.test.ts +0 -418
  177. package/core/config/__tests__/loader.test.ts +0 -331
  178. package/core/config/__tests__/schema.test.ts +0 -129
  179. package/core/config/__tests__/validator.test.ts +0 -318
  180. package/core/framework/__tests__/server.test.ts +0 -233
  181. package/core/plugins/__tests__/built-in.test.ts.disabled +0 -366
  182. package/core/plugins/__tests__/manager.test.ts +0 -398
  183. package/core/plugins/__tests__/monitoring.test.ts +0 -401
  184. package/core/plugins/__tests__/registry.test.ts +0 -335
  185. package/core/utils/__tests__/errors.test.ts +0 -139
  186. package/core/utils/__tests__/helpers.test.ts +0 -297
  187. package/core/utils/__tests__/logger.test.ts +0 -141
  188. package/create-test-app.ts +0 -156
  189. package/docker-compose.microservices.yml +0 -75
  190. package/docker-compose.simple.yml +0 -57
  191. package/docker-compose.yml +0 -71
  192. package/eslint.config.js +0 -23
  193. package/flux-cli.ts +0 -214
  194. package/nginx-lb.conf +0 -37
  195. package/publish.sh +0 -63
  196. package/run-clean.ts +0 -26
  197. package/run-env-tests.ts +0 -313
  198. package/tailwind.config.js +0 -34
  199. package/tests/__mocks__/api.ts +0 -56
  200. package/tests/fixtures/users.ts +0 -69
  201. package/tests/integration/api/users.routes.test.ts +0 -221
  202. package/tests/setup.ts +0 -29
  203. package/tests/unit/app/client/App-simple.test.tsx +0 -56
  204. package/tests/unit/app/client/App.test.tsx.skip +0 -237
  205. package/tests/unit/app/client/eden-api.test.ts +0 -186
  206. package/tests/unit/app/client/simple.test.tsx +0 -23
  207. package/tests/unit/app/controllers/users.controller.test.ts +0 -150
  208. package/tests/unit/core/create-project.test.ts.skip +0 -95
  209. package/tests/unit/core/framework.test.ts +0 -144
  210. package/tests/unit/core/plugins/logger.test.ts.skip +0 -268
  211. package/tests/unit/core/plugins/vite.test.ts.disabled +0 -188
  212. package/tests/utils/test-helpers.ts +0 -61
  213. package/vitest.config.ts +0 -50
  214. package/workspace.json +0 -6
package/tests/setup.ts DELETED
@@ -1,29 +0,0 @@
1
- import '@testing-library/jest-dom'
2
- import { beforeAll, afterAll, afterEach } from 'vitest'
3
- import { cleanup } from '@testing-library/react'
4
- import { act } from 'react'
5
-
6
- // Fix React.act for React 19
7
- global.React = { act }
8
-
9
- // Cleanup after each test case (e.g. clearing jsdom)
10
- afterEach(() => {
11
- cleanup()
12
- })
13
-
14
- // Global test setup
15
- beforeAll(() => {
16
- // Setup global test environment
17
- console.log('🧪 Setting up test environment...')
18
- })
19
-
20
- afterAll(() => {
21
- // Cleanup global test environment
22
- console.log('🧹 Cleaning up test environment...')
23
- })
24
-
25
- // Mock environment variables for tests
26
- process.env.NODE_ENV = 'test'
27
- process.env.PORT = '3001'
28
- process.env.FRONTEND_PORT = '5174'
29
- process.env.BACKEND_PORT = '3002'
@@ -1,56 +0,0 @@
1
- import { describe, it, expect } from 'vitest'
2
- import { render, screen } from '@testing-library/react'
3
- import { getErrorMessage, APIException } from '@/app/client/src/lib/eden-api'
4
-
5
- // Simple component test without full App complexity
6
- function SimpleHeader({ title }: { title: string }) {
7
- return (
8
- <header>
9
- <div>{title}</div>
10
- </header>
11
- )
12
- }
13
-
14
- describe('Simple App Components', () => {
15
- describe('Header Component', () => {
16
- it('should render header with title', () => {
17
- render(<SimpleHeader title="🔥 FluxStack v1.4.0" />)
18
-
19
- expect(screen.getByText('🔥 FluxStack v1.4.0')).toBeInTheDocument()
20
- })
21
- })
22
-
23
- describe('Error Handling Utilities', () => {
24
- it('should handle API exceptions correctly', () => {
25
- const apiError = new APIException({
26
- message: 'Test error',
27
- status: 400,
28
- code: 'TEST_ERROR'
29
- })
30
-
31
- const message = getErrorMessage(apiError)
32
- expect(message).toBe('Test error')
33
- })
34
-
35
- it('should handle different status codes', () => {
36
- const unauthorizedError = new APIException({
37
- message: 'Unauthorized',
38
- status: 401
39
- })
40
-
41
- const message = getErrorMessage(unauthorizedError)
42
- expect(message).toBe('Acesso não autorizado')
43
- })
44
-
45
- it('should handle regular errors', () => {
46
- const regularError = new Error('Regular error')
47
- const message = getErrorMessage(regularError)
48
- expect(message).toBe('Regular error')
49
- })
50
-
51
- it('should handle unknown errors', () => {
52
- const message = getErrorMessage('string error')
53
- expect(message).toBe('Erro desconhecido')
54
- })
55
- })
56
- })
@@ -1,237 +0,0 @@
1
- import { describe, it, expect, vi, beforeEach } from 'vitest'
2
- import { render, screen, fireEvent, waitFor } from '@testing-library/react'
3
- import userEvent from '@testing-library/user-event'
4
- import App from '@/app/client/src/App'
5
-
6
- // Mock the eden-api module properly for hoisting
7
- vi.mock('@/app/client/src/lib/eden-api', () => ({
8
- api: {
9
- health: {
10
- get: vi.fn(() => Promise.resolve({
11
- status: "🚀 Hot Reload ativo!",
12
- timestamp: new Date().toISOString(),
13
- uptime: "120s",
14
- version: "1.4.0",
15
- environment: "development"
16
- }))
17
- },
18
- users: {
19
- get: vi.fn(() => Promise.resolve({
20
- users: [
21
- { id: 1, name: 'Test User 1', email: 'test1@example.com', createdAt: '2024-01-01' },
22
- { id: 2, name: 'Test User 2', email: 'test2@example.com', createdAt: '2024-01-02' }
23
- ]
24
- })),
25
- post: vi.fn(() => Promise.resolve({
26
- success: true,
27
- user: { id: 3, name: 'New User', email: 'new@example.com', createdAt: '2024-01-03' }
28
- }))
29
- }
30
- },
31
- apiCall: vi.fn((promise) => promise),
32
- getErrorMessage: vi.fn((error) => error?.message || 'Unknown error')
33
- }))
34
-
35
- describe('App Component', () => {
36
- beforeEach(() => {
37
- vi.clearAllMocks()
38
- })
39
-
40
- describe('Header and Navigation', () => {
41
- it('should render header with logo and tabs', () => {
42
- render(<App />)
43
-
44
- const logo = screen.getByText('🔥 FluxStack v1.4.0')
45
- const overviewTab = screen.getByText('📋 Visão Geral')
46
- const demoTab = screen.getByText('🚀 Demo')
47
- const apiDocsTab = screen.getByText('📚 API Docs')
48
-
49
- expect(logo).toBeInTheDocument()
50
- expect(overviewTab).toBeInTheDocument()
51
- expect(demoTab).toBeInTheDocument()
52
- expect(apiDocsTab).toBeInTheDocument()
53
- })
54
-
55
- it('should switch tabs correctly', async () => {
56
- const user = userEvent.setup()
57
- render(<App />)
58
-
59
- // Initially on overview tab
60
- expect(screen.getByText('🔥 FluxStack - Hot Reload Ativo! ⚡')).toBeInTheDocument()
61
-
62
- // Click demo tab
63
- await user.click(screen.getByText('🚀 Demo'))
64
- expect(screen.getByText('🔥 Demo Interativo - Hot Reload Testando!')).toBeInTheDocument()
65
-
66
- // Click API docs tab
67
- await user.click(screen.getByText('📚 API Docs'))
68
- expect(screen.getByText('Documentação da API')).toBeInTheDocument()
69
- })
70
-
71
- it('should show API status indicator', () => {
72
- render(<App />)
73
-
74
- const statusBadge = screen.getByText(/API (Online|Offline)/)
75
- expect(statusBadge).toBeInTheDocument()
76
- })
77
- })
78
-
79
- describe('Overview Tab', () => {
80
- it('should render overview content with features', () => {
81
- render(<App />)
82
-
83
- expect(screen.getByText('🔥 FluxStack - Hot Reload Ativo! ⚡')).toBeInTheDocument()
84
- expect(screen.getByText('Framework full-stack TypeScript moderno com hot reload coordenado! 🚀')).toBeInTheDocument()
85
-
86
- // Check features
87
- expect(screen.getByText('Elysia.js')).toBeInTheDocument()
88
- expect(screen.getByText('React + Vite')).toBeInTheDocument()
89
- expect(screen.getByText('Eden Treaty')).toBeInTheDocument()
90
- expect(screen.getByText('Docker Ready')).toBeInTheDocument()
91
- })
92
-
93
- it('should render tech stack information', () => {
94
- render(<App />)
95
-
96
- expect(screen.getByText('Stack Tecnológica')).toBeInTheDocument()
97
- expect(screen.getByText('Backend')).toBeInTheDocument()
98
- expect(screen.getByText('Frontend')).toBeInTheDocument()
99
- expect(screen.getByText('Comunicação')).toBeInTheDocument()
100
- })
101
- })
102
-
103
- describe('Demo Tab - User Management', () => {
104
- it('should render user form in demo tab', async () => {
105
- const user = userEvent.setup()
106
- render(<App />)
107
-
108
- await user.click(screen.getByText('🚀 Demo'))
109
-
110
- expect(screen.getByLabelText('Nome')).toBeInTheDocument()
111
- expect(screen.getByLabelText('Email')).toBeInTheDocument()
112
- expect(screen.getByRole('button', { name: /adicionar/i })).toBeInTheDocument()
113
- })
114
-
115
- it('should handle user form submission', async () => {
116
- const user = userEvent.setup()
117
- render(<App />)
118
-
119
- await user.click(screen.getByText('🚀 Demo'))
120
-
121
- const nameInput = screen.getByLabelText('Nome')
122
- const emailInput = screen.getByLabelText('Email')
123
- const submitButton = screen.getByRole('button', { name: /adicionar/i })
124
-
125
- await user.type(nameInput, 'Test User')
126
- await user.type(emailInput, 'test@example.com')
127
- await user.click(submitButton)
128
-
129
- // Form should be cleared after submission
130
- await waitFor(() => {
131
- expect(nameInput).toHaveValue('')
132
- expect(emailInput).toHaveValue('')
133
- })
134
- })
135
-
136
- it('should display users list in demo tab', async () => {
137
- const user = userEvent.setup()
138
- render(<App />)
139
-
140
- await user.click(screen.getByText('🚀 Demo'))
141
-
142
- // Wait for users to load
143
- await waitFor(() => {
144
- expect(screen.getByText('Test User 1')).toBeInTheDocument()
145
- expect(screen.getByText('test1@example.com')).toBeInTheDocument()
146
- expect(screen.getByText('Test User 2')).toBeInTheDocument()
147
- expect(screen.getByText('test2@example.com')).toBeInTheDocument()
148
- })
149
- })
150
-
151
- it('should show stats cards in demo tab', async () => {
152
- const user = userEvent.setup()
153
- render(<App />)
154
-
155
- await user.click(screen.getByText('🚀 Demo'))
156
-
157
- expect(screen.getByText('Usuários')).toBeInTheDocument()
158
- expect(screen.getByText('API Status')).toBeInTheDocument()
159
- expect(screen.getByText('Eden Treaty')).toBeInTheDocument()
160
- })
161
-
162
- it('should not submit form with empty fields', async () => {
163
- const user = userEvent.setup()
164
- render(<App />)
165
-
166
- await user.click(screen.getByText('🚀 Demo'))
167
-
168
- const submitButton = screen.getByRole('button', { name: /adicionar/i })
169
- expect(submitButton).toBeDisabled()
170
- })
171
- })
172
-
173
- describe('API Docs Tab', () => {
174
- it('should render API documentation content', async () => {
175
- const user = userEvent.setup()
176
- render(<App />)
177
-
178
- await user.click(screen.getByText('📚 API Docs'))
179
-
180
- expect(screen.getByText('Documentação da API')).toBeInTheDocument()
181
- expect(screen.getByText('Documentação interativa gerada automaticamente com Swagger')).toBeInTheDocument()
182
- })
183
-
184
- it('should have swagger links in API docs tab', async () => {
185
- const user = userEvent.setup()
186
- render(<App />)
187
-
188
- await user.click(screen.getByText('📚 API Docs'))
189
-
190
- const swaggerLink = screen.getByText('🚀 Abrir em Nova Aba')
191
- const jsonLink = screen.getByText('📋 Ver JSON')
192
-
193
- expect(swaggerLink.closest('a')).toHaveAttribute('href', '/swagger')
194
- expect(jsonLink.closest('a')).toHaveAttribute('href', '/swagger/json')
195
- })
196
-
197
- it('should render Eden Treaty code examples', async () => {
198
- const user = userEvent.setup()
199
- render(<App />)
200
-
201
- await user.click(screen.getByText('📚 API Docs'))
202
-
203
- expect(screen.getByText('🔧 Como usar Eden Treaty')).toBeInTheDocument()
204
- expect(screen.getByText('Configuração do Cliente:')).toBeInTheDocument()
205
- expect(screen.getByText('Exemplos de Uso:')).toBeInTheDocument()
206
- })
207
- })
208
-
209
- describe('API Integration', () => {
210
- it('should check API status on mount', async () => {
211
- const { api } = await import('@/app/client/src/lib/eden-api')
212
- render(<App />)
213
-
214
- await waitFor(() => {
215
- expect(api.health.get).toHaveBeenCalled()
216
- })
217
- })
218
-
219
- it('should load users on mount', async () => {
220
- const { api } = await import('@/app/client/src/lib/eden-api')
221
- render(<App />)
222
-
223
- await waitFor(() => {
224
- expect(api.users.get).toHaveBeenCalled()
225
- })
226
- })
227
- })
228
-
229
- describe('Toast Messages', () => {
230
- it('should not show toast initially', () => {
231
- render(<App />)
232
-
233
- const toast = screen.queryByRole('alert')
234
- expect(toast).not.toBeInTheDocument()
235
- })
236
- })
237
- })
@@ -1,186 +0,0 @@
1
- import { describe, it, expect, vi, beforeEach } from 'vitest'
2
- import { apiCall, getErrorMessage, APIException } from '@/app/client/src/lib/eden-api'
3
-
4
- describe('Eden API Utilities', () => {
5
- beforeEach(() => {
6
- vi.clearAllMocks()
7
- })
8
-
9
- describe('apiCall', () => {
10
- it('should return data on successful API response', async () => {
11
- const mockData = { users: [{ id: 1, name: 'Test' }] }
12
- const mockPromise = Promise.resolve({
13
- data: mockData,
14
- error: null,
15
- status: 200,
16
- response: new Response()
17
- })
18
-
19
- const result = await apiCall(mockPromise)
20
- expect(result).toEqual(mockData)
21
- })
22
-
23
- it('should throw APIException on error response', async () => {
24
- const mockError = {
25
- status: 400,
26
- value: {
27
- message: 'Validation failed',
28
- code: 'VALIDATION_ERROR',
29
- details: { field: 'email' }
30
- }
31
- }
32
- const mockPromise = Promise.resolve({
33
- data: null,
34
- error: mockError,
35
- status: 400,
36
- response: new Response()
37
- })
38
-
39
- await expect(apiCall(mockPromise)).rejects.toThrow(APIException)
40
-
41
- try {
42
- await apiCall(mockPromise)
43
- } catch (error) {
44
- expect(error).toBeInstanceOf(APIException)
45
- expect((error as APIException).message).toBe('Validation failed')
46
- expect((error as APIException).status).toBe(400)
47
- expect((error as APIException).code).toBe('VALIDATION_ERROR')
48
- expect((error as APIException).details).toEqual(mockError.value)
49
- }
50
- })
51
-
52
- it('should handle network errors', async () => {
53
- const networkError = new Error('Network error')
54
- const mockPromise = Promise.reject(networkError)
55
-
56
- await expect(apiCall(mockPromise)).rejects.toThrow(APIException)
57
-
58
- try {
59
- await apiCall(mockPromise)
60
- } catch (error) {
61
- expect(error).toBeInstanceOf(APIException)
62
- expect((error as APIException).message).toBe('Network error')
63
- expect((error as APIException).status).toBe(500)
64
- expect((error as APIException).code).toBe('NETWORK_ERROR')
65
- }
66
- })
67
-
68
- it('should handle unknown errors', async () => {
69
- const unknownError = 'Some string error'
70
- const mockPromise = Promise.reject(unknownError)
71
-
72
- await expect(apiCall(mockPromise)).rejects.toThrow(APIException)
73
-
74
- try {
75
- await apiCall(mockPromise)
76
- } catch (error) {
77
- expect(error).toBeInstanceOf(APIException)
78
- expect((error as APIException).message).toBe('Unknown error')
79
- expect((error as APIException).status).toBe(500)
80
- expect((error as APIException).code).toBe('NETWORK_ERROR')
81
- }
82
- })
83
- })
84
-
85
- describe('getErrorMessage', () => {
86
- it('should return specific messages for different status codes', () => {
87
- const badRequestError = new APIException({
88
- message: 'Custom message',
89
- status: 400
90
- })
91
- expect(getErrorMessage(badRequestError)).toBe('Custom message')
92
-
93
- const unauthorizedError = new APIException({
94
- message: 'Custom auth message',
95
- status: 401
96
- })
97
- expect(getErrorMessage(unauthorizedError)).toBe('Acesso não autorizado')
98
-
99
- const forbiddenError = new APIException({
100
- message: 'Forbidden',
101
- status: 403
102
- })
103
- expect(getErrorMessage(forbiddenError)).toBe('Acesso negado')
104
-
105
- const notFoundError = new APIException({
106
- message: 'Not found',
107
- status: 404
108
- })
109
- expect(getErrorMessage(notFoundError)).toBe('Recurso não encontrado')
110
-
111
- const validationError = new APIException({
112
- message: 'Validation error',
113
- status: 422
114
- })
115
- expect(getErrorMessage(validationError)).toBe('Dados de entrada inválidos')
116
-
117
- const serverError = new APIException({
118
- message: 'Server error',
119
- status: 500
120
- })
121
- expect(getErrorMessage(serverError)).toBe('Erro interno do servidor')
122
- })
123
-
124
- it('should return generic message for unknown status codes', () => {
125
- const unknownError = new APIException({
126
- message: 'Custom error',
127
- status: 418 // I'm a teapot
128
- })
129
- expect(getErrorMessage(unknownError)).toBe('Custom error')
130
- })
131
-
132
- it('should handle regular Error objects', () => {
133
- const regularError = new Error('Regular error message')
134
- expect(getErrorMessage(regularError)).toBe('Regular error message')
135
- })
136
-
137
- it('should handle unknown error types', () => {
138
- expect(getErrorMessage('string error')).toBe('Erro desconhecido')
139
- expect(getErrorMessage(null)).toBe('Erro desconhecido')
140
- expect(getErrorMessage(undefined)).toBe('Erro desconhecido')
141
- expect(getErrorMessage({ unknownProp: 'value' })).toBe('Erro desconhecido')
142
- })
143
-
144
- it('should fallback to default messages when APIException has no message', () => {
145
- const errorWithoutMessage = new APIException({
146
- message: '',
147
- status: 401
148
- })
149
- expect(getErrorMessage(errorWithoutMessage)).toBe('Acesso não autorizado')
150
- })
151
- })
152
-
153
- describe('APIException', () => {
154
- it('should create APIException with all properties', () => {
155
- const errorData = {
156
- message: 'Test error',
157
- status: 400,
158
- code: 'TEST_ERROR',
159
- details: { field: 'test' }
160
- }
161
-
162
- const exception = new APIException(errorData)
163
-
164
- expect(exception.message).toBe('Test error')
165
- expect(exception.status).toBe(400)
166
- expect(exception.code).toBe('TEST_ERROR')
167
- expect(exception.details).toEqual({ field: 'test' })
168
- expect(exception.name).toBe('APIException')
169
- expect(exception).toBeInstanceOf(Error)
170
- })
171
-
172
- it('should create APIException with minimal properties', () => {
173
- const errorData = {
174
- message: 'Minimal error',
175
- status: 500
176
- }
177
-
178
- const exception = new APIException(errorData)
179
-
180
- expect(exception.message).toBe('Minimal error')
181
- expect(exception.status).toBe(500)
182
- expect(exception.code).toBeUndefined()
183
- expect(exception.details).toBeUndefined()
184
- })
185
- })
186
- })
@@ -1,23 +0,0 @@
1
- import { describe, it, expect } from 'vitest'
2
- import { render, screen } from '@testing-library/react'
3
-
4
- // Simple React component for testing
5
- function SimpleComponent({ message }: { message: string }) {
6
- return <div data-testid="message">{message}</div>
7
- }
8
-
9
- describe('Simple React Test', () => {
10
- it('should render a simple component', () => {
11
- render(<SimpleComponent message="Hello Test!" />)
12
-
13
- const messageElement = screen.getByTestId('message')
14
- expect(messageElement).toBeInTheDocument()
15
- expect(messageElement).toHaveTextContent('Hello Test!')
16
- })
17
-
18
- it('should handle different props', () => {
19
- render(<SimpleComponent message="Different message" />)
20
-
21
- expect(screen.getByText('Different message')).toBeInTheDocument()
22
- })
23
- })
@@ -1,150 +0,0 @@
1
- import { describe, it, expect, beforeEach } from 'vitest'
2
- import { UsersController } from '@/app/server/controllers/users.controller'
3
- import type { CreateUserRequest } from '@/app/shared/types'
4
-
5
- describe('UsersController', () => {
6
- beforeEach(() => {
7
- // Reset users array before each test
8
- // Note: In a real app, you'd want to use a test database
9
- // For now, we'll test the logic with the in-memory array
10
- UsersController.resetForTesting()
11
- })
12
-
13
- describe('getUsers', () => {
14
- it('should return users list', async () => {
15
- const result = await UsersController.getUsers()
16
-
17
- expect(result).toBeDefined()
18
- expect(result.users).toBeDefined()
19
- expect(Array.isArray(result.users)).toBe(true)
20
- })
21
-
22
- it('should return users with correct structure', async () => {
23
- const result = await UsersController.getUsers()
24
-
25
- if (result.users.length > 0) {
26
- const user = result.users[0]
27
- expect(user).toHaveProperty('id')
28
- expect(user).toHaveProperty('name')
29
- expect(user).toHaveProperty('email')
30
- expect(user).toHaveProperty('createdAt')
31
- }
32
- })
33
- })
34
-
35
- describe('createUser', () => {
36
- it('should create a new user successfully', async () => {
37
- const userData: CreateUserRequest = {
38
- name: 'Test User',
39
- email: 'test@example.com'
40
- }
41
-
42
- const result = await UsersController.createUser(userData)
43
-
44
- expect(result.success).toBe(true)
45
- expect(result.user).toBeDefined()
46
- expect(result.user?.name).toBe(userData.name)
47
- expect(result.user?.email).toBe(userData.email)
48
- expect(result.user?.id).toBeDefined()
49
- expect(result.user?.createdAt).toBeDefined()
50
- })
51
-
52
- it('should prevent duplicate email addresses', async () => {
53
- const userData: CreateUserRequest = {
54
- name: 'Test User',
55
- email: 'duplicate@example.com'
56
- }
57
-
58
- // Create first user
59
- const firstResult = await UsersController.createUser(userData)
60
- expect(firstResult.success).toBe(true)
61
-
62
- // Try to create user with same email
63
- const secondResult = await UsersController.createUser(userData)
64
- expect(secondResult.success).toBe(false)
65
- expect(secondResult.message).toBe('Email já está em uso')
66
- expect(secondResult.user).toBeUndefined()
67
- })
68
-
69
- it('should generate unique IDs for different users', async () => {
70
- const user1Data: CreateUserRequest = {
71
- name: 'User 1',
72
- email: 'user1@example.com'
73
- }
74
-
75
- const user2Data: CreateUserRequest = {
76
- name: 'User 2',
77
- email: 'user2@example.com'
78
- }
79
-
80
- const result1 = await UsersController.createUser(user1Data)
81
- // Add small delay to ensure different timestamps
82
- await new Promise(resolve => setTimeout(resolve, 2))
83
- const result2 = await UsersController.createUser(user2Data)
84
-
85
- expect(result1.success).toBe(true)
86
- expect(result2.success).toBe(true)
87
- expect(result1.user?.id).not.toBe(result2.user?.id)
88
- })
89
- })
90
-
91
- describe('getUserById', () => {
92
- it('should return user when found', async () => {
93
- // First create a user
94
- const userData: CreateUserRequest = {
95
- name: 'Findable User',
96
- email: 'findable@example.com'
97
- }
98
-
99
- const createResult = await UsersController.createUser(userData)
100
- expect(createResult.success).toBe(true)
101
-
102
- const userId = createResult.user!.id
103
- const result = await UsersController.getUserById(userId)
104
-
105
- expect(result).toBeDefined()
106
- expect(result?.user).toBeDefined()
107
- expect(result?.user.id).toBe(userId)
108
- expect(result?.user.name).toBe(userData.name)
109
- expect(result?.user.email).toBe(userData.email)
110
- })
111
-
112
- it('should return null when user not found', async () => {
113
- const result = await UsersController.getUserById(99999)
114
- expect(result).toBeNull()
115
- })
116
- })
117
-
118
- describe('deleteUser', () => {
119
- it('should delete existing user successfully', async () => {
120
- // First create a user
121
- const userData: CreateUserRequest = {
122
- name: 'Deletable User',
123
- email: 'deletable@example.com'
124
- }
125
-
126
- const createResult = await UsersController.createUser(userData)
127
- expect(createResult.success).toBe(true)
128
-
129
- const userId = createResult.user!.id
130
- const deleteResult = await UsersController.deleteUser(userId)
131
-
132
- expect(deleteResult.success).toBe(true)
133
- expect(deleteResult.user).toBeDefined()
134
- expect(deleteResult.user?.id).toBe(userId)
135
- expect(deleteResult.message).toBe('Usuário deletado com sucesso')
136
-
137
- // Verify user is actually deleted
138
- const findResult = await UsersController.getUserById(userId)
139
- expect(findResult).toBeNull()
140
- })
141
-
142
- it('should return error when trying to delete non-existent user', async () => {
143
- const result = await UsersController.deleteUser(99999)
144
-
145
- expect(result.success).toBe(false)
146
- expect(result.message).toBe('Usuário não encontrado')
147
- expect(result.user).toBeUndefined()
148
- })
149
- })
150
- })