- Auth service: hashPassword/verifyPassword via bcrypt - Storage service: saveFile, getFilePath, deleteStoredFile with ENOENT handling - Types: JwtPayload interface - Logging middleware: createLogger writing AUTH_FAILURE, AUTH_SUCCESS, FILE_NOT_FOUND - 27 tests passing Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
61 lines
2.3 KiB
TypeScript
61 lines
2.3 KiB
TypeScript
import { describe, it, expect, beforeEach, afterEach } from 'vitest';
|
|
import { mkdtempSync, rmSync, readFileSync, existsSync } from 'fs';
|
|
import { tmpdir } from 'os';
|
|
import { join } from 'path';
|
|
import { createLogger } from '../../src/middleware/logging.ts';
|
|
|
|
describe('middleware/logging', () => {
|
|
let logDir: string;
|
|
let logFile: string;
|
|
|
|
beforeEach(() => {
|
|
logDir = mkdtempSync(join(tmpdir(), 'nanodrop-log-test-'));
|
|
logFile = join(logDir, 'test.log');
|
|
});
|
|
|
|
afterEach(() => {
|
|
rmSync(logDir, { recursive: true, force: true });
|
|
});
|
|
|
|
it('writes AUTH_FAILURE log entry', async () => {
|
|
const logger = createLogger(logFile);
|
|
await logger.authFailure({ ip: '1.2.3.4', userAgent: 'TestAgent/1.0', username: 'admin' });
|
|
const content = readFileSync(logFile, 'utf-8');
|
|
expect(content).toMatch(/AUTH_FAILURE/);
|
|
expect(content).toMatch(/ip=1\.2\.3\.4/);
|
|
expect(content).toMatch(/username="admin"/);
|
|
expect(content).toMatch(/user-agent="TestAgent\/1\.0"/);
|
|
});
|
|
|
|
it('writes AUTH_SUCCESS log entry', async () => {
|
|
const logger = createLogger(logFile);
|
|
await logger.authSuccess({ ip: '1.2.3.4', userAgent: 'TestAgent/1.0', username: 'bob' });
|
|
const content = readFileSync(logFile, 'utf-8');
|
|
expect(content).toMatch(/AUTH_SUCCESS/);
|
|
expect(content).toMatch(/username="bob"/);
|
|
});
|
|
|
|
it('writes FILE_NOT_FOUND log entry', async () => {
|
|
const logger = createLogger(logFile);
|
|
await logger.fileNotFound({ ip: '5.6.7.8', userAgent: 'curl/7.0', fileId: 'abc123' });
|
|
const content = readFileSync(logFile, 'utf-8');
|
|
expect(content).toMatch(/FILE_NOT_FOUND/);
|
|
expect(content).toMatch(/file_id="abc123"/);
|
|
});
|
|
|
|
it('creates log file if it does not exist', async () => {
|
|
expect(existsSync(logFile)).toBe(false);
|
|
const logger = createLogger(logFile);
|
|
await logger.authSuccess({ ip: '1.1.1.1', userAgent: 'x', username: 'u' });
|
|
expect(existsSync(logFile)).toBe(true);
|
|
});
|
|
|
|
it('appends multiple entries', async () => {
|
|
const logger = createLogger(logFile);
|
|
await logger.authSuccess({ ip: '1.1.1.1', userAgent: 'a', username: 'u1' });
|
|
await logger.authFailure({ ip: '2.2.2.2', userAgent: 'b', username: 'u2' });
|
|
const lines = readFileSync(logFile, 'utf-8').trim().split('\n');
|
|
expect(lines).toHaveLength(2);
|
|
});
|
|
});
|