Skip to content

Commit

Permalink
updated the mock to reduce into an object, slightly nicer API?
Browse files Browse the repository at this point in the history
  • Loading branch information
jloleysens committed Jun 14, 2023
1 parent c6bca36 commit e3d50a8
Show file tree
Hide file tree
Showing 2 changed files with 145 additions and 10 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -6,19 +6,77 @@
* Side Public License, v 1.
*/

import type { VersionedRouter, VersionedRoute } from '@kbn/core-http-server';
import type {
VersionedRouter,
VersionedRoute,
VersionedRouteConfig,
AddVersionOpts,
} from '@kbn/core-http-server';

const createMockVersionedRoute = (): VersionedRoute => {
const api: VersionedRoute = { addVersion: jest.fn(() => api) };
export type MockedVersionedRoute = jest.Mocked<VersionedRoute>;

const createMockVersionedRoute = (): MockedVersionedRoute => {
const addVersion = jest.fn((_, __) => api);
const api: MockedVersionedRoute = { addVersion };
return api;
};

export type MockedVersionedRouter = jest.Mocked<VersionedRouter<any>>;

export const createVersionedRouterMock = (): MockedVersionedRouter => ({
delete: jest.fn((_) => createMockVersionedRoute()),
get: jest.fn((_) => createMockVersionedRoute()),
patch: jest.fn((_) => createMockVersionedRoute()),
post: jest.fn((_) => createMockVersionedRoute()),
put: jest.fn((_) => createMockVersionedRoute()),
});
const createMethodHandler = () => jest.fn((_) => createMockVersionedRoute());

export const createVersionedRouterMock = (): MockedVersionedRouter & {
getRoute: (method: keyof VersionedRouter, path: string) => RegisteredVersionedRoute;
} => {
const router: MockedVersionedRouter = {
delete: createMethodHandler(),
get: createMethodHandler(),
patch: createMethodHandler(),
post: createMethodHandler(),
put: createMethodHandler(),
};

return {
...router,
getRoute: getRoute.bind(null, router),
};
};

interface RegisteredVersionedRoute {
config: VersionedRouteConfig<any>;
versions: { [version: string]: { config: AddVersionOpts<any, any, any>; handler: any } };
}
const getRoute = (
router: MockedVersionedRouter,
method: keyof VersionedRouter,
path: string
): RegisteredVersionedRoute => {
if (!router[method].mock.calls.length) {
throw new Error(`No routes registered for [${method.toUpperCase()} ${path}]`);
}

let route: undefined | RegisteredVersionedRoute;
for (let x = 0; x < router[method].mock.calls.length; x++) {
const [routeConfig] = router[method].mock.calls[x];
if (routeConfig.path === path) {
const mockedAddVersion = router[method].mock.results[x].value as MockedVersionedRoute;
route = {
config: routeConfig,
versions: mockedAddVersion.addVersion.mock.calls.reduce(
(acc, [config, handler]) => ({
...acc,
[config.version]: { config, handler },
}),
{}
),
};
break;
}
}

if (!route) {
throw new Error(`No routes registered for [${method.toUpperCase()} ${path}]`);
}

return route;
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/

import { createVersionedRouterMock } from './versioned_router.mock';

describe('createVersionedRouterMock#getRoute', () => {
it('throws if no routes are registered', () => {
const versionedRouter = createVersionedRouterMock();
expect(() => versionedRouter.getRoute('get', '/foo')).toThrow(/No routes registered/);
versionedRouter.get({ path: '/foo', access: 'internal' });
expect(() => versionedRouter.getRoute('get', '/foo')).not.toThrow();
expect(() => versionedRouter.getRoute('get', '/bar')).toThrow(/No routes registered/);
});
it('allows versioned routes to be introspected', () => {
const versionedRouter = createVersionedRouterMock();
const route = versionedRouter.get({ path: '/foo', access: 'internal' });

// Empty case
expect(versionedRouter.getRoute('get', '/foo')).toMatchInlineSnapshot(`
Object {
"config": Object {
"access": "internal",
"path": "/foo",
},
"versions": Object {},
}
`);

const myHandler = jest.fn();
route
.addVersion({ validate: false, version: '1' }, myHandler)
.addVersion({ validate: false, version: '2' }, myHandler)
.addVersion({ validate: false, version: '3' }, myHandler);

const introspectedRoute = versionedRouter.getRoute('get', '/foo');
expect(introspectedRoute).toMatchInlineSnapshot(`
Object {
"config": Object {
"access": "internal",
"path": "/foo",
},
"versions": Object {
"1": Object {
"config": Object {
"validate": false,
"version": "1",
},
"handler": [MockFunction],
},
"2": Object {
"config": Object {
"validate": false,
"version": "2",
},
"handler": [MockFunction],
},
"3": Object {
"config": Object {
"validate": false,
"version": "3",
},
"handler": [MockFunction],
},
},
}
`);

expect(introspectedRoute.versions['3'].handler).toBe(myHandler);
expect(introspectedRoute.versions['3'].config.version).toBe('3');
expect(introspectedRoute.versions['3'].config.validate).toBe(false);
});
});

0 comments on commit e3d50a8

Please sign in to comment.