Skip to content

Commit

Permalink
test: progress
Browse files Browse the repository at this point in the history
  • Loading branch information
CptSchnitz committed Jul 7, 2024
1 parent 567d2a3 commit c1fdff2
Show file tree
Hide file tree
Showing 8 changed files with 5,134 additions and 3,008 deletions.
7,948 changes: 4,954 additions & 2,994 deletions package-lock.json

Large diffs are not rendered by default.

4 changes: 4 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
"prelint": "npm run format",
"lint": "eslint .",
"lint:fix": "eslint --fix .",
"test": "jest --config=./tests/configurations/jest.config.js",
"prebuild": "npm run clean",
"build": "tsc --project tsconfig.build.json",
"start": "npm run build && cd dist && node ./index.js",
Expand Down Expand Up @@ -65,13 +66,16 @@
"@map-colonies/eslint-config": "^4.0.0",
"@types/config": "^3.3.4",
"@types/debug": "^4.1.12",
"@types/jest": "^29.5.12",
"@types/node": "^14.14.12",
"commitlint": "^11.0.0",
"cz-conventional-changelog": "^3.3.0",
"eslint": "^8.56.0",
"husky": "^4.3.5",
"jest": "^29.7.0",
"prettier": "^2.2.1",
"pretty-quick": "^3.1.0",
"ts-jest": "^29.1.5",
"typescript": "^5.4.5"
}
}
1 change: 0 additions & 1 deletion src/httpClient.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import assert from 'node:assert';
import { Dispatcher, request } from 'undici';
import StatusCodes from 'http-status-codes';
import { getOptions } from './options';
Expand Down
29 changes: 16 additions & 13 deletions src/options.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,24 +6,27 @@ import { createConfigError } from './errors';

const debug = createDebug('options');

const envOptions: Partial<Record<keyof BaseOptions, string>> = {
configName: process.env.CONFIG_NAME,
configServerUrl: process.env.CONFIG_SERVER_URL,
version: process.env.CONFIG_VERSION,
offlineMode: process.env.CONFIG_OFFLINE_MODE,
ignoreServerIsOlderVersionError: process.env.CONFIG_IGNORE_SERVER_IS_OLDER_VERSION_ERROR,
};

