"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const testing_1 = require("@nestjs/testing"); const typeorm_1 = require("@nestjs/typeorm"); const common_1 = require("@nestjs/common"); const tenants_service_1 = require("../tenants.service"); const tenant_entity_1 = require("../entities/tenant.entity"); describe('TenantsService', () => { let service; let tenantRepository; const mockTenant = { id: 'tenant-123', name: 'Test Company', slug: 'test-company', domain: 'test.example.com', logo_url: 'https://example.com/logo.png', status: 'active', plan_id: 'plan-123', trial_ends_at: new Date('2026-02-01'), settings: { theme: 'dark' }, metadata: { industry: 'tech' }, created_at: new Date('2026-01-01'), updated_at: new Date('2026-01-01'), }; beforeEach(async () => { const module = await testing_1.Test.createTestingModule({ providers: [ tenants_service_1.TenantsService, { provide: (0, typeorm_1.getRepositoryToken)(tenant_entity_1.Tenant), useValue: { findOne: jest.fn(), find: jest.fn(), save: jest.fn(), create: jest.fn(), update: jest.fn(), delete: jest.fn(), }, }, ], }).compile(); service = module.get(tenants_service_1.TenantsService); tenantRepository = module.get((0, typeorm_1.getRepositoryToken)(tenant_entity_1.Tenant)); }); afterEach(() => { jest.clearAllMocks(); }); describe('findOne', () => { it('should return a tenant by id', async () => { tenantRepository.findOne.mockResolvedValue(mockTenant); const result = await service.findOne('tenant-123'); expect(result).toEqual(mockTenant); expect(tenantRepository.findOne).toHaveBeenCalledWith({ where: { id: 'tenant-123' }, }); }); it('should throw NotFoundException if tenant not found', async () => { tenantRepository.findOne.mockResolvedValue(null); await expect(service.findOne('non-existent')).rejects.toThrow(common_1.NotFoundException); await expect(service.findOne('non-existent')).rejects.toThrow('Tenant no encontrado'); }); it('should handle repository errors', async () => { tenantRepository.findOne.mockRejectedValue(new Error('DB Error')); await expect(service.findOne('tenant-123')).rejects.toThrow('DB Error'); }); }); describe('findBySlug', () => { it('should return a tenant by slug', async () => { tenantRepository.findOne.mockResolvedValue(mockTenant); const result = await service.findBySlug('test-company'); expect(result).toEqual(mockTenant); expect(tenantRepository.findOne).toHaveBeenCalledWith({ where: { slug: 'test-company' }, }); }); it('should return null if tenant not found by slug', async () => { tenantRepository.findOne.mockResolvedValue(null); const result = await service.findBySlug('non-existent'); expect(result).toBeNull(); }); it('should handle slugs with special characters', async () => { tenantRepository.findOne.mockResolvedValue(mockTenant); await service.findBySlug('company-name-123'); expect(tenantRepository.findOne).toHaveBeenCalledWith({ where: { slug: 'company-name-123' }, }); }); }); describe('create', () => { const createDto = { name: 'New Company', slug: 'new-company', domain: 'new.example.com', logo_url: 'https://example.com/new-logo.png', settings: { timezone: 'America/Mexico_City', industry: 'Technology', }, }; it('should create a new tenant successfully', async () => { const createdTenant = { ...mockTenant, id: 'new-tenant-id', name: createDto.name, slug: createDto.slug, domain: createDto.domain || null, logo_url: createDto.logo_url || null, status: 'trial', settings: createDto.settings || {}, }; tenantRepository.findOne.mockResolvedValue(null); tenantRepository.create.mockReturnValue(createdTenant); tenantRepository.save.mockResolvedValue(createdTenant); const result = await service.create(createDto); expect(result).toEqual(createdTenant); expect(tenantRepository.findOne).toHaveBeenCalledWith({ where: { slug: createDto.slug }, }); expect(tenantRepository.create).toHaveBeenCalledWith(expect.objectContaining({ name: createDto.name, slug: createDto.slug, domain: createDto.domain, logo_url: createDto.logo_url, status: 'trial', settings: createDto.settings, })); expect(tenantRepository.save).toHaveBeenCalled(); }); it('should throw ConflictException if slug already exists', async () => { tenantRepository.findOne.mockResolvedValue(mockTenant); await expect(service.create(createDto)).rejects.toThrow(common_1.ConflictException); await expect(service.create(createDto)).rejects.toThrow('Ya existe un tenant con este slug'); }); it('should create tenant with empty settings if not provided', async () => { const dtoWithoutSettings = { name: 'Minimal Company', slug: 'minimal-company', }; const createdTenant = { ...mockTenant, name: dtoWithoutSettings.name, slug: dtoWithoutSettings.slug, domain: null, logo_url: null, settings: {}, status: 'trial', }; tenantRepository.findOne.mockResolvedValue(null); tenantRepository.create.mockReturnValue(createdTenant); tenantRepository.save.mockResolvedValue(createdTenant); const result = await service.create(dtoWithoutSettings); expect(result.settings).toEqual({}); expect(result.domain).toBeNull(); expect(result.logo_url).toBeNull(); }); it('should set trial_ends_at to 14 days from now', async () => { const dtoMinimal = { name: 'Trial Company', slug: 'trial-company', }; const createdTenant = { ...mockTenant, name: dtoMinimal.name, slug: dtoMinimal.slug, status: 'trial', trial_ends_at: new Date(Date.now() + 14 * 24 * 60 * 60 * 1000), }; tenantRepository.findOne.mockResolvedValue(null); tenantRepository.create.mockReturnValue(createdTenant); tenantRepository.save.mockResolvedValue(createdTenant); await service.create(dtoMinimal); expect(tenantRepository.create).toHaveBeenCalledWith(expect.objectContaining({ status: 'trial', trial_ends_at: expect.any(Date), })); }); }); describe('update', () => { const updateDto = { name: 'Updated Company', logo_url: 'https://example.com/updated-logo.png', settings: { timezone: 'America/New_York', }, }; it('should update tenant successfully', async () => { const updatedTenant = { ...mockTenant, name: updateDto.name, logo_url: updateDto.logo_url, settings: { ...mockTenant.settings, ...updateDto.settings }, }; tenantRepository.findOne.mockResolvedValue(mockTenant); tenantRepository.save.mockResolvedValue(updatedTenant); const result = await service.update('tenant-123', updateDto); expect(result.name).toBe(updateDto.name); expect(result.logo_url).toBe(updateDto.logo_url); expect(result.settings).toEqual(expect.objectContaining({ timezone: 'America/New_York' })); expect(tenantRepository.save).toHaveBeenCalled(); }); it('should throw NotFoundException if tenant not found', async () => { tenantRepository.findOne.mockResolvedValue(null); await expect(service.update('non-existent', updateDto)).rejects.toThrow(common_1.NotFoundException); }); it('should only update provided fields', async () => { const partialUpdate = { name: 'Only Name Updated', }; tenantRepository.findOne.mockResolvedValue({ ...mockTenant }); tenantRepository.save.mockImplementation((tenant) => Promise.resolve(tenant)); const result = await service.update('tenant-123', partialUpdate); expect(result.name).toBe('Only Name Updated'); expect(result.logo_url).toBe(mockTenant.logo_url); expect(result.settings).toEqual(mockTenant.settings); }); it('should merge settings with existing settings', async () => { const settingsUpdate = { settings: { industry: 'Healthcare', }, }; const tenantWithSettings = { ...mockTenant, settings: { theme: 'dark', timezone: 'America/Mexico_City' }, }; tenantRepository.findOne.mockResolvedValue({ ...tenantWithSettings }); tenantRepository.save.mockImplementation((tenant) => Promise.resolve(tenant)); const result = await service.update('tenant-123', settingsUpdate); expect(result.settings).toEqual({ theme: 'dark', timezone: 'America/Mexico_City', industry: 'Healthcare', }); }); }); describe('slugExists', () => { it('should return true if slug exists', async () => { tenantRepository.findOne.mockResolvedValue(mockTenant); const result = await service.slugExists('test-company'); expect(result).toBe(true); }); it('should return false if slug does not exist', async () => { tenantRepository.findOne.mockResolvedValue(null); const result = await service.slugExists('non-existent'); expect(result).toBe(false); }); }); }); //# sourceMappingURL=tenants.service.spec.js.map