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,220 @@
/**
* Organization 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 } from '../../helpers/index.ts';
import { Organization } from '../../../ts/models/organization.ts';
describe('Organization Model', () => {
let testUserId: string;
beforeAll(async () => {
await setupTestDb();
});
afterAll(async () => {
await teardownTestDb();
});
beforeEach(async () => {
await cleanupTestDb();
const { user } = await createTestUser();
testUserId = user.id;
});
describe('createOrganization', () => {
it('should create an organization with valid data', async () => {
const org = await Organization.createOrganization({
name: 'test-org',
displayName: 'Test Organization',
description: 'A test organization',
createdById: testUserId,
});
assertExists(org.id);
assertEquals(org.name, 'test-org');
assertEquals(org.displayName, 'Test Organization');
assertEquals(org.description, 'A test organization');
assertEquals(org.createdById, testUserId);
assertEquals(org.isPublic, false);
assertEquals(org.memberCount, 0);
assertEquals(org.plan, 'free');
});
it('should allow dots in org name (domain-like)', async () => {
const org = await Organization.createOrganization({
name: 'push.rocks',
displayName: 'Push Rocks',
createdById: testUserId,
});
assertEquals(org.name, 'push.rocks');
});
it('should allow hyphens in org name', async () => {
const org = await Organization.createOrganization({
name: 'my-awesome-org',
displayName: 'My Awesome Org',
createdById: testUserId,
});
assertEquals(org.name, 'my-awesome-org');
});
it('should reject uppercase names (must be lowercase)', async () => {
await assertRejects(
async () => {
await Organization.createOrganization({
name: 'UPPERCASE',
displayName: 'Uppercase Org',
createdById: testUserId,
});
},
Error,
'lowercase alphanumeric'
);
});
it('should reject invalid names starting with dot', async () => {
await assertRejects(
async () => {
await Organization.createOrganization({
name: '.invalid',
displayName: 'Invalid',
createdById: testUserId,
});
},
Error,
'lowercase alphanumeric'
);
});
it('should reject invalid names ending with dot', async () => {
await assertRejects(
async () => {
await Organization.createOrganization({
name: 'invalid.',
displayName: 'Invalid',
createdById: testUserId,
});
},
Error,
'lowercase alphanumeric'
);
});
it('should reject names with special characters', async () => {
await assertRejects(
async () => {
await Organization.createOrganization({
name: 'invalid@org',
displayName: 'Invalid',
createdById: testUserId,
});
},
Error,
'lowercase alphanumeric'
);
});
it('should set default settings', async () => {
const org = await Organization.createOrganization({
name: 'defaults',
displayName: 'Defaults Test',
createdById: testUserId,
});
assertEquals(org.settings.requireMfa, false);
assertEquals(org.settings.allowPublicRepositories, true);
assertEquals(org.settings.defaultRepositoryVisibility, 'private');
assertEquals(org.settings.allowedProtocols.length, 7);
});
});
describe('findById', () => {
it('should find organization by ID', async () => {
const created = await Organization.createOrganization({
name: 'findable',
displayName: 'Findable Org',
createdById: testUserId,
});
const found = await Organization.findById(created.id);
assertExists(found);
assertEquals(found.id, created.id);
});
it('should return null for non-existent ID', async () => {
const found = await Organization.findById('non-existent-id');
assertEquals(found, null);
});
});
describe('findByName', () => {
it('should find organization by name (case-insensitive)', async () => {
await Organization.createOrganization({
name: 'byname',
displayName: 'By Name',
createdById: testUserId,
});
const found = await Organization.findByName('BYNAME');
assertExists(found);
assertEquals(found.name, 'byname');
});
});
describe('storage quota', () => {
it('should have default 5GB quota', async () => {
const org = await Organization.createOrganization({
name: 'quota-test',
displayName: 'Quota Test',
createdById: testUserId,
});
assertEquals(org.storageQuotaBytes, 5 * 1024 * 1024 * 1024);
assertEquals(org.usedStorageBytes, 0);
});
it('should check available storage', async () => {
const org = await Organization.createOrganization({
name: 'storage-check',
displayName: 'Storage Check',
createdById: testUserId,
});
assertEquals(org.hasStorageAvailable(1024), true);
assertEquals(org.hasStorageAvailable(6 * 1024 * 1024 * 1024), false);
});
it('should allow unlimited storage with -1 quota', async () => {
const org = await Organization.createOrganization({
name: 'unlimited',
displayName: 'Unlimited',
createdById: testUserId,
});
org.storageQuotaBytes = -1;
assertEquals(org.hasStorageAvailable(1000 * 1024 * 1024 * 1024), true);
});
it('should update storage usage', async () => {
const org = await Organization.createOrganization({
name: 'usage-test',
displayName: 'Usage Test',
createdById: testUserId,
});
await org.updateStorageUsage(1000);
assertEquals(org.usedStorageBytes, 1000);
await org.updateStorageUsage(500);
assertEquals(org.usedStorageBytes, 1500);
await org.updateStorageUsage(-2000);
assertEquals(org.usedStorageBytes, 0); // Should not go negative
});
});
});