- 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.
241 lines
7.0 KiB
TypeScript
241 lines
7.0 KiB
TypeScript
/**
|
|
* 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);
|
|
});
|
|
});
|
|
});
|