jwt.util.test.ts 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  1. import { describe, it, expect, vi, beforeEach } from 'vitest';
  2. import { JWTUtil } from '../../src/utils/jwt.util';
  3. describe('JWTUtil', () => {
  4. const mockUser = {
  5. id: 1,
  6. username: 'testuser',
  7. roles: [{ name: 'admin' }, { name: 'user' }],
  8. openid: 'test-openid'
  9. };
  10. beforeEach(() => {
  11. // 重置环境变量
  12. process.env.JWT_SECRET = 'test-secret-key';
  13. process.env.JWT_EXPIRES_IN = '1h';
  14. });
  15. describe('generateToken', () => {
  16. it('应该成功生成JWT token', () => {
  17. const token = JWTUtil.generateToken(mockUser);
  18. expect(token).toBeDefined();
  19. expect(typeof token).toBe('string');
  20. expect(token.split('.')).toHaveLength(3); // JWT token 应该有3部分
  21. });
  22. it('应该使用额外的payload数据', () => {
  23. const additionalPayload = { customField: 'customValue' };
  24. const token = JWTUtil.generateToken(mockUser, additionalPayload);
  25. const decoded = JWTUtil.decodeToken(token);
  26. expect(decoded).toMatchObject({
  27. id: mockUser.id,
  28. username: mockUser.username,
  29. roles: ['admin', 'user'],
  30. openid: mockUser.openid,
  31. customField: 'customValue'
  32. });
  33. });
  34. it('当用户缺少必要字段时应该抛出错误', () => {
  35. const invalidUser = { id: 1 } as any; // 缺少 username
  36. expect(() => {
  37. JWTUtil.generateToken(invalidUser);
  38. }).toThrow('用户ID和用户名不能为空');
  39. });
  40. });
  41. describe('verifyToken', () => {
  42. it('应该成功验证有效的token', () => {
  43. const token = JWTUtil.generateToken(mockUser);
  44. const payload = JWTUtil.verifyToken(token);
  45. expect(payload).toMatchObject({
  46. id: mockUser.id,
  47. username: mockUser.username,
  48. roles: ['admin', 'user'],
  49. openid: mockUser.openid
  50. });
  51. });
  52. it('当token无效时应该抛出错误', () => {
  53. const invalidToken = 'invalid.token.here';
  54. expect(() => {
  55. JWTUtil.verifyToken(invalidToken);
  56. }).toThrow('无效的token');
  57. });
  58. });
  59. describe('decodeToken', () => {
  60. it('应该成功解码token', () => {
  61. const token = JWTUtil.generateToken(mockUser);
  62. const payload = JWTUtil.decodeToken(token);
  63. expect(payload).toMatchObject({
  64. id: mockUser.id,
  65. username: mockUser.username,
  66. roles: ['admin', 'user'],
  67. openid: mockUser.openid
  68. });
  69. });
  70. it('当token格式错误时应该返回null', () => {
  71. const invalidToken = 'invalid';
  72. const payload = JWTUtil.decodeToken(invalidToken);
  73. expect(payload).toBeNull();
  74. });
  75. });
  76. describe('getTokenRemainingTime', () => {
  77. it('应该返回有效的剩余时间', () => {
  78. const token = JWTUtil.generateToken(mockUser, {}, '1h'); // 明确指定1小时过期
  79. const remainingTime = JWTUtil.getTokenRemainingTime(token);
  80. expect(remainingTime).toBeGreaterThan(0);
  81. expect(remainingTime).toBeLessThanOrEqual(3600); // 1小时
  82. });
  83. it('当token无效时应该返回0', () => {
  84. const invalidToken = 'invalid.token.here';
  85. const remainingTime = JWTUtil.getTokenRemainingTime(invalidToken);
  86. expect(remainingTime).toBe(0);
  87. });
  88. });
  89. });