create-dp-koa 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 (235) hide show
  1. package/README.md +50 -0
  2. package/index.mjs +97 -0
  3. package/package.json +33 -0
  4. package/template/.env.development +9 -0
  5. package/template/.env.production +12 -0
  6. package/template/.github/workflows/ci-cd.yml +182 -0
  7. package/template/.trae/documents/controller_development_plan.md +386 -0
  8. package/template/.trae/skills/00-backend-core.skill.md +50 -0
  9. package/template/.trae/skills/01-backend-skill-router.skill.md +55 -0
  10. package/template/.trae/skills/10-backend-api.skill.md +54 -0
  11. package/template/.trae/skills/11-backend-controller-recipes.skill.md +107 -0
  12. package/template/.trae/skills/20-backend-repository.skill.md +25 -0
  13. package/template/.trae/skills/21-backend-service.skill.md +135 -0
  14. package/template/.trae/skills/25-backend-comments-and-doc.skill.md +97 -0
  15. package/template/.trae/skills/30-backend-validation.skill.md +320 -0
  16. package/template/.trae/skills/40-backend-error-logging.skill.md +21 -0
  17. package/template/.trae/skills/50-backend-bootstrap-lifecycle.skill.md +90 -0
  18. package/template/.trae/skills/60-backend-router-registration.skill.md +71 -0
  19. package/template/.trae/skills/70-backend-middleware.skill.md +98 -0
  20. package/template/.trae/skills/80-backend-utils-and-libs.skill.md +90 -0
  21. package/template/.trae/skills/85-backend-plugins.rule.md +64 -0
  22. package/template/.trae/skills/90-backend-testing.skill.md +29 -0
  23. package/template/.trae/skills/README.md +49 -0
  24. package/template/.vscode/launch.json +38 -0
  25. package/template/.vscode/settings.json +1 -0
  26. package/template/Dockerfile +36 -0
  27. package/template/README.md +229 -0
  28. package/template/docker-compose.yml +135 -0
  29. package/template/docs/API_DOCUMENTATION.md +837 -0
  30. package/template/docs/ARCHITECTURE_REFACTOR.md +109 -0
  31. package/template/docs/CACHE_MIGRATION_GUIDE.md +142 -0
  32. package/template/docs/DEPLOYMENT_GUIDE.md +1062 -0
  33. package/template/docs/DEVELOPMENT_GUIDE.md +1097 -0
  34. package/template/docs/DOCUMENTATION_CLEANUP_REPORT.md +166 -0
  35. package/template/docs/DOCUMENTATION_COMPLETION_REPORT.md +223 -0
  36. package/template/docs/DOCUMENTATION_INDEX.md +294 -0
  37. package/template/docs/DOCUMENTATION_STRUCTURE.md +221 -0
  38. package/template/docs/ENTERPRISE_ANNOTATION_SYSTEM_GUIDE.md +2069 -0
  39. package/template/docs/ENTERPRISE_DATABASE_ARCHITECTURE.md +318 -0
  40. package/template/docs/ENTERPRISE_DEPLOYMENT_GUIDE.md +547 -0
  41. package/template/docs/ENTERPRISE_ERROR_HANDLING_GUIDE.md +357 -0
  42. package/template/docs/ENTERPRISE_LOGGING_SYSTEM_GUIDE.md +494 -0
  43. package/template/docs/ENVIRONMENT_CONFIG_EXAMPLE.md +69 -0
  44. package/template/docs/FINAL_IMPLEMENTATION_SUMMARY.md +206 -0
  45. package/template/docs/HEALTH_CHECK_ROUTE_FIX.md +134 -0
  46. package/template/docs/IMPLEMENTATION_CHECKLIST.md +204 -0
  47. package/template/docs/INSTALLATION_GUIDE.md +611 -0
  48. package/template/docs/INTERCEPTOR_TESTING_REPORT.md +226 -0
  49. package/template/docs/INTERCEPTOR_TESTING_SCRIPTS.md +143 -0
  50. package/template/docs/LOGGING_OPTIMIZATION_GUIDE.md +126 -0
  51. package/template/docs/MEMORY_DATABASE_GUIDE.md +212 -0
  52. package/template/docs/NEW_ROUTER_INTEGRATION_GUIDE.md +345 -0
  53. package/template/docs/NEW_ROUTER_INTEGRATION_SUMMARY.md +259 -0
  54. package/template/docs/NEW_ROUTER_USAGE_GUIDE.md +364 -0
  55. package/template/docs/QUICK_START.md +268 -0
  56. package/template/docs/ROUTE_SLASH_COMPATIBILITY_FIX.md +191 -0
  57. package/template/docs/SERVICE_INTERCEPTOR_GUIDE.md +243 -0
  58. package/template/docs/SERVICE_LAYER_INDEX.md +205 -0
  59. package/template/docs/SERVICE_PATTERN_GUIDE.md +270 -0
  60. package/template/docs/SERVICE_RETURN_VALUE_SPECIFICATION.md +466 -0
  61. package/template/docs/SWAGGER_DEBUG_MODE_GUIDE.md +80 -0
  62. package/template/docs/SWAGGER_INTEGRATION_GUIDE.md +416 -0
  63. package/template/docs/TRANSACTION_MANAGER_USAGE.md +360 -0
  64. package/template/docs/TROUBLESHOOTING.md +869 -0
  65. package/template/env.production.example +62 -0
  66. package/template/jest.config.js +34 -0
  67. package/template/package-lock.json +13240 -0
  68. package/template/package.json +119 -0
  69. package/template/patches/typeorm+0.3.25.patch +22 -0
  70. package/template/scripts/sync-template.mjs +84 -0
  71. package/template/scripts/test-annotation-system.sh +48 -0
  72. package/template/scripts/test-core-functionality.sh +28 -0
  73. package/template/src/annotations/decorators/ConfigManagement.ts +9 -0
  74. package/template/src/annotations/decorators/DistributedTracing.ts +9 -0
  75. package/template/src/annotations/decorators/EnterprisePerformance.ts +9 -0
  76. package/template/src/annotations/decorators/PerformanceMonitor.ts +32 -0
  77. package/template/src/annotations/decorators/SecurityAudit.ts +9 -0
  78. package/template/src/annotations/index.ts +50 -0
  79. package/template/src/annotations/processors/ConfigManagementProcessor.ts +369 -0
  80. package/template/src/annotations/processors/DistributedTracingProcessor.ts +288 -0
  81. package/template/src/annotations/processors/EnterprisePerformanceProcessor.ts +189 -0
  82. package/template/src/annotations/processors/PerformanceMonitorProcessor.ts +101 -0
  83. package/template/src/annotations/processors/SecurityAuditProcessor.ts +345 -0
  84. package/template/src/annotations/processors/SwaggerProcessor.ts +612 -0
  85. package/template/src/annotations/processors/index.ts +10 -0
  86. package/template/src/app.ts +123 -0
  87. package/template/src/controllers/base.controller.ts +41 -0
  88. package/template/src/controllers/cacheManagement.controller.ts +131 -0
  89. package/template/src/controllers/captcha.controller.ts +57 -0
  90. package/template/src/controllers/demo/AnnotationDemoController.ts +118 -0
  91. package/template/src/controllers/example/EnterpriseExampleController.ts +297 -0
  92. package/template/src/controllers/example/ExampleController.ts +110 -0
  93. package/template/src/controllers/example/NewAnnotationExampleController.ts +159 -0
  94. package/template/src/controllers/example/SwaggerExampleController.ts +205 -0
  95. package/template/src/controllers/example/TransactionExample.controller.ts +336 -0
  96. package/template/src/controllers/health.controller.ts +235 -0
  97. package/template/src/controllers/home/register.controller.ts +58 -0
  98. package/template/src/controllers/home/ytGoods.controller.ts +92 -0
  99. package/template/src/controllers/home/ytShop.controller.ts +135 -0
  100. package/template/src/controllers/home/ytUser.controller.ts +89 -0
  101. package/template/src/controllers/logManagement.controller.ts +396 -0
  102. package/template/src/controllers/public/emailSend.controller.ts +65 -0
  103. package/template/src/controllers/public/ytUserAuth.controller.ts +174 -0
  104. package/template/src/controllers/testData.controller.ts +253 -0
  105. package/template/src/dto/controller/example/NewAnnotationExampleController.dto.ts +73 -0
  106. package/template/src/dto/controller/home/emailSend.controller.dto.ts +40 -0
  107. package/template/src/dto/controller/home/register.controller.dto.ts +45 -0
  108. package/template/src/dto/controller/home/ytGoods.controller.dto.ts +55 -0
  109. package/template/src/dto/controller/home/ytShop.controller.dto.ts +69 -0
  110. package/template/src/dto/controller/home/ytUser.controller.dto.ts +44 -0
  111. package/template/src/dto/controller/public/ytUserAuth.controller.dto.ts +63 -0
  112. package/template/src/dto/goods.dto.ts +212 -0
  113. package/template/src/dto/service/ytService.dto.ts +13 -0
  114. package/template/src/dto/user.dto.ts +177 -0
  115. package/template/src/entity/base.entity.ts +13 -0
  116. package/template/src/entity/columnTypes.ts +13 -0
  117. package/template/src/entity/goodsImagesUnlockKey.entity.ts +33 -0
  118. package/template/src/entity/goodsUnlocker.entity.ts +34 -0
  119. package/template/src/entity/index.ts +15 -0
  120. package/template/src/entity/shop.entity.ts +52 -0
  121. package/template/src/entity/shopUser.entity.ts +41 -0
  122. package/template/src/entity/ytGoods.entity.ts +94 -0
  123. package/template/src/entity/ytUser.entity.ts +96 -0
  124. package/template/src/examples/InterceptorExampleRunner.ts +284 -0
  125. package/template/src/examples/ServiceInterceptorExample.ts +214 -0
  126. package/template/src/examples/SwaggerProcessorExample.ts +169 -0
  127. package/template/src/examples/TransactionManagerDemo.ts +377 -0
  128. package/template/src/examples/cacheExamples.ts +155 -0
  129. package/template/src/framework/decorator/controller.ts +311 -0
  130. package/template/src/framework/decorator/processor/AnnotationDecorators.ts +100 -0
  131. package/template/src/framework/decorator/processor/AnnotationProcessor.ts +156 -0
  132. package/template/src/framework/decorator/processor/AnnotationProcessorConfig.ts +45 -0
  133. package/template/src/framework/decorator/processor/AnnotationRegistry.ts +117 -0
  134. package/template/src/framework/decorator/processor/AnnotationSystemInitializer.ts +95 -0
  135. package/template/src/framework/decorator/processor/ProcessorManager.ts +76 -0
  136. package/template/src/framework/decorator/processor/processors/CustomProcessors.ts +126 -0
  137. package/template/src/framework/decorator/processor/processors/DefaultProcessors.ts +207 -0
  138. package/template/src/framework/decorator/refactored/DecoratorFactory.ts +99 -0
  139. package/template/src/framework/decorator/refactored/DecoratorMetadataManager.ts +125 -0
  140. package/template/src/framework/decorator/refactored/DecoratorValidator.ts +128 -0
  141. package/template/src/framework/decorator/refactored/TypeSafeDecorators.ts +139 -0
  142. package/template/src/framework/decorator/refactored/index.ts +98 -0
  143. package/template/src/framework/decorator/swagger.ts +150 -0
  144. package/template/src/framework/interceptors/AdvancedServiceCallInterceptor.ts +375 -0
  145. package/template/src/framework/interceptors/ServiceCallInterceptor.ts +348 -0
  146. package/template/src/framework/interceptors/index.ts +19 -0
  147. package/template/src/framework/plugins/registry.ts +63 -0
  148. package/template/src/framework/plugins/types.ts +15 -0
  149. package/template/src/framework/types/ServiceResult.ts +151 -0
  150. package/template/src/framework/types/index.ts +16 -0
  151. package/template/src/framework/utils/CacheManager.ts +430 -0
  152. package/template/src/framework/utils/CacheService.ts +248 -0
  153. package/template/src/framework/utils/DtoValidator.ts +164 -0
  154. package/template/src/framework/utils/MigrationHelper.ts +179 -0
  155. package/template/src/framework/utils/MigrationManager.ts +256 -0
  156. package/template/src/framework/utils/NewRouter.ts +207 -0
  157. package/template/src/framework/utils/TransactionManager.ts +172 -0
  158. package/template/src/framework/utils/bootstrap.ts +445 -0
  159. package/template/src/framework/utils/cache.ts +269 -0
  160. package/template/src/framework/utils/databaseConfig.ts +148 -0
  161. package/template/src/framework/utils/db.ts +39 -0
  162. package/template/src/framework/utils/dbMonitor.ts +106 -0
  163. package/template/src/framework/utils/dynamicSwagger.ts +410 -0
  164. package/template/src/framework/utils/function.ts +61 -0
  165. package/template/src/framework/utils/gracefulShutdown.ts +131 -0
  166. package/template/src/framework/utils/logger.ts +388 -0
  167. package/template/src/framework/utils/metrics.ts +182 -0
  168. package/template/src/framework/utils/router.ts +417 -0
  169. package/template/src/framework/utils/swagger.ts +184 -0
  170. package/template/src/framework/utils/testDb.ts +19 -0
  171. package/template/src/framework/utils/token.ts +23 -0
  172. package/template/src/framework/utils/transform.ts +17 -0
  173. package/template/src/libs/aokEmailSender.ts +42 -0
  174. package/template/src/libs/captcha.ts +37 -0
  175. package/template/src/libs/cos.ts +45 -0
  176. package/template/src/libs/mCache.ts +7 -0
  177. package/template/src/libs/serviceValidate.ts +3 -0
  178. package/template/src/libs/tecentSms.ts +51 -0
  179. package/template/src/middlewares/a.middleware.ts +6 -0
  180. package/template/src/middlewares/error.middleware.ts +14 -0
  181. package/template/src/middlewares/logging.middleware.ts +187 -0
  182. package/template/src/middlewares/static.middleware.ts +79 -0
  183. package/template/src/middlewares/swagger.middleware.ts +70 -0
  184. package/template/src/middlewares/token.middleware.ts +32 -0
  185. package/template/src/migrations/1700000000000-InitialDatabaseStructure.ts +172 -0
  186. package/template/src/migrations/index.ts +6 -0
  187. package/template/src/plugins/weboffice/core/context.ts +47 -0
  188. package/template/src/plugins/weboffice/core/errors.ts +51 -0
  189. package/template/src/plugins/weboffice/core/types.ts +63 -0
  190. package/template/src/plugins/weboffice/core/utils.ts +7 -0
  191. package/template/src/plugins/weboffice/entities/index.ts +3 -0
  192. package/template/src/plugins/weboffice/entities/webofficeFile.entity.ts +28 -0
  193. package/template/src/plugins/weboffice/entities/webofficeFileVersion.entity.ts +29 -0
  194. package/template/src/plugins/weboffice/http/routes.ts +179 -0
  195. package/template/src/plugins/weboffice/index.ts +23 -0
  196. package/template/src/plugins/weboffice/services/webofficeCallback.service.ts +274 -0
  197. package/template/src/repository/UserRepository.ts +122 -0
  198. package/template/src/repository/base/BaseRepository.ts +124 -0
  199. package/template/src/repository/interfaces/IBaseRepository.ts +67 -0
  200. package/template/src/routers/index.ts +49 -0
  201. package/template/src/service/base.service.ts +116 -0
  202. package/template/src/service/paramValidateTest.service.ts +139 -0
  203. package/template/src/service/ytGoods.service.ts +42 -0
  204. package/template/src/service/ytShop.service.ts +90 -0
  205. package/template/src/service/ytUser.service.ts +451 -0
  206. package/template/src/test/swaggerParameterTest.ts +90 -0
  207. package/template/src/utils/testDataInitializer.ts +296 -0
  208. package/template/static/output.json +15203 -0
  209. package/template/test/controllers/controllers.test.ts +173 -0
  210. package/template/test/controllers/example/ExampleController.test.ts +222 -0
  211. package/template/test/controllers/example/NewAnnotationExampleController.test.ts +200 -0
  212. package/template/test/framework/TransactionManagerDemo.test.ts +363 -0
  213. package/template/test/framework/annotation/AnnotationDecorators.test.ts +222 -0
  214. package/template/test/framework/annotation/AnnotationExecutor.test.ts +246 -0
  215. package/template/test/framework/annotation/AnnotationProcessor.test.ts +179 -0
  216. package/template/test/framework/annotation/CustomProcessors.test.ts +313 -0
  217. package/template/test/framework/annotation/DefaultProcessors.test.ts +371 -0
  218. package/template/test/framework/annotation/NewRouter.test.ts +272 -0
  219. package/template/test/framework/annotation/ProcessorManager.test.ts +248 -0
  220. package/template/test/framework/annotation/setup.ts +26 -0
  221. package/template/test/framework/cache.test.ts +101 -0
  222. package/template/test/framework/databaseConfig.test.ts +142 -0
  223. package/template/test/integration/integration.test.ts +153 -0
  224. package/template/test/plugins/weboffice/http.routes.int.test.ts +61 -0
  225. package/template/test/service/business.test.ts +87 -0
  226. package/template/test/service/paramValidateTest.service.test.ts +184 -0
  227. package/template/test/service/ytUser.service.test.ts +566 -0
  228. package/template/test/setup.ts +20 -0
  229. package/template/test/setupAfterEnv.ts +14 -0
  230. package/template/test/utils/testHelpers.ts +220 -0
  231. package/template/test_output.txt +0 -0
  232. package/template/tsconfig.build.json +17 -0
  233. package/template/tsconfig.json +31 -0
  234. package/template/webpack.config.js +71 -0
  235. package/template/yarn.lock +7354 -0
