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:
joelson brito
2025-11-07 11:07:28 -03:00
parent de4465ed60
commit fbdacf60f7
3 changed files with 603 additions and 300 deletions

View File

@@ -106,7 +106,24 @@ export class DataConsultService {
this.logger.log('Buscando informações de faturamento');
try {
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) {
this.logger.error('Erro ao buscar faturamento', 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);
}
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) {
this.logger.error('Erro ao buscar clientes', error);
throw new HttpException('Erro ao buscar clientes', HttpStatus.INTERNAL_SERVER_ERROR);
@@ -144,13 +178,35 @@ export class DataConsultService {
async getAllProducts(): Promise<ProductDto[]> {
this.logger.log('Buscando todos os produtos');
try {
return getOrSetCache<ProductDto[]>(
return await getOrSetCache<ProductDto[]>(
this.redisClient,
this.ALL_PRODUCTS_CACHE_KEY,
this.ALL_PRODUCTS_TTL,
async () => {
const products = await this.repository.findAllProducts();
return products.map(product => new ProductDto(product));
try {
const products = await this.repository.findAllProducts();
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) {
@@ -162,17 +218,39 @@ export class DataConsultService {
async getAllCarriers(): Promise<CarrierDto[]> {
this.logger.log('Buscando todas as transportadoras');
try {
return getOrSetCache<CarrierDto[]>(
return await getOrSetCache<CarrierDto[]>(
this.redisClient,
this.CARRIERS_CACHE_KEY,
this.CARRIERS_TTL,
async () => {
const carriers = await this.repository.findAllCarriers();
return carriers.map(carrier => ({
carrierId: carrier.carrierId?.toString() || '',
carrierName: carrier.carrierName || '',
carrierDescription: carrier.carrierDescription || '',
}));
try {
const carriers = await this.repository.findAllCarriers();
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() || '',
carrierName: carrier.carrierName || '',
carrierDescription: carrier.carrierDescription || '',
}));
} catch (error) {
this.logger.error('Erro ao buscar transportadoras', error);
throw error;
}
}
);
} catch (error) {
@@ -215,13 +293,34 @@ export class DataConsultService {
async getRegions(): Promise<RegionDto[]> {
this.logger.log('Buscando todas as regiões');
try {
return getOrSetCache<RegionDto[]>(
return await getOrSetCache<RegionDto[]>(
this.redisClient,
this.REGIONS_CACHE_KEY,
this.REGIONS_TTL,
async () => {
const regions = await this.repository.findRegions();
return regions;
try {
const regions = await this.repository.findRegions();
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) {