Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
8267f00
feat(common/utils): added RequireKeys utility type
NivGreenstein Oct 21, 2024
196fe3c
fix(tile/queries): changed param type to only require tile and subTile
NivGreenstein Oct 21, 2024
cfaf429
fix(contro/utils): changed max_score type to only be a number
NivGreenstein Oct 21, 2024
ba02809
feat: moved all mock objects under one folder at the top of tests dir…
NivGreenstein Oct 21, 2024
78981de
fix: removed mockOjbects and update import to the new directory
NivGreenstein Oct 21, 2024
e5c2fe8
feat(unit/control/tile): created unit tests
NivGreenstein Oct 21, 2024
fc25fbc
feat(tests/unit/control/utils): created unit tests
NivGreenstein Oct 21, 2024
57cc151
fix: changed unit test to only unit test tileManager.
NivGreenstein Oct 21, 2024
abc974e
fix: ignore DAL folders
NivGreenstein Oct 21, 2024
779bd00
fix: fixed mgrs routers directory name
NivGreenstein Oct 21, 2024
c0bc840
fix: added back elasticResponse.hits.max_score ?? 0
NivGreenstein Oct 21, 2024
6722ef5
fix: removed unused try-catch condition
NivGreenstein Oct 21, 2024
6ae3c3b
fix: removed unused properties
NivGreenstein Oct 21, 2024
57dae55
delete: removed duplicated test
NivGreenstein Oct 21, 2024
020819b
feat(tests/control/route): added unit test
NivGreenstein Oct 21, 2024
2407425
fix: added missing property
NivGreenstein Oct 21, 2024
ea0f414
delete: removed comment
NivGreenstein Oct 21, 2024
436c568
fix: fixed typo
NivGreenstein Oct 21, 2024
67dbfe3
fix: fixed logger.error message to msg. changed logger.warn to logger…
NivGreenstein Oct 21, 2024
b78e5c0
feat(control/unit/item): created unit tests
NivGreenstein Oct 21, 2024
6906960
fix: changed error to explicitly throw BadRequestError
NivGreenstein Oct 21, 2024
05fdf9b
fix: fixed expected error
NivGreenstein Oct 21, 2024
5527193
feat(tests/unit/mgrs): unit tests created
NivGreenstein Oct 21, 2024
e415ab4
fix: fixed GenericGeocodingFeatureResponse to inherit the Feture type…
NivGreenstein Oct 21, 2024
3aec896
fix: fixed returned value accoriding to the type
NivGreenstein Oct 21, 2024
ba62404
fix(tests/unit/mgrs): fixed test
NivGreenstein Oct 21, 2024
19b362b
feat(tests/unit/latLon): created unit tests
NivGreenstein Oct 21, 2024
03fe36c
fix: fixed tests to new type response
NivGreenstein Oct 21, 2024
a06011c
delete: removed duplicated tests
NivGreenstein Oct 21, 2024
22bdc7c
feat(tests/unit/location): created unit tests
NivGreenstein Oct 21, 2024
e8c91c1
chore: moved cleanQuery function location
NivGreenstein Oct 21, 2024
4d361cf
chore: added test case variety
NivGreenstein Oct 23, 2024
62b8392
fix: changed to also include highlight test-case
NivGreenstein Oct 23, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions devScripts/geotextElasticsearchData.json
Original file line number Diff line number Diff line change
Expand Up @@ -58,8 +58,8 @@
"geometry_hash": "f14be42df6ec5cf2290d764a89e3009b",
"region": ["USA"],
"sub_region": ["New York"],
"name": "JFK",
"text": ["JFK Airport"],
"name": "JFK International Airport",
"text": ["JFK International Airport", "John F Kennedy International Airport"],
"translated_text": ["Aeropuerto JFK"],
"text_language": "en"
}
Expand Down
3 changes: 2 additions & 1 deletion src/common/interfaces.ts
Original file line number Diff line number Diff line change
Expand Up @@ -109,4 +109,5 @@ export interface GenericGeocodingResponse<T extends Feature, G = any> extends Fe
})[];
}

