feat: adiciona validações e testes para métodos do data-consult service
- Adiciona validações para stores(), sellers(), billings(), customers(), getAllProducts(), getAllCarriers() e getRegions() - Valida se dados retornados têm propriedades necessárias - Valida se resultado do repository é array válido - Filtra dados incompletos ou com propriedades inválidas - Refatora testes criando helper para reduzir duplicação - Adiciona testes que expõem problemas e validam correções - Melhora tratamento de erros com logging adequado
This commit is contained in:
@@ -0,0 +1,82 @@
|
|||||||
|
import { Test, TestingModule } from '@nestjs/testing';
|
||||||
|
import { DataConsultService } from '../data-consult.service';
|
||||||
|
import { DataConsultRepository } from '../data-consult.repository';
|
||||||
|
import { ILogger } from '../../Log/ILogger';
|
||||||
|
import { IRedisClient } from '../../core/configs/cache/IRedisClient';
|
||||||
|
import { RedisClientToken } from '../../core/configs/cache/redis-client.adapter.provider';
|
||||||
|
import { DataSource } from 'typeorm';
|
||||||
|
import { DATA_SOURCE } from '../../core/constants';
|
||||||
|
|
||||||
|
export const createMockRepository = (methods: Partial<DataConsultRepository> = {}) => ({
|
||||||
|
findStores: jest.fn(),
|
||||||
|
findSellers: jest.fn(),
|
||||||
|
findBillings: jest.fn(),
|
||||||
|
findCustomers: jest.fn(),
|
||||||
|
findAllProducts: jest.fn(),
|
||||||
|
findAllCarriers: jest.fn(),
|
||||||
|
findRegions: jest.fn(),
|
||||||
|
...methods,
|
||||||
|
} as any);
|
||||||
|
|
||||||
|
export const createMockLogger = () => ({
|
||||||
|
log: jest.fn(),
|
||||||
|
error: jest.fn(),
|
||||||
|
warn: jest.fn(),
|
||||||
|
debug: jest.fn(),
|
||||||
|
} as any);
|
||||||
|
|
||||||
|
export const createMockRedisClient = () => ({
|
||||||
|
get: jest.fn().mockResolvedValue(null),
|
||||||
|
set: jest.fn().mockResolvedValue(undefined),
|
||||||
|
} as any);
|
||||||
|
|
||||||
|
export interface DataConsultServiceTestContext {
|
||||||
|
service: DataConsultService;
|
||||||
|
mockRepository: jest.Mocked<DataConsultRepository>;
|
||||||
|
mockLogger: jest.Mocked<ILogger>;
|
||||||
|
mockRedisClient: jest.Mocked<IRedisClient>;
|
||||||
|
mockDataSource: jest.Mocked<DataSource>;
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function createDataConsultServiceTestModule(
|
||||||
|
repositoryMethods: Partial<DataConsultRepository> = {},
|
||||||
|
redisClientMethods: Partial<IRedisClient> = {}
|
||||||
|
): Promise<DataConsultServiceTestContext> {
|
||||||
|
const mockRepository = createMockRepository(repositoryMethods);
|
||||||
|
const mockLogger = createMockLogger();
|
||||||
|
const mockRedisClient = { ...createMockRedisClient(), ...redisClientMethods } as any;
|
||||||
|
const mockDataSource = {} as any;
|
||||||
|
|
||||||
|
const module: TestingModule = await Test.createTestingModule({
|
||||||
|
providers: [
|
||||||
|
DataConsultService,
|
||||||
|
{
|
||||||
|
provide: DataConsultRepository,
|
||||||
|
useValue: mockRepository,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
provide: RedisClientToken,
|
||||||
|
useValue: mockRedisClient,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
provide: 'LoggerService',
|
||||||
|
useValue: mockLogger,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
provide: DATA_SOURCE,
|
||||||
|
useValue: mockDataSource,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}).compile();
|
||||||
|
|
||||||
|
const service = module.get<DataConsultService>(DataConsultService);
|
||||||
|
|
||||||
|
return {
|
||||||
|
service,
|
||||||
|
mockRepository,
|
||||||
|
mockLogger,
|
||||||
|
mockRedisClient,
|
||||||
|
mockDataSource,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
@@ -1,98 +1,28 @@
|
|||||||
import { Test, TestingModule } from '@nestjs/testing';
|
import { HttpException } from '@nestjs/common';
|
||||||
import { HttpException, HttpStatus } from '@nestjs/common';
|
import { createDataConsultServiceTestModule } from './data-consult.service.spec.helper';
|
||||||
import { DataConsultService } from '../data-consult.service';
|
|
||||||
import { DataConsultRepository } from '../data-consult.repository';
|
|
||||||
import { StoreDto } from '../dto/store.dto';
|
|
||||||
import { SellerDto } from '../dto/seller.dto';
|
|
||||||
import { ILogger } from '../../Log/ILogger';
|
|
||||||
import { IRedisClient } from '../../core/configs/cache/IRedisClient';
|
|
||||||
import { RedisClientToken } from '../../core/configs/cache/redis-client.adapter.provider';
|
|
||||||
import { DataSource } from 'typeorm';
|
|
||||||
import { DATA_SOURCE } from '../../core/constants';
|
|
||||||
|
|
||||||
describe('DataConsultService - stores', () => {
|
describe('DataConsultService', () => {
|
||||||
let service: DataConsultService;
|
describe('stores', () => {
|
||||||
let mockRepository: jest.Mocked<DataConsultRepository>;
|
let context: Awaited<ReturnType<typeof createDataConsultServiceTestModule>>;
|
||||||
let mockLogger: jest.Mocked<ILogger>;
|
|
||||||
let mockRedisClient: jest.Mocked<IRedisClient>;
|
|
||||||
let mockDataSource: jest.Mocked<DataSource>;
|
|
||||||
|
|
||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
mockRepository = {
|
context = await createDataConsultServiceTestModule();
|
||||||
findStores: jest.fn(),
|
|
||||||
findSellers: jest.fn(),
|
|
||||||
} as any;
|
|
||||||
|
|
||||||
mockLogger = {
|
|
||||||
log: jest.fn(),
|
|
||||||
error: jest.fn(),
|
|
||||||
warn: jest.fn(),
|
|
||||||
debug: jest.fn(),
|
|
||||||
} as any;
|
|
||||||
|
|
||||||
mockRedisClient = {
|
|
||||||
get: jest.fn(),
|
|
||||||
set: jest.fn(),
|
|
||||||
} as any;
|
|
||||||
|
|
||||||
mockDataSource = {} as any;
|
|
||||||
|
|
||||||
const module: TestingModule = await Test.createTestingModule({
|
|
||||||
providers: [
|
|
||||||
DataConsultService,
|
|
||||||
{
|
|
||||||
provide: DataConsultRepository,
|
|
||||||
useValue: mockRepository,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
provide: RedisClientToken,
|
|
||||||
useValue: mockRedisClient,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
provide: 'LoggerService',
|
|
||||||
useValue: mockLogger,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
provide: DATA_SOURCE,
|
|
||||||
useValue: mockDataSource,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
}).compile();
|
|
||||||
|
|
||||||
service = module.get<DataConsultService>(DataConsultService);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
afterEach(() => {
|
afterEach(() => {
|
||||||
jest.clearAllMocks();
|
jest.clearAllMocks();
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('stores - Tests that expose problems', () => {
|
describe('Tests that expose problems', () => {
|
||||||
/**
|
|
||||||
* NOTA: Estes testes identificam problemas no método stores.
|
|
||||||
*
|
|
||||||
* PROBLEMAS IDENTIFICADOS:
|
|
||||||
* 1. Não valida se os dados retornados têm todas as propriedades necessárias
|
|
||||||
* 2. Não valida se o resultado do repository é um array válido
|
|
||||||
* 3. Permite criar StoreDto com propriedades undefined
|
|
||||||
* 4. Não trata o caso onde o repository retorna dados incompletos
|
|
||||||
*/
|
|
||||||
|
|
||||||
it('should validate that all stores have required properties (id, name, store)', async () => {
|
it('should validate that all stores have required properties (id, name, store)', async () => {
|
||||||
/**
|
context.mockRepository.findStores.mockResolvedValue([
|
||||||
* Cenário: Repository retorna dados incompletos (faltando propriedades).
|
{ id: '001', name: 'Loja 1' },
|
||||||
* Problema: StoreDto é criado com propriedades undefined.
|
{ id: '002', store: '002 - Loja 2' },
|
||||||
* Solução esperada: Validar dados antes de criar StoreDto ou lançar exceção.
|
{ id: '003', name: 'Loja 3', store: '003 - Loja 3' },
|
||||||
*/
|
|
||||||
mockRepository.findStores.mockResolvedValue([
|
|
||||||
{ id: '001', name: 'Loja 1' }, // falta propriedade 'store'
|
|
||||||
{ id: '002', store: '002 - Loja 2' }, // falta propriedade 'name'
|
|
||||||
{ id: '003', name: 'Loja 3', store: '003 - Loja 3' }, // completo
|
|
||||||
] as any);
|
] as any);
|
||||||
|
|
||||||
const result = await service.stores();
|
const result = await context.service.stores();
|
||||||
|
|
||||||
// Este teste falha porque o método atual não valida as propriedades
|
|
||||||
// e permite criar StoreDto com propriedades undefined
|
|
||||||
result.forEach(store => {
|
result.forEach(store => {
|
||||||
expect(store.id).toBeDefined();
|
expect(store.id).toBeDefined();
|
||||||
expect(store.name).toBeDefined();
|
expect(store.name).toBeDefined();
|
||||||
@@ -101,45 +31,24 @@ describe('DataConsultService - stores', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should handle null or undefined result from repository', async () => {
|
it('should handle null or undefined result from repository', async () => {
|
||||||
/**
|
context.mockRepository.findStores.mockResolvedValue(null as any);
|
||||||
* Cenário: Repository retorna null ou undefined.
|
await expect(context.service.stores()).rejects.toThrow();
|
||||||
* Problema: Método tenta fazer map em null/undefined causando erro.
|
|
||||||
* Solução esperada: Validar se o resultado é um array antes de fazer map.
|
|
||||||
*/
|
|
||||||
mockRepository.findStores.mockResolvedValue(null as any);
|
|
||||||
|
|
||||||
await expect(service.stores()).rejects.toThrow();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should validate that repository result is an array', async () => {
|
it('should validate that repository result is an array', async () => {
|
||||||
/**
|
context.mockRepository.findStores.mockResolvedValue({ id: '001', name: 'Loja 1' } as any);
|
||||||
* Cenário: Repository retorna um objeto em vez de array.
|
const result = await context.service.stores();
|
||||||
* Problema: Método tenta fazer map em objeto causando comportamento inesperado.
|
|
||||||
* Solução esperada: Validar se o resultado é um array.
|
|
||||||
*/
|
|
||||||
mockRepository.findStores.mockResolvedValue({ id: '001', name: 'Loja 1' } as any);
|
|
||||||
|
|
||||||
const result = await service.stores();
|
|
||||||
|
|
||||||
// Este teste falha porque o método não valida se o resultado é um array
|
|
||||||
expect(Array.isArray(result)).toBe(true);
|
expect(Array.isArray(result)).toBe(true);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should validate that required properties are not empty strings', async () => {
|
it('should validate that required properties are not empty strings', async () => {
|
||||||
/**
|
context.mockRepository.findStores.mockResolvedValue([
|
||||||
* Cenário: Repository retorna dados com propriedades vazias.
|
{ id: '', name: 'Loja 1', store: '001 - Loja 1' },
|
||||||
* Problema: StoreDto é criado com strings vazias, o que pode causar problemas.
|
{ id: '002', name: '', store: '002 - Loja 2' },
|
||||||
* Solução esperada: Validar se as propriedades são strings não vazias.
|
{ id: '003', name: 'Loja 3', store: '' },
|
||||||
*/
|
|
||||||
mockRepository.findStores.mockResolvedValue([
|
|
||||||
{ id: '', name: 'Loja 1', store: '001 - Loja 1' }, // id vazio
|
|
||||||
{ id: '002', name: '', store: '002 - Loja 2' }, // name vazio
|
|
||||||
{ id: '003', name: 'Loja 3', store: '' }, // store vazio
|
|
||||||
] as any);
|
] as any);
|
||||||
|
|
||||||
const result = await service.stores();
|
const result = await context.service.stores();
|
||||||
|
|
||||||
// Este teste falha porque o método não valida se as propriedades são não vazias
|
|
||||||
result.forEach(store => {
|
result.forEach(store => {
|
||||||
expect(store.id).not.toBe('');
|
expect(store.id).not.toBe('');
|
||||||
expect(store.name).not.toBe('');
|
expect(store.name).not.toBe('');
|
||||||
@@ -148,103 +57,34 @@ describe('DataConsultService - stores', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should log error when repository throws exception', async () => {
|
it('should log error when repository throws exception', async () => {
|
||||||
/**
|
|
||||||
* Cenário: Repository lança uma exceção.
|
|
||||||
* Problema: Método deve logar o erro antes de lançar HttpException.
|
|
||||||
* Solução esperada: Logger.error deve ser chamado com a mensagem correta.
|
|
||||||
*/
|
|
||||||
const repositoryError = new Error('Database connection failed');
|
const repositoryError = new Error('Database connection failed');
|
||||||
mockRepository.findStores.mockRejectedValue(repositoryError);
|
context.mockRepository.findStores.mockRejectedValue(repositoryError);
|
||||||
|
await expect(context.service.stores()).rejects.toThrow(HttpException);
|
||||||
await expect(service.stores()).rejects.toThrow(HttpException);
|
expect(context.mockLogger.error).toHaveBeenCalledWith('Erro ao buscar lojas', repositoryError);
|
||||||
|
|
||||||
expect(mockLogger.error).toHaveBeenCalledWith('Erro ao buscar lojas', repositoryError);
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('DataConsultService - sellers', () => {
|
describe('sellers', () => {
|
||||||
let service: DataConsultService;
|
let context: Awaited<ReturnType<typeof createDataConsultServiceTestModule>>;
|
||||||
let mockRepository: jest.Mocked<DataConsultRepository>;
|
|
||||||
let mockLogger: jest.Mocked<ILogger>;
|
|
||||||
let mockRedisClient: jest.Mocked<IRedisClient>;
|
|
||||||
let mockDataSource: jest.Mocked<DataSource>;
|
|
||||||
|
|
||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
mockRepository = {
|
context = await createDataConsultServiceTestModule();
|
||||||
findSellers: jest.fn(),
|
|
||||||
} as any;
|
|
||||||
|
|
||||||
mockLogger = {
|
|
||||||
log: jest.fn(),
|
|
||||||
error: jest.fn(),
|
|
||||||
warn: jest.fn(),
|
|
||||||
debug: jest.fn(),
|
|
||||||
} as any;
|
|
||||||
|
|
||||||
mockRedisClient = {
|
|
||||||
get: jest.fn().mockResolvedValue(null),
|
|
||||||
set: jest.fn().mockResolvedValue(undefined),
|
|
||||||
} as any;
|
|
||||||
|
|
||||||
mockDataSource = {} as any;
|
|
||||||
|
|
||||||
const module: TestingModule = await Test.createTestingModule({
|
|
||||||
providers: [
|
|
||||||
DataConsultService,
|
|
||||||
{
|
|
||||||
provide: DataConsultRepository,
|
|
||||||
useValue: mockRepository,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
provide: RedisClientToken,
|
|
||||||
useValue: mockRedisClient,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
provide: 'LoggerService',
|
|
||||||
useValue: mockLogger,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
provide: DATA_SOURCE,
|
|
||||||
useValue: mockDataSource,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
}).compile();
|
|
||||||
|
|
||||||
service = module.get<DataConsultService>(DataConsultService);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
afterEach(() => {
|
afterEach(() => {
|
||||||
jest.clearAllMocks();
|
jest.clearAllMocks();
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('sellers - Tests that expose problems', () => {
|
describe('Tests that expose problems', () => {
|
||||||
/**
|
|
||||||
* NOTA: Estes testes identificam problemas no método sellers.
|
|
||||||
*
|
|
||||||
* PROBLEMAS IDENTIFICADOS:
|
|
||||||
* 1. Não valida se os dados retornados têm todas as propriedades necessárias
|
|
||||||
* 2. Não valida se o resultado do repository é um array válido
|
|
||||||
* 3. Permite criar SellerDto com propriedades undefined
|
|
||||||
* 4. Não trata o caso onde o repository retorna dados incompletos
|
|
||||||
*/
|
|
||||||
|
|
||||||
it('should validate that all sellers have required properties (id, name)', async () => {
|
it('should validate that all sellers have required properties (id, name)', async () => {
|
||||||
/**
|
context.mockRepository.findSellers.mockResolvedValue([
|
||||||
* Cenário: Repository retorna dados incompletos (faltando propriedades).
|
{ id: '001' },
|
||||||
* Problema: SellerDto é criado com propriedades undefined.
|
{ name: 'Vendedor 2' },
|
||||||
* Solução esperada: Validar dados antes de criar SellerDto ou lançar exceção.
|
{ id: '003', name: 'Vendedor 3' },
|
||||||
*/
|
|
||||||
mockRepository.findSellers.mockResolvedValue([
|
|
||||||
{ id: '001' }, // falta propriedade 'name'
|
|
||||||
{ name: 'Vendedor 2' }, // falta propriedade 'id'
|
|
||||||
{ id: '003', name: 'Vendedor 3' }, // completo
|
|
||||||
] as any);
|
] as any);
|
||||||
|
|
||||||
const result = await service.sellers();
|
const result = await context.service.sellers();
|
||||||
|
|
||||||
// Este teste falha porque o método atual não valida as propriedades
|
|
||||||
// e permite criar SellerDto com propriedades undefined
|
|
||||||
result.forEach(seller => {
|
result.forEach(seller => {
|
||||||
expect(seller.id).toBeDefined();
|
expect(seller.id).toBeDefined();
|
||||||
expect(seller.name).toBeDefined();
|
expect(seller.name).toBeDefined();
|
||||||
@@ -252,44 +92,23 @@ describe('DataConsultService - sellers', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should handle null or undefined result from repository', async () => {
|
it('should handle null or undefined result from repository', async () => {
|
||||||
/**
|
context.mockRepository.findSellers.mockResolvedValue(null as any);
|
||||||
* Cenário: Repository retorna null ou undefined.
|
await expect(context.service.sellers()).rejects.toThrow();
|
||||||
* Problema: Método tenta fazer map em null/undefined causando erro.
|
|
||||||
* Solução esperada: Validar se o resultado é um array antes de fazer map.
|
|
||||||
*/
|
|
||||||
mockRepository.findSellers.mockResolvedValue(null as any);
|
|
||||||
|
|
||||||
await expect(service.sellers()).rejects.toThrow();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should validate that repository result is an array', async () => {
|
it('should validate that repository result is an array', async () => {
|
||||||
/**
|
context.mockRepository.findSellers.mockResolvedValue({ id: '001', name: 'Vendedor 1' } as any);
|
||||||
* Cenário: Repository retorna um objeto em vez de array.
|
const result = await context.service.sellers();
|
||||||
* Problema: Método tenta fazer map em objeto causando comportamento inesperado.
|
|
||||||
* Solução esperada: Validar se o resultado é um array.
|
|
||||||
*/
|
|
||||||
mockRepository.findSellers.mockResolvedValue({ id: '001', name: 'Vendedor 1' } as any);
|
|
||||||
|
|
||||||
const result = await service.sellers();
|
|
||||||
|
|
||||||
// Este teste falha porque o método não valida se o resultado é um array
|
|
||||||
expect(Array.isArray(result)).toBe(true);
|
expect(Array.isArray(result)).toBe(true);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should validate that required properties are not empty strings', async () => {
|
it('should validate that required properties are not empty strings', async () => {
|
||||||
/**
|
context.mockRepository.findSellers.mockResolvedValue([
|
||||||
* Cenário: Repository retorna dados com propriedades vazias.
|
{ id: '', name: 'Vendedor 1' },
|
||||||
* Problema: SellerDto é criado com strings vazias, o que pode causar problemas.
|
{ id: '002', name: '' },
|
||||||
* Solução esperada: Validar se as propriedades são strings não vazias.
|
|
||||||
*/
|
|
||||||
mockRepository.findSellers.mockResolvedValue([
|
|
||||||
{ id: '', name: 'Vendedor 1' }, // id vazio
|
|
||||||
{ id: '002', name: '' }, // name vazio
|
|
||||||
] as any);
|
] as any);
|
||||||
|
|
||||||
const result = await service.sellers();
|
const result = await context.service.sellers();
|
||||||
|
|
||||||
// Este teste falha porque o método não valida se as propriedades são não vazias
|
|
||||||
result.forEach(seller => {
|
result.forEach(seller => {
|
||||||
expect(seller.id).not.toBe('');
|
expect(seller.id).not.toBe('');
|
||||||
expect(seller.name).not.toBe('');
|
expect(seller.name).not.toBe('');
|
||||||
@@ -297,18 +116,321 @@ describe('DataConsultService - sellers', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should log error when repository throws exception', async () => {
|
it('should log error when repository throws exception', async () => {
|
||||||
/**
|
|
||||||
* Cenário: Repository lança uma exceção.
|
|
||||||
* Problema: Método deve logar o erro antes de lançar HttpException.
|
|
||||||
* Solução esperada: Logger.error deve ser chamado com a mensagem correta.
|
|
||||||
*/
|
|
||||||
const repositoryError = new Error('Database connection failed');
|
const repositoryError = new Error('Database connection failed');
|
||||||
mockRepository.findSellers.mockRejectedValue(repositoryError);
|
context.mockRepository.findSellers.mockRejectedValue(repositoryError);
|
||||||
|
await expect(context.service.sellers()).rejects.toThrow(HttpException);
|
||||||
await expect(service.sellers()).rejects.toThrow(HttpException);
|
expect(context.mockLogger.error).toHaveBeenCalledWith('Erro ao buscar vendedores', repositoryError);
|
||||||
|
|
||||||
expect(mockLogger.error).toHaveBeenCalledWith('Erro ao buscar vendedores', repositoryError);
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('billings', () => {
|
||||||
|
let context: Awaited<ReturnType<typeof createDataConsultServiceTestModule>>;
|
||||||
|
|
||||||
|
beforeEach(async () => {
|
||||||
|
context = await createDataConsultServiceTestModule();
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
jest.clearAllMocks();
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('Tests that expose problems', () => {
|
||||||
|
it('should validate that all billings have required properties (id, date, total)', async () => {
|
||||||
|
context.mockRepository.findBillings.mockResolvedValue([
|
||||||
|
{ id: '001' },
|
||||||
|
{ date: new Date(), total: 1000 },
|
||||||
|
{ id: '003', date: new Date(), total: 2000 },
|
||||||
|
] as any);
|
||||||
|
|
||||||
|
const result = await context.service.billings();
|
||||||
|
result.forEach(billing => {
|
||||||
|
expect(billing.id).toBeDefined();
|
||||||
|
expect(billing.date).toBeDefined();
|
||||||
|
expect(billing.total).toBeDefined();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should handle null or undefined result from repository', async () => {
|
||||||
|
context.mockRepository.findBillings.mockResolvedValue(null as any);
|
||||||
|
await expect(context.service.billings()).rejects.toThrow();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should validate that repository result is an array', async () => {
|
||||||
|
context.mockRepository.findBillings.mockResolvedValue({ id: '001', date: new Date(), total: 1000 } as any);
|
||||||
|
const result = await context.service.billings();
|
||||||
|
expect(Array.isArray(result)).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should validate that required properties are not empty or invalid', async () => {
|
||||||
|
context.mockRepository.findBillings.mockResolvedValue([
|
||||||
|
{ id: '', date: new Date(), total: 1000 },
|
||||||
|
{ id: '002', date: null, total: 1000 },
|
||||||
|
{ id: '003', date: new Date(), total: null },
|
||||||
|
] as any);
|
||||||
|
|
||||||
|
const result = await context.service.billings();
|
||||||
|
result.forEach(billing => {
|
||||||
|
expect(billing.id).not.toBe('');
|
||||||
|
expect(billing.date).toBeDefined();
|
||||||
|
expect(billing.total).toBeDefined();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should log error when repository throws exception', async () => {
|
||||||
|
const repositoryError = new Error('Database connection failed');
|
||||||
|
context.mockRepository.findBillings.mockRejectedValue(repositoryError);
|
||||||
|
await expect(context.service.billings()).rejects.toThrow(HttpException);
|
||||||
|
expect(context.mockLogger.error).toHaveBeenCalledWith('Erro ao buscar faturamento', repositoryError);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('customers', () => {
|
||||||
|
let context: Awaited<ReturnType<typeof createDataConsultServiceTestModule>>;
|
||||||
|
|
||||||
|
beforeEach(async () => {
|
||||||
|
context = await createDataConsultServiceTestModule();
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
jest.clearAllMocks();
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('Tests that expose problems', () => {
|
||||||
|
it('should validate that all customers have required properties (id, name, document)', async () => {
|
||||||
|
context.mockRepository.findCustomers.mockResolvedValue([
|
||||||
|
{ id: '001', name: 'Cliente 1' },
|
||||||
|
{ id: '002', document: '12345678900' },
|
||||||
|
{ id: '003', name: 'Cliente 3', document: '12345678901' },
|
||||||
|
] as any);
|
||||||
|
|
||||||
|
const result = await context.service.customers('test');
|
||||||
|
result.forEach(customer => {
|
||||||
|
expect(customer.id).toBeDefined();
|
||||||
|
expect(customer.name).toBeDefined();
|
||||||
|
expect(customer.document).toBeDefined();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should handle null or undefined result from repository', async () => {
|
||||||
|
context.mockRepository.findCustomers.mockResolvedValue(null as any);
|
||||||
|
await expect(context.service.customers('test')).rejects.toThrow();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should validate that repository result is an array', async () => {
|
||||||
|
context.mockRepository.findCustomers.mockResolvedValue({ id: '001', name: 'Cliente 1', document: '12345678900' } as any);
|
||||||
|
const result = await context.service.customers('test');
|
||||||
|
expect(Array.isArray(result)).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should validate that required properties are not empty strings', async () => {
|
||||||
|
context.mockRepository.findCustomers.mockResolvedValue([
|
||||||
|
{ id: '', name: 'Cliente 1', document: '12345678900' },
|
||||||
|
{ id: '002', name: '', document: '12345678901' },
|
||||||
|
{ id: '003', name: 'Cliente 3', document: '' },
|
||||||
|
] as any);
|
||||||
|
|
||||||
|
const result = await context.service.customers('test');
|
||||||
|
result.forEach(customer => {
|
||||||
|
expect(customer.id).not.toBe('');
|
||||||
|
expect(customer.name).not.toBe('');
|
||||||
|
expect(customer.document).not.toBe('');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should log error when repository throws exception', async () => {
|
||||||
|
const repositoryError = new Error('Database connection failed');
|
||||||
|
context.mockRepository.findCustomers.mockRejectedValue(repositoryError);
|
||||||
|
await expect(context.service.customers('test')).rejects.toThrow(HttpException);
|
||||||
|
expect(context.mockLogger.error).toHaveBeenCalledWith('Erro ao buscar clientes', repositoryError);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('getAllProducts', () => {
|
||||||
|
let context: Awaited<ReturnType<typeof createDataConsultServiceTestModule>>;
|
||||||
|
|
||||||
|
beforeEach(async () => {
|
||||||
|
context = await createDataConsultServiceTestModule();
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
jest.clearAllMocks();
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('Tests that expose problems', () => {
|
||||||
|
it('should validate that all products have required properties (id, name, manufacturerCode)', async () => {
|
||||||
|
context.mockRepository.findAllProducts.mockResolvedValue([
|
||||||
|
{ id: '001', name: 'Produto 1' },
|
||||||
|
{ id: '002', manufacturerCode: 'FAB001' },
|
||||||
|
{ id: '003', name: 'Produto 3', manufacturerCode: 'FAB003' },
|
||||||
|
] as any);
|
||||||
|
|
||||||
|
const result = await context.service.getAllProducts();
|
||||||
|
result.forEach(product => {
|
||||||
|
expect(product.id).toBeDefined();
|
||||||
|
expect(product.name).toBeDefined();
|
||||||
|
expect(product.manufacturerCode).toBeDefined();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should handle null or undefined result from repository', async () => {
|
||||||
|
context.mockRepository.findAllProducts.mockResolvedValue(null as any);
|
||||||
|
await expect(context.service.getAllProducts()).rejects.toThrow();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should validate that repository result is an array', async () => {
|
||||||
|
context.mockRepository.findAllProducts.mockResolvedValue({ id: '001', name: 'Produto 1', manufacturerCode: 'FAB001' } as any);
|
||||||
|
const result = await context.service.getAllProducts();
|
||||||
|
expect(Array.isArray(result)).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should validate that required properties are not empty strings', async () => {
|
||||||
|
context.mockRepository.findAllProducts.mockResolvedValue([
|
||||||
|
{ id: '', name: 'Produto 1', manufacturerCode: 'FAB001' },
|
||||||
|
{ id: '002', name: '', manufacturerCode: 'FAB002' },
|
||||||
|
{ id: '003', name: 'Produto 3', manufacturerCode: '' },
|
||||||
|
] as any);
|
||||||
|
|
||||||
|
const result = await context.service.getAllProducts();
|
||||||
|
result.forEach(product => {
|
||||||
|
expect(product.id).not.toBe('');
|
||||||
|
expect(product.name).not.toBe('');
|
||||||
|
expect(product.manufacturerCode).not.toBe('');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should log error when repository throws exception', async () => {
|
||||||
|
const repositoryError = new Error('Database connection failed');
|
||||||
|
context.mockRepository.findAllProducts.mockRejectedValue(repositoryError);
|
||||||
|
await expect(context.service.getAllProducts()).rejects.toThrow(HttpException);
|
||||||
|
expect(context.mockLogger.error).toHaveBeenCalledWith('Erro ao buscar todos os produtos', repositoryError);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('getAllCarriers', () => {
|
||||||
|
let context: Awaited<ReturnType<typeof createDataConsultServiceTestModule>>;
|
||||||
|
|
||||||
|
beforeEach(async () => {
|
||||||
|
context = await createDataConsultServiceTestModule();
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
jest.clearAllMocks();
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('Tests that expose problems', () => {
|
||||||
|
it('should validate that all carriers have required properties (carrierId, carrierName, carrierDescription)', async () => {
|
||||||
|
context.mockRepository.findAllCarriers.mockResolvedValue([
|
||||||
|
{ carrierId: '001', carrierName: 'Transportadora 1' },
|
||||||
|
{ carrierName: 'Transportadora 2', carrierDescription: '002 - Transportadora 2' },
|
||||||
|
{ carrierId: '003', carrierName: 'Transportadora 3', carrierDescription: '003 - Transportadora 3' },
|
||||||
|
] as any);
|
||||||
|
|
||||||
|
const result = await context.service.getAllCarriers();
|
||||||
|
result.forEach(carrier => {
|
||||||
|
expect(carrier.carrierId).toBeDefined();
|
||||||
|
expect(carrier.carrierName).toBeDefined();
|
||||||
|
expect(carrier.carrierDescription).toBeDefined();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should handle null or undefined result from repository', async () => {
|
||||||
|
context.mockRepository.findAllCarriers.mockResolvedValue(null as any);
|
||||||
|
await expect(context.service.getAllCarriers()).rejects.toThrow();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should validate that repository result is an array', async () => {
|
||||||
|
context.mockRepository.findAllCarriers.mockResolvedValue({ carrierId: '001', carrierName: 'Transportadora 1', carrierDescription: '001 - Transportadora 1' } as any);
|
||||||
|
const result = await context.service.getAllCarriers();
|
||||||
|
expect(Array.isArray(result)).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should validate that required properties are not empty strings', async () => {
|
||||||
|
context.mockRepository.findAllCarriers.mockResolvedValue([
|
||||||
|
{ carrierId: '', carrierName: 'Transportadora 1', carrierDescription: '001 - Transportadora 1' },
|
||||||
|
{ carrierId: '002', carrierName: '', carrierDescription: '002 - Transportadora 2' },
|
||||||
|
{ carrierId: '003', carrierName: 'Transportadora 3', carrierDescription: '' },
|
||||||
|
] as any);
|
||||||
|
|
||||||
|
const result = await context.service.getAllCarriers();
|
||||||
|
result.forEach(carrier => {
|
||||||
|
expect(carrier.carrierId).not.toBe('');
|
||||||
|
expect(carrier.carrierName).not.toBe('');
|
||||||
|
expect(carrier.carrierDescription).not.toBe('');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should log error when repository throws exception', async () => {
|
||||||
|
const repositoryError = new Error('Database connection failed');
|
||||||
|
context.mockRepository.findAllCarriers.mockRejectedValue(repositoryError);
|
||||||
|
await expect(context.service.getAllCarriers()).rejects.toThrow(HttpException);
|
||||||
|
expect(context.mockLogger.error).toHaveBeenCalledWith('Erro ao buscar transportadoras', repositoryError);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('getRegions', () => {
|
||||||
|
let context: Awaited<ReturnType<typeof createDataConsultServiceTestModule>>;
|
||||||
|
|
||||||
|
beforeEach(async () => {
|
||||||
|
context = await createDataConsultServiceTestModule();
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
jest.clearAllMocks();
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('Tests that expose problems', () => {
|
||||||
|
it('should validate that all regions have required properties (numregiao, regiao)', async () => {
|
||||||
|
context.mockRepository.findRegions.mockResolvedValue([
|
||||||
|
{ numregiao: 1 },
|
||||||
|
{ regiao: 'Região Sul' },
|
||||||
|
{ numregiao: 3, regiao: 'Região Norte' },
|
||||||
|
] as any);
|
||||||
|
|
||||||
|
const result = await context.service.getRegions();
|
||||||
|
result.forEach(region => {
|
||||||
|
expect(region.numregiao).toBeDefined();
|
||||||
|
expect(region.regiao).toBeDefined();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should handle null or undefined result from repository', async () => {
|
||||||
|
context.mockRepository.findRegions.mockResolvedValue(null as any);
|
||||||
|
await expect(context.service.getRegions()).rejects.toThrow();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should validate that repository result is an array', async () => {
|
||||||
|
context.mockRepository.findRegions.mockResolvedValue({ numregiao: 1, regiao: 'Região Sul' } as any);
|
||||||
|
const result = await context.service.getRegions();
|
||||||
|
expect(Array.isArray(result)).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should validate that required properties are not empty or invalid', async () => {
|
||||||
|
context.mockRepository.findRegions.mockResolvedValue([
|
||||||
|
{ numregiao: null, regiao: 'Região Sul' },
|
||||||
|
{ numregiao: 2, regiao: '' },
|
||||||
|
{ numregiao: 3, regiao: 'Região Norte' },
|
||||||
|
] as any);
|
||||||
|
|
||||||
|
const result = await context.service.getRegions();
|
||||||
|
result.forEach(region => {
|
||||||
|
expect(region.numregiao).toBeDefined();
|
||||||
|
expect(region.numregiao).not.toBeNull();
|
||||||
|
expect(region.regiao).toBeDefined();
|
||||||
|
expect(region.regiao).not.toBe('');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should log error when repository throws exception', async () => {
|
||||||
|
const repositoryError = new Error('Database connection failed');
|
||||||
|
context.mockRepository.findRegions.mockRejectedValue(repositoryError);
|
||||||
|
await expect(context.service.getRegions()).rejects.toThrow(HttpException);
|
||||||
|
expect(context.mockLogger.error).toHaveBeenCalledWith('Erro ao buscar regiões', repositoryError);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|||||||
@@ -106,7 +106,24 @@ export class DataConsultService {
|
|||||||
this.logger.log('Buscando informações de faturamento');
|
this.logger.log('Buscando informações de faturamento');
|
||||||
try {
|
try {
|
||||||
const billings = await this.repository.findBillings();
|
const billings = await this.repository.findBillings();
|
||||||
return billings.map(billing => new BillingDto(billing));
|
|
||||||
|
if (billings === null || billings === undefined) {
|
||||||
|
throw new HttpException('Resultado inválido do repositório', HttpStatus.INTERNAL_SERVER_ERROR);
|
||||||
|
}
|
||||||
|
|
||||||
|
const billingsArray = Array.isArray(billings) ? billings : [billings];
|
||||||
|
|
||||||
|
return billingsArray
|
||||||
|
.filter(billing => {
|
||||||
|
if (!billing || typeof billing !== 'object') {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
const hasId = billing.id !== undefined && billing.id !== null && billing.id !== '';
|
||||||
|
const hasDate = billing.date !== undefined && billing.date !== null;
|
||||||
|
const hasTotal = billing.total !== undefined && billing.total !== null;
|
||||||
|
return hasId && hasDate && hasTotal;
|
||||||
|
})
|
||||||
|
.map(billing => new BillingDto(billing));
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
this.logger.error('Erro ao buscar faturamento', error);
|
this.logger.error('Erro ao buscar faturamento', error);
|
||||||
throw new HttpException('Erro ao buscar faturamento', HttpStatus.INTERNAL_SERVER_ERROR);
|
throw new HttpException('Erro ao buscar faturamento', HttpStatus.INTERNAL_SERVER_ERROR);
|
||||||
@@ -120,7 +137,24 @@ export class DataConsultService {
|
|||||||
throw new HttpException('Filtro inválido', HttpStatus.BAD_REQUEST);
|
throw new HttpException('Filtro inválido', HttpStatus.BAD_REQUEST);
|
||||||
}
|
}
|
||||||
const customers = await this.repository.findCustomers(filter);
|
const customers = await this.repository.findCustomers(filter);
|
||||||
return customers.map(customer => new CustomerDto(customer));
|
|
||||||
|
if (customers === null || customers === undefined) {
|
||||||
|
throw new HttpException('Resultado inválido do repositório', HttpStatus.INTERNAL_SERVER_ERROR);
|
||||||
|
}
|
||||||
|
|
||||||
|
const customersArray = Array.isArray(customers) ? customers : [customers];
|
||||||
|
|
||||||
|
return customersArray
|
||||||
|
.filter(customer => {
|
||||||
|
if (!customer || typeof customer !== 'object') {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
const hasId = customer.id !== undefined && customer.id !== null && customer.id !== '';
|
||||||
|
const hasName = customer.name !== undefined && customer.name !== null && customer.name !== '';
|
||||||
|
const hasDocument = customer.document !== undefined && customer.document !== null && customer.document !== '';
|
||||||
|
return hasId && hasName && hasDocument;
|
||||||
|
})
|
||||||
|
.map(customer => new CustomerDto(customer));
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
this.logger.error('Erro ao buscar clientes', error);
|
this.logger.error('Erro ao buscar clientes', error);
|
||||||
throw new HttpException('Erro ao buscar clientes', HttpStatus.INTERNAL_SERVER_ERROR);
|
throw new HttpException('Erro ao buscar clientes', HttpStatus.INTERNAL_SERVER_ERROR);
|
||||||
@@ -144,13 +178,35 @@ export class DataConsultService {
|
|||||||
async getAllProducts(): Promise<ProductDto[]> {
|
async getAllProducts(): Promise<ProductDto[]> {
|
||||||
this.logger.log('Buscando todos os produtos');
|
this.logger.log('Buscando todos os produtos');
|
||||||
try {
|
try {
|
||||||
return getOrSetCache<ProductDto[]>(
|
return await getOrSetCache<ProductDto[]>(
|
||||||
this.redisClient,
|
this.redisClient,
|
||||||
this.ALL_PRODUCTS_CACHE_KEY,
|
this.ALL_PRODUCTS_CACHE_KEY,
|
||||||
this.ALL_PRODUCTS_TTL,
|
this.ALL_PRODUCTS_TTL,
|
||||||
async () => {
|
async () => {
|
||||||
|
try {
|
||||||
const products = await this.repository.findAllProducts();
|
const products = await this.repository.findAllProducts();
|
||||||
return products.map(product => new ProductDto(product));
|
|
||||||
|
if (products === null || products === undefined) {
|
||||||
|
throw new HttpException('Resultado inválido do repositório', HttpStatus.INTERNAL_SERVER_ERROR);
|
||||||
|
}
|
||||||
|
|
||||||
|
const productsArray = Array.isArray(products) ? products : [products];
|
||||||
|
|
||||||
|
return productsArray
|
||||||
|
.filter(product => {
|
||||||
|
if (!product || typeof product !== 'object') {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
const hasId = product.id !== undefined && product.id !== null && product.id !== '';
|
||||||
|
const hasName = product.name !== undefined && product.name !== null && product.name !== '';
|
||||||
|
const hasManufacturerCode = product.manufacturerCode !== undefined && product.manufacturerCode !== null && product.manufacturerCode !== '';
|
||||||
|
return hasId && hasName && hasManufacturerCode;
|
||||||
|
})
|
||||||
|
.map(product => new ProductDto(product));
|
||||||
|
} catch (error) {
|
||||||
|
this.logger.error('Erro ao buscar todos os produtos', error);
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
@@ -162,17 +218,39 @@ export class DataConsultService {
|
|||||||
async getAllCarriers(): Promise<CarrierDto[]> {
|
async getAllCarriers(): Promise<CarrierDto[]> {
|
||||||
this.logger.log('Buscando todas as transportadoras');
|
this.logger.log('Buscando todas as transportadoras');
|
||||||
try {
|
try {
|
||||||
return getOrSetCache<CarrierDto[]>(
|
return await getOrSetCache<CarrierDto[]>(
|
||||||
this.redisClient,
|
this.redisClient,
|
||||||
this.CARRIERS_CACHE_KEY,
|
this.CARRIERS_CACHE_KEY,
|
||||||
this.CARRIERS_TTL,
|
this.CARRIERS_TTL,
|
||||||
async () => {
|
async () => {
|
||||||
|
try {
|
||||||
const carriers = await this.repository.findAllCarriers();
|
const carriers = await this.repository.findAllCarriers();
|
||||||
return carriers.map(carrier => ({
|
|
||||||
|
if (carriers === null || carriers === undefined) {
|
||||||
|
throw new HttpException('Resultado inválido do repositório', HttpStatus.INTERNAL_SERVER_ERROR);
|
||||||
|
}
|
||||||
|
|
||||||
|
const carriersArray = Array.isArray(carriers) ? carriers : [carriers];
|
||||||
|
|
||||||
|
return carriersArray
|
||||||
|
.filter(carrier => {
|
||||||
|
if (!carrier || typeof carrier !== 'object') {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
const hasCarrierId = carrier.carrierId !== undefined && carrier.carrierId !== null && carrier.carrierId !== '';
|
||||||
|
const hasCarrierName = carrier.carrierName !== undefined && carrier.carrierName !== null && carrier.carrierName !== '';
|
||||||
|
const hasCarrierDescription = carrier.carrierDescription !== undefined && carrier.carrierDescription !== null && carrier.carrierDescription !== '';
|
||||||
|
return hasCarrierId && hasCarrierName && hasCarrierDescription;
|
||||||
|
})
|
||||||
|
.map(carrier => ({
|
||||||
carrierId: carrier.carrierId?.toString() || '',
|
carrierId: carrier.carrierId?.toString() || '',
|
||||||
carrierName: carrier.carrierName || '',
|
carrierName: carrier.carrierName || '',
|
||||||
carrierDescription: carrier.carrierDescription || '',
|
carrierDescription: carrier.carrierDescription || '',
|
||||||
}));
|
}));
|
||||||
|
} catch (error) {
|
||||||
|
this.logger.error('Erro ao buscar transportadoras', error);
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
@@ -215,13 +293,34 @@ export class DataConsultService {
|
|||||||
async getRegions(): Promise<RegionDto[]> {
|
async getRegions(): Promise<RegionDto[]> {
|
||||||
this.logger.log('Buscando todas as regiões');
|
this.logger.log('Buscando todas as regiões');
|
||||||
try {
|
try {
|
||||||
return getOrSetCache<RegionDto[]>(
|
return await getOrSetCache<RegionDto[]>(
|
||||||
this.redisClient,
|
this.redisClient,
|
||||||
this.REGIONS_CACHE_KEY,
|
this.REGIONS_CACHE_KEY,
|
||||||
this.REGIONS_TTL,
|
this.REGIONS_TTL,
|
||||||
async () => {
|
async () => {
|
||||||
|
try {
|
||||||
const regions = await this.repository.findRegions();
|
const regions = await this.repository.findRegions();
|
||||||
return regions;
|
|
||||||
|
if (regions === null || regions === undefined) {
|
||||||
|
throw new HttpException('Resultado inválido do repositório', HttpStatus.INTERNAL_SERVER_ERROR);
|
||||||
|
}
|
||||||
|
|
||||||
|
const regionsArray = Array.isArray(regions) ? regions : [regions];
|
||||||
|
|
||||||
|
return regionsArray
|
||||||
|
.filter(region => {
|
||||||
|
if (!region || typeof region !== 'object') {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
const hasNumregiao = region.numregiao !== undefined && region.numregiao !== null;
|
||||||
|
const hasRegiao = region.regiao !== undefined && region.regiao !== null && region.regiao !== '';
|
||||||
|
return hasNumregiao && hasRegiao;
|
||||||
|
})
|
||||||
|
.map(region => new RegionDto(region));
|
||||||
|
} catch (error) {
|
||||||
|
this.logger.error('Erro ao buscar regiões', error);
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
|||||||
Reference in New Issue
Block a user