-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
c1fdff2
commit 4f40d19
Showing
15 changed files
with
396 additions
and
30 deletions.
There are no files selected for viewing
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
import { Interceptable, MockAgent, setGlobalDispatcher } from 'undici'; | ||
import { commonDbPartialV1 } from '@map-colonies/schemas'; | ||
import { StatusCodes } from 'http-status-codes'; | ||
import { config } from '../src/config'; | ||
|
||
const URL = 'http://localhost:8080'; | ||
describe('config', () => { | ||
describe('#config', () => { | ||
describe('httpClient', () => { | ||
let client: Interceptable; | ||
beforeEach(() => { | ||
const agent = new MockAgent(); | ||
agent.disableNetConnect(); | ||
|
||
setGlobalDispatcher(agent); | ||
client = agent.get(URL); | ||
}); | ||
|
||
it('should return the config with all the default values', async () => { | ||
const configData = { | ||
configName: 'name', | ||
schemaId: commonDbPartialV1.$id, | ||
version: 1, | ||
config: { | ||
host: 'avi', | ||
}, | ||
createdAt: 0, | ||
}; | ||
|
||
client.intercept({ path: '/config/name/1?shouldDereference=true', method: 'GET' }).reply(StatusCodes.OK, configData); | ||
|
||
const configInstance = await config({ | ||
configName: 'name', | ||
version: 1, | ||
schema: commonDbPartialV1, | ||
configServerUrl: URL, | ||
localConfigPath: '../tests/config', | ||
}); | ||
|
||
const conf = configInstance.getAll(); | ||
|
||
expect(conf).toEqual({ | ||
host: 'avi', | ||
port: 5432, | ||
username: 'postgres', | ||
password: 'postgres', | ||
ssl: { | ||
enabled: false, | ||
} | ||
}); | ||
}); | ||
}); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
{ | ||
"ssl": { | ||
"enabled": false | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
{} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,107 @@ | ||
/* eslint-disable @typescript-eslint/naming-convention */ | ||
import { satisfies } from 'semver'; | ||
import { JSONSchema } from '@apidevtools/json-schema-ref-parser'; | ||
import { getEnvValues } from '../src/env'; | ||
import { EnvType } from '../src/types'; | ||
|
||
describe('env', () => { | ||
describe('#getEnvValues', () => { | ||
const OLD_ENV = process.env; | ||
|
||
beforeEach(() => { | ||
// jest.resetModules() // Most important - it clears the cache | ||
process.env = { ...OLD_ENV }; // Make a copy | ||
}); | ||
|
||
afterAll(() => { | ||
process.env = OLD_ENV; // Restore old environment | ||
}); | ||
|
||
it('should return the env values', () => { | ||
process.env.FOO = 'bar'; | ||
const schema = { | ||
type: 'object', | ||
properties: { | ||
foo: { type: 'string', 'x-env-value': 'FOO' }, | ||
}, | ||
required: ['foo'], | ||
} satisfies JSONSchema; | ||
|
||
const envValues = getEnvValues(schema); | ||
|
||
expect(envValues).toEqual({ foo: 'bar' }); | ||
}); | ||
|
||
it.each([ | ||
['string', 'bar', 'bar'], | ||
['boolean', 'true', true], | ||
['integer', '1', 1], | ||
['number', '1.5', 1.5], | ||
['null', 'null', null], | ||
])(`should return the env values for %s`, (type, value, expected) => { | ||
process.env.FOO = value; | ||
const schema = { | ||
type: 'object', | ||
properties: { | ||
foo: { type: type as EnvType, 'x-env-value': 'FOO' }, | ||
}, | ||
required: ['foo'], | ||
} satisfies JSONSchema; | ||
|
||
const envValues = getEnvValues(schema); | ||
|
||
expect(envValues).toEqual({ foo: expected }); | ||
}); | ||
|
||
it('should handle nested objects', () => { | ||
process.env.FOO = 'bar'; | ||
const schema = { | ||
type: 'object', | ||
properties: { | ||
foo: { type: 'object', properties: { baz: { type: 'string', 'x-env-value': 'FOO' } } }, | ||
}, | ||
required: ['foo'], | ||
} satisfies JSONSchema; | ||
|
||
const envValues = getEnvValues(schema); | ||
|
||
expect(envValues).toEqual({ foo: { baz: 'bar' } }); | ||
}); | ||
|
||
it('should not handle array or any type, or any object inside of an array', () => { | ||
process.env.FOO = 'bar'; | ||
process.env.BAZ = 'baz'; | ||
const schema = { | ||
type: 'object', | ||
properties: { | ||
foo: { type: 'array', 'x-env-value': 'FOO', items: { type: 'string', 'x-env-value': "BAZ" } }, | ||
}, | ||
required: ['foo'], | ||
} satisfies JSONSchema; | ||
|
||
const envValues = getEnvValues(schema); | ||
|
||
expect(envValues).toEqual({}); | ||
}); | ||
|
||
it('should handle values in composed objects', () => { | ||
process.env.FOO = 'bar'; | ||
const schema = { | ||
type: 'object', | ||
allOf: [ | ||
{ | ||
type: 'object', | ||
properties: { | ||
foo: { type: 'string', 'x-env-value': 'FOO' }, | ||
}, | ||
required: ['foo'], | ||
}, | ||
], | ||
} satisfies JSONSchema; | ||
|
||
const envValues = getEnvValues(schema); | ||
|
||
expect(envValues).toEqual({ foo: 'bar' }); | ||
}); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,91 @@ | ||
import { Interceptable, MockAgent, setGlobalDispatcher } from 'undici'; | ||
import { StatusCodes } from 'http-status-codes'; | ||
import { getRemoteConfig, getServerCapabilities } from '../src/httpClient'; | ||
import { getOptions } from '../src/options'; | ||
import { BaseOptions } from '../src/types'; | ||
|
||
jest.mock('../src/options'); | ||
|
||
const URL = 'http://localhost:8080'; | ||
|
||
const mockedGetOptions = getOptions as jest.MockedFunction<typeof getOptions>; | ||
|
||
mockedGetOptions.mockReturnValue({ | ||
configServerUrl: URL, | ||
} as BaseOptions); | ||
|
||
describe('httpClient', () => { | ||
let client: Interceptable; | ||
beforeEach(() => { | ||
const agent = new MockAgent(); | ||
agent.disableNetConnect(); | ||
|
||
setGlobalDispatcher(agent); | ||
client = agent.get(URL); | ||
}); | ||
|
||
describe('#getServerCapabilities', () => { | ||
it('should return the server capabilities', async () => { | ||
const capabilities = { serverVersion: '1.0.0', schemasPackageVersion: '1.0.0', pubSubEnabled: true }; | ||
|
||
client.intercept({ path: '/capabilities', method: 'GET' }).reply(StatusCodes.OK, capabilities); | ||
|
||
const result = await getServerCapabilities(); | ||
|
||
expect(result).toEqual(capabilities); | ||
}); | ||
|
||
it('should throw an error if the request fails', async () => { | ||
client.intercept({ path: '/capabilities', method: 'GET' }).reply(StatusCodes.INTERNAL_SERVER_ERROR, 'Internal Server Error'); | ||
|
||
await expect(getServerCapabilities()).rejects.toThrow('Failed to fetch'); | ||
}); | ||
|
||
it('should throw an error if the request fails to be sent', async () => { | ||
client.intercept({ path: '/capabilities', method: 'GET' }).replyWithError(new Error('oh noes')); | ||
|
||
await expect(getServerCapabilities()).rejects.toThrow('An error occurred while making the request'); | ||
}); | ||
}); | ||
|
||
describe('#getRemoteConfig', () => { | ||
it('should return the remote config', async () => { | ||
const config = { | ||
configName: 'name', | ||
schemaId: 'schema', | ||
version: 1, | ||
config: {}, | ||
createdAt: 0, | ||
}; | ||
|
||
client.intercept({ path: '/config/name/1?shouldDereference=true', method: 'GET' }).reply(StatusCodes.OK, config); | ||
|
||
const result = await getRemoteConfig('name', 1); | ||
expect(result).toEqual(config); | ||
}); | ||
|
||
it('should throw an error if the response is bad request', async () => { | ||
client.intercept({ path: '/config/name/1?shouldDereference=true', method: 'GET' }).reply(StatusCodes.BAD_REQUEST, 'Bad request'); | ||
|
||
await expect(getRemoteConfig('name', 1)).rejects.toThrow('Invalid request to getConfig'); | ||
}); | ||
|
||
it('should throw an error if the response is not found', async () => { | ||
client.intercept({ path: '/config/name/1?shouldDereference=true', method: 'GET' }).reply(StatusCodes.NOT_FOUND, 'Not found'); | ||
|
||
await expect(getRemoteConfig('name', 1)).rejects.toThrow('Config with given name and version was not found'); | ||
}); | ||
|
||
it('should throw an error if the request fails', async () => { | ||
client.intercept({ path: '/config/name/1?shouldDereference=true', method: 'GET' }).reply(StatusCodes.INTERNAL_SERVER_ERROR, 'Internal Server Error'); | ||
|
||
await expect(getRemoteConfig('name', 1)).rejects.toThrow('Failed to fetch'); | ||
}); | ||
|
||
it('should throw an error if the request fails to be sent', async () => { | ||
client.intercept({ path: '/config/name/1?shouldDereference=true', method: 'GET' }).replyWithError(new Error('oh noes')); | ||
|
||
await expect(getRemoteConfig('name', 1)).rejects.toThrow('An error occurred while making the request'); | ||
}); | ||
}); | ||
}); |
Oops, something went wrong.