tenant-routes.integration.test.ts 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326
  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 { tenantRoutes } from '../../src/routes';
  8. import { TenantEntityMt } from '../../src/entities';
  9. // 设置集成测试钩子
  10. setupIntegrationDatabaseHooksWithEntities([UserEntity, Role, TenantEntityMt, File])
  11. describe('租户管理API集成测试', () => {
  12. let client: ReturnType<typeof testClient<typeof tenantRoutes>>;
  13. let superAdminToken: string;
  14. let regularUserToken: string;
  15. let testUser: UserEntity;
  16. let superAdminUser: UserEntity;
  17. beforeEach(async () => {
  18. // 创建测试客户端
  19. client = testClient(tenantRoutes);
  20. // 获取数据源
  21. const dataSource = await IntegrationTestDatabase.getDataSource();
  22. // 创建测试用户
  23. const userRepository = dataSource.getRepository(UserEntity);
  24. const roleRepository = dataSource.getRepository(Role);
  25. // 创建超级管理员用户(ID为1)
  26. superAdminUser = userRepository.create({
  27. id: 1,
  28. username: 'superadmin',
  29. password: 'hashed_password',
  30. nickname: '超级管理员',
  31. status: 1
  32. });
  33. await userRepository.save(superAdminUser);
  34. // 创建普通测试用户
  35. testUser = userRepository.create({
  36. username: 'testuser',
  37. password: 'hashed_password',
  38. nickname: '测试用户',
  39. status: 1
  40. });
  41. await userRepository.save(testUser);
  42. // 生成token
  43. superAdminToken = JWTUtil.generateToken(superAdminUser);
  44. regularUserToken = JWTUtil.generateToken(testUser);
  45. });
  46. afterEach(async () => {
  47. vi.clearAllMocks();
  48. });
  49. describe('创建租户', () => {
  50. it('超级管理员应该能够创建租户', async () => {
  51. const response = await client.index.$post({
  52. json: {
  53. name: '测试租户',
  54. code: 'test-tenant',
  55. contactName: '联系人',
  56. phone: '13800138000',
  57. email: 'test@example.com',
  58. status: 1
  59. }
  60. }, {
  61. headers: {
  62. Authorization: `Bearer ${superAdminToken}`
  63. }
  64. });
  65. expect(response.status).toBe(201);
  66. const data = await response.json();
  67. expect(data.name).toBe('测试租户');
  68. expect(data.code).toBe('test-tenant');
  69. expect(data.status).toBe(1);
  70. });
  71. it('普通用户不应该能够创建租户', async () => {
  72. const response = await client.index.$post({
  73. json: {
  74. name: '测试租户',
  75. code: 'test-tenant',
  76. contactName: '联系人',
  77. phone: '13800138000',
  78. email: 'test@example.com',
  79. status: 1
  80. }
  81. }, {
  82. headers: {
  83. Authorization: `Bearer ${regularUserToken}`
  84. }
  85. });
  86. expect(response.status).toBe(403);
  87. const data = await response.json();
  88. expect(data.message).toContain('Access denied');
  89. });
  90. it('未认证用户不应该能够创建租户', async () => {
  91. const response = await client.index.$post({
  92. json: {
  93. name: '测试租户',
  94. code: 'test-tenant',
  95. contactName: '联系人',
  96. phone: '13800138000',
  97. email: 'test@example.com',
  98. status: 1
  99. }
  100. });
  101. expect(response.status).toBe(401);
  102. });
  103. });
  104. describe('获取租户列表', () => {
  105. beforeEach(async () => {
  106. // 创建测试租户数据
  107. const dataSource = await IntegrationTestDatabase.getDataSource();
  108. const tenantRepository = dataSource.getRepository(TenantEntityMt);
  109. await tenantRepository.save([
  110. {
  111. name: '租户A',
  112. code: 'tenant-a',
  113. contactName: '联系人A',
  114. phone: '13800138001',
  115. email: 'a@example.com',
  116. status: 1,
  117. createdBy: 1
  118. },
  119. {
  120. name: '租户B',
  121. code: 'tenant-b',
  122. contactName: '联系人B',
  123. phone: '13800138002',
  124. email: 'b@example.com',
  125. status: 2,
  126. createdBy: 1
  127. }
  128. ]);
  129. });
  130. it('超级管理员应该能够获取租户列表', async () => {
  131. const response = await client.index.$get({
  132. query: {}
  133. }, {
  134. headers: {
  135. Authorization: `Bearer ${superAdminToken}`
  136. }
  137. });
  138. console.debug('列表查询响应状态:', response.status);
  139. if (response.status !== 200) {
  140. const errorData = await response.json();
  141. console.debug('错误响应:', errorData);
  142. }
  143. expect(response.status).toBe(200);
  144. const data = await response.json();
  145. expect(data.data).toHaveLength(2);
  146. expect(data.pagination.total).toBe(2);
  147. });
  148. it('普通用户不应该能够获取租户列表', async () => {
  149. const response = await client.index.$get({
  150. query: {}
  151. }, {
  152. headers: {
  153. Authorization: `Bearer ${regularUserToken}`
  154. }
  155. });
  156. expect(response.status).toBe(403);
  157. });
  158. });
  159. describe('获取单个租户', () => {
  160. let testTenant: TenantEntityMt;
  161. beforeEach(async () => {
  162. const dataSource = await IntegrationTestDatabase.getDataSource();
  163. const tenantRepository = dataSource.getRepository(TenantEntityMt);
  164. testTenant = await tenantRepository.save({
  165. name: '测试租户',
  166. code: 'test-tenant',
  167. contactName: '联系人',
  168. phone: '13800138000',
  169. email: 'test@example.com',
  170. status: 1,
  171. createdBy: 1
  172. });
  173. });
  174. it('超级管理员应该能够获取租户详情', async () => {
  175. const response = await client[':id'].$get({
  176. param: { id: testTenant.id.toString() }
  177. }, {
  178. headers: {
  179. Authorization: `Bearer ${superAdminToken}`
  180. }
  181. });
  182. expect(response.status).toBe(200);
  183. const data = await response.json();
  184. expect(data.name).toBe('测试租户');
  185. expect(data.code).toBe('test-tenant');
  186. });
  187. it('普通用户不应该能够获取租户详情', async () => {
  188. const response = await client[':id'].$get({
  189. param: { id: testTenant.id.toString() }
  190. }, {
  191. headers: {
  192. Authorization: `Bearer ${regularUserToken}`
  193. }
  194. });
  195. expect(response.status).toBe(403);
  196. });
  197. });
  198. describe('更新租户', () => {
  199. let testTenant: TenantEntityMt;
  200. beforeEach(async () => {
  201. const dataSource = await IntegrationTestDatabase.getDataSource();
  202. const tenantRepository = dataSource.getRepository(TenantEntityMt);
  203. testTenant = await tenantRepository.save({
  204. name: '测试租户',
  205. code: 'test-tenant',
  206. contactName: '联系人',
  207. phone: '13800138000',
  208. email: 'test@example.com',
  209. status: 1,
  210. createdBy: 1
  211. });
  212. });
  213. it('超级管理员应该能够更新租户', async () => {
  214. const response = await client[':id'].$put({
  215. param: { id: testTenant.id.toString() },
  216. json: {
  217. name: '更新后的租户',
  218. contactName: '新联系人',
  219. phone: '13900139000',
  220. status: 2
  221. }
  222. }, {
  223. headers: {
  224. Authorization: `Bearer ${superAdminToken}`
  225. }
  226. });
  227. expect(response.status).toBe(200);
  228. const data = await response.json();
  229. expect(data.name).toBe('更新后的租户');
  230. expect(data.contactName).toBe('新联系人');
  231. expect(data.status).toBe(2);
  232. });
  233. it('普通用户不应该能够更新租户', async () => {
  234. const response = await client[':id'].$put({
  235. param: { id: testTenant.id.toString() },
  236. json: {
  237. name: '更新后的租户'
  238. }
  239. }, {
  240. headers: {
  241. Authorization: `Bearer ${regularUserToken}`
  242. }
  243. });
  244. expect(response.status).toBe(403);
  245. });
  246. });
  247. describe('删除租户', () => {
  248. let testTenant: TenantEntityMt;
  249. beforeEach(async () => {
  250. const dataSource = await IntegrationTestDatabase.getDataSource();
  251. const tenantRepository = dataSource.getRepository(TenantEntityMt);
  252. testTenant = await tenantRepository.save({
  253. name: '测试租户',
  254. code: 'test-tenant',
  255. contactName: '联系人',
  256. phone: '13800138000',
  257. email: 'test@example.com',
  258. status: 1,
  259. createdBy: 1
  260. });
  261. });
  262. it('超级管理员应该能够删除租户', async () => {
  263. const response = await client[':id'].$delete({
  264. param: { id: testTenant.id.toString() }
  265. }, {
  266. headers: {
  267. Authorization: `Bearer ${superAdminToken}`
  268. }
  269. });
  270. expect(response.status).toBe(204);
  271. });
  272. it('普通用户不应该能够删除租户', async () => {
  273. const response = await client[':id'].$delete({
  274. param: { id: testTenant.id.toString() }
  275. }, {
  276. headers: {
  277. Authorization: `Bearer ${regularUserToken}`
  278. }
  279. });
  280. expect(response.status).toBe(403);
  281. });
  282. });
  283. });