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,173 @@
1
+ import { TestDatabaseHelper, TestUtils } from '../utils/testHelpers';
2
+ import { Provider } from 'dp-ioc2';
3
+ import { YtUserController } from '../../src/controllers/home/ytUser.controller';
4
+ import { YtShopController } from '../../src/controllers/home/ytShop.controller';
5
+ import { CaptchaController } from '../../src/controllers/captcha.controller';
6
+
7
+ describe('控制器测试', () => {
8
+ beforeAll(async () => {
9
+ await TestDatabaseHelper.initTestDatabase();
10
+ });
11
+
12
+ afterAll(async () => {
13
+ await TestDatabaseHelper.cleanupTestDatabase();
14
+ });
15
+
16
+ beforeEach(async () => {
17
+ await TestDatabaseHelper.resetTestData();
18
+ });
19
+
20
+ describe('用户控制器测试', () => {
21
+ let userController: YtUserController;
22
+
23
+ beforeEach(() => {
24
+ userController = Provider<any>(YtUserController);
25
+ });
26
+
27
+ test('应该能够获取用户信息', async () => {
28
+ const mockState = {
29
+ user: {
30
+ userId: 1,
31
+ type: 1
32
+ }
33
+ };
34
+
35
+ const result = await userController.getUserInfo(mockState);
36
+ expect(result.code).toBe(0);
37
+ expect(result.data).toBeDefined();
38
+ expect(result.data?.id).toBe(1);
39
+ expect(result.data?.nickName).toBe('测试用户1');
40
+ expect(result.data?.email).toBe('test1@example.com');
41
+ });
42
+
43
+ test('应该返回失败当用户不存在时', async () => {
44
+ const mockState = {
45
+ user: {
46
+ userId: 999,
47
+ type: 1
48
+ }
49
+ };
50
+
51
+ const result = await userController.getUserInfo(mockState);
52
+ expect(result.code).toBe(-1);
53
+ expect(result.data).toBeNull();
54
+ expect(result.message).toBe('用户不存在');
55
+ });
56
+
57
+ test('应该能够检查用户是否有店铺', async () => {
58
+ const mockState = {
59
+ user: {
60
+ userId: 1,
61
+ type: 1
62
+ }
63
+ };
64
+
65
+ const result = await userController.hasShop(mockState);
66
+ expect(result.code).toBe(0);
67
+ expect(result.data).toBeDefined();
68
+ expect(typeof result.data).toBe('number');
69
+ });
70
+ });
71
+
72
+ describe('店铺控制器测试', () => {
73
+ let shopController: YtShopController;
74
+
75
+ beforeEach(() => {
76
+ shopController = Provider<any>(YtShopController);
77
+ });
78
+
79
+ test('应该能够获取店铺信息', async () => {
80
+ const mockQuery = {
81
+ id: 1
82
+ };
83
+
84
+ const result = await shopController.getShopInfoById(mockQuery);
85
+ expect(result.code).toBe(0);
86
+ expect(result.data).toBeDefined();
87
+ expect(result.data?.id).toBe(1);
88
+ expect(result.data?.name).toBe('测试店铺1');
89
+ expect(result.data?.userId).toBeDefined();
90
+ });
91
+
92
+ test('应该返回失败当店铺不存在时', async () => {
93
+ const mockQuery = {
94
+ id: 999
95
+ };
96
+
97
+ const result = await shopController.getShopInfoById(mockQuery);
98
+ expect(result.code).toBe(-1);
99
+ expect(result.data).toBeNull();
100
+ expect(result.message).toBe('店铺不存在');
101
+ });
102
+
103
+ test('应该能够获取店铺商品列表', async () => {
104
+ const mockQuery = {
105
+ id: 1,
106
+ page: 1,
107
+ pageSize: 10
108
+ };
109
+
110
+ const result = await shopController.getShopGoodsList(mockQuery);
111
+ expect(result.code).toBe(0);
112
+ expect(result.data).toBeDefined();
113
+ expect(Array.isArray(result.data?.[0])).toBe(true);
114
+ expect(typeof result.data?.[1]).toBe('number');
115
+ });
116
+
117
+ test('应该能够获取店铺用户信息', async () => {
118
+ const mockQuery = {
119
+ shopId: 1
120
+ };
121
+
122
+ const result = await shopController.getShopUserInfo(mockQuery);
123
+ expect(result.code).toBe(0);
124
+ expect(result.data).toBeDefined();
125
+ expect(result.data?.id).toBeDefined();
126
+ expect(result.data?.nickName).toBeDefined();
127
+ });
128
+ });
129
+
130
+ describe('验证码控制器测试', () => {
131
+ let captchaController: CaptchaController;
132
+
133
+ beforeEach(() => {
134
+ captchaController = Provider<any>(CaptchaController);
135
+ });
136
+
137
+ test('应该能够生成验证码', async () => {
138
+ const result = await captchaController.getCaptcha();
139
+ expect(result).toBeDefined();
140
+ expect(result.image).toBeDefined();
141
+ expect(result.token).toBeDefined();
142
+ expect(result.contentType).toBe('image/svg+xml');
143
+ });
144
+
145
+ test('应该能够验证正确的验证码', async () => {
146
+ // 先生成验证码
147
+ const captchaResult = await captchaController.getCaptcha();
148
+ const { token } = captchaResult;
149
+
150
+ // 模拟用户输入(这里需要知道正确的验证码,实际测试中可能需要mock)
151
+ const mockBody = {
152
+ captcha: 'test', // 这里应该是正确的验证码
153
+ token: token
154
+ };
155
+
156
+ const result = await captchaController.verifyCaptcha(mockBody);
157
+ expect(result).toBeDefined();
158
+ expect(typeof result.success).toBe('boolean');
159
+ });
160
+
161
+ test('应该拒绝缺少token的验证请求', async () => {
162
+ const mockBody = {
163
+ captcha: 'test',
164
+ token: ''
165
+ };
166
+
167
+ const result = await captchaController.verifyCaptcha(mockBody);
168
+ expect(result.status).toBe(400);
169
+ expect(result.body?.success).toBe(false);
170
+ expect(result.body?.message).toBe('Missing captcha token');
171
+ });
172
+ });
173
+ });
@@ -0,0 +1,222 @@
1
+ import { ExampleController, initializeCustomProcessors } from '../../../src/controllers/example/ExampleController';
2
+ import { ProcessorManager } from '../../../src/framework/decorator/processor/ProcessorManager';
3
+ import { AnnotationRegistry } from '../../../src/framework/decorator/processor/AnnotationDecorators';
4
+
5
+ // 模拟依赖
6
+ jest.mock('@src/framework/decorator/controller', () => ({
7
+ Get: jest.fn(),
8
+ Query: jest.fn(),
9
+ State: jest.fn()
10
+ }));
11
+
12
+ jest.mock('@src/framework/decorator/processor/AnnotationDecorators', () => ({
13
+ Logging: jest.fn(),
14
+ Permission: jest.fn(),
15
+ RateLimit: jest.fn(),
16
+ AnnotationRegistry: {
17
+ register: jest.fn(),
18
+ get: jest.fn(),
19
+ getAll: jest.fn()
20
+ }
21
+ }));
22
+
23
+ jest.mock('@src/framework/decorator/processor/ProcessorManager', () => ({
24
+ ProcessorManager: {
25
+ registerProcessor: jest.fn(),
26
+ initialize: jest.fn()
27
+ }
28
+ }));
29
+
30
+ jest.mock('@src/framework/utils/logger', () => ({
31
+ logger: {
32
+ info: jest.fn()
33
+ }
34
+ }));
35
+
36
+ describe('示例控制器测试', () => {
37
+ let exampleController: ExampleController;
38
+
39
+ beforeEach(() => {
40
+ exampleController = new ExampleController();
41
+ jest.clearAllMocks();
42
+ });
43
+
44
+ describe('ExampleController', () => {
45
+ test('应该能够创建控制器实例', () => {
46
+ expect(exampleController).toBeInstanceOf(ExampleController);
47
+ });
48
+
49
+ test('getSecureData方法应该返回正确的数据结构', async () => {
50
+ const mockQuery = { id: '123' };
51
+ const mockState = { user: { id: 1, name: 'test' } };
52
+
53
+ const result = await exampleController.getSecureData(mockQuery, mockState);
54
+
55
+ expect(result).toEqual({
56
+ code: 0,
57
+ data: {
58
+ message: '这是受保护的数据',
59
+ user: mockState.user,
60
+ query: mockQuery
61
+ }
62
+ });
63
+ });
64
+
65
+ test('getMixedData方法应该返回正确的数据结构', async () => {
66
+ const mockQuery = { id: '456' };
67
+
68
+ const result = await exampleController.getMixedData(mockQuery);
69
+
70
+ expect(result).toEqual({
71
+ code: 0,
72
+ data: {
73
+ message: '混合注解示例',
74
+ query: mockQuery
75
+ }
76
+ });
77
+ });
78
+
79
+ test('getNewOnlyData方法应该返回正确的数据结构', async () => {
80
+ const result = await exampleController.getNewOnlyData();
81
+
82
+ expect(result).toEqual({
83
+ code: 0,
84
+ data: {
85
+ message: '仅使用新注解系统'
86
+ }
87
+ });
88
+ });
89
+ });
90
+
91
+ describe('注解装饰器测试', () => {
92
+ test('getSecureData方法应该有正确的注解', () => {
93
+ const { Logging, Permission, RateLimit } = require('@src/framework/decorator/processor/AnnotationDecorators');
94
+
95
+ // 验证装饰器被调用
96
+ expect(Logging).toHaveBeenCalled();
97
+ expect(Permission).toHaveBeenCalledWith({ requiredPermission: 'read:data' });
98
+ expect(RateLimit).toHaveBeenCalledWith({ maxRequests: 10, windowMs: 60000 });
99
+ });
100
+
101
+ test('getMixedData方法应该有Logging注解', () => {
102
+ const { Logging } = require('@src/framework/decorator/processor/AnnotationDecorators');
103
+
104
+ expect(Logging).toHaveBeenCalled();
105
+ });
106
+
107
+ test('getNewOnlyData方法应该有Logging和RateLimit注解', () => {
108
+ const { Logging, RateLimit } = require('@src/framework/decorator/processor/AnnotationDecorators');
109
+
110
+ expect(Logging).toHaveBeenCalled();
111
+ expect(RateLimit).toHaveBeenCalledWith({ maxRequests: 5, windowMs: 30000 });
112
+ });
113
+ });
114
+
115
+ describe('initializeCustomProcessors', () => {
116
+ test('应该注册自定义处理器', () => {
117
+ const { ProcessorManager } = require('@src/framework/decorator/processor/ProcessorManager');
118
+
119
+ initializeCustomProcessors();
120
+
121
+ expect(ProcessorManager.registerProcessor).toHaveBeenCalledTimes(3);
122
+ });
123
+
124
+ test('应该记录注册日志', () => {
125
+ const { logger } = require('@src/framework/utils/logger');
126
+
127
+ initializeCustomProcessors();
128
+
129
+ expect(logger.info).toHaveBeenCalledWith('自定义注解处理器已注册');
130
+ });
131
+ });
132
+
133
+ describe('控制器方法集成测试', () => {
134
+ test('getSecureData方法应该处理权限检查', async () => {
135
+ const mockQuery = { id: '123' };
136
+ const mockState = {
137
+ user: {
138
+ id: 1,
139
+ name: 'test',
140
+ permissions: ['read:data']
141
+ }
142
+ };
143
+
144
+ const result = await exampleController.getSecureData(mockQuery, mockState);
145
+
146
+ expect(result.code).toBe(0);
147
+ expect(result.data.user).toEqual(mockState.user);
148
+ });
149
+
150
+ test('getMixedData方法应该处理查询参数', async () => {
151
+ const mockQuery = {
152
+ id: '456',
153
+ name: 'test',
154
+ category: 'example'
155
+ };
156
+
157
+ const result = await exampleController.getMixedData(mockQuery);
158
+
159
+ expect(result.code).toBe(0);
160
+ expect(result.data.query).toEqual(mockQuery);
161
+ });
162
+
163
+ test('getNewOnlyData方法应该返回静态数据', async () => {
164
+ const result = await exampleController.getNewOnlyData();
165
+
166
+ expect(result.code).toBe(0);
167
+ expect(result.data.message).toBe('仅使用新注解系统');
168
+ });
169
+ });
170
+
171
+ describe('错误处理测试', () => {
172
+ test('方法应该能够处理异常情况', async () => {
173
+ // 测试空参数
174
+ const result1 = await exampleController.getSecureData(null, null);
175
+ expect(result1.code).toBe(0);
176
+
177
+ // 测试undefined参数
178
+ const result2 = await exampleController.getMixedData(undefined);
179
+ expect(result2.code).toBe(0);
180
+
181
+ // 测试空对象参数
182
+ const result3 = await exampleController.getSecureData({}, {});
183
+ expect(result3.code).toBe(0);
184
+ });
185
+ });
186
+
187
+ describe('注解系统兼容性测试', () => {
188
+ test('应该能够与旧的注解系统兼容', () => {
189
+ const { Get, Query, State } = require('@src/framework/decorator/controller');
190
+
191
+ // 验证旧的装饰器被调用
192
+ expect(Get).toHaveBeenCalled();
193
+ expect(Query).toHaveBeenCalled();
194
+ expect(State).toHaveBeenCalled();
195
+ });
196
+
197
+ test('应该能够使用新的注解装饰器', () => {
198
+ const { Logging, Permission, RateLimit } = require('@src/framework/decorator/processor/AnnotationDecorators');
199
+
200
+ // 验证新的装饰器被调用
201
+ expect(Logging).toHaveBeenCalled();
202
+ expect(Permission).toHaveBeenCalled();
203
+ expect(RateLimit).toHaveBeenCalled();
204
+ });
205
+ });
206
+
207
+ describe('性能测试', () => {
208
+ test('方法调用应该有合理的性能', async () => {
209
+ const startTime = Date.now();
210
+
211
+ for (let i = 0; i < 1000; i++) {
212
+ await exampleController.getNewOnlyData();
213
+ }
214
+
215
+ const endTime = Date.now();
216
+ const duration = endTime - startTime;
217
+
218
+ // 1000次调用应该在合理时间内完成(这里设置为1秒)
219
+ expect(duration).toBeLessThan(1000);
220
+ });
221
+ });
222
+ });
@@ -0,0 +1,200 @@
1
+ import { NewAnnotationExampleController } from '../../../src/controllers/example/NewAnnotationExampleController';
2
+ import { MigrationHelper } from '../../../src/framework/utils/MigrationHelper';
3
+ import { ProcessorManager } from '../../../src/framework/decorator/processor/ProcessorManager';
4
+ import { TestDatabaseHelper, TestUtils } from '../../utils/testHelpers';
5
+
6
+ describe('新注解系统集成测试', () => {
7
+ let controller: NewAnnotationExampleController;
8
+
9
+ beforeAll(async () => {
10
+ // 初始化测试数据库
11
+ await TestDatabaseHelper.initTestDatabase();
12
+
13
+ // 启用新注解系统
14
+ MigrationHelper.enableNewSystem();
15
+
16
+ // 创建控制器实例
17
+ controller = new NewAnnotationExampleController();
18
+ });
19
+
20
+ afterAll(async () => {
21
+ // 清理测试数据库
22
+ await TestDatabaseHelper.closeTestDatabase();
23
+ });
24
+
25
+ beforeEach(async () => {
26
+ // 重置测试数据
27
+ await TestDatabaseHelper.resetTestData();
28
+ });
29
+
30
+ describe('系统状态检查', () => {
31
+ test('应该正确初始化新注解系统', () => {
32
+ const status = MigrationHelper.getSystemStatus();
33
+ expect(status.newSystemEnabled).toBe(true);
34
+ expect(status.newSystemInitialized).toBe(true);
35
+ });
36
+
37
+ test('应该能够检测控制器注解类型', () => {
38
+ const isNew = MigrationHelper.isUsingNewAnnotationSystem(controller);
39
+ const isLegacy = MigrationHelper.isUsingLegacyAnnotationSystem(controller);
40
+
41
+ expect(isNew).toBe(true);
42
+ expect(isLegacy).toBe(true); // 因为使用了混合注解
43
+ });
44
+
45
+ test('应该能够检查控制器兼容性', () => {
46
+ const compatibility = MigrationHelper.checkControllerCompatibility(controller);
47
+ expect(compatibility.compatible).toBe(true);
48
+ });
49
+ });
50
+
51
+ describe('基础功能测试', () => {
52
+ test('应该能够执行基础示例方法', async () => {
53
+ const mockQuery = { id: '123', name: 'test' };
54
+ const mockContext = TestUtils.createMockContext({}, mockQuery);
55
+
56
+ const result = await controller.basicExample(mockQuery);
57
+
58
+ expect(result.code).toBe(0);
59
+ expect(result.data).toBe('基础示例执行成功');
60
+ });
61
+
62
+ test('应该能够处理权限检查', async () => {
63
+ const mockUser = {
64
+ id: 1,
65
+ name: 'test',
66
+ permissions: ['read:sensitive-data']
67
+ };
68
+ const mockState = { user: mockUser };
69
+
70
+ const result = await controller.getProtectedData(mockUser);
71
+
72
+ expect(result.code).toBe(0);
73
+ expect(result.data.message).toBe('这是受保护的数据');
74
+ expect(result.data.user).toEqual(mockUser);
75
+ });
76
+
77
+ test('应该能够处理限流', async () => {
78
+ const mockBody = { name: 'test', value: 'example' };
79
+
80
+ // 第一次请求应该成功
81
+ const result1 = await controller.rateLimitedEndpoint(mockBody);
82
+ expect(result1.code).toBe(0);
83
+
84
+ // 连续请求应该成功(在测试环境中限流可能不会生效)
85
+ const result2 = await controller.rateLimitedEndpoint(mockBody);
86
+ expect(result2.code).toBe(0);
87
+ });
88
+ });
89
+
90
+ describe('复合注解测试', () => {
91
+ test('应该能够处理复合注解', async () => {
92
+ const mockQuery = { id: '456', category: 'test' };
93
+ const mockUser = {
94
+ id: 1,
95
+ name: 'test',
96
+ permissions: ['read:complex-data']
97
+ };
98
+
99
+ const result = await controller.complexExample(mockQuery, mockUser);
100
+
101
+ expect(result.code).toBe(0);
102
+ expect(result.data.message).toBe('复杂示例执行成功');
103
+ expect(result.data.query).toEqual(mockQuery);
104
+ expect(result.data.user).toEqual(mockUser);
105
+ });
106
+
107
+ test('应该能够处理混合注解', async () => {
108
+ const mockBody = { name: 'mixed', value: 'example' };
109
+
110
+ const result = await controller.mixedAnnotations(mockBody);
111
+
112
+ expect(result.code).toBe(0);
113
+ expect(result.data.message).toBe('混合注解示例执行成功');
114
+ expect(result.data.note).toBe('这个端点同时使用了新旧注解系统');
115
+ });
116
+ });
117
+
118
+ describe('错误处理测试', () => {
119
+ test('应该能够处理权限不足错误', async () => {
120
+ await expect(controller.errorExample()).rejects.toThrow('模拟权限不足错误');
121
+ });
122
+ });
123
+
124
+ describe('异步处理测试', () => {
125
+ test('应该能够处理异步方法', async () => {
126
+ const startTime = Date.now();
127
+ const result = await controller.asyncExample();
128
+ const endTime = Date.now();
129
+
130
+ expect(result.code).toBe(0);
131
+ expect(result.data.message).toBe('异步处理完成');
132
+ expect(endTime - startTime).toBeGreaterThanOrEqual(1000); // 至少1秒
133
+ });
134
+ });
135
+
136
+ describe('数据验证测试', () => {
137
+ test('应该能够处理数据验证', async () => {
138
+ const mockBody = { name: 'validation', value: 'test' };
139
+
140
+ const result = await controller.validationExample(mockBody);
141
+
142
+ expect(result.code).toBe(0);
143
+ expect(result.data.message).toBe('验证通过');
144
+ expect(result.data.receivedData).toEqual(mockBody);
145
+ });
146
+ });
147
+
148
+ describe('系统切换测试', () => {
149
+ test('应该能够切换注解系统', () => {
150
+ // 当前应该是新系统
151
+ expect(MigrationHelper.getCurrentSystem()).toBe('new');
152
+
153
+ // 切换到旧系统
154
+ MigrationHelper.disableNewSystem();
155
+ expect(MigrationHelper.getCurrentSystem()).toBe('legacy');
156
+
157
+ // 切换回新系统
158
+ MigrationHelper.enableNewSystem();
159
+ expect(MigrationHelper.getCurrentSystem()).toBe('new');
160
+ });
161
+
162
+ test('应该能够切换系统状态', () => {
163
+ const initialState = MigrationHelper.getCurrentSystem();
164
+
165
+ // 切换系统
166
+ const newState = MigrationHelper.toggleSystem();
167
+
168
+ if (initialState === 'new') {
169
+ expect(newState).toBe(false);
170
+ expect(MigrationHelper.getCurrentSystem()).toBe('legacy');
171
+ } else {
172
+ expect(newState).toBe(true);
173
+ expect(MigrationHelper.getCurrentSystem()).toBe('new');
174
+ }
175
+ });
176
+ });
177
+
178
+ describe('性能测试', () => {
179
+ test('应该能够处理大量请求', async () => {
180
+ const mockQuery = { id: 'perf', name: 'test' };
181
+ const startTime = Date.now();
182
+
183
+ // 执行100次请求
184
+ const promises = Array(100).fill(null).map(() =>
185
+ controller.basicExample(mockQuery)
186
+ );
187
+
188
+ const results = await Promise.all(promises);
189
+ const endTime = Date.now();
190
+
191
+ // 验证所有请求都成功
192
+ results.forEach(result => {
193
+ expect(result.code).toBe(0);
194
+ });
195
+
196
+ // 验证性能(100次请求应该在合理时间内完成)
197
+ expect(endTime - startTime).toBeLessThan(5000); // 5秒内完成
198
+ });
199
+ });
200
+ });