// in order to merge correctly the keys should not exist, undefined is not enough
for (const key in envOptions) {
if (envOptions[key as keyof BaseOptions] === undefined) {
delete envOptions[key as keyof BaseOptions];
function getEnvOptions(): Partial<Record<keyof BaseOptions, string>> {
const envOptions: Partial<Record<keyof BaseOptions, string>> = {
configName: process.env.CONFIG_NAME,
configServerUrl: process.env.CONFIG_SERVER_URL,
version: process.env.CONFIG_VERSION,
offlineMode: process.env.CONFIG_OFFLINE_MODE,
ignoreServerIsOlderVersionError: process.env.CONFIG_IGNORE_SERVER_IS_OLDER_VERSION_ERROR,
};

// in order to merge correctly the keys should not exist, undefined is not enough
for (const key in envOptions) {
if (envOptions[key as keyof BaseOptions] === undefined) {
delete envOptions[key as keyof BaseOptions];
}
}
return envOptions;
}

let baseOptions: BaseOptions | undefined = undefined;

export function initializeOptions(options: Partial<BaseOptions>): BaseOptions {
const envOptions = getEnvOptions();
debug('initializing options with %j and env %j', options, envOptions);
const mergedOptions = deepmerge(options, envOptions);

Expand Down
31 changes: 31 additions & 0 deletions tests/configurations/jest.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
module.exports = {
transform: {
'^.+\\.ts$': ['ts-jest', { tsconfig: 'tsconfig.json' }],
},
coverageReporters: ['text', 'html'],
collectCoverage: true,
collectCoverageFrom: ['<rootDir>/src/**/*.ts', '!*/node_modules/', '!/vendor/**', '!*/common/**', '!**/models/**', '!<rootDir>/src/*'],
coverageDirectory: '<rootDir>/coverage',
rootDir: '../../.',
testMatch: ['<rootDir>/tests/**/*.spec.ts'],
// setupFiles: ['<rootDir>/tests/configurations/jest.setup.ts'],
// setupFilesAfterEnv: ['jest-openapi', '<rootDir>/tests/configurations/initJestOpenapi.setup.ts'],
// reporters: [
// 'default',
// [
// 'jest-html-reporters',
// { multipleReportsUnitePath: './reports', pageTitle: 'integration', publicPath: './reports', filename: 'integration.html' },
// ],
// ],
moduleDirectories: ['node_modules', 'src'],
preset: 'ts-jest',
testEnvironment: 'node',
coverageThreshold: {
global: {
branches: 80,
functions: 80,
lines: 80,
statements: -10,
},
},
};
64 changes: 64 additions & 0 deletions tests/schemas.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
import type { JSONSchema } from '@apidevtools/json-schema-ref-parser';
import { loadSchema } from '../src/schemas';

describe('schemas', () => {
describe('#loadSchema', () => {
it('should load the schema', async () => {
const schema = {
$id: 'https://mapcolonies.com/test',
type: 'object',
properties: {
foo: { type: 'string' },
},
required: ['foo'],
} satisfies JSONSchema;
const dereferencedSchema = await loadSchema(schema);
expect(dereferencedSchema).toEqual(schema);
});

it('should load the schema with a reference', async () => {
const schema = {
$id: 'https://mapcolonies.com/common/db/full/v1',
description: 'The full database schema including schema and database name',
type: 'object',
allOf: [
{
$ref: 'https://mapcolonies.com/common/db/partial/v1',
},
{
$ref: '#/definitions/db',
},
],
definitions: {
db: {
type: 'object',
required: ['database'],
properties: {
schema: {
type: 'string',
description: 'The schema name of the database',
default: 'public',
},
database: {
type: 'string',
description: 'The database name',
maxLength: 63,
},
},
},
},
} satisfies JSONSchema;

const dereferencedSchema = await loadSchema(schema);

expect(dereferencedSchema).toEqual({
$id: 'https://mapcolonies.com/test',
type: 'object',
properties: {
foo: { type: 'string' },
},
required: ['foo'],
});
});
});
});
64 changes: 64 additions & 0 deletions tests/validator.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
import { validate, ajvOptionsValidator, ajvConfigValidator } from '../src/validator';

describe('validator', () => {
describe('#validate', () => {
it('should return the validated data if the data is valid', () => {
const schema = {
type: 'object',
properties: {
foo: { type: 'string' },
},
required: ['foo'],
};
const data = { foo: 'bar' };
const [errors, validatedData] = validate(ajvOptionsValidator, schema, data);
expect(errors).toBeUndefined();
expect(validatedData).toEqual(data);
});

it('should return the errors if the data is invalid', () => {
const schema = {
type: 'object',
properties: {
foo: { type: 'string' },
},
required: ['foo'],
};
const data = {};
const [errors, validatedData] = validate(ajvOptionsValidator, schema, data);
expect(errors).toBeDefined();
expect(validatedData).toBeUndefined();
});

it('should coerce types and insert defaults if options validator is used', () => {
const schema = {
type: 'object',
properties: {
foo: { type: 'number' },
bar: { type: 'string', default: 'baz' },
},
required: ['foo'],
};
const data = { foo: '1' };
const [errors, validatedData] = validate(ajvOptionsValidator, schema, data);
expect(errors).toBeUndefined();
expect(validatedData).toEqual({ foo: 1, bar: 'baz' });
});

it('should insert defaults and allow x-env-value keyword if config validator is used', () => {
const schema = {
type: 'object',
properties: {
foo: { type: 'number', default: 1 },
// eslint-disable-next-line @typescript-eslint/naming-convention
bar: { type: 'string', 'x-env-value': 'BAR' },
},
required: ['foo'],
};
const data = {};
const [errors, validatedData] = validate(ajvConfigValidator, schema, data);
expect(errors).toBeUndefined();
expect(validatedData).toEqual({ foo: 1 });
});
});
});
1 change: 1 addition & 0 deletions tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
"allowSyntheticDefaultImports": true,
"strict": true,
"module": "NodeNext",
"esModuleInterop": true,
"moduleResolution": "NodeNext",
"resolveJsonModule": true,
"outDir": "dist",
Expand Down

0 comments on commit c1fdff2

Please sign in to comment.