add unit tests
All checks were successful
continuous-integration/drone/push Build is passing

This commit is contained in:
2026-02-24 11:14:24 +01:00
parent 7e938138ff
commit d7e144620e
23 changed files with 2766 additions and 17 deletions

60
tests/auth/jwt.test.ts Normal file
View File

@@ -0,0 +1,60 @@
import { beforeEach, describe, expect, it, vi } from 'vitest';
import { decodeJwtPayload, isJwtExpired } from '../../src/auth/jwt';
function createJwt(payload: Record<string, unknown>) {
const header = { alg: 'HS256', typ: 'JWT' };
const encode = (value: object) =>
btoa(JSON.stringify(value)).replace(/\+/g, '-').replace(/\//g, '_').replace(/=+$/g, '');
return `${encode(header)}.${encode(payload)}.signature`;
}
describe('decodeJwtPayload', () => {
it('returns null for malformed tokens or invalid payloads', () => {
expect(decodeJwtPayload('not-a-jwt')).toBeNull();
expect(decodeJwtPayload('a.b')).toBeNull();
expect(decodeJwtPayload('a.b.c.d')).toBeNull();
const nonJson = 'header.' + btoa('nope') + '.sig';
expect(decodeJwtPayload(nonJson)).toBeNull();
const nonObjectPayload = createJwt({ value: 1 }).replace(
/\.[^.]+\./,
`.${btoa('1').replace(/=+$/g, '')}.`,
);
expect(decodeJwtPayload(nonObjectPayload)).toBeNull();
});
it('decodes valid base64url payloads', () => {
const payload = { sub: 'user-1', role: 'ADMIN', exp: 1735689600 };
expect(decodeJwtPayload(createJwt(payload))).toEqual(payload);
});
});
describe('isJwtExpired', () => {
beforeEach(() => {
vi.useFakeTimers();
});
it('returns false for malformed tokens and invalid exp claim', () => {
expect(isJwtExpired('not-a-jwt')).toBe(false);
expect(isJwtExpired(createJwt({}))).toBe(false);
expect(isJwtExpired(createJwt({ exp: 'nope' }))).toBe(false);
expect(isJwtExpired(createJwt({ exp: Number.POSITIVE_INFINITY }))).toBe(false);
});
it('returns true when token is expired', () => {
vi.setSystemTime(new Date('2026-01-01T00:00:00Z'));
const exp = Math.floor(new Date('2025-12-31T23:59:00Z').getTime() / 1000);
expect(isJwtExpired(createJwt({ exp }))).toBe(true);
});
it('applies skew seconds when evaluating expiration', () => {
vi.setSystemTime(new Date('2026-01-01T00:00:00Z'));
const exp = Math.floor(new Date('2026-01-01T00:00:10Z').getTime() / 1000);
expect(isJwtExpired(createJwt({ exp }), 15)).toBe(true);
expect(isJwtExpired(createJwt({ exp }), 5)).toBe(false);
});
});