import { HttpMethod } from '../../src/API/Request.js' import { Route } from '../../src/Server/Router.js' import RouteResolver from '../../src/Server/RouteResolver.js' const mockRoute = (method: HttpMethod, path: string | string[]) => ({ method: method, path: path, }) as any as Route describe('RouteResolver', () => { test('no routes configured', () => { parameterizedTest({}, () => [ [HttpMethod.GET, '/', undefined], [HttpMethod.GET, '', undefined], [HttpMethod.GET, 'hjdah', undefined], ]) }) test('one route', () => { parameterizedTest( { route: mockRoute(HttpMethod.GET, '/'), }, routes => [ [HttpMethod.GET, '/', routes.route], [HttpMethod.GET, '', routes.route], [HttpMethod.GET, 'hjdah', undefined], [HttpMethod.POST, '/', undefined], [HttpMethod.DELETE, '/', undefined], ] ) }) test('basic matching', () => { parameterizedTest( { getBase: mockRoute(HttpMethod.GET, '/'), getA: mockRoute(HttpMethod.GET, '/a'), getB: mockRoute(HttpMethod.GET, '/b'), postBase: mockRoute(HttpMethod.POST, '/'), postA: mockRoute(HttpMethod.POST, '/a'), variable: mockRoute(HttpMethod.GET, '/:a'), getAb: mockRoute(HttpMethod.GET, '/a/b'), }, routes => [ [HttpMethod.GET, '/', routes.getBase], [HttpMethod.GET, '/a', routes.getA], [HttpMethod.GET, '/b', routes.getB], [HttpMethod.POST, '/', routes.postBase], [HttpMethod.POST, '/a', routes.postA], [HttpMethod.GET, '/c', routes.variable], [HttpMethod.GET, '/a/b', routes.getAb], ] ) }) test('multi matching', () => { parameterizedTest( { getA: mockRoute(HttpMethod.GET, ['/a', '/b']), variable: mockRoute(HttpMethod.GET, '/:a'), }, routes => [ [HttpMethod.GET, '/a', routes.getA], [HttpMethod.GET, '/b', routes.getA], [HttpMethod.GET, '/c', routes.variable], ] ) }) test('path variables', () => { parameterizedTest( { path_vars: mockRoute(HttpMethod.GET, '/base/:a/:b/:c'), abc: mockRoute(HttpMethod.GET, '/base/a/b/c'), abcd: mockRoute(HttpMethod.GET, '/base/a/b/c/d'), abc_path: mockRoute(HttpMethod.GET, '/base/a/b/c/:d'), }, routes => [ [HttpMethod.GET, '/base/1/2/3', routes.path_vars], [HttpMethod.GET, '/base/a/b/c', routes.abc], [HttpMethod.GET, '/base/a/b/c/d', routes.abcd], [HttpMethod.GET, '/base/a/b/c/u', routes.abc_path], [HttpMethod.GET, '/base/a/b', undefined], [HttpMethod.GET, '/base/a/b/c/d/e', undefined], [HttpMethod.GET, '/base/a/b/c/d/e/f', undefined], ] ) }) test('fails to construct with duplicate routes', () => { expect( () => new RouteResolver({ routes: [ mockRoute(HttpMethod.GET, '/a/b/c/:d/:e/b') as any, mockRoute(HttpMethod.GET, '/a/b/c/:jshj/:e/b') as any, ], }) ).toThrowError('Duplicate route: GET: /a/b/c/:jshj/:e/b') }) }) const parameterizedTest = ( routes: T, tests: (routes: T) => [HttpMethod, string, Route?][] ) => { const underTest = new RouteResolver({ routes: Object.values(routes) as any, }) tests(routes).forEach(([method, path, expected]) => expect(underTest.resolveRoute(method, path)).toBe(expected) ) }