From cb5f55215f1bd5e5058df005d6053a3473dd5d40 Mon Sep 17 00:00:00 2001 From: Maick Speck Date: Sun, 26 Jun 2022 19:51:44 -0300 Subject: [PATCH 01/39] realoc method --- .../aggregated-neighborhoods-city.interface.ts | 2 +- .../service/cities/get-cities-by-state.service.ts | 9 --------- .../get/get-neighborhoods-by-state.service.ts | 13 ++++++++++--- .../seed/seed-neighborhoods-by-state.service.ts | 13 +++++++------ test/e2e/app.e2e-spec.ts | 2 +- 5 files changed, 19 insertions(+), 20 deletions(-) diff --git a/src/microservice/domain/interface/aggregated/aggregated-neighborhoods-city.interface.ts b/src/microservice/domain/interface/aggregated/aggregated-neighborhoods-city.interface.ts index 8f6ccdd..195690e 100644 --- a/src/microservice/domain/interface/aggregated/aggregated-neighborhoods-city.interface.ts +++ b/src/microservice/domain/interface/aggregated/aggregated-neighborhoods-city.interface.ts @@ -1,4 +1,4 @@ -export interface AggregatedNeighborhoodsCity { +export interface AggregatedNeighborhoodsByCity { _id: { cityId: number }; count: number; city: string; diff --git a/src/microservice/domain/service/cities/get-cities-by-state.service.ts b/src/microservice/domain/service/cities/get-cities-by-state.service.ts index 36ca970..ef95bd9 100644 --- a/src/microservice/domain/service/cities/get-cities-by-state.service.ts +++ b/src/microservice/domain/service/cities/get-cities-by-state.service.ts @@ -1,7 +1,6 @@ import { Injectable } from '@nestjs/common'; import { NeighborhoodsMongoose } from '../../../adapter/repository/neighborhoods/neighborhoods-mongoose.repository'; import { CitiesMongoose } from '../../../adapter/repository/cities/cities-mongoose.repository'; -import { AggregatedNeighborhoodsCity } from '../../interface/aggregated/aggregated-neighborhoods-city.interface'; import { SearchCitiesDB } from '../../model/search/search-cities-db.model'; import { City } from '../../schemas/city.schema'; import { CitiesService } from './cities.service'; @@ -22,12 +21,4 @@ export class GetCitiesByStateService extends CitiesService { if (arrIgnore.length > 0) searchParams.id = { $nin: arrIgnore }; return this.mongoRepository.findBySearchParams(searchParams); } - - async groupByCity(stateId: number): Promise { - return this.mongoNeighborhoodsRepository.groupBy( - { cityId: '$cityId' }, - { stateId }, - { city: 'city' } - ); - } } diff --git a/src/microservice/domain/service/neighborhoods/get/get-neighborhoods-by-state.service.ts b/src/microservice/domain/service/neighborhoods/get/get-neighborhoods-by-state.service.ts index bcb1859..35ed15c 100644 --- a/src/microservice/domain/service/neighborhoods/get/get-neighborhoods-by-state.service.ts +++ b/src/microservice/domain/service/neighborhoods/get/get-neighborhoods-by-state.service.ts @@ -10,6 +10,7 @@ import { import { NeighborhoodsService } from '../neighborhoods.service'; import { ValidateInputParamsService } from '../../validate-input-params.service'; import { GetCitiesByStateService } from '../../cities/get-cities-by-state.service'; +import { AggregatedNeighborhoodsByCity } from '../../../interface/aggregated/aggregated-neighborhoods-city.interface'; @Injectable() export class GetNeighborhoodsByStateService extends NeighborhoodsService { @@ -37,9 +38,7 @@ export class GetNeighborhoodsByStateService extends NeighborhoodsService { this.logger.log( `Searching cities for state '${convertedSearch.state.stateCode}'...` ); - const aggregatedByCity = await this.getCitiesByStateService.groupByCity( - convertedSearch.state.id - ); + const aggregatedByCity = await this.groupByCity(convertedSearch.state.id); this.logger.log(`Founded cities: ${aggregatedByCity.length}`); for await (const item of aggregatedByCity) { const cityId = item._id.cityId; @@ -74,4 +73,12 @@ export class GetNeighborhoodsByStateService extends NeighborhoodsService { ); return this.findInDatabase(searchDB); } + + async groupByCity(stateId: number): Promise { + return this.mongoRepository.groupBy( + { cityId: '$cityId' }, + { stateId }, + { city: 'city' } + ); + } } diff --git a/src/microservice/domain/service/neighborhoods/seed/seed-neighborhoods-by-state.service.ts b/src/microservice/domain/service/neighborhoods/seed/seed-neighborhoods-by-state.service.ts index 0923b3c..e68cd44 100644 --- a/src/microservice/domain/service/neighborhoods/seed/seed-neighborhoods-by-state.service.ts +++ b/src/microservice/domain/service/neighborhoods/seed/seed-neighborhoods-by-state.service.ts @@ -10,14 +10,16 @@ import { EnumTranslations } from '../../../enumerators/enum-translations.enumera import { City } from '../../../schemas/city.schema'; import { NeighborhoodsMongoose } from '../../../../adapter/repository/neighborhoods/neighborhoods-mongoose.repository'; import { LogSeedJobService } from '../../logseed/log-seed-job.service'; -import { CustomResponse } from 'src/core/interface/custom-response.interface'; +import { CustomResponse } from '../../../../../core/interface/custom-response.interface'; +import { GetNeighborhoodsByStateService } from '../get/get-neighborhoods-by-state.service'; @Injectable() export class SeedNeighborhoodsByStateService extends NeighborhoodsService { constructor( mongoRepository: NeighborhoodsMongoose, private readonly validateService: ValidateInputParamsService, - private readonly getNeighborhoodsService: GetNeighborhoodsByCityService, + private readonly getNeighborhoodsByCityService: GetNeighborhoodsByCityService, + private readonly getNeighborhoodsByStateService: GetNeighborhoodsByStateService, private readonly getCitiesByStateService: GetCitiesByStateService, private readonly logSeedService: LogSeedJobService ) { @@ -91,7 +93,7 @@ export class SeedNeighborhoodsByStateService extends NeighborhoodsService { ); convertedSearch.city = city; this.logger.log(`Seeding city[${city.id}] ${city.name}...`); - await this.getNeighborhoodsService.searchByPuppeterAndSave( + await this.getNeighborhoodsByCityService.searchByPuppeterAndSave( searchParamsByCity, convertedSearch ); @@ -99,9 +101,8 @@ export class SeedNeighborhoodsByStateService extends NeighborhoodsService { async getSeededCities(stateId: number): Promise { this.logger.log('Getting seeded cities...'); - const aggregatedCities = await this.getCitiesByStateService.groupByCity( - stateId - ); + const aggregatedCities = + await this.getNeighborhoodsByStateService.groupByCity(stateId); return aggregatedCities.map((item) => { return item._id.cityId; }); diff --git a/test/e2e/app.e2e-spec.ts b/test/e2e/app.e2e-spec.ts index b98ad97..aa6d52c 100644 --- a/test/e2e/app.e2e-spec.ts +++ b/test/e2e/app.e2e-spec.ts @@ -5,7 +5,7 @@ import { AppModule } from '../../src/app.module'; import { NestFactory } from '@nestjs/core'; import '../../src/microservice/adapter/helper/extensions/exensions.module'; -jest.setTimeout(50000); +jest.setTimeout(75000); describe('App (e2e) ', () => { let app: INestApplication; From d2f650908d8ce46df4cdda82baf1501f14217d2a Mon Sep 17 00:00:00 2001 From: Maick Speck Date: Sun, 26 Jun 2022 20:04:48 -0300 Subject: [PATCH 02/39] fix test realoc goupByCity --- .../get/get-neighborhoods-by-state.service.ts | 2 -- .../get-cities-by-state.service.spec.ts | 27 ------------------- ...get-neighborhoods-by-state.service.spec.ts | 27 ++++++++++--------- ...ed-neighborhoods-by-state.service.spec.ts} | 18 +++++++++---- 4 files changed, 28 insertions(+), 46 deletions(-) rename test/unit/microservice/domain/service/neighborhoods/seed/{seed-neighborhoods-by-city.service.spec.ts => seed-neighborhoods-by-state.service.spec.ts} (90%) diff --git a/src/microservice/domain/service/neighborhoods/get/get-neighborhoods-by-state.service.ts b/src/microservice/domain/service/neighborhoods/get/get-neighborhoods-by-state.service.ts index 35ed15c..068ac33 100644 --- a/src/microservice/domain/service/neighborhoods/get/get-neighborhoods-by-state.service.ts +++ b/src/microservice/domain/service/neighborhoods/get/get-neighborhoods-by-state.service.ts @@ -9,14 +9,12 @@ import { } from '../../../model/neighborhoods/neighborhoods-by-state.model'; import { NeighborhoodsService } from '../neighborhoods.service'; import { ValidateInputParamsService } from '../../validate-input-params.service'; -import { GetCitiesByStateService } from '../../cities/get-cities-by-state.service'; import { AggregatedNeighborhoodsByCity } from '../../../interface/aggregated/aggregated-neighborhoods-city.interface'; @Injectable() export class GetNeighborhoodsByStateService extends NeighborhoodsService { constructor( protected readonly validateService: ValidateInputParamsService, - protected readonly getCitiesByStateService: GetCitiesByStateService, mongoRepository: NeighborhoodsMongoose ) { super(mongoRepository); diff --git a/test/unit/microservice/domain/service/cities/get-cities-by-state.service.spec.ts b/test/unit/microservice/domain/service/cities/get-cities-by-state.service.spec.ts index 5cafc91..95f0a17 100644 --- a/test/unit/microservice/domain/service/cities/get-cities-by-state.service.spec.ts +++ b/test/unit/microservice/domain/service/cities/get-cities-by-state.service.spec.ts @@ -41,19 +41,6 @@ describe('GetCitiesByStateService', () => { } }; - const mockAggregatedCities = [ - { - _id: { cityId: 1 }, - count: 60, - city: 'Orleans' - }, - { - _id: { cityId: 2 }, - count: 13, - city: 'Braço do Norte' - } - ]; - const mockCities = () => { const city1 = new City(); city1.name = 'any'; @@ -122,18 +109,4 @@ describe('GetCitiesByStateService', () => { groupByStub.restore(); }); }); - - describe('groupByCity', () => { - it('should call groupByCity and return an array by puppeteer', async () => { - const groupByStub = sinon - .stub(mockNeighborhoodsMongooseRepository, 'groupBy') - .returns(mockAggregatedCities); - - const actual = await sut.groupByCity(1); - - expect(actual).to.be.equal(mockAggregatedCities); - - groupByStub.restore(); - }); - }); }); diff --git a/test/unit/microservice/domain/service/neighborhoods/get/get-neighborhoods-by-state.service.spec.ts b/test/unit/microservice/domain/service/neighborhoods/get/get-neighborhoods-by-state.service.spec.ts index e492e20..d19c7c9 100644 --- a/test/unit/microservice/domain/service/neighborhoods/get/get-neighborhoods-by-state.service.spec.ts +++ b/test/unit/microservice/domain/service/neighborhoods/get/get-neighborhoods-by-state.service.spec.ts @@ -19,7 +19,6 @@ describe('GetNeighborhoodsByStateService', () => { findBySearchParams: () => { return []; }, - groupBy: () => { return []; } @@ -34,12 +33,6 @@ describe('GetNeighborhoodsByStateService', () => { } }; - const mockGetCitiesByStateService = { - groupByCity: () => { - return []; - } - }; - const mockMongoNeighborhoods = () => { const arr = []; const item1 = new Neighborhood(); @@ -83,10 +76,6 @@ describe('GetNeighborhoodsByStateService', () => { provide: NeighborhoodsMongoose, useValue: mockNeighborhoodsMongooseRepository }, - { - provide: GetCitiesByStateService, - useValue: mockGetCitiesByStateService - }, { provide: ValidateInputParamsService, useFactory: () => mockValidateService @@ -111,7 +100,7 @@ describe('GetNeighborhoodsByStateService', () => { .returns(mockMongoNeighborhoods()); const groupByStub = sinon - .stub(mockGetCitiesByStateService, 'groupByCity') + .stub(sut, 'groupByCity') .returns(mockAggregatedCities); const searchParams = new SearchNeighborhoodsInput('brasil', 'sc'); @@ -128,4 +117,18 @@ describe('GetNeighborhoodsByStateService', () => { groupByStub.restore(); }); }); + + describe('groupByCity', () => { + it('should call groupByCity and return an array by puppeteer', async () => { + const groupByStub = sinon + .stub(mockNeighborhoodsMongooseRepository, 'groupBy') + .returns(mockAggregatedCities); + + const actual = await sut.groupByCity(1); + + expect(actual).to.be.equal(mockAggregatedCities); + + groupByStub.restore(); + }); + }); }); diff --git a/test/unit/microservice/domain/service/neighborhoods/seed/seed-neighborhoods-by-city.service.spec.ts b/test/unit/microservice/domain/service/neighborhoods/seed/seed-neighborhoods-by-state.service.spec.ts similarity index 90% rename from test/unit/microservice/domain/service/neighborhoods/seed/seed-neighborhoods-by-city.service.spec.ts rename to test/unit/microservice/domain/service/neighborhoods/seed/seed-neighborhoods-by-state.service.spec.ts index 483d9f6..679c7fa 100644 --- a/test/unit/microservice/domain/service/neighborhoods/seed/seed-neighborhoods-by-city.service.spec.ts +++ b/test/unit/microservice/domain/service/neighborhoods/seed/seed-neighborhoods-by-state.service.spec.ts @@ -15,6 +15,7 @@ import { NeighborhoodsMongoose } from '../../../../../../../src/microservice/ada import { Translations } from '../../../../../../../src/microservice/domain/model/translations.model'; import { EnumTranslations } from '../../../../../../../src/microservice/domain/enumerators/enum-translations.enumerator'; import { NotFoundException } from '../../../../../../../src/core/error-handling/exception/not-found.exception'; +import { GetNeighborhoodsByStateService } from '../../../../../../../src/microservice/domain/service/neighborhoods/get/get-neighborhoods-by-state.service'; describe('SeedNeighborhoodsByStateService', () => { let sut: SeedNeighborhoodsByStateService; @@ -22,7 +23,10 @@ describe('SeedNeighborhoodsByStateService', () => { const mockGetCitiesByStateService = { getCitiesByState: () => { return; - }, + } + }; + + const mockGetNeighborhoodsByStateService = { groupByCity: () => { return; } @@ -122,6 +126,10 @@ describe('SeedNeighborhoodsByStateService', () => { provide: LogSeedJobService, useValue: mockLogSeedService }, + { + provide: GetNeighborhoodsByStateService, + useValue: mockGetNeighborhoodsByStateService + }, SeedNeighborhoodsByStateService ] }).compile(); @@ -134,7 +142,7 @@ describe('SeedNeighborhoodsByStateService', () => { describe('seedNeighborhoodsByStateService', () => { it('should call seedNeighborhoodsByStateService and return "Seeded"', async () => { const groupByCityStub = sinon - .stub(mockGetCitiesByStateService, 'groupByCity') + .stub(mockGetNeighborhoodsByStateService, 'groupByCity') .returns([]); const validateStub = sinon @@ -159,7 +167,7 @@ describe('SeedNeighborhoodsByStateService', () => { it('should call seedNeighborhoodsByStateService and return "Nothing to seed"', async () => { const groupByCityStub = sinon - .stub(mockGetCitiesByStateService, 'groupByCity') + .stub(mockGetNeighborhoodsByStateService, 'groupByCity') .returns([]); const validateStub = sinon @@ -184,7 +192,7 @@ describe('SeedNeighborhoodsByStateService', () => { it('should call seedNeighborhoodsByStateService with error and call logSeedService', async () => { const groupByCityStub = sinon - .stub(mockGetCitiesByStateService, 'groupByCity') + .stub(mockGetNeighborhoodsByStateService, 'groupByCity') .returns([]); const validateStub = sinon @@ -263,7 +271,7 @@ describe('SeedNeighborhoodsByStateService', () => { describe('getSeededCities', () => { it('should call getSeededCities and return the correct values', async () => { const groupByCityStub = sinon - .stub(mockGetCitiesByStateService, 'groupByCity') + .stub(mockGetNeighborhoodsByStateService, 'groupByCity') .resolves(mockAggregatedCities); const actual = await sut.getSeededCities(1); From 8816a9c1db603e72d5ba1a354bc3375fbc49df67 Mon Sep 17 00:00:00 2001 From: Maick Speck Date: Sun, 26 Jun 2022 20:08:24 -0300 Subject: [PATCH 03/39] rm noused --- .../neighborhoods/get/get-neighborhoods-by-state.service.spec.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/test/unit/microservice/domain/service/neighborhoods/get/get-neighborhoods-by-state.service.spec.ts b/test/unit/microservice/domain/service/neighborhoods/get/get-neighborhoods-by-state.service.spec.ts index d19c7c9..e20bb7a 100644 --- a/test/unit/microservice/domain/service/neighborhoods/get/get-neighborhoods-by-state.service.spec.ts +++ b/test/unit/microservice/domain/service/neighborhoods/get/get-neighborhoods-by-state.service.spec.ts @@ -9,7 +9,6 @@ import { ValidateInputParamsService } from '../../../../../../../src/microservic import { Country } from '../../../../../../../src/microservice/domain/schemas/country.schema'; import { State } from '../../../../../../../src/microservice/domain/schemas/state.schema'; import { City } from '../../../../../../../src/microservice/domain/schemas/city.schema'; -import { GetCitiesByStateService } from '../../../../../../../src/microservice/domain/service/cities/get-cities-by-state.service'; import { GetNeighborhoodsByStateService } from '../../../../../../../src/microservice/domain/service/neighborhoods/get/get-neighborhoods-by-state.service'; describe('GetNeighborhoodsByStateService', () => { From 22409d3455fd1e26a22663a8ad69a5105eb4e8ec Mon Sep 17 00:00:00 2001 From: Maick Speck Date: Sun, 26 Jun 2022 20:33:08 -0300 Subject: [PATCH 04/39] searchCities Input --- src/app.module.ts | 4 +- src/microservice/adapter/cities.module.ts | 42 +++++++++++++++++++ .../adapter/controller/cities.controller.ts | 24 +++++++++++ .../controller/neighborhoods.controller.ts | 2 +- .../search-neighborhoods-db.builder.ts | 2 +- .../puppeteer/guia-mais.repository.ts | 2 +- ...eteer-neighborhood-repository.interface.ts | 2 +- .../{ => cities}/search-cities-db.model.ts | 0 .../cities/search-cities-input.model.ts | 3 ++ .../search-neighborhoods-db.model.ts | 0 .../search-neighborhoods-input.model.ts | 0 .../puppeteer-neighborhood.repository.ts | 2 +- .../puppeteer/puppeteer.repository.ts | 2 +- .../cities/get-cities-by-state.service.ts | 21 ++++++++-- .../get/get-neighborhoods-by-city.service.ts | 4 +- .../get/get-neighborhoods-by-state.service.ts | 4 +- .../neighborhoods/neighborhoods.service.ts | 2 +- .../save-neighborhoods-by-city.service.ts | 2 +- .../seed-neighborhoods-by-state.service.ts | 6 +-- .../service/validate-input-params.service.ts | 5 ++- .../neighborhoods-mongoose.repository.spec.ts | 2 +- .../search-neighborhoods-input.model.spec.ts | 2 +- .../get-cities-by-state.service.spec.ts | 14 +++---- ...save-neighborhoods-by-city.service.spec.ts | 2 +- ...eed-neighborhoods-by-state.service.spec.ts | 8 ++-- 25 files changed, 121 insertions(+), 36 deletions(-) create mode 100644 src/microservice/adapter/cities.module.ts create mode 100644 src/microservice/adapter/controller/cities.controller.ts rename src/microservice/domain/model/search/{ => cities}/search-cities-db.model.ts (100%) create mode 100644 src/microservice/domain/model/search/cities/search-cities-input.model.ts rename src/microservice/domain/model/search/{ => neighborhoods}/search-neighborhoods-db.model.ts (100%) rename src/microservice/domain/model/search/{ => neighborhoods}/search-neighborhoods-input.model.ts (100%) rename test/unit/microservice/domain/model/search/{ => neighborhoods}/search-neighborhoods-input.model.spec.ts (83%) diff --git a/src/app.module.ts b/src/app.module.ts index cfd0b29..5e14837 100644 --- a/src/app.module.ts +++ b/src/app.module.ts @@ -4,6 +4,7 @@ import { APP_INTERCEPTOR } from '@nestjs/core'; import { MongooseModule } from '@nestjs/mongoose'; import { FiltersModule } from './core/error-handling/filters.module'; import { TransformResponseInterceptor } from './core/http/transform-response.interceptor'; +import { CitiesModule } from './microservice/adapter/cities.module'; import { ExtensionsModule } from './microservice/adapter/helper/extensions/exensions.module'; import { CustomPuppeteerModule } from './microservice/adapter/helper/modules/custom-puppeteer.module'; import { NeighborhoodsModule } from './microservice/adapter/neighborhoods.module'; @@ -23,7 +24,8 @@ import { NeighborhoodsModule } from './microservice/adapter/neighborhoods.module uri: config.get('database.mongodb.connection') }) }), - NeighborhoodsModule + NeighborhoodsModule, + CitiesModule ], controllers: [], providers: [ diff --git a/src/microservice/adapter/cities.module.ts b/src/microservice/adapter/cities.module.ts new file mode 100644 index 0000000..3a636e7 --- /dev/null +++ b/src/microservice/adapter/cities.module.ts @@ -0,0 +1,42 @@ +import { Module } from '@nestjs/common'; +import { ConfigModule } from '@nestjs/config'; +import configuration from '../../config/configuration'; +import { MongooseModule } from '@nestjs/mongoose'; +import { Country, CountrySchema } from '../domain/schemas/country.schema'; +import { ValidateCountryByNameOrAliasService } from '../domain/service/countries/validate-country-by-name-or-alias.service'; +import { CountriesMongoose } from './repository/countries/countries-mongoose.repository'; +import { State, StateSchema } from '../domain/schemas/state.schema'; +import { ValidateStateByNameOrAliasService } from '../domain/service/states/validate-state-by-name-or-alias.service'; +import { StatesMongoose } from './repository/states/states-mongoose.repository'; +import { City, CitySchema } from '../domain/schemas/city.schema'; +import { ValidateCityByNameOrAliasService } from '../domain/service/cities/validate-city-by-name-or-alias.service'; +import { CitiesMongoose } from './repository/cities/cities-mongoose.repository'; +import { ValidateInputParamsService } from '../domain/service/validate-input-params.service'; +import { GetCitiesByStateService } from '../domain/service/cities/get-cities-by-state.service'; +import { CitiesController } from './controller/cities.controller'; + +@Module({ + imports: [ + ConfigModule.forRoot({ + isGlobal: true, + load: [configuration] + }), + MongooseModule.forFeature([ + { name: Country.name, schema: CountrySchema }, + { name: State.name, schema: StateSchema }, + { name: City.name, schema: CitySchema } + ]) + ], + controllers: [CitiesController], + providers: [ + CountriesMongoose, + StatesMongoose, + CitiesMongoose, + ValidateCountryByNameOrAliasService, + ValidateStateByNameOrAliasService, + ValidateCityByNameOrAliasService, + ValidateInputParamsService, + GetCitiesByStateService + ] +}) +export class CitiesModule {} diff --git a/src/microservice/adapter/controller/cities.controller.ts b/src/microservice/adapter/controller/cities.controller.ts new file mode 100644 index 0000000..30c84cf --- /dev/null +++ b/src/microservice/adapter/controller/cities.controller.ts @@ -0,0 +1,24 @@ +import { Controller, Get, HttpStatus, Param } from '@nestjs/common'; +import { NestResponse } from '../../../core/http/nest-response'; +import { AbstractController } from '../../domain/controller/abstract-controller'; +import { GetCitiesByStateService } from '../../domain/service/cities/get-cities-by-state.service'; +import { SearchCitiesInput } from 'src/microservice/domain/model/search/cities/search-cities-input.model'; + +@Controller('cities') +export class CitiesController extends AbstractController { + constructor( + private readonly getCitiesByCityService: GetCitiesByStateService + ) { + super(); + } + + @Get('/state/:country/:state') + async getNeighborhoodsByState( + @Param() params: SearchCitiesInput + ): Promise { + return this.buildResponse( + HttpStatus.OK, + await this.getCitiesByCityService.getCitiesByState(params) + ); + } +} diff --git a/src/microservice/adapter/controller/neighborhoods.controller.ts b/src/microservice/adapter/controller/neighborhoods.controller.ts index 611c533..f71d23f 100644 --- a/src/microservice/adapter/controller/neighborhoods.controller.ts +++ b/src/microservice/adapter/controller/neighborhoods.controller.ts @@ -3,7 +3,7 @@ import { GetNeighborhoodsByStateService } from '../../domain/service/neighborhoo import { NestResponse } from '../../../core/http/nest-response'; import { AbstractController } from '../../domain/controller/abstract-controller'; import { GetNeighborhoodsByCityService } from '../../domain/service/neighborhoods/get/get-neighborhoods-by-city.service'; -import { SearchNeighborhoodsInput } from '../../domain/model/search/search-neighborhoods-input.model'; +import { SearchNeighborhoodsInput } from '../../domain/model/search/neighborhoods/search-neighborhoods-input.model'; import { SeedNeighborhoodsByStateService } from '../../domain/service/neighborhoods/seed/seed-neighborhoods-by-state.service'; @Controller('neighborhoods') diff --git a/src/microservice/adapter/helper/builder/neighborhoods/search-neighborhoods-db.builder.ts b/src/microservice/adapter/helper/builder/neighborhoods/search-neighborhoods-db.builder.ts index 24f9d66..b06c990 100644 --- a/src/microservice/adapter/helper/builder/neighborhoods/search-neighborhoods-db.builder.ts +++ b/src/microservice/adapter/helper/builder/neighborhoods/search-neighborhoods-db.builder.ts @@ -1,5 +1,5 @@ import { ValidOutputSearchNeighborhood } from '../../../../domain/interface/valid-output-search/valid-outpu-search-neighborhood.interface'; -import { SearchNeighborhoodsDB } from '../../../../domain/model/search/search-neighborhoods-db.model'; +import { SearchNeighborhoodsDB } from '../../../../domain/model/search/neighborhoods/search-neighborhoods-db.model'; export class SearchNeighborhoodsDBBuilder { constructor( diff --git a/src/microservice/adapter/repository/neighborhoods/puppeteer/guia-mais.repository.ts b/src/microservice/adapter/repository/neighborhoods/puppeteer/guia-mais.repository.ts index 6aeb5fb..107d0e8 100644 --- a/src/microservice/adapter/repository/neighborhoods/puppeteer/guia-mais.repository.ts +++ b/src/microservice/adapter/repository/neighborhoods/puppeteer/guia-mais.repository.ts @@ -3,7 +3,7 @@ import { ConfigService } from '@nestjs/config'; import { CheerioAPI } from 'cheerio'; import { InjectPage } from 'nest-puppeteer'; import { NeighborhoodByCity } from '../../../../domain/model/neighborhoods/neighborhood-by-city.model'; -import { SearchNeighborhoodsInput } from '../../../../domain/model/search/search-neighborhoods-input.model'; +import { SearchNeighborhoodsInput } from '../../../../domain/model/search/neighborhoods/search-neighborhoods-input.model'; import { IPuppeteerNeighborhoodRepository } from '../../../../domain/interface/puppeteer/repository/puppeteer-neighborhood-repository.interface'; import { PuppeteerNeighborhoodRepository } from '../../../../domain/repository/puppeteer/neighborhood/puppeteer-neighborhood.repository'; import { Page } from '../../../../domain/interface/puppeteer/page.interface'; diff --git a/src/microservice/domain/interface/puppeteer/repository/puppeteer-neighborhood-repository.interface.ts b/src/microservice/domain/interface/puppeteer/repository/puppeteer-neighborhood-repository.interface.ts index 3c59397..bfbff82 100644 --- a/src/microservice/domain/interface/puppeteer/repository/puppeteer-neighborhood-repository.interface.ts +++ b/src/microservice/domain/interface/puppeteer/repository/puppeteer-neighborhood-repository.interface.ts @@ -1,4 +1,4 @@ -import { SearchNeighborhoodsInput } from '../../../model/search/search-neighborhoods-input.model'; +import { SearchNeighborhoodsInput } from '../../../model/search/neighborhoods/search-neighborhoods-input.model'; import { NeighborhoodByCity } from '../../../model/neighborhoods/neighborhood-by-city.model'; import { IPuppeteerRepository } from './puppeteer-repository.interface'; import { EnumTranslations } from 'src/microservice/domain/enumerators/enum-translations.enumerator'; diff --git a/src/microservice/domain/model/search/search-cities-db.model.ts b/src/microservice/domain/model/search/cities/search-cities-db.model.ts similarity index 100% rename from src/microservice/domain/model/search/search-cities-db.model.ts rename to src/microservice/domain/model/search/cities/search-cities-db.model.ts diff --git a/src/microservice/domain/model/search/cities/search-cities-input.model.ts b/src/microservice/domain/model/search/cities/search-cities-input.model.ts new file mode 100644 index 0000000..e3101d9 --- /dev/null +++ b/src/microservice/domain/model/search/cities/search-cities-input.model.ts @@ -0,0 +1,3 @@ +export class SearchCitiesInput { + constructor(public country: string, public state: string) {} +} diff --git a/src/microservice/domain/model/search/search-neighborhoods-db.model.ts b/src/microservice/domain/model/search/neighborhoods/search-neighborhoods-db.model.ts similarity index 100% rename from src/microservice/domain/model/search/search-neighborhoods-db.model.ts rename to src/microservice/domain/model/search/neighborhoods/search-neighborhoods-db.model.ts diff --git a/src/microservice/domain/model/search/search-neighborhoods-input.model.ts b/src/microservice/domain/model/search/neighborhoods/search-neighborhoods-input.model.ts similarity index 100% rename from src/microservice/domain/model/search/search-neighborhoods-input.model.ts rename to src/microservice/domain/model/search/neighborhoods/search-neighborhoods-input.model.ts diff --git a/src/microservice/domain/repository/puppeteer/neighborhood/puppeteer-neighborhood.repository.ts b/src/microservice/domain/repository/puppeteer/neighborhood/puppeteer-neighborhood.repository.ts index b955114..077f58d 100644 --- a/src/microservice/domain/repository/puppeteer/neighborhood/puppeteer-neighborhood.repository.ts +++ b/src/microservice/domain/repository/puppeteer/neighborhood/puppeteer-neighborhood.repository.ts @@ -1,6 +1,6 @@ import { CheerioAPI } from 'cheerio'; import { NeighborhoodByCity } from '../../../model/neighborhoods/neighborhood-by-city.model'; -import { SearchNeighborhoodsInput } from '../../../model/search/search-neighborhoods-input.model'; +import { SearchNeighborhoodsInput } from '../../../model/search/neighborhoods/search-neighborhoods-input.model'; import { PuppeteerRepository } from '../puppeteer.repository'; import { IPuppeteerNeighborhoodRepository } from '../../../interface/puppeteer/repository/puppeteer-neighborhood-repository.interface'; import { NotFoundException } from '../../../../../core/error-handling/exception/not-found.exception'; diff --git a/src/microservice/domain/repository/puppeteer/puppeteer.repository.ts b/src/microservice/domain/repository/puppeteer/puppeteer.repository.ts index dcd55d9..6fe3b47 100644 --- a/src/microservice/domain/repository/puppeteer/puppeteer.repository.ts +++ b/src/microservice/domain/repository/puppeteer/puppeteer.repository.ts @@ -2,7 +2,7 @@ import { Logger } from '@nestjs/common'; import * as cheerio from 'cheerio'; import { CheerioAPI } from 'cheerio'; import { Page } from '../../interface/puppeteer/page.interface'; -import { SearchNeighborhoodsInput } from '../../model/search/search-neighborhoods-input.model'; +import { SearchNeighborhoodsInput } from '../../model/search/neighborhoods/search-neighborhoods-input.model'; export abstract class PuppeteerRepository { protected readonly logger: Logger = new Logger(this.constructor.name); diff --git a/src/microservice/domain/service/cities/get-cities-by-state.service.ts b/src/microservice/domain/service/cities/get-cities-by-state.service.ts index ef95bd9..030cce1 100644 --- a/src/microservice/domain/service/cities/get-cities-by-state.service.ts +++ b/src/microservice/domain/service/cities/get-cities-by-state.service.ts @@ -1,20 +1,33 @@ import { Injectable } from '@nestjs/common'; -import { NeighborhoodsMongoose } from '../../../adapter/repository/neighborhoods/neighborhoods-mongoose.repository'; import { CitiesMongoose } from '../../../adapter/repository/cities/cities-mongoose.repository'; -import { SearchCitiesDB } from '../../model/search/search-cities-db.model'; +import { SearchCitiesDB } from '../../model/search/cities/search-cities-db.model'; +import { SearchCitiesInput } from '../../model/search/cities/search-cities-input.model'; import { City } from '../../schemas/city.schema'; +import { ValidateInputParamsService } from '../validate-input-params.service'; import { CitiesService } from './cities.service'; @Injectable() export class GetCitiesByStateService extends CitiesService { constructor( mongoRepository: CitiesMongoose, - private readonly mongoNeighborhoodsRepository: NeighborhoodsMongoose + protected readonly validateService: ValidateInputParamsService ) { super(mongoRepository); } - async getCitiesByState( + async getCitiesByState(searchParams: SearchCitiesInput): Promise { + const convertedSearch = + await this.validateService.validateAndConvertSearchByState(searchParams); + + const searchDB = new SearchCitiesDB( + convertedSearch.country.id, + convertedSearch.state.id + ); + + return this.findCitiesByState(searchDB); + } + + async findCitiesByState( searchParams: SearchCitiesDB, arrIgnore = [] ): Promise { diff --git a/src/microservice/domain/service/neighborhoods/get/get-neighborhoods-by-city.service.ts b/src/microservice/domain/service/neighborhoods/get/get-neighborhoods-by-city.service.ts index b09a0ed..80729dd 100644 --- a/src/microservice/domain/service/neighborhoods/get/get-neighborhoods-by-city.service.ts +++ b/src/microservice/domain/service/neighborhoods/get/get-neighborhoods-by-city.service.ts @@ -1,11 +1,11 @@ import { Inject, Injectable } from '@nestjs/common'; import { NeighborhoodByCity } from '../../../model/neighborhoods/neighborhood-by-city.model'; -import { SearchNeighborhoodsInput } from '../../../model/search/search-neighborhoods-input.model'; +import { SearchNeighborhoodsInput } from '../../../model/search/neighborhoods/search-neighborhoods-input.model'; import { NeighborhoodsMongoose } from '../../../../adapter/repository/neighborhoods/neighborhoods-mongoose.repository'; import { GuiaMaisRepository } from '../../../../adapter/repository/neighborhoods/puppeteer/guia-mais.repository'; import { SaveNeighborhoodsByCityService } from '../save-neighborhoods-by-city.service'; import { ValidOutputSearchNeighborhood } from '../../../interface/valid-output-search/valid-outpu-search-neighborhood.interface'; -import { SearchNeighborhoodsDB } from '../../../model/search/search-neighborhoods-db.model'; +import { SearchNeighborhoodsDB } from '../../../model/search/neighborhoods/search-neighborhoods-db.model'; import { NeighborhoodsService } from '../neighborhoods.service'; import { ValidateInputParamsService } from '../../validate-input-params.service'; diff --git a/src/microservice/domain/service/neighborhoods/get/get-neighborhoods-by-state.service.ts b/src/microservice/domain/service/neighborhoods/get/get-neighborhoods-by-state.service.ts index 068ac33..4abd764 100644 --- a/src/microservice/domain/service/neighborhoods/get/get-neighborhoods-by-state.service.ts +++ b/src/microservice/domain/service/neighborhoods/get/get-neighborhoods-by-state.service.ts @@ -1,8 +1,8 @@ import { Injectable } from '@nestjs/common'; -import { SearchNeighborhoodsInput } from '../../../model/search/search-neighborhoods-input.model'; +import { SearchNeighborhoodsInput } from '../../../model/search/neighborhoods/search-neighborhoods-input.model'; import { NeighborhoodsMongoose } from '../../../../adapter/repository/neighborhoods/neighborhoods-mongoose.repository'; import { ValidOutputSearchNeighborhood } from '../../../interface/valid-output-search/valid-outpu-search-neighborhood.interface'; -import { SearchNeighborhoodsDB } from '../../../model/search/search-neighborhoods-db.model'; +import { SearchNeighborhoodsDB } from '../../../model/search/neighborhoods/search-neighborhoods-db.model'; import { NeighborhoodsByState, NeighborhooodAggregatedByCity diff --git a/src/microservice/domain/service/neighborhoods/neighborhoods.service.ts b/src/microservice/domain/service/neighborhoods/neighborhoods.service.ts index be4a66a..fa2f97d 100644 --- a/src/microservice/domain/service/neighborhoods/neighborhoods.service.ts +++ b/src/microservice/domain/service/neighborhoods/neighborhoods.service.ts @@ -1,7 +1,7 @@ import { NeighborhoodsPuppeteerBuilder } from '../../../adapter/helper/builder/neighborhoods/neighborhoods-puppeteer.builder'; import { NeighborhoodsMongoose } from '../../../adapter/repository/neighborhoods/neighborhoods-mongoose.repository'; import { NeighborhoodByCity } from '../../model/neighborhoods/neighborhood-by-city.model'; -import { SearchNeighborhoodsDB } from '../../model/search/search-neighborhoods-db.model'; +import { SearchNeighborhoodsDB } from '../../model/search/neighborhoods/search-neighborhoods-db.model'; import { AbstractService } from '../abstract-service.service'; export abstract class NeighborhoodsService extends AbstractService { diff --git a/src/microservice/domain/service/neighborhoods/save-neighborhoods-by-city.service.ts b/src/microservice/domain/service/neighborhoods/save-neighborhoods-by-city.service.ts index 7d146f1..301a592 100644 --- a/src/microservice/domain/service/neighborhoods/save-neighborhoods-by-city.service.ts +++ b/src/microservice/domain/service/neighborhoods/save-neighborhoods-by-city.service.ts @@ -2,7 +2,7 @@ import { Injectable } from '@nestjs/common'; import { NeighborhoodByCity } from '../../model/neighborhoods/neighborhood-by-city.model'; import { NeighborhoodsMongoose } from '../../../adapter/repository/neighborhoods/neighborhoods-mongoose.repository'; import { NeighborhoodsMongoBuilder } from '../../../adapter/helper/builder/neighborhoods/neighborhoods-mongo.builder'; -import { SearchNeighborhoodsInput } from '../../model/search/search-neighborhoods-input.model'; +import { SearchNeighborhoodsInput } from '../../model/search/neighborhoods/search-neighborhoods-input.model'; import { NeighborhoodsService } from './neighborhoods.service'; import { ValidOutputSearchNeighborhood } from '../../interface/valid-output-search/valid-outpu-search-neighborhood.interface'; import { Neighborhood } from '../../schemas/neighborhood.schema'; diff --git a/src/microservice/domain/service/neighborhoods/seed/seed-neighborhoods-by-state.service.ts b/src/microservice/domain/service/neighborhoods/seed/seed-neighborhoods-by-state.service.ts index e68cd44..57da1c4 100644 --- a/src/microservice/domain/service/neighborhoods/seed/seed-neighborhoods-by-state.service.ts +++ b/src/microservice/domain/service/neighborhoods/seed/seed-neighborhoods-by-state.service.ts @@ -1,9 +1,9 @@ import { Injectable } from '@nestjs/common'; -import { SearchNeighborhoodsInput } from '../../../model/search/search-neighborhoods-input.model'; +import { SearchNeighborhoodsInput } from '../../../model/search/neighborhoods/search-neighborhoods-input.model'; import { NeighborhoodsService } from '../neighborhoods.service'; import { ValidateInputParamsService } from '../../validate-input-params.service'; import { GetCitiesByStateService } from '../../cities/get-cities-by-state.service'; -import { SearchCitiesDB } from '../../../model/search/search-cities-db.model'; +import { SearchCitiesDB } from '../../../model/search/cities/search-cities-db.model'; import { GetNeighborhoodsByCityService } from '../get/get-neighborhoods-by-city.service'; import { ValidOutputSearchNeighborhood } from '../../../interface/valid-output-search/valid-outpu-search-neighborhood.interface'; import { EnumTranslations } from '../../../enumerators/enum-translations.enumerator'; @@ -42,7 +42,7 @@ export class SeedNeighborhoodsByStateService extends NeighborhoodsService { ); this.logger.log(`Getting cities for state '${searchParams.state}'...`); - const cities = await this.getCitiesByStateService.getCitiesByState( + const cities = await this.getCitiesByStateService.findCitiesByState( searchCities, arrSeededCities ); diff --git a/src/microservice/domain/service/validate-input-params.service.ts b/src/microservice/domain/service/validate-input-params.service.ts index 9633e19..cf04127 100644 --- a/src/microservice/domain/service/validate-input-params.service.ts +++ b/src/microservice/domain/service/validate-input-params.service.ts @@ -1,10 +1,11 @@ import { Injectable } from '@nestjs/common'; -import { SearchNeighborhoodsInput } from '../model/search/search-neighborhoods-input.model'; +import { SearchNeighborhoodsInput } from '../model/search/neighborhoods/search-neighborhoods-input.model'; import { ValidOutputSearchNeighborhood } from '../interface/valid-output-search/valid-outpu-search-neighborhood.interface'; import { AbstractService } from './abstract-service.service'; import { ValidateCountryByNameOrAliasService } from './countries/validate-country-by-name-or-alias.service'; import { ValidateStateByNameOrAliasService } from './states/validate-state-by-name-or-alias.service'; import { ValidateCityByNameOrAliasService } from './cities/validate-city-by-name-or-alias.service'; +import { SearchCitiesInput } from '../model/search/cities/search-cities-input.model'; @Injectable() export class ValidateInputParamsService extends AbstractService { @@ -17,7 +18,7 @@ export class ValidateInputParamsService extends AbstractService { } async validateAndConvertSearchByState( - searchParams: SearchNeighborhoodsInput + searchParams: SearchNeighborhoodsInput | SearchCitiesInput ): Promise { const country = await this.getCountryService.validateCountry( searchParams.country diff --git a/test/unit/microservice/adapter/repository/neighborhoods/neighborhoods-mongoose.repository.spec.ts b/test/unit/microservice/adapter/repository/neighborhoods/neighborhoods-mongoose.repository.spec.ts index 7888d00..0a506a8 100644 --- a/test/unit/microservice/adapter/repository/neighborhoods/neighborhoods-mongoose.repository.spec.ts +++ b/test/unit/microservice/adapter/repository/neighborhoods/neighborhoods-mongoose.repository.spec.ts @@ -7,7 +7,7 @@ import { getModelToken } from '@nestjs/mongoose'; import { Neighborhood } from '../../../../../../src/microservice/domain/schemas/neighborhood.schema'; import { mockModelMongoose } from '../../../../../mock/mongoose/mock-mongoose'; import { MongoDBException } from '../../../../../../src/core/error-handling/exception/mongodb-.exception'; -import { SearchNeighborhoodsDB } from '../../../../../../src/microservice/domain/model/search/search-neighborhoods-db.model'; +import { SearchNeighborhoodsDB } from '../../../../../../src/microservice/domain/model/search/neighborhoods/search-neighborhoods-db.model'; jest.useFakeTimers(); jest.setTimeout(20000); diff --git a/test/unit/microservice/domain/model/search/search-neighborhoods-input.model.spec.ts b/test/unit/microservice/domain/model/search/neighborhoods/search-neighborhoods-input.model.spec.ts similarity index 83% rename from test/unit/microservice/domain/model/search/search-neighborhoods-input.model.spec.ts rename to test/unit/microservice/domain/model/search/neighborhoods/search-neighborhoods-input.model.spec.ts index f95fb4a..2e16c4f 100644 --- a/test/unit/microservice/domain/model/search/search-neighborhoods-input.model.spec.ts +++ b/test/unit/microservice/domain/model/search/neighborhoods/search-neighborhoods-input.model.spec.ts @@ -1,5 +1,5 @@ import { expect } from 'chai'; -import { SearchNeighborhoodsInput } from '../../../../../../src/microservice/domain/model/search/search-neighborhoods-input.model'; +import { SearchNeighborhoodsInput } from '../../../../../../../src/microservice/domain/model/search/neighborhoods/search-neighborhoods-input.model'; describe('SearchNeighborhoodsInput', () => { it('should instance SearchNeighborhoodsInput and return the object with the correct properties', async () => { diff --git a/test/unit/microservice/domain/service/cities/get-cities-by-state.service.spec.ts b/test/unit/microservice/domain/service/cities/get-cities-by-state.service.spec.ts index 95f0a17..2a07e81 100644 --- a/test/unit/microservice/domain/service/cities/get-cities-by-state.service.spec.ts +++ b/test/unit/microservice/domain/service/cities/get-cities-by-state.service.spec.ts @@ -6,7 +6,7 @@ import '../../../../../../src/microservice/adapter/helper/extensions/exensions.m import { ValidateInputParamsService } from '../../../../../../src/microservice/domain/service/validate-input-params.service'; import { City } from '../../../../../../src/microservice/domain/schemas/city.schema'; import { GetCitiesByStateService } from '../../../../../../src/microservice/domain/service/cities/get-cities-by-state.service'; -import { SearchCitiesDB } from '../../../../../../src/microservice/domain/model/search/search-cities-db.model'; +import { SearchCitiesDB } from '../../../../../../src/microservice/domain/model/search/cities/search-cities-db.model'; import { CitiesMongoose } from '../../../../../../src/microservice/adapter/repository/cities/cities-mongoose.repository'; describe('GetCitiesByStateService', () => { @@ -74,8 +74,8 @@ describe('GetCitiesByStateService', () => { sut = app.get(GetCitiesByStateService); }); - describe('getCitiesByState', () => { - it('should call getCitiesByState and return an array by puppeteer', async () => { + describe('findCitiesByState', () => { + it('should call findCitiesByState and return an array by puppeteer', async () => { const arrMockCities = mockCities(); const groupByStub = sinon .stub(mockCitiesMongooseRepository, 'findBySearchParams') @@ -85,7 +85,7 @@ describe('GetCitiesByStateService', () => { const arrIgnore = [3, 4, 5]; - const actual = await sut.getCitiesByState(searchParams, arrIgnore); + const actual = await sut.findCitiesByState(searchParams, arrIgnore); expect(actual).to.be.equal(arrMockCities); @@ -93,8 +93,8 @@ describe('GetCitiesByStateService', () => { }); }); - describe('getCitiesByState', () => { - it('should call getCitiesByState and return an array by puppeteer', async () => { + describe('findCitiesByState', () => { + it('should call findCitiesByState and return an array by puppeteer', async () => { const arrMockCities = mockCities(); const groupByStub = sinon .stub(mockCitiesMongooseRepository, 'findBySearchParams') @@ -102,7 +102,7 @@ describe('GetCitiesByStateService', () => { const searchParams = new SearchCitiesDB(1, 2); - const actual = await sut.getCitiesByState(searchParams); + const actual = await sut.findCitiesByState(searchParams); expect(actual).to.be.equal(arrMockCities); diff --git a/test/unit/microservice/domain/service/neighborhoods/save-neighborhoods-by-city.service.spec.ts b/test/unit/microservice/domain/service/neighborhoods/save-neighborhoods-by-city.service.spec.ts index a640f80..ed69bf9 100644 --- a/test/unit/microservice/domain/service/neighborhoods/save-neighborhoods-by-city.service.spec.ts +++ b/test/unit/microservice/domain/service/neighborhoods/save-neighborhoods-by-city.service.spec.ts @@ -9,7 +9,7 @@ import { Neighborhood } from '../../../../../../src/microservice/domain/schemas/ import { Country } from '../../../../../../src/microservice/domain/schemas/country.schema'; import { State } from '../../../../../../src/microservice/domain/schemas/state.schema'; import { City } from '../../../../../../src/microservice/domain/schemas/city.schema'; -import { SearchNeighborhoodsDB } from '../../../../../../src/microservice/domain/model/search/search-neighborhoods-db.model'; +import { SearchNeighborhoodsDB } from '../../../../../../src/microservice/domain/model/search/neighborhoods/search-neighborhoods-db.model'; describe('SaveNeighborhoodsByCityService', () => { let sut: SaveNeighborhoodsByCityService; diff --git a/test/unit/microservice/domain/service/neighborhoods/seed/seed-neighborhoods-by-state.service.spec.ts b/test/unit/microservice/domain/service/neighborhoods/seed/seed-neighborhoods-by-state.service.spec.ts index 679c7fa..192a069 100644 --- a/test/unit/microservice/domain/service/neighborhoods/seed/seed-neighborhoods-by-state.service.spec.ts +++ b/test/unit/microservice/domain/service/neighborhoods/seed/seed-neighborhoods-by-state.service.spec.ts @@ -21,7 +21,7 @@ describe('SeedNeighborhoodsByStateService', () => { let sut: SeedNeighborhoodsByStateService; const mockGetCitiesByStateService = { - getCitiesByState: () => { + findCitiesByState: () => { return; } }; @@ -150,7 +150,7 @@ describe('SeedNeighborhoodsByStateService', () => { .returns(mockConvertedSearch()); const getCitiesByStateStub = sinon - .stub(mockGetCitiesByStateService, 'getCitiesByState') + .stub(mockGetCitiesByStateService, 'findCitiesByState') .returns(mockCities()); const searchParams = new SearchNeighborhoodsInput('brasil', 'sc'); @@ -175,7 +175,7 @@ describe('SeedNeighborhoodsByStateService', () => { .returns(mockConvertedSearch()); const getCitiesByStateStub = sinon - .stub(mockGetCitiesByStateService, 'getCitiesByState') + .stub(mockGetCitiesByStateService, 'findCitiesByState') .returns([]); const searchParams = new SearchNeighborhoodsInput('brasil', 'sc'); @@ -200,7 +200,7 @@ describe('SeedNeighborhoodsByStateService', () => { .returns(mockConvertedSearch()); const getCitiesByStateStub = sinon - .stub(mockGetCitiesByStateService, 'getCitiesByState') + .stub(mockGetCitiesByStateService, 'findCitiesByState') .returns(mockCities()); const mockError = new NotFoundException('Neighborhoods'); From d7aed4975ca18432594d99744f60fe11b3847ed3 Mon Sep 17 00:00:00 2001 From: Maick Speck Date: Sun, 26 Jun 2022 20:40:38 -0300 Subject: [PATCH 05/39] get Cities by state --- .../repository/mongoose/places-mongoose.repository.ts | 8 ++++++-- .../service/cities/get-cities-by-state.service.ts | 11 ++++++++++- 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/src/microservice/domain/repository/mongoose/places-mongoose.repository.ts b/src/microservice/domain/repository/mongoose/places-mongoose.repository.ts index 914f1af..fa40779 100644 --- a/src/microservice/domain/repository/mongoose/places-mongoose.repository.ts +++ b/src/microservice/domain/repository/mongoose/places-mongoose.repository.ts @@ -21,10 +21,14 @@ export abstract class PlacesMongooseRepository< .exec(); } - async findBySearchParams(searchParams: object): Promise { + async findBySearchParams( + searchParams: object, + select: object = {} + ): Promise { + if (Object.keys(select).length == 0) select = { _id: 0 }; return this.model .find(this.buildRegexFilterQuery(searchParams)) - .select({ _id: 0 }) + .select(select) .lean() .exec(); } diff --git a/src/microservice/domain/service/cities/get-cities-by-state.service.ts b/src/microservice/domain/service/cities/get-cities-by-state.service.ts index 030cce1..c8efc33 100644 --- a/src/microservice/domain/service/cities/get-cities-by-state.service.ts +++ b/src/microservice/domain/service/cities/get-cities-by-state.service.ts @@ -32,6 +32,15 @@ export class GetCitiesByStateService extends CitiesService { arrIgnore = [] ): Promise { if (arrIgnore.length > 0) searchParams.id = { $nin: arrIgnore }; - return this.mongoRepository.findBySearchParams(searchParams); + const select = { + _id: 0, + id: 1, + name: 1, + countryId: 1, + countryCode: 1, + stateId: 1, + stateCode: 1 + }; + return this.mongoRepository.findBySearchParams(searchParams, select); } } From 1c3a81b91cf52c3cb6606c9b331cdfb48aa66c0a Mon Sep 17 00:00:00 2001 From: Maick Speck Date: Sun, 26 Jun 2022 20:59:42 -0300 Subject: [PATCH 06/39] change model by city --- .../neighborhoods/neighborhoods-puppeteer.builder.ts | 5 ++++- .../neighborhoods/puppeteer/guia-mais.repository.ts | 10 +++++++++- .../puppeteer-neighborhood-repository.interface.ts | 10 ++++++++-- .../repository/puppeteer-repository.interface.ts | 7 ++++++- .../model/neighborhoods/neighborhood-by-city.model.ts | 3 +++ .../neighborhood/puppeteer-neighborhood.repository.ts | 11 +++++++++-- .../get/get-neighborhoods-by-city.service.ts | 3 ++- 7 files changed, 41 insertions(+), 8 deletions(-) diff --git a/src/microservice/adapter/helper/builder/neighborhoods/neighborhoods-puppeteer.builder.ts b/src/microservice/adapter/helper/builder/neighborhoods/neighborhoods-puppeteer.builder.ts index 73533c8..27a15dd 100644 --- a/src/microservice/adapter/helper/builder/neighborhoods/neighborhoods-puppeteer.builder.ts +++ b/src/microservice/adapter/helper/builder/neighborhoods/neighborhoods-puppeteer.builder.ts @@ -8,8 +8,11 @@ export class NeighborhoodsPuppeteerBuilder { const arr = []; this.mongoResponse.forEach((document) => { const obj = new NeighborhoodByCity(); - obj.city = `${document.city.capitalize()} - ${document.state.toUpperCase()}`; obj.name = document.name; + obj.cityId = document.cityId; + obj.city = `${document.city.capitalize()} - ${document.state.toUpperCase()}`; + obj.stateId = document.stateId; + obj.countryId = document.countryId; arr.push(obj); }); return arr; diff --git a/src/microservice/adapter/repository/neighborhoods/puppeteer/guia-mais.repository.ts b/src/microservice/adapter/repository/neighborhoods/puppeteer/guia-mais.repository.ts index 107d0e8..38c00aa 100644 --- a/src/microservice/adapter/repository/neighborhoods/puppeteer/guia-mais.repository.ts +++ b/src/microservice/adapter/repository/neighborhoods/puppeteer/guia-mais.repository.ts @@ -8,6 +8,7 @@ import { IPuppeteerNeighborhoodRepository } from '../../../../domain/interface/p import { PuppeteerNeighborhoodRepository } from '../../../../domain/repository/puppeteer/neighborhood/puppeteer-neighborhood.repository'; import { Page } from '../../../../domain/interface/puppeteer/page.interface'; import { EnumTranslations } from '../../../../domain/enumerators/enum-translations.enumerator'; +import { ValidOutputSearchNeighborhood } from '../../../../domain/interface/valid-output-search/valid-outpu-search-neighborhood.interface'; @Injectable() export class GuiaMaisRepository @@ -25,7 +26,11 @@ export class GuiaMaisRepository ); } - buildElementsFromDocument(searchParams, $: CheerioAPI): NeighborhoodByCity[] { + buildElementsFromDocument( + searchParams, + convertedSearch: ValidOutputSearchNeighborhood, + $: CheerioAPI + ): NeighborhoodByCity[] { const arrNeighborhoods = []; $('.cities.centerContent') .find('a') @@ -33,7 +38,10 @@ export class GuiaMaisRepository const neighborhood = new NeighborhoodByCity(); neighborhood.name = $(this).text(); + neighborhood.cityId = convertedSearch.city.id; neighborhood.city = `${searchParams.city.capitalize()} - ${searchParams.state.toUpperCase()}`; + neighborhood.stateId = convertedSearch.state.id; + neighborhood.countryId = convertedSearch.country.id; arrNeighborhoods.push(neighborhood); }); diff --git a/src/microservice/domain/interface/puppeteer/repository/puppeteer-neighborhood-repository.interface.ts b/src/microservice/domain/interface/puppeteer/repository/puppeteer-neighborhood-repository.interface.ts index bfbff82..662e875 100644 --- a/src/microservice/domain/interface/puppeteer/repository/puppeteer-neighborhood-repository.interface.ts +++ b/src/microservice/domain/interface/puppeteer/repository/puppeteer-neighborhood-repository.interface.ts @@ -2,11 +2,17 @@ import { SearchNeighborhoodsInput } from '../../../model/search/neighborhoods/se import { NeighborhoodByCity } from '../../../model/neighborhoods/neighborhood-by-city.model'; import { IPuppeteerRepository } from './puppeteer-repository.interface'; import { EnumTranslations } from 'src/microservice/domain/enumerators/enum-translations.enumerator'; +import { ValidOutputSearchNeighborhood } from '../../valid-output-search/valid-outpu-search-neighborhood.interface'; export interface IPuppeteerNeighborhoodRepository - extends IPuppeteerRepository { + extends IPuppeteerRepository< + NeighborhoodByCity, + SearchNeighborhoodsInput, + ValidOutputSearchNeighborhood + > { language: EnumTranslations; getNeighborhoodsByCity( - searchParams: SearchNeighborhoodsInput + searchParams: SearchNeighborhoodsInput, + convertedSearch: ValidOutputSearchNeighborhood ): Promise; } diff --git a/src/microservice/domain/interface/puppeteer/repository/puppeteer-repository.interface.ts b/src/microservice/domain/interface/puppeteer/repository/puppeteer-repository.interface.ts index 49a40bd..9ac7645 100644 --- a/src/microservice/domain/interface/puppeteer/repository/puppeteer-repository.interface.ts +++ b/src/microservice/domain/interface/puppeteer/repository/puppeteer-repository.interface.ts @@ -1,6 +1,10 @@ import { CheerioAPI } from 'cheerio'; -export interface IPuppeteerRepository { +export interface IPuppeteerRepository< + ElementPlace, + SearchElement, + ValidOutputSearch +> { callEndpoint(searchParams: SearchElement): Promise; getDocumentHtml(url: string): Promise; @@ -11,6 +15,7 @@ export interface IPuppeteerRepository { buildElementsFromDocument( searchParams: SearchElement, + convertedSearch: ValidOutputSearch, $: CheerioAPI ): ElementPlace[]; diff --git a/src/microservice/domain/model/neighborhoods/neighborhood-by-city.model.ts b/src/microservice/domain/model/neighborhoods/neighborhood-by-city.model.ts index 260bde8..c88a40e 100644 --- a/src/microservice/domain/model/neighborhoods/neighborhood-by-city.model.ts +++ b/src/microservice/domain/model/neighborhoods/neighborhood-by-city.model.ts @@ -1,4 +1,7 @@ export class NeighborhoodByCity { name: string; + cityId: number; city: string; + stateId: number; + countryId: number; } diff --git a/src/microservice/domain/repository/puppeteer/neighborhood/puppeteer-neighborhood.repository.ts b/src/microservice/domain/repository/puppeteer/neighborhood/puppeteer-neighborhood.repository.ts index 077f58d..fe7d834 100644 --- a/src/microservice/domain/repository/puppeteer/neighborhood/puppeteer-neighborhood.repository.ts +++ b/src/microservice/domain/repository/puppeteer/neighborhood/puppeteer-neighborhood.repository.ts @@ -5,6 +5,7 @@ import { PuppeteerRepository } from '../puppeteer.repository'; import { IPuppeteerNeighborhoodRepository } from '../../../interface/puppeteer/repository/puppeteer-neighborhood-repository.interface'; import { NotFoundException } from '../../../../../core/error-handling/exception/not-found.exception'; import { EnumTranslations } from 'src/microservice/domain/enumerators/enum-translations.enumerator'; +import { ValidOutputSearchNeighborhood } from 'src/microservice/domain/interface/valid-output-search/valid-outpu-search-neighborhood.interface'; export abstract class PuppeteerNeighborhoodRepository extends PuppeteerRepository @@ -12,12 +13,17 @@ export abstract class PuppeteerNeighborhoodRepository { language: EnumTranslations; async getNeighborhoodsByCity( - searchParams: SearchNeighborhoodsInput + searchParams: SearchNeighborhoodsInput, + convertedSearch: ValidOutputSearchNeighborhood ): Promise { this.validateInput(searchParams); const $ = await this.callEndpoint(searchParams); - const elements = this.buildElementsFromDocument(searchParams, $); + const elements = this.buildElementsFromDocument( + searchParams, + convertedSearch, + $ + ); this.validateOutput(elements); @@ -30,6 +36,7 @@ export abstract class PuppeteerNeighborhoodRepository abstract buildElementsFromDocument( _searchParams: SearchNeighborhoodsInput, + convertedSearch: ValidOutputSearchNeighborhood, _$: CheerioAPI ); diff --git a/src/microservice/domain/service/neighborhoods/get/get-neighborhoods-by-city.service.ts b/src/microservice/domain/service/neighborhoods/get/get-neighborhoods-by-city.service.ts index 80729dd..8ddefc7 100644 --- a/src/microservice/domain/service/neighborhoods/get/get-neighborhoods-by-city.service.ts +++ b/src/microservice/domain/service/neighborhoods/get/get-neighborhoods-by-city.service.ts @@ -52,7 +52,8 @@ export class GetNeighborhoodsByCityService extends NeighborhoodsService { convertedSearch: ValidOutputSearchNeighborhood ): Promise { const resPuppeteer = await this.guiaMaisRepository.getNeighborhoodsByCity( - searchParams + searchParams, + convertedSearch ); await this.saveNeighborhoodsService.saveNeighborhoodsByCity( From 078ead7660f627ebe39453d87151d9225b36c5ae Mon Sep 17 00:00:00 2001 From: Maick Speck Date: Sun, 26 Jun 2022 21:04:08 -0300 Subject: [PATCH 07/39] searching cities --- .../domain/model/cities/cities-by-state.model.ts | 8 ++++++++ .../domain/service/cities/get-cities-by-state.service.ts | 7 ++++++- 2 files changed, 14 insertions(+), 1 deletion(-) create mode 100644 src/microservice/domain/model/cities/cities-by-state.model.ts diff --git a/src/microservice/domain/model/cities/cities-by-state.model.ts b/src/microservice/domain/model/cities/cities-by-state.model.ts new file mode 100644 index 0000000..530163a --- /dev/null +++ b/src/microservice/domain/model/cities/cities-by-state.model.ts @@ -0,0 +1,8 @@ +export class CitiesByState { + id: number; + name: string; + countryCode: string; + countryId: number; + stateCode: string; + stateId: number; +} diff --git a/src/microservice/domain/service/cities/get-cities-by-state.service.ts b/src/microservice/domain/service/cities/get-cities-by-state.service.ts index c8efc33..6093148 100644 --- a/src/microservice/domain/service/cities/get-cities-by-state.service.ts +++ b/src/microservice/domain/service/cities/get-cities-by-state.service.ts @@ -1,5 +1,6 @@ import { Injectable } from '@nestjs/common'; import { CitiesMongoose } from '../../../adapter/repository/cities/cities-mongoose.repository'; +import { CitiesByState } from '../../model/cities/cities-by-state.model'; import { SearchCitiesDB } from '../../model/search/cities/search-cities-db.model'; import { SearchCitiesInput } from '../../model/search/cities/search-cities-input.model'; import { City } from '../../schemas/city.schema'; @@ -15,7 +16,9 @@ export class GetCitiesByStateService extends CitiesService { super(mongoRepository); } - async getCitiesByState(searchParams: SearchCitiesInput): Promise { + async getCitiesByState( + searchParams: SearchCitiesInput + ): Promise { const convertedSearch = await this.validateService.validateAndConvertSearchByState(searchParams); @@ -24,6 +27,8 @@ export class GetCitiesByStateService extends CitiesService { convertedSearch.state.id ); + this.logger.log('Searching cities in database...'); + return this.findCitiesByState(searchDB); } From 2531ba0354e5f6071fd329ddc6101649fd5860ac Mon Sep 17 00:00:00 2001 From: Maick Speck Date: Mon, 27 Jun 2022 13:04:18 -0300 Subject: [PATCH 08/39] refactor files and tests serch/dir --- .../adapter/controller/cities.controller.ts | 2 +- .../neighborhoods-mongo.builder.ts | 2 +- ...eteer-neighborhood-repository.interface.ts | 2 +- .../puppeteer-neighborhood.repository.ts | 4 +-- .../service/countries/countries.service.ts | 2 +- .../neighborhoods.controller.spec.ts | 12 ++++++--- .../neighborhoods-mongo.builder.spec.ts | 15 ++++++++--- .../neighborhoods-puppeteer.builder.spec.ts | 27 +++++++++++++------ .../extensions/object.extension.spec.ts | 2 +- .../puppeteer/guia-mais.repository.spec.ts | 25 +++++++++++++++-- .../get-neighborhoods-by-city.service.spec.ts | 12 ++++++--- ...get-neighborhoods-by-state.service.spec.ts | 2 +- ...save-neighborhoods-by-city.service.spec.ts | 12 ++++++--- ...eed-neighborhoods-by-state.service.spec.ts | 2 +- .../validate-input-params.service.spec.ts | 2 +- 15 files changed, 90 insertions(+), 33 deletions(-) diff --git a/src/microservice/adapter/controller/cities.controller.ts b/src/microservice/adapter/controller/cities.controller.ts index 30c84cf..79cd82a 100644 --- a/src/microservice/adapter/controller/cities.controller.ts +++ b/src/microservice/adapter/controller/cities.controller.ts @@ -2,7 +2,7 @@ import { Controller, Get, HttpStatus, Param } from '@nestjs/common'; import { NestResponse } from '../../../core/http/nest-response'; import { AbstractController } from '../../domain/controller/abstract-controller'; import { GetCitiesByStateService } from '../../domain/service/cities/get-cities-by-state.service'; -import { SearchCitiesInput } from 'src/microservice/domain/model/search/cities/search-cities-input.model'; +import { SearchCitiesInput } from '../../domain/model/search/cities/search-cities-input.model'; @Controller('cities') export class CitiesController extends AbstractController { diff --git a/src/microservice/adapter/helper/builder/neighborhoods/neighborhoods-mongo.builder.ts b/src/microservice/adapter/helper/builder/neighborhoods/neighborhoods-mongo.builder.ts index 4db3e1a..aa736bd 100644 --- a/src/microservice/adapter/helper/builder/neighborhoods/neighborhoods-mongo.builder.ts +++ b/src/microservice/adapter/helper/builder/neighborhoods/neighborhoods-mongo.builder.ts @@ -1,4 +1,4 @@ -import { ValidOutputSearchNeighborhood } from 'src/microservice/domain/interface/valid-output-search/valid-outpu-search-neighborhood.interface'; +import { ValidOutputSearchNeighborhood } from '../../../../domain/interface/valid-output-search/valid-outpu-search-neighborhood.interface'; import { NeighborhoodByCity } from '../../../../domain/model/neighborhoods/neighborhood-by-city.model'; import { Neighborhood } from '../../../../domain/schemas/neighborhood.schema'; diff --git a/src/microservice/domain/interface/puppeteer/repository/puppeteer-neighborhood-repository.interface.ts b/src/microservice/domain/interface/puppeteer/repository/puppeteer-neighborhood-repository.interface.ts index 662e875..cd0c4e6 100644 --- a/src/microservice/domain/interface/puppeteer/repository/puppeteer-neighborhood-repository.interface.ts +++ b/src/microservice/domain/interface/puppeteer/repository/puppeteer-neighborhood-repository.interface.ts @@ -1,7 +1,7 @@ import { SearchNeighborhoodsInput } from '../../../model/search/neighborhoods/search-neighborhoods-input.model'; import { NeighborhoodByCity } from '../../../model/neighborhoods/neighborhood-by-city.model'; import { IPuppeteerRepository } from './puppeteer-repository.interface'; -import { EnumTranslations } from 'src/microservice/domain/enumerators/enum-translations.enumerator'; +import { EnumTranslations } from '../../../enumerators/enum-translations.enumerator'; import { ValidOutputSearchNeighborhood } from '../../valid-output-search/valid-outpu-search-neighborhood.interface'; export interface IPuppeteerNeighborhoodRepository diff --git a/src/microservice/domain/repository/puppeteer/neighborhood/puppeteer-neighborhood.repository.ts b/src/microservice/domain/repository/puppeteer/neighborhood/puppeteer-neighborhood.repository.ts index fe7d834..83788cc 100644 --- a/src/microservice/domain/repository/puppeteer/neighborhood/puppeteer-neighborhood.repository.ts +++ b/src/microservice/domain/repository/puppeteer/neighborhood/puppeteer-neighborhood.repository.ts @@ -4,8 +4,8 @@ import { SearchNeighborhoodsInput } from '../../../model/search/neighborhoods/se import { PuppeteerRepository } from '../puppeteer.repository'; import { IPuppeteerNeighborhoodRepository } from '../../../interface/puppeteer/repository/puppeteer-neighborhood-repository.interface'; import { NotFoundException } from '../../../../../core/error-handling/exception/not-found.exception'; -import { EnumTranslations } from 'src/microservice/domain/enumerators/enum-translations.enumerator'; -import { ValidOutputSearchNeighborhood } from 'src/microservice/domain/interface/valid-output-search/valid-outpu-search-neighborhood.interface'; +import { EnumTranslations } from '../../../enumerators/enum-translations.enumerator'; +import { ValidOutputSearchNeighborhood } from '../../../interface/valid-output-search/valid-outpu-search-neighborhood.interface'; export abstract class PuppeteerNeighborhoodRepository extends PuppeteerRepository diff --git a/src/microservice/domain/service/countries/countries.service.ts b/src/microservice/domain/service/countries/countries.service.ts index 3bdcb71..ea5abbd 100644 --- a/src/microservice/domain/service/countries/countries.service.ts +++ b/src/microservice/domain/service/countries/countries.service.ts @@ -1,4 +1,4 @@ -import { CountriesMongoose } from 'src/microservice/adapter/repository/countries/countries-mongoose.repository'; +import { CountriesMongoose } from '../../../adapter/repository/countries/countries-mongoose.repository'; import { AbstractService } from '../abstract-service.service'; export abstract class CountriesService extends AbstractService { diff --git a/test/unit/microservice/adapter/controller/neighborhoods.controller.spec.ts b/test/unit/microservice/adapter/controller/neighborhoods.controller.spec.ts index 3b93dce..ab5deac 100644 --- a/test/unit/microservice/adapter/controller/neighborhoods.controller.spec.ts +++ b/test/unit/microservice/adapter/controller/neighborhoods.controller.spec.ts @@ -8,7 +8,7 @@ import { NeighborhoodByCity } from '../../../../../src/microservice/domain/model import { ExtensionsModule } from '../../../../../src/microservice/adapter/helper/extensions/exensions.module'; import { GetNeighborhoodsByCityService } from '../../../../../src/microservice/domain/service/neighborhoods/get/get-neighborhoods-by-city.service'; import { SaveNeighborhoodsByCityService } from '../../../../../src/microservice/domain/service/neighborhoods/save-neighborhoods-by-city.service'; -import { SearchNeighborhoodsInput } from '../../../../../src/microservice/domain/model/search/search-neighborhoods-input.model'; +import { SearchNeighborhoodsInput } from '../../../../../src/microservice/domain/model/search/neighborhoods/search-neighborhoods-input.model'; import { GetNeighborhoodsByStateService } from '../../../../../src/microservice/domain/service/neighborhoods/get/get-neighborhoods-by-state.service'; import { SeedNeighborhoodsByStateService } from '../../../../../src/microservice/domain/service/neighborhoods/seed/seed-neighborhoods-by-state.service'; import { ValidateInputParamsService } from '../../../../../src/microservice/domain/service/validate-input-params.service'; @@ -55,11 +55,17 @@ describe('NeighborhoodsController', () => { const mockNeighborhoods: NeighborhoodByCity[] = [ { name: 'Aires Rodrigues', - city: 'Orleans-SC' + city: 'Orleans - SC', + countryId: 31, + stateId: 2014, + cityId: 1 }, { name: 'Alto Paraná', - city: 'Orleans-SC' + city: 'Orleans - SC', + countryId: 31, + stateId: 2014, + cityId: 2 } ]; diff --git a/test/unit/microservice/adapter/helper/builder/neighborhoods/neighborhoods-mongo.builder.spec.ts b/test/unit/microservice/adapter/helper/builder/neighborhoods/neighborhoods-mongo.builder.spec.ts index ed03916..140320e 100644 --- a/test/unit/microservice/adapter/helper/builder/neighborhoods/neighborhoods-mongo.builder.spec.ts +++ b/test/unit/microservice/adapter/helper/builder/neighborhoods/neighborhoods-mongo.builder.spec.ts @@ -5,15 +5,22 @@ import { Neighborhood } from '../../../../../../../src/microservice/domain/schem import { Country } from '../../../../../../../src/microservice/domain/schemas/country.schema'; import { State } from '../../../../../../../src/microservice/domain/schemas/state.schema'; import { City } from '../../../../../../../src/microservice/domain/schemas/city.schema'; +import { NeighborhoodByCity } from '../../../../../../../src/microservice/domain/model/neighborhoods/neighborhood-by-city.model'; -const mockNeighborhoodsByCity = [ +const mockNeighborhoods: NeighborhoodByCity[] = [ { name: 'Harlem', - city: 'New York City - NY' + city: 'New York City - NY', + countryId: 31, + stateId: 41, + cityId: 3 }, { name: `Hell's Kitchen`, - city: 'New York City - NY' + city: 'New York City - NY', + countryId: 31, + stateId: 41, + cityId: 4 } ]; @@ -53,7 +60,7 @@ const mockConvertedSearch = () => { describe('NeighborhoodsMongoBuilder ', () => { it('Should instanciate NeighborhoodsMongoBuilder and build correctly', function () { - const nestBuilder = new NeighborhoodsMongoBuilder(mockNeighborhoodsByCity); + const nestBuilder = new NeighborhoodsMongoBuilder(mockNeighborhoods); const actual = nestBuilder.build(mockConvertedSearch()); expect(JSON.stringify(actual)).to.be.equal( JSON.stringify(mockMongoNeighborhoods()) diff --git a/test/unit/microservice/adapter/helper/builder/neighborhoods/neighborhoods-puppeteer.builder.spec.ts b/test/unit/microservice/adapter/helper/builder/neighborhoods/neighborhoods-puppeteer.builder.spec.ts index 4461785..87716d4 100644 --- a/test/unit/microservice/adapter/helper/builder/neighborhoods/neighborhoods-puppeteer.builder.spec.ts +++ b/test/unit/microservice/adapter/helper/builder/neighborhoods/neighborhoods-puppeteer.builder.spec.ts @@ -2,15 +2,22 @@ import '../../../../../../../src/microservice/adapter/helper/extensions/exension import { expect } from 'chai'; import { Neighborhood } from '../../../../../../../src/microservice/domain/schemas/neighborhood.schema'; import { NeighborhoodsPuppeteerBuilder } from '../../../../../../../src/microservice/adapter/helper/builder/neighborhoods/neighborhoods-puppeteer.builder'; +import { NeighborhoodByCity } from '../../../../../../../src/microservice/domain/model/neighborhoods/neighborhood-by-city.model'; -const mockNeighborhoodsByCity = [ +const mockNeighborhoods: NeighborhoodByCity[] = [ { + name: 'Harlem', + cityId: 3, city: 'New York City - NY', - name: 'Harlem' + stateId: 41, + countryId: 1 }, { + name: `Hell's Kitchen`, + cityId: 4, city: 'New York City - NY', - name: `Hell's Kitchen` + stateId: 41, + countryId: 1 } ]; @@ -20,6 +27,9 @@ const mockMongoNeighborhoods = () => { item1.country = 'USA'; item1.state = 'NY'; item1.city = 'New York City'; + item1.countryId = 1; + item1.stateId = 41; + item1.cityId = 3; item1.name = 'Harlem'; arr.push(item1); @@ -27,6 +37,9 @@ const mockMongoNeighborhoods = () => { item2.country = 'USA'; item2.state = 'NY'; item2.city = 'New York City'; + item2.countryId = 1; + item2.stateId = 41; + item2.cityId = 4; item2.name = `Hell's Kitchen`; arr.push(item2); @@ -35,12 +48,10 @@ const mockMongoNeighborhoods = () => { describe('NeighborhoodsPuppeteerBuilder ', () => { it('Should instanciate NeighborhoodsPuppeteerBuilder and build correctly', function () { - const nestBuilder = new NeighborhoodsPuppeteerBuilder( - mockMongoNeighborhoods() - ); - const actual = nestBuilder.build(); + const builder = new NeighborhoodsPuppeteerBuilder(mockMongoNeighborhoods()); + const actual = builder.build(); expect(JSON.stringify(actual)).to.be.equal( - JSON.stringify(mockNeighborhoodsByCity) + JSON.stringify(mockNeighborhoods) ); }); }); diff --git a/test/unit/microservice/adapter/helper/extensions/object.extension.spec.ts b/test/unit/microservice/adapter/helper/extensions/object.extension.spec.ts index 101ca95..961efc6 100644 --- a/test/unit/microservice/adapter/helper/extensions/object.extension.spec.ts +++ b/test/unit/microservice/adapter/helper/extensions/object.extension.spec.ts @@ -1,6 +1,6 @@ import '../../../../../../src/microservice/adapter/helper/extensions/exensions.module'; import { expect } from 'chai'; -import { SearchNeighborhoodsInput } from '../../../../../../src/microservice/domain/model/search/search-neighborhoods-input.model'; +import { SearchNeighborhoodsInput } from '../../../../../../src/microservice/domain/model/search/neighborhoods/search-neighborhoods-input.model'; describe('object.extension', () => { describe('getMethods', function () { diff --git a/test/unit/microservice/adapter/repository/neighborhoods/puppeteer/guia-mais.repository.spec.ts b/test/unit/microservice/adapter/repository/neighborhoods/puppeteer/guia-mais.repository.spec.ts index aca4ca6..a030bc4 100644 --- a/test/unit/microservice/adapter/repository/neighborhoods/puppeteer/guia-mais.repository.spec.ts +++ b/test/unit/microservice/adapter/repository/neighborhoods/puppeteer/guia-mais.repository.spec.ts @@ -4,10 +4,13 @@ import { expect } from 'chai'; import * as sinon from 'sinon'; import { GuiaMaisRepository } from '../../../../../../../src/microservice/adapter/repository/neighborhoods/puppeteer/guia-mais.repository'; import { PuppeteerModule } from 'nest-puppeteer'; -import { SearchNeighborhoodsInput } from '../../../../../../../src/microservice/domain/model/search/search-neighborhoods-input.model'; +import { SearchNeighborhoodsInput } from '../../../../../../../src/microservice/domain/model/search/neighborhoods/search-neighborhoods-input.model'; import * as fs from 'fs'; import { ExtensionsModule } from '../../../../../../../src/microservice/adapter/helper/extensions/exensions.module'; import * as cheerio from 'cheerio'; +import { Country } from '../../../../../../../src/microservice/domain/schemas/country.schema'; +import { State } from '../../../../../../../src/microservice/domain/schemas/state.schema'; +import { City } from '../../../../../../../src/microservice/domain/schemas/city.schema'; jest.useFakeTimers(); jest.setTimeout(50000); @@ -24,6 +27,21 @@ describe('GuiaMaisRepository', () => { } ); + const mockConvertedSearch = () => { + const mockCountry = new Country(); + mockCountry.name = 'USA'; + const mockState = new State(); + mockState.name = 'New York'; + mockState.stateCode = 'NY'; + const mockCity = new City(); + mockCity.name = 'New York City'; + return { + country: mockCountry, + state: mockState, + city: mockCity + }; + }; + beforeEach(async () => { app = await Test.createTestingModule({ imports: [ @@ -64,7 +82,10 @@ describe('GuiaMaisRepository', () => { const getDataHtmlStub = sinon.stub(sut, 'getDataHtml').returns(mockHTML); const goToUrlStub = sinon.stub(sut, 'goToUrl').returns(); - const actual = await sut.getNeighborhoodsByCity(mockSearchParams); + const actual = await sut.getNeighborhoodsByCity( + mockSearchParams, + mockConvertedSearch() + ); expect(actual).to.be.an('array').that.is.not.empty; expect(actual[0].city).to.be.equal('Orleans - SC'); diff --git a/test/unit/microservice/domain/service/neighborhoods/get/get-neighborhoods-by-city.service.spec.ts b/test/unit/microservice/domain/service/neighborhoods/get/get-neighborhoods-by-city.service.spec.ts index 58bd3d4..3b86b9c 100644 --- a/test/unit/microservice/domain/service/neighborhoods/get/get-neighborhoods-by-city.service.spec.ts +++ b/test/unit/microservice/domain/service/neighborhoods/get/get-neighborhoods-by-city.service.spec.ts @@ -10,7 +10,7 @@ import '../../../../../../../src/microservice/adapter/helper/extensions/exension import { CountriesMongoose } from '../../../../../../../src/microservice/adapter/repository/countries/countries-mongoose.repository'; import { CitiesMongoose } from '../../../../../../../src/microservice/adapter/repository/cities/cities-mongoose.repository'; import { StatesMongoose } from '../../../../../../../src/microservice/adapter/repository/states/states-mongoose.repository'; -import { SearchNeighborhoodsInput } from '../../../../../../../src/microservice/domain/model/search/search-neighborhoods-input.model'; +import { SearchNeighborhoodsInput } from '../../../../../../../src/microservice/domain/model/search/neighborhoods/search-neighborhoods-input.model'; import { ValidateInputParamsService } from '../../../../../../../src/microservice/domain/service/validate-input-params.service'; import { Country } from '../../../../../../../src/microservice/domain/schemas/country.schema'; import { State } from '../../../../../../../src/microservice/domain/schemas/state.schema'; @@ -65,11 +65,17 @@ describe('GetNeighborhoodsByCityService', () => { const mockNeighborhoods: NeighborhoodByCity[] = [ { name: 'Aires Rodrigues', - city: 'Orleans-SC' + city: 'Orleans - SC', + countryId: 31, + stateId: 2014, + cityId: 1 }, { name: 'Alto Paraná', - city: 'Orleans-SC' + city: 'Orleans - SC', + countryId: 31, + stateId: 2014, + cityId: 2 } ]; diff --git a/test/unit/microservice/domain/service/neighborhoods/get/get-neighborhoods-by-state.service.spec.ts b/test/unit/microservice/domain/service/neighborhoods/get/get-neighborhoods-by-state.service.spec.ts index e20bb7a..22b999e 100644 --- a/test/unit/microservice/domain/service/neighborhoods/get/get-neighborhoods-by-state.service.spec.ts +++ b/test/unit/microservice/domain/service/neighborhoods/get/get-neighborhoods-by-state.service.spec.ts @@ -4,7 +4,7 @@ import * as sinon from 'sinon'; import { NeighborhoodsMongoose } from '../../../../../../../src/microservice/adapter/repository/neighborhoods/neighborhoods-mongoose.repository'; import { Neighborhood } from '../../../../../../../src/microservice/domain/schemas/neighborhood.schema'; import '../../../../../../../src/microservice/adapter/helper/extensions/exensions.module'; -import { SearchNeighborhoodsInput } from '../../../../../../../src/microservice/domain/model/search/search-neighborhoods-input.model'; +import { SearchNeighborhoodsInput } from '../../../../../../../src/microservice/domain/model/search/neighborhoods/search-neighborhoods-input.model'; import { ValidateInputParamsService } from '../../../../../../../src/microservice/domain/service/validate-input-params.service'; import { Country } from '../../../../../../../src/microservice/domain/schemas/country.schema'; import { State } from '../../../../../../../src/microservice/domain/schemas/state.schema'; diff --git a/test/unit/microservice/domain/service/neighborhoods/save-neighborhoods-by-city.service.spec.ts b/test/unit/microservice/domain/service/neighborhoods/save-neighborhoods-by-city.service.spec.ts index ed69bf9..6249dbe 100644 --- a/test/unit/microservice/domain/service/neighborhoods/save-neighborhoods-by-city.service.spec.ts +++ b/test/unit/microservice/domain/service/neighborhoods/save-neighborhoods-by-city.service.spec.ts @@ -3,7 +3,7 @@ import * as sinon from 'sinon'; import { SaveNeighborhoodsByCityService } from '../../../../../../src/microservice/domain/service/neighborhoods/save-neighborhoods-by-city.service'; import { NeighborhoodsMongoose } from '../../../../../../src/microservice/adapter/repository/neighborhoods/neighborhoods-mongoose.repository'; import { ExtensionsModule } from '../../../../../../src/microservice/adapter/helper/extensions/exensions.module'; -import { SearchNeighborhoodsInput } from '../../../../../../src/microservice/domain/model/search/search-neighborhoods-input.model'; +import { SearchNeighborhoodsInput } from '../../../../../../src/microservice/domain/model/search/neighborhoods/search-neighborhoods-input.model'; import { NeighborhoodByCity } from '../../../../../../src/microservice/domain/model/neighborhoods/neighborhood-by-city.model'; import { Neighborhood } from '../../../../../../src/microservice/domain/schemas/neighborhood.schema'; import { Country } from '../../../../../../src/microservice/domain/schemas/country.schema'; @@ -17,11 +17,17 @@ describe('SaveNeighborhoodsByCityService', () => { const mockNeighborhoods: NeighborhoodByCity[] = [ { name: 'Aires Rodrigues', - city: 'Orleans-SC' + city: 'Orleans - SC', + countryId: 31, + stateId: 2014, + cityId: 1 }, { name: 'Alto Paraná', - city: 'Orleans-SC' + city: 'Orleans - SC', + countryId: 31, + stateId: 2014, + cityId: 2 } ]; diff --git a/test/unit/microservice/domain/service/neighborhoods/seed/seed-neighborhoods-by-state.service.spec.ts b/test/unit/microservice/domain/service/neighborhoods/seed/seed-neighborhoods-by-state.service.spec.ts index 192a069..77f6d5f 100644 --- a/test/unit/microservice/domain/service/neighborhoods/seed/seed-neighborhoods-by-state.service.spec.ts +++ b/test/unit/microservice/domain/service/neighborhoods/seed/seed-neighborhoods-by-state.service.spec.ts @@ -3,7 +3,7 @@ import { SeedNeighborhoodsByStateService } from '../../../../../../../src/micros import { expect } from 'chai'; import * as sinon from 'sinon'; import '../../../../../../../src/microservice/adapter/helper/extensions/exensions.module'; -import { SearchNeighborhoodsInput } from '../../../../../../../src/microservice/domain/model/search/search-neighborhoods-input.model'; +import { SearchNeighborhoodsInput } from '../../../../../../../src/microservice/domain/model/search/neighborhoods/search-neighborhoods-input.model'; import { Country } from '../../../../../../../src/microservice/domain/schemas/country.schema'; import { City } from '../../../../../../../src/microservice/domain/schemas/city.schema'; import { GetCitiesByStateService } from '../../../../../../../src/microservice/domain/service/cities/get-cities-by-state.service'; diff --git a/test/unit/microservice/domain/service/validate/validate-input-params.service.spec.ts b/test/unit/microservice/domain/service/validate/validate-input-params.service.spec.ts index ac259c1..d3b2f02 100644 --- a/test/unit/microservice/domain/service/validate/validate-input-params.service.spec.ts +++ b/test/unit/microservice/domain/service/validate/validate-input-params.service.spec.ts @@ -9,7 +9,7 @@ import { Country } from '../../../../../../src/microservice/domain/schemas/count import { City } from '../../../../../../src/microservice/domain/schemas/city.schema'; import { ValidateCountryByNameOrAliasService } from '../../../../../../src/microservice/domain/service/countries/validate-country-by-name-or-alias.service'; import { ValidateCityByNameOrAliasService } from '../../../../../../src/microservice/domain/service/cities/validate-city-by-name-or-alias.service'; -import { SearchNeighborhoodsInput } from '../../../../../../src/microservice/domain/model/search/search-neighborhoods-input.model'; +import { SearchNeighborhoodsInput } from '../../../../../../src/microservice/domain/model/search/neighborhoods/search-neighborhoods-input.model'; describe('ValidateInputParamsService', () => { let sut: ValidateInputParamsService; From 904299299faad6c3fa64e507704b49cea51394a8 Mon Sep 17 00:00:00 2001 From: Maick Speck Date: Mon, 27 Jun 2022 13:54:46 -0300 Subject: [PATCH 09/39] cities by country --- src/microservice/adapter/cities.module.ts | 8 ++-- .../adapter/controller/cities.controller.ts | 18 ++++++-- .../neighborhoods-mongo.builder.ts | 4 +- .../search-neighborhoods-db.builder.ts | 6 +-- .../adapter/neighborhoods.module.ts | 4 +- .../puppeteer/guia-mais.repository.ts | 4 +- ...eteer-neighborhood-repository.interface.ts | 6 +-- ...ace.ts => valid-outpu-search.interface.ts} | 7 ++- .../model/cities/cities-by-country.model.ts | 8 ++++ .../search/cities/search-cities-db.model.ts | 2 +- .../puppeteer-neighborhood.repository.ts | 6 +-- .../get/get-cities-by-country.service.ts | 46 +++++++++++++++++++ .../{ => get}/get-cities-by-state.service.ts | 14 +++--- .../get/get-neighborhoods-by-city.service.ts | 8 ++-- .../get/get-neighborhoods-by-state.service.ts | 8 ++-- .../save-neighborhoods-by-city.service.ts | 8 ++-- .../seed-neighborhoods-by-state.service.ts | 17 ++++--- .../validate-input-params.service.ts | 23 ++++++---- .../neighborhoods.controller.spec.ts | 2 +- .../get-cities-by-state.service.spec.ts | 4 +- .../get-neighborhoods-by-city.service.spec.ts | 2 +- ...get-neighborhoods-by-state.service.spec.ts | 2 +- ...eed-neighborhoods-by-state.service.spec.ts | 4 +- .../validate-input-params.service.spec.ts | 2 +- 24 files changed, 145 insertions(+), 68 deletions(-) rename src/microservice/domain/interface/valid-output-search/{valid-outpu-search-neighborhood.interface.ts => valid-outpu-search.interface.ts} (60%) create mode 100644 src/microservice/domain/model/cities/cities-by-country.model.ts create mode 100644 src/microservice/domain/service/cities/get/get-cities-by-country.service.ts rename src/microservice/domain/service/cities/{ => get}/get-cities-by-state.service.ts (64%) rename src/microservice/domain/service/{ => validate}/validate-input-params.service.ts (58%) diff --git a/src/microservice/adapter/cities.module.ts b/src/microservice/adapter/cities.module.ts index 3a636e7..a15693d 100644 --- a/src/microservice/adapter/cities.module.ts +++ b/src/microservice/adapter/cities.module.ts @@ -11,9 +11,10 @@ import { StatesMongoose } from './repository/states/states-mongoose.repository'; import { City, CitySchema } from '../domain/schemas/city.schema'; import { ValidateCityByNameOrAliasService } from '../domain/service/cities/validate-city-by-name-or-alias.service'; import { CitiesMongoose } from './repository/cities/cities-mongoose.repository'; -import { ValidateInputParamsService } from '../domain/service/validate-input-params.service'; -import { GetCitiesByStateService } from '../domain/service/cities/get-cities-by-state.service'; +import { ValidateInputParamsService } from '../domain/service/validate/validate-input-params.service'; +import { GetCitiesByStateService } from '../domain/service/cities/get/get-cities-by-state.service'; import { CitiesController } from './controller/cities.controller'; +import { GetCitiesByCountryService } from '../domain/service/cities/get/get-cities-by-country.service'; @Module({ imports: [ @@ -36,7 +37,8 @@ import { CitiesController } from './controller/cities.controller'; ValidateStateByNameOrAliasService, ValidateCityByNameOrAliasService, ValidateInputParamsService, - GetCitiesByStateService + GetCitiesByStateService, + GetCitiesByCountryService ] }) export class CitiesModule {} diff --git a/src/microservice/adapter/controller/cities.controller.ts b/src/microservice/adapter/controller/cities.controller.ts index 79cd82a..9173860 100644 --- a/src/microservice/adapter/controller/cities.controller.ts +++ b/src/microservice/adapter/controller/cities.controller.ts @@ -1,13 +1,15 @@ import { Controller, Get, HttpStatus, Param } from '@nestjs/common'; import { NestResponse } from '../../../core/http/nest-response'; import { AbstractController } from '../../domain/controller/abstract-controller'; -import { GetCitiesByStateService } from '../../domain/service/cities/get-cities-by-state.service'; +import { GetCitiesByStateService } from '../../domain/service/cities/get/get-cities-by-state.service'; import { SearchCitiesInput } from '../../domain/model/search/cities/search-cities-input.model'; +import { GetCitiesByCountryService } from 'src/microservice/domain/service/cities/get/get-cities-by-country.service'; @Controller('cities') export class CitiesController extends AbstractController { constructor( - private readonly getCitiesByCityService: GetCitiesByStateService + private readonly getCitiesByStateService: GetCitiesByStateService, + private readonly getCitiesByCountryService: GetCitiesByCountryService ) { super(); } @@ -18,7 +20,17 @@ export class CitiesController extends AbstractController { ): Promise { return this.buildResponse( HttpStatus.OK, - await this.getCitiesByCityService.getCitiesByState(params) + await this.getCitiesByStateService.getCitiesByState(params) + ); + } + + @Get('/country/:country') + async getNeighborhoodsByCountry( + @Param() params: SearchCitiesInput + ): Promise { + return this.buildResponse( + HttpStatus.OK, + await this.getCitiesByCountryService.getCitiesByCountry(params) ); } } diff --git a/src/microservice/adapter/helper/builder/neighborhoods/neighborhoods-mongo.builder.ts b/src/microservice/adapter/helper/builder/neighborhoods/neighborhoods-mongo.builder.ts index aa736bd..b2f4ba8 100644 --- a/src/microservice/adapter/helper/builder/neighborhoods/neighborhoods-mongo.builder.ts +++ b/src/microservice/adapter/helper/builder/neighborhoods/neighborhoods-mongo.builder.ts @@ -1,11 +1,11 @@ -import { ValidOutputSearchNeighborhood } from '../../../../domain/interface/valid-output-search/valid-outpu-search-neighborhood.interface'; +import { ValidOutputSearchByCity } from '../../../../domain/interface/valid-output-search/valid-outpu-search.interface'; import { NeighborhoodByCity } from '../../../../domain/model/neighborhoods/neighborhood-by-city.model'; import { Neighborhood } from '../../../../domain/schemas/neighborhood.schema'; export class NeighborhoodsMongoBuilder { constructor(private readonly puppeteerResponse: NeighborhoodByCity[]) {} - build(searchParams: ValidOutputSearchNeighborhood): Neighborhood[] { + build(searchParams: ValidOutputSearchByCity): Neighborhood[] { const arr = []; this.puppeteerResponse.forEach((item) => { diff --git a/src/microservice/adapter/helper/builder/neighborhoods/search-neighborhoods-db.builder.ts b/src/microservice/adapter/helper/builder/neighborhoods/search-neighborhoods-db.builder.ts index b06c990..191392c 100644 --- a/src/microservice/adapter/helper/builder/neighborhoods/search-neighborhoods-db.builder.ts +++ b/src/microservice/adapter/helper/builder/neighborhoods/search-neighborhoods-db.builder.ts @@ -1,10 +1,8 @@ -import { ValidOutputSearchNeighborhood } from '../../../../domain/interface/valid-output-search/valid-outpu-search-neighborhood.interface'; +import { ValidOutputSearchByCity } from '../../../../domain/interface/valid-output-search/valid-outpu-search.interface'; import { SearchNeighborhoodsDB } from '../../../../domain/model/search/neighborhoods/search-neighborhoods-db.model'; export class SearchNeighborhoodsDBBuilder { - constructor( - private readonly convertedSearch: ValidOutputSearchNeighborhood - ) {} + constructor(private readonly convertedSearch: ValidOutputSearchByCity) {} build(): SearchNeighborhoodsDB { return new SearchNeighborhoodsDB( diff --git a/src/microservice/adapter/neighborhoods.module.ts b/src/microservice/adapter/neighborhoods.module.ts index ae0586b..ea06b1a 100644 --- a/src/microservice/adapter/neighborhoods.module.ts +++ b/src/microservice/adapter/neighborhoods.module.ts @@ -22,9 +22,9 @@ import { City, CitySchema } from '../domain/schemas/city.schema'; import { ValidateCityByNameOrAliasService } from '../domain/service/cities/validate-city-by-name-or-alias.service'; import { CitiesMongoose } from './repository/cities/cities-mongoose.repository'; import { GetNeighborhoodsByStateService } from '../domain/service/neighborhoods/get/get-neighborhoods-by-state.service'; -import { ValidateInputParamsService } from '../domain/service/validate-input-params.service'; +import { ValidateInputParamsService } from '../domain/service/validate/validate-input-params.service'; import { SeedNeighborhoodsByStateService } from '../domain/service/neighborhoods/seed/seed-neighborhoods-by-state.service'; -import { GetCitiesByStateService } from '../domain/service/cities/get-cities-by-state.service'; +import { GetCitiesByStateService } from '../domain/service/cities/get/get-cities-by-state.service'; import { LogSeed, LogSeedSchema } from '../domain/schemas/logseed.schema'; import { LogSeedMongoose } from './repository/logseed/logseed-mongoose.repository'; import { LogSeedJobService } from '../domain/service/logseed/log-seed-job.service'; diff --git a/src/microservice/adapter/repository/neighborhoods/puppeteer/guia-mais.repository.ts b/src/microservice/adapter/repository/neighborhoods/puppeteer/guia-mais.repository.ts index 38c00aa..661bd7c 100644 --- a/src/microservice/adapter/repository/neighborhoods/puppeteer/guia-mais.repository.ts +++ b/src/microservice/adapter/repository/neighborhoods/puppeteer/guia-mais.repository.ts @@ -8,7 +8,7 @@ import { IPuppeteerNeighborhoodRepository } from '../../../../domain/interface/p import { PuppeteerNeighborhoodRepository } from '../../../../domain/repository/puppeteer/neighborhood/puppeteer-neighborhood.repository'; import { Page } from '../../../../domain/interface/puppeteer/page.interface'; import { EnumTranslations } from '../../../../domain/enumerators/enum-translations.enumerator'; -import { ValidOutputSearchNeighborhood } from '../../../../domain/interface/valid-output-search/valid-outpu-search-neighborhood.interface'; +import { ValidOutputSearchByCity } from '../../../../domain/interface/valid-output-search/valid-outpu-search.interface'; @Injectable() export class GuiaMaisRepository @@ -28,7 +28,7 @@ export class GuiaMaisRepository buildElementsFromDocument( searchParams, - convertedSearch: ValidOutputSearchNeighborhood, + convertedSearch: ValidOutputSearchByCity, $: CheerioAPI ): NeighborhoodByCity[] { const arrNeighborhoods = []; diff --git a/src/microservice/domain/interface/puppeteer/repository/puppeteer-neighborhood-repository.interface.ts b/src/microservice/domain/interface/puppeteer/repository/puppeteer-neighborhood-repository.interface.ts index cd0c4e6..cf3c18d 100644 --- a/src/microservice/domain/interface/puppeteer/repository/puppeteer-neighborhood-repository.interface.ts +++ b/src/microservice/domain/interface/puppeteer/repository/puppeteer-neighborhood-repository.interface.ts @@ -2,17 +2,17 @@ import { SearchNeighborhoodsInput } from '../../../model/search/neighborhoods/se import { NeighborhoodByCity } from '../../../model/neighborhoods/neighborhood-by-city.model'; import { IPuppeteerRepository } from './puppeteer-repository.interface'; import { EnumTranslations } from '../../../enumerators/enum-translations.enumerator'; -import { ValidOutputSearchNeighborhood } from '../../valid-output-search/valid-outpu-search-neighborhood.interface'; +import { ValidOutputSearchByCity } from '../../valid-output-search/valid-outpu-search.interface'; export interface IPuppeteerNeighborhoodRepository extends IPuppeteerRepository< NeighborhoodByCity, SearchNeighborhoodsInput, - ValidOutputSearchNeighborhood + ValidOutputSearchByCity > { language: EnumTranslations; getNeighborhoodsByCity( searchParams: SearchNeighborhoodsInput, - convertedSearch: ValidOutputSearchNeighborhood + convertedSearch: ValidOutputSearchByCity ): Promise; } diff --git a/src/microservice/domain/interface/valid-output-search/valid-outpu-search-neighborhood.interface.ts b/src/microservice/domain/interface/valid-output-search/valid-outpu-search.interface.ts similarity index 60% rename from src/microservice/domain/interface/valid-output-search/valid-outpu-search-neighborhood.interface.ts rename to src/microservice/domain/interface/valid-output-search/valid-outpu-search.interface.ts index 435c65c..ebd6da1 100644 --- a/src/microservice/domain/interface/valid-output-search/valid-outpu-search-neighborhood.interface.ts +++ b/src/microservice/domain/interface/valid-output-search/valid-outpu-search.interface.ts @@ -2,8 +2,13 @@ import { City } from '../../schemas/city.schema'; import { Country } from '../../schemas/country.schema'; import { State } from '../../schemas/state.schema'; -export interface ValidOutputSearchNeighborhood { +export interface ValidOutputSearchByCity { country: Country; state: State; city: City; } + +export interface ValidOutputSearchByState { + country: Country; + state: State; +} diff --git a/src/microservice/domain/model/cities/cities-by-country.model.ts b/src/microservice/domain/model/cities/cities-by-country.model.ts new file mode 100644 index 0000000..64fc844 --- /dev/null +++ b/src/microservice/domain/model/cities/cities-by-country.model.ts @@ -0,0 +1,8 @@ +export class CitiesByCountry { + id: number; + name: string; + countryCode: string; + countryId: number; + stateCode: string; + stateId: number; +} diff --git a/src/microservice/domain/model/search/cities/search-cities-db.model.ts b/src/microservice/domain/model/search/cities/search-cities-db.model.ts index 84ab2ed..97558f7 100644 --- a/src/microservice/domain/model/search/cities/search-cities-db.model.ts +++ b/src/microservice/domain/model/search/cities/search-cities-db.model.ts @@ -1,5 +1,5 @@ export class SearchCitiesDB { public id: any; - constructor(public countryId: number, public stateId: number) {} + constructor(public countryId: number, public stateId: number = null) {} } diff --git a/src/microservice/domain/repository/puppeteer/neighborhood/puppeteer-neighborhood.repository.ts b/src/microservice/domain/repository/puppeteer/neighborhood/puppeteer-neighborhood.repository.ts index 83788cc..957af2f 100644 --- a/src/microservice/domain/repository/puppeteer/neighborhood/puppeteer-neighborhood.repository.ts +++ b/src/microservice/domain/repository/puppeteer/neighborhood/puppeteer-neighborhood.repository.ts @@ -5,7 +5,7 @@ import { PuppeteerRepository } from '../puppeteer.repository'; import { IPuppeteerNeighborhoodRepository } from '../../../interface/puppeteer/repository/puppeteer-neighborhood-repository.interface'; import { NotFoundException } from '../../../../../core/error-handling/exception/not-found.exception'; import { EnumTranslations } from '../../../enumerators/enum-translations.enumerator'; -import { ValidOutputSearchNeighborhood } from '../../../interface/valid-output-search/valid-outpu-search-neighborhood.interface'; +import { ValidOutputSearchByCity } from '../../../interface/valid-output-search/valid-outpu-search.interface'; export abstract class PuppeteerNeighborhoodRepository extends PuppeteerRepository @@ -14,7 +14,7 @@ export abstract class PuppeteerNeighborhoodRepository language: EnumTranslations; async getNeighborhoodsByCity( searchParams: SearchNeighborhoodsInput, - convertedSearch: ValidOutputSearchNeighborhood + convertedSearch: ValidOutputSearchByCity ): Promise { this.validateInput(searchParams); @@ -36,7 +36,7 @@ export abstract class PuppeteerNeighborhoodRepository abstract buildElementsFromDocument( _searchParams: SearchNeighborhoodsInput, - convertedSearch: ValidOutputSearchNeighborhood, + convertedSearch: ValidOutputSearchByCity, _$: CheerioAPI ); diff --git a/src/microservice/domain/service/cities/get/get-cities-by-country.service.ts b/src/microservice/domain/service/cities/get/get-cities-by-country.service.ts new file mode 100644 index 0000000..c065575 --- /dev/null +++ b/src/microservice/domain/service/cities/get/get-cities-by-country.service.ts @@ -0,0 +1,46 @@ +import { Injectable } from '@nestjs/common'; +import { CitiesByCountry } from 'src/microservice/domain/model/cities/cities-by-country.model'; +import { CitiesMongoose } from '../../../../adapter/repository/cities/cities-mongoose.repository'; +import { SearchCitiesDB } from '../../../model/search/cities/search-cities-db.model'; +import { SearchCitiesInput } from '../../../model/search/cities/search-cities-input.model'; +import { City } from '../../../schemas/city.schema'; +import { ValidateInputParamsService } from '../../validate/validate-input-params.service'; +import { CitiesService } from '../cities.service'; + +@Injectable() +export class GetCitiesByCountryService extends CitiesService { + constructor( + mongoRepository: CitiesMongoose, + protected readonly validateService: ValidateInputParamsService + ) { + super(mongoRepository); + } + + async getCitiesByCountry( + searchParams: SearchCitiesInput + ): Promise { + const convertedSearch = + await this.validateService.validateAndConvertSearchByState(searchParams); + + this.logger.log('Searching cities in database...'); + + return this.findCitiesByCountry(convertedSearch.country.id); + } + + async findCitiesByCountry(countryId: number): Promise { + const select = { + _id: 0, + id: 1, + name: 1, + countryId: 1, + countryCode: 1, + stateId: 1, + state: 1, + stateCode: 1, + city: 1, + cityId: 1 + }; + + return this.mongoRepository.findBySearchParams({ countryId }, select); + } +} diff --git a/src/microservice/domain/service/cities/get-cities-by-state.service.ts b/src/microservice/domain/service/cities/get/get-cities-by-state.service.ts similarity index 64% rename from src/microservice/domain/service/cities/get-cities-by-state.service.ts rename to src/microservice/domain/service/cities/get/get-cities-by-state.service.ts index 6093148..9cdc783 100644 --- a/src/microservice/domain/service/cities/get-cities-by-state.service.ts +++ b/src/microservice/domain/service/cities/get/get-cities-by-state.service.ts @@ -1,11 +1,11 @@ import { Injectable } from '@nestjs/common'; -import { CitiesMongoose } from '../../../adapter/repository/cities/cities-mongoose.repository'; -import { CitiesByState } from '../../model/cities/cities-by-state.model'; -import { SearchCitiesDB } from '../../model/search/cities/search-cities-db.model'; -import { SearchCitiesInput } from '../../model/search/cities/search-cities-input.model'; -import { City } from '../../schemas/city.schema'; -import { ValidateInputParamsService } from '../validate-input-params.service'; -import { CitiesService } from './cities.service'; +import { CitiesMongoose } from '../../../../adapter/repository/cities/cities-mongoose.repository'; +import { CitiesByState } from '../../../model/cities/cities-by-state.model'; +import { SearchCitiesDB } from '../../../model/search/cities/search-cities-db.model'; +import { SearchCitiesInput } from '../../../model/search/cities/search-cities-input.model'; +import { City } from '../../../schemas/city.schema'; +import { ValidateInputParamsService } from '../../validate/validate-input-params.service'; +import { CitiesService } from '../cities.service'; @Injectable() export class GetCitiesByStateService extends CitiesService { diff --git a/src/microservice/domain/service/neighborhoods/get/get-neighborhoods-by-city.service.ts b/src/microservice/domain/service/neighborhoods/get/get-neighborhoods-by-city.service.ts index 8ddefc7..5d2400b 100644 --- a/src/microservice/domain/service/neighborhoods/get/get-neighborhoods-by-city.service.ts +++ b/src/microservice/domain/service/neighborhoods/get/get-neighborhoods-by-city.service.ts @@ -4,10 +4,10 @@ import { SearchNeighborhoodsInput } from '../../../model/search/neighborhoods/se import { NeighborhoodsMongoose } from '../../../../adapter/repository/neighborhoods/neighborhoods-mongoose.repository'; import { GuiaMaisRepository } from '../../../../adapter/repository/neighborhoods/puppeteer/guia-mais.repository'; import { SaveNeighborhoodsByCityService } from '../save-neighborhoods-by-city.service'; -import { ValidOutputSearchNeighborhood } from '../../../interface/valid-output-search/valid-outpu-search-neighborhood.interface'; +import { ValidOutputSearchByCity } from '../../../interface/valid-output-search/valid-outpu-search.interface'; import { SearchNeighborhoodsDB } from '../../../model/search/neighborhoods/search-neighborhoods-db.model'; import { NeighborhoodsService } from '../neighborhoods.service'; -import { ValidateInputParamsService } from '../../validate-input-params.service'; +import { ValidateInputParamsService } from '../../validate/validate-input-params.service'; @Injectable() export class GetNeighborhoodsByCityService extends NeighborhoodsService { @@ -49,7 +49,7 @@ export class GetNeighborhoodsByCityService extends NeighborhoodsService { async searchByPuppeterAndSave( searchParams: SearchNeighborhoodsInput, - convertedSearch: ValidOutputSearchNeighborhood + convertedSearch: ValidOutputSearchByCity ): Promise { const resPuppeteer = await this.guiaMaisRepository.getNeighborhoodsByCity( searchParams, @@ -66,7 +66,7 @@ export class GetNeighborhoodsByCityService extends NeighborhoodsService { } async findNeighborhoodsByCityInDatabase( - convertedSearch: ValidOutputSearchNeighborhood + convertedSearch: ValidOutputSearchByCity ): Promise { const searchDB = new SearchNeighborhoodsDB( convertedSearch.country.id, diff --git a/src/microservice/domain/service/neighborhoods/get/get-neighborhoods-by-state.service.ts b/src/microservice/domain/service/neighborhoods/get/get-neighborhoods-by-state.service.ts index 4abd764..0fb8d4e 100644 --- a/src/microservice/domain/service/neighborhoods/get/get-neighborhoods-by-state.service.ts +++ b/src/microservice/domain/service/neighborhoods/get/get-neighborhoods-by-state.service.ts @@ -1,14 +1,14 @@ import { Injectable } from '@nestjs/common'; import { SearchNeighborhoodsInput } from '../../../model/search/neighborhoods/search-neighborhoods-input.model'; import { NeighborhoodsMongoose } from '../../../../adapter/repository/neighborhoods/neighborhoods-mongoose.repository'; -import { ValidOutputSearchNeighborhood } from '../../../interface/valid-output-search/valid-outpu-search-neighborhood.interface'; +import { ValidOutputSearchByState } from '../../../interface/valid-output-search/valid-outpu-search.interface'; import { SearchNeighborhoodsDB } from '../../../model/search/neighborhoods/search-neighborhoods-db.model'; import { NeighborhoodsByState, NeighborhooodAggregatedByCity } from '../../../model/neighborhoods/neighborhoods-by-state.model'; import { NeighborhoodsService } from '../neighborhoods.service'; -import { ValidateInputParamsService } from '../../validate-input-params.service'; +import { ValidateInputParamsService } from '../../validate/validate-input-params.service'; import { AggregatedNeighborhoodsByCity } from '../../../interface/aggregated/aggregated-neighborhoods-city.interface'; @Injectable() @@ -29,7 +29,7 @@ export class GetNeighborhoodsByStateService extends NeighborhoodsService { return this.findNeighborhoodsByStateInDatabase(convertedSearch); } async findNeighborhoodsByStateInDatabase( - convertedSearch: ValidOutputSearchNeighborhood + convertedSearch: ValidOutputSearchByState ): Promise { const arrResponse: NeighborhoodsByState = {}; @@ -61,7 +61,7 @@ export class GetNeighborhoodsByStateService extends NeighborhoodsService { } async findByCityAndStateInDatabase( - convertedSearch: ValidOutputSearchNeighborhood, + convertedSearch: ValidOutputSearchByState, cityId: number ) { const searchDB = new SearchNeighborhoodsDB( diff --git a/src/microservice/domain/service/neighborhoods/save-neighborhoods-by-city.service.ts b/src/microservice/domain/service/neighborhoods/save-neighborhoods-by-city.service.ts index 301a592..58c8600 100644 --- a/src/microservice/domain/service/neighborhoods/save-neighborhoods-by-city.service.ts +++ b/src/microservice/domain/service/neighborhoods/save-neighborhoods-by-city.service.ts @@ -4,7 +4,7 @@ import { NeighborhoodsMongoose } from '../../../adapter/repository/neighborhoods import { NeighborhoodsMongoBuilder } from '../../../adapter/helper/builder/neighborhoods/neighborhoods-mongo.builder'; import { SearchNeighborhoodsInput } from '../../model/search/neighborhoods/search-neighborhoods-input.model'; import { NeighborhoodsService } from './neighborhoods.service'; -import { ValidOutputSearchNeighborhood } from '../../interface/valid-output-search/valid-outpu-search-neighborhood.interface'; +import { ValidOutputSearchByCity } from '../../interface/valid-output-search/valid-outpu-search.interface'; import { Neighborhood } from '../../schemas/neighborhood.schema'; import { SearchNeighborhoodsDBBuilder } from '../../../adapter/helper/builder/neighborhoods/search-neighborhoods-db.builder'; @@ -17,7 +17,7 @@ export class SaveNeighborhoodsByCityService extends NeighborhoodsService { async saveNeighborhoodsByCity( neighborhoodsPuppeteer: NeighborhoodByCity[], searchParams: SearchNeighborhoodsInput, - convertedSearch: ValidOutputSearchNeighborhood + convertedSearch: ValidOutputSearchByCity ): Promise { const arrDocument = new NeighborhoodsMongoBuilder( neighborhoodsPuppeteer @@ -36,7 +36,7 @@ export class SaveNeighborhoodsByCityService extends NeighborhoodsService { async createNeighborhood( item: Neighborhood, - convertedSearch: ValidOutputSearchNeighborhood + convertedSearch: ValidOutputSearchByCity ) { item.countryId = convertedSearch.country.id; item.country = convertedSearch.country.name.capitalize(); @@ -51,7 +51,7 @@ export class SaveNeighborhoodsByCityService extends NeighborhoodsService { } async findNeighborhoodInDatabase( - convertedSearch: ValidOutputSearchNeighborhood, + convertedSearch: ValidOutputSearchByCity, name: string ) { const searchParams = new SearchNeighborhoodsDBBuilder( diff --git a/src/microservice/domain/service/neighborhoods/seed/seed-neighborhoods-by-state.service.ts b/src/microservice/domain/service/neighborhoods/seed/seed-neighborhoods-by-state.service.ts index 57da1c4..0b803d3 100644 --- a/src/microservice/domain/service/neighborhoods/seed/seed-neighborhoods-by-state.service.ts +++ b/src/microservice/domain/service/neighborhoods/seed/seed-neighborhoods-by-state.service.ts @@ -1,11 +1,11 @@ import { Injectable } from '@nestjs/common'; import { SearchNeighborhoodsInput } from '../../../model/search/neighborhoods/search-neighborhoods-input.model'; import { NeighborhoodsService } from '../neighborhoods.service'; -import { ValidateInputParamsService } from '../../validate-input-params.service'; -import { GetCitiesByStateService } from '../../cities/get-cities-by-state.service'; +import { ValidateInputParamsService } from '../../validate/validate-input-params.service'; +import { GetCitiesByStateService } from '../../cities/get/get-cities-by-state.service'; import { SearchCitiesDB } from '../../../model/search/cities/search-cities-db.model'; import { GetNeighborhoodsByCityService } from '../get/get-neighborhoods-by-city.service'; -import { ValidOutputSearchNeighborhood } from '../../../interface/valid-output-search/valid-outpu-search-neighborhood.interface'; +import { ValidOutputSearchByState } from '../../../interface/valid-output-search/valid-outpu-search.interface'; import { EnumTranslations } from '../../../enumerators/enum-translations.enumerator'; import { City } from '../../../schemas/city.schema'; import { NeighborhoodsMongoose } from '../../../../adapter/repository/neighborhoods/neighborhoods-mongoose.repository'; @@ -73,7 +73,7 @@ export class SeedNeighborhoodsByStateService extends NeighborhoodsService { } async logErrorSeedJob( - convertedSearch: ValidOutputSearchNeighborhood, + convertedSearch: ValidOutputSearchByState, city: City, err: Error ): Promise { @@ -85,17 +85,20 @@ export class SeedNeighborhoodsByStateService extends NeighborhoodsService { ); } - async seedByCity(convertedSearch: ValidOutputSearchNeighborhood, city: City) { + async seedByCity(convertedSearch: ValidOutputSearchByState, city: City) { const searchParamsByCity = new SearchNeighborhoodsInput( convertedSearch.country.translations[EnumTranslations.BR], convertedSearch.state.stateCode, city.name ); - convertedSearch.city = city; this.logger.log(`Seeding city[${city.id}] ${city.name}...`); await this.getNeighborhoodsByCityService.searchByPuppeterAndSave( searchParamsByCity, - convertedSearch + { + country: convertedSearch.country, + state: convertedSearch.state, + city + } ); } diff --git a/src/microservice/domain/service/validate-input-params.service.ts b/src/microservice/domain/service/validate/validate-input-params.service.ts similarity index 58% rename from src/microservice/domain/service/validate-input-params.service.ts rename to src/microservice/domain/service/validate/validate-input-params.service.ts index cf04127..964040d 100644 --- a/src/microservice/domain/service/validate-input-params.service.ts +++ b/src/microservice/domain/service/validate/validate-input-params.service.ts @@ -1,11 +1,14 @@ import { Injectable } from '@nestjs/common'; -import { SearchNeighborhoodsInput } from '../model/search/neighborhoods/search-neighborhoods-input.model'; -import { ValidOutputSearchNeighborhood } from '../interface/valid-output-search/valid-outpu-search-neighborhood.interface'; -import { AbstractService } from './abstract-service.service'; -import { ValidateCountryByNameOrAliasService } from './countries/validate-country-by-name-or-alias.service'; -import { ValidateStateByNameOrAliasService } from './states/validate-state-by-name-or-alias.service'; -import { ValidateCityByNameOrAliasService } from './cities/validate-city-by-name-or-alias.service'; -import { SearchCitiesInput } from '../model/search/cities/search-cities-input.model'; +import { SearchNeighborhoodsInput } from '../../model/search/neighborhoods/search-neighborhoods-input.model'; +import { + ValidOutputSearchByCity, + ValidOutputSearchByState +} from '../../interface/valid-output-search/valid-outpu-search.interface'; +import { AbstractService } from '../abstract-service.service'; +import { ValidateCountryByNameOrAliasService } from '../countries/validate-country-by-name-or-alias.service'; +import { ValidateStateByNameOrAliasService } from '../states/validate-state-by-name-or-alias.service'; +import { ValidateCityByNameOrAliasService } from '../cities/validate-city-by-name-or-alias.service'; +import { SearchCitiesInput } from '../../model/search/cities/search-cities-input.model'; @Injectable() export class ValidateInputParamsService extends AbstractService { @@ -19,7 +22,7 @@ export class ValidateInputParamsService extends AbstractService { async validateAndConvertSearchByState( searchParams: SearchNeighborhoodsInput | SearchCitiesInput - ): Promise { + ): Promise { const country = await this.getCountryService.validateCountry( searchParams.country ); @@ -27,12 +30,12 @@ export class ValidateInputParamsService extends AbstractService { searchParams.state, country.id ); - return { country, state, city: null }; + return { country, state }; } async validateAndConvertSearchByCity( searchParams: SearchNeighborhoodsInput - ): Promise { + ): Promise { const country = await this.getCountryService.validateCountry( searchParams.country ); diff --git a/test/unit/microservice/adapter/controller/neighborhoods.controller.spec.ts b/test/unit/microservice/adapter/controller/neighborhoods.controller.spec.ts index ab5deac..369f33f 100644 --- a/test/unit/microservice/adapter/controller/neighborhoods.controller.spec.ts +++ b/test/unit/microservice/adapter/controller/neighborhoods.controller.spec.ts @@ -11,7 +11,7 @@ import { SaveNeighborhoodsByCityService } from '../../../../../src/microservice/ import { SearchNeighborhoodsInput } from '../../../../../src/microservice/domain/model/search/neighborhoods/search-neighborhoods-input.model'; import { GetNeighborhoodsByStateService } from '../../../../../src/microservice/domain/service/neighborhoods/get/get-neighborhoods-by-state.service'; import { SeedNeighborhoodsByStateService } from '../../../../../src/microservice/domain/service/neighborhoods/seed/seed-neighborhoods-by-state.service'; -import { ValidateInputParamsService } from '../../../../../src/microservice/domain/service/validate-input-params.service'; +import { ValidateInputParamsService } from '../../../../../src/microservice/domain/service/validate/validate-input-params.service'; describe('NeighborhoodsController', () => { let neighborhoodsController: NeighborhoodsController; diff --git a/test/unit/microservice/domain/service/cities/get-cities-by-state.service.spec.ts b/test/unit/microservice/domain/service/cities/get-cities-by-state.service.spec.ts index 2a07e81..3d67ac9 100644 --- a/test/unit/microservice/domain/service/cities/get-cities-by-state.service.spec.ts +++ b/test/unit/microservice/domain/service/cities/get-cities-by-state.service.spec.ts @@ -3,9 +3,9 @@ import { expect } from 'chai'; import * as sinon from 'sinon'; import { NeighborhoodsMongoose } from '../../../../../../src/microservice/adapter/repository/neighborhoods/neighborhoods-mongoose.repository'; import '../../../../../../src/microservice/adapter/helper/extensions/exensions.module'; -import { ValidateInputParamsService } from '../../../../../../src/microservice/domain/service/validate-input-params.service'; +import { ValidateInputParamsService } from '../../../../../../src/microservice/domain/service/validate/validate-input-params.service'; import { City } from '../../../../../../src/microservice/domain/schemas/city.schema'; -import { GetCitiesByStateService } from '../../../../../../src/microservice/domain/service/cities/get-cities-by-state.service'; +import { GetCitiesByStateService } from '../../../../../../src/microservice/domain/service/cities/get/get-cities-by-state.service'; import { SearchCitiesDB } from '../../../../../../src/microservice/domain/model/search/cities/search-cities-db.model'; import { CitiesMongoose } from '../../../../../../src/microservice/adapter/repository/cities/cities-mongoose.repository'; diff --git a/test/unit/microservice/domain/service/neighborhoods/get/get-neighborhoods-by-city.service.spec.ts b/test/unit/microservice/domain/service/neighborhoods/get/get-neighborhoods-by-city.service.spec.ts index 3b86b9c..74fae54 100644 --- a/test/unit/microservice/domain/service/neighborhoods/get/get-neighborhoods-by-city.service.spec.ts +++ b/test/unit/microservice/domain/service/neighborhoods/get/get-neighborhoods-by-city.service.spec.ts @@ -11,7 +11,7 @@ import { CountriesMongoose } from '../../../../../../../src/microservice/adapter import { CitiesMongoose } from '../../../../../../../src/microservice/adapter/repository/cities/cities-mongoose.repository'; import { StatesMongoose } from '../../../../../../../src/microservice/adapter/repository/states/states-mongoose.repository'; import { SearchNeighborhoodsInput } from '../../../../../../../src/microservice/domain/model/search/neighborhoods/search-neighborhoods-input.model'; -import { ValidateInputParamsService } from '../../../../../../../src/microservice/domain/service/validate-input-params.service'; +import { ValidateInputParamsService } from '../../../../../../../src/microservice/domain/service/validate/validate-input-params.service'; import { Country } from '../../../../../../../src/microservice/domain/schemas/country.schema'; import { State } from '../../../../../../../src/microservice/domain/schemas/state.schema'; import { City } from '../../../../../../../src/microservice/domain/schemas/city.schema'; diff --git a/test/unit/microservice/domain/service/neighborhoods/get/get-neighborhoods-by-state.service.spec.ts b/test/unit/microservice/domain/service/neighborhoods/get/get-neighborhoods-by-state.service.spec.ts index 22b999e..b171846 100644 --- a/test/unit/microservice/domain/service/neighborhoods/get/get-neighborhoods-by-state.service.spec.ts +++ b/test/unit/microservice/domain/service/neighborhoods/get/get-neighborhoods-by-state.service.spec.ts @@ -5,7 +5,7 @@ import { NeighborhoodsMongoose } from '../../../../../../../src/microservice/ada import { Neighborhood } from '../../../../../../../src/microservice/domain/schemas/neighborhood.schema'; import '../../../../../../../src/microservice/adapter/helper/extensions/exensions.module'; import { SearchNeighborhoodsInput } from '../../../../../../../src/microservice/domain/model/search/neighborhoods/search-neighborhoods-input.model'; -import { ValidateInputParamsService } from '../../../../../../../src/microservice/domain/service/validate-input-params.service'; +import { ValidateInputParamsService } from '../../../../../../../src/microservice/domain/service/validate/validate-input-params.service'; import { Country } from '../../../../../../../src/microservice/domain/schemas/country.schema'; import { State } from '../../../../../../../src/microservice/domain/schemas/state.schema'; import { City } from '../../../../../../../src/microservice/domain/schemas/city.schema'; diff --git a/test/unit/microservice/domain/service/neighborhoods/seed/seed-neighborhoods-by-state.service.spec.ts b/test/unit/microservice/domain/service/neighborhoods/seed/seed-neighborhoods-by-state.service.spec.ts index 77f6d5f..aec4794 100644 --- a/test/unit/microservice/domain/service/neighborhoods/seed/seed-neighborhoods-by-state.service.spec.ts +++ b/test/unit/microservice/domain/service/neighborhoods/seed/seed-neighborhoods-by-state.service.spec.ts @@ -6,11 +6,11 @@ import '../../../../../../../src/microservice/adapter/helper/extensions/exension import { SearchNeighborhoodsInput } from '../../../../../../../src/microservice/domain/model/search/neighborhoods/search-neighborhoods-input.model'; import { Country } from '../../../../../../../src/microservice/domain/schemas/country.schema'; import { City } from '../../../../../../../src/microservice/domain/schemas/city.schema'; -import { GetCitiesByStateService } from '../../../../../../../src/microservice/domain/service/cities/get-cities-by-state.service'; +import { GetCitiesByStateService } from '../../../../../../../src/microservice/domain/service/cities/get/get-cities-by-state.service'; import { GetNeighborhoodsByCityService } from '../../../../../../../src/microservice/domain/service/neighborhoods/get/get-neighborhoods-by-city.service'; import { LogSeedJobService } from '../../../../../../../src/microservice/domain/service/logseed/log-seed-job.service'; import { State } from '../../../../../../../src/microservice/domain/schemas/state.schema'; -import { ValidateInputParamsService } from '../../../../../../../src/microservice/domain/service/validate-input-params.service'; +import { ValidateInputParamsService } from '../../../../../../../src/microservice/domain/service/validate/validate-input-params.service'; import { NeighborhoodsMongoose } from '../../../../../../../src/microservice/adapter/repository/neighborhoods/neighborhoods-mongoose.repository'; import { Translations } from '../../../../../../../src/microservice/domain/model/translations.model'; import { EnumTranslations } from '../../../../../../../src/microservice/domain/enumerators/enum-translations.enumerator'; diff --git a/test/unit/microservice/domain/service/validate/validate-input-params.service.spec.ts b/test/unit/microservice/domain/service/validate/validate-input-params.service.spec.ts index d3b2f02..f0b29f0 100644 --- a/test/unit/microservice/domain/service/validate/validate-input-params.service.spec.ts +++ b/test/unit/microservice/domain/service/validate/validate-input-params.service.spec.ts @@ -4,7 +4,7 @@ import * as sinon from 'sinon'; import '../../../../../../src/microservice/adapter/helper/extensions/exensions.module'; import { ValidateStateByNameOrAliasService } from '../../../../../../src/microservice/domain/service/states/validate-state-by-name-or-alias.service'; import { State } from '../../../../../../src/microservice/domain/schemas/state.schema'; -import { ValidateInputParamsService } from '../../../../../../src/microservice/domain/service/validate-input-params.service'; +import { ValidateInputParamsService } from '../../../../../../src/microservice/domain/service/validate/validate-input-params.service'; import { Country } from '../../../../../../src/microservice/domain/schemas/country.schema'; import { City } from '../../../../../../src/microservice/domain/schemas/city.schema'; import { ValidateCountryByNameOrAliasService } from '../../../../../../src/microservice/domain/service/countries/validate-country-by-name-or-alias.service'; From fb15abd2c56c483b6a149a4ecd5fea5f4c0d79e1 Mon Sep 17 00:00:00 2001 From: Maick Speck Date: Mon, 27 Jun 2022 14:17:52 -0300 Subject: [PATCH 10/39] findByNameOrAliasOrId --- .../mongoose/places-mongoose.repository.ts | 10 +++++++--- .../validate-city-by-name-or-alias.service.ts | 5 ++++- .../validate-country-by-name-or-alias.service.ts | 2 +- .../validate-state-by-name-or-alias.service.ts | 2 +- .../countries-mongoose.repository.spec.ts | 2 +- .../{ => get}/get-cities-by-state.service.spec.ts | 14 +++++++------- .../validate-city-by-name-or-alias.service.spec.ts | 8 ++++---- ...lidate-country-by-name-or-alias.service.spec.ts | 8 ++++---- ...validate-state-by-name-or-alias.service.spec.ts | 8 ++++---- 9 files changed, 33 insertions(+), 26 deletions(-) rename test/unit/microservice/domain/service/cities/{ => get}/get-cities-by-state.service.spec.ts (72%) diff --git a/src/microservice/domain/repository/mongoose/places-mongoose.repository.ts b/src/microservice/domain/repository/mongoose/places-mongoose.repository.ts index fa40779..34dfdb6 100644 --- a/src/microservice/domain/repository/mongoose/places-mongoose.repository.ts +++ b/src/microservice/domain/repository/mongoose/places-mongoose.repository.ts @@ -1,4 +1,5 @@ import { Model } from 'mongoose'; +import { parse } from 'path'; import { Place } from '../../interface/place.interface'; import { MongooseRepository } from './mongoose.repository'; @@ -10,12 +11,15 @@ export abstract class PlacesMongooseRepository< super(model); } - async findByNameOrAlias(name: string, extraSearch = {}): Promise { - const nameRegex = new RegExp(name, 'i'); + async findByNameOrAliasOrId(ref: string, extraSearch = {}): Promise { + const nameRegex = new RegExp(ref, 'i'); return this.model .find({ ...extraSearch, - $or: [{ name: nameRegex }, { alias: { $in: [nameRegex] } }] + $or: [ + { alias: { $in: [nameRegex] } }, + isNaN(parseInt(ref)) ? { name: nameRegex } : { id: ref } + ] }) .lean() .exec(); diff --git a/src/microservice/domain/service/cities/validate-city-by-name-or-alias.service.ts b/src/microservice/domain/service/cities/validate-city-by-name-or-alias.service.ts index cf4083a..7c86331 100644 --- a/src/microservice/domain/service/cities/validate-city-by-name-or-alias.service.ts +++ b/src/microservice/domain/service/cities/validate-city-by-name-or-alias.service.ts @@ -15,7 +15,10 @@ export class ValidateCityByNameOrAliasService extends CitiesService { countryId: number, stateId: number ): Promise { - return this.mongoRepository.findByNameOrAlias(name, { countryId, stateId }); + return this.mongoRepository.findByNameOrAliasOrId(name, { + countryId, + stateId + }); } async validateCity( diff --git a/src/microservice/domain/service/countries/validate-country-by-name-or-alias.service.ts b/src/microservice/domain/service/countries/validate-country-by-name-or-alias.service.ts index 2c0acf7..3d2b30f 100644 --- a/src/microservice/domain/service/countries/validate-country-by-name-or-alias.service.ts +++ b/src/microservice/domain/service/countries/validate-country-by-name-or-alias.service.ts @@ -11,7 +11,7 @@ export class ValidateCountryByNameOrAliasService extends CountriesService { } async getCountryByNameOrAlias(name: string): Promise { - return this.mongoRepository.findByNameOrAlias(name); + return this.mongoRepository.findByNameOrAliasOrId(name); } async validateCountry(country: string): Promise { diff --git a/src/microservice/domain/service/states/validate-state-by-name-or-alias.service.ts b/src/microservice/domain/service/states/validate-state-by-name-or-alias.service.ts index 7260675..be12556 100644 --- a/src/microservice/domain/service/states/validate-state-by-name-or-alias.service.ts +++ b/src/microservice/domain/service/states/validate-state-by-name-or-alias.service.ts @@ -14,7 +14,7 @@ export class ValidateStateByNameOrAliasService extends StatesService { name: string, countryId: number ): Promise { - return this.mongoRepository.findByNameOrAlias(name, { countryId }); + return this.mongoRepository.findByNameOrAliasOrId(name, { countryId }); } async validateState(state: string, countryId: number): Promise { diff --git a/test/unit/microservice/adapter/repository/countries/countries-mongoose.repository.spec.ts b/test/unit/microservice/adapter/repository/countries/countries-mongoose.repository.spec.ts index e2e199f..ef1e598 100644 --- a/test/unit/microservice/adapter/repository/countries/countries-mongoose.repository.spec.ts +++ b/test/unit/microservice/adapter/repository/countries/countries-mongoose.repository.spec.ts @@ -61,7 +61,7 @@ describe('CountriesMongoose', () => { .stub(mockModelMongoose, 'find') .returns(mockFindCountries); - const actual = await sut.findByNameOrAlias('any'); + const actual = await sut.findByNameOrAliasOrId('any'); expect(actual).to.be.an('array').that.is.not.empty; diff --git a/test/unit/microservice/domain/service/cities/get-cities-by-state.service.spec.ts b/test/unit/microservice/domain/service/cities/get/get-cities-by-state.service.spec.ts similarity index 72% rename from test/unit/microservice/domain/service/cities/get-cities-by-state.service.spec.ts rename to test/unit/microservice/domain/service/cities/get/get-cities-by-state.service.spec.ts index 3d67ac9..fbcee43 100644 --- a/test/unit/microservice/domain/service/cities/get-cities-by-state.service.spec.ts +++ b/test/unit/microservice/domain/service/cities/get/get-cities-by-state.service.spec.ts @@ -1,13 +1,13 @@ import { Test, TestingModule } from '@nestjs/testing'; import { expect } from 'chai'; import * as sinon from 'sinon'; -import { NeighborhoodsMongoose } from '../../../../../../src/microservice/adapter/repository/neighborhoods/neighborhoods-mongoose.repository'; -import '../../../../../../src/microservice/adapter/helper/extensions/exensions.module'; -import { ValidateInputParamsService } from '../../../../../../src/microservice/domain/service/validate/validate-input-params.service'; -import { City } from '../../../../../../src/microservice/domain/schemas/city.schema'; -import { GetCitiesByStateService } from '../../../../../../src/microservice/domain/service/cities/get/get-cities-by-state.service'; -import { SearchCitiesDB } from '../../../../../../src/microservice/domain/model/search/cities/search-cities-db.model'; -import { CitiesMongoose } from '../../../../../../src/microservice/adapter/repository/cities/cities-mongoose.repository'; +import { NeighborhoodsMongoose } from '../../../../../../../src/microservice/adapter/repository/neighborhoods/neighborhoods-mongoose.repository'; +import '../../../../../../../src/microservice/adapter/helper/extensions/exensions.module'; +import { ValidateInputParamsService } from '../../../../../../../src/microservice/domain/service/validate/validate-input-params.service'; +import { City } from '../../../../../../../src/microservice/domain/schemas/city.schema'; +import { GetCitiesByStateService } from '../../../../../../../src/microservice/domain/service/cities/get/get-cities-by-state.service'; +import { SearchCitiesDB } from '../../../../../../../src/microservice/domain/model/search/cities/search-cities-db.model'; +import { CitiesMongoose } from '../../../../../../../src/microservice/adapter/repository/cities/cities-mongoose.repository'; describe('GetCitiesByStateService', () => { let sut: GetCitiesByStateService; diff --git a/test/unit/microservice/domain/service/cities/validate-city-by-name-or-alias.service.spec.ts b/test/unit/microservice/domain/service/cities/validate-city-by-name-or-alias.service.spec.ts index 8453a1c..41f142c 100644 --- a/test/unit/microservice/domain/service/cities/validate-city-by-name-or-alias.service.spec.ts +++ b/test/unit/microservice/domain/service/cities/validate-city-by-name-or-alias.service.spec.ts @@ -10,7 +10,7 @@ describe('ValidateCityByNameOrAliasService', () => { let sut: ValidateCityByNameOrAliasService; const mockCitiesMongooseRepository = { - findByNameOrAlias: () => { + findByNameOrAliasOrId: () => { return [new City()]; } }; @@ -43,7 +43,7 @@ describe('ValidateCityByNameOrAliasService', () => { describe('getCityByNameOrAlias', () => { it('should call getCityByCity and return an array by mongodb', async () => { const mongoFindStub = sinon - .stub(mockCitiesMongooseRepository, 'findByNameOrAlias') + .stub(mockCitiesMongooseRepository, 'findByNameOrAliasOrId') .returns(mockMongoCities()); const actual = await sut.getCityByNameOrAlias('orleans', 1, 2); @@ -59,7 +59,7 @@ describe('ValidateCityByNameOrAliasService', () => { describe('validateCity', () => { it('should call validateCity and throws invalid data exception', async () => { const getCityStub = sinon - .stub(mockCitiesMongooseRepository, 'findByNameOrAlias') + .stub(mockCitiesMongooseRepository, 'findByNameOrAliasOrId') .returns([]); try { @@ -76,7 +76,7 @@ describe('ValidateCityByNameOrAliasService', () => { city.name = 'any'; const getCityStub = sinon - .stub(mockCitiesMongooseRepository, 'findByNameOrAlias') + .stub(mockCitiesMongooseRepository, 'findByNameOrAliasOrId') .returns([city]); const actual = await sut.validateCity('orleans', 1, 2); diff --git a/test/unit/microservice/domain/service/countries/validate-country-by-name-or-alias.service.spec.ts b/test/unit/microservice/domain/service/countries/validate-country-by-name-or-alias.service.spec.ts index e77333e..88be8d4 100644 --- a/test/unit/microservice/domain/service/countries/validate-country-by-name-or-alias.service.spec.ts +++ b/test/unit/microservice/domain/service/countries/validate-country-by-name-or-alias.service.spec.ts @@ -10,7 +10,7 @@ describe('ValidateCountryByNameOrAliasService', () => { let sut: ValidateCountryByNameOrAliasService; const mockCountriesMongooseRepository = { - findByNameOrAlias: () => { + findByNameOrAliasOrId: () => { return [new Country()]; } }; @@ -43,7 +43,7 @@ describe('ValidateCountryByNameOrAliasService', () => { describe('validateCountry', () => { it('should call validateCountry and throws invalid data exception', async () => { const getCountryStub = sinon - .stub(mockCountriesMongooseRepository, 'findByNameOrAlias') + .stub(mockCountriesMongooseRepository, 'findByNameOrAliasOrId') .returns([]); try { @@ -59,7 +59,7 @@ describe('ValidateCountryByNameOrAliasService', () => { describe('getCountryByCity', () => { it('should call getCountryByCity and return an array by mongodb', async () => { const mongoFindStub = sinon - .stub(mockCountriesMongooseRepository, 'findByNameOrAlias') + .stub(mockCountriesMongooseRepository, 'findByNameOrAliasOrId') .returns(mockMongoCountries()); const actual = await sut.getCountryByNameOrAlias('brasil'); @@ -76,7 +76,7 @@ describe('ValidateCountryByNameOrAliasService', () => { country.name = 'any'; const getCountryStub = sinon - .stub(mockCountriesMongooseRepository, 'findByNameOrAlias') + .stub(mockCountriesMongooseRepository, 'findByNameOrAliasOrId') .returns([country]); const actual = await sut.validateCountry('orleans'); diff --git a/test/unit/microservice/domain/service/states/validate-state-by-name-or-alias.service.spec.ts b/test/unit/microservice/domain/service/states/validate-state-by-name-or-alias.service.spec.ts index c491812..fd11532 100644 --- a/test/unit/microservice/domain/service/states/validate-state-by-name-or-alias.service.spec.ts +++ b/test/unit/microservice/domain/service/states/validate-state-by-name-or-alias.service.spec.ts @@ -10,7 +10,7 @@ describe('ValidateStateByNameOrAliasService', () => { let sut: ValidateStateByNameOrAliasService; const mockStatesMongooseRepository = { - findByNameOrAlias: () => { + findByNameOrAliasOrId: () => { return [new State()]; } }; @@ -43,7 +43,7 @@ describe('ValidateStateByNameOrAliasService', () => { describe('getStateByNameOrAlias', () => { it('should call getStateByCity and return an array by mongodb', async () => { const mongoFindStub = sinon - .stub(mockStatesMongooseRepository, 'findByNameOrAlias') + .stub(mockStatesMongooseRepository, 'findByNameOrAliasOrId') .returns(mockMongoStates()); const actual = await sut.getStateByNameOrAlias('sc', 1); @@ -59,7 +59,7 @@ describe('ValidateStateByNameOrAliasService', () => { describe('validateState', () => { it('should call validateState and throws invalid data exception', async () => { const getStateStub = sinon - .stub(mockStatesMongooseRepository, 'findByNameOrAlias') + .stub(mockStatesMongooseRepository, 'findByNameOrAliasOrId') .returns([]); try { @@ -75,7 +75,7 @@ describe('ValidateStateByNameOrAliasService', () => { const state = new State(); state.name = 'any'; const getStateStub = sinon - .stub(mockStatesMongooseRepository, 'findByNameOrAlias') + .stub(mockStatesMongooseRepository, 'findByNameOrAliasOrId') .returns([state]); const actual = await sut.validateState('orleans', 1); From 8d535135ca7e6b93a2dd17e210fbfd99aeb75ba7 Mon Sep 17 00:00:00 2001 From: Maick Speck Date: Mon, 27 Jun 2022 14:19:34 -0300 Subject: [PATCH 11/39] validate country --- .../cities/get/get-cities-by-country.service.ts | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/microservice/domain/service/cities/get/get-cities-by-country.service.ts b/src/microservice/domain/service/cities/get/get-cities-by-country.service.ts index c065575..66ab8e4 100644 --- a/src/microservice/domain/service/cities/get/get-cities-by-country.service.ts +++ b/src/microservice/domain/service/cities/get/get-cities-by-country.service.ts @@ -1,17 +1,16 @@ import { Injectable } from '@nestjs/common'; import { CitiesByCountry } from 'src/microservice/domain/model/cities/cities-by-country.model'; import { CitiesMongoose } from '../../../../adapter/repository/cities/cities-mongoose.repository'; -import { SearchCitiesDB } from '../../../model/search/cities/search-cities-db.model'; import { SearchCitiesInput } from '../../../model/search/cities/search-cities-input.model'; import { City } from '../../../schemas/city.schema'; -import { ValidateInputParamsService } from '../../validate/validate-input-params.service'; +import { ValidateCountryByNameOrAliasService } from '../../countries/validate-country-by-name-or-alias.service'; import { CitiesService } from '../cities.service'; @Injectable() export class GetCitiesByCountryService extends CitiesService { constructor( mongoRepository: CitiesMongoose, - protected readonly validateService: ValidateInputParamsService + protected readonly validateCountryService: ValidateCountryByNameOrAliasService ) { super(mongoRepository); } @@ -19,12 +18,13 @@ export class GetCitiesByCountryService extends CitiesService { async getCitiesByCountry( searchParams: SearchCitiesInput ): Promise { - const convertedSearch = - await this.validateService.validateAndConvertSearchByState(searchParams); + const country = await this.validateCountryService.validateCountry( + searchParams.country + ); this.logger.log('Searching cities in database...'); - return this.findCitiesByCountry(convertedSearch.country.id); + return this.findCitiesByCountry(country.id); } async findCitiesByCountry(countryId: number): Promise { From 5a0dbf6233a1f02ab5b54839919bb1dc630aecc4 Mon Sep 17 00:00:00 2001 From: Maick Speck Date: Mon, 27 Jun 2022 14:20:02 -0300 Subject: [PATCH 12/39] r1 --- .../domain/repository/mongoose/places-mongoose.repository.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/microservice/domain/repository/mongoose/places-mongoose.repository.ts b/src/microservice/domain/repository/mongoose/places-mongoose.repository.ts index 34dfdb6..4e35702 100644 --- a/src/microservice/domain/repository/mongoose/places-mongoose.repository.ts +++ b/src/microservice/domain/repository/mongoose/places-mongoose.repository.ts @@ -1,5 +1,4 @@ import { Model } from 'mongoose'; -import { parse } from 'path'; import { Place } from '../../interface/place.interface'; import { MongooseRepository } from './mongoose.repository'; From 05fc78a20fba9aec20796749a321b81644e5dbff Mon Sep 17 00:00:00 2001 From: Maick Speck Date: Mon, 27 Jun 2022 14:43:16 -0300 Subject: [PATCH 13/39] getStatesByCountry --- src/app.module.ts | 4 +- .../adapter/controller/cities.controller.ts | 4 +- .../adapter/controller/states.controller.ts | 23 +++++++++++ src/microservice/adapter/states.module.ts | 34 ++++++++++++++++ .../model/states/states-by-country.model.ts | 7 ++++ .../get/get-cities-by-country.service.ts | 6 +-- .../states/get-states-by-country.service.ts | 40 +++++++++++++++++++ 7 files changed, 111 insertions(+), 7 deletions(-) create mode 100644 src/microservice/adapter/controller/states.controller.ts create mode 100644 src/microservice/adapter/states.module.ts create mode 100644 src/microservice/domain/model/states/states-by-country.model.ts create mode 100644 src/microservice/domain/service/states/get-states-by-country.service.ts diff --git a/src/app.module.ts b/src/app.module.ts index 5e14837..ea0767f 100644 --- a/src/app.module.ts +++ b/src/app.module.ts @@ -8,6 +8,7 @@ import { CitiesModule } from './microservice/adapter/cities.module'; import { ExtensionsModule } from './microservice/adapter/helper/extensions/exensions.module'; import { CustomPuppeteerModule } from './microservice/adapter/helper/modules/custom-puppeteer.module'; import { NeighborhoodsModule } from './microservice/adapter/neighborhoods.module'; +import { StatesModule } from './microservice/adapter/states.module'; @Module({ imports: [ @@ -25,7 +26,8 @@ import { NeighborhoodsModule } from './microservice/adapter/neighborhoods.module }) }), NeighborhoodsModule, - CitiesModule + CitiesModule, + StatesModule ], controllers: [], providers: [ diff --git a/src/microservice/adapter/controller/cities.controller.ts b/src/microservice/adapter/controller/cities.controller.ts index 9173860..28ecf7d 100644 --- a/src/microservice/adapter/controller/cities.controller.ts +++ b/src/microservice/adapter/controller/cities.controller.ts @@ -26,11 +26,11 @@ export class CitiesController extends AbstractController { @Get('/country/:country') async getNeighborhoodsByCountry( - @Param() params: SearchCitiesInput + @Param('country') country: string ): Promise { return this.buildResponse( HttpStatus.OK, - await this.getCitiesByCountryService.getCitiesByCountry(params) + await this.getCitiesByCountryService.getCitiesByCountry(country) ); } } diff --git a/src/microservice/adapter/controller/states.controller.ts b/src/microservice/adapter/controller/states.controller.ts new file mode 100644 index 0000000..be3a70e --- /dev/null +++ b/src/microservice/adapter/controller/states.controller.ts @@ -0,0 +1,23 @@ +import { Controller, Get, HttpStatus, Param } from '@nestjs/common'; +import { GetStateByCountryService } from '../../domain/service/states/get-states-by-country.service'; +import { NestResponse } from '../../../core/http/nest-response'; +import { AbstractController } from '../../domain/controller/abstract-controller'; + +@Controller('states') +export class StatesController extends AbstractController { + constructor( + private readonly getStatesByCountryService: GetStateByCountryService + ) { + super(); + } + + @Get('/country/:country') + async getStatesByCountry( + @Param('country') country: string + ): Promise { + return this.buildResponse( + HttpStatus.OK, + await this.getStatesByCountryService.getStatesByCountry(country) + ); + } +} diff --git a/src/microservice/adapter/states.module.ts b/src/microservice/adapter/states.module.ts new file mode 100644 index 0000000..d826f81 --- /dev/null +++ b/src/microservice/adapter/states.module.ts @@ -0,0 +1,34 @@ +import { Module } from '@nestjs/common'; +import { ConfigModule } from '@nestjs/config'; +import configuration from '../../config/configuration'; +import { MongooseModule } from '@nestjs/mongoose'; +import { Country, CountrySchema } from '../domain/schemas/country.schema'; +import { ValidateCountryByNameOrAliasService } from '../domain/service/countries/validate-country-by-name-or-alias.service'; +import { CountriesMongoose } from './repository/countries/countries-mongoose.repository'; +import { State, StateSchema } from '../domain/schemas/state.schema'; +import { ValidateStateByNameOrAliasService } from '../domain/service/states/validate-state-by-name-or-alias.service'; +import { StatesMongoose } from './repository/states/states-mongoose.repository'; +import { GetStateByCountryService } from '../domain/service/states/get-states-by-country.service'; +import { StatesController } from './controller/states.controller'; + +@Module({ + imports: [ + ConfigModule.forRoot({ + isGlobal: true, + load: [configuration] + }), + MongooseModule.forFeature([ + { name: Country.name, schema: CountrySchema }, + { name: State.name, schema: StateSchema } + ]) + ], + controllers: [StatesController], + providers: [ + CountriesMongoose, + StatesMongoose, + ValidateCountryByNameOrAliasService, + ValidateStateByNameOrAliasService, + GetStateByCountryService + ] +}) +export class StatesModule {} diff --git a/src/microservice/domain/model/states/states-by-country.model.ts b/src/microservice/domain/model/states/states-by-country.model.ts new file mode 100644 index 0000000..be6d3a4 --- /dev/null +++ b/src/microservice/domain/model/states/states-by-country.model.ts @@ -0,0 +1,7 @@ +export class StatesByCountry { + id: number; + name: string; + countryId: number; + countryCode: string; + stateCode: string; +} diff --git a/src/microservice/domain/service/cities/get/get-cities-by-country.service.ts b/src/microservice/domain/service/cities/get/get-cities-by-country.service.ts index 66ab8e4..5021502 100644 --- a/src/microservice/domain/service/cities/get/get-cities-by-country.service.ts +++ b/src/microservice/domain/service/cities/get/get-cities-by-country.service.ts @@ -15,11 +15,9 @@ export class GetCitiesByCountryService extends CitiesService { super(mongoRepository); } - async getCitiesByCountry( - searchParams: SearchCitiesInput - ): Promise { + async getCitiesByCountry(countryRef: string): Promise { const country = await this.validateCountryService.validateCountry( - searchParams.country + countryRef ); this.logger.log('Searching cities in database...'); diff --git a/src/microservice/domain/service/states/get-states-by-country.service.ts b/src/microservice/domain/service/states/get-states-by-country.service.ts new file mode 100644 index 0000000..e4b4373 --- /dev/null +++ b/src/microservice/domain/service/states/get-states-by-country.service.ts @@ -0,0 +1,40 @@ +import { Injectable } from '@nestjs/common'; +import { StatesMongoose } from '../../../adapter/repository/states/states-mongoose.repository'; +import { StatesByCountry } from '../../model/states/states-by-country.model'; +import { State } from '../../schemas/state.schema'; +import { ValidateCountryByNameOrAliasService } from '../countries/validate-country-by-name-or-alias.service'; +import { StatesService } from './states.service'; + +@Injectable() +export class GetStateByCountryService extends StatesService { + constructor( + mongoRepository: StatesMongoose, + protected readonly validateCountryService: ValidateCountryByNameOrAliasService + ) { + super(mongoRepository); + } + + async getStatesByCountry(countryRef: string): Promise { + const country = await this.validateCountryService.validateCountry( + countryRef + ); + + this.logger.log('Searching states in database...'); + + return this.findStatesByCountry(country.id); + } + + async findStatesByCountry(countryId: number): Promise { + const select = { + _id: 0, + id: 1, + name: 1, + countryId: 1, + countryCode: 1, + stateId: 1, + stateCode: 1 + }; + + return this.mongoRepository.findBySearchParams({ countryId }, select); + } +} From 0a3a3a529ce0d5f457ae27296cfafb1e88114606 Mon Sep 17 00:00:00 2001 From: Maick Speck Date: Mon, 27 Jun 2022 15:00:51 -0300 Subject: [PATCH 14/39] getAllCountries --- src/app.module.ts | 4 ++- .../controller/countries.controller.ts | 19 +++++++++++++ src/microservice/adapter/countries.module.ts | 21 ++++++++++++++ .../model/countries/country-response.model.ts | 12 ++++++++ .../mongoose/mongoose.repository.ts | 5 ++++ .../get/get-cities-by-country.service.ts | 1 - .../countries/get-countries.service.ts | 28 +++++++++++++++++++ 7 files changed, 88 insertions(+), 2 deletions(-) create mode 100644 src/microservice/adapter/controller/countries.controller.ts create mode 100644 src/microservice/adapter/countries.module.ts create mode 100644 src/microservice/domain/model/countries/country-response.model.ts create mode 100644 src/microservice/domain/service/countries/get-countries.service.ts diff --git a/src/app.module.ts b/src/app.module.ts index ea0767f..8cafec9 100644 --- a/src/app.module.ts +++ b/src/app.module.ts @@ -5,6 +5,7 @@ import { MongooseModule } from '@nestjs/mongoose'; import { FiltersModule } from './core/error-handling/filters.module'; import { TransformResponseInterceptor } from './core/http/transform-response.interceptor'; import { CitiesModule } from './microservice/adapter/cities.module'; +import { CountriesModule } from './microservice/adapter/countries.module'; import { ExtensionsModule } from './microservice/adapter/helper/extensions/exensions.module'; import { CustomPuppeteerModule } from './microservice/adapter/helper/modules/custom-puppeteer.module'; import { NeighborhoodsModule } from './microservice/adapter/neighborhoods.module'; @@ -27,7 +28,8 @@ import { StatesModule } from './microservice/adapter/states.module'; }), NeighborhoodsModule, CitiesModule, - StatesModule + StatesModule, + CountriesModule ], controllers: [], providers: [ diff --git a/src/microservice/adapter/controller/countries.controller.ts b/src/microservice/adapter/controller/countries.controller.ts new file mode 100644 index 0000000..fa0194d --- /dev/null +++ b/src/microservice/adapter/controller/countries.controller.ts @@ -0,0 +1,19 @@ +import { Controller, Get, HttpStatus } from '@nestjs/common'; +import { NestResponse } from '../../../core/http/nest-response'; +import { AbstractController } from '../../domain/controller/abstract-controller'; +import { GetCountriesService } from 'src/microservice/domain/service/countries/get-countries.service'; + +@Controller('countries') +export class CountriesController extends AbstractController { + constructor(private readonly getCountriesService: GetCountriesService) { + super(); + } + + @Get('/') + async getAllCountries(): Promise { + return this.buildResponse( + HttpStatus.OK, + await this.getCountriesService.getAll() + ); + } +} diff --git a/src/microservice/adapter/countries.module.ts b/src/microservice/adapter/countries.module.ts new file mode 100644 index 0000000..630ede1 --- /dev/null +++ b/src/microservice/adapter/countries.module.ts @@ -0,0 +1,21 @@ +import { Module } from '@nestjs/common'; +import { ConfigModule } from '@nestjs/config'; +import configuration from '../../config/configuration'; +import { MongooseModule } from '@nestjs/mongoose'; +import { Country, CountrySchema } from '../domain/schemas/country.schema'; +import { CountriesMongoose } from './repository/countries/countries-mongoose.repository'; +import { CountriesController } from './controller/countries.controller'; +import { GetCountriesService } from '../domain/service/countries/get-countries.service'; + +@Module({ + imports: [ + ConfigModule.forRoot({ + isGlobal: true, + load: [configuration] + }), + MongooseModule.forFeature([{ name: Country.name, schema: CountrySchema }]) + ], + controllers: [CountriesController], + providers: [CountriesMongoose, GetCountriesService] +}) +export class CountriesModule {} diff --git a/src/microservice/domain/model/countries/country-response.model.ts b/src/microservice/domain/model/countries/country-response.model.ts new file mode 100644 index 0000000..0c5c3ec --- /dev/null +++ b/src/microservice/domain/model/countries/country-response.model.ts @@ -0,0 +1,12 @@ +export class CountryResponse { + id: number; + name: string; + iso3: string; + iso2: string; + capital: string; + currency: string; + region: string; + subregion: string; + alias: string; + phoneCode: number; +} diff --git a/src/microservice/domain/repository/mongoose/mongoose.repository.ts b/src/microservice/domain/repository/mongoose/mongoose.repository.ts index e907849..bedd5d4 100644 --- a/src/microservice/domain/repository/mongoose/mongoose.repository.ts +++ b/src/microservice/domain/repository/mongoose/mongoose.repository.ts @@ -67,4 +67,9 @@ export abstract class MongooseRepository { }); return objSearchRegex; } + + async findAll(select: object = {}): Promise { + if (Object.keys(select).length == 0) select = { _id: 0 }; + return this.model.find({}).select(select).lean().exec(); + } } diff --git a/src/microservice/domain/service/cities/get/get-cities-by-country.service.ts b/src/microservice/domain/service/cities/get/get-cities-by-country.service.ts index 5021502..ad419ec 100644 --- a/src/microservice/domain/service/cities/get/get-cities-by-country.service.ts +++ b/src/microservice/domain/service/cities/get/get-cities-by-country.service.ts @@ -1,7 +1,6 @@ import { Injectable } from '@nestjs/common'; import { CitiesByCountry } from 'src/microservice/domain/model/cities/cities-by-country.model'; import { CitiesMongoose } from '../../../../adapter/repository/cities/cities-mongoose.repository'; -import { SearchCitiesInput } from '../../../model/search/cities/search-cities-input.model'; import { City } from '../../../schemas/city.schema'; import { ValidateCountryByNameOrAliasService } from '../../countries/validate-country-by-name-or-alias.service'; import { CitiesService } from '../cities.service'; diff --git a/src/microservice/domain/service/countries/get-countries.service.ts b/src/microservice/domain/service/countries/get-countries.service.ts new file mode 100644 index 0000000..bfc7d2c --- /dev/null +++ b/src/microservice/domain/service/countries/get-countries.service.ts @@ -0,0 +1,28 @@ +import { Injectable } from '@nestjs/common'; +import { CountriesMongoose } from 'src/microservice/adapter/repository/countries/countries-mongoose.repository'; +import { CountryResponse } from '../../model/countries/country-response.model'; +import { CountriesService } from './countries.service'; + +@Injectable() +export class GetCountriesService extends CountriesService { + constructor(mongoRepository: CountriesMongoose) { + super(mongoRepository); + } + + async getAll(): Promise { + const select = { + _id: 0, + id: 1, + name: 1, + iso3: 1, + iso2: 1, + capital: 1, + currency: 1, + region: 1, + subregion: 1, + alias: 1, + phoneCode: 1 + }; + return this.mongoRepository.findAll(select); + } +} From 62a7cce712efcffbfb6b31d38718ff883cfe9703 Mon Sep 17 00:00:00 2001 From: Maick Speck Date: Mon, 27 Jun 2022 15:08:00 -0300 Subject: [PATCH 15/39] clean imports modules --- src/microservice/adapter/cities.module.ts | 21 ++++---------- src/microservice/adapter/countries.module.ts | 3 +- .../adapter/neighborhoods.module.ts | 28 +++---------------- src/microservice/adapter/states.module.ts | 19 +++++++------ 4 files changed, 21 insertions(+), 50 deletions(-) diff --git a/src/microservice/adapter/cities.module.ts b/src/microservice/adapter/cities.module.ts index a15693d..df43649 100644 --- a/src/microservice/adapter/cities.module.ts +++ b/src/microservice/adapter/cities.module.ts @@ -2,12 +2,6 @@ import { Module } from '@nestjs/common'; import { ConfigModule } from '@nestjs/config'; import configuration from '../../config/configuration'; import { MongooseModule } from '@nestjs/mongoose'; -import { Country, CountrySchema } from '../domain/schemas/country.schema'; -import { ValidateCountryByNameOrAliasService } from '../domain/service/countries/validate-country-by-name-or-alias.service'; -import { CountriesMongoose } from './repository/countries/countries-mongoose.repository'; -import { State, StateSchema } from '../domain/schemas/state.schema'; -import { ValidateStateByNameOrAliasService } from '../domain/service/states/validate-state-by-name-or-alias.service'; -import { StatesMongoose } from './repository/states/states-mongoose.repository'; import { City, CitySchema } from '../domain/schemas/city.schema'; import { ValidateCityByNameOrAliasService } from '../domain/service/cities/validate-city-by-name-or-alias.service'; import { CitiesMongoose } from './repository/cities/cities-mongoose.repository'; @@ -15,6 +9,7 @@ import { ValidateInputParamsService } from '../domain/service/validate/validate- import { GetCitiesByStateService } from '../domain/service/cities/get/get-cities-by-state.service'; import { CitiesController } from './controller/cities.controller'; import { GetCitiesByCountryService } from '../domain/service/cities/get/get-cities-by-country.service'; +import { StatesModule } from './states.module'; @Module({ imports: [ @@ -22,23 +17,17 @@ import { GetCitiesByCountryService } from '../domain/service/cities/get/get-citi isGlobal: true, load: [configuration] }), - MongooseModule.forFeature([ - { name: Country.name, schema: CountrySchema }, - { name: State.name, schema: StateSchema }, - { name: City.name, schema: CitySchema } - ]) + MongooseModule.forFeature([{ name: City.name, schema: CitySchema }]), + StatesModule ], controllers: [CitiesController], providers: [ - CountriesMongoose, - StatesMongoose, CitiesMongoose, - ValidateCountryByNameOrAliasService, - ValidateStateByNameOrAliasService, ValidateCityByNameOrAliasService, ValidateInputParamsService, GetCitiesByStateService, GetCitiesByCountryService - ] + ], + exports: [CitiesMongoose, ValidateInputParamsService, GetCitiesByStateService] }) export class CitiesModule {} diff --git a/src/microservice/adapter/countries.module.ts b/src/microservice/adapter/countries.module.ts index 630ede1..6c90ea0 100644 --- a/src/microservice/adapter/countries.module.ts +++ b/src/microservice/adapter/countries.module.ts @@ -16,6 +16,7 @@ import { GetCountriesService } from '../domain/service/countries/get-countries.s MongooseModule.forFeature([{ name: Country.name, schema: CountrySchema }]) ], controllers: [CountriesController], - providers: [CountriesMongoose, GetCountriesService] + providers: [CountriesMongoose, GetCountriesService], + exports: [CountriesMongoose] }) export class CountriesModule {} diff --git a/src/microservice/adapter/neighborhoods.module.ts b/src/microservice/adapter/neighborhoods.module.ts index ea06b1a..5926fa9 100644 --- a/src/microservice/adapter/neighborhoods.module.ts +++ b/src/microservice/adapter/neighborhoods.module.ts @@ -12,22 +12,12 @@ import { } from '../domain/schemas/neighborhood.schema'; import { MongooseModule } from '@nestjs/mongoose'; import { SaveNeighborhoodsByCityService } from '../domain/service/neighborhoods/save-neighborhoods-by-city.service'; -import { Country, CountrySchema } from '../domain/schemas/country.schema'; -import { ValidateCountryByNameOrAliasService } from '../domain/service/countries/validate-country-by-name-or-alias.service'; -import { CountriesMongoose } from './repository/countries/countries-mongoose.repository'; -import { State, StateSchema } from '../domain/schemas/state.schema'; -import { ValidateStateByNameOrAliasService } from '../domain/service/states/validate-state-by-name-or-alias.service'; -import { StatesMongoose } from './repository/states/states-mongoose.repository'; -import { City, CitySchema } from '../domain/schemas/city.schema'; -import { ValidateCityByNameOrAliasService } from '../domain/service/cities/validate-city-by-name-or-alias.service'; -import { CitiesMongoose } from './repository/cities/cities-mongoose.repository'; import { GetNeighborhoodsByStateService } from '../domain/service/neighborhoods/get/get-neighborhoods-by-state.service'; -import { ValidateInputParamsService } from '../domain/service/validate/validate-input-params.service'; import { SeedNeighborhoodsByStateService } from '../domain/service/neighborhoods/seed/seed-neighborhoods-by-state.service'; -import { GetCitiesByStateService } from '../domain/service/cities/get/get-cities-by-state.service'; import { LogSeed, LogSeedSchema } from '../domain/schemas/logseed.schema'; import { LogSeedMongoose } from './repository/logseed/logseed-mongoose.repository'; import { LogSeedJobService } from '../domain/service/logseed/log-seed-job.service'; +import { CitiesModule } from './cities.module'; @Module({ imports: [ @@ -38,11 +28,9 @@ import { LogSeedJobService } from '../domain/service/logseed/log-seed-job.servic }), MongooseModule.forFeature([ { name: Neighborhood.name, schema: NeighborhoodSchema }, - { name: Country.name, schema: CountrySchema }, - { name: State.name, schema: StateSchema }, - { name: City.name, schema: CitySchema }, { name: LogSeed.name, schema: LogSeedSchema } - ]) + ]), + CitiesModule ], controllers: [NeighborhoodsController], providers: [ @@ -51,20 +39,12 @@ import { LogSeedJobService } from '../domain/service/logseed/log-seed-job.servic useClass: GuiaMaisRepository }, NeighborhoodsMongoose, - CountriesMongoose, - StatesMongoose, - CitiesMongoose, LogSeedMongoose, GetNeighborhoodsByCityService, GetNeighborhoodsByStateService, SaveNeighborhoodsByCityService, - ValidateCountryByNameOrAliasService, - ValidateStateByNameOrAliasService, - ValidateCityByNameOrAliasService, - ValidateInputParamsService, SeedNeighborhoodsByStateService, - LogSeedJobService, - GetCitiesByStateService + LogSeedJobService ] }) export class NeighborhoodsModule {} diff --git a/src/microservice/adapter/states.module.ts b/src/microservice/adapter/states.module.ts index d826f81..13b94b1 100644 --- a/src/microservice/adapter/states.module.ts +++ b/src/microservice/adapter/states.module.ts @@ -2,14 +2,13 @@ import { Module } from '@nestjs/common'; import { ConfigModule } from '@nestjs/config'; import configuration from '../../config/configuration'; import { MongooseModule } from '@nestjs/mongoose'; -import { Country, CountrySchema } from '../domain/schemas/country.schema'; -import { ValidateCountryByNameOrAliasService } from '../domain/service/countries/validate-country-by-name-or-alias.service'; -import { CountriesMongoose } from './repository/countries/countries-mongoose.repository'; import { State, StateSchema } from '../domain/schemas/state.schema'; import { ValidateStateByNameOrAliasService } from '../domain/service/states/validate-state-by-name-or-alias.service'; import { StatesMongoose } from './repository/states/states-mongoose.repository'; import { GetStateByCountryService } from '../domain/service/states/get-states-by-country.service'; import { StatesController } from './controller/states.controller'; +import { CountriesModule } from './countries.module'; +import { ValidateCountryByNameOrAliasService } from '../domain/service/countries/validate-country-by-name-or-alias.service'; @Module({ imports: [ @@ -17,18 +16,20 @@ import { StatesController } from './controller/states.controller'; isGlobal: true, load: [configuration] }), - MongooseModule.forFeature([ - { name: Country.name, schema: CountrySchema }, - { name: State.name, schema: StateSchema } - ]) + MongooseModule.forFeature([{ name: State.name, schema: StateSchema }]), + CountriesModule ], controllers: [StatesController], providers: [ - CountriesMongoose, StatesMongoose, - ValidateCountryByNameOrAliasService, ValidateStateByNameOrAliasService, + ValidateCountryByNameOrAliasService, GetStateByCountryService + ], + exports: [ + StatesMongoose, + ValidateCountryByNameOrAliasService, + ValidateStateByNameOrAliasService ] }) export class StatesModule {} From 954f026bb5a808a4f4e175b326bd103bd47c8b4d Mon Sep 17 00:00:00 2001 From: Maick Speck Date: Mon, 27 Jun 2022 15:13:18 -0300 Subject: [PATCH 16/39] fix unit tests new searches --- src/microservice/adapter/controller/cities.controller.ts | 2 +- src/microservice/adapter/controller/countries.controller.ts | 2 +- .../domain/service/countries/get-countries.service.ts | 2 +- .../service/validate/validate-input-params.service.spec.ts | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/microservice/adapter/controller/cities.controller.ts b/src/microservice/adapter/controller/cities.controller.ts index 28ecf7d..b6a85d8 100644 --- a/src/microservice/adapter/controller/cities.controller.ts +++ b/src/microservice/adapter/controller/cities.controller.ts @@ -3,7 +3,7 @@ import { NestResponse } from '../../../core/http/nest-response'; import { AbstractController } from '../../domain/controller/abstract-controller'; import { GetCitiesByStateService } from '../../domain/service/cities/get/get-cities-by-state.service'; import { SearchCitiesInput } from '../../domain/model/search/cities/search-cities-input.model'; -import { GetCitiesByCountryService } from 'src/microservice/domain/service/cities/get/get-cities-by-country.service'; +import { GetCitiesByCountryService } from '../../domain/service/cities/get/get-cities-by-country.service'; @Controller('cities') export class CitiesController extends AbstractController { diff --git a/src/microservice/adapter/controller/countries.controller.ts b/src/microservice/adapter/controller/countries.controller.ts index fa0194d..b259afe 100644 --- a/src/microservice/adapter/controller/countries.controller.ts +++ b/src/microservice/adapter/controller/countries.controller.ts @@ -1,7 +1,7 @@ import { Controller, Get, HttpStatus } from '@nestjs/common'; import { NestResponse } from '../../../core/http/nest-response'; import { AbstractController } from '../../domain/controller/abstract-controller'; -import { GetCountriesService } from 'src/microservice/domain/service/countries/get-countries.service'; +import { GetCountriesService } from '../../domain/service/countries/get-countries.service'; @Controller('countries') export class CountriesController extends AbstractController { diff --git a/src/microservice/domain/service/countries/get-countries.service.ts b/src/microservice/domain/service/countries/get-countries.service.ts index bfc7d2c..0217045 100644 --- a/src/microservice/domain/service/countries/get-countries.service.ts +++ b/src/microservice/domain/service/countries/get-countries.service.ts @@ -1,5 +1,5 @@ import { Injectable } from '@nestjs/common'; -import { CountriesMongoose } from 'src/microservice/adapter/repository/countries/countries-mongoose.repository'; +import { CountriesMongoose } from '../../../adapter/repository/countries/countries-mongoose.repository'; import { CountryResponse } from '../../model/countries/country-response.model'; import { CountriesService } from './countries.service'; diff --git a/test/unit/microservice/domain/service/validate/validate-input-params.service.spec.ts b/test/unit/microservice/domain/service/validate/validate-input-params.service.spec.ts index f0b29f0..f0f054b 100644 --- a/test/unit/microservice/domain/service/validate/validate-input-params.service.spec.ts +++ b/test/unit/microservice/domain/service/validate/validate-input-params.service.spec.ts @@ -116,7 +116,7 @@ describe('ValidateInputParamsService', () => { .returns(state); const mockConvertedSearch = () => { - return { country, state, city: null }; + return { country, state }; }; const searchParams = new SearchNeighborhoodsInput('brasil', 'sc'); From ad47dfde76f5473d6f4aff8be2019c626b9ff296 Mon Sep 17 00:00:00 2001 From: Maick Speck Date: Mon, 27 Jun 2022 16:05:01 -0300 Subject: [PATCH 17/39] get cities --- .../adapter/controller/states.controller.ts | 4 +- src/microservice/adapter/states.module.ts | 4 +- .../states/get-states-by-country.service.ts | 2 +- .../get/get-cities-by-country.service.spec.ts | 82 +++++++++++++++++ .../get/get-cities-by-state.service.spec.ts | 39 ++++++++- .../get-cities-by-country.service.spec.ts | 87 +++++++++++++++++++ 6 files changed, 211 insertions(+), 7 deletions(-) create mode 100644 test/unit/microservice/domain/service/cities/get/get-cities-by-country.service.spec.ts create mode 100644 test/unit/microservice/domain/service/states/get-cities-by-country.service.spec.ts diff --git a/src/microservice/adapter/controller/states.controller.ts b/src/microservice/adapter/controller/states.controller.ts index be3a70e..6574378 100644 --- a/src/microservice/adapter/controller/states.controller.ts +++ b/src/microservice/adapter/controller/states.controller.ts @@ -1,12 +1,12 @@ import { Controller, Get, HttpStatus, Param } from '@nestjs/common'; -import { GetStateByCountryService } from '../../domain/service/states/get-states-by-country.service'; +import { GetStatesByCountryService } from '../../domain/service/states/get-states-by-country.service'; import { NestResponse } from '../../../core/http/nest-response'; import { AbstractController } from '../../domain/controller/abstract-controller'; @Controller('states') export class StatesController extends AbstractController { constructor( - private readonly getStatesByCountryService: GetStateByCountryService + private readonly getStatesByCountryService: GetStatesByCountryService ) { super(); } diff --git a/src/microservice/adapter/states.module.ts b/src/microservice/adapter/states.module.ts index 13b94b1..9c44cad 100644 --- a/src/microservice/adapter/states.module.ts +++ b/src/microservice/adapter/states.module.ts @@ -5,7 +5,7 @@ import { MongooseModule } from '@nestjs/mongoose'; import { State, StateSchema } from '../domain/schemas/state.schema'; import { ValidateStateByNameOrAliasService } from '../domain/service/states/validate-state-by-name-or-alias.service'; import { StatesMongoose } from './repository/states/states-mongoose.repository'; -import { GetStateByCountryService } from '../domain/service/states/get-states-by-country.service'; +import { GetStatesByCountryService } from '../domain/service/states/get-states-by-country.service'; import { StatesController } from './controller/states.controller'; import { CountriesModule } from './countries.module'; import { ValidateCountryByNameOrAliasService } from '../domain/service/countries/validate-country-by-name-or-alias.service'; @@ -24,7 +24,7 @@ import { ValidateCountryByNameOrAliasService } from '../domain/service/countries StatesMongoose, ValidateStateByNameOrAliasService, ValidateCountryByNameOrAliasService, - GetStateByCountryService + GetStatesByCountryService ], exports: [ StatesMongoose, diff --git a/src/microservice/domain/service/states/get-states-by-country.service.ts b/src/microservice/domain/service/states/get-states-by-country.service.ts index e4b4373..1d17b9f 100644 --- a/src/microservice/domain/service/states/get-states-by-country.service.ts +++ b/src/microservice/domain/service/states/get-states-by-country.service.ts @@ -6,7 +6,7 @@ import { ValidateCountryByNameOrAliasService } from '../countries/validate-count import { StatesService } from './states.service'; @Injectable() -export class GetStateByCountryService extends StatesService { +export class GetStatesByCountryService extends StatesService { constructor( mongoRepository: StatesMongoose, protected readonly validateCountryService: ValidateCountryByNameOrAliasService diff --git a/test/unit/microservice/domain/service/cities/get/get-cities-by-country.service.spec.ts b/test/unit/microservice/domain/service/cities/get/get-cities-by-country.service.spec.ts new file mode 100644 index 0000000..92032a9 --- /dev/null +++ b/test/unit/microservice/domain/service/cities/get/get-cities-by-country.service.spec.ts @@ -0,0 +1,82 @@ +import { Test, TestingModule } from '@nestjs/testing'; +import { expect } from 'chai'; +import * as sinon from 'sinon'; +import '../../../../../../../src/microservice/adapter/helper/extensions/exensions.module'; +import { ValidateInputParamsService } from '../../../../../../../src/microservice/domain/service/validate/validate-input-params.service'; +import { City } from '../../../../../../../src/microservice/domain/schemas/city.schema'; +import { CitiesMongoose } from '../../../../../../../src/microservice/adapter/repository/cities/cities-mongoose.repository'; +import { GetCitiesByCountryService } from '../../../../../../../src/microservice/domain/service/cities/get/get-cities-by-country.service'; +import { ValidateCountryByNameOrAliasService } from '../../../../../../../src/microservice/domain/service/countries/validate-country-by-name-or-alias.service'; + +describe('GetCitiesByCountryService', () => { + let sut: GetCitiesByCountryService; + + const mockCitiesMongooseRepository = { + findBySearchParams: () => { + return []; + } + }; + + const mockValidateService = { + validateAndConvertSearchByState: () => { + return {}; + }, + validateAndConvertSearchByCity: () => { + return {}; + } + }; + + const mockValidateCountryService = { + validateCountry: () => { + return {}; + } + }; + + const mockCities = () => { + const city1 = new City(); + city1.name = 'any'; + + const city2 = new City(); + city2.name = 'any'; + return [city1, city2]; + }; + + beforeEach(async () => { + const app: TestingModule = await Test.createTestingModule({ + imports: [], + controllers: [], + providers: [ + { + provide: CitiesMongoose, + useValue: mockCitiesMongooseRepository + }, + { + provide: ValidateInputParamsService, + useFactory: () => mockValidateService + }, + { + provide: ValidateCountryByNameOrAliasService, + useFactory: () => mockValidateCountryService + }, + GetCitiesByCountryService + ] + }).compile(); + + sut = app.get(GetCitiesByCountryService); + }); + + describe('getCitiesByCountry', () => { + it('should call getCitiesByCountry and return an array', async () => { + const arrMockCities = mockCities(); + const getCitiesStub = sinon + .stub(mockCitiesMongooseRepository, 'findBySearchParams') + .returns(arrMockCities); + + const actual = await sut.getCitiesByCountry('any'); + + expect(actual).to.be.equal(arrMockCities); + + getCitiesStub.restore(); + }); + }); +}); diff --git a/test/unit/microservice/domain/service/cities/get/get-cities-by-state.service.spec.ts b/test/unit/microservice/domain/service/cities/get/get-cities-by-state.service.spec.ts index fbcee43..895b4b5 100644 --- a/test/unit/microservice/domain/service/cities/get/get-cities-by-state.service.spec.ts +++ b/test/unit/microservice/domain/service/cities/get/get-cities-by-state.service.spec.ts @@ -8,6 +8,9 @@ import { City } from '../../../../../../../src/microservice/domain/schemas/city. import { GetCitiesByStateService } from '../../../../../../../src/microservice/domain/service/cities/get/get-cities-by-state.service'; import { SearchCitiesDB } from '../../../../../../../src/microservice/domain/model/search/cities/search-cities-db.model'; import { CitiesMongoose } from '../../../../../../../src/microservice/adapter/repository/cities/cities-mongoose.repository'; +import { SearchCitiesInput } from '../../../../../../../src/microservice/domain/model/search/cities/search-cities-input.model'; +import { State } from '../../../../../../../src/microservice/domain/schemas/state.schema'; +import { Country } from '../../../../../../../src/microservice/domain/schemas/country.schema'; describe('GetCitiesByStateService', () => { let sut: GetCitiesByStateService; @@ -41,6 +44,18 @@ describe('GetCitiesByStateService', () => { } }; + const mockConvertedSearch = () => { + const mockCountry = new Country(); + mockCountry.name = 'USA'; + const mockState = new State(); + mockState.name = 'New York'; + mockState.stateCode = 'NY'; + return { + country: mockCountry, + state: mockState + }; + }; + const mockCities = () => { const city1 = new City(); city1.name = 'any'; @@ -91,9 +106,7 @@ describe('GetCitiesByStateService', () => { groupByStub.restore(); }); - }); - describe('findCitiesByState', () => { it('should call findCitiesByState and return an array by puppeteer', async () => { const arrMockCities = mockCities(); const groupByStub = sinon @@ -109,4 +122,26 @@ describe('GetCitiesByStateService', () => { groupByStub.restore(); }); }); + + describe('getCitiesByState', () => { + it('should call getCitiesByState and return an array', async () => { + const arrMockCities = mockCities(); + const groupByStub = sinon + .stub(mockCitiesMongooseRepository, 'findBySearchParams') + .returns(arrMockCities); + + const convertedSearchStub = sinon + .stub(mockValidateService, 'validateAndConvertSearchByState') + .returns(mockConvertedSearch()); + + const searchParams = new SearchCitiesInput('Brazil', 'SC'); + + const actual = await sut.getCitiesByState(searchParams); + + expect(actual).to.be.equal(arrMockCities); + + groupByStub.restore(); + convertedSearchStub.restore(); + }); + }); }); diff --git a/test/unit/microservice/domain/service/states/get-cities-by-country.service.spec.ts b/test/unit/microservice/domain/service/states/get-cities-by-country.service.spec.ts new file mode 100644 index 0000000..297be78 --- /dev/null +++ b/test/unit/microservice/domain/service/states/get-cities-by-country.service.spec.ts @@ -0,0 +1,87 @@ +import { Test, TestingModule } from '@nestjs/testing'; +import { expect } from 'chai'; +import * as sinon from 'sinon'; +import '../../../../../../src/microservice/adapter/helper/extensions/exensions.module'; +import { ValidateInputParamsService } from '../../../../../../src/microservice/domain/service/validate/validate-input-params.service'; +import { State } from '../../../../../../src/microservice/domain/schemas/state.schema'; +import { StatesMongoose } from '../../../../../../src/microservice/adapter/repository/states/states-mongoose.repository'; +import { ValidateCountryByNameOrAliasService } from '../../../../../../src/microservice/domain/service/countries/validate-country-by-name-or-alias.service'; +import { GetStatesByCountryService } from '../../../../../../src/microservice/domain/service/states/get-states-by-country.service'; + +describe('GetStatesByCountryService', () => { + let sut: GetStatesByCountryService; + + const mockCitiesMongooseRepository = { + findBySearchParams: () => { + return []; + } + }; + + const mockValidateService = { + validateAndConvertSearchByState: () => { + return {}; + }, + validateAndConvertSearchByCity: () => { + return {}; + } + }; + + const mockValidateCountryService = { + validateCountry: () => { + return {}; + } + }; + + beforeEach(async () => { + const app: TestingModule = await Test.createTestingModule({ + imports: [], + controllers: [], + providers: [ + { + provide: StatesMongoose, + useValue: mockCitiesMongooseRepository + }, + { + provide: ValidateInputParamsService, + useFactory: () => mockValidateService + }, + { + provide: ValidateCountryByNameOrAliasService, + useFactory: () => mockValidateCountryService + }, + GetStatesByCountryService + ] + }).compile(); + + sut = app.get(GetStatesByCountryService); + }); + + const mockStates = () => { + const state1 = new State(); + state1.id = 1; + state1.name = 'any'; + state1.stateCode = 'SC'; + + const state2 = new State(); + state1.id = 2; + state1.name = 'any'; + state1.stateCode = 'RS'; + + return [state1, state2]; + }; + + describe('getStatesByCountry', () => { + it('should call getStatesByCountry and return an array', async () => { + const arrStates = mockStates(); + const getCitiesStub = sinon + .stub(mockCitiesMongooseRepository, 'findBySearchParams') + .returns(arrStates); + + const actual = await sut.getStatesByCountry('any'); + + expect(actual).to.be.equal(arrStates); + + getCitiesStub.restore(); + }); + }); +}); From d6adebac2496adb3fa97676f373a3eec4b38ce64 Mon Sep 17 00:00:00 2001 From: Maick Speck Date: Mon, 27 Jun 2022 16:17:13 -0300 Subject: [PATCH 18/39] model tests csc --- .../model/cities/citites-by-country.model.spec.ts | 13 +++++++++++++ .../model/cities/citites-by-state.model.spec.ts | 13 +++++++++++++ .../countries/country-response.model.spec.ts | 15 +++++++++++++++ .../model/states/states-by-country.model.spec.ts | 13 +++++++++++++ 4 files changed, 54 insertions(+) create mode 100644 test/unit/microservice/domain/model/cities/citites-by-country.model.spec.ts create mode 100644 test/unit/microservice/domain/model/cities/citites-by-state.model.spec.ts create mode 100644 test/unit/microservice/domain/model/countries/country-response.model.spec.ts create mode 100644 test/unit/microservice/domain/model/states/states-by-country.model.spec.ts diff --git a/test/unit/microservice/domain/model/cities/citites-by-country.model.spec.ts b/test/unit/microservice/domain/model/cities/citites-by-country.model.spec.ts new file mode 100644 index 0000000..beec332 --- /dev/null +++ b/test/unit/microservice/domain/model/cities/citites-by-country.model.spec.ts @@ -0,0 +1,13 @@ +import { expect } from 'chai'; +import { CitiesByCountry } from '../../../../../../src/microservice/domain/model/cities/cities-by-country.model'; + +describe('CitiesByCountry', () => { + it('should instance CitiesByCountry and return the object with the correct properties', async () => { + const model = new CitiesByCountry(); + model.name = 'Torres'; + model.stateCode = 'RS'; + + expect(model.name).to.be.equal('Torres'); + expect(model.stateCode).to.be.equal('RS'); + }); +}); diff --git a/test/unit/microservice/domain/model/cities/citites-by-state.model.spec.ts b/test/unit/microservice/domain/model/cities/citites-by-state.model.spec.ts new file mode 100644 index 0000000..9d41059 --- /dev/null +++ b/test/unit/microservice/domain/model/cities/citites-by-state.model.spec.ts @@ -0,0 +1,13 @@ +import { expect } from 'chai'; +import { CitiesByState } from '../../../../../../src/microservice/domain/model/cities/cities-by-state.model'; + +describe('CitiesByState', () => { + it('should instance CitiesByState and return the object with the correct properties', async () => { + const model = new CitiesByState(); + model.name = 'Torres'; + model.stateCode = 'RS'; + + expect(model.name).to.be.equal('Torres'); + expect(model.stateCode).to.be.equal('RS'); + }); +}); diff --git a/test/unit/microservice/domain/model/countries/country-response.model.spec.ts b/test/unit/microservice/domain/model/countries/country-response.model.spec.ts new file mode 100644 index 0000000..dc4a615 --- /dev/null +++ b/test/unit/microservice/domain/model/countries/country-response.model.spec.ts @@ -0,0 +1,15 @@ +import { expect } from 'chai'; +import { CountryResponse } from '../../../../../../src/microservice/domain/model/countries/country-response.model'; + +describe('CountryResponse', () => { + it('should instance CountryResponse and return the object with the correct properties', async () => { + const model = new CountryResponse(); + model.name = 'Brazil'; + model.iso2 = 'BR'; + model.iso3 = 'BRA'; + + expect(model.name).to.be.equal('Brazil'); + expect(model.iso3).to.be.equal('BRA'); + expect(model.iso2).to.be.equal('BR'); + }); +}); diff --git a/test/unit/microservice/domain/model/states/states-by-country.model.spec.ts b/test/unit/microservice/domain/model/states/states-by-country.model.spec.ts new file mode 100644 index 0000000..20ae5de --- /dev/null +++ b/test/unit/microservice/domain/model/states/states-by-country.model.spec.ts @@ -0,0 +1,13 @@ +import { expect } from 'chai'; +import { StatesByCountry } from '../../../../../../src/microservice/domain/model/states/states-by-country.model'; + +describe('StatesByCountry', () => { + it('should instance StatesByCountry and return the object with the correct properties', async () => { + const model = new StatesByCountry(); + model.name = 'Rio Grande do Sul'; + model.stateCode = 'RS'; + + expect(model.name).to.be.equal('Rio Grande do Sul'); + expect(model.stateCode).to.be.equal('RS'); + }); +}); From e04964ef98525d7e35f31229b5100bb7e712753c Mon Sep 17 00:00:00 2001 From: Maick Speck Date: Mon, 27 Jun 2022 17:08:28 -0300 Subject: [PATCH 19/39] controllers tests --- .../adapter/controller/cities.controller.ts | 4 +- test/mock/mongoose/mock-mongoose.ts | 10 +- .../controller/cities.controller.spec.ts | 107 ++++++++++++++++++ .../controller/countries.controller.spec.ts | 64 +++++++++++ .../controller/states.controller.spec.ts | 78 +++++++++++++ .../countries-mongoose.repository.spec.ts | 27 ++++- .../countries/get-coutnries.service.spec.ts | 58 ++++++++++ ... => get-states-by-country.service.spec.ts} | 0 8 files changed, 343 insertions(+), 5 deletions(-) create mode 100644 test/unit/microservice/adapter/controller/cities.controller.spec.ts create mode 100644 test/unit/microservice/adapter/controller/countries.controller.spec.ts create mode 100644 test/unit/microservice/adapter/controller/states.controller.spec.ts create mode 100644 test/unit/microservice/domain/service/countries/get-coutnries.service.spec.ts rename test/unit/microservice/domain/service/states/{get-cities-by-country.service.spec.ts => get-states-by-country.service.spec.ts} (100%) diff --git a/src/microservice/adapter/controller/cities.controller.ts b/src/microservice/adapter/controller/cities.controller.ts index b6a85d8..cc2c3ca 100644 --- a/src/microservice/adapter/controller/cities.controller.ts +++ b/src/microservice/adapter/controller/cities.controller.ts @@ -15,7 +15,7 @@ export class CitiesController extends AbstractController { } @Get('/state/:country/:state') - async getNeighborhoodsByState( + async getCitiesByState( @Param() params: SearchCitiesInput ): Promise { return this.buildResponse( @@ -25,7 +25,7 @@ export class CitiesController extends AbstractController { } @Get('/country/:country') - async getNeighborhoodsByCountry( + async getCitiesByCountry( @Param('country') country: string ): Promise { return this.buildResponse( diff --git a/test/mock/mongoose/mock-mongoose.ts b/test/mock/mongoose/mock-mongoose.ts index a0e567c..9c2ad39 100644 --- a/test/mock/mongoose/mock-mongoose.ts +++ b/test/mock/mongoose/mock-mongoose.ts @@ -1,7 +1,15 @@ export const mockModelMongoose = { find: () => { return { - exec: jest.fn(() => null) + select: jest.fn(() => { + return { + lean: jest.fn(() => { + return { + exec: jest.fn(() => null) + }; + }) + }; + }) }; }, aggregate: () => { diff --git a/test/unit/microservice/adapter/controller/cities.controller.spec.ts b/test/unit/microservice/adapter/controller/cities.controller.spec.ts new file mode 100644 index 0000000..d113dbc --- /dev/null +++ b/test/unit/microservice/adapter/controller/cities.controller.spec.ts @@ -0,0 +1,107 @@ +import { Test, TestingModule } from '@nestjs/testing'; +import { ConfigModule } from '@nestjs/config'; +import configuration from '../../../../../src/config/configuration'; +import { expect } from 'chai'; +import * as sinon from 'sinon'; +import { ExtensionsModule } from '../../../../../src/microservice/adapter/helper/extensions/exensions.module'; +import { ValidateInputParamsService } from '../../../../../src/microservice/domain/service/validate/validate-input-params.service'; +import { CitiesController } from '../../../../../src/microservice/adapter/controller/cities.controller'; +import { GetCitiesByStateService } from '../../../../../src/microservice/domain/service/cities/get/get-cities-by-state.service'; +import { GetCitiesByCountryService } from '../../../../../src/microservice/domain/service/cities/get/get-cities-by-country.service'; +import { SearchCitiesInput } from '../../../../../src/microservice/domain/model/search/cities/search-cities-input.model'; +import { City } from '../../../../../src/microservice/domain/schemas/city.schema'; + +describe('CitiesController', () => { + let citiesController: CitiesController; + + const mockGetCitiesByStateService = { + getCitiesByState: () => { + return; + } + }; + + const mockGetCitiesByCountryService = { + getCitiesByCountry: () => { + return; + } + }; + + const mockValidateService = { + validateAndConvertSearchByState: () => { + return {}; + }, + validateAndConvertSearchByCity: () => { + return {}; + } + }; + + const mockCities = () => { + const city1 = new City(); + city1.name = 'any'; + + const city2 = new City(); + city2.name = 'any'; + return [city1, city2]; + }; + + beforeEach(async () => { + const app: TestingModule = await Test.createTestingModule({ + imports: [ + ConfigModule.forRoot({ + isGlobal: true, + load: [configuration] + }), + ExtensionsModule + ], + controllers: [CitiesController], + providers: [ + { + provide: GetCitiesByStateService, + useFactory: () => mockGetCitiesByStateService + }, + { + provide: GetCitiesByCountryService, + useFactory: () => mockGetCitiesByCountryService + }, + { + provide: ValidateInputParamsService, + useFactory: () => mockValidateService + } + ] + }).compile(); + + citiesController = app.get(CitiesController); + }); + + describe('getCitiesByState', () => { + it('should call getCitiesByState and return an array', async () => { + const getServiceStub = sinon + .stub(mockGetCitiesByStateService, 'getCitiesByState') + .returns(mockCities()); + + const searchParams = new SearchCitiesInput('brasil', 'sc'); + + const actual = await citiesController.getCitiesByState(searchParams); + + expect(actual.body).to.be.an('array').that.contains; + expect(actual.body).to.have.lengthOf(2); + + getServiceStub.restore(); + }); + }); + + describe('getCitiesByCountry', () => { + it('should call getCitiesByCountry and return an array', async () => { + const getServiceStub = sinon + .stub(mockGetCitiesByCountryService, 'getCitiesByCountry') + .returns(mockCities()); + + const actual = await citiesController.getCitiesByCountry('brasil'); + + expect(actual.body).to.be.an('array').that.contains; + expect(actual.body).to.have.lengthOf(2); + + getServiceStub.restore(); + }); + }); +}); diff --git a/test/unit/microservice/adapter/controller/countries.controller.spec.ts b/test/unit/microservice/adapter/controller/countries.controller.spec.ts new file mode 100644 index 0000000..ac6d4e6 --- /dev/null +++ b/test/unit/microservice/adapter/controller/countries.controller.spec.ts @@ -0,0 +1,64 @@ +import { Test, TestingModule } from '@nestjs/testing'; +import { ConfigModule } from '@nestjs/config'; +import configuration from '../../../../../src/config/configuration'; +import { expect } from 'chai'; +import * as sinon from 'sinon'; +import { ExtensionsModule } from '../../../../../src/microservice/adapter/helper/extensions/exensions.module'; +import { CountriesController } from '../../../../../src/microservice/adapter/controller/countries.controller'; +import { GetCountriesService } from '../../../../../src/microservice/domain/service/countries/get-countries.service'; +import { Country } from '../../../../../src/microservice/domain/schemas/country.schema'; + +describe('CountriesController', () => { + let countriesController: CountriesController; + + const mockGetCountriesService = { + getAll: () => { + return; + } + }; + + const mockCountries = () => { + const country1 = new Country(); + country1.name = 'any'; + + const country2 = new Country(); + country2.name = 'any'; + return [country1, country2]; + }; + + beforeEach(async () => { + const app: TestingModule = await Test.createTestingModule({ + imports: [ + ConfigModule.forRoot({ + isGlobal: true, + load: [configuration] + }), + ExtensionsModule + ], + controllers: [CountriesController], + providers: [ + { + provide: GetCountriesService, + useFactory: () => mockGetCountriesService + } + ] + }).compile(); + + countriesController = app.get(CountriesController); + }); + + describe('getAllCountries', () => { + it('should call getAllCountries and return an array', async () => { + const getServiceStub = sinon + .stub(mockGetCountriesService, 'getAll') + .returns(mockCountries()); + + const actual = await countriesController.getAllCountries(); + + expect(actual.body).to.be.an('array').that.contains; + expect(actual.body).to.have.lengthOf(2); + + getServiceStub.restore(); + }); + }); +}); diff --git a/test/unit/microservice/adapter/controller/states.controller.spec.ts b/test/unit/microservice/adapter/controller/states.controller.spec.ts new file mode 100644 index 0000000..193523a --- /dev/null +++ b/test/unit/microservice/adapter/controller/states.controller.spec.ts @@ -0,0 +1,78 @@ +import { Test, TestingModule } from '@nestjs/testing'; +import { ConfigModule } from '@nestjs/config'; +import configuration from '../../../../../src/config/configuration'; +import { expect } from 'chai'; +import * as sinon from 'sinon'; +import { ExtensionsModule } from '../../../../../src/microservice/adapter/helper/extensions/exensions.module'; +import { ValidateInputParamsService } from '../../../../../src/microservice/domain/service/validate/validate-input-params.service'; +import { StatesController } from '../../../../../src/microservice/adapter/controller/states.controller'; +import { GetStatesByCountryService } from '../../../../../src/microservice/domain/service/states/get-states-by-country.service'; +import { State } from '../../../../../src/microservice/domain/schemas/state.schema'; + +describe('StatesController', () => { + let statesController: StatesController; + + const mockGetStatesByCountryService = { + getStatesByCountry: () => { + return; + } + }; + + const mockValidateService = { + validateAndConvertSearchByState: () => { + return {}; + }, + validateAndConvertSearchByCity: () => { + return {}; + } + }; + + const mockStates = () => { + const state1 = new State(); + state1.name = 'any'; + + const state2 = new State(); + state2.name = 'any'; + return [state1, state2]; + }; + + beforeEach(async () => { + const app: TestingModule = await Test.createTestingModule({ + imports: [ + ConfigModule.forRoot({ + isGlobal: true, + load: [configuration] + }), + ExtensionsModule + ], + controllers: [StatesController], + providers: [ + { + provide: GetStatesByCountryService, + useFactory: () => mockGetStatesByCountryService + }, + { + provide: ValidateInputParamsService, + useFactory: () => mockValidateService + } + ] + }).compile(); + + statesController = app.get(StatesController); + }); + + describe('getStatesByCountry', () => { + it('should call getStatesByCountry and return an array', async () => { + const getServiceStub = sinon + .stub(mockGetStatesByCountryService, 'getStatesByCountry') + .returns(mockStates()); + + const actual = await statesController.getStatesByCountry('brasil'); + + expect(actual.body).to.be.an('array').that.contains; + expect(actual.body).to.have.lengthOf(2); + + getServiceStub.restore(); + }); + }); +}); diff --git a/test/unit/microservice/adapter/repository/countries/countries-mongoose.repository.spec.ts b/test/unit/microservice/adapter/repository/countries/countries-mongoose.repository.spec.ts index ef1e598..6032b21 100644 --- a/test/unit/microservice/adapter/repository/countries/countries-mongoose.repository.spec.ts +++ b/test/unit/microservice/adapter/repository/countries/countries-mongoose.repository.spec.ts @@ -32,6 +32,15 @@ describe('CountriesMongoose', () => { return { exec: jest.fn(() => mockCountries()) }; + }), + select: jest.fn(() => { + return { + lean: jest.fn(() => { + return { + exec: jest.fn(() => mockCountries()) + }; + }) + }; }) }; @@ -55,8 +64,8 @@ describe('CountriesMongoose', () => { await app.close(); }); - describe('findBySearchParams', () => { - it('should call findBySearchParams and return an array', async () => { + describe('findByNameOrAliasOrId', () => { + it('should call findByNameOrAliasOrId and return an array', async () => { const findManyStub = sinon .stub(mockModelMongoose, 'find') .returns(mockFindCountries); @@ -68,4 +77,18 @@ describe('CountriesMongoose', () => { findManyStub.restore(); }); }); + + describe('findAll', () => { + it('should call findAll and return an array', async () => { + const findManyStub = sinon + .stub(mockModelMongoose, 'find') + .returns(mockFindCountries); + + const actual = await sut.findAll(); + + expect(actual).to.be.an('array').that.is.not.empty; + + findManyStub.restore(); + }); + }); }); diff --git a/test/unit/microservice/domain/service/countries/get-coutnries.service.spec.ts b/test/unit/microservice/domain/service/countries/get-coutnries.service.spec.ts new file mode 100644 index 0000000..7fe2d04 --- /dev/null +++ b/test/unit/microservice/domain/service/countries/get-coutnries.service.spec.ts @@ -0,0 +1,58 @@ +import { Test, TestingModule } from '@nestjs/testing'; +import { expect } from 'chai'; +import * as sinon from 'sinon'; +import '../../../../../../src/microservice/adapter/helper/extensions/exensions.module'; +import { CountriesMongoose } from '../../../../../../src/microservice/adapter/repository/countries/countries-mongoose.repository'; +import { GetCountriesService } from '../../../../../../src/microservice/domain/service/countries/get-countries.service'; +import { CountryResponse } from '../../../../../../src/microservice/domain/model/countries/country-response.model'; + +describe('GetCountriesService', () => { + let sut: GetCountriesService; + + const mockMongoose = { + findAll: () => { + return []; + } + }; + + beforeEach(async () => { + const app: TestingModule = await Test.createTestingModule({ + imports: [], + controllers: [], + providers: [ + { + provide: CountriesMongoose, + useValue: mockMongoose + }, + GetCountriesService + ] + }).compile(); + + sut = app.get(GetCountriesService); + }); + + const mockCountries = () => { + const country1 = new CountryResponse(); + country1.id = 1; + country1.name = 'any'; + + const country2 = new CountryResponse(); + country1.id = 2; + country1.name = 'any'; + + return [country1, country2]; + }; + + describe('getAll', () => { + it('should call getAll and return an array', async () => { + const arr = mockCountries(); + const getCitiesStub = sinon.stub(mockMongoose, 'findAll').returns(arr); + + const actual = await sut.getAll(); + + expect(actual).to.be.equal(arr); + + getCitiesStub.restore(); + }); + }); +}); diff --git a/test/unit/microservice/domain/service/states/get-cities-by-country.service.spec.ts b/test/unit/microservice/domain/service/states/get-states-by-country.service.spec.ts similarity index 100% rename from test/unit/microservice/domain/service/states/get-cities-by-country.service.spec.ts rename to test/unit/microservice/domain/service/states/get-states-by-country.service.spec.ts From c2954f6548c27c7647429e9437a0ba1f9d0eb39f Mon Sep 17 00:00:00 2001 From: Maick Speck Date: Mon, 27 Jun 2022 17:28:04 -0300 Subject: [PATCH 20/39] branch test --- .../countries/countries-mongoose.repository.spec.ts | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/test/unit/microservice/adapter/repository/countries/countries-mongoose.repository.spec.ts b/test/unit/microservice/adapter/repository/countries/countries-mongoose.repository.spec.ts index 6032b21..86d3201 100644 --- a/test/unit/microservice/adapter/repository/countries/countries-mongoose.repository.spec.ts +++ b/test/unit/microservice/adapter/repository/countries/countries-mongoose.repository.spec.ts @@ -76,6 +76,18 @@ describe('CountriesMongoose', () => { findManyStub.restore(); }); + + it('should call findByNameOrAliasOrId with number param and return an array', async () => { + const findManyStub = sinon + .stub(mockModelMongoose, 'find') + .returns(mockFindCountries); + + const actual = await sut.findByNameOrAliasOrId('1'); + + expect(actual).to.be.an('array').that.is.not.empty; + + findManyStub.restore(); + }); }); describe('findAll', () => { From a63fe1c4e58aa8387759b836db5c89cafa4c1df6 Mon Sep 17 00:00:00 2001 From: Maick Speck Date: Mon, 27 Jun 2022 17:39:31 -0300 Subject: [PATCH 21/39] doc version --- CHANGELOG.MD | 9 +++++++++ README.md | 15 +++++++++++++-- 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index bc58234..0687e0c 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -32,3 +32,12 @@ All notable changes to this project will be documented in this file. - Route Neighborhoods By State - Route Seed Neighborhoods By State - logSeed Collection + +## [0.0.5] - 2022-06-27 + +### Added + +- Route Cities By State +- Route Cities By Country +- Route States By Country +- Route Countries diff --git a/README.md b/README.md index 95d27af..3aa6ee5 100644 --- a/README.md +++ b/README.md @@ -20,7 +20,10 @@ API to get Places by Local Names. -- Only Neighborhoods for now +- Neighborhoods +- Cities +- States +- Countries ## Installation @@ -81,8 +84,16 @@ After run the server, make a get in browser, postman or similar http://localhost:3000/neighborhoods/city/brazil/sc/orleans ## Neighborhoods By State example http://localhost:3000/neighborhoods/city/brazil/sc +## Cities By State example +http://localhost:3000/cities/brazil/sc +## Cities By Country example +http://localhost:3000/cities/brazil +## States By Country example +http://localhost:3000/states/brazil +## Countries example +http://localhost:3000/countries/ ``` [Swagger](https://app.swaggerhub.com/apis/dev-seeder/Places/1.0.0) -At the moment, it's working only for Brazilians cities and states. +At the moment, it's working only for Brazilians places. From c588c4c666ef15b026021b85d45b022b9a7ceb1c Mon Sep 17 00:00:00 2001 From: Maick Speck Date: Mon, 27 Jun 2022 20:07:19 -0300 Subject: [PATCH 22/39] init swagger openapi --- package-lock.json | 96 ++++++++++++++++++- package.json | 4 +- src/main.ts | 11 +++ .../controller/neighborhoods.controller.ts | 57 ++++++++++- .../helper/extensions/object.extension.ts | 33 ------- .../puppeteer/guia-mais.repository.ts | 4 +- ...eteer-neighborhood-repository.interface.ts | 6 +- .../neighborhood-by-city.model.ts | 31 ++++++ .../neighborhoods-by-state.model.ts | 19 ++++ .../cities/search-cities-input.model.ts | 19 +++- .../search-neighborhoods-dto.model.ts | 49 ++++++++++ .../search-neighborhoods-input.model.ts | 13 --- .../puppeteer-neighborhood.repository.ts | 8 +- .../puppeteer/puppeteer.repository.ts | 4 +- .../get/get-neighborhoods-by-city.service.ts | 6 +- .../get/get-neighborhoods-by-state.service.ts | 4 +- .../save-neighborhoods-by-city.service.ts | 4 +- .../seed-neighborhoods-by-state.service.ts | 6 +- .../validate/validate-input-params.service.ts | 6 +- .../neighborhoods.controller.spec.ts | 8 +- .../extensions/object.extension.spec.ts | 4 +- .../puppeteer/guia-mais.repository.spec.ts | 6 +- .../search-neighborhoods-input.model.spec.ts | 6 +- .../get-neighborhoods-by-city.service.spec.ts | 6 +- ...get-neighborhoods-by-state.service.spec.ts | 4 +- ...save-neighborhoods-by-city.service.spec.ts | 6 +- ...eed-neighborhoods-by-state.service.spec.ts | 10 +- .../validate-input-params.service.spec.ts | 6 +- 28 files changed, 331 insertions(+), 105 deletions(-) delete mode 100644 src/microservice/adapter/helper/extensions/object.extension.ts create mode 100644 src/microservice/domain/model/search/neighborhoods/search-neighborhoods-dto.model.ts delete mode 100644 src/microservice/domain/model/search/neighborhoods/search-neighborhoods-input.model.ts diff --git a/package-lock.json b/package-lock.json index db1940f..13a91a8 100644 --- a/package-lock.json +++ b/package-lock.json @@ -15,6 +15,7 @@ "@nestjs/core": "^8.0.0", "@nestjs/mongoose": "^9.1.0", "@nestjs/platform-express": "^8.0.0", + "@nestjs/swagger": "^5.2.1", "chai": "^4.3.6", "cheerio": "^1.0.0-rc.10", "class-transformer": "^0.5.1", @@ -30,7 +31,8 @@ "rimraf": "^3.0.2", "rxjs": "^7.2.0", "sinon": "^14.0.0", - "superagent": "^7.1.3" + "superagent": "^7.1.3", + "swagger-ui-express": "^4.4.0" }, "devDependencies": { "@nestjs/cli": "^8.0.0", @@ -1468,6 +1470,25 @@ } } }, + "node_modules/@nestjs/mapped-types": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@nestjs/mapped-types/-/mapped-types-1.0.1.tgz", + "integrity": "sha512-NFvofzSinp00j5rzUd4tf+xi9od6383iY0JP7o0Bnu1fuItAUkWBgc4EKuIQ3D+c2QI3i9pG1kDWAeY27EMGtg==", + "peerDependencies": { + "@nestjs/common": "^7.0.8 || ^8.0.0", + "class-transformer": "^0.2.0 || ^0.3.0 || ^0.4.0 || ^0.5.0", + "class-validator": "^0.11.1 || ^0.12.0 || ^0.13.0", + "reflect-metadata": "^0.1.12" + }, + "peerDependenciesMeta": { + "class-transformer": { + "optional": true + }, + "class-validator": { + "optional": true + } + } + }, "node_modules/@nestjs/mongoose": { "version": "9.1.0", "resolved": "https://registry.npmjs.org/@nestjs/mongoose/-/mongoose-9.1.0.tgz", @@ -1516,6 +1537,31 @@ "typescript": "^3.4.5 || ^4.3.5" } }, + "node_modules/@nestjs/swagger": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/@nestjs/swagger/-/swagger-5.2.1.tgz", + "integrity": "sha512-7dNa08WCnTsW/oAk3Ujde+z64JMfNm19DhpXasFR8oJp/9pggYAbYU927HpA+GJsSFJX6adjIRZsCKUqaGWznw==", + "dependencies": { + "@nestjs/mapped-types": "1.0.1", + "lodash": "4.17.21", + "path-to-regexp": "3.2.0" + }, + "peerDependencies": { + "@nestjs/common": "^8.0.0", + "@nestjs/core": "^8.0.0", + "fastify-swagger": "*", + "reflect-metadata": "^0.1.12", + "swagger-ui-express": "*" + }, + "peerDependenciesMeta": { + "fastify-swagger": { + "optional": true + }, + "swagger-ui-express": { + "optional": true + } + } + }, "node_modules/@nestjs/testing": { "version": "8.4.5", "resolved": "https://registry.npmjs.org/@nestjs/testing/-/testing-8.4.5.tgz", @@ -8427,6 +8473,25 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/swagger-ui-dist": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/swagger-ui-dist/-/swagger-ui-dist-4.12.0.tgz", + "integrity": "sha512-B0Iy2ueXtbByE6OOyHTi3lFQkpPi/L7kFOKFeKTr44za7dJIELa9kzaca6GkndCgpK1QTjArnoXG+aUy0XQp1w==" + }, + "node_modules/swagger-ui-express": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/swagger-ui-express/-/swagger-ui-express-4.4.0.tgz", + "integrity": "sha512-1CzRkHG386VQMVZK406jcpgnW2a9A5A/NiAjKhsFTQqUBWRF+uGbXTU/mA7WSV3mTzyOQDvjBdWP/c2qd5lqKw==", + "dependencies": { + "swagger-ui-dist": ">=4.11.0" + }, + "engines": { + "node": ">= v0.10.32" + }, + "peerDependencies": { + "express": ">=4.0.0" + } + }, "node_modules/symbol-observable": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-4.0.0.tgz", @@ -10588,6 +10653,12 @@ "uuid": "8.3.2" } }, + "@nestjs/mapped-types": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@nestjs/mapped-types/-/mapped-types-1.0.1.tgz", + "integrity": "sha512-NFvofzSinp00j5rzUd4tf+xi9od6383iY0JP7o0Bnu1fuItAUkWBgc4EKuIQ3D+c2QI3i9pG1kDWAeY27EMGtg==", + "requires": {} + }, "@nestjs/mongoose": { "version": "9.1.0", "resolved": "https://registry.npmjs.org/@nestjs/mongoose/-/mongoose-9.1.0.tgz", @@ -10619,6 +10690,16 @@ "pluralize": "8.0.0" } }, + "@nestjs/swagger": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/@nestjs/swagger/-/swagger-5.2.1.tgz", + "integrity": "sha512-7dNa08WCnTsW/oAk3Ujde+z64JMfNm19DhpXasFR8oJp/9pggYAbYU927HpA+GJsSFJX6adjIRZsCKUqaGWznw==", + "requires": { + "@nestjs/mapped-types": "1.0.1", + "lodash": "4.17.21", + "path-to-regexp": "3.2.0" + } + }, "@nestjs/testing": { "version": "8.4.5", "resolved": "https://registry.npmjs.org/@nestjs/testing/-/testing-8.4.5.tgz", @@ -15890,6 +15971,19 @@ "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", "dev": true }, + "swagger-ui-dist": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/swagger-ui-dist/-/swagger-ui-dist-4.12.0.tgz", + "integrity": "sha512-B0Iy2ueXtbByE6OOyHTi3lFQkpPi/L7kFOKFeKTr44za7dJIELa9kzaca6GkndCgpK1QTjArnoXG+aUy0XQp1w==" + }, + "swagger-ui-express": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/swagger-ui-express/-/swagger-ui-express-4.4.0.tgz", + "integrity": "sha512-1CzRkHG386VQMVZK406jcpgnW2a9A5A/NiAjKhsFTQqUBWRF+uGbXTU/mA7WSV3mTzyOQDvjBdWP/c2qd5lqKw==", + "requires": { + "swagger-ui-dist": ">=4.11.0" + } + }, "symbol-observable": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-4.0.0.tgz", diff --git a/package.json b/package.json index 7743384..f85dc81 100644 --- a/package.json +++ b/package.json @@ -30,6 +30,7 @@ "@nestjs/core": "^8.0.0", "@nestjs/mongoose": "^9.1.0", "@nestjs/platform-express": "^8.0.0", + "@nestjs/swagger": "^5.2.1", "chai": "^4.3.6", "cheerio": "^1.0.0-rc.10", "class-transformer": "^0.5.1", @@ -45,7 +46,8 @@ "rimraf": "^3.0.2", "rxjs": "^7.2.0", "sinon": "^14.0.0", - "superagent": "^7.1.3" + "superagent": "^7.1.3", + "swagger-ui-express": "^4.4.0" }, "devDependencies": { "@nestjs/cli": "^8.0.0", diff --git a/src/main.ts b/src/main.ts index 7e3f12a..d92028f 100644 --- a/src/main.ts +++ b/src/main.ts @@ -3,6 +3,7 @@ import { ConfigService } from '@nestjs/config'; import { NestFactory } from '@nestjs/core'; import { useContainer } from 'class-validator'; import { AppModule } from './app.module'; +import { SwaggerModule, DocumentBuilder } from '@nestjs/swagger'; async function bootstrap() { const app = await NestFactory.create(AppModule); @@ -12,6 +13,16 @@ async function bootstrap() { }) ); useContainer(app.select(AppModule), { fallbackOnErrors: true }); + + const config = new DocumentBuilder() + .setTitle('Places') + .setDescription('Places API') + .setVersion('1.0') + .build(); + + const document = SwaggerModule.createDocument(app, config); + SwaggerModule.setup('api', app, document); + const configService = app.get(ConfigService); return await app.listen(configService.get('api.port')); } diff --git a/src/microservice/adapter/controller/neighborhoods.controller.ts b/src/microservice/adapter/controller/neighborhoods.controller.ts index f71d23f..ec57f23 100644 --- a/src/microservice/adapter/controller/neighborhoods.controller.ts +++ b/src/microservice/adapter/controller/neighborhoods.controller.ts @@ -3,9 +3,18 @@ import { GetNeighborhoodsByStateService } from '../../domain/service/neighborhoo import { NestResponse } from '../../../core/http/nest-response'; import { AbstractController } from '../../domain/controller/abstract-controller'; import { GetNeighborhoodsByCityService } from '../../domain/service/neighborhoods/get/get-neighborhoods-by-city.service'; -import { SearchNeighborhoodsInput } from '../../domain/model/search/neighborhoods/search-neighborhoods-input.model'; +import { SearchNeighborhoodsDTO } from '../../domain/model/search/neighborhoods/search-neighborhoods-dto.model'; import { SeedNeighborhoodsByStateService } from '../../domain/service/neighborhoods/seed/seed-neighborhoods-by-state.service'; +import { + ApiExcludeEndpoint, + ApiOkResponse, + ApiParam, + ApiTags +} from '@nestjs/swagger'; +import { NeighborhoodByCity } from 'src/microservice/domain/model/neighborhoods/neighborhood-by-city.model'; +import { NeighborhoodsByState } from 'src/microservice/domain/model/neighborhoods/neighborhoods-by-state.model'; +@ApiTags('neighborhoods') @Controller('neighborhoods') export class NeighborhoodsController extends AbstractController { constructor( @@ -16,9 +25,32 @@ export class NeighborhoodsController extends AbstractController { super(); } + @ApiOkResponse({ + description: 'Neighborhoods found.', + isArray: true, + type: NeighborhoodByCity + }) + @ApiParam({ + name: 'country', + required: true, + description: 'The Country name of the neighborhood', + type: String + }) + @ApiParam({ + name: 'state', + required: true, + description: 'The State name of the neighborhood', + type: String + }) + @ApiParam({ + name: 'city', + required: true, + description: 'The City name of the neighborhood', + type: String + }) @Get('/city/:country/:state/:city') async getNeighborhoodsByCity( - @Param() params: SearchNeighborhoodsInput + @Param() params: SearchNeighborhoodsDTO ): Promise { return this.buildResponse( HttpStatus.OK, @@ -26,9 +58,25 @@ export class NeighborhoodsController extends AbstractController { ); } + @ApiOkResponse({ + description: 'Neighborhoods found.', + type: NeighborhoodsByState + }) + @ApiParam({ + name: 'country', + required: true, + description: 'The Country name of the neighborhood', + type: String + }) + @ApiParam({ + name: 'state', + required: true, + description: 'The State name of the neighborhood', + type: String + }) @Get('/state/:country/:state') async getNeighborhoodsByState( - @Param() params: SearchNeighborhoodsInput + @Param() params: SearchNeighborhoodsDTO ): Promise { return this.buildResponse( HttpStatus.OK, @@ -36,9 +84,10 @@ export class NeighborhoodsController extends AbstractController { ); } + @ApiExcludeEndpoint() @Get('/seed/state/:country/:state') async seedNeighborhoodsByState( - @Param() params: SearchNeighborhoodsInput + @Param() params: SearchNeighborhoodsDTO ): Promise { return this.buildResponse( HttpStatus.OK, diff --git a/src/microservice/adapter/helper/extensions/object.extension.ts b/src/microservice/adapter/helper/extensions/object.extension.ts deleted file mode 100644 index 3662288..0000000 --- a/src/microservice/adapter/helper/extensions/object.extension.ts +++ /dev/null @@ -1,33 +0,0 @@ -/* eslint-disable @typescript-eslint/no-this-alias */ -import { EmptyPropException } from '../../../../core/error-handling/exception/empty-prop.exception'; - -declare global { - interface Object { - validateIsAnyEmptyKey(): void; - getMethods(): string[]; - } -} - -Object.prototype.validateIsAnyEmptyKey = function () { - const context = this; - Object.keys(this).forEach(function (key) { - if (context[key].length === 0) throw new EmptyPropException(key); - }); -}; - -Object.prototype.getMethods = (): any[] => { - const properties = new Set(); - let currentObj = this; - const obj = this; - do { - Object.getOwnPropertyNames(currentObj).forEach((item) => - properties.add(item) - ); - } while ((currentObj = Object.getPrototypeOf(currentObj))); - return [...properties.keys()].filter( - (item: string) => - typeof obj !== 'undefined' && typeof obj[item] === 'function' - ); -}; - -export {}; diff --git a/src/microservice/adapter/repository/neighborhoods/puppeteer/guia-mais.repository.ts b/src/microservice/adapter/repository/neighborhoods/puppeteer/guia-mais.repository.ts index 661bd7c..ac52c37 100644 --- a/src/microservice/adapter/repository/neighborhoods/puppeteer/guia-mais.repository.ts +++ b/src/microservice/adapter/repository/neighborhoods/puppeteer/guia-mais.repository.ts @@ -3,7 +3,7 @@ import { ConfigService } from '@nestjs/config'; import { CheerioAPI } from 'cheerio'; import { InjectPage } from 'nest-puppeteer'; import { NeighborhoodByCity } from '../../../../domain/model/neighborhoods/neighborhood-by-city.model'; -import { SearchNeighborhoodsInput } from '../../../../domain/model/search/neighborhoods/search-neighborhoods-input.model'; +import { SearchNeighborhoodsDTO } from '../../../../domain/model/search/neighborhoods/search-neighborhoods-dto.model'; import { IPuppeteerNeighborhoodRepository } from '../../../../domain/interface/puppeteer/repository/puppeteer-neighborhood-repository.interface'; import { PuppeteerNeighborhoodRepository } from '../../../../domain/repository/puppeteer/neighborhood/puppeteer-neighborhood.repository'; import { Page } from '../../../../domain/interface/puppeteer/page.interface'; @@ -50,7 +50,7 @@ export class GuiaMaisRepository } async callEndpoint( - searchParams: SearchNeighborhoodsInput + searchParams: SearchNeighborhoodsDTO ): Promise { const url = `${this.url}/${searchParams.city}-${searchParams.state}`; return this.getDocumentHtml(url); diff --git a/src/microservice/domain/interface/puppeteer/repository/puppeteer-neighborhood-repository.interface.ts b/src/microservice/domain/interface/puppeteer/repository/puppeteer-neighborhood-repository.interface.ts index cf3c18d..38bfcd1 100644 --- a/src/microservice/domain/interface/puppeteer/repository/puppeteer-neighborhood-repository.interface.ts +++ b/src/microservice/domain/interface/puppeteer/repository/puppeteer-neighborhood-repository.interface.ts @@ -1,4 +1,4 @@ -import { SearchNeighborhoodsInput } from '../../../model/search/neighborhoods/search-neighborhoods-input.model'; +import { SearchNeighborhoodsDTO } from '../../../model/search/neighborhoods/search-neighborhoods-dto.model'; import { NeighborhoodByCity } from '../../../model/neighborhoods/neighborhood-by-city.model'; import { IPuppeteerRepository } from './puppeteer-repository.interface'; import { EnumTranslations } from '../../../enumerators/enum-translations.enumerator'; @@ -7,12 +7,12 @@ import { ValidOutputSearchByCity } from '../../valid-output-search/valid-outpu-s export interface IPuppeteerNeighborhoodRepository extends IPuppeteerRepository< NeighborhoodByCity, - SearchNeighborhoodsInput, + SearchNeighborhoodsDTO, ValidOutputSearchByCity > { language: EnumTranslations; getNeighborhoodsByCity( - searchParams: SearchNeighborhoodsInput, + searchParams: SearchNeighborhoodsDTO, convertedSearch: ValidOutputSearchByCity ): Promise; } diff --git a/src/microservice/domain/model/neighborhoods/neighborhood-by-city.model.ts b/src/microservice/domain/model/neighborhoods/neighborhood-by-city.model.ts index c88a40e..3703473 100644 --- a/src/microservice/domain/model/neighborhoods/neighborhood-by-city.model.ts +++ b/src/microservice/domain/model/neighborhoods/neighborhood-by-city.model.ts @@ -1,7 +1,38 @@ +import { ApiProperty } from '@nestjs/swagger'; + export class NeighborhoodByCity { + @ApiProperty({ + type: String, + description: 'The name of the Neighborhood', + example: 'Alto Paraná' + }) name: string; + + @ApiProperty({ + type: Number, + description: 'The id reference of the City in database', + example: 1 + }) cityId: number; + + @ApiProperty({ + type: String, + description: `The name of the City's Neighborhood`, + example: 'Orleans' + }) city: string; + + @ApiProperty({ + type: Number, + description: 'The id reference of the state in database', + example: 2014 + }) stateId: number; + + @ApiProperty({ + type: Number, + description: 'The id reference of the country in database', + example: 31 + }) countryId: number; } diff --git a/src/microservice/domain/model/neighborhoods/neighborhoods-by-state.model.ts b/src/microservice/domain/model/neighborhoods/neighborhoods-by-state.model.ts index 46ae889..a3a6907 100644 --- a/src/microservice/domain/model/neighborhoods/neighborhoods-by-state.model.ts +++ b/src/microservice/domain/model/neighborhoods/neighborhoods-by-state.model.ts @@ -1,9 +1,28 @@ +import { ApiProperty } from '@nestjs/swagger'; + export class NeighborhoodsByState { [key: string]: NeighborhooodAggregatedByCity[]; } export class NeighborhooodAggregatedByCity { + @ApiProperty({ + type: String, + description: 'The name of the Neighborhood', + example: 'Alto Paraná' + }) name: string; + + @ApiProperty({ + type: Number, + description: 'The id reference of the City in database', + example: 1 + }) cityId: number; + + @ApiProperty({ + type: String, + description: 'The name of the state', + example: 'Santa Catarina - BRA' + }) state: string; } diff --git a/src/microservice/domain/model/search/cities/search-cities-input.model.ts b/src/microservice/domain/model/search/cities/search-cities-input.model.ts index e3101d9..8c4ae4e 100644 --- a/src/microservice/domain/model/search/cities/search-cities-input.model.ts +++ b/src/microservice/domain/model/search/cities/search-cities-input.model.ts @@ -1,3 +1,20 @@ +import { ApiProperty } from '@nestjs/swagger'; + export class SearchCitiesInput { - constructor(public country: string, public state: string) {} + @ApiProperty({ + type: String, + description: 'The country of the City' + }) + public country: string; + + @ApiProperty({ + type: String, + description: 'The state of the City' + }) + public state: string; + + constructor(country: string, state: string) { + this.country = country; + this.state = state; + } } diff --git a/src/microservice/domain/model/search/neighborhoods/search-neighborhoods-dto.model.ts b/src/microservice/domain/model/search/neighborhoods/search-neighborhoods-dto.model.ts new file mode 100644 index 0000000..fe00b0a --- /dev/null +++ b/src/microservice/domain/model/search/neighborhoods/search-neighborhoods-dto.model.ts @@ -0,0 +1,49 @@ +import { ApiProperty } from '@nestjs/swagger'; +import { EmptyPropException } from 'src/core/error-handling/exception/empty-prop.exception'; + +export class DTO { + validateIsAnyEmptyKey() { + // eslint-disable-next-line @typescript-eslint/no-this-alias + const context = this; + Object.keys(this).forEach(function (key) { + if (context[key].length === 0) throw new EmptyPropException(key); + }); + } +} + +export class SearchNeighborhoodsDTO extends DTO { + @ApiProperty({ + type: String, + description: 'The name of the Neighborhood' + }) + public name: string; + + @ApiProperty({ + type: String, + description: 'The country of the Neighborhood' + }) + public country: string; + + @ApiProperty({ + type: String, + description: 'The state of the Neighborhood' + }) + public state: string; + + @ApiProperty({ + type: String, + description: 'The city of the Neighborhood' + }) + public city: string; + + constructor(country: string, state: string, city: string = null) { + super(); + this.country = country; + this.state = state; + this.city = city; + } + + setName(name: string) { + this.name = name; + } +} diff --git a/src/microservice/domain/model/search/neighborhoods/search-neighborhoods-input.model.ts b/src/microservice/domain/model/search/neighborhoods/search-neighborhoods-input.model.ts deleted file mode 100644 index e0e4ec0..0000000 --- a/src/microservice/domain/model/search/neighborhoods/search-neighborhoods-input.model.ts +++ /dev/null @@ -1,13 +0,0 @@ -export class SearchNeighborhoodsInput { - public name: string; - - constructor( - public country: string, - public state: string, - public city: string = null - ) {} - - setName(name: string) { - this.name = name; - } -} diff --git a/src/microservice/domain/repository/puppeteer/neighborhood/puppeteer-neighborhood.repository.ts b/src/microservice/domain/repository/puppeteer/neighborhood/puppeteer-neighborhood.repository.ts index 957af2f..93ff235 100644 --- a/src/microservice/domain/repository/puppeteer/neighborhood/puppeteer-neighborhood.repository.ts +++ b/src/microservice/domain/repository/puppeteer/neighborhood/puppeteer-neighborhood.repository.ts @@ -1,6 +1,6 @@ import { CheerioAPI } from 'cheerio'; import { NeighborhoodByCity } from '../../../model/neighborhoods/neighborhood-by-city.model'; -import { SearchNeighborhoodsInput } from '../../../model/search/neighborhoods/search-neighborhoods-input.model'; +import { SearchNeighborhoodsDTO } from '../../../model/search/neighborhoods/search-neighborhoods-dto.model'; import { PuppeteerRepository } from '../puppeteer.repository'; import { IPuppeteerNeighborhoodRepository } from '../../../interface/puppeteer/repository/puppeteer-neighborhood-repository.interface'; import { NotFoundException } from '../../../../../core/error-handling/exception/not-found.exception'; @@ -13,7 +13,7 @@ export abstract class PuppeteerNeighborhoodRepository { language: EnumTranslations; async getNeighborhoodsByCity( - searchParams: SearchNeighborhoodsInput, + searchParams: SearchNeighborhoodsDTO, convertedSearch: ValidOutputSearchByCity ): Promise { this.validateInput(searchParams); @@ -35,12 +35,12 @@ export abstract class PuppeteerNeighborhoodRepository } abstract buildElementsFromDocument( - _searchParams: SearchNeighborhoodsInput, + _searchParams: SearchNeighborhoodsDTO, convertedSearch: ValidOutputSearchByCity, _$: CheerioAPI ); abstract callEndpoint( - _searchParams: SearchNeighborhoodsInput + _searchParams: SearchNeighborhoodsDTO ): Promise; } diff --git a/src/microservice/domain/repository/puppeteer/puppeteer.repository.ts b/src/microservice/domain/repository/puppeteer/puppeteer.repository.ts index 6fe3b47..0473e62 100644 --- a/src/microservice/domain/repository/puppeteer/puppeteer.repository.ts +++ b/src/microservice/domain/repository/puppeteer/puppeteer.repository.ts @@ -2,7 +2,7 @@ import { Logger } from '@nestjs/common'; import * as cheerio from 'cheerio'; import { CheerioAPI } from 'cheerio'; import { Page } from '../../interface/puppeteer/page.interface'; -import { SearchNeighborhoodsInput } from '../../model/search/neighborhoods/search-neighborhoods-input.model'; +import { SearchNeighborhoodsDTO } from '../../model/search/neighborhoods/search-neighborhoods-dto.model'; export abstract class PuppeteerRepository { protected readonly logger: Logger = new Logger(this.constructor.name); @@ -27,7 +27,7 @@ export abstract class PuppeteerRepository { return this.page.evaluate(() => document.querySelector('*').outerHTML); } - validateInput(searchParams: SearchNeighborhoodsInput) { + validateInput(searchParams: SearchNeighborhoodsDTO) { searchParams.validateIsAnyEmptyKey(); } } diff --git a/src/microservice/domain/service/neighborhoods/get/get-neighborhoods-by-city.service.ts b/src/microservice/domain/service/neighborhoods/get/get-neighborhoods-by-city.service.ts index 5d2400b..9eef8ed 100644 --- a/src/microservice/domain/service/neighborhoods/get/get-neighborhoods-by-city.service.ts +++ b/src/microservice/domain/service/neighborhoods/get/get-neighborhoods-by-city.service.ts @@ -1,6 +1,6 @@ import { Inject, Injectable } from '@nestjs/common'; import { NeighborhoodByCity } from '../../../model/neighborhoods/neighborhood-by-city.model'; -import { SearchNeighborhoodsInput } from '../../../model/search/neighborhoods/search-neighborhoods-input.model'; +import { SearchNeighborhoodsDTO } from '../../../model/search/neighborhoods/search-neighborhoods-dto.model'; import { NeighborhoodsMongoose } from '../../../../adapter/repository/neighborhoods/neighborhoods-mongoose.repository'; import { GuiaMaisRepository } from '../../../../adapter/repository/neighborhoods/puppeteer/guia-mais.repository'; import { SaveNeighborhoodsByCityService } from '../save-neighborhoods-by-city.service'; @@ -22,7 +22,7 @@ export class GetNeighborhoodsByCityService extends NeighborhoodsService { } async getNeighborhoodsByCity( - searchParams: SearchNeighborhoodsInput + searchParams: SearchNeighborhoodsDTO ): Promise { const convertedSearch = await this.validateService.validateAndConvertSearchByCity(searchParams); @@ -48,7 +48,7 @@ export class GetNeighborhoodsByCityService extends NeighborhoodsService { } async searchByPuppeterAndSave( - searchParams: SearchNeighborhoodsInput, + searchParams: SearchNeighborhoodsDTO, convertedSearch: ValidOutputSearchByCity ): Promise { const resPuppeteer = await this.guiaMaisRepository.getNeighborhoodsByCity( diff --git a/src/microservice/domain/service/neighborhoods/get/get-neighborhoods-by-state.service.ts b/src/microservice/domain/service/neighborhoods/get/get-neighborhoods-by-state.service.ts index 0fb8d4e..08cce9f 100644 --- a/src/microservice/domain/service/neighborhoods/get/get-neighborhoods-by-state.service.ts +++ b/src/microservice/domain/service/neighborhoods/get/get-neighborhoods-by-state.service.ts @@ -1,5 +1,5 @@ import { Injectable } from '@nestjs/common'; -import { SearchNeighborhoodsInput } from '../../../model/search/neighborhoods/search-neighborhoods-input.model'; +import { SearchNeighborhoodsDTO } from '../../../model/search/neighborhoods/search-neighborhoods-dto.model'; import { NeighborhoodsMongoose } from '../../../../adapter/repository/neighborhoods/neighborhoods-mongoose.repository'; import { ValidOutputSearchByState } from '../../../interface/valid-output-search/valid-outpu-search.interface'; import { SearchNeighborhoodsDB } from '../../../model/search/neighborhoods/search-neighborhoods-db.model'; @@ -21,7 +21,7 @@ export class GetNeighborhoodsByStateService extends NeighborhoodsService { } async getNeighborhoodsByState( - searchParams: SearchNeighborhoodsInput + searchParams: SearchNeighborhoodsDTO ): Promise { const convertedSearch = await this.validateService.validateAndConvertSearchByState(searchParams); diff --git a/src/microservice/domain/service/neighborhoods/save-neighborhoods-by-city.service.ts b/src/microservice/domain/service/neighborhoods/save-neighborhoods-by-city.service.ts index 58c8600..ff7bd2a 100644 --- a/src/microservice/domain/service/neighborhoods/save-neighborhoods-by-city.service.ts +++ b/src/microservice/domain/service/neighborhoods/save-neighborhoods-by-city.service.ts @@ -2,7 +2,7 @@ import { Injectable } from '@nestjs/common'; import { NeighborhoodByCity } from '../../model/neighborhoods/neighborhood-by-city.model'; import { NeighborhoodsMongoose } from '../../../adapter/repository/neighborhoods/neighborhoods-mongoose.repository'; import { NeighborhoodsMongoBuilder } from '../../../adapter/helper/builder/neighborhoods/neighborhoods-mongo.builder'; -import { SearchNeighborhoodsInput } from '../../model/search/neighborhoods/search-neighborhoods-input.model'; +import { SearchNeighborhoodsDTO } from '../../model/search/neighborhoods/search-neighborhoods-dto.model'; import { NeighborhoodsService } from './neighborhoods.service'; import { ValidOutputSearchByCity } from '../../interface/valid-output-search/valid-outpu-search.interface'; import { Neighborhood } from '../../schemas/neighborhood.schema'; @@ -16,7 +16,7 @@ export class SaveNeighborhoodsByCityService extends NeighborhoodsService { async saveNeighborhoodsByCity( neighborhoodsPuppeteer: NeighborhoodByCity[], - searchParams: SearchNeighborhoodsInput, + searchParams: SearchNeighborhoodsDTO, convertedSearch: ValidOutputSearchByCity ): Promise { const arrDocument = new NeighborhoodsMongoBuilder( diff --git a/src/microservice/domain/service/neighborhoods/seed/seed-neighborhoods-by-state.service.ts b/src/microservice/domain/service/neighborhoods/seed/seed-neighborhoods-by-state.service.ts index 0b803d3..00f98c0 100644 --- a/src/microservice/domain/service/neighborhoods/seed/seed-neighborhoods-by-state.service.ts +++ b/src/microservice/domain/service/neighborhoods/seed/seed-neighborhoods-by-state.service.ts @@ -1,5 +1,5 @@ import { Injectable } from '@nestjs/common'; -import { SearchNeighborhoodsInput } from '../../../model/search/neighborhoods/search-neighborhoods-input.model'; +import { SearchNeighborhoodsDTO } from '../../../model/search/neighborhoods/search-neighborhoods-dto.model'; import { NeighborhoodsService } from '../neighborhoods.service'; import { ValidateInputParamsService } from '../../validate/validate-input-params.service'; import { GetCitiesByStateService } from '../../cities/get/get-cities-by-state.service'; @@ -27,7 +27,7 @@ export class SeedNeighborhoodsByStateService extends NeighborhoodsService { } async seedNeighborhoodsByState( - searchParams: SearchNeighborhoodsInput + searchParams: SearchNeighborhoodsDTO ): Promise { const convertedSearch = await this.validateService.validateAndConvertSearchByState(searchParams); @@ -86,7 +86,7 @@ export class SeedNeighborhoodsByStateService extends NeighborhoodsService { } async seedByCity(convertedSearch: ValidOutputSearchByState, city: City) { - const searchParamsByCity = new SearchNeighborhoodsInput( + const searchParamsByCity = new SearchNeighborhoodsDTO( convertedSearch.country.translations[EnumTranslations.BR], convertedSearch.state.stateCode, city.name diff --git a/src/microservice/domain/service/validate/validate-input-params.service.ts b/src/microservice/domain/service/validate/validate-input-params.service.ts index 964040d..c70198f 100644 --- a/src/microservice/domain/service/validate/validate-input-params.service.ts +++ b/src/microservice/domain/service/validate/validate-input-params.service.ts @@ -1,5 +1,5 @@ import { Injectable } from '@nestjs/common'; -import { SearchNeighborhoodsInput } from '../../model/search/neighborhoods/search-neighborhoods-input.model'; +import { SearchNeighborhoodsDTO } from '../../model/search/neighborhoods/search-neighborhoods-dto.model'; import { ValidOutputSearchByCity, ValidOutputSearchByState @@ -21,7 +21,7 @@ export class ValidateInputParamsService extends AbstractService { } async validateAndConvertSearchByState( - searchParams: SearchNeighborhoodsInput | SearchCitiesInput + searchParams: SearchNeighborhoodsDTO | SearchCitiesInput ): Promise { const country = await this.getCountryService.validateCountry( searchParams.country @@ -34,7 +34,7 @@ export class ValidateInputParamsService extends AbstractService { } async validateAndConvertSearchByCity( - searchParams: SearchNeighborhoodsInput + searchParams: SearchNeighborhoodsDTO ): Promise { const country = await this.getCountryService.validateCountry( searchParams.country diff --git a/test/unit/microservice/adapter/controller/neighborhoods.controller.spec.ts b/test/unit/microservice/adapter/controller/neighborhoods.controller.spec.ts index 369f33f..0cddbd9 100644 --- a/test/unit/microservice/adapter/controller/neighborhoods.controller.spec.ts +++ b/test/unit/microservice/adapter/controller/neighborhoods.controller.spec.ts @@ -8,7 +8,7 @@ import { NeighborhoodByCity } from '../../../../../src/microservice/domain/model import { ExtensionsModule } from '../../../../../src/microservice/adapter/helper/extensions/exensions.module'; import { GetNeighborhoodsByCityService } from '../../../../../src/microservice/domain/service/neighborhoods/get/get-neighborhoods-by-city.service'; import { SaveNeighborhoodsByCityService } from '../../../../../src/microservice/domain/service/neighborhoods/save-neighborhoods-by-city.service'; -import { SearchNeighborhoodsInput } from '../../../../../src/microservice/domain/model/search/neighborhoods/search-neighborhoods-input.model'; +import { SearchNeighborhoodsDTO } from '../../../../../src/microservice/domain/model/search/neighborhoods/search-neighborhoods-dto.model'; import { GetNeighborhoodsByStateService } from '../../../../../src/microservice/domain/service/neighborhoods/get/get-neighborhoods-by-state.service'; import { SeedNeighborhoodsByStateService } from '../../../../../src/microservice/domain/service/neighborhoods/seed/seed-neighborhoods-by-state.service'; import { ValidateInputParamsService } from '../../../../../src/microservice/domain/service/validate/validate-input-params.service'; @@ -114,7 +114,7 @@ describe('NeighborhoodsController', () => { .stub(mockGetNeighborhoodsService, 'getNeighborhoodsByCity') .returns(mockNeighborhoods); - const searchParams = new SearchNeighborhoodsInput( + const searchParams = new SearchNeighborhoodsDTO( 'brasil', 'sc', 'orleans' @@ -137,7 +137,7 @@ describe('NeighborhoodsController', () => { .stub(mockGetNeighborhoodsByStateService, 'getNeighborhoodsByState') .returns(mockNeighborhoods); - const searchParams = new SearchNeighborhoodsInput('brasil', 'sc'); + const searchParams = new SearchNeighborhoodsDTO('brasil', 'sc'); const actual = await neighborhoodsController.getNeighborhoodsByState( searchParams @@ -161,7 +161,7 @@ describe('NeighborhoodsController', () => { .stub(mockSeedNeighborhoodsByStateService, 'seedNeighborhoodsByState') .returns(mockResponseSeed); - const searchParams = new SearchNeighborhoodsInput('brasil', 'sc'); + const searchParams = new SearchNeighborhoodsDTO('brasil', 'sc'); const actual = await neighborhoodsController.seedNeighborhoodsByState( searchParams diff --git a/test/unit/microservice/adapter/helper/extensions/object.extension.spec.ts b/test/unit/microservice/adapter/helper/extensions/object.extension.spec.ts index 961efc6..b023e66 100644 --- a/test/unit/microservice/adapter/helper/extensions/object.extension.spec.ts +++ b/test/unit/microservice/adapter/helper/extensions/object.extension.spec.ts @@ -1,6 +1,6 @@ import '../../../../../../src/microservice/adapter/helper/extensions/exensions.module'; import { expect } from 'chai'; -import { SearchNeighborhoodsInput } from '../../../../../../src/microservice/domain/model/search/neighborhoods/search-neighborhoods-input.model'; +import { SearchNeighborhoodsDTO } from '../../../../../../src/microservice/domain/model/search/neighborhoods/search-neighborhoods-dto.model'; describe('object.extension', () => { describe('getMethods', function () { @@ -13,7 +13,7 @@ describe('object.extension', () => { describe('validateIsAnyEmptyKey', function () { it('Should call validateIsAnyEmptyKey and throw exccption', function () { const validation = () => { - const obj = new SearchNeighborhoodsInput('brasil', 'sc', 'orleans'); + const obj = new SearchNeighborhoodsDTO('brasil', 'sc', 'orleans'); obj.city = ''; obj.validateIsAnyEmptyKey(); }; diff --git a/test/unit/microservice/adapter/repository/neighborhoods/puppeteer/guia-mais.repository.spec.ts b/test/unit/microservice/adapter/repository/neighborhoods/puppeteer/guia-mais.repository.spec.ts index a030bc4..9f70335 100644 --- a/test/unit/microservice/adapter/repository/neighborhoods/puppeteer/guia-mais.repository.spec.ts +++ b/test/unit/microservice/adapter/repository/neighborhoods/puppeteer/guia-mais.repository.spec.ts @@ -4,7 +4,7 @@ import { expect } from 'chai'; import * as sinon from 'sinon'; import { GuiaMaisRepository } from '../../../../../../../src/microservice/adapter/repository/neighborhoods/puppeteer/guia-mais.repository'; import { PuppeteerModule } from 'nest-puppeteer'; -import { SearchNeighborhoodsInput } from '../../../../../../../src/microservice/domain/model/search/neighborhoods/search-neighborhoods-input.model'; +import { SearchNeighborhoodsDTO } from '../../../../../../../src/microservice/domain/model/search/neighborhoods/search-neighborhoods-dto.model'; import * as fs from 'fs'; import { ExtensionsModule } from '../../../../../../../src/microservice/adapter/helper/extensions/exensions.module'; import * as cheerio from 'cheerio'; @@ -74,7 +74,7 @@ describe('GuiaMaisRepository', () => { describe('getNeighborhoodsByCity', () => { it('should call getNeighborhoodsByCity and return an array', async () => { - const mockSearchParams = new SearchNeighborhoodsInput( + const mockSearchParams = new SearchNeighborhoodsDTO( 'brasil', 'sc', 'orleans' @@ -98,7 +98,7 @@ describe('GuiaMaisRepository', () => { describe('callEndpoint', () => { it('should call callEndpoint and call getDocumentHtml with the correct params', async () => { - const mockSearchParams = new SearchNeighborhoodsInput( + const mockSearchParams = new SearchNeighborhoodsDTO( 'brasil', 'sc', 'orleans' diff --git a/test/unit/microservice/domain/model/search/neighborhoods/search-neighborhoods-input.model.spec.ts b/test/unit/microservice/domain/model/search/neighborhoods/search-neighborhoods-input.model.spec.ts index 2e16c4f..9cb337e 100644 --- a/test/unit/microservice/domain/model/search/neighborhoods/search-neighborhoods-input.model.spec.ts +++ b/test/unit/microservice/domain/model/search/neighborhoods/search-neighborhoods-input.model.spec.ts @@ -1,9 +1,9 @@ import { expect } from 'chai'; -import { SearchNeighborhoodsInput } from '../../../../../../../src/microservice/domain/model/search/neighborhoods/search-neighborhoods-input.model'; +import { SearchNeighborhoodsDTO } from '../../../../../../../src/microservice/domain/model/search/neighborhoods/search-neighborhoods-dto.model'; describe('SearchNeighborhoodsInput', () => { it('should instance SearchNeighborhoodsInput and return the object with the correct properties', async () => { - const model = new SearchNeighborhoodsInput('brasil', 'sc', 'praia grande'); + const model = new SearchNeighborhoodsDTO('brasil', 'sc', 'praia grande'); expect(model.country).to.be.equal('brasil'); expect(model.state).to.be.equal('sc'); @@ -11,7 +11,7 @@ describe('SearchNeighborhoodsInput', () => { }); it('should instance SearchNeighborhoodsInput, setName and return the object with the correct properties', async () => { - const model = new SearchNeighborhoodsInput('brasil', 'sc', 'praia grande'); + const model = new SearchNeighborhoodsDTO('brasil', 'sc', 'praia grande'); model.setName('Vila Rosa'); expect(model.country).to.be.equal('brasil'); diff --git a/test/unit/microservice/domain/service/neighborhoods/get/get-neighborhoods-by-city.service.spec.ts b/test/unit/microservice/domain/service/neighborhoods/get/get-neighborhoods-by-city.service.spec.ts index 74fae54..f9b414f 100644 --- a/test/unit/microservice/domain/service/neighborhoods/get/get-neighborhoods-by-city.service.spec.ts +++ b/test/unit/microservice/domain/service/neighborhoods/get/get-neighborhoods-by-city.service.spec.ts @@ -10,7 +10,7 @@ import '../../../../../../../src/microservice/adapter/helper/extensions/exension import { CountriesMongoose } from '../../../../../../../src/microservice/adapter/repository/countries/countries-mongoose.repository'; import { CitiesMongoose } from '../../../../../../../src/microservice/adapter/repository/cities/cities-mongoose.repository'; import { StatesMongoose } from '../../../../../../../src/microservice/adapter/repository/states/states-mongoose.repository'; -import { SearchNeighborhoodsInput } from '../../../../../../../src/microservice/domain/model/search/neighborhoods/search-neighborhoods-input.model'; +import { SearchNeighborhoodsDTO } from '../../../../../../../src/microservice/domain/model/search/neighborhoods/search-neighborhoods-dto.model'; import { ValidateInputParamsService } from '../../../../../../../src/microservice/domain/service/validate/validate-input-params.service'; import { Country } from '../../../../../../../src/microservice/domain/schemas/country.schema'; import { State } from '../../../../../../../src/microservice/domain/schemas/state.schema'; @@ -143,7 +143,7 @@ describe('GetNeighborhoodsByCityService', () => { .stub(mockValidateService, 'validateAndConvertSearchByCity') .returns(mockConvertedSearch()); - const searchParams = new SearchNeighborhoodsInput( + const searchParams = new SearchNeighborhoodsDTO( 'brasil', 'sc', 'orleans' @@ -167,7 +167,7 @@ describe('GetNeighborhoodsByCityService', () => { .stub(mockValidateService, 'validateAndConvertSearchByCity') .returns(mockConvertedSearch()); - const searchParams = new SearchNeighborhoodsInput( + const searchParams = new SearchNeighborhoodsDTO( 'Brazil', 'SC', 'Orleans' diff --git a/test/unit/microservice/domain/service/neighborhoods/get/get-neighborhoods-by-state.service.spec.ts b/test/unit/microservice/domain/service/neighborhoods/get/get-neighborhoods-by-state.service.spec.ts index b171846..a35ecfc 100644 --- a/test/unit/microservice/domain/service/neighborhoods/get/get-neighborhoods-by-state.service.spec.ts +++ b/test/unit/microservice/domain/service/neighborhoods/get/get-neighborhoods-by-state.service.spec.ts @@ -4,7 +4,7 @@ import * as sinon from 'sinon'; import { NeighborhoodsMongoose } from '../../../../../../../src/microservice/adapter/repository/neighborhoods/neighborhoods-mongoose.repository'; import { Neighborhood } from '../../../../../../../src/microservice/domain/schemas/neighborhood.schema'; import '../../../../../../../src/microservice/adapter/helper/extensions/exensions.module'; -import { SearchNeighborhoodsInput } from '../../../../../../../src/microservice/domain/model/search/neighborhoods/search-neighborhoods-input.model'; +import { SearchNeighborhoodsDTO } from '../../../../../../../src/microservice/domain/model/search/neighborhoods/search-neighborhoods-dto.model'; import { ValidateInputParamsService } from '../../../../../../../src/microservice/domain/service/validate/validate-input-params.service'; import { Country } from '../../../../../../../src/microservice/domain/schemas/country.schema'; import { State } from '../../../../../../../src/microservice/domain/schemas/state.schema'; @@ -102,7 +102,7 @@ describe('GetNeighborhoodsByStateService', () => { .stub(sut, 'groupByCity') .returns(mockAggregatedCities); - const searchParams = new SearchNeighborhoodsInput('brasil', 'sc'); + const searchParams = new SearchNeighborhoodsDTO('brasil', 'sc'); const actual = await sut.getNeighborhoodsByState(searchParams); diff --git a/test/unit/microservice/domain/service/neighborhoods/save-neighborhoods-by-city.service.spec.ts b/test/unit/microservice/domain/service/neighborhoods/save-neighborhoods-by-city.service.spec.ts index 6249dbe..f722574 100644 --- a/test/unit/microservice/domain/service/neighborhoods/save-neighborhoods-by-city.service.spec.ts +++ b/test/unit/microservice/domain/service/neighborhoods/save-neighborhoods-by-city.service.spec.ts @@ -3,7 +3,7 @@ import * as sinon from 'sinon'; import { SaveNeighborhoodsByCityService } from '../../../../../../src/microservice/domain/service/neighborhoods/save-neighborhoods-by-city.service'; import { NeighborhoodsMongoose } from '../../../../../../src/microservice/adapter/repository/neighborhoods/neighborhoods-mongoose.repository'; import { ExtensionsModule } from '../../../../../../src/microservice/adapter/helper/extensions/exensions.module'; -import { SearchNeighborhoodsInput } from '../../../../../../src/microservice/domain/model/search/neighborhoods/search-neighborhoods-input.model'; +import { SearchNeighborhoodsDTO } from '../../../../../../src/microservice/domain/model/search/neighborhoods/search-neighborhoods-dto.model'; import { NeighborhoodByCity } from '../../../../../../src/microservice/domain/model/neighborhoods/neighborhood-by-city.model'; import { Neighborhood } from '../../../../../../src/microservice/domain/schemas/neighborhood.schema'; import { Country } from '../../../../../../src/microservice/domain/schemas/country.schema'; @@ -103,7 +103,7 @@ describe('SaveNeighborhoodsByCityService', () => { 'insertOne' ); - const searchParams = new SearchNeighborhoodsInput( + const searchParams = new SearchNeighborhoodsDTO( 'brasil', 'sc', 'orleans' @@ -131,7 +131,7 @@ describe('SaveNeighborhoodsByCityService', () => { 'insertOne' ); - const searchParams = new SearchNeighborhoodsInput( + const searchParams = new SearchNeighborhoodsDTO( 'brasil', 'sc', 'orleans' diff --git a/test/unit/microservice/domain/service/neighborhoods/seed/seed-neighborhoods-by-state.service.spec.ts b/test/unit/microservice/domain/service/neighborhoods/seed/seed-neighborhoods-by-state.service.spec.ts index aec4794..83158a2 100644 --- a/test/unit/microservice/domain/service/neighborhoods/seed/seed-neighborhoods-by-state.service.spec.ts +++ b/test/unit/microservice/domain/service/neighborhoods/seed/seed-neighborhoods-by-state.service.spec.ts @@ -3,7 +3,7 @@ import { SeedNeighborhoodsByStateService } from '../../../../../../../src/micros import { expect } from 'chai'; import * as sinon from 'sinon'; import '../../../../../../../src/microservice/adapter/helper/extensions/exensions.module'; -import { SearchNeighborhoodsInput } from '../../../../../../../src/microservice/domain/model/search/neighborhoods/search-neighborhoods-input.model'; +import { SearchNeighborhoodsDTO } from '../../../../../../../src/microservice/domain/model/search/neighborhoods/search-neighborhoods-dto.model'; import { Country } from '../../../../../../../src/microservice/domain/schemas/country.schema'; import { City } from '../../../../../../../src/microservice/domain/schemas/city.schema'; import { GetCitiesByStateService } from '../../../../../../../src/microservice/domain/service/cities/get/get-cities-by-state.service'; @@ -153,7 +153,7 @@ describe('SeedNeighborhoodsByStateService', () => { .stub(mockGetCitiesByStateService, 'findCitiesByState') .returns(mockCities()); - const searchParams = new SearchNeighborhoodsInput('brasil', 'sc'); + const searchParams = new SearchNeighborhoodsDTO('brasil', 'sc'); const actual = await sut.seedNeighborhoodsByState(searchParams); @@ -178,7 +178,7 @@ describe('SeedNeighborhoodsByStateService', () => { .stub(mockGetCitiesByStateService, 'findCitiesByState') .returns([]); - const searchParams = new SearchNeighborhoodsInput('brasil', 'sc'); + const searchParams = new SearchNeighborhoodsDTO('brasil', 'sc'); const actual = await sut.seedNeighborhoodsByState(searchParams); @@ -214,7 +214,7 @@ describe('SeedNeighborhoodsByStateService', () => { 'logSeedByState' ); - const searchParams = new SearchNeighborhoodsInput('brasil', 'sc'); + const searchParams = new SearchNeighborhoodsDTO('brasil', 'sc'); await sut.seedNeighborhoodsByState(searchParams); @@ -254,7 +254,7 @@ describe('SeedNeighborhoodsByStateService', () => { await sut.seedByCity(mockConvertedSearch(), mockCity); - const spySearch = new SearchNeighborhoodsInput('brasil', 'SC', 'Orleans'); + const spySearch = new SearchNeighborhoodsDTO('brasil', 'SC', 'Orleans'); const spyConvertedSearch = mockConvertedSearch(); spyConvertedSearch.city = mockCity; diff --git a/test/unit/microservice/domain/service/validate/validate-input-params.service.spec.ts b/test/unit/microservice/domain/service/validate/validate-input-params.service.spec.ts index f0f054b..ca5e7d2 100644 --- a/test/unit/microservice/domain/service/validate/validate-input-params.service.spec.ts +++ b/test/unit/microservice/domain/service/validate/validate-input-params.service.spec.ts @@ -9,7 +9,7 @@ import { Country } from '../../../../../../src/microservice/domain/schemas/count import { City } from '../../../../../../src/microservice/domain/schemas/city.schema'; import { ValidateCountryByNameOrAliasService } from '../../../../../../src/microservice/domain/service/countries/validate-country-by-name-or-alias.service'; import { ValidateCityByNameOrAliasService } from '../../../../../../src/microservice/domain/service/cities/validate-city-by-name-or-alias.service'; -import { SearchNeighborhoodsInput } from '../../../../../../src/microservice/domain/model/search/neighborhoods/search-neighborhoods-input.model'; +import { SearchNeighborhoodsDTO } from '../../../../../../src/microservice/domain/model/search/neighborhoods/search-neighborhoods-dto.model'; describe('ValidateInputParamsService', () => { let sut: ValidateInputParamsService; @@ -87,7 +87,7 @@ describe('ValidateInputParamsService', () => { return { country, state, city }; }; - const searchParams = new SearchNeighborhoodsInput( + const searchParams = new SearchNeighborhoodsDTO( 'brasil', 'sc', 'orleans' @@ -119,7 +119,7 @@ describe('ValidateInputParamsService', () => { return { country, state }; }; - const searchParams = new SearchNeighborhoodsInput('brasil', 'sc'); + const searchParams = new SearchNeighborhoodsDTO('brasil', 'sc'); const actual = await sut.validateAndConvertSearchByState(searchParams); From 3ad51626c9de8a08bc4dd26af775abb8c37aa6f6 Mon Sep 17 00:00:00 2001 From: Maick Speck Date: Mon, 27 Jun 2022 20:17:02 -0300 Subject: [PATCH 23/39] cities swagger --- .../adapter/controller/cities.controller.ts | 31 +++++++++++++++ .../model/cities/cities-by-state.model.ts | 39 ++++++++++++++++++- .../get/get-cities-by-country.service.ts | 4 +- .../cities/get/get-cities-by-state.service.ts | 4 +- .../cities/citites-by-state.model.spec.ts | 4 +- 5 files changed, 75 insertions(+), 7 deletions(-) diff --git a/src/microservice/adapter/controller/cities.controller.ts b/src/microservice/adapter/controller/cities.controller.ts index cc2c3ca..0fec71e 100644 --- a/src/microservice/adapter/controller/cities.controller.ts +++ b/src/microservice/adapter/controller/cities.controller.ts @@ -4,7 +4,10 @@ import { AbstractController } from '../../domain/controller/abstract-controller' import { GetCitiesByStateService } from '../../domain/service/cities/get/get-cities-by-state.service'; import { SearchCitiesInput } from '../../domain/model/search/cities/search-cities-input.model'; import { GetCitiesByCountryService } from '../../domain/service/cities/get/get-cities-by-country.service'; +import { ApiOkResponse, ApiParam, ApiTags } from '@nestjs/swagger'; +import { CitiesResponse } from '../../domain/model/cities/cities-by-state.model'; +@ApiTags('cities') @Controller('cities') export class CitiesController extends AbstractController { constructor( @@ -14,6 +17,23 @@ export class CitiesController extends AbstractController { super(); } + @ApiOkResponse({ + description: 'Cities found.', + isArray: true, + type: CitiesResponse + }) + @ApiParam({ + name: 'country', + required: true, + description: 'The Country name of the city', + type: String + }) + @ApiParam({ + name: 'state', + required: true, + description: 'The State name of the city', + type: String + }) @Get('/state/:country/:state') async getCitiesByState( @Param() params: SearchCitiesInput @@ -24,6 +44,17 @@ export class CitiesController extends AbstractController { ); } + @ApiOkResponse({ + description: 'Cities found.', + isArray: true, + type: CitiesResponse + }) + @ApiParam({ + name: 'country', + required: true, + description: 'The Country name of the city', + type: String + }) @Get('/country/:country') async getCitiesByCountry( @Param('country') country: string diff --git a/src/microservice/domain/model/cities/cities-by-state.model.ts b/src/microservice/domain/model/cities/cities-by-state.model.ts index 530163a..c5818ad 100644 --- a/src/microservice/domain/model/cities/cities-by-state.model.ts +++ b/src/microservice/domain/model/cities/cities-by-state.model.ts @@ -1,8 +1,45 @@ -export class CitiesByState { +import { ApiProperty } from '@nestjs/swagger'; + +export class CitiesResponse { + @ApiProperty({ + type: Number, + description: 'City Id reference in database', + example: 1 + }) id: number; + + @ApiProperty({ + type: String, + description: 'The name of the City', + example: 'Orleans' + }) name: string; + + @ApiProperty({ + type: String, + description: `The code(ISO3) of the Country's City`, + example: 'BRA' + }) countryCode: string; + + @ApiProperty({ + type: Number, + description: 'Country Id reference in database', + example: 31 + }) countryId: number; + + @ApiProperty({ + type: String, + description: `The code(ISO2) of the State's City`, + example: 'SC' + }) stateCode: string; + + @ApiProperty({ + type: Number, + description: 'State Id reference in database', + example: 2014 + }) stateId: number; } diff --git a/src/microservice/domain/service/cities/get/get-cities-by-country.service.ts b/src/microservice/domain/service/cities/get/get-cities-by-country.service.ts index ad419ec..443b568 100644 --- a/src/microservice/domain/service/cities/get/get-cities-by-country.service.ts +++ b/src/microservice/domain/service/cities/get/get-cities-by-country.service.ts @@ -1,5 +1,5 @@ import { Injectable } from '@nestjs/common'; -import { CitiesByCountry } from 'src/microservice/domain/model/cities/cities-by-country.model'; +import { CitiesResponse } from 'src/microservice/domain/model/cities/cities-by-state.model'; import { CitiesMongoose } from '../../../../adapter/repository/cities/cities-mongoose.repository'; import { City } from '../../../schemas/city.schema'; import { ValidateCountryByNameOrAliasService } from '../../countries/validate-country-by-name-or-alias.service'; @@ -14,7 +14,7 @@ export class GetCitiesByCountryService extends CitiesService { super(mongoRepository); } - async getCitiesByCountry(countryRef: string): Promise { + async getCitiesByCountry(countryRef: string): Promise { const country = await this.validateCountryService.validateCountry( countryRef ); diff --git a/src/microservice/domain/service/cities/get/get-cities-by-state.service.ts b/src/microservice/domain/service/cities/get/get-cities-by-state.service.ts index 9cdc783..ae0a385 100644 --- a/src/microservice/domain/service/cities/get/get-cities-by-state.service.ts +++ b/src/microservice/domain/service/cities/get/get-cities-by-state.service.ts @@ -1,6 +1,6 @@ import { Injectable } from '@nestjs/common'; import { CitiesMongoose } from '../../../../adapter/repository/cities/cities-mongoose.repository'; -import { CitiesByState } from '../../../model/cities/cities-by-state.model'; +import { CitiesResponse } from '../../../model/cities/cities-by-state.model'; import { SearchCitiesDB } from '../../../model/search/cities/search-cities-db.model'; import { SearchCitiesInput } from '../../../model/search/cities/search-cities-input.model'; import { City } from '../../../schemas/city.schema'; @@ -18,7 +18,7 @@ export class GetCitiesByStateService extends CitiesService { async getCitiesByState( searchParams: SearchCitiesInput - ): Promise { + ): Promise { const convertedSearch = await this.validateService.validateAndConvertSearchByState(searchParams); diff --git a/test/unit/microservice/domain/model/cities/citites-by-state.model.spec.ts b/test/unit/microservice/domain/model/cities/citites-by-state.model.spec.ts index 9d41059..011532f 100644 --- a/test/unit/microservice/domain/model/cities/citites-by-state.model.spec.ts +++ b/test/unit/microservice/domain/model/cities/citites-by-state.model.spec.ts @@ -1,9 +1,9 @@ import { expect } from 'chai'; -import { CitiesByState } from '../../../../../../src/microservice/domain/model/cities/cities-by-state.model'; +import { CitiesResponse } from '../../../../../../src/microservice/domain/model/cities/cities-by-state.model'; describe('CitiesByState', () => { it('should instance CitiesByState and return the object with the correct properties', async () => { - const model = new CitiesByState(); + const model = new CitiesResponse(); model.name = 'Torres'; model.stateCode = 'RS'; From f3fa2df8322d6b08eaa6edc16df15d21ccf8f2f6 Mon Sep 17 00:00:00 2001 From: Maick Speck Date: Mon, 27 Jun 2022 20:28:11 -0300 Subject: [PATCH 24/39] routes swagger mapped --- .../adapter/controller/cities.controller.ts | 6 +- .../controller/countries.controller.ts | 8 +++ .../adapter/controller/states.controller.ts | 14 ++++ .../model/cities/cities-by-country.model.ts | 8 --- ...-state.model.ts => city-response.model.ts} | 2 +- .../model/countries/country-response.model.ts | 64 ++++++++++++++++++- .../model/states/states-by-country.model.ts | 33 +++++++++- .../get/get-cities-by-country.service.ts | 4 +- .../cities/get/get-cities-by-state.service.ts | 4 +- .../cities/citites-by-state.model.spec.ts | 4 +- 10 files changed, 127 insertions(+), 20 deletions(-) delete mode 100644 src/microservice/domain/model/cities/cities-by-country.model.ts rename src/microservice/domain/model/cities/{cities-by-state.model.ts => city-response.model.ts} (91%) diff --git a/src/microservice/adapter/controller/cities.controller.ts b/src/microservice/adapter/controller/cities.controller.ts index 0fec71e..dcf6f25 100644 --- a/src/microservice/adapter/controller/cities.controller.ts +++ b/src/microservice/adapter/controller/cities.controller.ts @@ -5,7 +5,7 @@ import { GetCitiesByStateService } from '../../domain/service/cities/get/get-cit import { SearchCitiesInput } from '../../domain/model/search/cities/search-cities-input.model'; import { GetCitiesByCountryService } from '../../domain/service/cities/get/get-cities-by-country.service'; import { ApiOkResponse, ApiParam, ApiTags } from '@nestjs/swagger'; -import { CitiesResponse } from '../../domain/model/cities/cities-by-state.model'; +import { CityResponse } from '../../domain/model/cities/city-response.model'; @ApiTags('cities') @Controller('cities') @@ -20,7 +20,7 @@ export class CitiesController extends AbstractController { @ApiOkResponse({ description: 'Cities found.', isArray: true, - type: CitiesResponse + type: CityResponse }) @ApiParam({ name: 'country', @@ -47,7 +47,7 @@ export class CitiesController extends AbstractController { @ApiOkResponse({ description: 'Cities found.', isArray: true, - type: CitiesResponse + type: CityResponse }) @ApiParam({ name: 'country', diff --git a/src/microservice/adapter/controller/countries.controller.ts b/src/microservice/adapter/controller/countries.controller.ts index b259afe..64560e3 100644 --- a/src/microservice/adapter/controller/countries.controller.ts +++ b/src/microservice/adapter/controller/countries.controller.ts @@ -1,14 +1,22 @@ import { Controller, Get, HttpStatus } from '@nestjs/common'; +import { ApiOkResponse, ApiTags } from '@nestjs/swagger'; +import { CountryResponse } from 'src/microservice/domain/model/countries/country-response.model'; import { NestResponse } from '../../../core/http/nest-response'; import { AbstractController } from '../../domain/controller/abstract-controller'; import { GetCountriesService } from '../../domain/service/countries/get-countries.service'; +@ApiTags('countries') @Controller('countries') export class CountriesController extends AbstractController { constructor(private readonly getCountriesService: GetCountriesService) { super(); } + @ApiOkResponse({ + description: 'Countries found.', + isArray: true, + type: CountryResponse + }) @Get('/') async getAllCountries(): Promise { return this.buildResponse( diff --git a/src/microservice/adapter/controller/states.controller.ts b/src/microservice/adapter/controller/states.controller.ts index 6574378..27e9c79 100644 --- a/src/microservice/adapter/controller/states.controller.ts +++ b/src/microservice/adapter/controller/states.controller.ts @@ -2,7 +2,10 @@ import { Controller, Get, HttpStatus, Param } from '@nestjs/common'; import { GetStatesByCountryService } from '../../domain/service/states/get-states-by-country.service'; import { NestResponse } from '../../../core/http/nest-response'; import { AbstractController } from '../../domain/controller/abstract-controller'; +import { ApiOkResponse, ApiParam, ApiTags } from '@nestjs/swagger'; +import { StatesByCountry } from 'src/microservice/domain/model/states/states-by-country.model'; +@ApiTags('states') @Controller('states') export class StatesController extends AbstractController { constructor( @@ -11,6 +14,17 @@ export class StatesController extends AbstractController { super(); } + @ApiOkResponse({ + description: 'States found.', + isArray: true, + type: StatesByCountry + }) + @ApiParam({ + name: 'country', + required: true, + description: 'The Country name of the state', + type: String + }) @Get('/country/:country') async getStatesByCountry( @Param('country') country: string diff --git a/src/microservice/domain/model/cities/cities-by-country.model.ts b/src/microservice/domain/model/cities/cities-by-country.model.ts deleted file mode 100644 index 64fc844..0000000 --- a/src/microservice/domain/model/cities/cities-by-country.model.ts +++ /dev/null @@ -1,8 +0,0 @@ -export class CitiesByCountry { - id: number; - name: string; - countryCode: string; - countryId: number; - stateCode: string; - stateId: number; -} diff --git a/src/microservice/domain/model/cities/cities-by-state.model.ts b/src/microservice/domain/model/cities/city-response.model.ts similarity index 91% rename from src/microservice/domain/model/cities/cities-by-state.model.ts rename to src/microservice/domain/model/cities/city-response.model.ts index c5818ad..edc292e 100644 --- a/src/microservice/domain/model/cities/cities-by-state.model.ts +++ b/src/microservice/domain/model/cities/city-response.model.ts @@ -1,6 +1,6 @@ import { ApiProperty } from '@nestjs/swagger'; -export class CitiesResponse { +export class CityResponse { @ApiProperty({ type: Number, description: 'City Id reference in database', diff --git a/src/microservice/domain/model/countries/country-response.model.ts b/src/microservice/domain/model/countries/country-response.model.ts index 0c5c3ec..5fdea20 100644 --- a/src/microservice/domain/model/countries/country-response.model.ts +++ b/src/microservice/domain/model/countries/country-response.model.ts @@ -1,12 +1,74 @@ +import { ApiProperty } from '@nestjs/swagger'; + export class CountryResponse { + @ApiProperty({ + type: Number, + description: 'Country Id reference in database', + example: 1 + }) id: number; - name: string; + + @ApiProperty({ + type: Number, + description: 'Country Name', + example: 'Brasil' + }) + name: number; + + @ApiProperty({ + type: String, + description: `The code(ISO3) of the Country`, + example: 'BRA' + }) iso3: string; + + @ApiProperty({ + type: String, + description: `The code(ISO2) of the Country`, + example: 'BR' + }) iso2: string; + + @ApiProperty({ + type: String, + description: 'Capital', + example: 'Brasília' + }) capital: string; + + @ApiProperty({ + type: String, + description: 'Currency Symbol', + example: 'R$' + }) currency: string; + + @ApiProperty({ + type: String, + description: 'Continent Region of the country', + example: 'South America' + }) region: string; + + @ApiProperty({ + type: String, + description: 'Continent SubRegion of the country', + example: 'South' + }) subregion: string; + + @ApiProperty({ + type: String, + isArray: true, + description: 'Alias names', + example: ['BR', 'BRA', 'Brazil', 'Brasil'] + }) alias: string; + + @ApiProperty({ + type: Number, + description: 'Phone number code DDI', + example: 55 + }) phoneCode: number; } diff --git a/src/microservice/domain/model/states/states-by-country.model.ts b/src/microservice/domain/model/states/states-by-country.model.ts index be6d3a4..6d5748b 100644 --- a/src/microservice/domain/model/states/states-by-country.model.ts +++ b/src/microservice/domain/model/states/states-by-country.model.ts @@ -1,7 +1,38 @@ +import { ApiProperty } from '@nestjs/swagger'; + export class StatesByCountry { + @ApiProperty({ + type: Number, + description: 'State Id reference in database', + example: 1 + }) id: number; + + @ApiProperty({ + type: String, + description: 'The name of the State', + example: 'Orleans' + }) name: string; - countryId: number; + + @ApiProperty({ + type: String, + description: `The code(ISO3) of the Country's State`, + example: 'BRA' + }) countryCode: string; + + @ApiProperty({ + type: Number, + description: 'Country Id reference in database', + example: 31 + }) + countryId: number; + + @ApiProperty({ + type: String, + description: `The code(ISO2) of the State`, + example: 'SC' + }) stateCode: string; } diff --git a/src/microservice/domain/service/cities/get/get-cities-by-country.service.ts b/src/microservice/domain/service/cities/get/get-cities-by-country.service.ts index 443b568..3fb600c 100644 --- a/src/microservice/domain/service/cities/get/get-cities-by-country.service.ts +++ b/src/microservice/domain/service/cities/get/get-cities-by-country.service.ts @@ -1,5 +1,5 @@ import { Injectable } from '@nestjs/common'; -import { CitiesResponse } from 'src/microservice/domain/model/cities/cities-by-state.model'; +import { CityResponse } from 'src/microservice/domain/model/cities/city-response.model'; import { CitiesMongoose } from '../../../../adapter/repository/cities/cities-mongoose.repository'; import { City } from '../../../schemas/city.schema'; import { ValidateCountryByNameOrAliasService } from '../../countries/validate-country-by-name-or-alias.service'; @@ -14,7 +14,7 @@ export class GetCitiesByCountryService extends CitiesService { super(mongoRepository); } - async getCitiesByCountry(countryRef: string): Promise { + async getCitiesByCountry(countryRef: string): Promise { const country = await this.validateCountryService.validateCountry( countryRef ); diff --git a/src/microservice/domain/service/cities/get/get-cities-by-state.service.ts b/src/microservice/domain/service/cities/get/get-cities-by-state.service.ts index ae0a385..fbc8dd5 100644 --- a/src/microservice/domain/service/cities/get/get-cities-by-state.service.ts +++ b/src/microservice/domain/service/cities/get/get-cities-by-state.service.ts @@ -1,6 +1,6 @@ import { Injectable } from '@nestjs/common'; import { CitiesMongoose } from '../../../../adapter/repository/cities/cities-mongoose.repository'; -import { CitiesResponse } from '../../../model/cities/cities-by-state.model'; +import { CityResponse } from '../../../model/cities/city-response.model'; import { SearchCitiesDB } from '../../../model/search/cities/search-cities-db.model'; import { SearchCitiesInput } from '../../../model/search/cities/search-cities-input.model'; import { City } from '../../../schemas/city.schema'; @@ -18,7 +18,7 @@ export class GetCitiesByStateService extends CitiesService { async getCitiesByState( searchParams: SearchCitiesInput - ): Promise { + ): Promise { const convertedSearch = await this.validateService.validateAndConvertSearchByState(searchParams); diff --git a/test/unit/microservice/domain/model/cities/citites-by-state.model.spec.ts b/test/unit/microservice/domain/model/cities/citites-by-state.model.spec.ts index 011532f..62cf223 100644 --- a/test/unit/microservice/domain/model/cities/citites-by-state.model.spec.ts +++ b/test/unit/microservice/domain/model/cities/citites-by-state.model.spec.ts @@ -1,9 +1,9 @@ import { expect } from 'chai'; -import { CitiesResponse } from '../../../../../../src/microservice/domain/model/cities/cities-by-state.model'; +import { CityResponse } from '../../../../../../src/microservice/domain/model/cities/city-response.model'; describe('CitiesByState', () => { it('should instance CitiesByState and return the object with the correct properties', async () => { - const model = new CitiesResponse(); + const model = new CityResponse(); model.name = 'Torres'; model.stateCode = 'RS'; From 006332cb084e52878d71ed688622275a20249d06 Mon Sep 17 00:00:00 2001 From: Maick Speck Date: Mon, 27 Jun 2022 20:51:19 -0300 Subject: [PATCH 25/39] api operation swagger --- .../adapter/controller/cities.controller.ts | 13 ++++++++++++- .../adapter/controller/countries.controller.ts | 5 ++++- .../adapter/controller/neighborhoods.controller.ts | 7 +++++++ 3 files changed, 23 insertions(+), 2 deletions(-) diff --git a/src/microservice/adapter/controller/cities.controller.ts b/src/microservice/adapter/controller/cities.controller.ts index dcf6f25..bc15093 100644 --- a/src/microservice/adapter/controller/cities.controller.ts +++ b/src/microservice/adapter/controller/cities.controller.ts @@ -4,7 +4,12 @@ import { AbstractController } from '../../domain/controller/abstract-controller' import { GetCitiesByStateService } from '../../domain/service/cities/get/get-cities-by-state.service'; import { SearchCitiesInput } from '../../domain/model/search/cities/search-cities-input.model'; import { GetCitiesByCountryService } from '../../domain/service/cities/get/get-cities-by-country.service'; -import { ApiOkResponse, ApiParam, ApiTags } from '@nestjs/swagger'; +import { + ApiOkResponse, + ApiOperation, + ApiParam, + ApiTags +} from '@nestjs/swagger'; import { CityResponse } from '../../domain/model/cities/city-response.model'; @ApiTags('cities') @@ -17,6 +22,9 @@ export class CitiesController extends AbstractController { super(); } + @ApiOperation({ + description: 'Get Cities By State Reference' + }) @ApiOkResponse({ description: 'Cities found.', isArray: true, @@ -44,6 +52,9 @@ export class CitiesController extends AbstractController { ); } + @ApiOperation({ + description: 'Get Cities By Country Reference' + }) @ApiOkResponse({ description: 'Cities found.', isArray: true, diff --git a/src/microservice/adapter/controller/countries.controller.ts b/src/microservice/adapter/controller/countries.controller.ts index 64560e3..a1fcf7a 100644 --- a/src/microservice/adapter/controller/countries.controller.ts +++ b/src/microservice/adapter/controller/countries.controller.ts @@ -1,5 +1,5 @@ import { Controller, Get, HttpStatus } from '@nestjs/common'; -import { ApiOkResponse, ApiTags } from '@nestjs/swagger'; +import { ApiOkResponse, ApiOperation, ApiTags } from '@nestjs/swagger'; import { CountryResponse } from 'src/microservice/domain/model/countries/country-response.model'; import { NestResponse } from '../../../core/http/nest-response'; import { AbstractController } from '../../domain/controller/abstract-controller'; @@ -12,6 +12,9 @@ export class CountriesController extends AbstractController { super(); } + @ApiOperation({ + description: 'Get All Countries' + }) @ApiOkResponse({ description: 'Countries found.', isArray: true, diff --git a/src/microservice/adapter/controller/neighborhoods.controller.ts b/src/microservice/adapter/controller/neighborhoods.controller.ts index ec57f23..54721d0 100644 --- a/src/microservice/adapter/controller/neighborhoods.controller.ts +++ b/src/microservice/adapter/controller/neighborhoods.controller.ts @@ -8,6 +8,7 @@ import { SeedNeighborhoodsByStateService } from '../../domain/service/neighborho import { ApiExcludeEndpoint, ApiOkResponse, + ApiOperation, ApiParam, ApiTags } from '@nestjs/swagger'; @@ -25,6 +26,9 @@ export class NeighborhoodsController extends AbstractController { super(); } + @ApiOperation({ + description: 'Get Neighborhoods By City Reference' + }) @ApiOkResponse({ description: 'Neighborhoods found.', isArray: true, @@ -58,6 +62,9 @@ export class NeighborhoodsController extends AbstractController { ); } + @ApiOperation({ + description: 'Get Neighborhoods By State Reference' + }) @ApiOkResponse({ description: 'Neighborhoods found.', type: NeighborhoodsByState From c1d9fb2ef1c3903100200e21b2783b2de7722dc9 Mon Sep 17 00:00:00 2001 From: Maick Speck Date: Mon, 27 Jun 2022 21:01:35 -0300 Subject: [PATCH 26/39] fix swagger test --- .../adapter/controller/cities.controller.ts | 4 +-- .../controller/countries.controller.ts | 2 +- .../controller/neighborhoods.controller.ts | 4 +-- .../adapter/controller/states.controller.ts | 2 +- .../helper/extensions/exensions.module.ts | 1 - .../model/countries/country-response.model.ts | 4 +-- src/microservice/domain/model/dto.model.ts | 11 ++++++++ ...ut.model.ts => search-cities-dto.model.ts} | 4 ++- .../search-neighborhoods-dto.model.ts | 12 +------- .../cities/get/get-cities-by-state.service.ts | 4 +-- .../validate/validate-input-params.service.ts | 4 +-- .../controller/cities.controller.spec.ts | 4 +-- .../extensions/object.extension.spec.ts | 28 ------------------- .../cities/citites-by-country.model.spec.ts | 13 --------- ...el.spec.ts => city-response.model.spec.ts} | 4 +-- .../search-neighborhoods-input.model.spec.ts | 6 ++-- .../get/get-cities-by-state.service.spec.ts | 4 +-- 17 files changed, 36 insertions(+), 75 deletions(-) create mode 100644 src/microservice/domain/model/dto.model.ts rename src/microservice/domain/model/search/cities/{search-cities-input.model.ts => search-cities-dto.model.ts} (75%) delete mode 100644 test/unit/microservice/adapter/helper/extensions/object.extension.spec.ts delete mode 100644 test/unit/microservice/domain/model/cities/citites-by-country.model.spec.ts rename test/unit/microservice/domain/model/cities/{citites-by-state.model.spec.ts => city-response.model.spec.ts} (69%) diff --git a/src/microservice/adapter/controller/cities.controller.ts b/src/microservice/adapter/controller/cities.controller.ts index bc15093..957ba7a 100644 --- a/src/microservice/adapter/controller/cities.controller.ts +++ b/src/microservice/adapter/controller/cities.controller.ts @@ -2,7 +2,7 @@ import { Controller, Get, HttpStatus, Param } from '@nestjs/common'; import { NestResponse } from '../../../core/http/nest-response'; import { AbstractController } from '../../domain/controller/abstract-controller'; import { GetCitiesByStateService } from '../../domain/service/cities/get/get-cities-by-state.service'; -import { SearchCitiesInput } from '../../domain/model/search/cities/search-cities-input.model'; +import { SearchCitiesDTO } from '../../domain/model/search/cities/search-cities-dto.model'; import { GetCitiesByCountryService } from '../../domain/service/cities/get/get-cities-by-country.service'; import { ApiOkResponse, @@ -44,7 +44,7 @@ export class CitiesController extends AbstractController { }) @Get('/state/:country/:state') async getCitiesByState( - @Param() params: SearchCitiesInput + @Param() params: SearchCitiesDTO ): Promise { return this.buildResponse( HttpStatus.OK, diff --git a/src/microservice/adapter/controller/countries.controller.ts b/src/microservice/adapter/controller/countries.controller.ts index a1fcf7a..ecfde22 100644 --- a/src/microservice/adapter/controller/countries.controller.ts +++ b/src/microservice/adapter/controller/countries.controller.ts @@ -1,6 +1,6 @@ import { Controller, Get, HttpStatus } from '@nestjs/common'; import { ApiOkResponse, ApiOperation, ApiTags } from '@nestjs/swagger'; -import { CountryResponse } from 'src/microservice/domain/model/countries/country-response.model'; +import { CountryResponse } from '../../domain/model/countries/country-response.model'; import { NestResponse } from '../../../core/http/nest-response'; import { AbstractController } from '../../domain/controller/abstract-controller'; import { GetCountriesService } from '../../domain/service/countries/get-countries.service'; diff --git a/src/microservice/adapter/controller/neighborhoods.controller.ts b/src/microservice/adapter/controller/neighborhoods.controller.ts index 54721d0..7763cbd 100644 --- a/src/microservice/adapter/controller/neighborhoods.controller.ts +++ b/src/microservice/adapter/controller/neighborhoods.controller.ts @@ -12,8 +12,8 @@ import { ApiParam, ApiTags } from '@nestjs/swagger'; -import { NeighborhoodByCity } from 'src/microservice/domain/model/neighborhoods/neighborhood-by-city.model'; -import { NeighborhoodsByState } from 'src/microservice/domain/model/neighborhoods/neighborhoods-by-state.model'; +import { NeighborhoodByCity } from '../../domain/model/neighborhoods/neighborhood-by-city.model'; +import { NeighborhoodsByState } from '../../domain/model/neighborhoods/neighborhoods-by-state.model'; @ApiTags('neighborhoods') @Controller('neighborhoods') diff --git a/src/microservice/adapter/controller/states.controller.ts b/src/microservice/adapter/controller/states.controller.ts index 27e9c79..9e43944 100644 --- a/src/microservice/adapter/controller/states.controller.ts +++ b/src/microservice/adapter/controller/states.controller.ts @@ -3,7 +3,7 @@ import { GetStatesByCountryService } from '../../domain/service/states/get-state import { NestResponse } from '../../../core/http/nest-response'; import { AbstractController } from '../../domain/controller/abstract-controller'; import { ApiOkResponse, ApiParam, ApiTags } from '@nestjs/swagger'; -import { StatesByCountry } from 'src/microservice/domain/model/states/states-by-country.model'; +import { StatesByCountry } from '../../domain/model/states/states-by-country.model'; @ApiTags('states') @Controller('states') diff --git a/src/microservice/adapter/helper/extensions/exensions.module.ts b/src/microservice/adapter/helper/extensions/exensions.module.ts index acfc2c1..0489ae4 100644 --- a/src/microservice/adapter/helper/extensions/exensions.module.ts +++ b/src/microservice/adapter/helper/extensions/exensions.module.ts @@ -1,5 +1,4 @@ import './string.extension'; -import './object.extension'; import { Module } from '@nestjs/common'; @Module({ diff --git a/src/microservice/domain/model/countries/country-response.model.ts b/src/microservice/domain/model/countries/country-response.model.ts index 5fdea20..0177739 100644 --- a/src/microservice/domain/model/countries/country-response.model.ts +++ b/src/microservice/domain/model/countries/country-response.model.ts @@ -9,11 +9,11 @@ export class CountryResponse { id: number; @ApiProperty({ - type: Number, + type: String, description: 'Country Name', example: 'Brasil' }) - name: number; + name: string; @ApiProperty({ type: String, diff --git a/src/microservice/domain/model/dto.model.ts b/src/microservice/domain/model/dto.model.ts new file mode 100644 index 0000000..64fd512 --- /dev/null +++ b/src/microservice/domain/model/dto.model.ts @@ -0,0 +1,11 @@ +import { EmptyPropException } from '../../../core/error-handling/exception/empty-prop.exception'; + +export abstract class DTO { + validateIsAnyEmptyKey() { + // eslint-disable-next-line @typescript-eslint/no-this-alias + const context = this; + Object.keys(this).forEach(function (key) { + if (context[key].length === 0) throw new EmptyPropException(key); + }); + } +} diff --git a/src/microservice/domain/model/search/cities/search-cities-input.model.ts b/src/microservice/domain/model/search/cities/search-cities-dto.model.ts similarity index 75% rename from src/microservice/domain/model/search/cities/search-cities-input.model.ts rename to src/microservice/domain/model/search/cities/search-cities-dto.model.ts index 8c4ae4e..29d6068 100644 --- a/src/microservice/domain/model/search/cities/search-cities-input.model.ts +++ b/src/microservice/domain/model/search/cities/search-cities-dto.model.ts @@ -1,6 +1,7 @@ import { ApiProperty } from '@nestjs/swagger'; +import { DTO } from '../../dto.model'; -export class SearchCitiesInput { +export class SearchCitiesDTO extends DTO { @ApiProperty({ type: String, description: 'The country of the City' @@ -14,6 +15,7 @@ export class SearchCitiesInput { public state: string; constructor(country: string, state: string) { + super(); this.country = country; this.state = state; } diff --git a/src/microservice/domain/model/search/neighborhoods/search-neighborhoods-dto.model.ts b/src/microservice/domain/model/search/neighborhoods/search-neighborhoods-dto.model.ts index fe00b0a..e805626 100644 --- a/src/microservice/domain/model/search/neighborhoods/search-neighborhoods-dto.model.ts +++ b/src/microservice/domain/model/search/neighborhoods/search-neighborhoods-dto.model.ts @@ -1,15 +1,5 @@ import { ApiProperty } from '@nestjs/swagger'; -import { EmptyPropException } from 'src/core/error-handling/exception/empty-prop.exception'; - -export class DTO { - validateIsAnyEmptyKey() { - // eslint-disable-next-line @typescript-eslint/no-this-alias - const context = this; - Object.keys(this).forEach(function (key) { - if (context[key].length === 0) throw new EmptyPropException(key); - }); - } -} +import { DTO } from '../../dto.model'; export class SearchNeighborhoodsDTO extends DTO { @ApiProperty({ diff --git a/src/microservice/domain/service/cities/get/get-cities-by-state.service.ts b/src/microservice/domain/service/cities/get/get-cities-by-state.service.ts index fbc8dd5..c2f564c 100644 --- a/src/microservice/domain/service/cities/get/get-cities-by-state.service.ts +++ b/src/microservice/domain/service/cities/get/get-cities-by-state.service.ts @@ -2,7 +2,7 @@ import { Injectable } from '@nestjs/common'; import { CitiesMongoose } from '../../../../adapter/repository/cities/cities-mongoose.repository'; import { CityResponse } from '../../../model/cities/city-response.model'; import { SearchCitiesDB } from '../../../model/search/cities/search-cities-db.model'; -import { SearchCitiesInput } from '../../../model/search/cities/search-cities-input.model'; +import { SearchCitiesDTO } from '../../../model/search/cities/search-cities-dto.model'; import { City } from '../../../schemas/city.schema'; import { ValidateInputParamsService } from '../../validate/validate-input-params.service'; import { CitiesService } from '../cities.service'; @@ -17,7 +17,7 @@ export class GetCitiesByStateService extends CitiesService { } async getCitiesByState( - searchParams: SearchCitiesInput + searchParams: SearchCitiesDTO ): Promise { const convertedSearch = await this.validateService.validateAndConvertSearchByState(searchParams); diff --git a/src/microservice/domain/service/validate/validate-input-params.service.ts b/src/microservice/domain/service/validate/validate-input-params.service.ts index c70198f..deeebaa 100644 --- a/src/microservice/domain/service/validate/validate-input-params.service.ts +++ b/src/microservice/domain/service/validate/validate-input-params.service.ts @@ -8,7 +8,7 @@ import { AbstractService } from '../abstract-service.service'; import { ValidateCountryByNameOrAliasService } from '../countries/validate-country-by-name-or-alias.service'; import { ValidateStateByNameOrAliasService } from '../states/validate-state-by-name-or-alias.service'; import { ValidateCityByNameOrAliasService } from '../cities/validate-city-by-name-or-alias.service'; -import { SearchCitiesInput } from '../../model/search/cities/search-cities-input.model'; +import { SearchCitiesDTO } from '../../model/search/cities/search-cities-dto.model'; @Injectable() export class ValidateInputParamsService extends AbstractService { @@ -21,7 +21,7 @@ export class ValidateInputParamsService extends AbstractService { } async validateAndConvertSearchByState( - searchParams: SearchNeighborhoodsDTO | SearchCitiesInput + searchParams: SearchNeighborhoodsDTO | SearchCitiesDTO ): Promise { const country = await this.getCountryService.validateCountry( searchParams.country diff --git a/test/unit/microservice/adapter/controller/cities.controller.spec.ts b/test/unit/microservice/adapter/controller/cities.controller.spec.ts index d113dbc..a64b105 100644 --- a/test/unit/microservice/adapter/controller/cities.controller.spec.ts +++ b/test/unit/microservice/adapter/controller/cities.controller.spec.ts @@ -8,7 +8,7 @@ import { ValidateInputParamsService } from '../../../../../src/microservice/doma import { CitiesController } from '../../../../../src/microservice/adapter/controller/cities.controller'; import { GetCitiesByStateService } from '../../../../../src/microservice/domain/service/cities/get/get-cities-by-state.service'; import { GetCitiesByCountryService } from '../../../../../src/microservice/domain/service/cities/get/get-cities-by-country.service'; -import { SearchCitiesInput } from '../../../../../src/microservice/domain/model/search/cities/search-cities-input.model'; +import { SearchCitiesDTO } from '../../../../../src/microservice/domain/model/search/cities/search-cities-dto.model'; import { City } from '../../../../../src/microservice/domain/schemas/city.schema'; describe('CitiesController', () => { @@ -79,7 +79,7 @@ describe('CitiesController', () => { .stub(mockGetCitiesByStateService, 'getCitiesByState') .returns(mockCities()); - const searchParams = new SearchCitiesInput('brasil', 'sc'); + const searchParams = new SearchCitiesDTO('brasil', 'sc'); const actual = await citiesController.getCitiesByState(searchParams); diff --git a/test/unit/microservice/adapter/helper/extensions/object.extension.spec.ts b/test/unit/microservice/adapter/helper/extensions/object.extension.spec.ts deleted file mode 100644 index b023e66..0000000 --- a/test/unit/microservice/adapter/helper/extensions/object.extension.spec.ts +++ /dev/null @@ -1,28 +0,0 @@ -import '../../../../../../src/microservice/adapter/helper/extensions/exensions.module'; -import { expect } from 'chai'; -import { SearchNeighborhoodsDTO } from '../../../../../../src/microservice/domain/model/search/neighborhoods/search-neighborhoods-dto.model'; - -describe('object.extension', () => { - describe('getMethods', function () { - it('Should call getMethods and contain toString', function () { - const obj = new Object(); - expect(obj.getMethods()).to.include.members(['toString']); - }); - }); - - describe('validateIsAnyEmptyKey', function () { - it('Should call validateIsAnyEmptyKey and throw exccption', function () { - const validation = () => { - const obj = new SearchNeighborhoodsDTO('brasil', 'sc', 'orleans'); - obj.city = ''; - obj.validateIsAnyEmptyKey(); - }; - - try { - validation(); - } catch (err) { - expect(err.message).to.be.equal("The property 'City' cannot be empty"); - } - }); - }); -}); diff --git a/test/unit/microservice/domain/model/cities/citites-by-country.model.spec.ts b/test/unit/microservice/domain/model/cities/citites-by-country.model.spec.ts deleted file mode 100644 index beec332..0000000 --- a/test/unit/microservice/domain/model/cities/citites-by-country.model.spec.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { expect } from 'chai'; -import { CitiesByCountry } from '../../../../../../src/microservice/domain/model/cities/cities-by-country.model'; - -describe('CitiesByCountry', () => { - it('should instance CitiesByCountry and return the object with the correct properties', async () => { - const model = new CitiesByCountry(); - model.name = 'Torres'; - model.stateCode = 'RS'; - - expect(model.name).to.be.equal('Torres'); - expect(model.stateCode).to.be.equal('RS'); - }); -}); diff --git a/test/unit/microservice/domain/model/cities/citites-by-state.model.spec.ts b/test/unit/microservice/domain/model/cities/city-response.model.spec.ts similarity index 69% rename from test/unit/microservice/domain/model/cities/citites-by-state.model.spec.ts rename to test/unit/microservice/domain/model/cities/city-response.model.spec.ts index 62cf223..b85336f 100644 --- a/test/unit/microservice/domain/model/cities/citites-by-state.model.spec.ts +++ b/test/unit/microservice/domain/model/cities/city-response.model.spec.ts @@ -1,8 +1,8 @@ import { expect } from 'chai'; import { CityResponse } from '../../../../../../src/microservice/domain/model/cities/city-response.model'; -describe('CitiesByState', () => { - it('should instance CitiesByState and return the object with the correct properties', async () => { +describe('CityResponse', () => { + it('should instance CityResponse and return the object with the correct properties', async () => { const model = new CityResponse(); model.name = 'Torres'; model.stateCode = 'RS'; diff --git a/test/unit/microservice/domain/model/search/neighborhoods/search-neighborhoods-input.model.spec.ts b/test/unit/microservice/domain/model/search/neighborhoods/search-neighborhoods-input.model.spec.ts index 9cb337e..1c0009f 100644 --- a/test/unit/microservice/domain/model/search/neighborhoods/search-neighborhoods-input.model.spec.ts +++ b/test/unit/microservice/domain/model/search/neighborhoods/search-neighborhoods-input.model.spec.ts @@ -1,8 +1,8 @@ import { expect } from 'chai'; import { SearchNeighborhoodsDTO } from '../../../../../../../src/microservice/domain/model/search/neighborhoods/search-neighborhoods-dto.model'; -describe('SearchNeighborhoodsInput', () => { - it('should instance SearchNeighborhoodsInput and return the object with the correct properties', async () => { +describe('SearchNeighborhoodsDTO', () => { + it('should instance SearchNeighborhoodsDTO and return the object with the correct properties', async () => { const model = new SearchNeighborhoodsDTO('brasil', 'sc', 'praia grande'); expect(model.country).to.be.equal('brasil'); @@ -10,7 +10,7 @@ describe('SearchNeighborhoodsInput', () => { expect(model.city).to.be.equal('praia grande'); }); - it('should instance SearchNeighborhoodsInput, setName and return the object with the correct properties', async () => { + it('should instance SearchNeighborhoodsDTO, setName and return the object with the correct properties', async () => { const model = new SearchNeighborhoodsDTO('brasil', 'sc', 'praia grande'); model.setName('Vila Rosa'); diff --git a/test/unit/microservice/domain/service/cities/get/get-cities-by-state.service.spec.ts b/test/unit/microservice/domain/service/cities/get/get-cities-by-state.service.spec.ts index 895b4b5..b3c2f2a 100644 --- a/test/unit/microservice/domain/service/cities/get/get-cities-by-state.service.spec.ts +++ b/test/unit/microservice/domain/service/cities/get/get-cities-by-state.service.spec.ts @@ -8,7 +8,7 @@ import { City } from '../../../../../../../src/microservice/domain/schemas/city. import { GetCitiesByStateService } from '../../../../../../../src/microservice/domain/service/cities/get/get-cities-by-state.service'; import { SearchCitiesDB } from '../../../../../../../src/microservice/domain/model/search/cities/search-cities-db.model'; import { CitiesMongoose } from '../../../../../../../src/microservice/adapter/repository/cities/cities-mongoose.repository'; -import { SearchCitiesInput } from '../../../../../../../src/microservice/domain/model/search/cities/search-cities-input.model'; +import { SearchCitiesDTO } from '../../../../../../../src/microservice/domain/model/search/cities/search-cities-dto.model'; import { State } from '../../../../../../../src/microservice/domain/schemas/state.schema'; import { Country } from '../../../../../../../src/microservice/domain/schemas/country.schema'; @@ -134,7 +134,7 @@ describe('GetCitiesByStateService', () => { .stub(mockValidateService, 'validateAndConvertSearchByState') .returns(mockConvertedSearch()); - const searchParams = new SearchCitiesInput('Brazil', 'SC'); + const searchParams = new SearchCitiesDTO('Brazil', 'SC'); const actual = await sut.getCitiesByState(searchParams); From 41acf73601ed1f8c185b9af9a74490e8a3c8c3d9 Mon Sep 17 00:00:00 2001 From: Maick Speck Date: Mon, 27 Jun 2022 21:12:28 -0300 Subject: [PATCH 27/39] improve cov tests swagger --- ...spec.ts => search-neighborhoods-dto.model.spec.ts} | 11 +++++++++++ 1 file changed, 11 insertions(+) rename test/unit/microservice/domain/model/search/neighborhoods/{search-neighborhoods-input.model.spec.ts => search-neighborhoods-dto.model.spec.ts} (68%) diff --git a/test/unit/microservice/domain/model/search/neighborhoods/search-neighborhoods-input.model.spec.ts b/test/unit/microservice/domain/model/search/neighborhoods/search-neighborhoods-dto.model.spec.ts similarity index 68% rename from test/unit/microservice/domain/model/search/neighborhoods/search-neighborhoods-input.model.spec.ts rename to test/unit/microservice/domain/model/search/neighborhoods/search-neighborhoods-dto.model.spec.ts index 1c0009f..99fbd72 100644 --- a/test/unit/microservice/domain/model/search/neighborhoods/search-neighborhoods-input.model.spec.ts +++ b/test/unit/microservice/domain/model/search/neighborhoods/search-neighborhoods-dto.model.spec.ts @@ -1,5 +1,6 @@ import { expect } from 'chai'; import { SearchNeighborhoodsDTO } from '../../../../../../../src/microservice/domain/model/search/neighborhoods/search-neighborhoods-dto.model'; +import '../../../../../../../src/microservice/adapter/helper/extensions/exensions.module'; describe('SearchNeighborhoodsDTO', () => { it('should instance SearchNeighborhoodsDTO and return the object with the correct properties', async () => { @@ -19,4 +20,14 @@ describe('SearchNeighborhoodsDTO', () => { expect(model.city).to.be.equal('praia grande'); expect(model.name).to.be.equal('Vila Rosa'); }); + + it('should instance SearchNeighborhoodsDTOand throws invalid data exception', async () => { + const model = new SearchNeighborhoodsDTO('', 'sc', 'praia grande'); + + try { + model.validateIsAnyEmptyKey(); + } catch (err) { + expect(err.message).to.be.equal(`The property 'Country' cannot be empty`); + } + }); }); From 3ef301b7dd725fc5ca50715e61bd5105e0164fdd Mon Sep 17 00:00:00 2001 From: Maick Speck Date: Mon, 27 Jun 2022 21:13:12 -0300 Subject: [PATCH 28/39] md cl --- CHANGELOG.MD | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index 0687e0c..baa0fe6 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -41,3 +41,4 @@ All notable changes to this project will be documented in this file. - Route Cities By Country - Route States By Country - Route Countries +- Swagger Openapi automation From 137f20852522109e73352584855d313964b2053c Mon Sep 17 00:00:00 2001 From: Maick Speck Date: Tue, 28 Jun 2022 09:35:20 -0300 Subject: [PATCH 29/39] doc yaml --- config/yaml/values.yaml | 2 ++ src/main.ts | 9 +++++---- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/config/yaml/values.yaml b/config/yaml/values.yaml index 16aa11c..4afe32e 100644 --- a/config/yaml/values.yaml +++ b/config/yaml/values.yaml @@ -7,3 +7,5 @@ database: connection: 'mongodb+srv://dev-seeder-root:hpYpxyjrKExNQviu@devseeder.v6xtv.mongodb.net/places?retryWrites=true&w=majority&ssl=true&wtimeoutMS=0' api: port: 3000 +doc: + version: 0.0.5 diff --git a/src/main.ts b/src/main.ts index d92028f..df9d8a0 100644 --- a/src/main.ts +++ b/src/main.ts @@ -14,16 +14,17 @@ async function bootstrap() { ); useContainer(app.select(AppModule), { fallbackOnErrors: true }); - const config = new DocumentBuilder() + const configService = app.get(ConfigService); + + const docApi = new DocumentBuilder() .setTitle('Places') .setDescription('Places API') - .setVersion('1.0') + .setVersion(configService.get('doc.version')) .build(); - const document = SwaggerModule.createDocument(app, config); + const document = SwaggerModule.createDocument(app, docApi); SwaggerModule.setup('api', app, document); - const configService = app.get(ConfigService); return await app.listen(configService.get('api.port')); } From b04f4e12695767f9ee5332ce45e71a689657427a Mon Sep 17 00:00:00 2001 From: Maick Speck Date: Tue, 28 Jun 2022 09:42:02 -0300 Subject: [PATCH 30/39] e2e new routes --- test/e2e/app.e2e-spec.ts | 38 +++++++++++++++++++++++++++++++++++++- 1 file changed, 37 insertions(+), 1 deletion(-) diff --git a/test/e2e/app.e2e-spec.ts b/test/e2e/app.e2e-spec.ts index aa6d52c..76c153a 100644 --- a/test/e2e/app.e2e-spec.ts +++ b/test/e2e/app.e2e-spec.ts @@ -5,7 +5,7 @@ import { AppModule } from '../../src/app.module'; import { NestFactory } from '@nestjs/core'; import '../../src/microservice/adapter/helper/extensions/exensions.module'; -jest.setTimeout(75000); +jest.setTimeout(400000); describe('App (e2e) ', () => { let app: INestApplication; @@ -41,4 +41,40 @@ describe('App (e2e) ', () => { expect(actual.body.Orleans).to.be.an('array').that.is.not.empty; }); }); + + describe('City (e2e) ', () => { + it('/cities/state/brasil/sc (GET)', async () => { + const actual = await request(app.getHttpServer()).get( + '/cities/state/brasil/sc' + ); + + expect(actual.body).to.be.an('array').that.is.not.empty; + }); + + it('/cities/country/brasil (GET)', async () => { + const actual = await request(app.getHttpServer()).get( + '/cities/country/brasil' + ); + + expect(actual.body).to.be.an('array').that.is.not.empty; + }); + }); + + describe('State (e2e) ', () => { + it('/states/country/brasil (GET)', async () => { + const actual = await request(app.getHttpServer()).get( + '/states/country/brasil' + ); + + expect(actual.body).to.be.an('array').that.is.not.empty; + }); + }); + + describe('Country (e2e) ', () => { + it('/countries/ (GET)', async () => { + const actual = await request(app.getHttpServer()).get('/countries/'); + + expect(actual.body).to.be.an('array').that.is.not.empty; + }); + }); }); From c88df9ded5b0b91b4685b2b78ee067150e32d1d4 Mon Sep 17 00:00:00 2001 From: Maick Speck Date: Tue, 28 Jun 2022 10:55:22 -0300 Subject: [PATCH 31/39] model city by country --- .../adapter/controller/cities.controller.ts | 4 ++-- .../cities/cities-by-country.builder.ts | 22 +++++++++++++++++++ .../neighborhoods-mongo.builder.ts | 12 +++++++--- .../neighborhoods-puppeteer.builder.ts | 12 +++++++--- .../search-neighborhoods-db.builder.ts | 16 +++++++++----- .../domain/helper/builder/builder.builder.ts | 9 ++++++++ .../interface/helper/builder.interface.ts | 3 +++ .../model/cities/cities-by-country.model.ts | 5 +++++ .../get/get-cities-by-country.service.ts | 9 +++++--- 9 files changed, 76 insertions(+), 16 deletions(-) create mode 100644 src/microservice/adapter/helper/builder/cities/cities-by-country.builder.ts create mode 100644 src/microservice/domain/helper/builder/builder.builder.ts create mode 100644 src/microservice/domain/interface/helper/builder.interface.ts create mode 100644 src/microservice/domain/model/cities/cities-by-country.model.ts diff --git a/src/microservice/adapter/controller/cities.controller.ts b/src/microservice/adapter/controller/cities.controller.ts index 957ba7a..2c84dea 100644 --- a/src/microservice/adapter/controller/cities.controller.ts +++ b/src/microservice/adapter/controller/cities.controller.ts @@ -11,6 +11,7 @@ import { ApiTags } from '@nestjs/swagger'; import { CityResponse } from '../../domain/model/cities/city-response.model'; +import { CitiesByCountry } from '../../domain/model/cities/cities-by-country.model'; @ApiTags('cities') @Controller('cities') @@ -57,8 +58,7 @@ export class CitiesController extends AbstractController { }) @ApiOkResponse({ description: 'Cities found.', - isArray: true, - type: CityResponse + type: CitiesByCountry }) @ApiParam({ name: 'country', diff --git a/src/microservice/adapter/helper/builder/cities/cities-by-country.builder.ts b/src/microservice/adapter/helper/builder/cities/cities-by-country.builder.ts new file mode 100644 index 0000000..879c17c --- /dev/null +++ b/src/microservice/adapter/helper/builder/cities/cities-by-country.builder.ts @@ -0,0 +1,22 @@ +import { Builder } from '../../../../domain/helper/builder/builder.builder'; +import { CitiesByCountry } from '../../../../domain/model/cities/cities-by-country.model'; +import { City } from '../../../../domain/schemas/city.schema'; + +export class CitiesByCountryBuilder extends Builder { + constructor(inputElement: City[]) { + super(inputElement); + } + + build(): CitiesByCountry { + const builtElement = new CitiesByCountry(); + for (const item of this.inputElement) { + const keyState = `${item.stateName.capitalize()} - ${item.stateCode.toUpperCase()}`; + if (Object.keys(builtElement).includes(keyState)) { + delete item.stateName; + builtElement[keyState].push(item); + } else builtElement[keyState] = []; + } + + return builtElement; + } +} diff --git a/src/microservice/adapter/helper/builder/neighborhoods/neighborhoods-mongo.builder.ts b/src/microservice/adapter/helper/builder/neighborhoods/neighborhoods-mongo.builder.ts index b2f4ba8..c0a05cd 100644 --- a/src/microservice/adapter/helper/builder/neighborhoods/neighborhoods-mongo.builder.ts +++ b/src/microservice/adapter/helper/builder/neighborhoods/neighborhoods-mongo.builder.ts @@ -1,14 +1,20 @@ +import { Builder } from '../../../../domain/helper/builder/builder.builder'; import { ValidOutputSearchByCity } from '../../../../domain/interface/valid-output-search/valid-outpu-search.interface'; import { NeighborhoodByCity } from '../../../../domain/model/neighborhoods/neighborhood-by-city.model'; import { Neighborhood } from '../../../../domain/schemas/neighborhood.schema'; -export class NeighborhoodsMongoBuilder { - constructor(private readonly puppeteerResponse: NeighborhoodByCity[]) {} +export class NeighborhoodsMongoBuilder extends Builder< + NeighborhoodByCity[], + Neighborhood[] +> { + constructor(inputElement: NeighborhoodByCity[]) { + super(inputElement); + } build(searchParams: ValidOutputSearchByCity): Neighborhood[] { const arr = []; - this.puppeteerResponse.forEach((item) => { + this.inputElement.forEach((item) => { const obj = new Neighborhood(); obj.countryId = searchParams.country.id; obj.country = searchParams.country.name; diff --git a/src/microservice/adapter/helper/builder/neighborhoods/neighborhoods-puppeteer.builder.ts b/src/microservice/adapter/helper/builder/neighborhoods/neighborhoods-puppeteer.builder.ts index 27a15dd..ddb0dbb 100644 --- a/src/microservice/adapter/helper/builder/neighborhoods/neighborhoods-puppeteer.builder.ts +++ b/src/microservice/adapter/helper/builder/neighborhoods/neighborhoods-puppeteer.builder.ts @@ -1,12 +1,18 @@ +import { Builder } from '../../../../domain/helper/builder/builder.builder'; import { NeighborhoodByCity } from '../../../../domain/model/neighborhoods/neighborhood-by-city.model'; import { Neighborhood } from '../../../../domain/schemas/neighborhood.schema'; -export class NeighborhoodsPuppeteerBuilder { - constructor(private readonly mongoResponse: Neighborhood[]) {} +export class NeighborhoodsPuppeteerBuilder extends Builder< + Neighborhood[], + NeighborhoodByCity[] +> { + constructor(inputElement: Neighborhood[]) { + super(inputElement); + } build(): NeighborhoodByCity[] { const arr = []; - this.mongoResponse.forEach((document) => { + this.inputElement.forEach((document) => { const obj = new NeighborhoodByCity(); obj.name = document.name; obj.cityId = document.cityId; diff --git a/src/microservice/adapter/helper/builder/neighborhoods/search-neighborhoods-db.builder.ts b/src/microservice/adapter/helper/builder/neighborhoods/search-neighborhoods-db.builder.ts index 191392c..8f9afbd 100644 --- a/src/microservice/adapter/helper/builder/neighborhoods/search-neighborhoods-db.builder.ts +++ b/src/microservice/adapter/helper/builder/neighborhoods/search-neighborhoods-db.builder.ts @@ -1,14 +1,20 @@ +import { Builder } from '../../../../domain/helper/builder/builder.builder'; import { ValidOutputSearchByCity } from '../../../../domain/interface/valid-output-search/valid-outpu-search.interface'; import { SearchNeighborhoodsDB } from '../../../../domain/model/search/neighborhoods/search-neighborhoods-db.model'; -export class SearchNeighborhoodsDBBuilder { - constructor(private readonly convertedSearch: ValidOutputSearchByCity) {} +export class SearchNeighborhoodsDBBuilder extends Builder< + ValidOutputSearchByCity, + SearchNeighborhoodsDB +> { + constructor(inputElement: ValidOutputSearchByCity) { + super(inputElement); + } build(): SearchNeighborhoodsDB { return new SearchNeighborhoodsDB( - this.convertedSearch.country.id, - this.convertedSearch.state.id, - this.convertedSearch.city.id + this.inputElement.country.id, + this.inputElement.state.id, + this.inputElement.city.id ); } } diff --git a/src/microservice/domain/helper/builder/builder.builder.ts b/src/microservice/domain/helper/builder/builder.builder.ts new file mode 100644 index 0000000..eba252d --- /dev/null +++ b/src/microservice/domain/helper/builder/builder.builder.ts @@ -0,0 +1,9 @@ +import { IBuilder } from '../../interface/helper/builder.interface'; + +export abstract class Builder + implements IBuilder +{ + constructor(protected readonly inputElement: InputElementConvert) {} + + abstract build(buildParams?: any): BuiltElement; +} diff --git a/src/microservice/domain/interface/helper/builder.interface.ts b/src/microservice/domain/interface/helper/builder.interface.ts new file mode 100644 index 0000000..380b8a6 --- /dev/null +++ b/src/microservice/domain/interface/helper/builder.interface.ts @@ -0,0 +1,3 @@ +export interface IBuilder { + build(buildParams): BuiltElement; +} diff --git a/src/microservice/domain/model/cities/cities-by-country.model.ts b/src/microservice/domain/model/cities/cities-by-country.model.ts new file mode 100644 index 0000000..0837c4f --- /dev/null +++ b/src/microservice/domain/model/cities/cities-by-country.model.ts @@ -0,0 +1,5 @@ +import { CityResponse } from './city-response.model'; + +export class CitiesByCountry { + [key: string]: CityResponse[]; +} diff --git a/src/microservice/domain/service/cities/get/get-cities-by-country.service.ts b/src/microservice/domain/service/cities/get/get-cities-by-country.service.ts index 3fb600c..6f8d5a7 100644 --- a/src/microservice/domain/service/cities/get/get-cities-by-country.service.ts +++ b/src/microservice/domain/service/cities/get/get-cities-by-country.service.ts @@ -1,9 +1,10 @@ import { Injectable } from '@nestjs/common'; -import { CityResponse } from 'src/microservice/domain/model/cities/city-response.model'; +import { CitiesByCountry } from '../../../model/cities/cities-by-country.model'; import { CitiesMongoose } from '../../../../adapter/repository/cities/cities-mongoose.repository'; import { City } from '../../../schemas/city.schema'; import { ValidateCountryByNameOrAliasService } from '../../countries/validate-country-by-name-or-alias.service'; import { CitiesService } from '../cities.service'; +import { CitiesByCountryBuilder } from '../../../../adapter/helper/builder/cities/cities-by-country.builder'; @Injectable() export class GetCitiesByCountryService extends CitiesService { @@ -14,14 +15,15 @@ export class GetCitiesByCountryService extends CitiesService { super(mongoRepository); } - async getCitiesByCountry(countryRef: string): Promise { + async getCitiesByCountry(countryRef: string): Promise { const country = await this.validateCountryService.validateCountry( countryRef ); this.logger.log('Searching cities in database...'); - return this.findCitiesByCountry(country.id); + const arrCities = await this.findCitiesByCountry(country.id); + return new CitiesByCountryBuilder(arrCities).build(); } async findCitiesByCountry(countryId: number): Promise { @@ -32,6 +34,7 @@ export class GetCitiesByCountryService extends CitiesService { countryId: 1, countryCode: 1, stateId: 1, + stateName: 1, state: 1, stateCode: 1, city: 1, From de83dadd66133b72981fa30605094426486ccc05 Mon Sep 17 00:00:00 2001 From: Maick Speck Date: Tue, 28 Jun 2022 11:13:09 -0300 Subject: [PATCH 32/39] optmize search services --- .../neighborhoods-by-state.builder.ts | 31 ++++++++++++ .../search-neighborhoods-db.model.ts | 2 +- .../mongoose/mongoose.repository.ts | 1 + .../mongoose/places-mongoose.repository.ts | 1 + .../get/get-neighborhoods-by-state.service.ts | 48 +++++-------------- 5 files changed, 47 insertions(+), 36 deletions(-) create mode 100644 src/microservice/adapter/helper/builder/neighborhoods/neighborhoods-by-state.builder.ts diff --git a/src/microservice/adapter/helper/builder/neighborhoods/neighborhoods-by-state.builder.ts b/src/microservice/adapter/helper/builder/neighborhoods/neighborhoods-by-state.builder.ts new file mode 100644 index 0000000..09cd295 --- /dev/null +++ b/src/microservice/adapter/helper/builder/neighborhoods/neighborhoods-by-state.builder.ts @@ -0,0 +1,31 @@ +import { + NeighborhoodsByState, + NeighborhooodAggregatedByCity +} from '../../../../domain/model/neighborhoods/neighborhoods-by-state.model'; +import { Neighborhood } from '../../../../domain/schemas/neighborhood.schema'; +import { Builder } from '../../../../domain/helper/builder/builder.builder'; +import { ValidOutputSearchByState } from '../../../../domain/interface/valid-output-search/valid-outpu-search.interface'; + +export class NeighborhoodsByStateBuilder extends Builder< + Neighborhood[], + NeighborhoodsByState +> { + constructor(inputElement: Neighborhood[]) { + super(inputElement); + } + + build(convertedSearch: ValidOutputSearchByState): NeighborhoodsByState { + const builtElement = new NeighborhoodsByState(); + for (const item of this.inputElement) { + const keyCity = item.city.capitalize(); + if (Object.keys(builtElement).includes(keyCity)) { + const obj = new NeighborhooodAggregatedByCity(); + obj.name = item.name; + obj.cityId = obj.cityId; + obj.state = `${convertedSearch.state.name} - ${convertedSearch.country.iso3}`; + builtElement[keyCity].push(obj); + } else builtElement[keyCity] = []; + } + return builtElement; + } +} diff --git a/src/microservice/domain/model/search/neighborhoods/search-neighborhoods-db.model.ts b/src/microservice/domain/model/search/neighborhoods/search-neighborhoods-db.model.ts index 1ecd08c..965ebdf 100644 --- a/src/microservice/domain/model/search/neighborhoods/search-neighborhoods-db.model.ts +++ b/src/microservice/domain/model/search/neighborhoods/search-neighborhoods-db.model.ts @@ -4,6 +4,6 @@ export class SearchNeighborhoodsDB { constructor( public countryId: number, public stateId: number, - public cityId: number + public cityId: number = null ) {} } diff --git a/src/microservice/domain/repository/mongoose/mongoose.repository.ts b/src/microservice/domain/repository/mongoose/mongoose.repository.ts index bedd5d4..fc30242 100644 --- a/src/microservice/domain/repository/mongoose/mongoose.repository.ts +++ b/src/microservice/domain/repository/mongoose/mongoose.repository.ts @@ -61,6 +61,7 @@ export abstract class MongooseRepository { buildRegexFilterQuery(objSearch: object = {}) { const objSearchRegex = {}; Object.keys(objSearch).forEach(function (key) { + if (objSearch[key] == null) return; objSearchRegex[key] = objSearch[key]; if (typeof objSearch[key] === 'string') objSearchRegex[key] = new RegExp(objSearch[key], 'i'); diff --git a/src/microservice/domain/repository/mongoose/places-mongoose.repository.ts b/src/microservice/domain/repository/mongoose/places-mongoose.repository.ts index 4e35702..c928215 100644 --- a/src/microservice/domain/repository/mongoose/places-mongoose.repository.ts +++ b/src/microservice/domain/repository/mongoose/places-mongoose.repository.ts @@ -28,6 +28,7 @@ export abstract class PlacesMongooseRepository< searchParams: object, select: object = {} ): Promise { + console.log(JSON.stringify(searchParams)); if (Object.keys(select).length == 0) select = { _id: 0 }; return this.model .find(this.buildRegexFilterQuery(searchParams)) diff --git a/src/microservice/domain/service/neighborhoods/get/get-neighborhoods-by-state.service.ts b/src/microservice/domain/service/neighborhoods/get/get-neighborhoods-by-state.service.ts index 08cce9f..6f73fb6 100644 --- a/src/microservice/domain/service/neighborhoods/get/get-neighborhoods-by-state.service.ts +++ b/src/microservice/domain/service/neighborhoods/get/get-neighborhoods-by-state.service.ts @@ -3,13 +3,12 @@ import { SearchNeighborhoodsDTO } from '../../../model/search/neighborhoods/sear import { NeighborhoodsMongoose } from '../../../../adapter/repository/neighborhoods/neighborhoods-mongoose.repository'; import { ValidOutputSearchByState } from '../../../interface/valid-output-search/valid-outpu-search.interface'; import { SearchNeighborhoodsDB } from '../../../model/search/neighborhoods/search-neighborhoods-db.model'; -import { - NeighborhoodsByState, - NeighborhooodAggregatedByCity -} from '../../../model/neighborhoods/neighborhoods-by-state.model'; +import { NeighborhoodsByState } from '../../../model/neighborhoods/neighborhoods-by-state.model'; import { NeighborhoodsService } from '../neighborhoods.service'; import { ValidateInputParamsService } from '../../validate/validate-input-params.service'; import { AggregatedNeighborhoodsByCity } from '../../../interface/aggregated/aggregated-neighborhoods-city.interface'; +import { NeighborhoodsByStateBuilder } from '../../../../adapter/helper/builder/neighborhoods/neighborhoods-by-state.builder'; +import { Neighborhood } from '../../../schemas/neighborhood.schema'; @Injectable() export class GetNeighborhoodsByStateService extends NeighborhoodsService { @@ -28,48 +27,27 @@ export class GetNeighborhoodsByStateService extends NeighborhoodsService { return this.findNeighborhoodsByStateInDatabase(convertedSearch); } + async findNeighborhoodsByStateInDatabase( convertedSearch: ValidOutputSearchByState ): Promise { - const arrResponse: NeighborhoodsByState = {}; - this.logger.log( - `Searching cities for state '${convertedSearch.state.stateCode}'...` + `Searching Neighborhoods for state '${convertedSearch.state.stateCode}'...` ); - const aggregatedByCity = await this.groupByCity(convertedSearch.state.id); - this.logger.log(`Founded cities: ${aggregatedByCity.length}`); - for await (const item of aggregatedByCity) { - const cityId = item._id.cityId; - const arrNeighborhoods = await this.findByCityAndStateInDatabase( - convertedSearch, - cityId - ); - - this.logger.log( - `City "${item.city}": ${arrNeighborhoods.length} Neighborhoods` - ); + const arrByState = await this.findByStateInDatabase(convertedSearch); + this.logger.log(`Founded Neighborhoods: ${arrByState.length}`); - arrResponse[item.city] = arrNeighborhoods.map((neighborhood) => { - const obj = new NeighborhooodAggregatedByCity(); - obj.name = neighborhood.name; - obj.cityId = cityId; - obj.state = `${convertedSearch.state.name} - ${convertedSearch.country.iso3}`; - return obj; - }); - } - return arrResponse; + return new NeighborhoodsByStateBuilder(arrByState).build(convertedSearch); } - async findByCityAndStateInDatabase( - convertedSearch: ValidOutputSearchByState, - cityId: number - ) { + async findByStateInDatabase( + convertedSearch: ValidOutputSearchByState + ): Promise { const searchDB = new SearchNeighborhoodsDB( convertedSearch.country.id, - convertedSearch.state.id, - cityId + convertedSearch.state.id ); - return this.findInDatabase(searchDB); + return this.mongoRepository.findBySearchParams(searchDB); } async groupByCity(stateId: number): Promise { From 468d18a20d1f656d0afe45a973160bc350146a16 Mon Sep 17 00:00:00 2001 From: Maick Speck Date: Tue, 28 Jun 2022 11:38:07 -0300 Subject: [PATCH 33/39] sort --- .../neighborhoods-by-state.builder.ts | 2 +- .../mongoose/places-mongoose.repository.ts | 15 ++++++++------- .../cities/get/get-cities-by-country.service.ts | 5 ++++- .../get/get-neighborhoods-by-state.service.ts | 6 +++++- 4 files changed, 18 insertions(+), 10 deletions(-) diff --git a/src/microservice/adapter/helper/builder/neighborhoods/neighborhoods-by-state.builder.ts b/src/microservice/adapter/helper/builder/neighborhoods/neighborhoods-by-state.builder.ts index 09cd295..d2d3d34 100644 --- a/src/microservice/adapter/helper/builder/neighborhoods/neighborhoods-by-state.builder.ts +++ b/src/microservice/adapter/helper/builder/neighborhoods/neighborhoods-by-state.builder.ts @@ -21,7 +21,7 @@ export class NeighborhoodsByStateBuilder extends Builder< if (Object.keys(builtElement).includes(keyCity)) { const obj = new NeighborhooodAggregatedByCity(); obj.name = item.name; - obj.cityId = obj.cityId; + obj.cityId = item.cityId; obj.state = `${convertedSearch.state.name} - ${convertedSearch.country.iso3}`; builtElement[keyCity].push(obj); } else builtElement[keyCity] = []; diff --git a/src/microservice/domain/repository/mongoose/places-mongoose.repository.ts b/src/microservice/domain/repository/mongoose/places-mongoose.repository.ts index c928215..538c92d 100644 --- a/src/microservice/domain/repository/mongoose/places-mongoose.repository.ts +++ b/src/microservice/domain/repository/mongoose/places-mongoose.repository.ts @@ -26,14 +26,15 @@ export abstract class PlacesMongooseRepository< async findBySearchParams( searchParams: object, - select: object = {} + select: object = {}, + sort: any = { name: 1 } ): Promise { - console.log(JSON.stringify(searchParams)); if (Object.keys(select).length == 0) select = { _id: 0 }; - return this.model - .find(this.buildRegexFilterQuery(searchParams)) - .select(select) - .lean() - .exec(); + let res = this.model.find(this.buildRegexFilterQuery(searchParams)); + + if (typeof sort === 'object' && Object.keys(sort).length > 0) + res = res.sort(sort); + + return res.select(select).lean().exec(); } } diff --git a/src/microservice/domain/service/cities/get/get-cities-by-country.service.ts b/src/microservice/domain/service/cities/get/get-cities-by-country.service.ts index 6f8d5a7..86f6639 100644 --- a/src/microservice/domain/service/cities/get/get-cities-by-country.service.ts +++ b/src/microservice/domain/service/cities/get/get-cities-by-country.service.ts @@ -41,6 +41,9 @@ export class GetCitiesByCountryService extends CitiesService { cityId: 1 }; - return this.mongoRepository.findBySearchParams({ countryId }, select); + return this.mongoRepository.findBySearchParams({ countryId }, select, { + stateName: 1, + name: 1 + }); } } diff --git a/src/microservice/domain/service/neighborhoods/get/get-neighborhoods-by-state.service.ts b/src/microservice/domain/service/neighborhoods/get/get-neighborhoods-by-state.service.ts index 6f73fb6..6338403 100644 --- a/src/microservice/domain/service/neighborhoods/get/get-neighborhoods-by-state.service.ts +++ b/src/microservice/domain/service/neighborhoods/get/get-neighborhoods-by-state.service.ts @@ -47,7 +47,11 @@ export class GetNeighborhoodsByStateService extends NeighborhoodsService { convertedSearch.country.id, convertedSearch.state.id ); - return this.mongoRepository.findBySearchParams(searchDB); + return this.mongoRepository.findBySearchParams( + searchDB, + { _id: 0, name: 1, cityId: 1, state: 1, city: 1 }, + { city: 1, name: 1 } + ); } async groupByCity(stateId: number): Promise { From a69c1ca766f2925576c4f075fd20a1c5f7f15e51 Mon Sep 17 00:00:00 2001 From: Maick Speck Date: Tue, 28 Jun 2022 12:01:49 -0300 Subject: [PATCH 34/39] fix tests optmize search --- .../cities/cities-by-country.builder.ts | 9 +++--- .../neighborhoods-by-state.builder.ts | 15 +++++----- .../neighborhoods-mongoose.repository.spec.ts | 12 +++++--- .../get/get-cities-by-country.service.spec.ts | 11 ++++++-- ...get-neighborhoods-by-state.service.spec.ts | 28 ++++++++++--------- 5 files changed, 45 insertions(+), 30 deletions(-) diff --git a/src/microservice/adapter/helper/builder/cities/cities-by-country.builder.ts b/src/microservice/adapter/helper/builder/cities/cities-by-country.builder.ts index 879c17c..538501c 100644 --- a/src/microservice/adapter/helper/builder/cities/cities-by-country.builder.ts +++ b/src/microservice/adapter/helper/builder/cities/cities-by-country.builder.ts @@ -11,10 +11,11 @@ export class CitiesByCountryBuilder extends Builder { const builtElement = new CitiesByCountry(); for (const item of this.inputElement) { const keyState = `${item.stateName.capitalize()} - ${item.stateCode.toUpperCase()}`; - if (Object.keys(builtElement).includes(keyState)) { - delete item.stateName; - builtElement[keyState].push(item); - } else builtElement[keyState] = []; + if (!Object.keys(builtElement).includes(keyState)) + builtElement[keyState] = []; + + delete item.stateName; + builtElement[keyState].push(item); } return builtElement; diff --git a/src/microservice/adapter/helper/builder/neighborhoods/neighborhoods-by-state.builder.ts b/src/microservice/adapter/helper/builder/neighborhoods/neighborhoods-by-state.builder.ts index d2d3d34..58c522a 100644 --- a/src/microservice/adapter/helper/builder/neighborhoods/neighborhoods-by-state.builder.ts +++ b/src/microservice/adapter/helper/builder/neighborhoods/neighborhoods-by-state.builder.ts @@ -18,13 +18,14 @@ export class NeighborhoodsByStateBuilder extends Builder< const builtElement = new NeighborhoodsByState(); for (const item of this.inputElement) { const keyCity = item.city.capitalize(); - if (Object.keys(builtElement).includes(keyCity)) { - const obj = new NeighborhooodAggregatedByCity(); - obj.name = item.name; - obj.cityId = item.cityId; - obj.state = `${convertedSearch.state.name} - ${convertedSearch.country.iso3}`; - builtElement[keyCity].push(obj); - } else builtElement[keyCity] = []; + if (!Object.keys(builtElement).includes(keyCity)) + builtElement[keyCity] = []; + + const obj = new NeighborhooodAggregatedByCity(); + obj.name = item.name; + obj.cityId = item.cityId; + obj.state = `${convertedSearch.state.name} - ${convertedSearch.country.iso3}`; + builtElement[keyCity].push(obj); } return builtElement; } diff --git a/test/unit/microservice/adapter/repository/neighborhoods/neighborhoods-mongoose.repository.spec.ts b/test/unit/microservice/adapter/repository/neighborhoods/neighborhoods-mongoose.repository.spec.ts index 0a506a8..818c4af 100644 --- a/test/unit/microservice/adapter/repository/neighborhoods/neighborhoods-mongoose.repository.spec.ts +++ b/test/unit/microservice/adapter/repository/neighborhoods/neighborhoods-mongoose.repository.spec.ts @@ -60,14 +60,18 @@ describe('NeighborhoodsMongoose', () => { ]; const mockFindNeighborhoods = { - select: jest.fn(() => { + sort: jest.fn(() => { return { - lean: jest.fn(() => { + select: jest.fn(() => { return { + lean: jest.fn(() => { + return { + exec: jest.fn(() => mockNeighborhoods()) + }; + }), exec: jest.fn(() => mockNeighborhoods()) }; - }), - exec: jest.fn(() => mockNeighborhoods()) + }) }; }) }; diff --git a/test/unit/microservice/domain/service/cities/get/get-cities-by-country.service.spec.ts b/test/unit/microservice/domain/service/cities/get/get-cities-by-country.service.spec.ts index 92032a9..87772b0 100644 --- a/test/unit/microservice/domain/service/cities/get/get-cities-by-country.service.spec.ts +++ b/test/unit/microservice/domain/service/cities/get/get-cities-by-country.service.spec.ts @@ -35,9 +35,13 @@ describe('GetCitiesByCountryService', () => { const mockCities = () => { const city1 = new City(); city1.name = 'any'; + city1.stateName = 'anystate'; + city1.stateCode = 'A2'; const city2 = new City(); - city2.name = 'any'; + city2.name = 'any2'; + city2.stateName = 'anystate2'; + city2.stateCode = 'A1'; return [city1, city2]; }; @@ -74,7 +78,10 @@ describe('GetCitiesByCountryService', () => { const actual = await sut.getCitiesByCountry('any'); - expect(actual).to.be.equal(arrMockCities); + expect(actual['Anystate - A2']).to.be.an('array'); + expect(actual['Anystate - A2'].length).to.be.equal(1); + expect(actual['Anystate2 - A1']).to.be.an('array'); + expect(actual['Anystate2 - A1'].length).to.be.equal(1); getCitiesStub.restore(); }); diff --git a/test/unit/microservice/domain/service/neighborhoods/get/get-neighborhoods-by-state.service.spec.ts b/test/unit/microservice/domain/service/neighborhoods/get/get-neighborhoods-by-state.service.spec.ts index a35ecfc..1e32e08 100644 --- a/test/unit/microservice/domain/service/neighborhoods/get/get-neighborhoods-by-state.service.spec.ts +++ b/test/unit/microservice/domain/service/neighborhoods/get/get-neighborhoods-by-state.service.spec.ts @@ -8,7 +8,6 @@ import { SearchNeighborhoodsDTO } from '../../../../../../../src/microservice/do import { ValidateInputParamsService } from '../../../../../../../src/microservice/domain/service/validate/validate-input-params.service'; import { Country } from '../../../../../../../src/microservice/domain/schemas/country.schema'; import { State } from '../../../../../../../src/microservice/domain/schemas/state.schema'; -import { City } from '../../../../../../../src/microservice/domain/schemas/city.schema'; import { GetNeighborhoodsByStateService } from '../../../../../../../src/microservice/domain/service/neighborhoods/get/get-neighborhoods-by-state.service'; describe('GetNeighborhoodsByStateService', () => { @@ -37,7 +36,15 @@ describe('GetNeighborhoodsByStateService', () => { const item1 = new Neighborhood(); item1.id = 1; item1.name = 'any'; + item1.city = 'Orleans'; + item1.cityId = 1; arr.push(item1); + const item2 = new Neighborhood(); + item2.id = 2; + item2.name = 'any1'; + item2.city = 'Braço do Norte'; + item2.cityId = 2; + arr.push(item2); return arr; }; @@ -45,12 +52,12 @@ describe('GetNeighborhoodsByStateService', () => { const country = new Country(); country.id = 31; country.name = 'Brazil'; + country.iso3 = 'BRA'; const state = new State(); state.id = 2014; state.name = 'Santa Catarina'; state.stateCode = 'SC'; - const city = new City(); - return { country, city, state }; + return { country, state }; }; const mockAggregatedCities = [ @@ -89,36 +96,31 @@ describe('GetNeighborhoodsByStateService', () => { }); describe('getNeighborhoodsByState', () => { - it('should call getNeighborhoodsByState and return an array by puppeteer', async () => { + it('should call getNeighborhoodsByState and return an array', async () => { const validateStub = sinon .stub(mockValidateService, 'validateAndConvertSearchByState') .returns(mockConvertedSearch()); const findInDatabaseStub = sinon - .stub(sut, 'findInDatabase') + .stub(mockNeighborhoodsMongooseRepository, 'findBySearchParams') .returns(mockMongoNeighborhoods()); - const groupByStub = sinon - .stub(sut, 'groupByCity') - .returns(mockAggregatedCities); - const searchParams = new SearchNeighborhoodsDTO('brasil', 'sc'); const actual = await sut.getNeighborhoodsByState(searchParams); expect(actual.Orleans).to.be.an('array'); expect(actual.Orleans.length).to.be.equal(1); - expect(actual['Braço do Norte']).to.be.an('array'); - expect(actual['Braço do Norte'].length).to.be.equal(1); + expect(actual['Braço Do Norte']).to.be.an('array'); + expect(actual['Braço Do Norte'].length).to.be.equal(1); findInDatabaseStub.restore(); validateStub.restore(); - groupByStub.restore(); }); }); describe('groupByCity', () => { - it('should call groupByCity and return an array by puppeteer', async () => { + it('should call groupByCity and return an array', async () => { const groupByStub = sinon .stub(mockNeighborhoodsMongooseRepository, 'groupBy') .returns(mockAggregatedCities); From bf44bb4776ede3fa2d623f2321b8c3deb50fc0ac Mon Sep 17 00:00:00 2001 From: Maick Speck Date: Tue, 28 Jun 2022 12:06:07 -0300 Subject: [PATCH 35/39] improve cov null key --- .../neighborhoods-mongoose.repository.spec.ts | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/test/unit/microservice/adapter/repository/neighborhoods/neighborhoods-mongoose.repository.spec.ts b/test/unit/microservice/adapter/repository/neighborhoods/neighborhoods-mongoose.repository.spec.ts index 818c4af..54c218c 100644 --- a/test/unit/microservice/adapter/repository/neighborhoods/neighborhoods-mongoose.repository.spec.ts +++ b/test/unit/microservice/adapter/repository/neighborhoods/neighborhoods-mongoose.repository.spec.ts @@ -137,6 +137,13 @@ describe('NeighborhoodsMongoose', () => { const actual = await sut.buildRegexFilterQuery(); expect(JSON.stringify(actual)).to.be.equal(JSON.stringify({})); }); + + it('should call buildRegexFilterQuery with null param and return regex filter with empty obj', async () => { + const actual = await sut.buildRegexFilterQuery({ + name: null + }); + expect(JSON.stringify(actual)).to.be.equal(JSON.stringify({})); + }); }); describe('insertOne', () => { From ee74c7ffc0740b62a44a08960c41a13b81deee58 Mon Sep 17 00:00:00 2001 From: Maick Speck Date: Tue, 28 Jun 2022 12:07:52 -0300 Subject: [PATCH 36/39] update change log 0.0.5 --- CHANGELOG.MD | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index baa0fe6..ae9f604 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -42,3 +42,5 @@ All notable changes to this project will be documented in this file. - Route States By Country - Route Countries - Swagger Openapi automation +- Optmize Neighborhoods by State +- Sort Collections result From d663be4a9b8afc90bb560eb3a2c254f2d7299974 Mon Sep 17 00:00:00 2001 From: Maick Speck Date: Tue, 28 Jun 2022 12:20:27 -0300 Subject: [PATCH 37/39] write file swagger auto --- README.md | 2 +- src/main.ts | 2 ++ .../search/neighborhoods/search-neighborhoods-dto.model.ts | 4 ---- swagger-spec.json | 1 + 4 files changed, 4 insertions(+), 5 deletions(-) create mode 100644 swagger-spec.json diff --git a/README.md b/README.md index 3aa6ee5..dc938d5 100644 --- a/README.md +++ b/README.md @@ -94,6 +94,6 @@ http://localhost:3000/states/brazil http://localhost:3000/countries/ ``` -[Swagger](https://app.swaggerhub.com/apis/dev-seeder/Places/1.0.0) +[Swagger](https://app.swaggerhub.com/apis/dev-seeder/Places/) At the moment, it's working only for Brazilians places. diff --git a/src/main.ts b/src/main.ts index df9d8a0..53c08a0 100644 --- a/src/main.ts +++ b/src/main.ts @@ -4,6 +4,7 @@ import { NestFactory } from '@nestjs/core'; import { useContainer } from 'class-validator'; import { AppModule } from './app.module'; import { SwaggerModule, DocumentBuilder } from '@nestjs/swagger'; +import * as fs from 'fs'; async function bootstrap() { const app = await NestFactory.create(AppModule); @@ -23,6 +24,7 @@ async function bootstrap() { .build(); const document = SwaggerModule.createDocument(app, docApi); + fs.writeFileSync('./swagger-spec.json', JSON.stringify(document)); SwaggerModule.setup('api', app, document); return await app.listen(configService.get('api.port')); diff --git a/src/microservice/domain/model/search/neighborhoods/search-neighborhoods-dto.model.ts b/src/microservice/domain/model/search/neighborhoods/search-neighborhoods-dto.model.ts index e805626..5b20553 100644 --- a/src/microservice/domain/model/search/neighborhoods/search-neighborhoods-dto.model.ts +++ b/src/microservice/domain/model/search/neighborhoods/search-neighborhoods-dto.model.ts @@ -2,10 +2,6 @@ import { ApiProperty } from '@nestjs/swagger'; import { DTO } from '../../dto.model'; export class SearchNeighborhoodsDTO extends DTO { - @ApiProperty({ - type: String, - description: 'The name of the Neighborhood' - }) public name: string; @ApiProperty({ diff --git a/swagger-spec.json b/swagger-spec.json new file mode 100644 index 0000000..7ef527c --- /dev/null +++ b/swagger-spec.json @@ -0,0 +1 @@ +{"openapi":"3.0.0","paths":{"/neighborhoods/city/{country}/{state}/{city}":{"get":{"operationId":"NeighborhoodsController_getNeighborhoodsByCity","summary":"","description":"Get Neighborhoods By City Reference","parameters":[{"name":"country","required":true,"in":"path","description":"The Country name of the neighborhood","schema":{"type":"string"}},{"name":"state","required":true,"in":"path","description":"The State name of the neighborhood","schema":{"type":"string"}},{"name":"city","required":true,"in":"path","description":"The City name of the neighborhood","schema":{"type":"string"}}],"responses":{"200":{"description":"Neighborhoods found.","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/NeighborhoodByCity"}}}}}},"tags":["neighborhoods"]}},"/neighborhoods/state/{country}/{state}":{"get":{"operationId":"NeighborhoodsController_getNeighborhoodsByState","summary":"","description":"Get Neighborhoods By State Reference","parameters":[{"name":"country","required":true,"in":"path","description":"The Country name of the neighborhood","schema":{"type":"string"}},{"name":"state","required":true,"in":"path","description":"The State name of the neighborhood","schema":{"type":"string"}},{"name":"city","required":true,"in":"path","description":"The city of the Neighborhood","schema":{"type":"string"}}],"responses":{"200":{"description":"Neighborhoods found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NeighborhoodsByState"}}}}},"tags":["neighborhoods"]}},"/cities/state/{country}/{state}":{"get":{"operationId":"CitiesController_getCitiesByState","summary":"","description":"Get Cities By State Reference","parameters":[{"name":"country","required":true,"in":"path","description":"The Country name of the city","schema":{"type":"string"}},{"name":"state","required":true,"in":"path","description":"The State name of the city","schema":{"type":"string"}}],"responses":{"200":{"description":"Cities found.","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/CityResponse"}}}}}},"tags":["cities"]}},"/cities/country/{country}":{"get":{"operationId":"CitiesController_getCitiesByCountry","summary":"","description":"Get Cities By Country Reference","parameters":[{"name":"country","required":true,"in":"path","description":"The Country name of the city","schema":{"type":"string"}}],"responses":{"200":{"description":"Cities found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CitiesByCountry"}}}}},"tags":["cities"]}},"/states/country/{country}":{"get":{"operationId":"StatesController_getStatesByCountry","parameters":[{"name":"country","required":true,"in":"path","description":"The Country name of the state","schema":{"type":"string"}}],"responses":{"200":{"description":"States found.","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/StatesByCountry"}}}}}},"tags":["states"]}},"/countries":{"get":{"operationId":"CountriesController_getAllCountries","summary":"","description":"Get All Countries","parameters":[],"responses":{"200":{"description":"Countries found.","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/CountryResponse"}}}}}},"tags":["countries"]}}},"info":{"title":"Places","description":"Places API","version":"0.0.5","contact":{}},"tags":[],"servers":[],"components":{"schemas":{"NeighborhoodByCity":{"type":"object","properties":{"name":{"type":"string","description":"The name of the Neighborhood","example":"Alto Paraná"},"cityId":{"type":"number","description":"The id reference of the City in database","example":1},"city":{"type":"string","description":"The name of the City's Neighborhood","example":"Orleans"},"stateId":{"type":"number","description":"The id reference of the state in database","example":2014},"countryId":{"type":"number","description":"The id reference of the country in database","example":31}},"required":["name","cityId","city","stateId","countryId"]},"NeighborhoodsByState":{"type":"object","properties":{}},"CityResponse":{"type":"object","properties":{"id":{"type":"number","description":"City Id reference in database","example":1},"name":{"type":"string","description":"The name of the City","example":"Orleans"},"countryCode":{"type":"string","description":"The code(ISO3) of the Country's City","example":"BRA"},"countryId":{"type":"number","description":"Country Id reference in database","example":31},"stateCode":{"type":"string","description":"The code(ISO2) of the State's City","example":"SC"},"stateId":{"type":"number","description":"State Id reference in database","example":2014}},"required":["id","name","countryCode","countryId","stateCode","stateId"]},"CitiesByCountry":{"type":"object","properties":{}},"StatesByCountry":{"type":"object","properties":{"id":{"type":"number","description":"State Id reference in database","example":1},"name":{"type":"string","description":"The name of the State","example":"Orleans"},"countryCode":{"type":"string","description":"The code(ISO3) of the Country's State","example":"BRA"},"countryId":{"type":"number","description":"Country Id reference in database","example":31},"stateCode":{"type":"string","description":"The code(ISO2) of the State","example":"SC"}},"required":["id","name","countryCode","countryId","stateCode"]},"CountryResponse":{"type":"object","properties":{"id":{"type":"number","description":"Country Id reference in database","example":1},"name":{"type":"string","description":"Country Name","example":"Brasil"},"iso3":{"type":"string","description":"The code(ISO3) of the Country","example":"BRA"},"iso2":{"type":"string","description":"The code(ISO2) of the Country","example":"BR"},"capital":{"type":"string","description":"Capital","example":"Brasília"},"currency":{"type":"string","description":"Currency Symbol","example":"R$"},"region":{"type":"string","description":"Continent Region of the country","example":"South America"},"subregion":{"type":"string","description":"Continent SubRegion of the country","example":"South"},"alias":{"description":"Alias names","example":["BR","BRA","Brazil","Brasil"],"type":"array","items":{"type":"string"}},"phoneCode":{"type":"number","description":"Phone number code DDI","example":55}},"required":["id","name","iso3","iso2","capital","currency","region","subregion","alias","phoneCode"]}}}} \ No newline at end of file From 6c96a9fe7caeaab84cabfa17d8ec687f083cd916 Mon Sep 17 00:00:00 2001 From: Maick Speck Date: Tue, 28 Jun 2022 12:27:09 -0300 Subject: [PATCH 38/39] fix e2e optmize --- test/e2e/app.e2e-spec.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/test/e2e/app.e2e-spec.ts b/test/e2e/app.e2e-spec.ts index 76c153a..084085a 100644 --- a/test/e2e/app.e2e-spec.ts +++ b/test/e2e/app.e2e-spec.ts @@ -56,7 +56,9 @@ describe('App (e2e) ', () => { '/cities/country/brasil' ); - expect(actual.body).to.be.an('array').that.is.not.empty; + expect(actual.body).to.be.an('object').that.is.not.empty; + expect(actual.body['Santa Catarina - SC']).to.be.an('array').that.is.not + .empty; }); }); From 68fea3efc19cf9fd617e77f98a4a2d679ca6b31b Mon Sep 17 00:00:00 2001 From: Maick Speck Date: Tue, 28 Jun 2022 12:38:24 -0300 Subject: [PATCH 39/39] places response --- .../model/cities/city-response.model.ts | 38 +------------------ .../domain/model/places-response.model.ts | 31 +++++++++++++++ .../model/states/states-by-country.model.ts | 33 ++-------------- .../mongoose/mongoose.repository.ts | 2 +- .../mongoose/places-mongoose.repository.ts | 2 +- 5 files changed, 38 insertions(+), 68 deletions(-) create mode 100644 src/microservice/domain/model/places-response.model.ts diff --git a/src/microservice/domain/model/cities/city-response.model.ts b/src/microservice/domain/model/cities/city-response.model.ts index edc292e..8b66dec 100644 --- a/src/microservice/domain/model/cities/city-response.model.ts +++ b/src/microservice/domain/model/cities/city-response.model.ts @@ -1,45 +1,11 @@ import { ApiProperty } from '@nestjs/swagger'; +import { PlacesReponse } from '../places-response.model'; -export class CityResponse { - @ApiProperty({ - type: Number, - description: 'City Id reference in database', - example: 1 - }) - id: number; - +export class CityResponse extends PlacesReponse { @ApiProperty({ type: String, description: 'The name of the City', example: 'Orleans' }) name: string; - - @ApiProperty({ - type: String, - description: `The code(ISO3) of the Country's City`, - example: 'BRA' - }) - countryCode: string; - - @ApiProperty({ - type: Number, - description: 'Country Id reference in database', - example: 31 - }) - countryId: number; - - @ApiProperty({ - type: String, - description: `The code(ISO2) of the State's City`, - example: 'SC' - }) - stateCode: string; - - @ApiProperty({ - type: Number, - description: 'State Id reference in database', - example: 2014 - }) - stateId: number; } diff --git a/src/microservice/domain/model/places-response.model.ts b/src/microservice/domain/model/places-response.model.ts new file mode 100644 index 0000000..f6e09e2 --- /dev/null +++ b/src/microservice/domain/model/places-response.model.ts @@ -0,0 +1,31 @@ +import { ApiProperty } from '@nestjs/swagger'; + +export abstract class PlacesReponse { + @ApiProperty({ + type: Number, + description: `Id reference in database`, + example: 1 + }) + id: number; + + @ApiProperty({ + type: String, + description: `The code(ISO3) of the Country's State`, + example: 'BRA' + }) + countryCode: string; + + @ApiProperty({ + type: Number, + description: 'Country Id reference in database', + example: 31 + }) + countryId: number; + + @ApiProperty({ + type: String, + description: `The code(ISO2) of the State`, + example: 'SC' + }) + stateCode: string; +} diff --git a/src/microservice/domain/model/states/states-by-country.model.ts b/src/microservice/domain/model/states/states-by-country.model.ts index 6d5748b..801f094 100644 --- a/src/microservice/domain/model/states/states-by-country.model.ts +++ b/src/microservice/domain/model/states/states-by-country.model.ts @@ -1,38 +1,11 @@ import { ApiProperty } from '@nestjs/swagger'; +import { PlacesReponse } from '../places-response.model'; -export class StatesByCountry { - @ApiProperty({ - type: Number, - description: 'State Id reference in database', - example: 1 - }) - id: number; - +export class StatesByCountry extends PlacesReponse { @ApiProperty({ type: String, description: 'The name of the State', - example: 'Orleans' + example: 'Santa Catarina' }) name: string; - - @ApiProperty({ - type: String, - description: `The code(ISO3) of the Country's State`, - example: 'BRA' - }) - countryCode: string; - - @ApiProperty({ - type: Number, - description: 'Country Id reference in database', - example: 31 - }) - countryId: number; - - @ApiProperty({ - type: String, - description: `The code(ISO2) of the State`, - example: 'SC' - }) - stateCode: string; } diff --git a/src/microservice/domain/repository/mongoose/mongoose.repository.ts b/src/microservice/domain/repository/mongoose/mongoose.repository.ts index fc30242..39bc53e 100644 --- a/src/microservice/domain/repository/mongoose/mongoose.repository.ts +++ b/src/microservice/domain/repository/mongoose/mongoose.repository.ts @@ -70,7 +70,7 @@ export abstract class MongooseRepository { } async findAll(select: object = {}): Promise { - if (Object.keys(select).length == 0) select = { _id: 0 }; + if (Object.keys(select).length === 0) select = { _id: 0 }; return this.model.find({}).select(select).lean().exec(); } } diff --git a/src/microservice/domain/repository/mongoose/places-mongoose.repository.ts b/src/microservice/domain/repository/mongoose/places-mongoose.repository.ts index 538c92d..6afdfbc 100644 --- a/src/microservice/domain/repository/mongoose/places-mongoose.repository.ts +++ b/src/microservice/domain/repository/mongoose/places-mongoose.repository.ts @@ -29,7 +29,7 @@ export abstract class PlacesMongooseRepository< select: object = {}, sort: any = { name: 1 } ): Promise { - if (Object.keys(select).length == 0) select = { _id: 0 }; + if (Object.keys(select).length === 0) select = { _id: 0 }; let res = this.model.find(this.buildRegexFilterQuery(searchParams)); if (typeof sort === 'object' && Object.keys(sort).length > 0)