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:
285
test/unit/models/repository.test.ts
Normal file
285
test/unit/models/repository.test.ts
Normal file
@@ -0,0 +1,285 @@
|
||||
/**
|
||||
* 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');
|
||||
});
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user