@maestro-ai/cli 1.0.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 (252) hide show
  1. package/README.md +59 -0
  2. package/content/guides/Cat/303/241logo de Stacks para Cloud Moderna.md" +119 -0
  3. package/content/guides/Cat/303/241logo de Stacks para Hospedagem Compartilhada.md" +147 -0
  4. package/content/guides/Checklist Mestre de Entrega.md +68 -0
  5. package/content/guides/Gates de Qualidade.md +209 -0
  6. package/content/guides/Guia de Adi/303/247/303/243o de Novas Funcionalidades.md" +355 -0
  7. package/content/guides/Guia de Chaos Engineering.md +267 -0
  8. package/content/guides/Guia de Debugging com IA.md +135 -0
  9. package/content/guides/Guia de Estrat/303/251gias de Cache.md" +352 -0
  10. package/content/guides/Guia de Migrations Zero-Downtime.md +311 -0
  11. package/content/guides/Guia de Multi-tenancy.md +368 -0
  12. package/content/guides/Guia de Otimiza/303/247/303/243o de Custos Cloud.md" +195 -0
  13. package/content/guides/Guia de Refatora/303/247/303/243o de C/303/263digo Legado com IA.md" +162 -0
  14. package/content/guides/Guia de SLOs e Error Budgets.md +315 -0
  15. package/content/guides/M/303/251tricas de Efici/303/252ncia do Desenvolvimento com IA.md" +93 -0
  16. package/content/guides/Rules base.md +90 -0
  17. package/content/prompts/README.md +203 -0
  18. package/content/prompts/acessibilidade/analise-acessibilidade.md +257 -0
  19. package/content/prompts/apis/design-api-rest.md +303 -0
  20. package/content/prompts/apis/idempotencia.md +254 -0
  21. package/content/prompts/apis/versionamento.md +313 -0
  22. package/content/prompts/arquitetura/arquitetura-c4-completo.md +190 -0
  23. package/content/prompts/arquitetura/clean-architecture.md +151 -0
  24. package/content/prompts/arquitetura/ddd-bounded-contexts.md +183 -0
  25. package/content/prompts/arquitetura/ddd-cqrs.md +176 -0
  26. package/content/prompts/arquitetura/modelo-dominio.md +207 -0
  27. package/content/prompts/arquitetura/multi-tenancy.md +235 -0
  28. package/content/prompts/database/migrations-zero-downtime.md +192 -0
  29. package/content/prompts/database/otimizacao-queries.md +296 -0
  30. package/content/prompts/desenvolvimento/code-review.md +301 -0
  31. package/content/prompts/desenvolvimento/gerar-servico.md +271 -0
  32. package/content/prompts/devops/docker-compose.md +336 -0
  33. package/content/prompts/devops/feature-flags.md +374 -0
  34. package/content/prompts/devops/kubernetes-deploy.md +460 -0
  35. package/content/prompts/devops/pipeline-cicd.md +358 -0
  36. package/content/prompts/devops/terraform-iac.md +502 -0
  37. package/content/prompts/escalabilidade/analise-performance.md +240 -0
  38. package/content/prompts/escalabilidade/analise-performance.txt +94 -0
  39. package/content/prompts/escalabilidade/caching.md +255 -0
  40. package/content/prompts/observabilidade/chaos-testing.md +237 -0
  41. package/content/prompts/observabilidade/estrategia-observabilidade.md +263 -0
  42. package/content/prompts/observabilidade/estrategia-observabilidade.txt +134 -0
  43. package/content/prompts/observabilidade/slos.md +215 -0
  44. package/content/prompts/produto/discovery-inicial.md +203 -0
  45. package/content/prompts/produto/discovery-inicial.txt +33 -0
  46. package/content/prompts/requisitos/refinar-requisitos.md +232 -0
  47. package/content/prompts/requisitos/refinar-requisitos.txt +40 -0
  48. package/content/prompts/seguranca/analise-seguranca.md +243 -0
  49. package/content/prompts/seguranca/pentest-checklist.md +333 -0
  50. package/content/prompts/seguranca/rate-limiting.md +356 -0
  51. package/content/prompts/seguranca/revisao-lgpd.md +227 -0
  52. package/content/prompts/seguranca/threat-modeling.md +224 -0
  53. package/content/prompts/testes/contract-testing.md +340 -0
  54. package/content/prompts/testes/gerar-testes-unitarios.md +474 -0
  55. package/content/prompts/testes/testes-e2e.md +460 -0
  56. package/content/prompts/testes/testes-integracao.md +418 -0
  57. package/content/prompts/testes/testes-performance.md +458 -0
  58. package/content/prompts/ux/gerar-ui-stitch.md +151 -0
  59. package/content/skills/api-patterns/SKILL.md +81 -0
  60. package/content/skills/api-patterns/api-style.md +42 -0
  61. package/content/skills/api-patterns/auth.md +24 -0
  62. package/content/skills/api-patterns/documentation.md +26 -0
  63. package/content/skills/api-patterns/graphql.md +41 -0
  64. package/content/skills/api-patterns/rate-limiting.md +31 -0
  65. package/content/skills/api-patterns/response.md +37 -0
  66. package/content/skills/api-patterns/rest.md +40 -0
  67. package/content/skills/api-patterns/scripts/api_validator.py +211 -0
  68. package/content/skills/api-patterns/security-testing.md +122 -0
  69. package/content/skills/api-patterns/trpc.md +41 -0
  70. package/content/skills/api-patterns/versioning.md +22 -0
  71. package/content/skills/app-builder/SKILL.md +75 -0
  72. package/content/skills/app-builder/agent-coordination.md +71 -0
  73. package/content/skills/app-builder/feature-building.md +53 -0
  74. package/content/skills/app-builder/project-detection.md +34 -0
  75. package/content/skills/app-builder/scaffolding.md +118 -0
  76. package/content/skills/app-builder/tech-stack.md +40 -0
  77. package/content/skills/app-builder/templates/SKILL.md +39 -0
  78. package/content/skills/app-builder/templates/astro-static/TEMPLATE.md +76 -0
  79. package/content/skills/app-builder/templates/chrome-extension/TEMPLATE.md +92 -0
  80. package/content/skills/app-builder/templates/cli-tool/TEMPLATE.md +88 -0
  81. package/content/skills/app-builder/templates/electron-desktop/TEMPLATE.md +88 -0
  82. package/content/skills/app-builder/templates/express-api/TEMPLATE.md +83 -0
  83. package/content/skills/app-builder/templates/flutter-app/TEMPLATE.md +90 -0
  84. package/content/skills/app-builder/templates/monorepo-turborepo/TEMPLATE.md +90 -0
  85. package/content/skills/app-builder/templates/nextjs-fullstack/TEMPLATE.md +82 -0
  86. package/content/skills/app-builder/templates/nextjs-saas/TEMPLATE.md +100 -0
  87. package/content/skills/app-builder/templates/nextjs-static/TEMPLATE.md +106 -0
  88. package/content/skills/app-builder/templates/nuxt-app/TEMPLATE.md +101 -0
  89. package/content/skills/app-builder/templates/python-fastapi/TEMPLATE.md +83 -0
  90. package/content/skills/app-builder/templates/react-native-app/TEMPLATE.md +93 -0
  91. package/content/skills/architecture/SKILL.md +55 -0
  92. package/content/skills/architecture/context-discovery.md +43 -0
  93. package/content/skills/architecture/examples.md +94 -0
  94. package/content/skills/architecture/pattern-selection.md +68 -0
  95. package/content/skills/architecture/patterns-reference.md +50 -0
  96. package/content/skills/architecture/trade-off-analysis.md +77 -0
  97. package/content/skills/bash-linux/SKILL.md +199 -0
  98. package/content/skills/behavioral-modes/SKILL.md +242 -0
  99. package/content/skills/brainstorming/SKILL.md +163 -0
  100. package/content/skills/brainstorming/dynamic-questioning.md +350 -0
  101. package/content/skills/clean-code/SKILL.md +201 -0
  102. package/content/skills/code-review-checklist/SKILL.md +109 -0
  103. package/content/skills/database-design/SKILL.md +52 -0
  104. package/content/skills/database-design/database-selection.md +43 -0
  105. package/content/skills/database-design/indexing.md +39 -0
  106. package/content/skills/database-design/migrations.md +48 -0
  107. package/content/skills/database-design/optimization.md +36 -0
  108. package/content/skills/database-design/orm-selection.md +30 -0
  109. package/content/skills/database-design/schema-design.md +56 -0
  110. package/content/skills/database-design/scripts/schema_validator.py +172 -0
  111. package/content/skills/deployment-procedures/SKILL.md +241 -0
  112. package/content/skills/doc.md +177 -0
  113. package/content/skills/documentation-templates/SKILL.md +194 -0
  114. package/content/skills/frontend-design/SKILL.md +396 -0
  115. package/content/skills/frontend-design/animation-guide.md +331 -0
  116. package/content/skills/frontend-design/color-system.md +311 -0
  117. package/content/skills/frontend-design/decision-trees.md +418 -0
  118. package/content/skills/frontend-design/motion-graphics.md +306 -0
  119. package/content/skills/frontend-design/scripts/accessibility_checker.py +183 -0
  120. package/content/skills/frontend-design/scripts/ux_audit.py +722 -0
  121. package/content/skills/frontend-design/typography-system.md +345 -0
  122. package/content/skills/frontend-design/ux-psychology.md +541 -0
  123. package/content/skills/frontend-design/visual-effects.md +383 -0
  124. package/content/skills/game-development/2d-games/SKILL.md +119 -0
  125. package/content/skills/game-development/3d-games/SKILL.md +135 -0
  126. package/content/skills/game-development/SKILL.md +167 -0
  127. package/content/skills/game-development/game-art/SKILL.md +185 -0
  128. package/content/skills/game-development/game-audio/SKILL.md +190 -0
  129. package/content/skills/game-development/game-design/SKILL.md +129 -0
  130. package/content/skills/game-development/mobile-games/SKILL.md +108 -0
  131. package/content/skills/game-development/multiplayer/SKILL.md +132 -0
  132. package/content/skills/game-development/pc-games/SKILL.md +144 -0
  133. package/content/skills/game-development/vr-ar/SKILL.md +123 -0
  134. package/content/skills/game-development/web-games/SKILL.md +150 -0
  135. package/content/skills/geo-fundamentals/SKILL.md +156 -0
  136. package/content/skills/geo-fundamentals/scripts/geo_checker.py +289 -0
  137. package/content/skills/i18n-localization/SKILL.md +154 -0
  138. package/content/skills/i18n-localization/scripts/i18n_checker.py +241 -0
  139. package/content/skills/intelligent-routing/SKILL.md +334 -0
  140. package/content/skills/lint-and-validate/SKILL.md +45 -0
  141. package/content/skills/lint-and-validate/scripts/lint_runner.py +172 -0
  142. package/content/skills/lint-and-validate/scripts/type_coverage.py +173 -0
  143. package/content/skills/mcp-builder/SKILL.md +176 -0
  144. package/content/skills/mobile-design/SKILL.md +394 -0
  145. package/content/skills/mobile-design/decision-trees.md +516 -0
  146. package/content/skills/mobile-design/mobile-backend.md +491 -0
  147. package/content/skills/mobile-design/mobile-color-system.md +420 -0
  148. package/content/skills/mobile-design/mobile-debugging.md +122 -0
  149. package/content/skills/mobile-design/mobile-design-thinking.md +357 -0
  150. package/content/skills/mobile-design/mobile-navigation.md +458 -0
  151. package/content/skills/mobile-design/mobile-performance.md +767 -0
  152. package/content/skills/mobile-design/mobile-testing.md +356 -0
  153. package/content/skills/mobile-design/mobile-typography.md +433 -0
  154. package/content/skills/mobile-design/platform-android.md +666 -0
  155. package/content/skills/mobile-design/platform-ios.md +561 -0
  156. package/content/skills/mobile-design/scripts/mobile_audit.py +670 -0
  157. package/content/skills/mobile-design/touch-psychology.md +537 -0
  158. package/content/skills/nextjs-best-practices/SKILL.md +203 -0
  159. package/content/skills/nodejs-best-practices/SKILL.md +333 -0
  160. package/content/skills/parallel-agents/SKILL.md +175 -0
  161. package/content/skills/performance-profiling/SKILL.md +143 -0
  162. package/content/skills/performance-profiling/scripts/lighthouse_audit.py +76 -0
  163. package/content/skills/plan-writing/SKILL.md +152 -0
  164. package/content/skills/powershell-windows/SKILL.md +167 -0
  165. package/content/skills/python-patterns/SKILL.md +441 -0
  166. package/content/skills/react-patterns/SKILL.md +198 -0
  167. package/content/skills/red-team-tactics/SKILL.md +199 -0
  168. package/content/skills/seo-fundamentals/SKILL.md +129 -0
  169. package/content/skills/seo-fundamentals/scripts/seo_checker.py +219 -0
  170. package/content/skills/server-management/SKILL.md +161 -0
  171. package/content/skills/systematic-debugging/SKILL.md +109 -0
  172. package/content/skills/tailwind-patterns/SKILL.md +269 -0
  173. package/content/skills/tdd-workflow/SKILL.md +149 -0
  174. package/content/skills/testing-patterns/SKILL.md +178 -0
  175. package/content/skills/testing-patterns/scripts/test_runner.py +219 -0
  176. package/content/skills/vulnerability-scanner/SKILL.md +276 -0
  177. package/content/skills/vulnerability-scanner/checklists.md +121 -0
  178. package/content/skills/vulnerability-scanner/scripts/security_scan.py +458 -0
  179. package/content/skills/webapp-testing/SKILL.md +187 -0
  180. package/content/skills/webapp-testing/scripts/playwright_runner.py +173 -0
  181. package/content/specialists/Especialista em Acessibilidade.md +266 -0
  182. package/content/specialists/Especialista em An/303/241lise de Testes.md" +434 -0
  183. package/content/specialists/Especialista em Arquitetura Avan/303/247ada.md" +358 -0
  184. package/content/specialists/Especialista em Arquitetura de Software.md +177 -0
  185. package/content/specialists/Especialista em Banco de Dados.md +260 -0
  186. package/content/specialists/Especialista em Contrato de API.md +172 -0
  187. package/content/specialists/Especialista em Dados e Analytics com IA.md +246 -0
  188. package/content/specialists/Especialista em Debugging e Troubleshooting.md +191 -0
  189. package/content/specialists/Especialista em Desenvolvimento Frontend.md +477 -0
  190. package/content/specialists/Especialista em Desenvolvimento Mobile.md +241 -0
  191. package/content/specialists/Especialista em Desenvolvimento e Vibe Coding Estruturado.md +417 -0
  192. package/content/specialists/Especialista em DevOps e Infraestrutura.md +294 -0
  193. package/content/specialists/Especialista em Documenta/303/247/303/243o T/303/251cnica.md" +227 -0
  194. package/content/specialists/Especialista em Engenharia de Requisitos com IA.md +299 -0
  195. package/content/specialists/Especialista em Explora/303/247/303/243o de Codebase.md" +179 -0
  196. package/content/specialists/Especialista em Gest/303/243o de Produto.md" +179 -0
  197. package/content/specialists/Especialista em Migra/303/247/303/243o e Moderniza/303/247/303/243o.md" +410 -0
  198. package/content/specialists/Especialista em Modelagem e Arquitetura de Dom/303/255nio com IA.md" +248 -0
  199. package/content/specialists/Especialista em Observabilidade.md +415 -0
  200. package/content/specialists/Especialista em Performance e Escalabilidade.md +373 -0
  201. package/content/specialists/Especialista em Plano de Execu/303/247/303/243o com IA.md" +341 -0
  202. package/content/specialists/Especialista em Prototipagem R/303/241pida com Google Stitch.md" +419 -0
  203. package/content/specialists/Especialista em Seguran/303/247a da Informa/303/247/303/243o.md" +508 -0
  204. package/content/specialists/Especialista em UX Design.md +453 -0
  205. package/content/specialists/INDEX.md +43 -0
  206. package/content/templates/PRD.md +165 -0
  207. package/content/templates/README.md +65 -0
  208. package/content/templates/adr.md +103 -0
  209. package/content/templates/arquitetura.md +279 -0
  210. package/content/templates/backlog.md +185 -0
  211. package/content/templates/checklist-seguranca.md +180 -0
  212. package/content/templates/contexto.md +120 -0
  213. package/content/templates/criterios-aceite.md +99 -0
  214. package/content/templates/design-banco.md +270 -0
  215. package/content/templates/design-doc.md +240 -0
  216. package/content/templates/feature.md +88 -0
  217. package/content/templates/historia-backend.md +84 -0
  218. package/content/templates/historia-frontend.md +75 -0
  219. package/content/templates/historia-usuario.md +125 -0
  220. package/content/templates/mapa-navegacao.md +133 -0
  221. package/content/templates/matriz-rastreabilidade.md +121 -0
  222. package/content/templates/modelo-dominio.md +219 -0
  223. package/content/templates/plano-testes.md +199 -0
  224. package/content/templates/prototipo-stitch.md +138 -0
  225. package/content/templates/requisitos.md +162 -0
  226. package/content/templates/slo-sli.md +197 -0
  227. package/content/workflows/README-MCP.md +363 -0
  228. package/content/workflows/brainstorm.md +113 -0
  229. package/content/workflows/create.md +59 -0
  230. package/content/workflows/debug.md +103 -0
  231. package/content/workflows/deploy.md +176 -0
  232. package/content/workflows/enhance.md +63 -0
  233. package/content/workflows/mcp-debug.md +506 -0
  234. package/content/workflows/mcp-feature.md +385 -0
  235. package/content/workflows/mcp-gate.md +413 -0
  236. package/content/workflows/mcp-next.md +388 -0
  237. package/content/workflows/mcp-refactor.md +600 -0
  238. package/content/workflows/mcp-start.md +304 -0
  239. package/content/workflows/mcp-status.md +400 -0
  240. package/content/workflows/orchestrate.md +237 -0
  241. package/content/workflows/plan.md +89 -0
  242. package/content/workflows/preview.md +81 -0
  243. package/content/workflows/status.md +86 -0
  244. package/content/workflows/test.md +144 -0
  245. package/content/workflows/ui-ux-pro-max.md +296 -0
  246. package/dist/commands/init.d.ts +6 -0
  247. package/dist/commands/init.js +138 -0
  248. package/dist/commands/update.d.ts +5 -0
  249. package/dist/commands/update.js +50 -0
  250. package/dist/index.d.ts +2 -0
  251. package/dist/index.js +21 -0
  252. package/package.json +48 -0
