test: add session management tests
This commit is contained in:
@@ -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');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -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,
|
||||||
|
};
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user