/** * 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 }); }); });