143 lines
4.6 KiB
TypeScript
143 lines
4.6 KiB
TypeScript
|
|
/**
|
||
|
|
* Session model unit tests
|
||
|
|
*/
|
||
|
|
|
||
|
|
import { assertEquals, assertExists } from 'jsr:@std/assert';
|
||
|
|
import { describe, it, beforeAll, afterAll, beforeEach } from 'jsr:@std/testing/bdd';
|
||
|
|
import { setupTestDb, teardownTestDb, cleanupTestDb, createTestUser } from '../../helpers/index.ts';
|
||
|
|
import { Session } from '../../../ts/models/session.ts';
|
||
|
|
|
||
|
|
describe('Session Model', () => {
|
||
|
|
let testUserId: string;
|
||
|
|
|
||
|
|
beforeAll(async () => {
|
||
|
|
await setupTestDb();
|
||
|
|
});
|
||
|
|
|
||
|
|
afterAll(async () => {
|
||
|
|
await teardownTestDb();
|
||
|
|
});
|
||
|
|
|
||
|
|
beforeEach(async () => {
|
||
|
|
await cleanupTestDb();
|
||
|
|
const { user } = await createTestUser();
|
||
|
|
testUserId = user.id;
|
||
|
|
});
|
||
|
|
|
||
|
|
describe('createSession', () => {
|
||
|
|
it('should create a session with valid data', async () => {
|
||
|
|
const session = await Session.createSession({
|
||
|
|
userId: testUserId,
|
||
|
|
userAgent: 'Mozilla/5.0',
|
||
|
|
ipAddress: '192.168.1.1',
|
||
|
|
});
|
||
|
|
|
||
|
|
assertExists(session.id);
|
||
|
|
assertEquals(session.userId, testUserId);
|
||
|
|
assertEquals(session.userAgent, 'Mozilla/5.0');
|
||
|
|
assertEquals(session.ipAddress, '192.168.1.1');
|
||
|
|
assertEquals(session.isValid, true);
|
||
|
|
assertExists(session.createdAt);
|
||
|
|
assertExists(session.lastActivityAt);
|
||
|
|
});
|
||
|
|
});
|
||
|
|
|
||
|
|
describe('findValidSession', () => {
|
||
|
|
it('should find valid session by ID', async () => {
|
||
|
|
const created = await Session.createSession({
|
||
|
|
userId: testUserId,
|
||
|
|
userAgent: 'Test Agent',
|
||
|
|
ipAddress: '127.0.0.1',
|
||
|
|
});
|
||
|
|
|
||
|
|
const found = await Session.findValidSession(created.id);
|
||
|
|
assertExists(found);
|
||
|
|
assertEquals(found.id, created.id);
|
||
|
|
});
|
||
|
|
|
||
|
|
it('should not find invalidated session', async () => {
|
||
|
|
const session = await Session.createSession({
|
||
|
|
userId: testUserId,
|
||
|
|
userAgent: 'Test Agent',
|
||
|
|
ipAddress: '127.0.0.1',
|
||
|
|
});
|
||
|
|
await session.invalidate('Logged out');
|
||
|
|
|
||
|
|
const found = await Session.findValidSession(session.id);
|
||
|
|
assertEquals(found, null);
|
||
|
|
});
|
||
|
|
});
|
||
|
|
|
||
|
|
describe('getUserSessions', () => {
|
||
|
|
it('should return all valid sessions for user', async () => {
|
||
|
|
await Session.createSession({ userId: testUserId, userAgent: 'Agent 1', ipAddress: '1.1.1.1' });
|
||
|
|
await Session.createSession({ userId: testUserId, userAgent: 'Agent 2', ipAddress: '2.2.2.2' });
|
||
|
|
await Session.createSession({ userId: testUserId, userAgent: 'Agent 3', ipAddress: '3.3.3.3' });
|
||
|
|
|
||
|
|
const sessions = await Session.getUserSessions(testUserId);
|
||
|
|
assertEquals(sessions.length, 3);
|
||
|
|
});
|
||
|
|
|
||
|
|
it('should not return invalidated sessions', async () => {
|
||
|
|
await Session.createSession({ userId: testUserId, userAgent: 'Valid', ipAddress: '1.1.1.1' });
|
||
|
|
const invalid = await Session.createSession({
|
||
|
|
userId: testUserId,
|
||
|
|
userAgent: 'Invalid',
|
||
|
|
ipAddress: '2.2.2.2',
|
||
|
|
});
|
||
|
|
await invalid.invalidate('test');
|
||
|
|
|
||
|
|
const sessions = await Session.getUserSessions(testUserId);
|
||
|
|
assertEquals(sessions.length, 1);
|
||
|
|
});
|
||
|
|
});
|
||
|
|
|
||
|
|
describe('invalidate', () => {
|
||
|
|
it('should invalidate session with reason', async () => {
|
||
|
|
const session = await Session.createSession({
|
||
|
|
userId: testUserId,
|
||
|
|
userAgent: 'Test',
|
||
|
|
ipAddress: '127.0.0.1',
|
||
|
|
});
|
||
|
|
|
||
|
|
await session.invalidate('User logged out');
|
||
|
|
|
||
|
|
assertEquals(session.isValid, false);
|
||
|
|
assertExists(session.invalidatedAt);
|
||
|
|
assertEquals(session.invalidatedReason, 'User logged out');
|
||
|
|
});
|
||
|
|
});
|
||
|
|
|
||
|
|
describe('invalidateAllUserSessions', () => {
|
||
|
|
it('should invalidate all user sessions', async () => {
|
||
|
|
await Session.createSession({ userId: testUserId, userAgent: 'Agent 1', ipAddress: '1.1.1.1' });
|
||
|
|
await Session.createSession({ userId: testUserId, userAgent: 'Agent 2', ipAddress: '2.2.2.2' });
|
||
|
|
await Session.createSession({ userId: testUserId, userAgent: 'Agent 3', ipAddress: '3.3.3.3' });
|
||
|
|
|
||
|
|
const count = await Session.invalidateAllUserSessions(testUserId, 'Security logout');
|
||
|
|
assertEquals(count, 3);
|
||
|
|
|
||
|
|
const remaining = await Session.getUserSessions(testUserId);
|
||
|
|
assertEquals(remaining.length, 0);
|
||
|
|
});
|
||
|
|
});
|
||
|
|
|
||
|
|
describe('touchActivity', () => {
|
||
|
|
it('should update lastActivityAt', async () => {
|
||
|
|
const session = await Session.createSession({
|
||
|
|
userId: testUserId,
|
||
|
|
userAgent: 'Test',
|
||
|
|
ipAddress: '127.0.0.1',
|
||
|
|
});
|
||
|
|
const originalActivity = session.lastActivityAt;
|
||
|
|
|
||
|
|
// Wait a bit to ensure time difference
|
||
|
|
await new Promise((r) => setTimeout(r, 10));
|
||
|
|
|
||
|
|
await session.touchActivity();
|
||
|
|
|
||
|
|
assertEquals(session.lastActivityAt > originalActivity, true);
|
||
|
|
});
|
||
|
|
});
|
||
|
|
});
|