@@ -0,0 +1,474 @@
1
+ # Prompt: Gerar Testes Unitários
2
+
3
+ > **Quando usar**: Após implementar uma classe/função, para criar testes
4
+ > **Especialista**: [Análise de Testes](../../02-especialistas/Especialista%20em%20Análise%20de%20Testes.md)
5
+ > **Nível**: Simples a Médio
6
+
7
+ ---
8
+
9
+ ## Fluxo de Contexto
10
+
11
+ Antes de usar este prompt, tenha em mãos:
12
+ - Código da classe/função a ser testada
13
+ - Entendimento das regras de negócio
14
+
15
+ Após gerar, salve os testes em:
16
+ - `src/__tests__/` ou `tests/` conforme convenção do projeto
17
+
18
+ ---
19
+
20
+ ## Prompt Completo
21
+
22
+ ```text
23
+ Atue como engenheiro de qualidade especializado em testes automatizados.
24
+
25
+ ## Contexto do Projeto
26
+
27
+ [COLE BREVE CONTEXTO - O que o sistema faz]
28
+
29
+ ## Código a Testar
30
+
31
+ ```[LINGUAGEM]
32
+ [COLE O CÓDIGO DA CLASSE/FUNÇÃO]
33
+ ```
34
+
35
+ ## Stack de Testes
36
+
37
+ Framework: [Jest/Pytest/JUnit/xUnit/Vitest/etc]
38
+ Linguagem: [TypeScript/Python/Java/C#/etc]
39
+ Mocking: [jest.mock/unittest.mock/Mockito/etc]
40
+
41
+ ---
42
+
43
+ ## Sua Missão
44
+
45
+ Gere testes unitários completos seguindo boas práticas:
46
+
47
+ ### 1. Estrutura dos Testes
48
+
49
+ Use o padrão AAA (Arrange, Act, Assert):
50
+ - **Arrange**: Preparar dados e mocks
51
+ - **Act**: Executar a ação
52
+ - **Assert**: Verificar resultado
53
+
54
+ ### 2. Cenários Obrigatórios
55
+
56
+ Para cada método público, cubra:
57
+
58
+ #### Happy Path
59
+ - Fluxo de sucesso com dados válidos
60
+ - Retorno esperado correto
61
+
62
+ #### Edge Cases (Casos de Borda)
63
+ - Valores mínimos/máximos
64
+ - Listas vazias
65
+ - Strings vazias
66
+ - Null/undefined (se aplicável)
67
+ - Zero, números negativos
68
+
69
+ #### Error Cases
70
+ - Entradas inválidas
71
+ - Exceções esperadas
72
+ - Mensagens de erro corretas
73
+
74
+ #### Validation Cases
75
+ - Cada regra de validação testada
76
+ - Combinações de validações
77
+
78
+ ### 3. Mocking
79
+
80
+ Para cada dependência (repositório, serviço externo):
81
+ - Mock da dependência
82
+ - Configurar retornos para cada cenário
83
+ - Verificar que foi chamado corretamente
84
+
85
+ ### 4. Formato do Teste
86
+
87
+ ```
88
+ describe('[NomeClasse]', () => {
89
+ describe('[nomeMetodo]', () => {
90
+ it('deve [fazer algo] quando [condição]', () => {
91
+ // Arrange
92
+ // Act
93
+ // Assert
94
+ });
95
+ });
96
+ });
97
+ ```
98
+
99
+ ### 5. Comentários
100
+
101
+ Para cada teste, inclua:
102
+ - Comentário de 1 linha explicando o que garante
103
+ - Anotação se é happy path, edge case ou error case
104
+
105
+ ### 6. Coverage Mínimo
106
+
107
+ - Todas as branches (if/else)
108
+ - Todos os catches de exceção
109
+ - Todos os retornos possíveis
110
+ ```
111
+
112
+ ---
113
+
114
+ ## Exemplo de Uso
115
+
116
+ ```text
117
+ Atue como engenheiro de qualidade especializado em testes automatizados.
118
+
119
+ ## Contexto do Projeto
120
+
121
+ Sistema de agendamento para salões de beleza.
122
+
123
+ ## Código a Testar
124
+
125
+ ```typescript
126
+ @Injectable()
127
+ export class AgendamentoService {
128
+ constructor(
129
+ private readonly repository: AgendamentoRepository,
130
+ private readonly notificacao: NotificacaoService,
131
+ ) {}
132
+
133
+ async criar(dto: CriarAgendamentoDto): Promise<Agendamento> {
134
+ if (dto.dataHora < new Date()) {
135
+ throw new BadRequestException('Não é possível agendar no passado');
136
+ }
137
+
138
+ const conflito = await this.repository.findByHorario(dto.dataHora);
139
+ if (conflito) {
140
+ throw new ConflictException('Horário já ocupado');
141
+ }
142
+
143
+ const agendamento = await this.repository.create({
144
+ ...dto,
145
+ status: StatusAgendamento.PENDENTE,
146
+ });
147
+
148
+ await this.notificacao.enviarConfirmacao(agendamento);
149
+ return agendamento;
150
+ }
151
+
152
+ async cancelar(id: string): Promise<void> {
153
+ const agendamento = await this.repository.findById(id);
154
+
155
+ const limite = new Date(agendamento.dataHora);
156
+ limite.setHours(limite.getHours() - 2);
157
+
158
+ if (new Date() > limite) {
159
+ throw new BadRequestException('Cancelamento só até 2h antes');
160
+ }
161
+
162
+ await this.repository.updateStatus(id, StatusAgendamento.CANCELADO);
163
+ }
164
+ }
165
+ ```
166
+
167
+ ## Stack de Testes
168
+
169
+ Framework: Jest
170
+ Linguagem: TypeScript
171
+ Mocking: jest.mock
172
+ ```
173
+
174
+ ---
175
+
176
+ ## Resposta Esperada
177
+
178
+ ```typescript
179
+ import { Test, TestingModule } from '@nestjs/testing';
180
+ import { AgendamentoService } from './agendamento.service';
181
+ import { AgendamentoRepository } from './agendamento.repository';
182
+ import { NotificacaoService } from '../notificacao/notificacao.service';
183
+ import { BadRequestException, ConflictException } from '@nestjs/common';
184
+ import { StatusAgendamento } from './enums/status-agendamento.enum';
185
+
186
+ describe('AgendamentoService', () => {
187
+ let service: AgendamentoService;
188
+ let repository: jest.Mocked<AgendamentoRepository>;
189
+ let notificacao: jest.Mocked<NotificacaoService>;
190
+
191
+ // Factory para criar DTOs de teste
192
+ const criarDto = (overrides = {}) => ({
193
+ clienteId: 'cliente-123',
194
+ servicoId: 'servico-456',
195
+ dataHora: new Date(Date.now() + 86400000), // amanhã
196
+ ...overrides,
197
+ });
198
+
199
+ // Factory para criar entidade mock
200
+ const criarAgendamento = (overrides = {}) => ({
201
+ id: 'agendamento-789',
202
+ ...criarDto(),
203
+ status: StatusAgendamento.PENDENTE,
204
+ criadoEm: new Date(),
205
+ ...overrides,
206
+ });
207
+
208
+ beforeEach(async () => {
209
+ // Arrange: Setup dos mocks
210
+ const module: TestingModule = await Test.createTestingModule({
211
+ providers: [
212
+ AgendamentoService,
213
+ {
214
+ provide: AgendamentoRepository,
215
+ useValue: {
216
+ findById: jest.fn(),
217
+ findByHorario: jest.fn(),
218
+ create: jest.fn(),
219
+ updateStatus: jest.fn(),
220
+ },
221
+ },
222
+ {
223
+ provide: NotificacaoService,
224
+ useValue: {
225
+ enviarConfirmacao: jest.fn(),
226
+ },
227
+ },
228
+ ],
229
+ }).compile();
230
+
231
+ service = module.get<AgendamentoService>(AgendamentoService);
232
+ repository = module.get(AgendamentoRepository);
233
+ notificacao = module.get(NotificacaoService);
234
+ });
235
+
236
+ describe('criar', () => {
237
+ // ========== HAPPY PATH ==========
238
+
239
+ // Garante que agendamento válido é criado com sucesso
240
+ it('deve criar agendamento quando horário está disponível', async () => {
241
+ // Arrange
242
+ const dto = criarDto();
243
+ const agendamentoCriado = criarAgendamento();
244
+ repository.findByHorario.mockResolvedValue(null);
245
+ repository.create.mockResolvedValue(agendamentoCriado);
246
+ notificacao.enviarConfirmacao.mockResolvedValue(undefined);
247
+
248
+ // Act
249
+ const resultado = await service.criar(dto);
250
+
251
+ // Assert
252
+ expect(resultado).toEqual(agendamentoCriado);
253
+ expect(resultado.status).toBe(StatusAgendamento.PENDENTE);
254
+ expect(repository.create).toHaveBeenCalledWith({
255
+ ...dto,
256
+ status: StatusAgendamento.PENDENTE,
257
+ });
258
+ });
259
+
260
+ // Garante que notificação é enviada após criar
261
+ it('deve enviar notificação após criar agendamento', async () => {
262
+ // Arrange
263
+ const dto = criarDto();
264
+ const agendamentoCriado = criarAgendamento();
265
+ repository.findByHorario.mockResolvedValue(null);
266
+ repository.create.mockResolvedValue(agendamentoCriado);
267
+
268
+ // Act
269
+ await service.criar(dto);
270
+
271
+ // Assert
272
+ expect(notificacao.enviarConfirmacao).toHaveBeenCalledWith(agendamentoCriado);
273
+ expect(notificacao.enviarConfirmacao).toHaveBeenCalledTimes(1);
274
+ });
275
+
276
+ // ========== ERROR CASES ==========
277
+
278
+ // Garante que data no passado é rejeitada
279
+ it('deve lançar BadRequestException quando data é no passado', async () => {
280
+ // Arrange
281
+ const dto = criarDto({
282
+ dataHora: new Date('2020-01-01'), // data no passado
283
+ });
284
+
285
+ // Act & Assert
286
+ await expect(service.criar(dto)).rejects.toThrow(BadRequestException);
287
+ await expect(service.criar(dto)).rejects.toThrow('Não é possível agendar no passado');
288
+ expect(repository.create).not.toHaveBeenCalled();
289
+ });
290
+
291
+ // Garante que conflito de horário é tratado
292
+ it('deve lançar ConflictException quando horário já está ocupado', async () => {
293
+ // Arrange
294
+ const dto = criarDto();
295
+ const agendamentoExistente = criarAgendamento();
296
+ repository.findByHorario.mockResolvedValue(agendamentoExistente);
297
+
298
+ // Act & Assert
299
+ await expect(service.criar(dto)).rejects.toThrow(ConflictException);
300
+ await expect(service.criar(dto)).rejects.toThrow('Horário já ocupado');
301
+ expect(repository.create).not.toHaveBeenCalled();
302
+ });
303
+
304
+ // ========== EDGE CASES ==========
305
+
306
+ // Garante que data exatamente no momento atual é rejeitada
307
+ it('deve rejeitar agendamento com data igual ao momento atual', async () => {
308
+ // Arrange
309
+ const agora = new Date();
310
+ const dto = criarDto({ dataHora: agora });
311
+
312
+ // Act & Assert
313
+ await expect(service.criar(dto)).rejects.toThrow(BadRequestException);
314
+ });
315
+ });
316
+
317
+ describe('cancelar', () => {
318
+ // ========== HAPPY PATH ==========
319
+
320
+ // Garante que cancelamento funciona quando dentro do limite
321
+ it('deve cancelar agendamento quando falta mais de 2h', async () => {
322
+ // Arrange
323
+ const treHorasDepois = new Date(Date.now() + 3 * 60 * 60 * 1000);
324
+ const agendamento = criarAgendamento({ dataHora: treHorasDepois });
325
+ repository.findById.mockResolvedValue(agendamento);
326
+
327
+ // Act
328
+ await service.cancelar('agendamento-789');
329
+
330
+ // Assert
331
+ expect(repository.updateStatus).toHaveBeenCalledWith(
332
+ 'agendamento-789',
333
+ StatusAgendamento.CANCELADO,
334
+ );
335
+ });
336
+
337
+ // ========== ERROR CASES ==========
338
+
339
+ // Garante que cancelamento tardio é rejeitado
340
+ it('deve lançar BadRequestException quando falta menos de 2h', async () => {
341
+ // Arrange
342
+ const umaHoraDepois = new Date(Date.now() + 1 * 60 * 60 * 1000);
343
+ const agendamento = criarAgendamento({ dataHora: umaHoraDepois });
344
+ repository.findById.mockResolvedValue(agendamento);
345
+
346
+ // Act & Assert
347
+ await expect(service.cancelar('agendamento-789')).rejects.toThrow(
348
+ BadRequestException,
349
+ );
350
+ await expect(service.cancelar('agendamento-789')).rejects.toThrow(
351
+ 'Cancelamento só até 2h antes',
352
+ );
353
+ expect(repository.updateStatus).not.toHaveBeenCalled();
354
+ });
355
+
356
+ // ========== EDGE CASES ==========
357
+
358
+ // Garante que exatamente 2h antes ainda permite cancelar
359
+ it('deve permitir cancelamento exatamente 2h antes', async () => {
360
+ // Arrange
361
+ const exatamenteDuasHoras = new Date(Date.now() + 2 * 60 * 60 * 1000 + 1000);
362
+ const agendamento = criarAgendamento({ dataHora: exatamenteDuasHoras });
363
+ repository.findById.mockResolvedValue(agendamento);
364
+
365
+ // Act
366
+ await service.cancelar('agendamento-789');
367
+
368
+ // Assert
369
+ expect(repository.updateStatus).toHaveBeenCalled();
370
+ });
371
+ });
372
+ });
373
+ ```
374
+
375
+ ---
376
+
377
+ ## Variações por Framework
378
+
379
+ ### Python + Pytest
380
+
381
+ ```python
382
+ import pytest
383
+ from unittest.mock import Mock, AsyncMock
384
+ from datetime import datetime, timedelta
385
+ from app.services.agendamento_service import AgendamentoService
386
+ from app.exceptions import BadRequestError, ConflictError
387
+
388
+ class TestAgendamentoService:
389
+ @pytest.fixture
390
+ def repository(self):
391
+ return Mock()
392
+
393
+ @pytest.fixture
394
+ def service(self, repository):
395
+ return AgendamentoService(repository)
396
+
397
+ # Garante que agendamento válido é criado
398
+ async def test_criar_agendamento_sucesso(self, service, repository):
399
+ # Arrange
400
+ dto = {"data_hora": datetime.now() + timedelta(days=1)}
401
+ repository.find_by_horario.return_value = None
402
+ repository.create.return_value = {"id": "123", **dto}
403
+
404
+ # Act
405
+ resultado = await service.criar(dto)
406
+
407
+ # Assert
408
+ assert resultado["id"] == "123"
409
+ repository.create.assert_called_once()
410
+
411
+ # Garante que data passada é rejeitada
412
+ async def test_criar_agendamento_data_passada(self, service):
413
+ # Arrange
414
+ dto = {"data_hora": datetime(2020, 1, 1)}
415
+
416
+ # Act & Assert
417
+ with pytest.raises(BadRequestError):
418
+ await service.criar(dto)
419
+ ```
420
+
421
+ ### Java + JUnit
422
+
423
+ ```java
424
+ @ExtendWith(MockitoExtension.class)
425
+ class AgendamentoServiceTest {
426
+
427
+ @Mock
428
+ private AgendamentoRepository repository;
429
+
430
+ @InjectMocks
431
+ private AgendamentoService service;
432
+
433
+ // Garante que agendamento válido é criado
434
+ @Test
435
+ void deveCriarAgendamentoQuandoHorarioDisponivel() {
436
+ // Arrange
437
+ var dto = new CriarAgendamentoDto(LocalDateTime.now().plusDays(1));
438
+ when(repository.findByHorario(any())).thenReturn(Optional.empty());
439
+ when(repository.create(any())).thenReturn(new Agendamento());
440
+
441
+ // Act
442
+ var resultado = service.criar(dto);
443
+
444
+ // Assert
445
+ assertNotNull(resultado);
446
+ verify(repository).create(any());
447
+ }
448
+
449
+ // Garante que data passada é rejeitada
450
+ @Test
451
+ void deveLancarExcecaoQuandoDataPassada() {
452
+ // Arrange
453
+ var dto = new CriarAgendamentoDto(LocalDateTime.of(2020, 1, 1, 10, 0));
454
+
455
+ // Act & Assert
456
+ assertThrows(BadRequestException.class, () -> service.criar(dto));
457
+ }
458
+ }
459
+ ```
460
+
461
+ ---
462
+
463
+ ## Checklist Pós-Geração
464
+
465
+ - [ ] Todos os métodos públicos têm pelo menos 1 teste
466
+ - [ ] Happy path testado para cada método
467
+ - [ ] Error cases testados (exceções)
468
+ - [ ] Edge cases testados (limites, vazios, nulls)
469
+ - [ ] Mocks configurados corretamente
470
+ - [ ] Padrão AAA seguido (Arrange, Act, Assert)
471
+ - [ ] Cada teste tem comentário explicando o que garante
472
+ - [ ] Factories criadas para dados de teste
473
+ - [ ] Nenhum teste depende de outro (isolamento)
474
+ - [ ] Rodar testes e verificar que passam