@@ -0,0 +1,272 @@
1
+ import { callControllerWithProcessors } from '../../../src/framework/utils/NewRouter';
2
+ import { ProcessorManager } from '../../../src/framework/decorator/processor/ProcessorManager';
3
+ import { LoggingProcessor, PermissionProcessor } from '../../../src/framework/decorator/processor/processors/CustomProcessors';
4
+ import { Context } from 'koa';
5
+
6
+ // 模拟 Koa Context
7
+ const createMockContext = (): Context => ({
8
+ status: 200,
9
+ body: null,
10
+ request: {
11
+ body: { name: 'test' },
12
+ headers: { 'content-type': 'application/json' },
13
+ query: { id: '123' }
14
+ },
15
+ params: { userId: '456' },
16
+ state: { user: { id: 1, name: 'test', permissions: ['read:data'] } },
17
+ set: jest.fn(),
18
+ throw: jest.fn()
19
+ } as any);
20
+
21
+ // 模拟 class-validator
22
+ jest.mock('class-validator', () => ({
23
+ validate: jest.fn().mockResolvedValue([])
24
+ }));
25
+
26
+ // 模拟缓存
27
+ jest.mock('../../../src/framework/utils/cache', () => ({
28
+ createCache: jest.fn().mockReturnValue({
29
+ set: jest.fn(),
30
+ get: jest.fn()
31
+ }),
32
+ CacheType: {
33
+ CONTROLLER: 'controller'
34
+ }
35
+ }));
36
+
37
+ // 模拟日志
38
+ jest.mock('../../../src/framework/utils/logger', () => ({
39
+ logger: {
40
+ error: jest.fn()
41
+ }
42
+ }));
43
+
44
+ describe('新路由系统集成测试', () => {
45
+ let mockContext: Context;
46
+
47
+ beforeEach(() => {
48
+ mockContext = createMockContext();
49
+ ProcessorManager.clear();
50
+ ProcessorManager.initialize();
51
+ jest.clearAllMocks();
52
+ jest.spyOn(console, 'log').mockImplementation(() => {});
53
+ });
54
+
55
+ afterEach(() => {
56
+ jest.restoreAllMocks();
57
+ });
58
+
59
+ describe('callControllerWithProcessors', () => {
60
+ test('应该能够调用控制器方法', async () => {
61
+ const mockController = {
62
+ testMethod: jest.fn().mockReturnValue({ data: 'test' }),
63
+ $_MethdosParamInfo: new Map([
64
+ ['testMethod', [{ type: 'Body', validate: null }]]
65
+ ])
66
+ };
67
+
68
+ await callControllerWithProcessors(mockContext, mockController, 'testMethod');
69
+
70
+ expect(mockController.testMethod).toHaveBeenCalledWith({ name: 'test' });
71
+ expect(mockContext.body).toEqual({ data: 'test' });
72
+ });
73
+
74
+ test('应该能够处理异步控制器方法', async () => {
75
+ const mockController = {
76
+ testMethod: jest.fn().mockResolvedValue({ data: 'async test' }),
77
+ $_MethdosParamInfo: new Map([
78
+ ['testMethod', [{ type: 'Body', validate: null }]]
79
+ ])
80
+ };
81
+
82
+ await callControllerWithProcessors(mockContext, mockController, 'testMethod');
83
+
84
+ expect(mockController.testMethod).toHaveBeenCalledWith({ name: 'test' });
85
+ expect(mockContext.body).toEqual({ data: 'async test' });
86
+ });
87
+
88
+ test('应该能够处理不同类型的参数', async () => {
89
+ const mockController = {
90
+ testMethod: jest.fn().mockReturnValue({ data: 'test' }),
91
+ $_MethdosParamInfo: new Map([
92
+ ['testMethod', [
93
+ { type: 'Body', validate: null },
94
+ { type: 'Query', validate: null },
95
+ { type: 'Params', validate: null },
96
+ { type: 'Headers', validate: null },
97
+ { type: 'State', validate: null }
98
+ ]]
99
+ ])
100
+ };
101
+
102
+ await callControllerWithProcessors(mockContext, mockController, 'testMethod');
103
+
104
+ expect(mockController.testMethod).toHaveBeenCalledWith(
105
+ { name: 'test' }, // Body
106
+ { id: '123' }, // Query
107
+ { userId: '456' }, // Params
108
+ { 'content-type': 'application/json' }, // Headers
109
+ { user: { id: 1, name: 'test', permissions: ['read:data'] } } // State
110
+ );
111
+ });
112
+
113
+ test('应该能够处理响应验证', async () => {
114
+ const mockController = {
115
+ testMethod: jest.fn().mockReturnValue({ data: 'test' }),
116
+ $_ResponseValidator: new Map([
117
+ ['testMethod', { clas: class {}, objectKey: '' }]
118
+ ])
119
+ };
120
+
121
+ await callControllerWithProcessors(mockContext, mockController, 'testMethod');
122
+
123
+ expect(mockContext.body).toEqual({ data: 'test' });
124
+ });
125
+
126
+ test('响应验证失败时应该设置错误响应', async () => {
127
+ const { validate } = require('class-validator');
128
+ validate.mockResolvedValue([{ property: 'data', constraints: { isNotEmpty: '数据不能为空' } }]);
129
+
130
+ const mockController = {
131
+ testMethod: jest.fn().mockReturnValue({ data: '' }),
132
+ $_ResponseValidator: new Map([
133
+ ['testMethod', { clas: class {}, objectKey: '' }]
134
+ ])
135
+ };
136
+
137
+ await callControllerWithProcessors(mockContext, mockController, 'testMethod');
138
+
139
+ expect(mockContext.status).toBe(400);
140
+ expect(mockContext.body).toBe('接口testMethod返回数据参数校验异常');
141
+ });
142
+
143
+ test('应该能够处理缓存注解', async () => {
144
+ const mockController = {
145
+ testMethod: jest.fn().mockReturnValue({ data: 'test' }),
146
+ $_ControllerCache: new Map([
147
+ ['testMethod', {
148
+ cacheyFn: jest.fn().mockReturnValue('cache-key'),
149
+ options: { enable: true, ttl: 30 }
150
+ }]
151
+ ])
152
+ };
153
+
154
+ await callControllerWithProcessors(mockContext, mockController, 'testMethod');
155
+
156
+ expect(mockController.testMethod).toHaveBeenCalled();
157
+ expect(mockContext.body).toEqual({ data: 'test' });
158
+ });
159
+
160
+ test('应该能够处理响应码注解', async () => {
161
+ const mockController = {
162
+ testMethod: jest.fn().mockReturnValue({ data: 'test' }),
163
+ $_ResponseCode: new Map([
164
+ ['testMethod', 201]
165
+ ])
166
+ };
167
+
168
+ await callControllerWithProcessors(mockContext, mockController, 'testMethod');
169
+
170
+ expect(mockContext.status).toBe(201);
171
+ expect(mockContext.body).toEqual({ data: 'test' });
172
+ });
173
+
174
+ test('应该能够处理响应头注解', async () => {
175
+ const mockController = {
176
+ testMethod: jest.fn().mockReturnValue({ data: 'test' }),
177
+ $_ResponseHeader: new Map([
178
+ ['testMethod', new Map([
179
+ ['Content-Type', 'application/json'],
180
+ ['Cache-Control', 'no-cache']
181
+ ])]
182
+ ])
183
+ };
184
+
185
+ await callControllerWithProcessors(mockContext, mockController, 'testMethod');
186
+
187
+ expect(mockContext.set).toHaveBeenCalledWith('Content-Type', 'application/json');
188
+ expect(mockContext.set).toHaveBeenCalledWith('Cache-Control', 'no-cache');
189
+ });
190
+
191
+ test('控制器方法抛出异常时应该重新抛出', async () => {
192
+ const mockController = {
193
+ testMethod: jest.fn().mockRejectedValue(new Error('Controller error'))
194
+ };
195
+
196
+ await expect(callControllerWithProcessors(mockContext, mockController, 'testMethod'))
197
+ .rejects.toThrow('Controller error');
198
+ });
199
+
200
+ test('应该能够处理自定义处理器', async () => {
201
+ ProcessorManager.registerProcessor(new LoggingProcessor());
202
+
203
+ const mockController = {
204
+ testMethod: jest.fn().mockReturnValue({ data: 'test' }),
205
+ $_Annotations: new Map([
206
+ ['testMethod', new Map([
207
+ ['Logging', { level: 'info' }]
208
+ ])]
209
+ ])
210
+ };
211
+
212
+ await callControllerWithProcessors(mockContext, mockController, 'testMethod');
213
+
214
+ expect(console.log).toHaveBeenCalledWith(
215
+ '[Logging] 开始处理请求: undefined.testMethod'
216
+ );
217
+ expect(mockContext.body).toEqual({ data: 'test' });
218
+ });
219
+
220
+ test('权限处理器拒绝访问时应该中断执行', async () => {
221
+ ProcessorManager.registerProcessor(new PermissionProcessor());
222
+
223
+ const mockController = {
224
+ testMethod: jest.fn().mockReturnValue({ data: 'test' }),
225
+ $_Annotations: new Map([
226
+ ['testMethod', new Map([
227
+ ['Permission', { requiredPermission: 'write:data' }]
228
+ ])]
229
+ ])
230
+ };
231
+
232
+ await callControllerWithProcessors(mockContext, mockController, 'testMethod');
233
+
234
+ expect(mockController.testMethod).not.toHaveBeenCalled();
235
+ expect(mockContext.status).toBe(403);
236
+ expect(mockContext.body).toEqual({ error: '权限不足' });
237
+ });
238
+
239
+ test('应该能够处理复杂的注解组合', async () => {
240
+ ProcessorManager.registerProcessor(new LoggingProcessor());
241
+ ProcessorManager.registerProcessor(new PermissionProcessor());
242
+
243
+ const mockController = {
244
+ testMethod: jest.fn().mockReturnValue({ data: 'test' }),
245
+ $_Annotations: new Map([
246
+ ['testMethod', new Map([
247
+ ['Logging', { level: 'info' }],
248
+ ['Permission', { requiredPermission: 'read:data' }]
249
+ ])]
250
+ ]),
251
+ $_ResponseCode: new Map([
252
+ ['testMethod', 200]
253
+ ]),
254
+ $_ResponseHeader: new Map([
255
+ ['testMethod', new Map([
256
+ ['Content-Type', 'application/json']
257
+ ])]
258
+ ])
259
+ };
260
+
261
+ await callControllerWithProcessors(mockContext, mockController, 'testMethod');
262
+
263
+ expect(console.log).toHaveBeenCalledWith(
264
+ '[Logging] 开始处理请求: undefined.testMethod'
265
+ );
266
+ expect(mockController.testMethod).toHaveBeenCalled();
267
+ expect(mockContext.status).toBe(200);
268
+ expect(mockContext.set).toHaveBeenCalledWith('Content-Type', 'application/json');
269
+ expect(mockContext.body).toEqual({ data: 'test' });
270
+ });
271
+ });
272
+ });
@@ -0,0 +1,248 @@
1
+ import { ProcessorManager } from '../../../src/framework/decorator/processor/ProcessorManager';
2
+ import { AnnotationProcessor } from '../../../src/framework/decorator/processor/AnnotationProcessor';
3
+ import {
4
+ ParameterValidationProcessor,
5
+ ResponseValidationProcessor,
6
+ CacheProcessor,
7
+ ResponseCodeProcessor,
8
+ ResponseHeaderProcessor
9
+ } from '../../../src/framework/decorator/processor/processors/DefaultProcessors';
10
+ import { LoggingProcessor, PermissionProcessor, RateLimitProcessor } from '../../../src/framework/decorator/processor/processors/CustomProcessors';
11
+
12
+ // 测试用的注解处理器
13
+ class TestProcessor implements AnnotationProcessor {
14
+ readonly name = 'TestProcessor';
15
+ readonly priority = 100;
16
+
17
+ async process(): Promise<boolean> {
18
+ return true;
19
+ }
20
+ }
21
+
22
+ describe('处理器管理器测试', () => {
23
+ beforeEach(() => {
24
+ ProcessorManager.clear();
25
+ });
26
+
27
+ describe('ProcessorManager', () => {
28
+ test('initialize方法应该注册默认处理器', () => {
29
+ ProcessorManager.initialize();
30
+
31
+ const allProcessors = ProcessorManager.getAllProcessors();
32
+ expect(allProcessors.length).toBeGreaterThan(0);
33
+
34
+ // 检查是否包含默认处理器
35
+ const processorNames = allProcessors.map(p => p.name);
36
+ expect(processorNames).toContain('ParameterValidation');
37
+ expect(processorNames).toContain('ResponseValidation');
38
+ expect(processorNames).toContain('Cache');
39
+ expect(processorNames).toContain('ResponseCode');
40
+ expect(processorNames).toContain('ResponseHeader');
41
+ });
42
+
43
+ test('多次调用initialize不应该重复注册', () => {
44
+ ProcessorManager.initialize();
45
+ const firstCount = ProcessorManager.getAllProcessors().length;
46
+
47
+ ProcessorManager.initialize();
48
+ const secondCount = ProcessorManager.getAllProcessors().length;
49
+
50
+ expect(firstCount).toBe(secondCount);
51
+ });
52
+
53
+ test('应该能够注册自定义处理器', () => {
54
+ const testProcessor = new TestProcessor();
55
+ ProcessorManager.registerProcessor(testProcessor);
56
+
57
+ const retrievedProcessor = ProcessorManager.getProcessor('TestProcessor');
58
+ expect(retrievedProcessor).toBe(testProcessor);
59
+ });
60
+
61
+ test('应该能够获取所有处理器', () => {
62
+ const processor1 = new TestProcessor();
63
+ processor1.name = 'Processor1';
64
+ processor1.priority = 50;
65
+
66
+ const processor2 = new TestProcessor();
67
+ processor2.name = 'Processor2';
68
+ processor2.priority = 100;
69
+
70
+ ProcessorManager.registerProcessor(processor1);
71
+ ProcessorManager.registerProcessor(processor2);
72
+
73
+ const allProcessors = ProcessorManager.getAllProcessors();
74
+ expect(allProcessors).toHaveLength(2);
75
+ expect(allProcessors[0]).toBe(processor1); // 优先级高的在前面
76
+ expect(allProcessors[1]).toBe(processor2);
77
+ });
78
+
79
+ test('应该能够获取特定处理器', () => {
80
+ const testProcessor = new TestProcessor();
81
+ ProcessorManager.registerProcessor(testProcessor);
82
+
83
+ const retrievedProcessor = ProcessorManager.getProcessor('TestProcessor');
84
+ expect(retrievedProcessor).toBe(testProcessor);
85
+ });
86
+
87
+ test('获取不存在的处理器应该返回undefined', () => {
88
+ const retrievedProcessor = ProcessorManager.getProcessor('NonExistentProcessor');
89
+ expect(retrievedProcessor).toBeUndefined();
90
+ });
91
+
92
+ test('应该能够移除处理器', () => {
93
+ const testProcessor = new TestProcessor();
94
+ ProcessorManager.registerProcessor(testProcessor);
95
+
96
+ expect(ProcessorManager.getProcessor('TestProcessor')).toBe(testProcessor);
97
+
98
+ const removed = ProcessorManager.removeProcessor('TestProcessor');
99
+ expect(removed).toBe(true);
100
+ expect(ProcessorManager.getProcessor('TestProcessor')).toBeUndefined();
101
+ });
102
+
103
+ test('移除不存在的处理器应该返回false', () => {
104
+ const removed = ProcessorManager.removeProcessor('NonExistentProcessor');
105
+ expect(removed).toBe(false);
106
+ });
107
+
108
+ test('应该能够清空所有处理器', () => {
109
+ const testProcessor = new TestProcessor();
110
+ ProcessorManager.registerProcessor(testProcessor);
111
+
112
+ expect(ProcessorManager.getAllProcessors().length).toBeGreaterThan(0);
113
+
114
+ ProcessorManager.clear();
115
+ expect(ProcessorManager.getAllProcessors().length).toBe(0);
116
+ });
117
+
118
+ test('清空后应该能够重新初始化', () => {
119
+ ProcessorManager.initialize();
120
+ const initialCount = ProcessorManager.getAllProcessors().length;
121
+
122
+ ProcessorManager.clear();
123
+ expect(ProcessorManager.getAllProcessors().length).toBe(0);
124
+
125
+ ProcessorManager.initialize();
126
+ expect(ProcessorManager.getAllProcessors().length).toBe(initialCount);
127
+ });
128
+ });
129
+
130
+ describe('默认处理器注册', () => {
131
+ test('应该注册ParameterValidationProcessor', () => {
132
+ ProcessorManager.initialize();
133
+ const processor = ProcessorManager.getProcessor('ParameterValidation');
134
+ expect(processor).toBeInstanceOf(ParameterValidationProcessor);
135
+ expect(processor?.priority).toBe(100);
136
+ });
137
+
138
+ test('应该注册ResponseValidationProcessor', () => {
139
+ ProcessorManager.initialize();
140
+ const processor = ProcessorManager.getProcessor('ResponseValidation');
141
+ expect(processor).toBeInstanceOf(ResponseValidationProcessor);
142
+ expect(processor?.priority).toBe(200);
143
+ });
144
+
145
+ test('应该注册CacheProcessor', () => {
146
+ ProcessorManager.initialize();
147
+ const processor = ProcessorManager.getProcessor('Cache');
148
+ expect(processor).toBeInstanceOf(CacheProcessor);
149
+ expect(processor?.priority).toBe(50);
150
+ });
151
+
152
+ test('应该注册ResponseCodeProcessor', () => {
153
+ ProcessorManager.initialize();
154
+ const processor = ProcessorManager.getProcessor('ResponseCode');
155
+ expect(processor).toBeInstanceOf(ResponseCodeProcessor);
156
+ expect(processor?.priority).toBe(300);
157
+ });
158
+
159
+ test('应该注册ResponseHeaderProcessor', () => {
160
+ ProcessorManager.initialize();
161
+ const processor = ProcessorManager.getProcessor('ResponseHeader');
162
+ expect(processor).toBeInstanceOf(ResponseHeaderProcessor);
163
+ expect(processor?.priority).toBe(400);
164
+ });
165
+ });
166
+
167
+ describe('自定义处理器注册', () => {
168
+ test('应该能够注册LoggingProcessor', () => {
169
+ const loggingProcessor = new LoggingProcessor();
170
+ ProcessorManager.registerProcessor(loggingProcessor);
171
+
172
+ const retrievedProcessor = ProcessorManager.getProcessor('Logging');
173
+ expect(retrievedProcessor).toBe(loggingProcessor);
174
+ expect(retrievedProcessor?.priority).toBe(10);
175
+ });
176
+
177
+ test('应该能够注册PermissionProcessor', () => {
178
+ const permissionProcessor = new PermissionProcessor();
179
+ ProcessorManager.registerProcessor(permissionProcessor);
180
+
181
+ const retrievedProcessor = ProcessorManager.getProcessor('Permission');
182
+ expect(retrievedProcessor).toBe(permissionProcessor);
183
+ expect(retrievedProcessor?.priority).toBe(5);
184
+ });
185
+
186
+ test('应该能够注册RateLimitProcessor', () => {
187
+ const rateLimitProcessor = new RateLimitProcessor();
188
+ ProcessorManager.registerProcessor(rateLimitProcessor);
189
+
190
+ const retrievedProcessor = ProcessorManager.getProcessor('RateLimit');
191
+ expect(retrievedProcessor).toBe(rateLimitProcessor);
192
+ expect(retrievedProcessor?.priority).toBe(15);
193
+ });
194
+ });
195
+
196
+ describe('处理器优先级', () => {
197
+ test('应该按优先级排序所有处理器', () => {
198
+ const processor1 = new TestProcessor();
199
+ processor1.name = 'Processor1';
200
+ processor1.priority = 200;
201
+
202
+ const processor2 = new TestProcessor();
203
+ processor2.name = 'Processor2';
204
+ processor2.priority = 50;
205
+
206
+ const processor3 = new TestProcessor();
207
+ processor3.name = 'Processor3';
208
+ processor3.priority = 100;
209
+
210
+ ProcessorManager.registerProcessor(processor1);
211
+ ProcessorManager.registerProcessor(processor2);
212
+ ProcessorManager.registerProcessor(processor3);
213
+
214
+ const allProcessors = ProcessorManager.getAllProcessors();
215
+ expect(allProcessors[0]).toBe(processor2); // 优先级 50
216
+ expect(allProcessors[1]).toBe(processor3); // 优先级 100
217
+ expect(allProcessors[2]).toBe(processor1); // 优先级 200
218
+ });
219
+
220
+ test('默认处理器应该按正确优先级排序', () => {
221
+ ProcessorManager.initialize();
222
+ const allProcessors = ProcessorManager.getAllProcessors();
223
+
224
+ // 检查优先级顺序
225
+ const priorities = allProcessors.map(p => p.priority);
226
+ const sortedPriorities = [...priorities].sort((a, b) => a - b);
227
+ expect(priorities).toEqual(sortedPriorities);
228
+ });
229
+ });
230
+
231
+ describe('处理器覆盖', () => {
232
+ test('注册同名处理器应该覆盖原有处理器', () => {
233
+ const processor1 = new TestProcessor();
234
+ processor1.name = 'TestProcessor';
235
+ processor1.priority = 100;
236
+
237
+ const processor2 = new TestProcessor();
238
+ processor2.name = 'TestProcessor';
239
+ processor2.priority = 200;
240
+
241
+ ProcessorManager.registerProcessor(processor1);
242
+ expect(ProcessorManager.getProcessor('TestProcessor')).toBe(processor1);
243
+
244
+ ProcessorManager.registerProcessor(processor2);
245
+ expect(ProcessorManager.getProcessor('TestProcessor')).toBe(processor2);
246
+ });
247
+ });
248
+ });
@@ -0,0 +1,26 @@
1
+ import { TestDatabaseHelper } from '../utils/testHelpers';
2
+
3
+ // 设置测试环境
4
+ beforeAll(async () => {
5
+ // 初始化测试数据库
6
+ await TestDatabaseHelper.initTestDatabase();
7
+ });
8
+
9
+ afterAll(async () => {
10
+ // 清理测试数据库
11
+ await TestDatabaseHelper.closeTestDatabase();
12
+ });
13
+
14
+ beforeEach(async () => {
15
+ // 重置测试数据
16
+ await TestDatabaseHelper.resetTestData();
17
+ });
18
+
19
+ // 全局测试超时设置
20
+ jest.setTimeout(10000);
21
+
22
+ // 清理所有定时器
23
+ afterEach(() => {
24
+ jest.clearAllTimers();
25
+ jest.clearAllMocks();
26
+ });
@@ -0,0 +1,101 @@
1
+ import { TestDatabaseHelper, TestUtils } from '../utils/testHelpers';
2
+ import { createCache, CacheType, getCacheStats, clearAllCaches } from '../../src/framework/utils/cache';
3
+
4
+ describe('缓存管理测试', () => {
5
+ beforeEach(() => {
6
+ clearAllCaches();
7
+ });
8
+
9
+ afterEach(() => {
10
+ clearAllCaches();
11
+ });
12
+
13
+ describe('缓存创建', () => {
14
+ test('应该能够创建用户缓存', () => {
15
+ const userCache = createCache('test-user-cache', CacheType.USER);
16
+ expect(userCache).toBeDefined();
17
+ });
18
+
19
+ test('应该能够创建控制器缓存', () => {
20
+ const controllerCache = createCache('test-controller-cache', CacheType.CONTROLLER);
21
+ expect(controllerCache).toBeDefined();
22
+ });
23
+
24
+ test('应该能够创建验证码缓存', () => {
25
+ const captchaCache = createCache('test-captcha-cache', CacheType.CAPTCHA);
26
+ expect(captchaCache).toBeDefined();
27
+ });
28
+ });
29
+
30
+ describe('缓存操作', () => {
31
+ test('应该能够设置和获取缓存值', () => {
32
+ const cache = createCache('test-cache', CacheType.TEMP);
33
+ const key = 'test-key';
34
+ const value = { name: 'test', value: 123 };
35
+
36
+ cache.set(key, value);
37
+ const retrieved = cache.get(key);
38
+
39
+ expect(retrieved).toEqual(value);
40
+ });
41
+
42
+ test('应该能够删除缓存值', () => {
43
+ const cache = createCache('test-cache', CacheType.TEMP);
44
+ const key = 'test-key';
45
+ const value = 'test-value';
46
+
47
+ cache.set(key, value);
48
+ expect(cache.get(key)).toBe(value);
49
+
50
+ cache.del(key);
51
+ expect(cache.get(key)).toBeUndefined();
52
+ });
53
+
54
+ test('应该能够清空所有缓存', () => {
55
+ const cache1 = createCache('test-cache-1', CacheType.TEMP);
56
+ const cache2 = createCache('test-cache-2', CacheType.TEMP);
57
+
58
+ cache1.set('key1', 'value1');
59
+ cache2.set('key2', 'value2');
60
+
61
+ expect(cache1.get('key1')).toBe('value1');
62
+ expect(cache2.get('key2')).toBe('value2');
63
+
64
+ clearAllCaches();
65
+
66
+ expect(cache1.get('key1')).toBeUndefined();
67
+ expect(cache2.get('key2')).toBeUndefined();
68
+ });
69
+ });
70
+
71
+ describe('缓存统计', () => {
72
+ test('应该能够获取缓存统计信息', () => {
73
+ const cache = createCache('test-cache-stats', CacheType.TEMP);
74
+
75
+ cache.set('key1', 'value1');
76
+ cache.set('key2', 'value2');
77
+ cache.get('key1'); // 命中
78
+ cache.get('key3'); // 未命中
79
+
80
+ const stats = getCacheStats();
81
+ expect(stats['test-cache-stats']).toBeDefined();
82
+ expect(stats['test-cache-stats'].hits).toBe(1);
83
+ expect(stats['test-cache-stats'].misses).toBe(1);
84
+ expect(stats['test-cache-stats'].keys).toBe(2);
85
+ });
86
+ });
87
+
88
+ describe('缓存过期', () => {
89
+ test('应该能够设置缓存过期时间', async () => {
90
+ const cache = createCache('test-cache', CacheType.TEMP);
91
+ const key = 'test-key';
92
+ const value = 'test-value';
93
+
94
+ cache.set(key, value, 1); // 1秒过期
95
+ expect(cache.get(key)).toBe(value);
96
+
97
+ await TestUtils.wait(1100); // 等待1.1秒
98
+ expect(cache.get(key)).toBeUndefined();
99
+ });
100
+ });
101
+ });