import { describe, it, expect, vi, beforeEach } from 'vitest' import * as repo from './company.repo' import * as service from './company.service' vi.mock('./company.repo') vi.mock('../../lib/storage', () => ({ uploadImage: vi.fn().mockResolvedValue('http://localhost:4000/storage/companies/comp_1/brand/logo.jpg'), })) const mockCompany = { id: 'comp_1', name: 'Test Rentals', slug: 'test-rentals', email: 'info@test.com', brand: null, subscription: null, _count: { vehicles: 5, customers: 10, reservations: 20 }, } const mockBrand = { id: 'brand_1', companyId: 'comp_1', displayName: 'Test Rentals', subdomain: 'test-rentals', logoUrl: null, heroImageUrl: null, customDomain: null, customDomainVerified: false, amanpayMerchantId: null, amanpaySecretKey: null, paypalEmail: null, } beforeEach(() => { vi.clearAllMocks() }) describe('company.service', () => { describe('getCompany', () => { it('returns company with brand and subscription', async () => { vi.mocked(repo.findCompany).mockResolvedValue(mockCompany as any) const result = await service.getCompany('comp_1') expect(result).toEqual(mockCompany) expect(repo.findCompany).toHaveBeenCalledWith('comp_1') }) }) describe('updateCompany', () => { it('updates company profile', async () => { vi.mocked(repo.updateCompany).mockResolvedValue({ ...mockCompany, name: 'Updated Rentals' } as any) const result = await service.updateCompany('comp_1', { name: 'Updated Rentals' }) expect(repo.updateCompany).toHaveBeenCalledWith('comp_1', { name: 'Updated Rentals' }) }) }) describe('uploadLogo', () => { it('uploads logo and upserts brand', async () => { vi.mocked(repo.upsertBrand).mockResolvedValue({ ...mockBrand, logoUrl: 'http://localhost:4000/storage/companies/comp_1/brand/logo.jpg' } as any) const result = await service.uploadLogo('comp_1', 'Test Rentals', 'test-rentals', Buffer.from('')) expect(repo.upsertBrand).toHaveBeenCalledWith( 'comp_1', expect.objectContaining({ logoUrl: 'http://localhost:4000/storage/companies/comp_1/brand/logo.jpg' }), expect.objectContaining({ logoUrl: 'http://localhost:4000/storage/companies/comp_1/brand/logo.jpg' }), ) }) }) describe('uploadHeroImage', () => { it('uploads hero image and upserts brand', async () => { vi.mocked(repo.upsertBrand).mockResolvedValue({ ...mockBrand, heroImageUrl: 'http://localhost:4000/storage/companies/comp_1/brand/logo.jpg' } as any) await service.uploadHeroImage('comp_1', 'Test Rentals', 'test-rentals', Buffer.from('')) expect(repo.upsertBrand).toHaveBeenCalledWith( 'comp_1', expect.objectContaining({ heroImageUrl: expect.any(String) }), expect.objectContaining({ heroImageUrl: expect.any(String) }), ) }) }) describe('checkSubdomainAvailability', () => { it('returns available=true when subdomain is free', async () => { vi.mocked(repo.findBrandBySubdomain).mockResolvedValue(null) const result = await service.checkSubdomainAvailability('my-rental', 'comp_1') expect(result.available).toBe(true) }) it('returns available=false when subdomain is taken', async () => { vi.mocked(repo.findBrandBySubdomain).mockResolvedValue(mockBrand as any) const result = await service.checkSubdomainAvailability('taken-rental', 'comp_1') expect(result.available).toBe(false) }) }) describe('setCustomDomain', () => { it('throws ConflictError when custom domain is already in use', async () => { vi.mocked(repo.findBrandByCustomDomain).mockResolvedValue(mockBrand as any) await expect(service.setCustomDomain('comp_1', 'Test Rentals', 'test-rentals', 'taken.com')).rejects.toThrow('This custom domain is already in use') }) it('sets custom domain when available', async () => { vi.mocked(repo.findBrandByCustomDomain).mockResolvedValue(null) vi.mocked(repo.upsertBrand).mockResolvedValue({ ...mockBrand, customDomain: 'my-rental.com' } as any) await service.setCustomDomain('comp_1', 'Test Rentals', 'test-rentals', 'My-Rental.com') expect(repo.upsertBrand).toHaveBeenCalledWith( 'comp_1', expect.objectContaining({ customDomain: 'my-rental.com' }), expect.objectContaining({ customDomain: 'my-rental.com' }), ) }) }) describe('updateInsurancePolicy', () => { it('throws NotFoundError when policy does not belong to company', async () => { vi.mocked(repo.updateInsurancePolicy).mockResolvedValue({ count: 0 } as any) await expect(service.updateInsurancePolicy('pol_1', 'comp_1', { name: 'CDW' })).rejects.toThrow('Insurance policy not found') }) }) describe('deletePricingRule', () => { it('throws NotFoundError when rule does not belong to company', async () => { vi.mocked(repo.deletePricingRule).mockResolvedValue({ count: 0 } as any) await expect(service.deletePricingRule('rule_1', 'comp_1')).rejects.toThrow('Pricing rule not found') }) }) })