advertisements.integration.test.ts 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257
  1. import { describe, it, expect, beforeEach, vi, afterEach } from 'vitest';
  2. import { testClient } from 'hono/testing';
  3. import { IntegrationTestDatabase, setupIntegrationDatabaseHooksWithEntities } from '@d8d/shared-test-util';
  4. import { JWTUtil } from '@d8d/shared-utils';
  5. import { UserEntity, Role } from '@d8d/user-module';
  6. import { File } from '@d8d/file-module';
  7. import advertisementRoutes from '../../src/routes/advertisements';
  8. import { Advertisement } from '../../src/entities/advertisement.entity';
  9. import { AdvertisementType } from '../../src/entities/advertisement-type.entity';
  10. // 设置集成测试钩子
  11. setupIntegrationDatabaseHooksWithEntities([UserEntity, File, Role, Advertisement, AdvertisementType])
  12. describe('广告管理API集成测试', () => {
  13. let client: ReturnType<typeof testClient<typeof advertisementRoutes>>;
  14. let testToken: string;
  15. let testUser: UserEntity;
  16. let testAdvertisementType: AdvertisementType;
  17. beforeEach(async () => {
  18. // 创建测试客户端
  19. client = testClient(advertisementRoutes);
  20. // 获取数据源
  21. const dataSource = await IntegrationTestDatabase.getDataSource();
  22. // 创建测试用户
  23. const userRepository = dataSource.getRepository(UserEntity);
  24. testUser = userRepository.create({
  25. username: `test_user_${Date.now()}`,
  26. password: 'test_password',
  27. nickname: '测试用户',
  28. registrationSource: 'web'
  29. });
  30. await userRepository.save(testUser);
  31. // 创建测试广告类型
  32. const advertisementTypeRepository = dataSource.getRepository(AdvertisementType);
  33. testAdvertisementType = advertisementTypeRepository.create({
  34. name: '首页轮播',
  35. code: 'home_banner',
  36. remark: '用于首页轮播图展示',
  37. status: 1
  38. });
  39. await advertisementTypeRepository.save(testAdvertisementType);
  40. // 生成测试用户的token
  41. testToken = JWTUtil.generateToken({
  42. id: testUser.id,
  43. username: testUser.username,
  44. roles: [{name:'user'}]
  45. });
  46. });
  47. describe('GET /advertisements', () => {
  48. it('应该返回广告列表', async () => {
  49. const response = await client.$get({
  50. headers: {
  51. 'Authorization': `Bearer ${testToken}`
  52. }
  53. });
  54. console.debug('广告列表响应状态:', response.status);
  55. expect(response.status).toBe(200);
  56. if (response.status === 200) {
  57. const data = await response.json();
  58. expect(data).toHaveProperty('data');
  59. expect(Array.isArray(data.data)).toBe(true);
  60. }
  61. });
  62. it('应该拒绝未认证用户的访问', async () => {
  63. const response = await client.$get();
  64. expect(response.status).toBe(401);
  65. });
  66. });
  67. describe('POST /advertisements', () => {
  68. it('应该成功创建广告', async () => {
  69. const createData = {
  70. title: '测试广告',
  71. typeId: testAdvertisementType.id,
  72. code: 'test_ad',
  73. url: 'https://example.com',
  74. sort: 10,
  75. status: 1,
  76. actionType: 1
  77. };
  78. const response = await client.$post({
  79. json: createData
  80. }, {
  81. headers: {
  82. 'Authorization': `Bearer ${testToken}`
  83. }
  84. });
  85. console.debug('创建广告响应状态:', response.status);
  86. expect(response.status).toBe(201);
  87. if (response.status === 201) {
  88. const data = await response.json();
  89. expect(data).toHaveProperty('id');
  90. expect(data.title).toBe(createData.title);
  91. expect(data.code).toBe(createData.code);
  92. expect(data.status).toBe(createData.status);
  93. }
  94. });
  95. it('应该验证创建广告的必填字段', async () => {
  96. const invalidData = {
  97. // 缺少必填字段
  98. url: 'https://example.com'
  99. };
  100. const response = await client.$post({
  101. json: invalidData
  102. }, {
  103. headers: {
  104. 'Authorization': `Bearer ${testToken}`
  105. }
  106. });
  107. expect(response.status).toBe(400);
  108. });
  109. });
  110. describe('GET /advertisements/:id', () => {
  111. it('应该返回指定广告的详情', async () => {
  112. // 先创建一个广告
  113. const dataSource = await IntegrationTestDatabase.getDataSource();
  114. const advertisementRepository = dataSource.getRepository(Advertisement);
  115. const testAdvertisement = advertisementRepository.create({
  116. title: '测试广告详情',
  117. typeId: testAdvertisementType.id,
  118. code: 'test_ad_detail',
  119. url: 'https://example.com',
  120. sort: 5,
  121. status: 1,
  122. actionType: 1,
  123. createdBy: testUser.id
  124. });
  125. await advertisementRepository.save(testAdvertisement);
  126. const response = await client[':id'].$get({
  127. param: { id: testAdvertisement.id.toString() }
  128. }, {
  129. headers: {
  130. 'Authorization': `Bearer ${testToken}`
  131. }
  132. });
  133. console.debug('广告详情响应状态:', response.status);
  134. expect(response.status).toBe(200);
  135. if (response.status === 200) {
  136. const data = await response.json();
  137. expect(data.id).toBe(testAdvertisement.id);
  138. expect(data.title).toBe(testAdvertisement.title);
  139. expect(data.code).toBe(testAdvertisement.code);
  140. }
  141. });
  142. it('应该处理不存在的广告', async () => {
  143. const response = await client[':id'].$get({
  144. param: { id: '999999' }
  145. }, {
  146. headers: {
  147. 'Authorization': `Bearer ${testToken}`
  148. }
  149. });
  150. expect(response.status).toBe(404);
  151. });
  152. });
  153. describe('PUT /advertisements/:id', () => {
  154. it('应该成功更新广告', async () => {
  155. // 先创建一个广告
  156. const dataSource = await IntegrationTestDatabase.getDataSource();
  157. const advertisementRepository = dataSource.getRepository(Advertisement);
  158. const testAdvertisement = advertisementRepository.create({
  159. title: '原始广告',
  160. typeId: testAdvertisementType.id,
  161. code: 'original_ad',
  162. url: 'https://example.com',
  163. sort: 5,
  164. status: 1,
  165. actionType: 1,
  166. createdBy: testUser.id
  167. });
  168. await advertisementRepository.save(testAdvertisement);
  169. const updateData = {
  170. title: '更新后的广告',
  171. code: 'updated_ad',
  172. sort: 15
  173. };
  174. const response = await client[':id'].$put({
  175. param: { id: testAdvertisement.id.toString() },
  176. json: updateData
  177. }, {
  178. headers: {
  179. 'Authorization': `Bearer ${testToken}`
  180. }
  181. });
  182. console.debug('更新广告响应状态:', response.status);
  183. expect(response.status).toBe(200);
  184. if (response.status === 200) {
  185. const data = await response.json();
  186. expect(data.title).toBe(updateData.title);
  187. expect(data.code).toBe(updateData.code);
  188. expect(data.sort).toBe(updateData.sort);
  189. }
  190. });
  191. });
  192. describe('DELETE /advertisements/:id', () => {
  193. it('应该成功删除广告', async () => {
  194. // 先创建一个广告
  195. const dataSource = await IntegrationTestDatabase.getDataSource();
  196. const advertisementRepository = dataSource.getRepository(Advertisement);
  197. const testAdvertisement = advertisementRepository.create({
  198. title: '待删除广告',
  199. typeId: testAdvertisementType.id,
  200. code: 'delete_ad',
  201. url: 'https://example.com',
  202. sort: 5,
  203. status: 1,
  204. actionType: 1,
  205. createdBy: testUser.id
  206. });
  207. await advertisementRepository.save(testAdvertisement);
  208. const response = await client[':id'].$delete({
  209. param: { id: testAdvertisement.id.toString() }
  210. }, {
  211. headers: {
  212. 'Authorization': `Bearer ${testToken}`
  213. }
  214. });
  215. console.debug('删除广告响应状态:', response.status);
  216. expect(response.status).toBe(204);
  217. // 验证广告确实被删除
  218. const deletedAdvertisement = await advertisementRepository.findOne({
  219. where: { id: testAdvertisement.id }
  220. });
  221. expect(deletedAdvertisement).toBeNull();
  222. });
  223. });
  224. });