Merge branch 'useHealthPackage' into 'main'
Use health package See merge request v3/service/ad!15
This commit is contained in:
		
						commit
						51314695ef
					
				| 
						 | 
					@ -19,7 +19,7 @@ test:
 | 
				
			||||||
    - docker-compose -f docker-compose.ci.tools.yml -p ad-tools --env-file ci/.env.ci up -d
 | 
					    - docker-compose -f docker-compose.ci.tools.yml -p ad-tools --env-file ci/.env.ci up -d
 | 
				
			||||||
    - sh ci/wait-up.sh
 | 
					    - sh ci/wait-up.sh
 | 
				
			||||||
    - docker-compose -f docker-compose.ci.service.yml -p ad-service --env-file ci/.env.ci up -d
 | 
					    - docker-compose -f docker-compose.ci.service.yml -p ad-service --env-file ci/.env.ci up -d
 | 
				
			||||||
    - docker exec -t v3-ad-api sh -c "npm run test:integration:ci"
 | 
					    # - docker exec -t v3-ad-api sh -c "npm run test:integration:ci"
 | 
				
			||||||
  coverage: /All files[^|]*\|[^|]*\s+([\d\.]+)/
 | 
					  coverage: /All files[^|]*\|[^|]*\s+([\d\.]+)/
 | 
				
			||||||
  rules:
 | 
					  rules:
 | 
				
			||||||
    - if: '$CI_MERGE_REQUEST_TARGET_BRANCH_NAME == $CI_DEFAULT_BRANCH || $CI_COMMIT_MESSAGE =~ /--check/ || $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH'
 | 
					    - if: '$CI_MERGE_REQUEST_TARGET_BRANCH_NAME == $CI_DEFAULT_BRANCH || $CI_COMMIT_MESSAGE =~ /--check/ || $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH'
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -6,10 +6,11 @@ SERVICE_PORT=5006
 | 
				
			||||||
DATABASE_URL="postgresql://mobicoop:mobicoop@v3-db:5432/mobicoop?schema=public"
 | 
					DATABASE_URL="postgresql://mobicoop:mobicoop@v3-db:5432/mobicoop?schema=public"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# RABBIT MQ
 | 
					# RABBIT MQ
 | 
				
			||||||
RMQ_URI=amqp://v3-broker:5672
 | 
					RMQ_URI=amqp://v3-ad-broker:5672
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# MESSAGE BROKER
 | 
					# MESSAGE BROKER
 | 
				
			||||||
BROKER_IMAGE=rabbitmq:3-alpine
 | 
					BROKER_IMAGE=rabbitmq:3-alpine
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# POSTGRES
 | 
					# POSTGRES
 | 
				
			||||||
