import { test, expect } from '../fixtures/auth.fixture'; /** * 多租户数据隔离测试 * 验证不同租户之间的数据隔离 */ test.describe('多租户数据隔离测试', () => { const API_BASE = 'http://localhost:8580'; test.describe('用户数据隔离', () => { test('TC-TENANT-001: 超管跨租户查询用户', async ({ request, loginViaAPI }) => { // 使用超管账号登录 const { token } = await loginViaAPI('platform'); // 查询用户列表(超管应该能看到所有租户的用户) const response = await request.get(`${API_BASE}/api/users`, { headers: { Authorization: `Bearer ${token}`, }, }); const data = await response.json(); expect(data.code).toBe(200); console.log('✓ TC-TENANT-001 通过:超管跨租户查询用户'); }); test('TC-TENANT-002: 租户查询本租户用户', async ({ request, loginViaAPI }) => { // 使用租户账号登录 const { token, tenantCode } = await loginViaAPI('gdlib'); // 查询用户列表(租户应该只能看到本租户的用户) const response = await request.get(`${API_BASE}/api/users`, { headers: { Authorization: `Bearer ${token}`, }, }); const data = await response.json(); expect(data.code).toBe(200); // 验证返回的用户都属于当前租户 if (data.data && data.data.records) { data.data.records.forEach((user: any) => { expect(user.tenantCode).toBe(tenantCode); }); } console.log('✓ TC-TENANT-002 通过:租户查询本租户用户'); }); test('TC-TENANT-003: 租户查询他租户用户', async ({ request, loginViaAPI }) => { // 使用 gdlib 租户账号登录 const { token } = await loginViaAPI('gdlib'); // 尝试查询其他租户的用户(应该返回空列表或无权限) const response = await request.get(`${API_BASE}/api/users?tenantCode=platform`, { headers: { Authorization: `Bearer ${token}`, }, }); const data = await response.json(); // 应该返回空列表或无权限错误 if (data.code === 200 && data.data && data.data.records) { expect(data.data.records.length).toBe(0); } else { // 或者返回无权限错误 expect(data.code).not.toBe(200); } console.log('✓ TC-TENANT-003 通过:租户查询他租户用户'); }); }); test.describe('角色数据隔离', () => { test('租户只能查看本租户角色', async ({ request, loginViaAPI }) => { // 使用租户账号登录 const { token, tenantCode } = await loginViaAPI('gdlib'); // 查询角色列表 const response = await request.get(`${API_BASE}/api/roles`, { headers: { Authorization: `Bearer ${token}`, }, }); const data = await response.json(); expect(data.code).toBe(200); // 验证返回的角色都属于当前租户 if (data.data && data.data.records) { data.data.records.forEach((role: any) => { expect(role.tenantCode).toBe(tenantCode); }); } console.log('✓ 租户只能查看本租户角色'); }); }); test.describe('菜单数据隔离', () => { test('不同租户返回不同菜单', async ({ request, loginViaAPI }) => { // 分别登录不同租户 const platformToken = await loginViaAPI('platform').then(r => r.token); const gdlibToken = await loginViaAPI('gdlib').then(r => r.token); // 获取菜单 const platformMenus = await request.get(`${API_BASE}/api/menus`, { headers: { Authorization: `Bearer ${platformToken}` }, }).then(r => r.json()); const gdlibMenus = await request.get(`${API_BASE}/api/menus`, { headers: { Authorization: `Bearer ${gdlibToken}` }, }).then(r => r.json()); // 验证菜单存在 expect(platformMenus.code).toBe(200); expect(gdlibMenus.code).toBe(200); console.log('✓ 不同租户返回菜单'); }); }); test.describe('权限验证', () => { test('Token 包含租户信息', async ({ request, loginViaAPI }) => { const { token, tenantCode } = await loginViaAPI('gdlib'); // 验证 Token 格式 expect(token).toBeTruthy(); expect(token.split('.').length).toBe(3); // Token 中应该包含租户信息 const tokenBody = JSON.parse( Buffer.from(token.split('.')[1], 'base64').toString('utf-8') ); expect(tokenBody.tenantCode).toBe(tenantCode); console.log('✓ Token 包含租户信息'); }); test('超管标识验证', async ({ request, loginViaAPI }) => { // 登录超管账号 const { token } = await loginViaAPI('platform'); // 解析 Token const tokenBody = JSON.parse( Buffer.from(token.split('.')[1], 'base64').toString('utf-8') ); // 验证超管标识 expect(tokenBody.isSuperTenant).toBeTruthy(); console.log('✓ 超管标识验证通过'); }); }); });