advertisements.integration.test.ts 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264
  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.index.$get({
  50. query: {}
  51. }, {
  52. headers: {
  53. 'Authorization': `Bearer ${testToken}`
  54. }
  55. });
  56. console.debug('广告列表响应状态:', response.status);
  57. expect(response.status).toBe(200);
  58. if (response.status === 200) {
  59. const data = await response.json();
  60. expect(data).toHaveProperty('data');
  61. expect(Array.isArray(data.data)).toBe(true);
  62. }
  63. });
  64. it('应该拒绝未认证用户的访问', async () => {
  65. const response = await client.index.$get({
  66. query: {}
  67. });
  68. expect(response.status).toBe(401);
  69. });
  70. });
  71. describe('POST /advertisements', () => {
  72. it('应该成功创建广告', async () => {
  73. const createData = {
  74. title: '测试广告',
  75. typeId: testAdvertisementType.id,
  76. code: 'test_ad',
  77. url: 'https://example.com',
  78. sort: 10,
  79. status: 1,
  80. actionType: 1
  81. };
  82. const response = await client.index.$post({
  83. json: createData
  84. }, {
  85. headers: {
  86. 'Authorization': `Bearer ${testToken}`
  87. }
  88. });
  89. console.debug('创建广告响应状态:', response.status);
  90. expect(response.status).toBe(201);
  91. if (response.status === 201) {
  92. const data = await response.json();
  93. expect(data).toHaveProperty('id');
  94. expect(data.title).toBe(createData.title);
  95. expect(data.code).toBe(createData.code);
  96. expect(data.status).toBe(createData.status);
  97. }
  98. });
  99. it('应该验证创建广告的必填字段', async () => {
  100. const invalidData = {
  101. // 缺少必填字段
  102. title: '',
  103. typeId: 0,
  104. code: '',
  105. url: 'https://example.com'
  106. };
  107. const response = await client.index.$post({
  108. json: invalidData
  109. }, {
  110. headers: {
  111. 'Authorization': `Bearer ${testToken}`
  112. }
  113. });
  114. expect(response.status).toBe(400);
  115. });
  116. });
  117. describe('GET /advertisements/:id', () => {
  118. it('应该返回指定广告的详情', async () => {
  119. // 先创建一个广告
  120. const dataSource = await IntegrationTestDatabase.getDataSource();
  121. const advertisementRepository = dataSource.getRepository(Advertisement);
  122. const testAdvertisement = advertisementRepository.create({
  123. title: '测试广告详情',
  124. typeId: testAdvertisementType.id,
  125. code: 'test_ad_detail',
  126. url: 'https://example.com',
  127. sort: 5,
  128. status: 1,
  129. actionType: 1,
  130. createdBy: testUser.id
  131. });
  132. await advertisementRepository.save(testAdvertisement);
  133. const response = await client[':id'].$get({
  134. param: { id: testAdvertisement.id }
  135. }, {
  136. headers: {
  137. 'Authorization': `Bearer ${testToken}`
  138. }
  139. });
  140. console.debug('广告详情响应状态:', response.status);
  141. expect(response.status).toBe(200);
  142. if (response.status === 200) {
  143. const data = await response.json();
  144. expect(data.id).toBe(testAdvertisement.id);
  145. expect(data.title).toBe(testAdvertisement.title);
  146. expect(data.code).toBe(testAdvertisement.code);
  147. }
  148. });
  149. it('应该处理不存在的广告', async () => {
  150. const response = await client[':id'].$get({
  151. param: { id: 999999 }
  152. }, {
  153. headers: {
  154. 'Authorization': `Bearer ${testToken}`
  155. }
  156. });
  157. expect(response.status).toBe(404);
  158. });
  159. });
  160. describe('PUT /advertisements/:id', () => {
  161. it('应该成功更新广告', async () => {
  162. // 先创建一个广告
  163. const dataSource = await IntegrationTestDatabase.getDataSource();
  164. const advertisementRepository = dataSource.getRepository(Advertisement);
  165. const testAdvertisement = advertisementRepository.create({
  166. title: '原始广告',
  167. typeId: testAdvertisementType.id,
  168. code: 'original_ad',
  169. url: 'https://example.com',
  170. sort: 5,
  171. status: 1,
  172. actionType: 1,
  173. createdBy: testUser.id
  174. });
  175. await advertisementRepository.save(testAdvertisement);
  176. const updateData = {
  177. title: '更新后的广告',
  178. code: 'updated_ad',
  179. sort: 15
  180. };
  181. const response = await client[':id'].$put({
  182. param: { id: testAdvertisement.id },
  183. json: updateData
  184. }, {
  185. headers: {
  186. 'Authorization': `Bearer ${testToken}`
  187. }
  188. });
  189. console.debug('更新广告响应状态:', response.status);
  190. expect(response.status).toBe(200);
  191. if (response.status === 200) {
  192. const data = await response.json();
  193. expect(data.title).toBe(updateData.title);
  194. expect(data.code).toBe(updateData.code);
  195. expect(data.sort).toBe(updateData.sort);
  196. }
  197. });
  198. });
  199. describe('DELETE /advertisements/:id', () => {
  200. it('应该成功删除广告', async () => {
  201. // 先创建一个广告
  202. const dataSource = await IntegrationTestDatabase.getDataSource();
  203. const advertisementRepository = dataSource.getRepository(Advertisement);
  204. const testAdvertisement = advertisementRepository.create({
  205. title: '待删除广告',
  206. typeId: testAdvertisementType.id,
  207. code: 'delete_ad',
  208. url: 'https://example.com',
  209. sort: 5,
  210. status: 1,
  211. actionType: 1,
  212. createdBy: testUser.id
  213. });
  214. await advertisementRepository.save(testAdvertisement);
  215. const response = await client[':id'].$delete({
  216. param: { id: testAdvertisement.id }
  217. }, {
  218. headers: {
  219. 'Authorization': `Bearer ${testToken}`
  220. }
  221. });
  222. console.debug('删除广告响应状态:', response.status);
  223. expect(response.status).toBe(204);
  224. // 验证广告确实被删除
  225. const deletedAdvertisement = await advertisementRepository.findOne({
  226. where: { id: testAdvertisement.id }
  227. });
  228. expect(deletedAdvertisement).toBeNull();
  229. });
  230. });
  231. });