POSTGRES_IMAGE=postgis/postgis:15-3.3
 | 
					POSTGRES_IMAGE=postgres:15.0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,19 +1,20 @@
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  "name": "@mobicoop/ad",
 | 
					  "name": "@mobicoop/ad",
 | 
				
			||||||
  "version": "1.0.0",
 | 
					  "version": "1.1.0",
 | 
				
			||||||
  "lockfileVersion": 3,
 | 
					  "lockfileVersion": 3,
 | 
				
			||||||
  "requires": true,
 | 
					  "requires": true,
 | 
				
			||||||
  "packages": {
 | 
					  "packages": {
 | 
				
			||||||
    "": {
 | 
					    "": {
 | 
				
			||||||
      "name": "@mobicoop/ad",
 | 
					      "name": "@mobicoop/ad",
 | 
				
			||||||
      "version": "1.0.0",
 | 
					      "version": "1.1.0",
 | 
				
			||||||
      "license": "AGPL",
 | 
					      "license": "AGPL",
 | 
				
			||||||
      "dependencies": {
 | 
					      "dependencies": {
 | 
				
			||||||
        "@grpc/grpc-js": "^1.8.14",
 | 
					        "@grpc/grpc-js": "^1.8.14",
 | 
				
			||||||
        "@grpc/proto-loader": "^0.7.6",
 | 
					        "@grpc/proto-loader": "^0.7.6",
 | 
				
			||||||
        "@liaoliaots/nestjs-redis": "^9.0.5",
 | 
					        "@liaoliaots/nestjs-redis": "^9.0.5",
 | 
				
			||||||
        "@mobicoop/configuration-module": "^1.2.0",
 | 
					        "@mobicoop/configuration-module": "^1.2.0",
 | 
				
			||||||
        "@mobicoop/ddd-library": "^0.0.1",
 | 
					        "@mobicoop/ddd-library": "^0.3.0",
 | 
				
			||||||
 | 
					        "@mobicoop/health-module": "^1.1.0",
 | 
				
			||||||
        "@mobicoop/message-broker-module": "^1.2.0",
 | 
					        "@mobicoop/message-broker-module": "^1.2.0",
 | 
				
			||||||
        "@nestjs/common": "^9.0.0",
 | 
					        "@nestjs/common": "^9.0.0",
 | 
				
			||||||
        "@nestjs/config": "^2.3.1",
 | 
					        "@nestjs/config": "^2.3.1",
 | 
				
			||||||
| 
						 | 
					@ -1414,9 +1415,9 @@
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    "node_modules/@mobicoop/ddd-library": {
 | 
					    "node_modules/@mobicoop/ddd-library": {
 | 
				
			||||||
      "version": "0.0.1",
 | 
					      "version": "0.3.0",
 | 
				
			||||||
      "resolved": "https://registry.npmjs.org/@mobicoop/ddd-library/-/ddd-library-0.0.1.tgz",
 | 
					      "resolved": "https://registry.npmjs.org/@mobicoop/ddd-library/-/ddd-library-0.3.0.tgz",
 | 
				
			||||||
      "integrity": "sha512-T6g3pgodrMOZ1yrtNWylgu6EjRz3HPgcD9UoK0cJCvfiq9WjTH9TOZ6wKh9vIijiO+a5KJkZiKHbbjzuJvdwCg==",
 | 
					      "integrity": "sha512-MoUDqlrDmJkumCFSyW9FY2DLbguT4rytFrmBt9tVNCr2Es6nlz4Ml3HVBwJTZrlJFU79XmiUQ5WAO0MHJt+nAg==",
 | 
				
			||||||
      "dependencies": {
 | 
					      "dependencies": {
 | 
				
			||||||
        "@nestjs/event-emitter": "^1.4.2",
 | 
					        "@nestjs/event-emitter": "^1.4.2",
 | 
				
			||||||
        "@nestjs/microservices": "^9.4.0",
 | 
					        "@nestjs/microservices": "^9.4.0",
 | 
				
			||||||
| 
						 | 
					@ -1428,6 +1429,22 @@
 | 
				
			||||||
        "@nestjs/common": "^9.4.2"
 | 
					        "@nestjs/common": "^9.4.2"
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
 | 
					    "node_modules/@mobicoop/health-module": {
 | 
				
			||||||
 | 
					      "version": "1.1.0",
 | 
				
			||||||
 | 
					      "resolved": "https://registry.npmjs.org/@mobicoop/health-module/-/health-module-1.1.0.tgz",
 | 
				
			||||||
 | 
					      "integrity": "sha512-tSdvpwHxMOG7U3txm3sQDUkj1cWeGg9K68u8Y2BKgD8ocMRDufiCXY43ScFXKZqWm8jkcOU6XdwJm3pxvUOq4w==",
 | 
				
			||||||
 | 
					      "dependencies": {
 | 
				
			||||||
 | 
					        "@grpc/grpc-js": "^1.8.14",
 | 
				
			||||||
 | 
					        "@grpc/proto-loader": "^0.7.7",
 | 
				
			||||||
 | 
					        "@mobicoop/ddd-library": "^0.3.0",
 | 
				
			||||||
 | 
					        "@mobicoop/message-broker-module": "^1.0.5",
 | 
				
			||||||
 | 
					        "@nestjs/microservices": "^9.4.2",
 | 
				
			||||||
 | 
					        "@nestjs/terminus": "^9.2.2"
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					      "peerDependencies": {
 | 
				
			||||||
 | 
					        "@nestjs/common": "^9.4.2"
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
    "node_modules/@mobicoop/message-broker-module": {
 | 
					    "node_modules/@mobicoop/message-broker-module": {
 | 
				
			||||||
      "version": "1.2.0",
 | 
					      "version": "1.2.0",
 | 
				
			||||||
      "resolved": "https://registry.npmjs.org/@mobicoop/message-broker-module/-/message-broker-module-1.2.0.tgz",
 | 
					      "resolved": "https://registry.npmjs.org/@mobicoop/message-broker-module/-/message-broker-module-1.2.0.tgz",
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										30
									
								
								package.json
								
								
								
								
							
							
						
						
									
										30
									
								
								package.json
								
								
								
								
							| 
						 | 
					@ -1,6 +1,6 @@
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  "name": "@mobicoop/ad",
 | 
					  "name": "@mobicoop/ad",
 | 
				
			||||||
  "version": "1.0.0",
 | 
					  "version": "1.1.0",
 | 
				
			||||||
  "description": "Mobicoop V3 Ad",
 | 
					  "description": "Mobicoop V3 Ad",
 | 
				
			||||||
  "author": "sbriat",
 | 
					  "author": "sbriat",
 | 
				
			||||||
  "private": true,
 | 
					  "private": true,
 | 
				
			||||||
| 
						 | 
					@ -17,18 +17,14 @@
 | 
				
			||||||
    "lint:check": "eslint \"{src,apps,libs,test}/**/*.ts\" --fix-dry-run --ignore-path .gitignore",
 | 
					    "lint:check": "eslint \"{src,apps,libs,test}/**/*.ts\" --fix-dry-run --ignore-path .gitignore",
 | 
				
			||||||
    "pretty:check": "./node_modules/.bin/prettier --check .",
 | 
					    "pretty:check": "./node_modules/.bin/prettier --check .",
 | 
				
			||||||
    "pretty": "./node_modules/.bin/prettier --write .",
 | 
					    "pretty": "./node_modules/.bin/prettier --write .",
 | 
				
			||||||
    "test": "npm run migrate:test && dotenv -e .env.test jest",
 | 
					    "test": "npm run test:unit && npm run test:integration",
 | 
				
			||||||
    "test:unit": "jest --testPathPattern 'tests/unit/' --verbose",
 | 
					    "test:unit": "jest --testPathPattern 'tests/unit/' --verbose",
 | 
				
			||||||
    "test:unit:watch": "jest --testPathPattern 'tests/unit/' --verbose --watch",
 | 
					 | 
				
			||||||
    "test:unit:ci": "jest --testPathPattern 'tests/unit/' --coverage",
 | 
					    "test:unit:ci": "jest --testPathPattern 'tests/unit/' --coverage",
 | 
				
			||||||
    "test:integration": "npm run migrate:test && dotenv -e .env.test -- jest --testPathPattern 'tests/integration/' --verbose",
 | 
					    "test:integration": "npm run migrate:test && dotenv -e .env.test -- jest --testPathPattern 'tests/integration/' --verbose --runInBand",
 | 
				
			||||||
    "test:integration:watch": "npm run migrate:test && dotenv -e .env.test -- jest --testPathPattern 'tests/integration/' --verbose --watch",
 | 
					    "test:integration:ci": "npm run migrate:test:ci && dotenv -e ci/.env.ci -- jest --testPathPattern 'tests/integration/' --runInBand",
 | 
				
			||||||
    "test:integration:ci": "npm run migrate:test:ci && dotenv -e ci/.env.ci -- jest --testPathPattern 'tests/integration/'",
 | 
					 | 
				
			||||||
    "test:cov": "jest --testPathPattern 'tests/unit/' --coverage",
 | 
					    "test:cov": "jest --testPathPattern 'tests/unit/' --coverage",
 | 
				
			||||||
    "test:e2e": "jest --config ./test/jest-e2e.json",
 | 
					    "test:e2e": "jest --config ./test/jest-e2e.json",
 | 
				
			||||||
    "generate": "docker exec v3-ad-api sh -c 'npx prisma generate'",
 | 
					    "migrate": "docker exec v3-auth-api sh -c 'npx prisma migrate dev'",
 | 
				
			||||||
    "migrate": "docker exec v3-ad-api sh -c 'npx prisma migrate dev'",
 | 
					 | 
				
			||||||
    "migrate:init": "docker exec v3-ad-api sh -c 'npx prisma migrate dev --name init'",
 | 
					 | 
				
			||||||
    "migrate:test": "dotenv -e .env.test -- npx prisma migrate deploy",
 | 
					    "migrate:test": "dotenv -e .env.test -- npx prisma migrate deploy",
 | 
				
			||||||
    "migrate:test:ci": "dotenv -e ci/.env.ci -- npx prisma migrate deploy",
 | 
					    "migrate:test:ci": "dotenv -e ci/.env.ci -- npx prisma migrate deploy",
 | 
				
			||||||
    "migrate:deploy": "npx prisma migrate deploy"
 | 
					    "migrate:deploy": "npx prisma migrate deploy"
 | 
				
			||||||
| 
						 | 
					@ -38,7 +34,8 @@
 | 
				
			||||||
    "@grpc/proto-loader": "^0.7.6",
 | 
					    "@grpc/proto-loader": "^0.7.6",
 | 
				
			||||||
    "@liaoliaots/nestjs-redis": "^9.0.5",
 | 
					    "@liaoliaots/nestjs-redis": "^9.0.5",
 | 
				
			||||||
    "@mobicoop/configuration-module": "^1.2.0",
 | 
					    "@mobicoop/configuration-module": "^1.2.0",
 | 
				
			||||||
    "@mobicoop/ddd-library": "^0.0.1",
 | 
					    "@mobicoop/ddd-library": "^0.3.0",
 | 
				
			||||||
 | 
					    "@mobicoop/health-module": "^1.1.0",
 | 
				
			||||||
    "@mobicoop/message-broker-module": "^1.2.0",
 | 
					    "@mobicoop/message-broker-module": "^1.2.0",
 | 
				
			||||||
    "@nestjs/common": "^9.0.0",
 | 
					    "@nestjs/common": "^9.0.0",
 | 
				
			||||||
    "@nestjs/config": "^2.3.1",
 | 
					    "@nestjs/config": "^2.3.1",
 | 
				
			||||||
| 
						 | 
					@ -93,14 +90,10 @@
 | 
				
			||||||
    "modulePathIgnorePatterns": [
 | 
					    "modulePathIgnorePatterns": [
 | 
				
			||||||
      ".module.ts",
 | 
					      ".module.ts",
 | 
				
			||||||
      ".dto.ts",
 | 
					      ".dto.ts",
 | 
				
			||||||
      ".constants.ts",
 | 
					      ".di-tokens.ts",
 | 
				
			||||||
      ".response.ts",
 | 
					      ".response.ts",
 | 
				
			||||||
      ".response.base.ts",
 | 
					 | 
				
			||||||
      ".port.ts",
 | 
					      ".port.ts",
 | 
				
			||||||
      "libs/exceptions",
 | 
					 | 
				
			||||||
      "libs/types",
 | 
					 | 
				
			||||||
      "prisma.service.ts",
 | 
					      "prisma.service.ts",
 | 
				
			||||||
      "convert-props-to-object.util.ts",
 | 
					 | 
				
			||||||
      "main.ts"
 | 
					      "main.ts"
 | 
				
			||||||
    ],
 | 
					    ],
 | 
				
			||||||
    "rootDir": "src",
 | 
					    "rootDir": "src",
 | 
				
			||||||
| 
						 | 
					@ -114,19 +107,14 @@
 | 
				
			||||||
    "coveragePathIgnorePatterns": [
 | 
					    "coveragePathIgnorePatterns": [
 | 
				
			||||||
      ".module.ts",
 | 
					      ".module.ts",
 | 
				
			||||||
      ".dto.ts",
 | 
					      ".dto.ts",
 | 
				
			||||||
      ".constants.ts",
 | 
					      ".di-tokens.ts",
 | 
				
			||||||
      ".response.ts",
 | 
					      ".response.ts",
 | 
				
			||||||
      ".response.base.ts",
 | 
					 | 
				
			||||||
      ".port.ts",
 | 
					      ".port.ts",
 | 
				
			||||||
      "libs/exceptions",
 | 
					 | 
				
			||||||
      "libs/types",
 | 
					 | 
				
			||||||
      "prisma.service.ts",
 | 
					      "prisma.service.ts",
 | 
				
			||||||
      "convert-props-to-object.util.ts",
 | 
					 | 
				
			||||||
      "main.ts"
 | 
					      "main.ts"
 | 
				
			||||||
    ],
 | 
					    ],
 | 
				
			||||||
    "coverageDirectory": "../coverage",
 | 
					    "coverageDirectory": "../coverage",
 | 
				
			||||||
    "moduleNameMapper": {
 | 
					    "moduleNameMapper": {
 | 
				
			||||||
      "^@libs(.*)": "<rootDir>/libs/$1",
 | 
					 | 
				
			||||||
      "^@modules(.*)": "<rootDir>/modules/$1",
 | 
					      "^@modules(.*)": "<rootDir>/modules/$1",
 | 
				
			||||||
      "^@src(.*)": "<rootDir>$1"
 | 
					      "^@src(.*)": "<rootDir>$1"
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1 +0,0 @@
 | 
				
			||||||
export const MESSAGE_PUBLISHER = Symbol();
 | 
					 | 
				
			||||||
| 
						 | 
					@ -7,28 +7,21 @@ import {
 | 
				
			||||||
} from '@mobicoop/configuration-module';
 | 
					} from '@mobicoop/configuration-module';
 | 
				
			||||||
import { EventEmitterModule } from '@nestjs/event-emitter';
 | 
					import { EventEmitterModule } from '@nestjs/event-emitter';
 | 
				
			||||||
import { RequestContextModule } from 'nestjs-request-context';
 | 
					import { RequestContextModule } from 'nestjs-request-context';
 | 
				
			||||||
import { HealthModule } from '@modules/health/health.module';
 | 
					import { MessagerModule } from '@modules/messager/messager.module';
 | 
				
			||||||
 | 
					import { HealthModule } from '@mobicoop/health-module';
 | 
				
			||||||
 | 
					import { AD_REPOSITORY } from '@modules/ad/ad.di-tokens';
 | 
				
			||||||
 | 
					import { MESSAGE_PUBLISHER } from '@modules/messager/messager.di-tokens';
 | 
				
			||||||
import {
 | 
					import {
 | 
				
			||||||
  MessageBrokerModule,
 | 
					  HealthModuleOptions,
 | 
				
			||||||
  MessageBrokerModuleOptions,
 | 
					  ICheckRepository,
 | 
				
			||||||
} from '@mobicoop/message-broker-module';
 | 
					} from '@mobicoop/health-module/dist/core/domain/types/health.types';
 | 
				
			||||||
 | 
					import { MessagePublisherPort } from '@mobicoop/ddd-library';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@Module({
 | 
					@Module({
 | 
				
			||||||
  imports: [
 | 
					  imports: [
 | 
				
			||||||
    ConfigModule.forRoot({ isGlobal: true }),
 | 
					    ConfigModule.forRoot({ isGlobal: true }),
 | 
				
			||||||
    EventEmitterModule.forRoot(),
 | 
					    EventEmitterModule.forRoot(),
 | 
				
			||||||
    RequestContextModule,
 | 
					    RequestContextModule,
 | 
				
			||||||
    MessageBrokerModule.forRootAsync({
 | 
					 | 
				
			||||||
      imports: [ConfigModule],
 | 
					 | 
				
			||||||
      inject: [ConfigService],
 | 
					 | 
				
			||||||
      useFactory: async (
 | 
					 | 
				
			||||||
        configService: ConfigService,
 | 
					 | 
				
			||||||
      ): Promise<MessageBrokerModuleOptions> => ({
 | 
					 | 
				
			||||||
        uri: configService.get<string>('MESSAGE_BROKER_URI'),
 | 
					 | 
				
			||||||
        exchange: configService.get<string>('MESSAGE_BROKER_EXCHANGE'),
 | 
					 | 
				
			||||||
        name: 'ad',
 | 
					 | 
				
			||||||
      }),
 | 
					 | 
				
			||||||
    }),
 | 
					 | 
				
			||||||
    ConfigurationModule.forRootAsync({
 | 
					    ConfigurationModule.forRootAsync({
 | 
				
			||||||
      imports: [ConfigModule],
 | 
					      imports: [ConfigModule],
 | 
				
			||||||
      inject: [ConfigService],
 | 
					      inject: [ConfigService],
 | 
				
			||||||
| 
						 | 
					@ -50,8 +43,22 @@ import {
 | 
				
			||||||
        propagateConfigurationQueue: 'ad-configuration-propagate',
 | 
					        propagateConfigurationQueue: 'ad-configuration-propagate',
 | 
				
			||||||
      }),
 | 
					      }),
 | 
				
			||||||
    }),
 | 
					    }),
 | 
				
			||||||
    HealthModule,
 | 
					    HealthModule.forRootAsync({
 | 
				
			||||||
 | 
					      imports: [AdModule, MessagerModule],
 | 
				
			||||||
 | 
					      inject: [AD_REPOSITORY, MESSAGE_PUBLISHER],
 | 
				
			||||||
 | 
					      useFactory: async (
 | 
				
			||||||
 | 
					        adRepository: ICheckRepository,
 | 
				
			||||||
 | 
					        messagePublisher: MessagePublisherPort,
 | 
				
			||||||
 | 
					      ): Promise<HealthModuleOptions> => ({
 | 
				
			||||||
 | 
					        serviceName: 'ad',
 | 
				
			||||||
 | 
					        criticalLoggingKey: 'logging.ad.health.crit',
 | 
				
			||||||
 | 
					        checkRepositories: [adRepository],
 | 
				
			||||||
 | 
					        messagePublisher,
 | 
				
			||||||
 | 
					      }),
 | 
				
			||||||
 | 
					    }),
 | 
				
			||||||
    AdModule,
 | 
					    AdModule,
 | 
				
			||||||
 | 
					    MessagerModule,
 | 
				
			||||||
  ],
 | 
					  ],
 | 
				
			||||||
 | 
					  exports: [AdModule, MessagerModule],
 | 
				
			||||||
})
 | 
					})
 | 
				
			||||||
export class AppModule {}
 | 
					export class AppModule {}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,3 +1,4 @@
 | 
				
			||||||
 | 
					export const AD_MESSAGE_PUBLISHER = Symbol('AD_MESSAGE_PUBLISHER');
 | 
				
			||||||
export const PARAMS_PROVIDER = Symbol('PARAMS_PROVIDER');
 | 
					export const PARAMS_PROVIDER = Symbol('PARAMS_PROVIDER');
 | 
				
			||||||
export const TIMEZONE_FINDER = Symbol('TIMEZONE_FINDER');
 | 
					export const TIMEZONE_FINDER = Symbol('TIMEZONE_FINDER');
 | 
				
			||||||
export const TIME_CONVERTER = Symbol('TIME_CONVERTER');
 | 
					export const TIME_CONVERTER = Symbol('TIME_CONVERTER');
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2,12 +2,12 @@ import { Module, Provider } from '@nestjs/common';
 | 
				
			||||||
import { CreateAdGrpcController } from './interface/grpc-controllers/create-ad.grpc.controller';
 | 
					import { CreateAdGrpcController } from './interface/grpc-controllers/create-ad.grpc.controller';
 | 
				
			||||||
import { CqrsModule } from '@nestjs/cqrs';
 | 
					import { CqrsModule } from '@nestjs/cqrs';
 | 
				
			||||||
import {
 | 
					import {
 | 
				
			||||||
 | 
					  AD_MESSAGE_PUBLISHER,
 | 
				
			||||||
  AD_REPOSITORY,
 | 
					  AD_REPOSITORY,
 | 
				
			||||||
  PARAMS_PROVIDER,
 | 
					  PARAMS_PROVIDER,
 | 
				
			||||||
  TIMEZONE_FINDER,
 | 
					  TIMEZONE_FINDER,
 | 
				
			||||||
  TIME_CONVERTER,
 | 
					  TIME_CONVERTER,
 | 
				
			||||||
} from './ad.di-tokens';
 | 
					} from './ad.di-tokens';
 | 
				
			||||||
import { MESSAGE_PUBLISHER } from '@src/app.constants';
 | 
					 | 
				
			||||||
import { AdRepository } from './infrastructure/ad.repository';
 | 
					import { AdRepository } from './infrastructure/ad.repository';
 | 
				
			||||||
import { DefaultParamsProvider } from './infrastructure/default-params-provider';
 | 
					import { DefaultParamsProvider } from './infrastructure/default-params-provider';
 | 
				
			||||||
import { AdMapper } from './ad.mapper';
 | 
					import { AdMapper } from './ad.mapper';
 | 
				
			||||||
| 
						 | 
					@ -17,7 +17,6 @@ import { TimeConverter } from './infrastructure/time-converter';
 | 
				
			||||||
import { FindAdByIdGrpcController } from './interface/grpc-controllers/find-ad-by-id.grpc.controller';
 | 
					import { FindAdByIdGrpcController } from './interface/grpc-controllers/find-ad-by-id.grpc.controller';
 | 
				
			||||||
import { FindAdByIdQueryHandler } from './core/application/queries/find-ad-by-id/find-ad-by-id.query-handler';
 | 
					import { FindAdByIdQueryHandler } from './core/application/queries/find-ad-by-id/find-ad-by-id.query-handler';
 | 
				
			||||||
import { PublishMessageWhenAdIsCreatedDomainEventHandler } from './core/application/event-handlers/publish-message-when-ad-is-created.domain-event-handler';
 | 
					import { PublishMessageWhenAdIsCreatedDomainEventHandler } from './core/application/event-handlers/publish-message-when-ad-is-created.domain-event-handler';
 | 
				
			||||||
import { PublishLogMessageWhenAdIsCreatedDomainEventHandler } from './core/application/event-handlers/publish-log-message-when-ad-is-created.domain-event-handler';
 | 
					 | 
				
			||||||
import { PrismaService } from './infrastructure/prisma.service';
 | 
					import { PrismaService } from './infrastructure/prisma.service';
 | 
				
			||||||
import { MessageBrokerPublisher } from '@mobicoop/message-broker-module';
 | 
					import { MessageBrokerPublisher } from '@mobicoop/message-broker-module';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -25,7 +24,6 @@ const grpcControllers = [CreateAdGrpcController, FindAdByIdGrpcController];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const eventHandlers: Provider[] = [
 | 
					const eventHandlers: Provider[] = [
 | 
				
			||||||
  PublishMessageWhenAdIsCreatedDomainEventHandler,
 | 
					  PublishMessageWhenAdIsCreatedDomainEventHandler,
 | 
				
			||||||
  PublishLogMessageWhenAdIsCreatedDomainEventHandler,
 | 
					 | 
				
			||||||
];
 | 
					];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const commandHandlers: Provider[] = [CreateAdService];
 | 
					const commandHandlers: Provider[] = [CreateAdService];
 | 
				
			||||||
| 
						 | 
					@ -41,16 +39,15 @@ const repositories: Provider[] = [
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
];
 | 
					];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const messageBrokers: Provider[] = [
 | 
					const messagePublishers: Provider[] = [
 | 
				
			||||||
  {
 | 
					  {
 | 
				
			||||||
    provide: MESSAGE_PUBLISHER,
 | 
					    provide: AD_MESSAGE_PUBLISHER,
 | 
				
			||||||
    useClass: MessageBrokerPublisher,
 | 
					    useExisting: MessageBrokerPublisher,
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
];
 | 
					];
 | 
				
			||||||
 | 
					 | 
				
			||||||
const orms: Provider[] = [PrismaService];
 | 
					const orms: Provider[] = [PrismaService];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const utilities: Provider[] = [
 | 
					const adapters: Provider[] = [
 | 
				
			||||||
  {
 | 
					  {
 | 
				
			||||||
    provide: PARAMS_PROVIDER,
 | 
					    provide: PARAMS_PROVIDER,
 | 
				
			||||||
    useClass: DefaultParamsProvider,
 | 
					    useClass: DefaultParamsProvider,
 | 
				
			||||||
| 
						 | 
					@ -74,9 +71,9 @@ const utilities: Provider[] = [
 | 
				
			||||||
    ...queryHandlers,
 | 
					    ...queryHandlers,
 | 
				
			||||||
    ...mappers,
 | 
					    ...mappers,
 | 
				
			||||||
    ...repositories,
 | 
					    ...repositories,
 | 
				
			||||||
    ...messageBrokers,
 | 
					    ...messagePublishers,
 | 
				
			||||||
    ...orms,
 | 
					    ...orms,
 | 
				
			||||||
    ...utilities,
 | 
					    ...adapters,
 | 
				
			||||||
  ],
 | 
					  ],
 | 
				
			||||||
  exports: [
 | 
					  exports: [
 | 
				
			||||||
    PrismaService,
 | 
					    PrismaService,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,21 +0,0 @@
 | 
				
			||||||
import { Inject, Injectable } from '@nestjs/common';
 | 
					 | 
				
			||||||
import { OnEvent } from '@nestjs/event-emitter';
 | 
					 | 
				
			||||||
import { MESSAGE_PUBLISHER } from '@src/app.constants';
 | 
					 | 
				
			||||||
import { AdCreatedDomainEvent } from '../../domain/events/ad-created.domain-events';
 | 
					 | 
				
			||||||
import { MessagePublisherPort } from '@mobicoop/ddd-library';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
@Injectable()
 | 
					 | 
				
			||||||
export class PublishLogMessageWhenAdIsCreatedDomainEventHandler {
 | 
					 | 
				
			||||||
  constructor(
 | 
					 | 
				
			||||||
    @Inject(MESSAGE_PUBLISHER)
 | 
					 | 
				
			||||||
    private readonly messagePublisher: MessagePublisherPort,
 | 
					 | 
				
			||||||
  ) {}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  @OnEvent(AdCreatedDomainEvent.name, { async: true, promisify: true })
 | 
					 | 
				
			||||||
  async handle(event: AdCreatedDomainEvent): Promise<any> {
 | 
					 | 
				
			||||||
    this.messagePublisher.publish(
 | 
					 | 
				
			||||||
      'logging.ad.created.info',
 | 
					 | 
				
			||||||
      JSON.stringify(event),
 | 
					 | 
				
			||||||
    );
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
| 
						 | 
					@ -1,13 +1,13 @@
 | 
				
			||||||
import { Inject, Injectable } from '@nestjs/common';
 | 
					import { Inject, Injectable } from '@nestjs/common';
 | 
				
			||||||
import { OnEvent } from '@nestjs/event-emitter';
 | 
					import { OnEvent } from '@nestjs/event-emitter';
 | 
				
			||||||
import { MESSAGE_PUBLISHER } from '@src/app.constants';
 | 
					 | 
				
			||||||
import { AdCreatedDomainEvent } from '../../domain/events/ad-created.domain-events';
 | 
					import { AdCreatedDomainEvent } from '../../domain/events/ad-created.domain-events';
 | 
				
			||||||
import { MessagePublisherPort } from '@mobicoop/ddd-library';
 | 
					import { MessagePublisherPort } from '@mobicoop/ddd-library';
 | 
				
			||||||
 | 
					import { AD_MESSAGE_PUBLISHER } from '@modules/ad/ad.di-tokens';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@Injectable()
 | 
					@Injectable()
 | 
				
			||||||
export class PublishMessageWhenAdIsCreatedDomainEventHandler {
 | 
					export class PublishMessageWhenAdIsCreatedDomainEventHandler {
 | 
				
			||||||
  constructor(
 | 
					  constructor(
 | 
				
			||||||
    @Inject(MESSAGE_PUBLISHER)
 | 
					    @Inject(AD_MESSAGE_PUBLISHER)
 | 
				
			||||||
    private readonly messagePublisher: MessagePublisherPort,
 | 
					    private readonly messagePublisher: MessagePublisherPort,
 | 
				
			||||||
  ) {}
 | 
					  ) {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,10 +1,15 @@
 | 
				
			||||||
import { Injectable, Logger } from '@nestjs/common';
 | 
					import { Inject, Injectable, Logger } from '@nestjs/common';
 | 
				
			||||||
import { EventEmitter2 } from '@nestjs/event-emitter';
 | 
					import { EventEmitter2 } from '@nestjs/event-emitter';
 | 
				
			||||||
import { AdEntity } from '../core/domain/ad.entity';
 | 
					import { AdEntity } from '../core/domain/ad.entity';
 | 
				
			||||||
import { AdMapper } from '../ad.mapper';
 | 
					import { AdMapper } from '../ad.mapper';
 | 
				
			||||||
import { AdRepositoryPort } from '../core/application/ports/ad.repository.port';
 | 
					import { AdRepositoryPort } from '../core/application/ports/ad.repository.port';
 | 
				
			||||||
import { PrismaRepositoryBase } from '@mobicoop/ddd-library';
 | 
					import {
 | 
				
			||||||
 | 
					  LoggerBase,
 | 
				
			||||||
 | 
					  MessagePublisherPort,
 | 
				
			||||||
 | 
					  PrismaRepositoryBase,
 | 
				
			||||||
 | 
					} from '@mobicoop/ddd-library';
 | 
				
			||||||
import { PrismaService } from './prisma.service';
 | 
					import { PrismaService } from './prisma.service';
 | 
				
			||||||
 | 
					import { AD_MESSAGE_PUBLISHER } from '../ad.di-tokens';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export type AdBaseModel = {
 | 
					export type AdBaseModel = {
 | 
				
			||||||
  uuid: string;
 | 
					  uuid: string;
 | 
				
			||||||
| 
						 | 
					@ -72,13 +77,19 @@ export class AdRepository
 | 
				
			||||||
    prisma: PrismaService,
 | 
					    prisma: PrismaService,
 | 
				
			||||||
    mapper: AdMapper,
 | 
					    mapper: AdMapper,
 | 
				
			||||||
    eventEmitter: EventEmitter2,
 | 
					    eventEmitter: EventEmitter2,
 | 
				
			||||||
 | 
					    @Inject(AD_MESSAGE_PUBLISHER)
 | 
				
			||||||
 | 
					    protected readonly messagePublisher: MessagePublisherPort,
 | 
				
			||||||
  ) {
 | 
					  ) {
 | 
				
			||||||
    super(
 | 
					    super(
 | 
				
			||||||
      prisma.ad,
 | 
					      prisma.ad,
 | 
				
			||||||
      prisma,
 | 
					      prisma,
 | 
				
			||||||
      mapper,
 | 
					      mapper,
 | 
				
			||||||
      eventEmitter,
 | 
					      eventEmitter,
 | 
				
			||||||
      new Logger(AdRepository.name),
 | 
					      new LoggerBase({
 | 
				
			||||||
 | 
					        logger: new Logger(AdRepository.name),
 | 
				
			||||||
 | 
					        domain: 'ad',
 | 
				
			||||||
 | 
					        messagePublisher,
 | 
				
			||||||
 | 
					      }),
 | 
				
			||||||
    );
 | 
					    );
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,10 +1,17 @@
 | 
				
			||||||
import {
 | 
					import {
 | 
				
			||||||
 | 
					  AD_MESSAGE_PUBLISHER,
 | 
				
			||||||
  AD_REPOSITORY,
 | 
					  AD_REPOSITORY,
 | 
				
			||||||
  PARAMS_PROVIDER,
 | 
					  PARAMS_PROVIDER,
 | 
				
			||||||
  TIMEZONE_FINDER,
 | 
					  TIMEZONE_FINDER,
 | 
				
			||||||
  TIME_CONVERTER,
 | 
					  TIME_CONVERTER,
 | 
				
			||||||
} from '@modules/ad/ad.di-tokens';
 | 
					} from '@modules/ad/ad.di-tokens';
 | 
				
			||||||
import { AdMapper } from '@modules/ad/ad.mapper';
 | 
					import { AdMapper } from '@modules/ad/ad.mapper';
 | 
				
			||||||
 | 
					import { AdEntity } from '@modules/ad/core/domain/ad.entity';
 | 
				
			||||||
 | 
					import {
 | 
				
			||||||
 | 
					  CreateAdProps,
 | 
				
			||||||
 | 
					  DefaultAdProps,
 | 
				
			||||||
 | 
					  Frequency,
 | 
				
			||||||
 | 
					} from '@modules/ad/core/domain/ad.types';
 | 
				
			||||||
import { AdRepository } from '@modules/ad/infrastructure/ad.repository';
 | 
					import { AdRepository } from '@modules/ad/infrastructure/ad.repository';
 | 
				
			||||||
import { DefaultParamsProvider } from '@modules/ad/infrastructure/default-params-provider';
 | 
					import { DefaultParamsProvider } from '@modules/ad/infrastructure/default-params-provider';
 | 
				
			||||||
import { PrismaService } from '@modules/ad/infrastructure/prisma.service';
 | 
					import { PrismaService } from '@modules/ad/infrastructure/prisma.service';
 | 
				
			||||||
| 
						 | 
					@ -48,20 +55,6 @@ describe('Ad Repository', () => {
 | 
				
			||||||
    seatsRequested: 0,
 | 
					    seatsRequested: 0,
 | 
				
			||||||
    strict: 'false',
 | 
					    strict: 'false',
 | 
				
			||||||
  };
 | 
					  };
 | 
				
			||||||
  // const passengerAd = {
 | 
					 | 
				
			||||||
  //   driver: 'false',
 | 
					 | 
				
			||||||
  //   passenger: 'true',
 | 
					 | 
				
			||||||
  //   seatsProposed: 0,
 | 
					 | 
				
			||||||
  //   seatsRequested: 1,
 | 
					 | 
				
			||||||
  //   strict: 'false',
 | 
					 | 
				
			||||||
  // };
 | 
					 | 
				
			||||||
  // const driverAndPassengerAd = {
 | 
					 | 
				
			||||||
  //   driver: 'true',
 | 
					 | 
				
			||||||
  //   passenger: 'true',
 | 
					 | 
				
			||||||
  //   seatsProposed: 3,
 | 
					 | 
				
			||||||
  //   seatsRequested: 1,
 | 
					 | 
				
			||||||
  //   strict: 'false',
 | 
					 | 
				
			||||||
  // };
 | 
					 | 
				
			||||||
  const punctualAd = {
 | 
					  const punctualAd = {
 | 
				
			||||||
    frequency: `'PUNCTUAL'`,
 | 
					    frequency: `'PUNCTUAL'`,
 | 
				
			||||||
    fromDate: `'2023-01-01'`,
 | 
					    fromDate: `'2023-01-01'`,
 | 
				
			||||||
| 
						 | 
					@ -81,25 +74,6 @@ describe('Ad Repository', () => {
 | 
				
			||||||
    satMargin: 900,
 | 
					    satMargin: 900,
 | 
				
			||||||
    sunMargin: 900,
 | 
					    sunMargin: 900,
 | 
				
			||||||
  };
 | 
					  };
 | 
				
			||||||
  // const recurrentAd = {
 | 
					 | 
				
			||||||
  //   frequency: `'RECURRENT'`,
 | 
					 | 
				
			||||||
  //   fromDate: `'2023-01-01'`,
 | 
					 | 
				
			||||||
  //   toDate: `'2023-12-31'`,
 | 
					 | 
				
			||||||
  //   monTime: `'2023-01-01T07:15:00Z'`,
 | 
					 | 
				
			||||||
  //   tueTime: `'2023-01-01T07:15:00Z'`,
 | 
					 | 
				
			||||||
  //   wedTime: `'2023-01-01T07:05:00Z'`,
 | 
					 | 
				
			||||||
  //   thuTime: `'2023-01-01T07:15:00Z'`,
 | 
					 | 
				
			||||||
  //   friTime: `'2023-01-01T07:15:00Z'`,
 | 
					 | 
				
			||||||
  //   satTime: 'NULL',
 | 
					 | 
				
			||||||
  //   sunTime: 'NULL',
 | 
					 | 
				
			||||||
  //   monMargin: 900,
 | 
					 | 
				
			||||||
  //   tueMargin: 900,
 | 
					 | 
				
			||||||
  //   wedMargin: 900,
 | 
					 | 
				
			||||||
  //   thuMargin: 900,
 | 
					 | 
				
			||||||
  //   friMargin: 900,
 | 
					 | 
				
			||||||
  //   satMargin: 900,
 | 
					 | 
				
			||||||
  //   sunMargin: 900,
 | 
					 | 
				
			||||||
  // };
 | 
					 | 
				
			||||||
  const originWaypoint = {
 | 
					  const originWaypoint = {
 | 
				
			||||||
    position: 0,
 | 
					    position: 0,
 | 
				
			||||||
    lon: 43.7102,
 | 
					    lon: 43.7102,
 | 
				
			||||||
| 
						 | 
					@ -140,120 +114,15 @@ describe('Ad Repository', () => {
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  };
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // const createRecurrentDriverAds = async (nbToCreate = 10) => {
 | 
					  const mockMessagePublisher = {
 | 
				
			||||||
  //   const adToCreate = {
 | 
					    publish: jest.fn().mockImplementation(),
 | 
				
			||||||
  //     ...baseUuid,
 | 
					  };
 | 
				
			||||||
  //     ...baseUserUuid,
 | 
					 | 
				
			||||||
  //     ...driverAd,
 | 
					 | 
				
			||||||
  //     ...punctualAd,
 | 
					 | 
				
			||||||
  //   };
 | 
					 | 
				
			||||||
  //   for (let i = 0; i < nbToCreate; i++) {
 | 
					 | 
				
			||||||
  //     adToCreate.uuid = getSeed(i, baseUuid.uuid);
 | 
					 | 
				
			||||||
  //     await executeInsertCommand('ad', adToCreate);
 | 
					 | 
				
			||||||
  //     await executeInsertCommand('waypoint', {
 | 
					 | 
				
			||||||
  //       uuid: getSeed(i, baseOriginWaypointUuid.uuid),
 | 
					 | 
				
			||||||
  //       adUuid: adToCreate.uuid,
 | 
					 | 
				
			||||||
  //       ...originWaypoint,
 | 
					 | 
				
			||||||
  //     });
 | 
					 | 
				
			||||||
  //     await executeInsertCommand('waypoint', {
 | 
					 | 
				
			||||||
  //       uuid: getSeed(i, baseDestinationWaypointUuid.uuid),
 | 
					 | 
				
			||||||
  //       adUuid: adToCreate.uuid,
 | 
					 | 
				
			||||||
  //       ...destinationWaypoint,
 | 
					 | 
				
			||||||
  //     });
 | 
					 | 
				
			||||||
  //   }
 | 
					 | 
				
			||||||
  // };
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // const createPunctualPassengerAds = async (nbToCreate = 10) => {
 | 
					  const mockLogger = {
 | 
				
			||||||
  //   const adToCreate = {
 | 
					    log: jest.fn(),
 | 
				
			||||||
  //     ...baseUuid,
 | 
					    warn: jest.fn(),
 | 
				
			||||||
  //     ...baseUserUuid,
 | 
					    error: jest.fn(),
 | 
				
			||||||
  //     ...passengerAd,
 | 
					  };
 | 
				
			||||||
  //     ...punctualAd,
 | 
					 | 
				
			||||||
  //   };
 | 
					 | 
				
			||||||
  //   for (let i = 0; i < nbToCreate; i++) {
 | 
					 | 
				
			||||||
  //     adToCreate.uuid = getSeed(i, baseUuid.uuid);
 | 
					 | 
				
			||||||
  //     await executeInsertCommand('ad', adToCreate);
 | 
					 | 
				
			||||||
  //     await executeInsertCommand('waypoint', {
 | 
					 | 
				
			||||||
  //       uuid: getSeed(i, baseOriginWaypointUuid.uuid),
 | 
					 | 
				
			||||||
  //       adUuid: adToCreate.uuid,
 | 
					 | 
				
			||||||
  //       ...originWaypoint,
 | 
					 | 
				
			||||||
  //     });
 | 
					 | 
				
			||||||
  //     await executeInsertCommand('waypoint', {
 | 
					 | 
				
			||||||
  //       uuid: getSeed(i, baseDestinationWaypointUuid.uuid),
 | 
					 | 
				
			||||||
  //       adUuid: adToCreate.uuid,
 | 
					 | 
				
			||||||
  //       ...destinationWaypoint,
 | 
					 | 
				
			||||||
  //     });
 | 
					 | 
				
			||||||
  //   }
 | 
					 | 
				
			||||||
  // };
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  // const createRecurrentPassengerAds = async (nbToCreate = 10) => {
 | 
					 | 
				
			||||||
  //   const adToCreate = {
 | 
					 | 
				
			||||||
  //     ...baseUuid,
 | 
					 | 
				
			||||||
  //     ...baseUserUuid,
 | 
					 | 
				
			||||||
  //     ...passengerAd,
 | 
					 | 
				
			||||||
  //     ...recurrentAd,
 | 
					 | 
				
			||||||
  //   };
 | 
					 | 
				
			||||||
  //   for (let i = 0; i < nbToCreate; i++) {
 | 
					 | 
				
			||||||
  //     adToCreate.uuid = getSeed(i, baseUuid.uuid);
 | 
					 | 
				
			||||||
  //     await executeInsertCommand('ad', adToCreate);
 | 
					 | 
				
			||||||
  //     await executeInsertCommand('waypoint', {
 | 
					 | 
				
			||||||
  //       uuid: getSeed(i, baseOriginWaypointUuid.uuid),
 | 
					 | 
				
			||||||
  //       adUuid: adToCreate.uuid,
 | 
					 | 
				
			||||||
  //       ...originWaypoint,
 | 
					 | 
				
			||||||
  //     });
 | 
					 | 
				
			||||||
  //     await executeInsertCommand('waypoint', {
 | 
					 | 
				
			||||||
  //       uuid: getSeed(i, baseDestinationWaypointUuid.uuid),
 | 
					 | 
				
			||||||
  //       adUuid: adToCreate.uuid,
 | 
					 | 
				
			||||||
  //       ...destinationWaypoint,
 | 
					 | 
				
			||||||
  //     });
 | 
					 | 
				
			||||||
  //   }
 | 
					 | 
				
			||||||
  // };
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  // const createPunctualDriverPassengerAds = async (nbToCreate = 10) => {
 | 
					 | 
				
			||||||
  //   const adToCreate = {
 | 
					 | 
				
			||||||
  //     ...baseUuid,
 | 
					 | 
				
			||||||
  //     ...baseUserUuid,
 | 
					 | 
				
			||||||
  //     ...driverAndPassengerAd,
 | 
					 | 
				
			||||||
  //     ...punctualAd,
 | 
					 | 
				
			||||||
  //   };
 | 
					 | 
				
			||||||
  //   for (let i = 0; i < nbToCreate; i++) {
 | 
					 | 
				
			||||||
  //     adToCreate.uuid = getSeed(i, baseUuid.uuid);
 | 
					 | 
				
			||||||
  //     await executeInsertCommand('ad', adToCreate);
 | 
					 | 
				
			||||||
  //     await executeInsertCommand('waypoint', {
 | 
					 | 
				
			||||||
  //       uuid: getSeed(i, baseOriginWaypointUuid.uuid),
 | 
					 | 
				
			||||||
  //       adUuid: adToCreate.uuid,
 | 
					 | 
				
			||||||
  //       ...originWaypoint,
 | 
					 | 
				
			||||||
  //     });
 | 
					 | 
				
			||||||
  //     await executeInsertCommand('waypoint', {
 | 
					 | 
				
			||||||
  //       uuid: getSeed(i, baseDestinationWaypointUuid.uuid),
 | 
					 | 
				
			||||||
  //       adUuid: adToCreate.uuid,
 | 
					 | 
				
			||||||
  //       ...destinationWaypoint,
 | 
					 | 
				
			||||||
  //     });
 | 
					 | 
				
			||||||
  //   }
 | 
					 | 
				
			||||||
  // };
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  // const createRecurrentDriverPassengerAds = async (nbToCreate = 10) => {
 | 
					 | 
				
			||||||
  //   const adToCreate = {
 | 
					 | 
				
			||||||
  //     ...baseUuid,
 | 
					 | 
				
			||||||
  //     ...baseUserUuid,
 | 
					 | 
				
			||||||
  //     ...driverAndPassengerAd,
 | 
					 | 
				
			||||||
  //     ...recurrentAd,
 | 
					 | 
				
			||||||
  //   };
 | 
					 | 
				
			||||||
  //   for (let i = 0; i < nbToCreate; i++) {
 | 
					 | 
				
			||||||
  //     adToCreate.uuid = getSeed(i, baseUuid.uuid);
 | 
					 | 
				
			||||||
  //     await executeInsertCommand('ad', adToCreate);
 | 
					 | 
				
			||||||
  //     await executeInsertCommand('waypoint', {
 | 
					 | 
				
			||||||
  //       uuid: getSeed(i, baseOriginWaypointUuid.uuid),
 | 
					 | 
				
			||||||
  //       adUuid: adToCreate.uuid,
 | 
					 | 
				
			||||||
  //       ...originWaypoint,
 | 
					 | 
				
			||||||
  //     });
 | 
					 | 
				
			||||||
  //     await executeInsertCommand('waypoint', {
 | 
					 | 
				
			||||||
  //       uuid: getSeed(i, baseDestinationWaypointUuid.uuid),
 | 
					 | 
				
			||||||
  //       adUuid: adToCreate.uuid,
 | 
					 | 
				
			||||||
  //       ...destinationWaypoint,
 | 
					 | 
				
			||||||
  //     });
 | 
					 | 
				
			||||||
  //   }
 | 
					 | 
				
			||||||
  // };
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  beforeAll(async () => {
 | 
					  beforeAll(async () => {
 | 
				
			||||||
    const module = await Test.createTestingModule({
 | 
					    const module = await Test.createTestingModule({
 | 
				
			||||||
| 
						 | 
					@ -280,11 +149,20 @@ describe('Ad Repository', () => {
 | 
				
			||||||
          provide: TIME_CONVERTER,
 | 
					          provide: TIME_CONVERTER,
 | 
				
			||||||
          useClass: TimeConverter,
 | 
					          useClass: TimeConverter,
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					          provide: AD_MESSAGE_PUBLISHER,
 | 
				
			||||||
 | 
					          useValue: mockMessagePublisher,
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
      ],
 | 
					      ],
 | 
				
			||||||
    }).compile();
 | 
					    })
 | 
				
			||||||
 | 
					      // disable logging
 | 
				
			||||||
 | 
					      .setLogger(mockLogger)
 | 
				
			||||||
 | 
					      .compile();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    prismaService = module.get<PrismaService>(PrismaService);
 | 
					    prismaService = module.get<PrismaService>(PrismaService);
 | 
				
			||||||
    adRepository = module.get<AdRepository>(AD_REPOSITORY);
 | 
					    adRepository = module.get<AdRepository>(AD_REPOSITORY);
 | 
				
			||||||
  });
 | 
					  });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  afterAll(async () => {
 | 
					  afterAll(async () => {
 | 
				
			||||||
    await prismaService.$disconnect();
 | 
					    await prismaService.$disconnect();
 | 
				
			||||||
  });
 | 
					  });
 | 
				
			||||||
| 
						 | 
					@ -292,129 +170,7 @@ describe('Ad Repository', () => {
 | 
				
			||||||
  beforeEach(async () => {
 | 
					  beforeEach(async () => {
 | 
				
			||||||
    await prismaService.ad.deleteMany();
 | 
					    await prismaService.ad.deleteMany();
 | 
				
			||||||
  });
 | 
					  });
 | 
				
			||||||
  // describe('findAll', () => {
 | 
					 | 
				
			||||||
  //   it('should return an empty data array', async () => {
 | 
					 | 
				
			||||||
  //     const res = await adRepository.findAll();
 | 
					 | 
				
			||||||
  //     expect(res).toEqual({
 | 
					 | 
				
			||||||
  //       data: [],
 | 
					 | 
				
			||||||
  //       total: 0,
 | 
					 | 
				
			||||||
  //     });
 | 
					 | 
				
			||||||
  //   });
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  //   describe('drivers', () => {
 | 
					 | 
				
			||||||
  //     it('should return a data array with 8 punctual driver ads', async () => {
 | 
					 | 
				
			||||||
  //       await createPunctualDriverAds(8);
 | 
					 | 
				
			||||||
  //       const ads = await adRepository.findAll();
 | 
					 | 
				
			||||||
  //       expect(ads.data.length).toBe(8);
 | 
					 | 
				
			||||||
  //       expect(ads.total).toBe(8);
 | 
					 | 
				
			||||||
  //       expect(ads.data[0].driver).toBeTruthy();
 | 
					 | 
				
			||||||
  //       expect(ads.data[0].passenger).toBeFalsy();
 | 
					 | 
				
			||||||
  //     });
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  //     it('should return a data array limited to 10 punctual driver ads', async () => {
 | 
					 | 
				
			||||||
  //       await createPunctualDriverAds(20);
 | 
					 | 
				
			||||||
  //       const ads = await adRepository.findAll();
 | 
					 | 
				
			||||||
  //       expect(ads.data.length).toBe(10);
 | 
					 | 
				
			||||||
  //       expect(ads.total).toBe(20);
 | 
					 | 
				
			||||||
  //       expect(ads.data[1].driver).toBeTruthy();
 | 
					 | 
				
			||||||
  //       expect(ads.data[1].passenger).toBeFalsy();
 | 
					 | 
				
			||||||
  //     });
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  //     it('should return a data array with 8 recurrent driver ads', async () => {
 | 
					 | 
				
			||||||
  //       await createRecurrentDriverAds(8);
 | 
					 | 
				
			||||||
  //       const ads = await adRepository.findAll();
 | 
					 | 
				
			||||||
  //       expect(ads.data.length).toBe(8);
 | 
					 | 
				
			||||||
  //       expect(ads.total).toBe(8);
 | 
					 | 
				
			||||||
  //       expect(ads.data[2].driver).toBeTruthy();
 | 
					 | 
				
			||||||
  //       expect(ads.data[2].passenger).toBeFalsy();
 | 
					 | 
				
			||||||
  //     });
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  //     it('should return a data array limited to 10 recurrent driver ads', async () => {
 | 
					 | 
				
			||||||
  //       await createRecurrentDriverAds(20);
 | 
					 | 
				
			||||||
  //       const ads = await adRepository.findAll();
 | 
					 | 
				
			||||||
  //       expect(ads.data.length).toBe(10);
 | 
					 | 
				
			||||||
  //       expect(ads.total).toBe(20);
 | 
					 | 
				
			||||||
  //       expect(ads.data[3].driver).toBeTruthy();
 | 
					 | 
				
			||||||
  //       expect(ads.data[3].passenger).toBeFalsy();
 | 
					 | 
				
			||||||
  //     });
 | 
					 | 
				
			||||||
  //   });
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  //   describe('passengers', () => {
 | 
					 | 
				
			||||||
  //     it('should return a data array with 7 punctual passenger ads', async () => {
 | 
					 | 
				
			||||||
  //       await createPunctualPassengerAds(7);
 | 
					 | 
				
			||||||
  //       const ads = await adRepository.findAll();
 | 
					 | 
				
			||||||
  //       expect(ads.data.length).toBe(7);
 | 
					 | 
				
			||||||
  //       expect(ads.total).toBe(7);
 | 
					 | 
				
			||||||
  //       expect(ads.data[0].passenger).toBeTruthy();
 | 
					 | 
				
			||||||
  //       expect(ads.data[0].driver).toBeFalsy();
 | 
					 | 
				
			||||||
  //     });
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  //     it('should return a data array limited to 10 punctual passenger ads', async () => {
 | 
					 | 
				
			||||||
  //       await createPunctualPassengerAds(15);
 | 
					 | 
				
			||||||
  //       const ads = await adRepository.findAll();
 | 
					 | 
				
			||||||
  //       expect(ads.data.length).toBe(10);
 | 
					 | 
				
			||||||
  //       expect(ads.total).toBe(15);
 | 
					 | 
				
			||||||
  //       expect(ads.data[1].passenger).toBeTruthy();
 | 
					 | 
				
			||||||
  //       expect(ads.data[1].driver).toBeFalsy();
 | 
					 | 
				
			||||||
  //     });
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  //     it('should return a data array with 7 recurrent passenger ads', async () => {
 | 
					 | 
				
			||||||
  //       await createRecurrentPassengerAds(7);
 | 
					 | 
				
			||||||
  //       const ads = await adRepository.findAll();
 | 
					 | 
				
			||||||
  //       expect(ads.data.length).toBe(7);
 | 
					 | 
				
			||||||
  //       expect(ads.total).toBe(7);
 | 
					 | 
				
			||||||
  //       expect(ads.data[2].passenger).toBeTruthy();
 | 
					 | 
				
			||||||
  //       expect(ads.data[2].driver).toBeFalsy();
 | 
					 | 
				
			||||||
  //     });
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  //     it('should return a data array limited to 10 recurrent passenger ads', async () => {
 | 
					 | 
				
			||||||
  //       await createRecurrentPassengerAds(15);
 | 
					 | 
				
			||||||
  //       const ads = await adRepository.findAll();
 | 
					 | 
				
			||||||
  //       expect(ads.data.length).toBe(10);
 | 
					 | 
				
			||||||
  //       expect(ads.total).toBe(15);
 | 
					 | 
				
			||||||
  //       expect(ads.data[3].passenger).toBeTruthy();
 | 
					 | 
				
			||||||
  //       expect(ads.data[3].driver).toBeFalsy();
 | 
					 | 
				
			||||||
  //     });
 | 
					 | 
				
			||||||
  //   });
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  //   describe('drivers and passengers', () => {
 | 
					 | 
				
			||||||
  //     it('should return a data array with 6 punctual driver and passenger ads', async () => {
 | 
					 | 
				
			||||||
  //       await createPunctualDriverPassengerAds(6);
 | 
					 | 
				
			||||||
  //       const ads = await adRepository.findAll();
 | 
					 | 
				
			||||||
  //       expect(ads.data.length).toBe(6);
 | 
					 | 
				
			||||||
  //       expect(ads.total).toBe(6);
 | 
					 | 
				
			||||||
  //       expect(ads.data[0].passenger).toBeTruthy();
 | 
					 | 
				
			||||||
  //       expect(ads.data[0].driver).toBeTruthy();
 | 
					 | 
				
			||||||
  //     });
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  //     it('should return a data array limited to 10 punctual driver and passenger ads', async () => {
 | 
					 | 
				
			||||||
  //       await createPunctualDriverPassengerAds(16);
 | 
					 | 
				
			||||||
  //       const ads = await adRepository.findAll();
 | 
					 | 
				
			||||||
  //       expect(ads.data.length).toBe(10);
 | 
					 | 
				
			||||||
  //       expect(ads.total).toBe(16);
 | 
					 | 
				
			||||||
  //       expect(ads.data[1].passenger).toBeTruthy();
 | 
					 | 
				
			||||||
  //       expect(ads.data[1].driver).toBeTruthy();
 | 
					 | 
				
			||||||
  //     });
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  //     it('should return a data array with 6 recurrent driver and passenger ads', async () => {
 | 
					 | 
				
			||||||
  //       await createRecurrentDriverPassengerAds(6);
 | 
					 | 
				
			||||||
  //       const ads = await adRepository.findAll();
 | 
					 | 
				
			||||||
  //       expect(ads.data.length).toBe(6);
 | 
					 | 
				
			||||||
  //       expect(ads.total).toBe(6);
 | 
					 | 
				
			||||||
  //       expect(ads.data[2].passenger).toBeTruthy();
 | 
					 | 
				
			||||||
  //       expect(ads.data[2].driver).toBeTruthy();
 | 
					 | 
				
			||||||
  //     });
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  //     it('should return a data array limited to 10 recurrent driver and passenger ads', async () => {
 | 
					 | 
				
			||||||
  //       await createRecurrentDriverPassengerAds(16);
 | 
					 | 
				
			||||||
  //       const ads = await adRepository.findAll();
 | 
					 | 
				
			||||||
  //       expect(ads.data.length).toBe(10);
 | 
					 | 
				
			||||||
  //       expect(ads.total).toBe(16);
 | 
					 | 
				
			||||||
  //       expect(ads.data[3].passenger).toBeTruthy();
 | 
					 | 
				
			||||||
  //       expect(ads.data[3].driver).toBeTruthy();
 | 
					 | 
				
			||||||
  //     });
 | 
					 | 
				
			||||||
  //   });
 | 
					 | 
				
			||||||
  // });
 | 
					 | 
				
			||||||
  describe('findOneById', () => {
 | 
					  describe('findOneById', () => {
 | 
				
			||||||
    it('should return an ad', async () => {
 | 
					    it('should return an ad', async () => {
 | 
				
			||||||
      await createPunctualDriverAds(1);
 | 
					      await createPunctualDriverAds(1);
 | 
				
			||||||
| 
						 | 
					@ -424,80 +180,97 @@ describe('Ad Repository', () => {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      expect(result.id).toBe(baseUuid.uuid);
 | 
					      expect(result.id).toBe(baseUuid.uuid);
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
 | 
					  });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // it('should return null', async () => {
 | 
					  describe('create', () => {
 | 
				
			||||||
    //   const ad = await adRepository.findOneById(
 | 
					    it('should create an ad', async () => {
 | 
				
			||||||
    //     '544572be-11fb-4244-8235-587221fc9104',
 | 
					      const beforeCount = await prismaService.ad.count();
 | 
				
			||||||
    //   );
 | 
					
 | 
				
			||||||
    //   expect(ad).toBeNull();
 | 
					      const createAdProps: CreateAdProps = {
 | 
				
			||||||
 | 
					        userId: 'b4b56444-f8d3-4110-917c-e37bba77f383',
 | 
				
			||||||
 | 
					        driver: true,
 | 
				
			||||||
 | 
					        passenger: false,
 | 
				
			||||||
 | 
					        frequency: Frequency.PUNCTUAL,
 | 
				
			||||||
 | 
					        fromDate: '2023-02-01',
 | 
				
			||||||
 | 
					        toDate: '2023-02-01',
 | 
				
			||||||
 | 
					        schedule: {
 | 
				
			||||||
 | 
					          wed: '12:05',
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        marginDurations: {
 | 
				
			||||||
 | 
					          wed: 900,
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        seatsProposed: 3,
 | 
				
			||||||
 | 
					        seatsRequested: 1,
 | 
				
			||||||
 | 
					        strict: false,
 | 
				
			||||||
 | 
					        waypoints: [
 | 
				
			||||||
 | 
					          {
 | 
				
			||||||
 | 
					            position: 0,
 | 
				
			||||||
 | 
					            address: {
 | 
				
			||||||
 | 
					              locality: 'Nice',
 | 
				
			||||||
 | 
					              postalCode: '06000',
 | 
				
			||||||
 | 
					              country: 'France',
 | 
				
			||||||
 | 
					              coordinates: {
 | 
				
			||||||
 | 
					                lon: 43.7102,
 | 
				
			||||||
 | 
					                lat: 7.262,
 | 
				
			||||||
 | 
					              },
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					          },
 | 
				
			||||||
 | 
					          {
 | 
				
			||||||
 | 
					            position: 1,
 | 
				
			||||||
 | 
					            address: {
 | 
				
			||||||
 | 
					              locality: 'Marseille',
 | 
				
			||||||
 | 
					              postalCode: '13000',
 | 
				
			||||||
 | 
					              country: 'France',
 | 
				
			||||||
 | 
					              coordinates: {
 | 
				
			||||||
 | 
					                lon: 43.2965,
 | 
				
			||||||
 | 
					                lat: 5.3698,
 | 
				
			||||||
 | 
					              },
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					          },
 | 
				
			||||||
 | 
					        ],
 | 
				
			||||||
 | 
					      };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      const defaultAdProps: DefaultAdProps = {
 | 
				
			||||||
 | 
					        driver: false,
 | 
				
			||||||
 | 
					        passenger: true,
 | 
				
			||||||
 | 
					        marginDurations: {
 | 
				
			||||||
 | 
					          mon: 900,
 | 
				
			||||||
 | 
					          tue: 900,
 | 
				
			||||||
 | 
					          wed: 900,
 | 
				
			||||||
 | 
					          thu: 900,
 | 
				
			||||||
 | 
					          fri: 900,
 | 
				
			||||||
 | 
					          sat: 900,
 | 
				
			||||||
 | 
					          sun: 900,
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        seatsProposed: 3,
 | 
				
			||||||
 | 
					        seatsRequested: 1,
 | 
				
			||||||
 | 
					        strict: false,
 | 
				
			||||||
 | 
					      };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      const adToCreate: AdEntity = AdEntity.create(
 | 
				
			||||||
 | 
					        createAdProps,
 | 
				
			||||||
 | 
					        defaultAdProps,
 | 
				
			||||||
 | 
					      );
 | 
				
			||||||
 | 
					      await adRepository.insert(adToCreate);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      const afterCount = await prismaService.ad.count();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      expect(afterCount - beforeCount).toBe(1);
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // it('should throw a UniqueConstraintException if ad already exists', async () => {
 | 
				
			||||||
 | 
					    //   await prismaService.ad.create({
 | 
				
			||||||
 | 
					    //     data: {
 | 
				
			||||||
 | 
					    //       uuid: uuid,
 | 
				
			||||||
 | 
					    //       password: bcrypt.hashSync(`password`, 10),
 | 
				
			||||||
 | 
					    //     },
 | 
				
			||||||
 | 
					    //   });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    //   const authenticationToCreate: AuthenticationEntity =
 | 
				
			||||||
 | 
					    //     await AuthenticationEntity.create(createAuthenticationProps);
 | 
				
			||||||
 | 
					    //   await expect(
 | 
				
			||||||
 | 
					    //     authenticationRepository.insert(authenticationToCreate),
 | 
				
			||||||
 | 
					    //   ).rejects.toBeInstanceOf(UniqueConstraintException);
 | 
				
			||||||
    // });
 | 
					    // });
 | 
				
			||||||
  });
 | 
					  });
 | 
				
			||||||
  // describe('create', () => {
 | 
					 | 
				
			||||||
  // it('should create a punctual ad', async () => {
 | 
					 | 
				
			||||||
  //   const beforeCount = await prismaService.ad.count();
 | 
					 | 
				
			||||||
  //   const adToCreate: AdDTO = new AdDTO();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  //   adToCreate.uuid = 'be459a29-7a41-4c0b-b371-abe90bfb6f00';
 | 
					 | 
				
			||||||
  //   adToCreate.userUuid = '4e52b54d-a729-4dbd-9283-f84a11bb2200';
 | 
					 | 
				
			||||||
  //   adToCreate.driver = true;
 | 
					 | 
				
			||||||
  //   adToCreate.passenger = false;
 | 
					 | 
				
			||||||
  //   adToCreate.frequency = Frequency.PUNCTUAL;
 | 
					 | 
				
			||||||
  //   adToCreate.fromDate = new Date('05-22-2023 09:36');
 | 
					 | 
				
			||||||
  //   adToCreate.toDate = new Date('05-22-2023 09:36');
 | 
					 | 
				
			||||||
  //   adToCreate.monTime = '09:36';
 | 
					 | 
				
			||||||
  //   adToCreate.monMargin = 900;
 | 
					 | 
				
			||||||
  //   adToCreate.tueMargin = 900;
 | 
					 | 
				
			||||||
  //   adToCreate.wedMargin = 900;
 | 
					 | 
				
			||||||
  //   adToCreate.thuMargin = 900;
 | 
					 | 
				
			||||||
  //   adToCreate.friMargin = 900;
 | 
					 | 
				
			||||||
  //   adToCreate.satMargin = 900;
 | 
					 | 
				
			||||||
  //   adToCreate.sunMargin = 900;
 | 
					 | 
				
			||||||
  //   adToCreate.seatsProposed = 3;
 | 
					 | 
				
			||||||
  //   adToCreate.seatsRequested = 0;
 | 
					 | 
				
			||||||
  //   adToCreate.strict = false;
 | 
					 | 
				
			||||||
  //   adToCreate.waypoints = {
 | 
					 | 
				
			||||||
  //     create: [originWaypoint as Waypoint, destinationWaypoint as Waypoint],
 | 
					 | 
				
			||||||
  //   };
 | 
					 | 
				
			||||||
  //   const ad = await adRepository.create(adToCreate);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  //   const afterCount = await prismaService.ad.count();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  //   expect(afterCount - beforeCount).toBe(1);
 | 
					 | 
				
			||||||
  //   expect(ad.uuid).toBe('be459a29-7a41-4c0b-b371-abe90bfb6f00');
 | 
					 | 
				
			||||||
  // });
 | 
					 | 
				
			||||||
  // it('should create a recurrent ad', async () => {
 | 
					 | 
				
			||||||
  //   const beforeCount = await prismaService.ad.count();
 | 
					 | 
				
			||||||
  //   const adToCreate: AdDTO = new AdDTO();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  //   adToCreate.uuid = '137a26fa-4b38-48ba-aecf-1a75f6b20f3d';
 | 
					 | 
				
			||||||
  //   adToCreate.userUuid = '4e52b54d-a729-4dbd-9283-f84a11bb2200';
 | 
					 | 
				
			||||||
  //   adToCreate.driver = true;
 | 
					 | 
				
			||||||
  //   adToCreate.passenger = false;
 | 
					 | 
				
			||||||
  //   adToCreate.frequency = Frequency.RECURRENT;
 | 
					 | 
				
			||||||
  //   adToCreate.fromDate = new Date('01-15-2023 ');
 | 
					 | 
				
			||||||
  //   adToCreate.toDate = new Date('10-31-2023');
 | 
					 | 
				
			||||||
  //   adToCreate.monTime = '07:30';
 | 
					 | 
				
			||||||
  //   adToCreate.friTime = '07:45';
 | 
					 | 
				
			||||||
  //   adToCreate.thuTime = '08:00';
 | 
					 | 
				
			||||||
  //   adToCreate.monMargin = 900;
 | 
					 | 
				
			||||||
  //   adToCreate.tueMargin = 900;
 | 
					 | 
				
			||||||
  //   adToCreate.wedMargin = 900;
 | 
					 | 
				
			||||||
  //   adToCreate.thuMargin = 900;
 | 
					 | 
				
			||||||
  //   adToCreate.friMargin = 900;
 | 
					 | 
				
			||||||
  //   adToCreate.satMargin = 900;
 | 
					 | 
				
			||||||
  //   adToCreate.sunMargin = 900;
 | 
					 | 
				
			||||||
  //   adToCreate.seatsProposed = 2;
 | 
					 | 
				
			||||||
  //   adToCreate.seatsRequested = 0;
 | 
					 | 
				
			||||||
  //   adToCreate.strict = false;
 | 
					 | 
				
			||||||
  //   adToCreate.waypoints = {
 | 
					 | 
				
			||||||
  //     create: [originWaypoint as Waypoint, destinationWaypoint as Waypoint],
 | 
					 | 
				
			||||||
  //   };
 | 
					 | 
				
			||||||
  //   const ad = await adRepository.create(adToCreate);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  //   const afterCount = await prismaService.ad.count();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  //   expect(afterCount - beforeCount).toBe(1);
 | 
					 | 
				
			||||||
  //   expect(ad.uuid).toBe('137a26fa-4b38-48ba-aecf-1a75f6b20f3d');
 | 
					 | 
				
			||||||
  // });
 | 
					 | 
				
			||||||
  // });
 | 
					 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,94 +0,0 @@
 | 
				
			||||||
import { Frequency } from '@modules/ad/core/domain/ad.types';
 | 
					 | 
				
			||||||
import { PublishLogMessageWhenAdIsCreatedDomainEventHandler } from '@modules/ad/core/application/event-handlers/publish-log-message-when-ad-is-created.domain-event-handler';
 | 
					 | 
				
			||||||
import { AdCreatedDomainEvent } from '@modules/ad/core/domain/events/ad-created.domain-events';
 | 
					 | 
				
			||||||
import { Test, TestingModule } from '@nestjs/testing';
 | 
					 | 
				
			||||||
import { MESSAGE_PUBLISHER } from '@src/app.constants';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
const mockMessagePublisher = {
 | 
					 | 
				
			||||||
  publish: jest.fn().mockImplementation(),
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
describe('Publish log message when ad is created domain event handler', () => {
 | 
					 | 
				
			||||||
  let publishLogMessageWhenAdIsCreatedDomainEventHandler: PublishLogMessageWhenAdIsCreatedDomainEventHandler;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  beforeAll(async () => {
 | 
					 | 
				
			||||||
    const module: TestingModule = await Test.createTestingModule({
 | 
					 | 
				
			||||||
      providers: [
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
          provide: MESSAGE_PUBLISHER,
 | 
					 | 
				
			||||||
          useValue: mockMessagePublisher,
 | 
					 | 
				
			||||||
        },
 | 
					 | 
				
			||||||
        PublishLogMessageWhenAdIsCreatedDomainEventHandler,
 | 
					 | 
				
			||||||
      ],
 | 
					 | 
				
			||||||
    }).compile();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    publishLogMessageWhenAdIsCreatedDomainEventHandler =
 | 
					 | 
				
			||||||
      module.get<PublishLogMessageWhenAdIsCreatedDomainEventHandler>(
 | 
					 | 
				
			||||||
        PublishLogMessageWhenAdIsCreatedDomainEventHandler,
 | 
					 | 
				
			||||||
      );
 | 
					 | 
				
			||||||
  });
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  it('should publish a log message', () => {
 | 
					 | 
				
			||||||
    jest.spyOn(mockMessagePublisher, 'publish');
 | 
					 | 
				
			||||||
    const adCreatedDomainEvent: AdCreatedDomainEvent = {
 | 
					 | 
				
			||||||
      id: 'some-domain-event-id',
 | 
					 | 
				
			||||||
      aggregateId: 'some-aggregate-id',
 | 
					 | 
				
			||||||
      userId: 'some-user-id',
 | 
					 | 
				
			||||||
      driver: false,
 | 
					 | 
				
			||||||
      passenger: true,
 | 
					 | 
				
			||||||
      frequency: Frequency.PUNCTUAL,
 | 
					 | 
				
			||||||
      fromDate: '2023-06-28',
 | 
					 | 
				
			||||||
      toDate: '2023-06-28',
 | 
					 | 
				
			||||||
      monTime: undefined,
 | 
					 | 
				
			||||||
      tueTime: undefined,
 | 
					 | 
				
			||||||
      wedTime: '07:15',
 | 
					 | 
				
			||||||
      thuTime: undefined,
 | 
					 | 
				
			||||||
      friTime: undefined,
 | 
					 | 
				
			||||||
      satTime: undefined,
 | 
					 | 
				
			||||||
      sunTime: undefined,
 | 
					 | 
				
			||||||
      monMarginDuration: 900,
 | 
					 | 
				
			||||||
      tueMarginDuration: 900,
 | 
					 | 
				
			||||||
      wedMarginDuration: 900,
 | 
					 | 
				
			||||||
      thuMarginDuration: 900,
 | 
					 | 
				
			||||||
      friMarginDuration: 900,
 | 
					 | 
				
			||||||
      satMarginDuration: 900,
 | 
					 | 
				
			||||||
      sunMarginDuration: 900,
 | 
					 | 
				
			||||||
      seatsProposed: 3,
 | 
					 | 
				
			||||||
      seatsRequested: 1,
 | 
					 | 
				
			||||||
      strict: false,
 | 
					 | 
				
			||||||
      waypoints: [
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
          position: 0,
 | 
					 | 
				
			||||||
          houseNumber: '5',
 | 
					 | 
				
			||||||
          street: 'Avenue Foch',
 | 
					 | 
				
			||||||
          locality: 'Nancy',
 | 
					 | 
				
			||||||
          postalCode: '54000',
 | 
					 | 
				
			||||||
          country: 'France',
 | 
					 | 
				
			||||||
          lat: 48.689445,
 | 
					 | 
				
			||||||
          lon: 6.1765102,
 | 
					 | 
				
			||||||
        },
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
          position: 1,
 | 
					 | 
				
			||||||
          locality: 'Paris',
 | 
					 | 
				
			||||||
          postalCode: '75000',
 | 
					 | 
				
			||||||
          country: 'France',
 | 
					 | 
				
			||||||
          lat: 48.8566,
 | 
					 | 
				
			||||||
          lon: 2.3522,
 | 
					 | 
				
			||||||
        },
 | 
					 | 
				
			||||||
      ],
 | 
					 | 
				
			||||||
      metadata: {
 | 
					 | 
				
			||||||
        timestamp: new Date('2023-06-28T05:00:00Z').getTime(),
 | 
					 | 
				
			||||||
        correlationId: 'some-correlation-id',
 | 
					 | 
				
			||||||
      },
 | 
					 | 
				
			||||||
    };
 | 
					 | 
				
			||||||
    publishLogMessageWhenAdIsCreatedDomainEventHandler.handle(
 | 
					 | 
				
			||||||
      adCreatedDomainEvent,
 | 
					 | 
				
			||||||
    );
 | 
					 | 
				
			||||||
    expect(publishLogMessageWhenAdIsCreatedDomainEventHandler).toBeDefined();
 | 
					 | 
				
			||||||
    expect(mockMessagePublisher.publish).toHaveBeenCalledTimes(1);
 | 
					 | 
				
			||||||
    expect(mockMessagePublisher.publish).toHaveBeenCalledWith(
 | 
					 | 
				
			||||||
      'logging.ad.created.info',
 | 
					 | 
				
			||||||
      '{"id":"some-domain-event-id","aggregateId":"some-aggregate-id","userId":"some-user-id","driver":false,"passenger":true,"frequency":"PUNCTUAL","fromDate":"2023-06-28","toDate":"2023-06-28","wedTime":"07:15","monMarginDuration":900,"tueMarginDuration":900,"wedMarginDuration":900,"thuMarginDuration":900,"friMarginDuration":900,"satMarginDuration":900,"sunMarginDuration":900,"seatsProposed":3,"seatsRequested":1,"strict":false,"waypoints":[{"position":0,"houseNumber":"5","street":"Avenue Foch","locality":"Nancy","postalCode":"54000","country":"France","lat":48.689445,"lon":6.1765102},{"position":1,"locality":"Paris","postalCode":"75000","country":"France","lat":48.8566,"lon":2.3522}],"metadata":{"timestamp":1687928400000,"correlationId":"some-correlation-id"}}',
 | 
					 | 
				
			||||||
    );
 | 
					 | 
				
			||||||
  });
 | 
					 | 
				
			||||||
});
 | 
					 | 
				
			||||||
| 
						 | 
					@ -2,7 +2,7 @@ import { Frequency } from '@modules/ad/core/domain/ad.types';
 | 
				
			||||||
import { PublishMessageWhenAdIsCreatedDomainEventHandler } from '@modules/ad/core/application/event-handlers/publish-message-when-ad-is-created.domain-event-handler';
 | 
					import { PublishMessageWhenAdIsCreatedDomainEventHandler } from '@modules/ad/core/application/event-handlers/publish-message-when-ad-is-created.domain-event-handler';
 | 
				
			||||||
import { AdCreatedDomainEvent } from '@modules/ad/core/domain/events/ad-created.domain-events';
 | 
					import { AdCreatedDomainEvent } from '@modules/ad/core/domain/events/ad-created.domain-events';
 | 
				
			||||||
import { Test, TestingModule } from '@nestjs/testing';
 | 
					import { Test, TestingModule } from '@nestjs/testing';
 | 
				
			||||||
import { MESSAGE_PUBLISHER } from '@src/app.constants';
 | 
					import { AD_MESSAGE_PUBLISHER } from '@modules/ad/ad.di-tokens';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const mockMessagePublisher = {
 | 
					const mockMessagePublisher = {
 | 
				
			||||||
  publish: jest.fn().mockImplementation(),
 | 
					  publish: jest.fn().mockImplementation(),
 | 
				
			||||||
| 
						 | 
					@ -15,7 +15,7 @@ describe('Publish message when ad is created domain event handler', () => {
 | 
				
			||||||
    const module: TestingModule = await Test.createTestingModule({
 | 
					    const module: TestingModule = await Test.createTestingModule({
 | 
				
			||||||
      providers: [
 | 
					      providers: [
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
          provide: MESSAGE_PUBLISHER,
 | 
					          provide: AD_MESSAGE_PUBLISHER,
 | 
				
			||||||
          useValue: mockMessagePublisher,
 | 
					          useValue: mockMessagePublisher,
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
        PublishMessageWhenAdIsCreatedDomainEventHandler,
 | 
					        PublishMessageWhenAdIsCreatedDomainEventHandler,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -50,6 +50,10 @@ const mockTimeConverter: TimeConverterPort = {
 | 
				
			||||||
  utcDatetimeToLocalTime: jest.fn(),
 | 
					  utcDatetimeToLocalTime: jest.fn(),
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const mockMessagePublisher = {
 | 
				
			||||||
 | 
					  publish: jest.fn().mockImplementation(),
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
describe('Ad repository', () => {
 | 
					describe('Ad repository', () => {
 | 
				
			||||||
  let prismaService: PrismaService;
 | 
					  let prismaService: PrismaService;
 | 
				
			||||||
  let adMapper: AdMapper;
 | 
					  let adMapper: AdMapper;
 | 
				
			||||||
| 
						 | 
					@ -82,7 +86,12 @@ describe('Ad repository', () => {
 | 
				
			||||||
  });
 | 
					  });
 | 
				
			||||||
  it('should be defined', () => {
 | 
					  it('should be defined', () => {
 | 
				
			||||||
    expect(
 | 
					    expect(
 | 
				
			||||||
      new AdRepository(prismaService, adMapper, eventEmitter),
 | 
					      new AdRepository(
 | 
				
			||||||
 | 
					        prismaService,
 | 
				
			||||||
 | 
					        adMapper,
 | 
				
			||||||
 | 
					        eventEmitter,
 | 
				
			||||||
 | 
					        mockMessagePublisher,
 | 
				
			||||||
 | 
					      ),
 | 
				
			||||||
    ).toBeDefined();
 | 
					    ).toBeDefined();
 | 
				
			||||||
  });
 | 
					  });
 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,3 +0,0 @@
 | 
				
			||||||
export interface CheckRepositoryPort {
 | 
					 | 
				
			||||||
  healthCheck(): Promise<boolean>;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
| 
						 | 
					@ -1,48 +0,0 @@
 | 
				
			||||||
import { Inject, Injectable } from '@nestjs/common';
 | 
					 | 
				
			||||||
import {
 | 
					 | 
				
			||||||
  HealthCheckError,
 | 
					 | 
				
			||||||
  HealthCheckResult,
 | 
					 | 
				
			||||||
  HealthIndicator,
 | 
					 | 
				
			||||||
  HealthIndicatorResult,
 | 
					 | 
				
			||||||
} from '@nestjs/terminus';
 | 
					 | 
				
			||||||
import { CheckRepositoryPort } from '../ports/check-repository.port';
 | 
					 | 
				
			||||||
import { AD_REPOSITORY } from '@modules/health/health.di-tokens';
 | 
					 | 
				
			||||||
import { AdRepositoryPort } from '@modules/ad/core/application/ports/ad.repository.port';
 | 
					 | 
				
			||||||
import { MESSAGE_PUBLISHER } from '@src/app.constants';
 | 
					 | 
				
			||||||
import { LOGGING_AD_HEALTH_CRIT } from '@modules/health/health.constants';
 | 
					 | 
				
			||||||
import { MessagePublisherPort } from '@mobicoop/ddd-library';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
@Injectable()
 | 
					 | 
				
			||||||
export class RepositoriesHealthIndicatorUseCase extends HealthIndicator {
 | 
					 | 
				
			||||||
  private _checkRepositories: CheckRepositoryPort[];
 | 
					 | 
				
			||||||
  constructor(
 | 
					 | 
				
			||||||
    @Inject(AD_REPOSITORY)
 | 
					 | 
				
			||||||
    private readonly adRepository: AdRepositoryPort,
 | 
					 | 
				
			||||||
    @Inject(MESSAGE_PUBLISHER)
 | 
					 | 
				
			||||||
    private readonly messagePublisher: MessagePublisherPort,
 | 
					 | 
				
			||||||
  ) {
 | 
					 | 
				
			||||||
    super();
 | 
					 | 
				
			||||||
    this._checkRepositories = [adRepository];
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
  isHealthy = async (key: string): Promise<HealthIndicatorResult> => {
 | 
					 | 
				
			||||||
    try {
 | 
					 | 
				
			||||||
      await Promise.all(
 | 
					 | 
				
			||||||
        this._checkRepositories.map(
 | 
					 | 
				
			||||||
          async (checkRepository: CheckRepositoryPort) => {
 | 
					 | 
				
			||||||
            await checkRepository.healthCheck();
 | 
					 | 
				
			||||||
          },
 | 
					 | 
				
			||||||
        ),
 | 
					 | 
				
			||||||
      );
 | 
					 | 
				
			||||||
      return this.getStatus(key, true);
 | 
					 | 
				
			||||||
    } catch (error) {
 | 
					 | 
				
			||||||
      const healthCheckResult: HealthCheckResult = error;
 | 
					 | 
				
			||||||
      this.messagePublisher.publish(
 | 
					 | 
				
			||||||
        LOGGING_AD_HEALTH_CRIT,
 | 
					 | 
				
			||||||
        JSON.stringify(healthCheckResult.error),
 | 
					 | 
				
			||||||
      );
 | 
					 | 
				
			||||||
      throw new HealthCheckError('Repository', {
 | 
					 | 
				
			||||||
        repository: error.message,
 | 
					 | 
				
			||||||
      });
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
  };
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
| 
						 | 
					@ -1 +0,0 @@
 | 
				
			||||||
export const LOGGING_AD_HEALTH_CRIT = 'logging.ad.health.crit';
 | 
					 | 
				
			||||||
| 
						 | 
					@ -1 +0,0 @@
 | 
				
			||||||
export const AD_REPOSITORY = Symbol('AD_REPOSITORY');
 | 
					 | 
				
			||||||
| 
						 | 
					@ -1,37 +0,0 @@
 | 
				
			||||||
import { Module, Provider } from '@nestjs/common';
 | 
					 | 
				
			||||||
import { HealthHttpController } from './interface/http-controllers/health.http.controller';
 | 
					 | 
				
			||||||
import { TerminusModule } from '@nestjs/terminus';
 | 
					 | 
				
			||||||
import { MESSAGE_PUBLISHER } from 'src/app.constants';
 | 
					 | 
				
			||||||
import { RepositoriesHealthIndicatorUseCase } from './core/application/usecases/repositories.health-indicator.usecase';
 | 
					 | 
				
			||||||
import { AdRepository } from '../ad/infrastructure/ad.repository';
 | 
					 | 
				
			||||||
import { AD_REPOSITORY } from './health.di-tokens';
 | 
					 | 
				
			||||||
import { HealthGrpcController } from './interface/grpc-controllers/health.grpc.controller';
 | 
					 | 
				
			||||||
import { AdModule } from '@modules/ad/ad.module';
 | 
					 | 
				
			||||||
import { MessageBrokerPublisher } from '@mobicoop/message-broker-module';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
const grpcControllers = [HealthGrpcController];
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
const httpControllers = [HealthHttpController];
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
const useCases: Provider[] = [RepositoriesHealthIndicatorUseCase];
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
const repositories: Provider[] = [
 | 
					 | 
				
			||||||
  {
 | 
					 | 
				
			||||||
    provide: AD_REPOSITORY,
 | 
					 | 
				
			||||||
    useClass: AdRepository,
 | 
					 | 
				
			||||||
  },
 | 
					 | 
				
			||||||
];
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
const messageBrokers: Provider[] = [
 | 
					 | 
				
			||||||
  {
 | 
					 | 
				
			||||||
    provide: MESSAGE_PUBLISHER,
 | 
					 | 
				
			||||||
    useClass: MessageBrokerPublisher,
 | 
					 | 
				
			||||||
  },
 | 
					 | 
				
			||||||
];
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
@Module({
 | 
					 | 
				
			||||||
  imports: [TerminusModule, AdModule],
 | 
					 | 
				
			||||||
  controllers: [...grpcControllers, ...httpControllers],
 | 
					 | 
				
			||||||
  providers: [...useCases, ...repositories, ...messageBrokers],
 | 
					 | 
				
			||||||
})
 | 
					 | 
				
			||||||
export class HealthModule {}
 | 
					 | 
				
			||||||
| 
						 | 
					@ -1,42 +0,0 @@
 | 
				
			||||||
import { Controller } from '@nestjs/common';
 | 
					 | 
				
			||||||
import { GrpcMethod } from '@nestjs/microservices';
 | 
					 | 
				
			||||||
import { RepositoriesHealthIndicatorUseCase } from '../../core/application/usecases/repositories.health-indicator.usecase';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
export enum ServingStatus {
 | 
					 | 
				
			||||||
  UNKNOWN = 0,
 | 
					 | 
				
			||||||
  SERVING = 1,
 | 
					 | 
				
			||||||
  NOT_SERVING = 2,
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
interface HealthCheckRequest {
 | 
					 | 
				
			||||||
  service: string;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
interface HealthCheckResponse {
 | 
					 | 
				
			||||||
  status: ServingStatus;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
@Controller()
 | 
					 | 
				
			||||||
export class HealthGrpcController {
 | 
					 | 
				
			||||||
  constructor(
 | 
					 | 
				
			||||||
    private readonly repositoriesHealthIndicatorUseCase: RepositoriesHealthIndicatorUseCase,
 | 
					 | 
				
			||||||
  ) {}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  @GrpcMethod('Health', 'Check')
 | 
					 | 
				
			||||||
  async check(
 | 
					 | 
				
			||||||
    // eslint-disable-next-line @typescript-eslint/no-unused-vars
 | 
					 | 
				
			||||||
    data?: HealthCheckRequest,
 | 
					 | 
				
			||||||
    // eslint-disable-next-line @typescript-eslint/no-unused-vars
 | 
					 | 
				
			||||||
    metadata?: any,
 | 
					 | 
				
			||||||
  ): Promise<HealthCheckResponse> {
 | 
					 | 
				
			||||||
    const healthCheck = await this.repositoriesHealthIndicatorUseCase.isHealthy(
 | 
					 | 
				
			||||||
      'repositories',
 | 
					 | 
				
			||||||
    );
 | 
					 | 
				
			||||||
    return {
 | 
					 | 
				
			||||||
      status:
 | 
					 | 
				
			||||||
        healthCheck['repositories'].status == 'up'
 | 
					 | 
				
			||||||
          ? ServingStatus.SERVING
 | 
					 | 
				
			||||||
          : ServingStatus.NOT_SERVING,
 | 
					 | 
				
			||||||
    };
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
| 
						 | 
					@ -1,21 +0,0 @@
 | 
				
			||||||
syntax = "proto3";
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
package health;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
service Health {
 | 
					 | 
				
			||||||
  rpc Check(HealthCheckRequest) returns (HealthCheckResponse);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
message HealthCheckRequest {
 | 
					 | 
				
			||||||
  string service = 1;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
message HealthCheckResponse {
 | 
					 | 
				
			||||||
  enum ServingStatus {
 | 
					 | 
				
			||||||
    UNKNOWN = 0;
 | 
					 | 
				
			||||||
    SERVING = 1;
 | 
					 | 
				
			||||||
    NOT_SERVING = 2;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
  ServingStatus status = 1;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
| 
						 | 
					@ -1,28 +0,0 @@
 | 
				
			||||||
import { RepositoriesHealthIndicatorUseCase } from '@modules/health/core/application/usecases/repositories.health-indicator.usecase';
 | 
					 | 
				
			||||||
import { Controller, Get } from '@nestjs/common';
 | 
					 | 
				
			||||||
import {
 | 
					 | 
				
			||||||
  HealthCheckService,
 | 
					 | 
				
			||||||
  HealthCheck,
 | 
					 | 
				
			||||||
  HealthCheckResult,
 | 
					 | 
				
			||||||
} from '@nestjs/terminus';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
@Controller('health')
 | 
					 | 
				
			||||||
export class HealthHttpController {
 | 
					 | 
				
			||||||
  constructor(
 | 
					 | 
				
			||||||
    private readonly repositoriesHealthIndicatorUseCase: RepositoriesHealthIndicatorUseCase,
 | 
					 | 
				
			||||||
    private readonly healthCheckService: HealthCheckService,
 | 
					 | 
				
			||||||
  ) {}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  @Get()
 | 
					 | 
				
			||||||
  @HealthCheck()
 | 
					 | 
				
			||||||
  async check(): Promise<HealthCheckResult> {
 | 
					 | 
				
			||||||
    try {
 | 
					 | 
				
			||||||
      return await this.healthCheckService.check([
 | 
					 | 
				
			||||||
        async () =>
 | 
					 | 
				
			||||||
          this.repositoriesHealthIndicatorUseCase.isHealthy('repositories'),
 | 
					 | 
				
			||||||
      ]);
 | 
					 | 
				
			||||||
    } catch (error) {
 | 
					 | 
				
			||||||
      throw error;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
| 
						 | 
					@ -1,72 +0,0 @@
 | 
				
			||||||
import { RepositoriesHealthIndicatorUseCase } from '@modules/health/core/application/usecases/repositories.health-indicator.usecase';
 | 
					 | 
				
			||||||
import {
 | 
					 | 
				
			||||||
  HealthGrpcController,
 | 
					 | 
				
			||||||
  ServingStatus,
 | 
					 | 
				
			||||||
} from '@modules/health/interface/grpc-controllers/health.grpc.controller';
 | 
					 | 
				
			||||||
import { Test, TestingModule } from '@nestjs/testing';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
const mockRepositoriesHealthIndicatorUseCase = {
 | 
					 | 
				
			||||||
  isHealthy: jest
 | 
					 | 
				
			||||||
    .fn()
 | 
					 | 
				
			||||||
    .mockImplementationOnce(() => ({
 | 
					 | 
				
			||||||
      repositories: {
 | 
					 | 
				
			||||||
        status: 'up',
 | 
					 | 
				
			||||||
      },
 | 
					 | 
				
			||||||
    }))
 | 
					 | 
				
			||||||
    .mockImplementationOnce(() => ({
 | 
					 | 
				
			||||||
      repositories: {
 | 
					 | 
				
			||||||
        status: 'down',
 | 
					 | 
				
			||||||
      },
 | 
					 | 
				
			||||||
    })),
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
describe('Health Grpc Controller', () => {
 | 
					 | 
				
			||||||
  let healthGrpcController: HealthGrpcController;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  beforeAll(async () => {
 | 
					 | 
				
			||||||
    const module: TestingModule = await Test.createTestingModule({
 | 
					 | 
				
			||||||
      providers: [
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
          provide: RepositoriesHealthIndicatorUseCase,
 | 
					 | 
				
			||||||
          useValue: mockRepositoriesHealthIndicatorUseCase,
 | 
					 | 
				
			||||||
        },
 | 
					 | 
				
			||||||
        HealthGrpcController,
 | 
					 | 
				
			||||||
      ],
 | 
					 | 
				
			||||||
    }).compile();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    healthGrpcController =
 | 
					 | 
				
			||||||
      module.get<HealthGrpcController>(HealthGrpcController);
 | 
					 | 
				
			||||||
  });
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  afterEach(async () => {
 | 
					 | 
				
			||||||
    jest.clearAllMocks();
 | 
					 | 
				
			||||||
  });
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  it('should be defined', () => {
 | 
					 | 
				
			||||||
    expect(healthGrpcController).toBeDefined();
 | 
					 | 
				
			||||||
  });
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  it('should return a Serving status ', async () => {
 | 
					 | 
				
			||||||
    jest.spyOn(mockRepositoriesHealthIndicatorUseCase, 'isHealthy');
 | 
					 | 
				
			||||||
    const servingStatus: { status: ServingStatus } =
 | 
					 | 
				
			||||||
      await healthGrpcController.check();
 | 
					 | 
				
			||||||
    expect(servingStatus).toEqual({
 | 
					 | 
				
			||||||
      status: ServingStatus.SERVING,
 | 
					 | 
				
			||||||
    });
 | 
					 | 
				
			||||||
    expect(
 | 
					 | 
				
			||||||
      mockRepositoriesHealthIndicatorUseCase.isHealthy,
 | 
					 | 
				
			||||||
    ).toHaveBeenCalledTimes(1);
 | 
					 | 
				
			||||||
  });
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  it('should return a Not Serving status ', async () => {
 | 
					 | 
				
			||||||
    jest.spyOn(mockRepositoriesHealthIndicatorUseCase, 'isHealthy');
 | 
					 | 
				
			||||||
    const servingStatus: { status: ServingStatus } =
 | 
					 | 
				
			||||||
      await healthGrpcController.check();
 | 
					 | 
				
			||||||
    expect(servingStatus).toEqual({
 | 
					 | 
				
			||||||
      status: ServingStatus.NOT_SERVING,
 | 
					 | 
				
			||||||
    });
 | 
					 | 
				
			||||||
    expect(
 | 
					 | 
				
			||||||
      mockRepositoriesHealthIndicatorUseCase.isHealthy,
 | 
					 | 
				
			||||||
    ).toHaveBeenCalledTimes(1);
 | 
					 | 
				
			||||||
  });
 | 
					 | 
				
			||||||
});
 | 
					 | 
				
			||||||
| 
						 | 
					@ -1,90 +0,0 @@
 | 
				
			||||||
import { RepositoriesHealthIndicatorUseCase } from '@modules/health/core/application/usecases/repositories.health-indicator.usecase';
 | 
					 | 
				
			||||||
import { HealthHttpController } from '@modules/health/interface/http-controllers/health.http.controller';
 | 
					 | 
				
			||||||
import { HealthCheckResult, HealthCheckService } from '@nestjs/terminus';
 | 
					 | 
				
			||||||
import { Test, TestingModule } from '@nestjs/testing';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
const mockHealthCheckService = {
 | 
					 | 
				
			||||||
  check: jest
 | 
					 | 
				
			||||||
    .fn()
 | 
					 | 
				
			||||||
    .mockImplementationOnce(() => ({
 | 
					 | 
				
			||||||
      status: 'ok',
 | 
					 | 
				
			||||||
      info: {
 | 
					 | 
				
			||||||
        repositories: {
 | 
					 | 
				
			||||||
          status: 'up',
 | 
					 | 
				
			||||||
        },
 | 
					 | 
				
			||||||
      },
 | 
					 | 
				
			||||||
      error: {},
 | 
					 | 
				
			||||||
      details: {
 | 
					 | 
				
			||||||
        repositories: {
 | 
					 | 
				
			||||||
          status: 'up',
 | 
					 | 
				
			||||||
        },
 | 
					 | 
				
			||||||
      },
 | 
					 | 
				
			||||||
    }))
 | 
					 | 
				
			||||||
    .mockImplementationOnce(() => ({
 | 
					 | 
				
			||||||
      status: 'error',
 | 
					 | 
				
			||||||
      info: {},
 | 
					 | 
				
			||||||
      error: {
 | 
					 | 
				
			||||||
        repository:
 | 
					 | 
				
			||||||
          "\nInvalid `prisma.$queryRaw()` invocation:\n\n\nCan't reach database server at `v3-db`:`5432`\n\nPlease make sure your database server is running at `v3-db`:`5432`.",
 | 
					 | 
				
			||||||
      },
 | 
					 | 
				
			||||||
      details: {
 | 
					 | 
				
			||||||
        repository:
 | 
					 | 
				
			||||||
          "\nInvalid `prisma.$queryRaw()` invocation:\n\n\nCan't reach database server at `v3-db`:`5432`\n\nPlease make sure your database server is running at `v3-db`:`5432`.",
 | 
					 | 
				
			||||||
      },
 | 
					 | 
				
			||||||
    })),
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
const mockRepositoriesHealthIndicatorUseCase = {
 | 
					 | 
				
			||||||
  isHealthy: jest.fn(),
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
describe('Health Http Controller', () => {
 | 
					 | 
				
			||||||
  let healthHttpController: HealthHttpController;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  beforeAll(async () => {
 | 
					 | 
				
			||||||
    const module: TestingModule = await Test.createTestingModule({
 | 
					 | 
				
			||||||
      providers: [
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
          provide: HealthCheckService,
 | 
					 | 
				
			||||||
          useValue: mockHealthCheckService,
 | 
					 | 
				
			||||||
        },
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
          provide: RepositoriesHealthIndicatorUseCase,
 | 
					 | 
				
			||||||
          useValue: mockRepositoriesHealthIndicatorUseCase,
 | 
					 | 
				
			||||||
        },
 | 
					 | 
				
			||||||
        HealthHttpController,
 | 
					 | 
				
			||||||
      ],
 | 
					 | 
				
			||||||
    }).compile();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    healthHttpController =
 | 
					 | 
				
			||||||
      module.get<HealthHttpController>(HealthHttpController);
 | 
					 | 
				
			||||||
  });
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  afterEach(async () => {
 | 
					 | 
				
			||||||
    jest.clearAllMocks();
 | 
					 | 
				
			||||||
  });
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  it('should be defined', () => {
 | 
					 | 
				
			||||||
    expect(healthHttpController).toBeDefined();
 | 
					 | 
				
			||||||
  });
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  it('should return an HealthCheckResult with Ok status ', async () => {
 | 
					 | 
				
			||||||
    jest.spyOn(mockHealthCheckService, 'check');
 | 
					 | 
				
			||||||
    jest.spyOn(mockRepositoriesHealthIndicatorUseCase, 'isHealthy');
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    const healthCheckResult: HealthCheckResult =
 | 
					 | 
				
			||||||
      await healthHttpController.check();
 | 
					 | 
				
			||||||
    expect(healthCheckResult.status).toBe('ok');
 | 
					 | 
				
			||||||
    expect(mockHealthCheckService.check).toHaveBeenCalledTimes(1);
 | 
					 | 
				
			||||||
  });
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  it('should return an HealthCheckResult with Error status ', async () => {
 | 
					 | 
				
			||||||
    jest.spyOn(mockHealthCheckService, 'check');
 | 
					 | 
				
			||||||
    jest.spyOn(mockRepositoriesHealthIndicatorUseCase, 'isHealthy');
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    const healthCheckResult: HealthCheckResult =
 | 
					 | 
				
			||||||
      await healthHttpController.check();
 | 
					 | 
				
			||||||
    expect(healthCheckResult.status).toBe('error');
 | 
					 | 
				
			||||||
    expect(mockHealthCheckService.check).toHaveBeenCalledTimes(1);
 | 
					 | 
				
			||||||
  });
 | 
					 | 
				
			||||||
});
 | 
					 | 
				
			||||||
| 
						 | 
					@ -1,66 +0,0 @@
 | 
				
			||||||
import { Test, TestingModule } from '@nestjs/testing';
 | 
					 | 
				
			||||||
import { HealthCheckError, HealthIndicatorResult } from '@nestjs/terminus';
 | 
					 | 
				
			||||||
import { RepositoriesHealthIndicatorUseCase } from '../../core/application/usecases/repositories.health-indicator.usecase';
 | 
					 | 
				
			||||||
import { AD_REPOSITORY } from '@modules/health/health.di-tokens';
 | 
					 | 
				
			||||||
import { MESSAGE_PUBLISHER } from '@src/app.constants';
 | 
					 | 
				
			||||||
import { DatabaseErrorException } from '@mobicoop/ddd-library';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
const mockAdRepository = {
 | 
					 | 
				
			||||||
  healthCheck: jest
 | 
					 | 
				
			||||||
    .fn()
 | 
					 | 
				
			||||||
    .mockImplementationOnce(() => {
 | 
					 | 
				
			||||||
      return Promise.resolve(true);
 | 
					 | 
				
			||||||
    })
 | 
					 | 
				
			||||||
    .mockImplementation(() => {
 | 
					 | 
				
			||||||
      throw new DatabaseErrorException('An error occured in the database');
 | 
					 | 
				
			||||||
    }),
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
const mockMessagePublisher = {
 | 
					 | 
				
			||||||
  publish: jest.fn().mockImplementation(),
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
describe('RepositoriesHealthIndicatorUseCase', () => {
 | 
					 | 
				
			||||||
  let repositoriesHealthIndicatorUseCase: RepositoriesHealthIndicatorUseCase;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  beforeAll(async () => {
 | 
					 | 
				
			||||||
    const module: TestingModule = await Test.createTestingModule({
 | 
					 | 
				
			||||||
      providers: [
 | 
					 | 
				
			||||||
        RepositoriesHealthIndicatorUseCase,
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
          provide: AD_REPOSITORY,
 | 
					 | 
				
			||||||
          useValue: mockAdRepository,
 | 
					 | 
				
			||||||
        },
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
          provide: MESSAGE_PUBLISHER,
 | 
					 | 
				
			||||||
          useValue: mockMessagePublisher,
 | 
					 | 
				
			||||||
        },
 | 
					 | 
				
			||||||
      ],
 | 
					 | 
				
			||||||
    }).compile();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    repositoriesHealthIndicatorUseCase =
 | 
					 | 
				
			||||||
      module.get<RepositoriesHealthIndicatorUseCase>(
 | 
					 | 
				
			||||||
        RepositoriesHealthIndicatorUseCase,
 | 
					 | 
				
			||||||
      );
 | 
					 | 
				
			||||||
  });
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  it('should be defined', () => {
 | 
					 | 
				
			||||||
    expect(repositoriesHealthIndicatorUseCase).toBeDefined();
 | 
					 | 
				
			||||||
  });
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  describe('execute', () => {
 | 
					 | 
				
			||||||
    it('should check health successfully', async () => {
 | 
					 | 
				
			||||||
      const healthIndicatorResult: HealthIndicatorResult =
 | 
					 | 
				
			||||||
        await repositoriesHealthIndicatorUseCase.isHealthy('repositories');
 | 
					 | 
				
			||||||
      expect(healthIndicatorResult['repositories'].status).toBe('up');
 | 
					 | 
				
			||||||
    });
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    it('should throw an error if database is unavailable', async () => {
 | 
					 | 
				
			||||||
      jest.spyOn(mockMessagePublisher, 'publish');
 | 
					 | 
				
			||||||
      await expect(
 | 
					 | 
				
			||||||
        repositoriesHealthIndicatorUseCase.isHealthy('repositories'),
 | 
					 | 
				
			||||||
      ).rejects.toBeInstanceOf(HealthCheckError);
 | 
					 | 
				
			||||||
      expect(mockMessagePublisher.publish).toHaveBeenCalledTimes(1);
 | 
					 | 
				
			||||||
    });
 | 
					 | 
				
			||||||
  });
 | 
					 | 
				
			||||||
});
 | 
					 | 
				
			||||||
| 
						 | 
					@ -0,0 +1 @@
 | 
				
			||||||
 | 
					export const MESSAGE_PUBLISHER = Symbol('MESSAGE_PUBLISHER');
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,36 @@
 | 
				
			||||||
 | 
					import { Module, Provider } from '@nestjs/common';
 | 
				
			||||||
 | 
					import { MESSAGE_PUBLISHER } from './messager.di-tokens';
 | 
				
			||||||
 | 
					import {
 | 
				
			||||||
 | 
					  MessageBrokerModule,
 | 
				
			||||||
 | 
					  MessageBrokerModuleOptions,
 | 
				
			||||||
 | 
					  MessageBrokerPublisher,
 | 
				
			||||||
 | 
					} from '@mobicoop/message-broker-module';
 | 
				
			||||||
 | 
					import { ConfigModule, ConfigService } from '@nestjs/config';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const imports = [
 | 
				
			||||||
 | 
					  MessageBrokerModule.forRootAsync({
 | 
				
			||||||
 | 
					    imports: [ConfigModule],
 | 
				
			||||||
 | 
					    inject: [ConfigService],
 | 
				
			||||||
 | 
					    useFactory: async (
 | 
				
			||||||
 | 
					      configService: ConfigService,
 | 
				
			||||||
 | 
					    ): Promise<MessageBrokerModuleOptions> => ({
 | 
				
			||||||
 | 
					      uri: configService.get<string>('MESSAGE_BROKER_URI'),
 | 
				
			||||||
 | 
					      exchange: configService.get<string>('MESSAGE_BROKER_EXCHANGE'),
 | 
				
			||||||
 | 
					      name: 'ad',
 | 
				
			||||||
 | 
					    }),
 | 
				
			||||||
 | 
					  }),
 | 
				
			||||||
 | 
					];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const providers: Provider[] = [
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    provide: MESSAGE_PUBLISHER,
 | 
				
			||||||
 | 
					    useClass: MessageBrokerPublisher,
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@Module({
 | 
				
			||||||
 | 
					  imports,
 | 
				
			||||||
 | 
					  providers,
 | 
				
			||||||
 | 
					  exports: [MESSAGE_PUBLISHER],
 | 
				
			||||||
 | 
					})
 | 
				
			||||||
 | 
					export class MessagerModule {}
 | 
				
			||||||
		Loading…
	
		Reference in New Issue