- 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.
286 lines
7.7 KiB
TypeScript
286 lines
7.7 KiB
TypeScript
/**
|
|
* Repository model unit tests
|
|
*/
|
|
|
|
import { assertEquals, assertExists, assertRejects } from 'jsr:@std/assert';
|
|
import { describe, it, beforeAll, afterAll, beforeEach } from 'jsr:@std/testing/bdd';
|
|
import {
|
|
setupTestDb,
|
|
teardownTestDb,
|
|
cleanupTestDb,
|
|
createTestUser,
|
|
createOrgWithOwner,
|
|
} from '../../helpers/index.ts';
|
|
import { Repository } from '../../../ts/models/repository.ts';
|
|
|
|
describe('Repository Model', () => {
|
|
let testUserId: string;
|
|
let testOrgId: 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;
|
|
});
|
|
|
|
describe('createRepository', () => {
|
|
it('should create a repository with valid data', async () => {
|
|
const repo = await Repository.createRepository({
|
|
organizationId: testOrgId,
|
|
name: 'test-repo',
|
|
description: 'A test repository',
|
|
protocol: 'npm',
|
|
createdById: testUserId,
|
|
});
|
|
|
|
assertExists(repo.id);
|
|
assertEquals(repo.name, 'test-repo');
|
|
assertEquals(repo.organizationId, testOrgId);
|
|
assertEquals(repo.protocol, 'npm');
|
|
assertEquals(repo.visibility, 'private');
|
|
assertEquals(repo.downloadCount, 0);
|
|
assertEquals(repo.starCount, 0);
|
|
});
|
|
|
|
it('should allow dots and underscores in name', async () => {
|
|
const repo = await Repository.createRepository({
|
|
organizationId: testOrgId,
|
|
name: 'my.test_repo',
|
|
protocol: 'npm',
|
|
createdById: testUserId,
|
|
});
|
|
|
|
assertEquals(repo.name, 'my.test_repo');
|
|
});
|
|
|
|
it('should lowercase the name', async () => {
|
|
const repo = await Repository.createRepository({
|
|
organizationId: testOrgId,
|
|
name: 'UPPERCASE',
|
|
protocol: 'npm',
|
|
createdById: testUserId,
|
|
});
|
|
|
|
assertEquals(repo.name, 'uppercase');
|
|
});
|
|
|
|
it('should set correct storage namespace', async () => {
|
|
const repo = await Repository.createRepository({
|
|
organizationId: testOrgId,
|
|
name: 'packages',
|
|
protocol: 'npm',
|
|
createdById: testUserId,
|
|
});
|
|
|
|
assertEquals(repo.storageNamespace, `npm/${testOrgId}/packages`);
|
|
});
|
|
|
|
it('should reject duplicate name+protocol in same org', async () => {
|
|
await Repository.createRepository({
|
|
organizationId: testOrgId,
|
|
name: 'unique',
|
|
protocol: 'npm',
|
|
createdById: testUserId,
|
|
});
|
|
|
|
await assertRejects(
|
|
async () => {
|
|
await Repository.createRepository({
|
|
organizationId: testOrgId,
|
|
name: 'unique',
|
|
protocol: 'npm',
|
|
createdById: testUserId,
|
|
});
|
|
},
|
|
Error,
|
|
'already exists'
|
|
);
|
|
});
|
|
|
|
it('should allow same name with different protocol', async () => {
|
|
await Repository.createRepository({
|
|
organizationId: testOrgId,
|
|
name: 'packages',
|
|
protocol: 'npm',
|
|
createdById: testUserId,
|
|
});
|
|
|
|
const ociRepo = await Repository.createRepository({
|
|
organizationId: testOrgId,
|
|
name: 'packages',
|
|
protocol: 'oci',
|
|
createdById: testUserId,
|
|
});
|
|
|
|
assertEquals(ociRepo.name, 'packages');
|
|
assertEquals(ociRepo.protocol, 'oci');
|
|
});
|
|
|
|
it('should reject invalid names', async () => {
|
|
await assertRejects(
|
|
async () => {
|
|
await Repository.createRepository({
|
|
organizationId: testOrgId,
|
|
name: '-invalid',
|
|
protocol: 'npm',
|
|
createdById: testUserId,
|
|
});
|
|
},
|
|
Error,
|
|
'lowercase alphanumeric'
|
|
);
|
|
});
|
|
|
|
it('should set visibility when provided', async () => {
|
|
const repo = await Repository.createRepository({
|
|
organizationId: testOrgId,
|
|
name: 'public-repo',
|
|
protocol: 'npm',
|
|
visibility: 'public',
|
|
createdById: testUserId,
|
|
});
|
|
|
|
assertEquals(repo.visibility, 'public');
|
|
});
|
|
});
|
|
|
|
describe('findByName', () => {
|
|
it('should find repository by org, name, and protocol', async () => {
|
|
await Repository.createRepository({
|
|
organizationId: testOrgId,
|
|
name: 'findable',
|
|
protocol: 'npm',
|
|
createdById: testUserId,
|
|
});
|
|
|
|
const found = await Repository.findByName(testOrgId, 'FINDABLE', 'npm');
|
|
assertExists(found);
|
|
assertEquals(found.name, 'findable');
|
|
});
|
|
|
|
it('should return null for wrong protocol', async () => {
|
|
await Repository.createRepository({
|
|
organizationId: testOrgId,
|
|
name: 'npm-only',
|
|
protocol: 'npm',
|
|
createdById: testUserId,
|
|
});
|
|
|
|
const found = await Repository.findByName(testOrgId, 'npm-only', 'oci');
|
|
assertEquals(found, null);
|
|
});
|
|
});
|
|
|
|
describe('getOrgRepositories', () => {
|
|
it('should return all org repositories', async () => {
|
|
await Repository.createRepository({
|
|
organizationId: testOrgId,
|
|
name: 'repo1',
|
|
protocol: 'npm',
|
|
createdById: testUserId,
|
|
});
|
|
await Repository.createRepository({
|
|
organizationId: testOrgId,
|
|
name: 'repo2',
|
|
protocol: 'oci',
|
|
createdById: testUserId,
|
|
});
|
|
await Repository.createRepository({
|
|
organizationId: testOrgId,
|
|
name: 'repo3',
|
|
protocol: 'maven',
|
|
createdById: testUserId,
|
|
});
|
|
|
|
const repos = await Repository.getOrgRepositories(testOrgId);
|
|
assertEquals(repos.length, 3);
|
|
});
|
|
});
|
|
|
|
describe('getPublicRepositories', () => {
|
|
it('should return only public repositories', async () => {
|
|
await Repository.createRepository({
|
|
organizationId: testOrgId,
|
|
name: 'public1',
|
|
protocol: 'npm',
|
|
visibility: 'public',
|
|
createdById: testUserId,
|
|
});
|
|
await Repository.createRepository({
|
|
organizationId: testOrgId,
|
|
name: 'private1',
|
|
protocol: 'npm',
|
|
visibility: 'private',
|
|
createdById: testUserId,
|
|
});
|
|
|
|
const repos = await Repository.getPublicRepositories();
|
|
assertEquals(repos.length, 1);
|
|
assertEquals(repos[0].name, 'public1');
|
|
});
|
|
|
|
it('should filter by protocol when provided', async () => {
|
|
await Repository.createRepository({
|
|
organizationId: testOrgId,
|
|
name: 'npm-public',
|
|
protocol: 'npm',
|
|
visibility: 'public',
|
|
createdById: testUserId,
|
|
});
|
|
await Repository.createRepository({
|
|
organizationId: testOrgId,
|
|
name: 'oci-public',
|
|
protocol: 'oci',
|
|
visibility: 'public',
|
|
createdById: testUserId,
|
|
});
|
|
|
|
const repos = await Repository.getPublicRepositories('npm');
|
|
assertEquals(repos.length, 1);
|
|
assertEquals(repos[0].protocol, 'npm');
|
|
});
|
|
});
|
|
|
|
describe('incrementDownloads', () => {
|
|
it('should increment download count', async () => {
|
|
const repo = await Repository.createRepository({
|
|
organizationId: testOrgId,
|
|
name: 'downloads',
|
|
protocol: 'npm',
|
|
createdById: testUserId,
|
|
});
|
|
|
|
await repo.incrementDownloads();
|
|
assertEquals(repo.downloadCount, 1);
|
|
|
|
await repo.incrementDownloads();
|
|
await repo.incrementDownloads();
|
|
assertEquals(repo.downloadCount, 3);
|
|
});
|
|
});
|
|
|
|
describe('getFullPath', () => {
|
|
it('should return org/repo path', async () => {
|
|
const repo = await Repository.createRepository({
|
|
organizationId: testOrgId,
|
|
name: 'my-package',
|
|
protocol: 'npm',
|
|
createdById: testUserId,
|
|
});
|
|
|
|
const path = repo.getFullPath('my-org');
|
|
assertEquals(path, 'my-org/my-package');
|
|
});
|
|
});
|
|
});
|