small fixes for CI checks

Signed-off-by: aramissennyeydd <aramis.sennyey@doordash.com>
This commit is contained in:
aramissennyeydd
2024-07-07 17:44:17 -04:00
parent 28744791cb
commit 85b4e92f5c
7 changed files with 84 additions and 56 deletions
+5 -1
View File
@@ -32,4 +32,8 @@ export type {
} from './utility';
export type { ApiRouter } from './router';
export { createValidatedOpenApiRouter, getOpenApiSpecRoute } from './stub';
export { wrapInOpenApiTestServer, wrapServer } from './testUtils';
export {
wrapInOpenApiTestServer,
wrapServer,
setupProxyHooks,
} from './testUtils';
@@ -111,53 +111,51 @@ export class QueryParameterParser
const remainingQueryParameters = new Set<string>(searchParams.keys());
const queryParameters: Record<string, any> = {};
const parameterIterator = Object.entries(this.parameters);
// object parameters with form/explode style should be processed last as they collect all remaining parameters.
const parameterIterator = Object.entries(this.parameters).toSorted(
([_, parameterA], [_B, parameterB]) => {
if (
parameterA.schema.type !== 'object' &&
parameterB.schema.type !== 'object'
) {
return EQUAL;
}
if (
parameterA.schema.type === 'object' &&
parameterB.schema.type !== 'object'
) {
return PLACE_A_AFTER_B;
}
if (
parameterA.schema.type !== 'object' &&
parameterB.schema.type === 'object'
) {
return PLACE_A_BEFORE_B;
}
const isParameterAForm =
parameterA.style === 'form' || !parameterA.style;
const isParameterAFormExplode =
isParameterAForm &&
(parameterA.explode || typeof parameterA.explode === 'undefined');
const isParameterBForm =
parameterB.style === 'form' || !parameterB.style;
const isParameterBFormExplode =
isParameterBForm &&
(parameterB.explode || typeof parameterB.explode === 'undefined');
// Sort the form explode to the bottom of the array.
if (isParameterAFormExplode && isParameterBFormExplode) {
throw new OperationError(
this.operation,
'Ambiguous query parameters, you cannot have 2 form explode parameters',
);
}
if (isParameterAFormExplode) {
return PLACE_A_AFTER_B;
}
if (isParameterBFormExplode) {
return PLACE_A_BEFORE_B;
}
parameterIterator.sort(([_, parameterA], [_B, parameterB]) => {
if (
parameterA.schema.type !== 'object' &&
parameterB.schema.type !== 'object'
) {
return EQUAL;
},
);
}
if (
parameterA.schema.type === 'object' &&
parameterB.schema.type !== 'object'
) {
return PLACE_A_AFTER_B;
}
if (
parameterA.schema.type !== 'object' &&
parameterB.schema.type === 'object'
) {
return PLACE_A_BEFORE_B;
}
const isParameterAForm = parameterA.style === 'form' || !parameterA.style;
const isParameterAFormExplode =
isParameterAForm &&
(parameterA.explode || typeof parameterA.explode === 'undefined');
const isParameterBForm = parameterB.style === 'form' || !parameterB.style;
const isParameterBFormExplode =
isParameterBForm &&
(parameterB.explode || typeof parameterB.explode === 'undefined');
// Sort the form explode to the bottom of the array.
if (isParameterAFormExplode && isParameterBFormExplode) {
throw new OperationError(
this.operation,
'Ambiguous query parameters, you cannot have 2 form explode parameters',
);
}
if (isParameterAFormExplode) {
return PLACE_A_AFTER_B;
}
if (isParameterBFormExplode) {
return PLACE_A_BEFORE_B;
}
return EQUAL;
});
for (const [name, parameter] of parameterIterator) {
if (!parameter.schema) {
throw new OperationError(
@@ -17,7 +17,7 @@
import { findOperationByRequest, OpenApiProxyValidator } from './validation';
import { rest } from 'msw';
import { setupServer } from 'msw/node';
import { setupRequestMockHandlers } from '@backstage/backend-test-utils';
import { registerMswTestHooks } from '@backstage/test-utils';
import { CompletedBody, CompletedRequest, CompletedResponse } from 'mockttp';
import withResponseBody from './__fixtures__/schemas/withJsonResponseBody.json';
import withQueryParameter from './__fixtures__/schemas/withQueryParameter.json';
@@ -61,7 +61,7 @@ function createMockttpResponse(response: {
}
describe('OpenApiProxyValidator', () => {
setupRequestMockHandlers(server);
registerMswTestHooks(server);
let validator: OpenApiProxyValidator;
async function mockSchema(schema: any) {
@@ -19,14 +19,28 @@ import { Proxy } from './proxy/setup';
const proxy = new Proxy();
beforeAll(async () => {
await proxy.setup();
});
/**
* Setup the proxy hooks for the test suite. This will start the proxy before all tests and stop it after all tests.
* @public
*/
export function setupProxyHooks() {
beforeAll(async () => {
await proxy.setup();
});
afterAll(() => {
proxy.stop();
});
afterAll(() => {
proxy.stop();
});
}
/**
* !!! THIS CURRENTLY ONLY SUPPORTS SUPERTEST !!!
* Setup a server with a custom OpenAPI proxy. This proxy will capture all requests and responses and make sure they
* conform to the spec.
* @param app - express server, needed to ensure we have the correct ports for the proxy.
* @returns - a configured HTTP server that should be used with supertest.
* @public
*/
export async function wrapServer(app: Express): Promise<Server> {
const server = app.listen(proxy.forwardTo.port);
await proxy.initialize(`http://localhost:${proxy.forwardTo.port}`, server);