- HERENCIA-SIMCO.md actualizado con directivas v3.7 y v3.8 - Actualizaciones de configuracion Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
249 lines
11 KiB
JavaScript
249 lines
11 KiB
JavaScript
"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
|