Add unit tests for models and services
- Implemented unit tests for the Package model, covering methods such as generateId, findById, findByName, and version management. - Created unit tests for the Repository model, including repository creation, name validation, and retrieval methods. - Added tests for the Session model, focusing on session creation, validation, and invalidation. - Developed unit tests for the User model, ensuring user creation, password hashing, and retrieval methods function correctly. - Implemented AuthService tests, validating login, token refresh, and session management. - Added TokenService tests, covering token creation, validation, and revocation processes.
This commit is contained in:
106
test/helpers/db.helper.ts
Normal file
106
test/helpers/db.helper.ts
Normal file
@@ -0,0 +1,106 @@
|
||||
/**
|
||||
* Database test helper - manages test database lifecycle
|
||||
*
|
||||
* NOTE: The smartdata models use a global `db` singleton. This helper
|
||||
* ensures proper initialization and cleanup for tests.
|
||||
*/
|
||||
|
||||
import * as plugins from '../../ts/plugins.ts';
|
||||
import { testConfig } from '../test.config.ts';
|
||||
|
||||
// Test database instance - separate from production
|
||||
let testDb: plugins.smartdata.SmartdataDb | null = null;
|
||||
let testDbName: string = '';
|
||||
let isConnected = false;
|
||||
|
||||
// We need to patch the global db export since models reference it
|
||||
// This is done by re-initializing with the test config
|
||||
import { initDb, closeDb } from '../../ts/models/db.ts';
|
||||
|
||||
/**
|
||||
* Initialize test database with unique name per test run
|
||||
*/
|
||||
export async function setupTestDb(config?: {
|
||||
mongoUrl?: string;
|
||||
dbName?: string;
|
||||
}): Promise<void> {
|
||||
// If already connected, reuse the connection
|
||||
if (isConnected && testDb) {
|
||||
return;
|
||||
}
|
||||
|
||||
const mongoUrl = config?.mongoUrl || testConfig.mongodb.url;
|
||||
|
||||
// Generate unique database name for this test session
|
||||
const uniqueId = crypto.randomUUID().slice(0, 8);
|
||||
testDbName = config?.dbName || `${testConfig.mongodb.name}-${uniqueId}`;
|
||||
|
||||
// Initialize the global db singleton with test configuration
|
||||
testDb = await initDb(mongoUrl, testDbName);
|
||||
isConnected = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clean up test database - deletes all documents from collections
|
||||
* This is safer than dropping collections which causes index rebuild issues
|
||||
*/
|
||||
export async function cleanupTestDb(): Promise<void> {
|
||||
if (!testDb || !isConnected) return;
|
||||
|
||||
try {
|
||||
const collections = await testDb.mongoDb.listCollections().toArray();
|
||||
for (const col of collections) {
|
||||
// Delete all documents but preserve indexes
|
||||
await testDb.mongoDb.collection(col.name).deleteMany({});
|
||||
}
|
||||
} catch (error) {
|
||||
console.warn('[TestHelper] Error cleaning database:', error);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Teardown test database - drops database and closes connection
|
||||
*/
|
||||
export async function teardownTestDb(): Promise<void> {
|
||||
if (!testDb || !isConnected) return;
|
||||
|
||||
try {
|
||||
// Drop the test database
|
||||
await testDb.mongoDb.dropDatabase();
|
||||
// Close the connection
|
||||
await closeDb();
|
||||
testDb = null;
|
||||
isConnected = false;
|
||||
} catch (error) {
|
||||
console.warn('[TestHelper] Error tearing down database:', error);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear specific collection(s) - deletes all documents
|
||||
*/
|
||||
export async function clearCollections(...collectionNames: string[]): Promise<void> {
|
||||
if (!testDb || !isConnected) return;
|
||||
|
||||
for (const name of collectionNames) {
|
||||
try {
|
||||
await testDb.mongoDb.collection(name).deleteMany({});
|
||||
} catch {
|
||||
// Collection may not exist, ignore
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the current test database name
|
||||
*/
|
||||
export function getTestDbName(): string {
|
||||
return testDbName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the database instance for direct access
|
||||
*/
|
||||
export function getTestDb(): plugins.smartdata.SmartdataDb | null {
|
||||
return testDb;
|
||||
}
|
||||
Reference in New Issue
Block a user