test: add session management tests

This commit is contained in:
张翔
2026-03-10 11:43:58 +08:00
parent 4ece85a9c3
commit 24cec5f572
2 changed files with 241 additions and 0 deletions
+198
View File
@@ -0,0 +1,198 @@
import { describe, it, expect, beforeEach } from '@jest/globals';
import {
createSession,
isSessionValid,
getSessionAge,
getSessionTimeRemaining,
isSessionExpired,
createSessionWithCustomExpiration,
Session,
SessionData,
} from './session';
describe('session management', () => {
describe('createSession', () => {
it('should create session with user data', () => {
const session = createSession({ userId: '123', role: 'admin' });
expect(session).toBeDefined();
expect(session.userId).toBe('123');
expect(session.role).toBe('admin');
});
it('should create session with createdAt timestamp', () => {
const beforeCreate = Date.now();
const session = createSession({ userId: '123' });
const afterCreate = Date.now();
expect(session.createdAt).toBeGreaterThanOrEqual(beforeCreate);
expect(session.createdAt).toBeLessThanOrEqual(afterCreate);
});
it('should create session with 24 hour expiration', () => {
const session = createSession({ userId: '123' });
const expectedExpiration = session.createdAt + (24 * 60 * 60 * 1000);
expect(session.expiresAt).toBe(expectedExpiration);
});
it('should create session without optional role', () => {
const session = createSession({ userId: '123' });
expect(session.userId).toBe('123');
expect(session.role).toBeUndefined();
});
});
describe('isSessionValid', () => {
it('should return true for valid session', () => {
const session = createSession({ userId: '123' });
expect(isSessionValid(session)).toBe(true);
});
it('should return false for expired session', () => {
const expiredSession = createSessionWithCustomExpiration({ userId: '123' }, -1000);
expect(isSessionValid(expiredSession)).toBe(false);
});
it('should return false for session with zero expiration time', () => {
const session = createSessionWithCustomExpiration({ userId: '123' }, 0);
expect(isSessionValid(session)).toBe(false);
});
it('should return true for session with 1ms remaining', () => {
const session = createSessionWithCustomExpiration({ userId: '123' }, 1);
expect(isSessionValid(session)).toBe(true);
});
});
describe('getSessionAge', () => {
it('should return age of session in milliseconds', () => {
const session = createSession({ userId: '123' });
const age = getSessionAge(session);
expect(age).toBeGreaterThanOrEqual(0);
expect(age).toBeLessThan(100);
});
it('should increase over time', async () => {
const session = createSession({ userId: '123' });
const age1 = getSessionAge(session);
await new Promise(resolve => setTimeout(resolve, 10));
const age2 = getSessionAge(session);
expect(age2).toBeGreaterThan(age1);
});
});
describe('getSessionTimeRemaining', () => {
it('should return positive time for valid session', () => {
const session = createSession({ userId: '123' });
const remaining = getSessionTimeRemaining(session);
expect(remaining).toBeGreaterThan(0);
});
it('should return approximately 24 hours for new session', () => {
const session = createSession({ userId: '123' });
const remaining = getSessionTimeRemaining(session);
const expectedRemaining = 24 * 60 * 60 * 1000;
const tolerance = 100;
expect(remaining).toBeGreaterThanOrEqual(expectedRemaining - tolerance);
expect(remaining).toBeLessThanOrEqual(expectedRemaining + tolerance);
});
it('should return 0 for expired session', () => {
const expiredSession = createSessionWithCustomExpiration({ userId: '123' }, -1000);
const remaining = getSessionTimeRemaining(expiredSession);
expect(remaining).toBe(0);
});
it('should return 0 for session at exact expiration time', () => {
const session = createSessionWithCustomExpiration({ userId: '123' }, 0);
const remaining = getSessionTimeRemaining(session);
expect(remaining).toBe(0);
});
});
describe('isSessionExpired', () => {
it('should return false for valid session', () => {
const session = createSession({ userId: '123' });
expect(isSessionExpired(session)).toBe(false);
});
it('should return true for expired session', () => {
const expiredSession = createSessionWithCustomExpiration({ userId: '123' }, -1000);
expect(isSessionExpired(expiredSession)).toBe(true);
});
it('should return true for session at exact expiration time', () => {
const session = createSessionWithCustomExpiration({ userId: '123' }, 0);
expect(isSessionExpired(session)).toBe(true);
});
it('should return false for session with 1ms remaining', () => {
const session = createSessionWithCustomExpiration({ userId: '123' }, 1);
expect(isSessionExpired(session)).toBe(false);
});
});
describe('createSessionWithCustomExpiration', () => {
it('should create session with custom expiration time', () => {
const session = createSessionWithCustomExpiration({ userId: '123' }, 60000);
const expectedExpiration = session.createdAt + 60000;
expect(session.expiresAt).toBe(expectedExpiration);
});
it('should create session with negative expiration time', () => {
const session = createSessionWithCustomExpiration({ userId: '123' }, -1000);
const expectedExpiration = session.createdAt - 1000;
expect(session.expiresAt).toBe(expectedExpiration);
});
it('should preserve user data', () => {
const session = createSessionWithCustomExpiration(
{ userId: '123', role: 'admin' },
60000
);
expect(session.userId).toBe('123');
expect(session.role).toBe('admin');
});
});
describe('session lifecycle', () => {
it('should track session from creation to expiration', async () => {
const session = createSessionWithCustomExpiration({ userId: '123' }, 100);
expect(isSessionValid(session)).toBe(true);
expect(isSessionExpired(session)).toBe(false);
await new Promise(resolve => setTimeout(resolve, 150));
expect(isSessionValid(session)).toBe(false);
expect(isSessionExpired(session)).toBe(true);
});
it('should have consistent age and time remaining', () => {
const session = createSessionWithCustomExpiration({ userId: '123' }, 10000);
const age = getSessionAge(session);
const remaining = getSessionTimeRemaining(session);
const totalLifetime = age + remaining;
expect(totalLifetime).toBeCloseTo(10000, -2);
});
});
describe('session data integrity', () => {
it('should maintain session data immutability', () => {
const originalData: SessionData = { userId: '123', role: 'admin' };
const session = createSession(originalData);
expect(session.userId).toBe(originalData.userId);
expect(session.role).toBe(originalData.role);
});
it('should handle empty role gracefully', () => {
const session = createSession({ userId: '123', role: '' });
expect(session.role).toBe('');
});
it('should handle special characters in userId', () => {
const session = createSession({ userId: 'user-123@example.com' });
expect(session.userId).toBe('user-123@example.com');
});
});
});
+43
View File
@@ -0,0 +1,43 @@
import { describe, it, expect } from '@jest/globals';
export interface SessionData {
userId: string;
role?: string;
}
export interface Session extends SessionData {
createdAt: number;
expiresAt: number;
}
export function createSession(userData: SessionData): Session {
return {
...userData,
createdAt: Date.now(),
expiresAt: Date.now() + (24 * 60 * 60 * 1000),
};
}
export function isSessionValid(session: Session): boolean {
return Date.now() < session.expiresAt;
}
export function getSessionAge(session: Session): number {
return Date.now() - session.createdAt;
}
export function getSessionTimeRemaining(session: Session): number {
return Math.max(0, session.expiresAt - Date.now());
}
export function isSessionExpired(session: Session): boolean {
return Date.now() >= session.expiresAt;
}
export function createSessionWithCustomExpiration(userData: SessionData, expiresInMs: number): Session {
return {
...userData,
createdAt: Date.now(),
expiresAt: Date.now() + expiresInMs,
};
}