export type GenericGeocodingFeatureResponse = Feature & Pick<GenericGeocodingResponse<Feature>, 'geocoding'>;
export type GenericGeocodingFeatureResponse = GenericGeocodingResponse<Feature>['features'][number] &
Pick<GenericGeocodingResponse<Feature>, 'geocoding'>;
2 changes: 1 addition & 1 deletion src/common/middlewares/feedbackApi.middleware.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ export class FeedbackApiMiddlewareManager {
.then(() => {
logger.info({ msg: `response ${reqId?.toString() ?? ''} saved to redis` });
})
.catch((error: Error) => logger.error({ message: 'Error setting key:', error }));
.catch((error: Error) => logger.error({ msg: 'Error setting key:', error }));

return originalJson.call(this, body);
};
Expand Down
2 changes: 1 addition & 1 deletion src/common/redis/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,6 @@ export const redisClientFactory: FactoryFunction<RedisClient | undefined> = (con
.on('ready', (...args) => logger.debug({ msg: 'redis client is ready', ...args }));
return redisClient;
} catch (error) {
logger.error({ message: 'Connection to Redis was unsuccessful', error });
logger.error({ msg: 'Connection to Redis was unsuccessful', error });
}
};
2 changes: 1 addition & 1 deletion src/common/s3/s3Repository.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ const createS3Repository = (s3Client: S3Client, config: IConfig, logger: Logger)

return filePath;
} catch (error) {
logger.error({ message: `Error while downloading ${key}'s data from S3.`, error });
logger.error({ msg: `Error while downloading ${key}'s data from S3.`, error });
throw error;
}
},
Expand Down
4 changes: 3 additions & 1 deletion src/common/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,8 @@ export type RemoveUnderscore<T> = {
[K in keyof T as K extends `_${infer Rest}` ? Rest : K]: T[K];
};

export type RequireKeys<T extends object, K extends keyof T> = Required<Pick<T, K>> & Omit<T, K>;

export const validateWGS84Coordinate = (coordinate: { lon: number; lat: number }): boolean => {
// eslint-disable-next-line @typescript-eslint/no-magic-numbers
const [min, max] = [0, 180];
Expand Down Expand Up @@ -216,7 +218,7 @@ export const healthCheckFactory: FactoryFunction<void> = (container: DependencyC
return;
})
.catch((error: Error) => {
logger.error({ message: `Healthcheck failed for ${key}.`, error });
logger.error({ msg: `Healthcheck failed for ${key}.`, error });
});
}

Expand Down
10 changes: 5 additions & 5 deletions src/containerConfig.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ import { RedisClient, redisClientFactory } from './common/redis';
import { s3ClientFactory } from './common/s3';
import { S3_REPOSITORY_SYMBOL, s3RepositoryFactory } from './common/s3/s3Repository';
import { healthCheckFactory } from './common/utils';
import { MGRS_ROUTER_SYMBOL, mgrsRouterFactory } from './mgrs/routers/mgrsRouter';
import { MGRS_ROUTER_SYMBOL, mgrsRouterFactory } from './mgrs/routes/mgrsRouter';

