Files
gongxue-base/apps/server/src/auth/strategies/jwt.strategy.spec.ts

66 lines
2.1 KiB
TypeScript

import { UnauthorizedException } from '@nestjs/common';
import { JwtStrategy } from './jwt.strategy';
describe('JwtStrategy', () => {
const config = { get: jest.fn().mockReturnValue('secret') };
it('refreshes permissions from the database instead of trusting stale JWT permissions', async () => {
const userRepo = {
findOne: jest.fn().mockResolvedValue({
id: 7,
username: 'teacher',
isActive: true,
isArchived: false,
roles: [
{
name: '老师',
status: 1,
permissions: [{ code: 'class:view' }, { code: 'attendance:view' }],
},
],
}),
};
const strategy = new JwtStrategy(config as never, userRepo as never);
await expect(
strategy.validate({ sub: 7, username: 'teacher', permissions: ['user:delete'] }),
).resolves.toEqual({
id: 7,
username: 'teacher',
permissions: ['class:view', 'attendance:view'],
isSuperAdmin: false,
roles: ['老师'],
});
});
it('recognizes the canonical super_admin role code even when the display name changes', async () => {
const userRepo = {
findOne: jest.fn().mockResolvedValue({
id: 1,
username: 'admin',
isActive: true,
isArchived: false,
roles: [{ name: '系统管理员', code: 'super_admin', status: 1, permissions: [] }],
}),
};
const strategy = new JwtStrategy(config as never, userRepo as never);
await expect(strategy.validate({ sub: 1 })).resolves.toEqual(
expect.objectContaining({ isSuperAdmin: true }),
);
});
it.each([
[{ id: 7, isActive: false, isArchived: false, roles: [] }],
[{ id: 7, isActive: true, isArchived: true, roles: [] }],
[null],
])('rejects disabled, archived, or deleted users', async (user) => {
const userRepo = { findOne: jest.fn().mockResolvedValue(user) };
const strategy = new JwtStrategy(config as never, userRepo as never);
await expect(strategy.validate({ sub: 7, username: 'teacher' })).rejects.toBeInstanceOf(
UnauthorizedException,
);
});
});