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:
2025-11-28 15:27:04 +00:00
parent 61324ba195
commit 44e92d48f2
50 changed files with 4403 additions and 108 deletions

View File

@@ -0,0 +1,240 @@
/**
* Package 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,
createOrgWithOwner,
createTestRepository,
} from '../../helpers/index.ts';
import { Package } from '../../../ts/models/package.ts';
import type { IPackageVersion } from '../../../ts/interfaces/package.interfaces.ts';
describe('Package Model', () => {
let testUserId: string;
let testOrgId: string;
let testRepoId: string;
beforeAll(async () => {
await setupTestDb();
});
afterAll(async () => {
await teardownTestDb();
});
beforeEach(async () => {
await cleanupTestDb();
const { user } = await createTestUser();
testUserId = user.id;
const { organization } = await createOrgWithOwner(testUserId);
testOrgId = organization.id;
const repo = await createTestRepository({
organizationId: testOrgId,
createdById: testUserId,
protocol: 'npm',
});
testRepoId = repo.id;
});
function createVersion(version: string): IPackageVersion {
return {
version,
publishedAt: new Date(),
publishedBy: testUserId,
size: 1024,
checksum: `sha256-${crypto.randomUUID()}`,
checksumAlgorithm: 'sha256',
downloads: 0,
metadata: {},
};
}
async function createPackage(name: string, versions: string[] = ['1.0.0']): Promise<Package> {
const pkg = new Package();
pkg.id = Package.generateId('npm', testOrgId, name);
pkg.organizationId = testOrgId;
pkg.repositoryId = testRepoId;
pkg.protocol = 'npm';
pkg.name = name;
pkg.createdById = testUserId;
pkg.createdAt = new Date();
pkg.updatedAt = new Date();
for (const v of versions) {
pkg.addVersion(createVersion(v));
}
pkg.distTags['latest'] = versions[versions.length - 1];
await pkg.save();
return pkg;
}
describe('generateId', () => {
it('should generate correct format', () => {
const id = Package.generateId('npm', 'my-org', 'my-package');
assertEquals(id, 'npm:my-org:my-package');
});
});
describe('findById', () => {
it('should find package by ID', async () => {
const created = await createPackage('findable');
const found = await Package.findById(created.id);
assertExists(found);
assertEquals(found.name, 'findable');
});
it('should return null for non-existent ID', async () => {
const found = await Package.findById('npm:fake:package');
assertEquals(found, null);
});
});
describe('findByName', () => {
it('should find package by protocol, org, and name', async () => {
await createPackage('by-name');
const found = await Package.findByName('npm', testOrgId, 'by-name');
assertExists(found);
assertEquals(found.name, 'by-name');
});
});
describe('getOrgPackages', () => {
it('should return all packages in organization', async () => {
await createPackage('pkg1');
await createPackage('pkg2');
await createPackage('pkg3');
const packages = await Package.getOrgPackages(testOrgId);
assertEquals(packages.length, 3);
});
});
describe('search', () => {
it('should find packages by name', async () => {
await createPackage('search-me');
await createPackage('find-this');
await createPackage('other');
const results = await Package.search('search');
assertEquals(results.length, 1);
assertEquals(results[0].name, 'search-me');
});
it('should find packages by description', async () => {
const pkg = await createPackage('described');
pkg.description = 'A unique description for testing';
await pkg.save();
const results = await Package.search('unique description');
assertEquals(results.length, 1);
});
it('should filter by protocol', async () => {
await createPackage('npm-pkg');
const results = await Package.search('npm', { protocol: 'oci' });
assertEquals(results.length, 0);
});
it('should apply pagination', async () => {
await createPackage('page1');
await createPackage('page2');
await createPackage('page3');
const firstPage = await Package.search('page', { limit: 2, offset: 0 });
assertEquals(firstPage.length, 2);
const secondPage = await Package.search('page', { limit: 2, offset: 2 });
assertEquals(secondPage.length, 1);
});
});
describe('versions', () => {
it('should add version and update storage', async () => {
const pkg = await createPackage('versioned', []);
pkg.addVersion(createVersion('1.0.0'));
assertEquals(Object.keys(pkg.versions).length, 1);
assertEquals(pkg.storageBytes, 1024);
});
it('should get specific version', async () => {
const pkg = await createPackage('multi-version', ['1.0.0', '1.1.0', '2.0.0']);
const v1 = pkg.getVersion('1.0.0');
assertExists(v1);
assertEquals(v1.version, '1.0.0');
const v2 = pkg.getVersion('2.0.0');
assertExists(v2);
assertEquals(v2.version, '2.0.0');
});
it('should return undefined for non-existent version', async () => {
const pkg = await createPackage('single', ['1.0.0']);
const missing = pkg.getVersion('9.9.9');
assertEquals(missing, undefined);
});
});
describe('getLatestVersion', () => {
it('should return version from distTags.latest', async () => {
const pkg = await createPackage('tagged', ['1.0.0', '2.0.0']);
pkg.distTags['latest'] = '1.0.0'; // Set older version as latest
await pkg.save();
const latest = pkg.getLatestVersion();
assertExists(latest);
assertEquals(latest.version, '1.0.0');
});
it('should fallback to last version if no latest tag', async () => {
const pkg = await createPackage('untagged', ['1.0.0', '2.0.0']);
delete pkg.distTags['latest'];
const latest = pkg.getLatestVersion();
assertExists(latest);
assertEquals(latest.version, '2.0.0');
});
it('should return undefined for empty versions', async () => {
const pkg = await createPackage('empty', []);
delete pkg.distTags['latest'];
const latest = pkg.getLatestVersion();
assertEquals(latest, undefined);
});
});
describe('incrementDownloads', () => {
it('should increment total download count', async () => {
const pkg = await createPackage('downloads');
await pkg.incrementDownloads();
assertEquals(pkg.downloadCount, 1);
await pkg.incrementDownloads();
await pkg.incrementDownloads();
assertEquals(pkg.downloadCount, 3);
});
it('should increment version-specific downloads', async () => {
const pkg = await createPackage('version-downloads', ['1.0.0', '2.0.0']);
await pkg.incrementDownloads('1.0.0');
assertEquals(pkg.versions['1.0.0'].downloads, 1);
assertEquals(pkg.versions['2.0.0'].downloads, 0);
});
});
});