Merge branch 'geocoderConfig' into 'main'
Geocoder configuration See merge request v3/service/configuration!39
This commit is contained in:
commit
5a5f1172a4
|
@ -74,7 +74,11 @@ GEOCODER_PROXIMITY=5
|
|||
# population vs distance prioritizer coef
|
||||
# "boost" population weight for results with a short distance
|
||||
# => multiply the population by COEF / distance (in km)
|
||||
GEOCODDER_POPULATION_PRIORITIZER_COEF=100
|
||||
GEOCODER_POPULATION_PRIORITIZER_COEF=100
|
||||
# main providers, separated by a comma
|
||||
GEOCODER_PROVIDERS=ADDOK,PELIAS_SEARCH,PELIAS_AUTOCOMPLETE
|
||||
# fallback providers, separated by a comma
|
||||
GEOCODER_PROVIDERS_FALLBACK=GMAPS
|
||||
|
||||
# PAGINATION
|
||||
# number of results per page
|
||||
|
|
|
@ -52,7 +52,7 @@ Redis database is automatically populated at the start of the service. If keys a
|
|||
|
||||
The app exposes the following [gRPC](https://grpc.io/) services :
|
||||
|
||||
- **Get** : get a configuration item by its domain and key
|
||||
- **Get** : get a configuration item by its domain and key (retrieves the domain, key, value and type)
|
||||
|
||||
```json
|
||||
{
|
||||
|
|
File diff suppressed because it is too large
Load Diff
54
package.json
54
package.json
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "@mobicoop/configuration",
|
||||
"version": "2.6.0",
|
||||
"version": "2.7.0",
|
||||
"description": "Mobicoop V3 Configuration Service",
|
||||
"author": "sbriat",
|
||||
"private": true,
|
||||
|
@ -24,48 +24,48 @@
|
|||
"test:e2e": "jest --config ./test/jest-e2e.json"
|
||||
},
|
||||
"dependencies": {
|
||||
"@grpc/grpc-js": "^1.9.9",
|
||||
"@grpc/grpc-js": "^1.9.13",
|
||||
"@grpc/proto-loader": "^0.7.10",
|
||||
"@mobicoop/configuration-module": "^7.3.0",
|
||||
"@mobicoop/ddd-library": "^2.3.0",
|
||||
"@mobicoop/configuration-module": "^8.0.0",
|
||||
"@mobicoop/ddd-library": "^2.4.2",
|
||||
"@mobicoop/health-module": "^2.3.1",
|
||||
"@mobicoop/message-broker-module": "^2.1.1",
|
||||
"@nestjs/common": "^10.2.8",
|
||||
"@nestjs/common": "^10.3.0",
|
||||
"@nestjs/config": "^3.1.1",
|
||||
"@nestjs/core": "^10.2.8",
|
||||
"@nestjs/core": "^10.3.0",
|
||||
"@nestjs/cqrs": "^10.2.6",
|
||||
"@nestjs/event-emitter": "^2.0.3",
|
||||
"@nestjs/microservices": "^10.2.8",
|
||||
"@nestjs/platform-express": "^10.2.8",
|
||||
"@nestjs/terminus": "^10.1.1",
|
||||
"@nestjs/microservices": "^10.3.0",
|
||||
"@nestjs/platform-express": "^10.3.0",
|
||||
"@nestjs/terminus": "^10.2.0",
|
||||
"class-transformer": "^0.5.1",
|
||||
"class-validator": "^0.14.0",
|
||||
"reflect-metadata": "^0.1.13",
|
||||
"class-validator": "^0.14.1",
|
||||
"reflect-metadata": "^0.1.12",
|
||||
"rimraf": "^5.0.5"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@nestjs/cli": "^10.2.1",
|
||||
"@nestjs/schematics": "^10.0.3",
|
||||
"@nestjs/testing": "^10.2.8",
|
||||
"@nestjs/cli": "^10.3.0",
|
||||
"@nestjs/schematics": "^10.1.0",
|
||||
"@nestjs/testing": "^10.3.0",
|
||||
"@types/express": "^4.17.21",
|
||||
"@types/jest": "29.5.8",
|
||||
"@types/node": "^20.9.0",
|
||||
"@types/supertest": "^2.0.16",
|
||||
"@typescript-eslint/eslint-plugin": "^6.10.0",
|
||||
"@typescript-eslint/parser": "^6.10.0",
|
||||
"@types/jest": "29.5.11",
|
||||
"@types/node": "^20.11.2",
|
||||
"@types/supertest": "^6.0.2",
|
||||
"@typescript-eslint/eslint-plugin": "^6.18.1",
|
||||
"@typescript-eslint/parser": "^6.18.1",
|
||||
"dotenv-cli": "^7.3.0",
|
||||
"eslint": "^8.53.0",
|
||||
"eslint-config-prettier": "^9.0.0",
|
||||
"eslint-plugin-prettier": "^5.0.1",
|
||||
"eslint": "^8.56.0",
|
||||
"eslint-config-prettier": "^9.1.0",
|
||||
"eslint-plugin-prettier": "^5.1.3",
|
||||
"jest": "29.7.0",
|
||||
"prettier": "^3.0.3",
|
||||
"prettier": "^3.2.2",
|
||||
"source-map-support": "^0.5.21",
|
||||
"supertest": "^6.3.3",
|
||||
"supertest": "^6.3.4",
|
||||
"ts-jest": "29.1.1",
|
||||
"ts-loader": "^9.5.0",
|
||||
"ts-node": "^10.9.1",
|
||||
"ts-loader": "^9.5.1",
|
||||
"ts-node": "^10.9.2",
|
||||
"tsconfig-paths": "4.2.0",
|
||||
"typescript": "^5.2.2"
|
||||
"typescript": "^5.3.3"
|
||||
},
|
||||
"jest": {
|
||||
"moduleFileExtensions": [
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { ConfigurationDomain } from '@mobicoop/configuration-module';
|
||||
import { Domain } from '@mobicoop/configuration-module';
|
||||
|
||||
export interface Config {
|
||||
domain: ConfigurationDomain;
|
||||
domain: Domain;
|
||||
}
|
||||
|
|
|
@ -46,7 +46,10 @@ export default registerAs('geography', () => ({
|
|||
.GEOCODER_POPULATION_PRIORITIZER_COEF
|
||||
? parseInt(process.env.GEOCODER_POPULATION_PRIORITIZER_COEF)
|
||||
: 100,
|
||||
geocoderProviders:
|
||||
process.env.GEOCODER_PROVIDERS ?? 'ADDOK,PELIAS_SEARCH,PELIAS_AUTOCOMPLETE',
|
||||
geocoderProvidersFallback: process.env.GEOCODER_PROVIDERS_FALLBACK ?? 'GMAPS',
|
||||
geocoderProviders: process.env.GEOCODER_PROVIDERS
|
||||
? process.env.GEOCODER_PROVIDERS?.split(',')
|
||||
: ['ADDOK,PELIAS_SEARCH,PELIAS_AUTOCOMPLETE'],
|
||||
geocoderProvidersFallback: process.env.GEOCODER_PROVIDERS_FALLBACK
|
||||
? process.env.GEOCODER_PROVIDERS_FALLBACK?.split(',')
|
||||
: ['GMAPS'],
|
||||
}));
|
||||
|
|
|
@ -1,9 +1,6 @@
|
|||
import { Injectable } from '@nestjs/common';
|
||||
import { ConfigurationResponseDto } from './interface/dtos/configuration.response.dto';
|
||||
import {
|
||||
ConfigurationIdentifier,
|
||||
ConfigurationValue,
|
||||
} from '@mobicoop/configuration-module';
|
||||
import { Identifier, Value } from '@mobicoop/configuration-module';
|
||||
import { ConfigurationsManagerService } from './core/application/services/configurations-manager.service';
|
||||
|
||||
@Injectable()
|
||||
|
@ -13,15 +10,14 @@ export class ConfigurationMapper {
|
|||
) {}
|
||||
|
||||
toResponse = (
|
||||
configurationIdentifier: ConfigurationIdentifier,
|
||||
configurationValue: ConfigurationValue,
|
||||
identifier: Identifier,
|
||||
value: Value,
|
||||
): ConfigurationResponseDto => {
|
||||
const response = new ConfigurationResponseDto();
|
||||
response.domain = configurationIdentifier.domain;
|
||||
response.key = configurationIdentifier.key;
|
||||
response.value = configurationValue;
|
||||
response.type =
|
||||
this.configurationsManager.configurationType(configurationValue);
|
||||
response.domain = identifier.domain;
|
||||
response.key = identifier.key;
|
||||
response.value = value;
|
||||
response.type = this.configurationsManager.configurationType(value);
|
||||
return response;
|
||||
};
|
||||
}
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
import { ConfigurationIdentifier } from '@mobicoop/configuration-module';
|
||||
import { Identifier } from '@mobicoop/configuration-module';
|
||||
import { Command, CommandProps } from '@mobicoop/ddd-library';
|
||||
|
||||
export class SetConfigurationCommand extends Command {
|
||||
readonly configurationIdentifier: ConfigurationIdentifier;
|
||||
readonly identifier: Identifier;
|
||||
readonly value: string | boolean | number;
|
||||
|
||||
constructor(props: CommandProps<SetConfigurationCommand>) {
|
||||
super(props);
|
||||
this.configurationIdentifier = props.configurationIdentifier;
|
||||
this.identifier = props.identifier;
|
||||
this.value = props.value;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,8 +3,8 @@ import { Inject } from '@nestjs/common';
|
|||
import { SetConfigurationCommand } from './set-configuration.command';
|
||||
import { CONFIGURATION_REPOSITORY } from '@modules/configuration/configuration.di-tokens';
|
||||
import {
|
||||
ConfigurationIdentifier,
|
||||
ConfigurationType,
|
||||
Identifier,
|
||||
Type,
|
||||
SetConfigurationRepositoryPort,
|
||||
} from '@mobicoop/configuration-module';
|
||||
import { ConfigurationsManagerService } from '../../services/configurations-manager.service';
|
||||
|
@ -18,26 +18,19 @@ export class SetConfigurationService implements ICommandHandler {
|
|||
private readonly configurationsManager: ConfigurationsManagerService,
|
||||
) {}
|
||||
|
||||
async execute(
|
||||
command: SetConfigurationCommand,
|
||||
): Promise<ConfigurationIdentifier> {
|
||||
const configurationType: ConfigurationType =
|
||||
this.configurationsManager.identifierType(
|
||||
command.configurationIdentifier,
|
||||
async execute(command: SetConfigurationCommand): Promise<Identifier> {
|
||||
const type: Type = this.configurationsManager.identifierType(
|
||||
command.identifier,
|
||||
);
|
||||
const value: any = this.configurationsManager.cast(
|
||||
`${command.value}`,
|
||||
configurationType,
|
||||
type,
|
||||
);
|
||||
if (
|
||||
(configurationType === ConfigurationType.INT ||
|
||||
configurationType === ConfigurationType.FLOAT) &&
|
||||
isNaN(value)
|
||||
)
|
||||
if ((type === Type.INT || type === Type.FLOAT) && isNaN(value))
|
||||
throw new ArgumentInvalidException('Bad value');
|
||||
return await this.configurationRepository.set(
|
||||
command.configurationIdentifier.domain,
|
||||
command.configurationIdentifier.key,
|
||||
command.identifier.domain,
|
||||
command.identifier.key,
|
||||
value,
|
||||
);
|
||||
}
|
||||
|
|
|
@ -3,7 +3,7 @@ import { GetConfigurationQuery } from './get-configuration.query';
|
|||
import { Inject } from '@nestjs/common';
|
||||
import { CONFIGURATION_REPOSITORY } from '@modules/configuration/configuration.di-tokens';
|
||||
import {
|
||||
ConfigurationValue,
|
||||
Value,
|
||||
GetConfigurationRepositoryPort,
|
||||
} from '@mobicoop/configuration-module';
|
||||
import { ConfigurationsManagerService } from '../../services/configurations-manager.service';
|
||||
|
@ -15,11 +15,10 @@ export class GetConfigurationQueryHandler implements IQueryHandler {
|
|||
private readonly configurationRepository: GetConfigurationRepositoryPort,
|
||||
private readonly configurationsManager: ConfigurationsManagerService,
|
||||
) {}
|
||||
async execute(query: GetConfigurationQuery): Promise<ConfigurationValue> {
|
||||
return await this.configurationRepository.get(
|
||||
query.configurationIdentifier.domain,
|
||||
query.configurationIdentifier.key,
|
||||
this.configurationsManager.identifierType(query.configurationIdentifier),
|
||||
);
|
||||
async execute(query: GetConfigurationQuery): Promise<Value> {
|
||||
return await this.configurationRepository.get(query.identifier.domain, {
|
||||
key: query.identifier.key,
|
||||
type: this.configurationsManager.identifierType(query.identifier),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,15 +1,12 @@
|
|||
import {
|
||||
ConfigurationDomain,
|
||||
ConfigurationIdentifier,
|
||||
} from '@mobicoop/configuration-module';
|
||||
import { Domain, Identifier } from '@mobicoop/configuration-module';
|
||||
import { QueryBase } from '@mobicoop/ddd-library';
|
||||
|
||||
export class GetConfigurationQuery extends QueryBase {
|
||||
readonly configurationIdentifier: ConfigurationIdentifier;
|
||||
readonly identifier: Identifier;
|
||||
|
||||
constructor(domain: ConfigurationDomain, key: string) {
|
||||
constructor(domain: Domain, key: string) {
|
||||
super();
|
||||
this.configurationIdentifier = {
|
||||
this.identifier = {
|
||||
domain,
|
||||
key,
|
||||
};
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
import {
|
||||
ConfigurationDomain,
|
||||
ConfigurationIdentifier,
|
||||
ConfigurationType,
|
||||
ConfigurationValue,
|
||||
Domain,
|
||||
Identifier,
|
||||
Type,
|
||||
Value,
|
||||
} from '@mobicoop/configuration-module';
|
||||
import { NotFoundException } from '@mobicoop/ddd-library';
|
||||
import { Injectable } from '@nestjs/common';
|
||||
|
@ -22,70 +22,81 @@ export class ConfigurationsManagerService {
|
|||
return [
|
||||
{
|
||||
...(this.configService.get<AuthConfig>('auth') as AuthConfig),
|
||||
domain: ConfigurationDomain.AUTH,
|
||||
domain: Domain.AUTH,
|
||||
},
|
||||
{
|
||||
...(this.configService.get<CarpoolConfig>('carpool') as CarpoolConfig),
|
||||
domain: ConfigurationDomain.CARPOOL,
|
||||
domain: Domain.CARPOOL,
|
||||
},
|
||||
{
|
||||
...(this.configService.get<GeographyConfig>(
|
||||
'geography',
|
||||
) as GeographyConfig),
|
||||
domain: ConfigurationDomain.GEOGRAPHY,
|
||||
domain: Domain.GEOGRAPHY,
|
||||
},
|
||||
{
|
||||
...(this.configService.get<MatchConfig>('match') as MatchConfig),
|
||||
domain: ConfigurationDomain.MATCH,
|
||||
domain: Domain.MATCH,
|
||||
},
|
||||
{
|
||||
...(this.configService.get<PaginationConfig>(
|
||||
'pagination',
|
||||
) as PaginationConfig),
|
||||
domain: ConfigurationDomain.PAGINATION,
|
||||
domain: Domain.PAGINATION,
|
||||
},
|
||||
];
|
||||
};
|
||||
|
||||
identifierType = (
|
||||
configurationIdentifier: ConfigurationIdentifier,
|
||||
): ConfigurationType => {
|
||||
identifierType = (identifier: Identifier): Type => {
|
||||
const configs: Config[] = this.list();
|
||||
const configuration: Config | undefined = configs.find(
|
||||
(config: Config) =>
|
||||
config.domain === configurationIdentifier.domain &&
|
||||
this._hasProperty(configurationIdentifier.key, config),
|
||||
config.domain === identifier.domain &&
|
||||
this._hasProperty(identifier.key, config),
|
||||
);
|
||||
if (!configuration)
|
||||
throw new NotFoundException('Configuration item not found');
|
||||
return this.configurationType(
|
||||
this._getValue(configurationIdentifier.key, configuration),
|
||||
this._getValue(identifier.key, configuration),
|
||||
);
|
||||
};
|
||||
|
||||
configurationType = (value: any): ConfigurationType => {
|
||||
configurationType = (value: any): Type => {
|
||||
if (Array.isArray(value)) return this._configurationTypeArray(value);
|
||||
switch (typeof value) {
|
||||
case 'number':
|
||||
if (this._isInt(value)) return ConfigurationType.INT;
|
||||
return ConfigurationType.FLOAT;
|
||||
if (this._isInt(value)) return Type.INT;
|
||||
return Type.FLOAT;
|
||||
case 'boolean':
|
||||
return ConfigurationType.BOOLEAN;
|
||||
return Type.BOOLEAN;
|
||||
default:
|
||||
return ConfigurationType.STRING;
|
||||
if (value.indexOf(',') === -1) return Type.STRING;
|
||||
return this._configurationTypeArray(value.split(','));
|
||||
}
|
||||
};
|
||||
|
||||
cast = (
|
||||
value: string,
|
||||
configurationType: ConfigurationType,
|
||||
): ConfigurationValue => {
|
||||
switch (configurationType) {
|
||||
case ConfigurationType.BOOLEAN:
|
||||
_configurationTypeArray = (value: Array<string | number>): Type => {
|
||||
return value.every((item) => typeof item === 'number' && this._isInt(item))
|
||||
? Type.INT_ARRAY
|
||||
: value.every((item) => typeof item === 'number')
|
||||
? Type.FLOAT_ARRAY
|
||||
: Type.STRING_ARRAY;
|
||||
};
|
||||
|
||||
cast = (value: string, type: Type): Value => {
|
||||
switch (type) {
|
||||
case Type.BOOLEAN:
|
||||
return value === 'true';
|
||||
case ConfigurationType.INT:
|
||||
case Type.INT:
|
||||
return parseInt(value);
|
||||
case ConfigurationType.FLOAT:
|
||||
case Type.FLOAT:
|
||||
return parseFloat(value);
|
||||
case Type.INT_ARRAY:
|
||||
return value.split(',').map((item: string) => parseInt(item));
|
||||
case Type.FLOAT_ARRAY:
|
||||
return value.split(',').map((item: string) => parseFloat(item));
|
||||
case Type.STRING_ARRAY:
|
||||
return value.split(',');
|
||||
default:
|
||||
return value;
|
||||
}
|
||||
|
|
|
@ -35,11 +35,12 @@ export class PopulateService implements OnApplicationBootstrap {
|
|||
for (key in configuration) {
|
||||
try {
|
||||
if (key !== 'domain')
|
||||
await this.getConfigurationRepository.get(
|
||||
config.domain,
|
||||
await this.getConfigurationRepository.get(config.domain, {
|
||||
key,
|
||||
this.configurationsManager.configurationType(configuration[key]),
|
||||
);
|
||||
type: this.configurationsManager.configurationType(
|
||||
configuration[key],
|
||||
),
|
||||
});
|
||||
} catch (error: any) {
|
||||
if (error instanceof NotFoundException) {
|
||||
this.setConfigurationRepository.set(
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
import { ConfigurationType } from '@mobicoop/configuration-module';
|
||||
import { Type } from '@mobicoop/configuration-module';
|
||||
|
||||
export class ConfigurationResponseDto {
|
||||
domain: string;
|
||||
key: string;
|
||||
value: string | boolean | number;
|
||||
type: ConfigurationType;
|
||||
value: string | boolean | number | string[] | number[];
|
||||
type: Type;
|
||||
}
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
import { ConfigurationDomain } from '@mobicoop/configuration-module';
|
||||
import { Domain } from '@mobicoop/configuration-module';
|
||||
import { IsEnum, IsNotEmpty, IsString } from 'class-validator';
|
||||
|
||||
export class GetConfigurationRequestDto {
|
||||
@IsEnum(ConfigurationDomain)
|
||||
@IsEnum(Domain)
|
||||
@IsNotEmpty()
|
||||
domain: ConfigurationDomain;
|
||||
domain: Domain;
|
||||
|
||||
@IsString()
|
||||
@IsNotEmpty()
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
import { ConfigurationDomain } from '@mobicoop/configuration-module';
|
||||
import { Domain } from '@mobicoop/configuration-module';
|
||||
import { IsEnum, IsNotEmpty, IsString } from 'class-validator';
|
||||
|
||||
export class SetConfigurationRequestDto {
|
||||
@IsEnum(ConfigurationDomain)
|
||||
@IsEnum(Domain)
|
||||
@IsNotEmpty()
|
||||
domain: ConfigurationDomain;
|
||||
domain: Domain;
|
||||
|
||||
@IsString()
|
||||
@IsNotEmpty()
|
||||
|
|
|
@ -11,7 +11,7 @@ import {
|
|||
RpcExceptionCode,
|
||||
RpcValidationPipe,
|
||||
} from '@mobicoop/ddd-library';
|
||||
import { ConfigurationValue } from '@mobicoop/configuration-module';
|
||||
import { Value } from '@mobicoop/configuration-module';
|
||||
|
||||
@UsePipes(
|
||||
new RpcValidationPipe({
|
||||
|
@ -31,11 +31,10 @@ export class GetConfigurationGrpcController {
|
|||
data: GetConfigurationRequestDto,
|
||||
): Promise<ConfigurationResponseDto> {
|
||||
try {
|
||||
const configurationValue: ConfigurationValue =
|
||||
await this.queryBus.execute(
|
||||
const value: Value = await this.queryBus.execute(
|
||||
new GetConfigurationQuery(data.domain, data.key),
|
||||
);
|
||||
return this.mapper.toResponse(data, configurationValue);
|
||||
return this.mapper.toResponse(data, value);
|
||||
} catch (e) {
|
||||
if (e instanceof NotFoundException) {
|
||||
throw new RpcException({
|
||||
|
|
|
@ -5,7 +5,7 @@ import { RpcExceptionCode, RpcValidationPipe } from '@mobicoop/ddd-library';
|
|||
import { GRPC_SERVICE_NAME } from '@src/app.constants';
|
||||
import { SetConfigurationRequestDto } from './dtos/set-configuration.request.dto';
|
||||
import { SetConfigurationCommand } from '@modules/configuration/core/application/commands/set-configuration/set-configuration.command';
|
||||
import { ConfigurationIdentifier } from '@mobicoop/configuration-module';
|
||||
import { Identifier } from '@mobicoop/configuration-module';
|
||||
|
||||
@UsePipes(
|
||||
new RpcValidationPipe({
|
||||
|
@ -20,19 +20,18 @@ export class SetConfigurationGrpcController {
|
|||
@GrpcMethod(GRPC_SERVICE_NAME, 'Set')
|
||||
async set(
|
||||
setConfigurationRequestDto: SetConfigurationRequestDto,
|
||||
): Promise<ConfigurationIdentifier> {
|
||||
): Promise<Identifier> {
|
||||
try {
|
||||
const configurationIdentifier: ConfigurationIdentifier =
|
||||
await this.commandBus.execute(
|
||||
const identifier: Identifier = await this.commandBus.execute(
|
||||
new SetConfigurationCommand({
|
||||
configurationIdentifier: {
|
||||
identifier: {
|
||||
domain: setConfigurationRequestDto.domain,
|
||||
key: setConfigurationRequestDto.key,
|
||||
},
|
||||
value: setConfigurationRequestDto.value,
|
||||
}),
|
||||
);
|
||||
return configurationIdentifier;
|
||||
return identifier;
|
||||
} catch (error: any) {
|
||||
throw new RpcException({
|
||||
code: RpcExceptionCode.UNKNOWN,
|
||||
|
|
|
@ -1,14 +1,11 @@
|
|||
import {
|
||||
ConfigurationDomain,
|
||||
ConfigurationType,
|
||||
} from '@mobicoop/configuration-module';
|
||||
import { Domain, Type } from '@mobicoop/configuration-module';
|
||||
import { ConfigurationMapper } from '@modules/configuration/configuration.mapper';
|
||||
import { ConfigurationsManagerService } from '@modules/configuration/core/application/services/configurations-manager.service';
|
||||
import { ConfigurationResponseDto } from '@modules/configuration/interface/dtos/configuration.response.dto';
|
||||
import { Test } from '@nestjs/testing';
|
||||
|
||||
const mockConfigurationsManagerService = {
|
||||
configurationType: jest.fn().mockImplementation(() => ConfigurationType.INT),
|
||||
configurationType: jest.fn().mockImplementation(() => Type.INT),
|
||||
};
|
||||
|
||||
describe('Configuration Mapper', () => {
|
||||
|
@ -34,7 +31,7 @@ describe('Configuration Mapper', () => {
|
|||
it('should map configuration to response', async () => {
|
||||
const mapped: ConfigurationResponseDto = configurationMapper.toResponse(
|
||||
{
|
||||
domain: ConfigurationDomain.CARPOOL,
|
||||
domain: Domain.CARPOOL,
|
||||
key: 'seatsProposed',
|
||||
},
|
||||
'3',
|
||||
|
|
|
@ -1,8 +1,4 @@
|
|||
import {
|
||||
ConfigurationDomain,
|
||||
ConfigurationIdentifier,
|
||||
ConfigurationType,
|
||||
} from '@mobicoop/configuration-module';
|
||||
import { Domain, Identifier, Type } from '@mobicoop/configuration-module';
|
||||
import { NotFoundException } from '@mobicoop/ddd-library';
|
||||
import { ConfigurationsManagerService } from '@modules/configuration/core/application/services/configurations-manager.service';
|
||||
import { ConfigService } from '@nestjs/config';
|
||||
|
@ -26,8 +22,18 @@ const mockConfigService = {
|
|||
};
|
||||
case 'geography':
|
||||
return {
|
||||
type: 'graphhopper',
|
||||
url: 'http://localhost:8989',
|
||||
georouterType: 'graphhopper',
|
||||
georouterUrl: 'http://localhost:8989',
|
||||
geocoderLang: 'fr',
|
||||
geocoderMinConfidence: 0.3,
|
||||
geocoderMaxResultsPerProvider: 5,
|
||||
geocoderMaxResultsPerType: 5,
|
||||
geocoderSanitize: true,
|
||||
geocoderConsolidate: true,
|
||||
geocoderProximity: 5,
|
||||
geocoderPopulationPrioritizerCoef: 100,
|
||||
geocoderProviders: ['provider1', 'provider2'],
|
||||
geocoderProvidersFallback: ['provider3'],
|
||||
};
|
||||
case 'match':
|
||||
return {
|
||||
|
@ -78,68 +84,95 @@ describe('Configurations Manager Service', () => {
|
|||
|
||||
describe('identifierType', () => {
|
||||
it('should return the type of a configuration item for a given identifier', () => {
|
||||
const configurationIdentifier: ConfigurationIdentifier = {
|
||||
domain: ConfigurationDomain.CARPOOL,
|
||||
const identifier: Identifier = {
|
||||
domain: Domain.CARPOOL,
|
||||
key: 'seatsProposed',
|
||||
};
|
||||
const configurationType: ConfigurationType =
|
||||
configurationsManagerService.identifierType(configurationIdentifier);
|
||||
expect(configurationType).toBe(ConfigurationType.INT);
|
||||
const type: Type =
|
||||
configurationsManagerService.identifierType(identifier);
|
||||
expect(type).toBe(Type.INT);
|
||||
});
|
||||
it('should throw if configuration item is not found', () => {
|
||||
const configurationIdentifier: ConfigurationIdentifier = {
|
||||
domain: ConfigurationDomain.MATCH,
|
||||
const dentifier: Identifier = {
|
||||
domain: Domain.MATCH,
|
||||
key: 'maxDetour',
|
||||
};
|
||||
expect(() => {
|
||||
configurationsManagerService.identifierType(configurationIdentifier);
|
||||
configurationsManagerService.identifierType(dentifier);
|
||||
}).toThrow(NotFoundException);
|
||||
});
|
||||
});
|
||||
|
||||
describe('configurationType', () => {
|
||||
describe('Type', () => {
|
||||
it('should return the configuration type of an int', () => {
|
||||
expect(configurationsManagerService.configurationType(3)).toBe(
|
||||
ConfigurationType.INT,
|
||||
);
|
||||
expect(configurationsManagerService.configurationType(3)).toBe(Type.INT);
|
||||
});
|
||||
it('should return the configuration type of a float', () => {
|
||||
expect(configurationsManagerService.configurationType(3.5)).toBe(
|
||||
ConfigurationType.FLOAT,
|
||||
Type.FLOAT,
|
||||
);
|
||||
});
|
||||
it('should return the configuration type of a boolean', () => {
|
||||
expect(configurationsManagerService.configurationType(true)).toBe(
|
||||
ConfigurationType.BOOLEAN,
|
||||
Type.BOOLEAN,
|
||||
);
|
||||
});
|
||||
it('should return the configuration type of a string', () => {
|
||||
expect(configurationsManagerService.configurationType('role')).toBe(
|
||||
ConfigurationType.STRING,
|
||||
Type.STRING,
|
||||
);
|
||||
});
|
||||
it('should return the configuration type of a string array', () => {
|
||||
expect(
|
||||
configurationsManagerService.configurationType(['test', 'test2']),
|
||||
).toBe(Type.STRING_ARRAY);
|
||||
expect(configurationsManagerService.configurationType('test,test2')).toBe(
|
||||
Type.STRING_ARRAY,
|
||||
);
|
||||
});
|
||||
it('should return the configuration type of an int array', () => {
|
||||
expect(configurationsManagerService.configurationType([2, 3])).toBe(
|
||||
Type.INT_ARRAY,
|
||||
);
|
||||
});
|
||||
it('should return the configuration type of a float array', () => {
|
||||
expect(configurationsManagerService.configurationType([1.2, 3.6])).toBe(
|
||||
Type.FLOAT_ARRAY,
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('cast', () => {
|
||||
it('should cast a string to int', () => {
|
||||
expect(
|
||||
configurationsManagerService.cast('1', ConfigurationType.INT),
|
||||
).toBe(1);
|
||||
expect(configurationsManagerService.cast('1', Type.INT)).toBe(1);
|
||||
});
|
||||
it('should cast a string to float', () => {
|
||||
expect(
|
||||
configurationsManagerService.cast('1.5', ConfigurationType.FLOAT),
|
||||
).toBe(1.5);
|
||||
expect(configurationsManagerService.cast('1.5', Type.FLOAT)).toBe(1.5);
|
||||
});
|
||||
it('should cast a string to boolean', () => {
|
||||
expect(
|
||||
configurationsManagerService.cast('true', ConfigurationType.BOOLEAN),
|
||||
configurationsManagerService.cast('true', Type.BOOLEAN),
|
||||
).toBeTruthy();
|
||||
});
|
||||
it('should not cast a string and return it as is', () => {
|
||||
expect(configurationsManagerService.cast('role', Type.STRING)).toBe(
|
||||
'role',
|
||||
);
|
||||
});
|
||||
it('should cast a string to an array of strings', () => {
|
||||
expect(
|
||||
configurationsManagerService.cast('role', ConfigurationType.STRING),
|
||||
).toBe('role');
|
||||
configurationsManagerService.cast('test,test2', Type.STRING_ARRAY),
|
||||
).toStrictEqual(['test', 'test2']);
|
||||
});
|
||||
it('should cast a string to an array of ints', () => {
|
||||
expect(
|
||||
configurationsManagerService.cast('1,2', Type.INT_ARRAY),
|
||||
).toStrictEqual([1, 2]);
|
||||
});
|
||||
it('should cast a string to an array of floats', () => {
|
||||
expect(
|
||||
configurationsManagerService.cast('1.2,2.3', Type.FLOAT_ARRAY),
|
||||
).toStrictEqual([1.2, 2.3]);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -2,21 +2,17 @@ import { Test, TestingModule } from '@nestjs/testing';
|
|||
import { GetConfigurationQueryHandler } from '@modules/configuration/core/application/queries/get-configuration/get-configuration.query-handler';
|
||||
import { CONFIGURATION_REPOSITORY } from '@modules/configuration/configuration.di-tokens';
|
||||
import { GetConfigurationQuery } from '@modules/configuration/core/application/queries/get-configuration/get-configuration.query';
|
||||
import {
|
||||
ConfigurationDomain,
|
||||
ConfigurationType,
|
||||
ConfigurationValue,
|
||||
} from '@mobicoop/configuration-module';
|
||||
import { Domain, Type, Value } from '@mobicoop/configuration-module';
|
||||
import { ConfigurationsManagerService } from '@modules/configuration/core/application/services/configurations-manager.service';
|
||||
|
||||
const configurationValue: ConfigurationValue = '3';
|
||||
const value: Value = '3';
|
||||
|
||||
const mockConfigurationRepository = {
|
||||
get: jest.fn().mockImplementation(() => configurationValue),
|
||||
get: jest.fn().mockImplementation(() => value),
|
||||
};
|
||||
|
||||
const mockConfigurationsManagerService = {
|
||||
identifierType: jest.fn().mockImplementation(() => ConfigurationType.INT),
|
||||
identifierType: jest.fn().mockImplementation(() => Type.INT),
|
||||
};
|
||||
|
||||
describe('Get Configuration Query Handler', () => {
|
||||
|
@ -49,12 +45,13 @@ describe('Get Configuration Query Handler', () => {
|
|||
describe('execution', () => {
|
||||
it('should return a configuration value', async () => {
|
||||
const getConfigurationQuery = new GetConfigurationQuery(
|
||||
ConfigurationDomain.CARPOOL,
|
||||
Domain.CARPOOL,
|
||||
'seatsProposed',
|
||||
);
|
||||
const configurationValue: ConfigurationValue =
|
||||
await getConfigurationQueryHandler.execute(getConfigurationQuery);
|
||||
expect(configurationValue).toBe('3');
|
||||
const value: Value = await getConfigurationQueryHandler.execute(
|
||||
getConfigurationQuery,
|
||||
);
|
||||
expect(value).toBe('3');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -1,7 +1,4 @@
|
|||
import {
|
||||
ConfigurationDomain,
|
||||
NotFoundException,
|
||||
} from '@mobicoop/configuration-module';
|
||||
import { Domain, NotFoundException } from '@mobicoop/configuration-module';
|
||||
import { CONFIGURATION_REPOSITORY } from '@modules/configuration/configuration.di-tokens';
|
||||
import { ConfigurationsManagerService } from '@modules/configuration/core/application/services/configurations-manager.service';
|
||||
import { PopulateService } from '@modules/configuration/core/application/services/populate.service';
|
||||
|
@ -20,7 +17,7 @@ const mockConfigurationRepository = {
|
|||
const mockConfigurationsManagerService = {
|
||||
list: jest.fn().mockImplementation(() => [
|
||||
{
|
||||
domain: ConfigurationDomain.CARPOOL,
|
||||
domain: Domain.CARPOOL,
|
||||
departureTimeMargin: 900,
|
||||
role: 'passenger',
|
||||
seatsProposed: 3,
|
||||
|
@ -28,7 +25,7 @@ const mockConfigurationsManagerService = {
|
|||
strictFrequency: false,
|
||||
},
|
||||
{
|
||||
domain: ConfigurationDomain.PAGINATION,
|
||||
domain: Domain.PAGINATION,
|
||||
perPage: 10,
|
||||
},
|
||||
]),
|
||||
|
|
|
@ -3,14 +3,11 @@ import { SetConfigurationRequestDto } from '@modules/configuration/interface/grp
|
|||
import { SetConfigurationService } from '@modules/configuration/core/application/commands/set-configuration/set-configuration.service';
|
||||
import { CONFIGURATION_REPOSITORY } from '@modules/configuration/configuration.di-tokens';
|
||||
import { SetConfigurationCommand } from '@modules/configuration/core/application/commands/set-configuration/set-configuration.command';
|
||||
import {
|
||||
ConfigurationDomain,
|
||||
ConfigurationType,
|
||||
} from '@mobicoop/configuration-module';
|
||||
import { Domain, Type } from '@mobicoop/configuration-module';
|
||||
import { ConfigurationsManagerService } from '@modules/configuration/core/application/services/configurations-manager.service';
|
||||
|
||||
const setConfigurationRequest: SetConfigurationRequestDto = {
|
||||
domain: ConfigurationDomain.CARPOOL,
|
||||
domain: Domain.CARPOOL,
|
||||
key: 'seatsProposed',
|
||||
value: '3',
|
||||
};
|
||||
|
@ -25,7 +22,7 @@ const mockConfigurationRepository = {
|
|||
};
|
||||
|
||||
const mockConfigurationsManagerService = {
|
||||
identifierType: jest.fn().mockImplementation(() => ConfigurationType.INT),
|
||||
identifierType: jest.fn().mockImplementation(() => Type.INT),
|
||||
cast: jest.fn().mockImplementation(() => 3),
|
||||
};
|
||||
|
||||
|
@ -58,7 +55,7 @@ describe('Set Configuration Service', () => {
|
|||
|
||||
describe('execution', () => {
|
||||
const setConfigurationCommand = new SetConfigurationCommand({
|
||||
configurationIdentifier: {
|
||||
identifier: {
|
||||
domain: setConfigurationRequest.domain,
|
||||
key: setConfigurationRequest.key,
|
||||
},
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { ConfigurationDomain } from '@mobicoop/configuration-module';
|
||||
import { Domain } from '@mobicoop/configuration-module';
|
||||
import { NotFoundException, RpcExceptionCode } from '@mobicoop/ddd-library';
|
||||
import { ConfigurationMapper } from '@modules/configuration/configuration.mapper';
|
||||
import { GetConfigurationGrpcController } from '@modules/configuration/interface/grpc-controllers/get-configuration.grpc.controller';
|
||||
|
@ -20,7 +20,7 @@ const mockQueryBus = {
|
|||
|
||||
const mockConfigurationMapper = {
|
||||
toResponse: jest.fn().mockImplementationOnce(() => ({
|
||||
domain: ConfigurationDomain.CARPOOL,
|
||||
domain: Domain.CARPOOL,
|
||||
key: 'seatsProposed',
|
||||
value: '3',
|
||||
})),
|
||||
|
@ -61,7 +61,7 @@ describe('Get Configuration Grpc Controller', () => {
|
|||
jest.spyOn(mockQueryBus, 'execute');
|
||||
jest.spyOn(mockConfigurationMapper, 'toResponse');
|
||||
const response = await getConfigurationGrpcController.get({
|
||||
domain: ConfigurationDomain.CARPOOL,
|
||||
domain: Domain.CARPOOL,
|
||||
key: 'seatsProposed',
|
||||
});
|
||||
expect(response.value).toBe('3');
|
||||
|
@ -75,7 +75,7 @@ describe('Get Configuration Grpc Controller', () => {
|
|||
expect.assertions(4);
|
||||
try {
|
||||
await getConfigurationGrpcController.get({
|
||||
domain: ConfigurationDomain.CARPOOL,
|
||||
domain: Domain.CARPOOL,
|
||||
key: 'price',
|
||||
});
|
||||
} catch (e: any) {
|
||||
|
@ -92,7 +92,7 @@ describe('Get Configuration Grpc Controller', () => {
|
|||
expect.assertions(4);
|
||||
try {
|
||||
await getConfigurationGrpcController.get({
|
||||
domain: ConfigurationDomain.CARPOOL,
|
||||
domain: Domain.CARPOOL,
|
||||
key: 'someValue',
|
||||
});
|
||||
} catch (e: any) {
|
||||
|
|
|
@ -1,7 +1,4 @@
|
|||
import {
|
||||
ConfigurationDomain,
|
||||
ConfigurationIdentifier,
|
||||
} from '@mobicoop/configuration-module';
|
||||
import { Domain, Identifier } from '@mobicoop/configuration-module';
|
||||
import { RpcExceptionCode } from '@mobicoop/ddd-library';
|
||||
import { SetConfigurationRequestDto } from '@modules/configuration/interface/grpc-controllers/dtos/set-configuration.request.dto';
|
||||
import { SetConfigurationGrpcController } from '@modules/configuration/interface/grpc-controllers/set-configuration.grpc.controller';
|
||||
|
@ -10,7 +7,7 @@ import { RpcException } from '@nestjs/microservices';
|
|||
import { Test, TestingModule } from '@nestjs/testing';
|
||||
|
||||
const setConfigurationRequest: SetConfigurationRequestDto = {
|
||||
domain: ConfigurationDomain.CARPOOL,
|
||||
domain: Domain.CARPOOL,
|
||||
key: 'seatsProposed',
|
||||
value: '3',
|
||||
};
|
||||
|
@ -19,7 +16,7 @@ const mockCommandBus = {
|
|||
execute: jest
|
||||
.fn()
|
||||
.mockImplementationOnce(() => ({
|
||||
domain: ConfigurationDomain.CARPOOL,
|
||||
domain: Domain.CARPOOL,
|
||||
key: 'seatsProposed',
|
||||
}))
|
||||
.mockImplementationOnce(() => {
|
||||
|
@ -56,9 +53,10 @@ describe('Set Configuration Grpc Controller', () => {
|
|||
|
||||
it('should set a configuration item', async () => {
|
||||
jest.spyOn(mockCommandBus, 'execute');
|
||||
const configurationIdentifier: ConfigurationIdentifier =
|
||||
await setConfigurationGrpcController.set(setConfigurationRequest);
|
||||
expect(configurationIdentifier.key).toBe('seatsProposed');
|
||||
const identifier: Identifier = await setConfigurationGrpcController.set(
|
||||
setConfigurationRequest,
|
||||
);
|
||||
expect(identifier.key).toBe('seatsProposed');
|
||||
expect(mockCommandBus.execute).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
|
|
Loading…
Reference in New Issue