export interface RegisterOptions {
override?: InjectionObject<unknown>[];
Expand Down Expand Up @@ -79,7 +79,7 @@ export const registerExternalValues = async (options?: RegisterOptions): Promise
const response = await Promise.all([elasticClients.control.ping(), elasticClients.geotext.ping()]);
response.forEach((res) => {
if (!res) {
logger.error({ message: 'Failed to connect to Elasticsearch', res });
logger.error({ msg: 'Failed to connect to Elasticsearch', res });
}
});
cleanupRegistry.register({
Expand All @@ -90,7 +90,7 @@ export const registerExternalValues = async (options?: RegisterOptions): Promise
id: SERVICES.ELASTIC_CLIENTS,
});
} catch (error) {
logger.error({ message: 'Failed to connect to Elasticsearch', error });
logger.error({ msg: 'Failed to connect to Elasticsearch', error });
}
},
},
Expand All @@ -103,7 +103,7 @@ export const registerExternalValues = async (options?: RegisterOptions): Promise
await s3Client.send(new ListBucketsCommand({}));
logger.info('Connected to S3');
} catch (error) {
logger.error({ message: 'Failed to connect to S3', error });
logger.error({ msg: 'Failed to connect to S3', error });
}
cleanupRegistry.register({
func: async () => {
Expand Down Expand Up @@ -160,7 +160,7 @@ export const registerExternalValues = async (options?: RegisterOptions): Promise
cleanupRegistry.register({ func: redis.disconnect.bind(redis), id: SERVICES.REDIS });
await redis.connect();
} catch (error) {
logger.error({ message: 'Connection to redis failed', error });
logger.error({ msg: 'Connection to redis failed', error });
}
},
},
Expand Down
2 changes: 1 addition & 1 deletion src/control/item/controllers/itemController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ export class ItemController {
});
return res.status(httpStatus.OK).json(response);
} catch (error: unknown) {
this.logger.warn('itemController.getItems Error:', error);
this.logger.error({ msg: 'itemController.getItems error', error });
next(error);
}
};
Expand Down
2 changes: 1 addition & 1 deletion src/control/route/controllers/routeController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ export class RouteController {
});
return res.status(httpStatus.OK).json(response);
} catch (error: unknown) {
this.logger.warn('routeController.getRoutes Error:', error);
this.logger.error({ msg: 'routeController.getRoutes error', error });
next(error);
}
};
Expand Down
1 change: 1 addition & 0 deletions src/control/route/models/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ export interface Route extends Feature {
properties: GeoJsonProperties & {
TYPE: 'ROUTE';
OBJECT_COMMAND_NAME: string;
TIED_TO?: string;
ENTITY_HEB: string;
LAYER_NAME: string;
};
Expand Down
4 changes: 2 additions & 2 deletions src/control/tile/DAL/queries.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { estypes } from '@elastic/elasticsearch';
import { BBox } from 'geojson';
import { CommonRequestParameters } from '../../../common/interfaces';
import { ELASTIC_KEYWORDS } from '../../constants';
import { ConvertSnakeToCamelCase, geoContextQuery, parseGeo } from '../../../common/utils';
import { ConvertSnakeToCamelCase, geoContextQuery, parseGeo, RequireKeys } from '../../../common/utils';

export interface TileQueryParams extends ConvertSnakeToCamelCase<CommonRequestParameters> {
tile?: string;
Expand Down Expand Up @@ -46,7 +46,7 @@ export const queryForSubTiles = ({
geoContextMode,
subTile,
disableFuzziness,
}: Omit<Required<TileQueryParams>, 'mgrs'>): estypes.SearchRequest => ({
}: RequireKeys<Omit<TileQueryParams, 'mgrs'>, 'tile' | 'subTile'>): estypes.SearchRequest => ({
query: {
bool: {
must: [
Expand Down
2 changes: 1 addition & 1 deletion src/control/tile/controllers/tileController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ export class TileController {
});
return res.status(httpStatus.OK).json(response);
} catch (error: unknown) {
this.logger.warn('tileController.getTiles Error:', error);
this.logger.error({ msg: 'tileController.getTiles', error });
next(error);
}
};
Expand Down
5 changes: 0 additions & 5 deletions src/control/tile/models/tileManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,11 +35,6 @@ export class TileManager {
let bbox: BBox = [0, 0, 0, 0];
try {
bbox = mgrs.inverse(tileQueryParams.mgrs);
bbox.forEach((coord) => {
if (isNaN(coord)) {
throw new Error('Invalid MGRS');
}
});
} catch (error) {
throw new BadRequestError(`Invalid MGRS: ${tileQueryParams.mgrs}`);
}
Expand Down
8 changes: 4 additions & 4 deletions src/latLon/DAL/latLonDAL.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ export class LatLonDAL {
this.dataLoadError = false;

this.init().catch((error: Error) => {
this.logger.error({ message: 'Failed to initialize lat-lon data', error });
this.logger.error({ msg: 'Failed to initialize lat-lon data', error });
this.dataLoadError = true;
});
}
Expand Down Expand Up @@ -74,7 +74,7 @@ export class LatLonDAL {

this.logger.debug('latLonData initialized');
} catch (error) {
this.logger.error({ message: `Failed to initialize latLon data.`, error });
this.logger.error({ msg: `Failed to initialize latLon data.`, error });
this.dataLoadError = true;
} finally {
this.onGoingUpdate = false;
Expand Down Expand Up @@ -111,7 +111,7 @@ export class LatLonDAL {
try {
await fs.promises.unlink(latLonDataPath);
} catch (error) {
this.logger.error({ message: `Failed to delete latLonData file ${latLonDataPath}.`, error });
this.logger.error({ msg: `Failed to delete latLonData file ${latLonDataPath}.`, error });
}
this.logger.info('loadLatLonData: update completed');
}
Expand Down Expand Up @@ -147,7 +147,7 @@ export const cronLoadTileLatLonDataFactory: FactoryFunction<cron.ScheduledTask>
if (!latLonDAL.getOnGoingUpdate()) {
logger.info('cronLoadTileLatLonData: starting update');
latLonDAL.init().catch((error: Error) => {
logger.error({ message: 'cronLoadTileLatLonData: update failed', error });
logger.error({ msg: 'cronLoadTileLatLonData: update failed', error });
});
} else {
logger.info('cronLoadTileLatLonData: update is already in progress');
Expand Down
2 changes: 1 addition & 1 deletion src/latLon/controllers/latLonController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ export class LatLonController {

return res.status(httpStatus.OK).json(response);
} catch (error: unknown) {
this.logger.warn('latLonController.getCoordinates Error:', error);
this.logger.error({ msG: 'latLonController.getCoordinates error', error });
next(error);
}
};
Expand Down
37 changes: 29 additions & 8 deletions src/latLon/models/latLonManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,14 +26,14 @@ export class LatLonManager {

public async latLonToTile({ lat, lon, targetGrid }: WGS84Coordinate & { targetGrid: string }): Promise<GenericGeocodingFeatureResponse> {
if (!validateWGS84Coordinate({ lat, lon })) {
this.logger.warn("LatLonManager.latLonToTile: Invalid lat lon, check 'lat' and 'lon' keys exists and their values are legal");
this.logger.error({ msg: "LatLonManager.latLonToTile: Invalid lat lon, check 'lat' and 'lon' keys exists and their values are legal" });
throw new BadRequestError("Invalid lat lon, check 'lat' and 'lon' keys exists and their values are legal");
}

const utm = convertWgs84ToUTM({ longitude: lon, latitude: lat });

if (typeof utm === 'string') {
this.logger.warn('LatLonManager.latLonToTile: utm is string');
this.logger.error({ msg: 'LatLonManager.latLonToTile: utm is string' });
throw new BadRequestError('utm is string');
}

Expand All @@ -46,7 +46,7 @@ export class LatLonManager {
const tileCoordinateData = await this.latLonDAL.latLonToTile({ x: coordinatesUTM.x, y: coordinatesUTM.y, zone: coordinatesUTM.zone });

if (!tileCoordinateData) {
this.logger.warn('LatLonManager.latLonToTile: The coordinate is outside the grid extent');
this.logger.error({ msg: 'LatLonManager.latLonToTile: The coordinate is outside the grid extent' });
throw new BadRequestError('The coordinate is outside the grid extent');
}

Expand Down Expand Up @@ -89,7 +89,18 @@ export class LatLonManager {
coordinates: [lon, lat],
},
properties: {
name: tileCoordinateData.tile_name,
matches: [
{
layer: 'convertionTable',
source: 'mapcolonies',
// eslint-disable-next-line @typescript-eslint/naming-convention
source_id: [],
},
],
names: {
default: [tileCoordinateData.tile_name],
display: tileCoordinateData.tile_name,
},
tileName: tileCoordinateData.tile_name,
subTileNumber: new Array(SUB_TILE_LENGTH).fill('').map(function (value, i) {
return xNumber[i] + yNumber[i];
Expand All @@ -103,9 +114,7 @@ export class LatLonManager {
lon,
accuracy = MGRS_ACCURACY,
targetGrid,
}: {
lat: number;
lon: number;
}: WGS84Coordinate & {
accuracy?: number;
targetGrid: string;
}): GenericGeocodingFeatureResponse {
Expand Down Expand Up @@ -139,9 +148,21 @@ export class LatLonManager {
coordinates: [lon, lat],
},
properties: {
name: mgrsStr,
matches: [
{
layer: 'MGRS',
source: 'npm/MGRS',
// eslint-disable-next-line @typescript-eslint/naming-convention
source_id: [],
},
],
names: {
default: [mgrsStr],
display: mgrsStr,
},
accuracy: accuracyString[accuracy],
mgrs: mgrsStr,
score: 1,
},
};
}
Expand Down
9 changes: 6 additions & 3 deletions src/location/DAL/locationRepository.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { Logger } from '@map-colonies/js-logger';
import { estypes } from '@elastic/elasticsearch';
import { FactoryFunction } from 'tsyringe';
import { ElasticClient } from '../../common/elastic';
import { cleanQuery, fetchNLPService } from '../utils';
import { fetchNLPService } from '../utils';
import { TextSearchParams, TokenResponse } from '../interfaces';
import { PlaceTypeSearchHit, HierarchySearchHit, TextSearchHit } from '../models/elasticsearchHits';
import { BadRequestError } from '../../common/errors';
Expand All @@ -12,7 +12,10 @@ import { queryElastic } from '../../common/elastic/utils';
import { SERVICES } from '../../common/constants';
import { hierarchyQuery, placetypeQuery, geotextQuery } from './queries';

/* eslint-enable @typescript-eslint/naming-convention */
const FIND_QUOTES = /["']/g;

const FIND_SPECIAL = /[`!@#$%^&*()_\-+=|\\/,.<>:[\]{}\n\t\r\s;؛]+/g;
const cleanQuery = (query: string): string[] => query.replace(FIND_QUOTES, '').split(FIND_SPECIAL);

// eslint-disable-next-line @typescript-eslint/explicit-function-return-type
const createGeotextRepository = (client: ElasticClient, logger: Logger) => {
Expand All @@ -25,7 +28,7 @@ const createGeotextRepository = (client: ElasticClient, logger: Logger) => {

if (!tokens || !tokens.length || !prediction || !prediction.length) {
const message = 'No tokens or prediction';
logger.error({ message });
logger.error({ msg: message });
throw new BadRequestError(message);
}

Expand Down
2 changes: 1 addition & 1 deletion src/location/controllers/locationController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ export class GeotextSearchController {
const response = await this.manager.search({ query, region, source, disableFuzziness, geoContext, geoContextMode, limit });
return res.status(httpStatus.OK).json(response);
} catch (error: unknown) {
this.logger.error({ message: 'Error in getGeotextSearch', error });
this.logger.error({ msg: 'Error in getGeotextSearch', error });
next(error);
}
};
Expand Down
9 changes: 2 additions & 7 deletions src/location/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,11 @@ import { TextSearchParams } from './interfaces';
import { TextSearchHit } from './models/elasticsearchHits';
import { generateDisplayName } from './parsing';

const FIND_QUOTES = /["']/g;

const FIND_SPECIAL = /[`!@#$%^&*()_\-+=|\\/,.<>:[\]{}\n\t\r\s;؛]+/g;

const axiosInstance = axios.create({
httpsAgent: new https.Agent({ rejectUnauthorized: false }),
});

/* istanbul ignore next */
export const fetchNLPService = async <T>(endpoint: string, requestData: object): Promise<{ data: T[]; latency: number }> => {
let res: Response | null = null,
data: T[] | undefined | null = null;
Expand All @@ -38,8 +35,6 @@ export const fetchNLPService = async <T>(endpoint: string, requestData: object):
return { data, latency };
};

export const cleanQuery = (query: string): string[] => query.replace(FIND_QUOTES, '').split(FIND_SPECIAL);

/* eslint-disable @typescript-eslint/naming-convention */
export const convertResult = (
params: TextSearchParams,
Expand All @@ -61,7 +56,7 @@ export const convertResult = (
placeType: number;
hierarchies: number;
};
} = { nameKeys: [], mainLanguageRegex: '', externalResourcesLatency: { query: 0, nlpAnalyser: 0, placeType: 0, hierarchies: 0 } }
}
): GenericGeocodingResponse<Feature> => ({
type: 'FeatureCollection',
geocoding: {
Expand Down
2 changes: 1 addition & 1 deletion src/mgrs/controllers/mgrsController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ export class MgrsController {
const response = this.manager.getTile({ tile });
return res.status(httpStatus.OK).json(response);
} catch (error: unknown) {
this.logger.error({ message: 'MgrsController.getTile', error });
this.logger.error({ msg: 'MgrsController.getTile', error });
next(error);
}
};
Expand Down
Loading