Skip to content

Commit

Permalink
fix: working mock integration options method for defaultCors
Browse files Browse the repository at this point in the history
  • Loading branch information
mpiltz committed Jan 26, 2023
1 parent 92b907a commit a0048d0
Show file tree
Hide file tree
Showing 2 changed files with 187 additions and 6 deletions.
47 changes: 42 additions & 5 deletions src/api/definition.ts
Expand Up @@ -161,15 +161,45 @@ export class ApiDefinition extends apigateway.ApiDefinition {
addError(this.scope, message);
return;
}

if (typeof defaultCors !== 'undefined') {
this.schema.set(`paths.${path}.options`, {
'x-amazon-apigateway-integration': defaultCors.xAmazonApigatewayIntegration,
});
this.configureDefaultCors(path, defaultCors);
}

const methods = paths[path];
this.configurePathMethods(path, schemaPaths[path], methods, defaultIntegration);
this.configurePathMethods(path, schemaPaths[path], methods, defaultIntegration, defaultCors );
});
}

private configureDefaultCors(path: string, defaultCors: CorsIntegration): void {
this.schema.set(`paths.${path}.options`, {
'summary': 'CORS support',
'description': 'Enable CORS by returning correct headers',
'consumes': [
'application/json',
],
'produces': [
'application/json',
],
'tags': [
'CORS',
],
'responses': {
204: {
description: 'Default response for CORS method',
headers: {
'Access-Control-Allow-Headers': {
type: 'string',
},
'Access-Control-Allow-Methods': {
type: 'string',
},
'Access-Control-Allow-Origin': {
type: 'string',
},
},
},
},
'x-amazon-apigateway-integration': defaultCors.xAmazonApigatewayIntegration,
});
}

Expand All @@ -181,6 +211,8 @@ export class ApiDefinition extends apigateway.ApiDefinition {
schemaPath: Record<string, any>,
methods: Methods = {},
defaultIntegration?: Integration,
defaultCors?: CorsIntegration,

): void {
// Loop through given methods to ensure they are defined
// and dont have an existing integration
Expand All @@ -195,6 +227,11 @@ export class ApiDefinition extends apigateway.ApiDefinition {
Object.keys(schemaPathMethods).map((schemaPathMethod) => {
const method = methods[schemaPathMethod as HTTPMethod];

// Do not process options method because it has been modified already
// and no overrider method is present
if (defaultCors && schemaPathMethod === 'options' && !method) {
return;
}
if (!defaultIntegration && !method) {
const message = `OpenAPI schema has an unhandled path method: ${schemaPathName}/${schemaPathMethod}`;
addError(this.scope, message);
Expand Down
146 changes: 145 additions & 1 deletion test/definition.test.ts
Expand Up @@ -3,7 +3,7 @@ import * as cdk from 'aws-cdk-lib';
import { Annotations } from 'aws-cdk-lib/assertions';
import * as lambda from 'aws-cdk-lib/aws-lambda';
import * as openapix from '../src';
import { MockIntegration } from '../src';
import { CorsIntegration, MockIntegration } from '../src';
import { ApiDefinition } from '../src/api/definition';


Expand Down Expand Up @@ -234,3 +234,147 @@ test('Should add mock integrations', () => {
'AWS_PROXY',
);
});
test('Should add cors integrations', () => {
const stack = new cdk.Stack();

const value = {
openapi: '3.0.1',
info: {
title: 'TestApi',
version: '0.0.0',
},
paths: {
'/foo': {
get: {
operationId: 'get-foo',
responses: {
200: {
content: {
'application/json': {
example: [
{
some: 'foo',
thing: 'bar',
},
],
},
},
description: 'foo',
},
},
},
},
'/bar': {
get: {
operationId: 'get-bar',
responses: {
200: {
content: {
'application/json': {
example: [
{
some: 'foo',
thing: 'bar',
},
],
},
},
description: 'foo',
},
},
},
},
},
};

const sampleLambdaFunction = new lambda.Function(stack, 'SampleLambdaFunction', {
code: lambda.Code.fromInline('foo'),
handler: 'index.handler',
runtime: lambda.Runtime.NODEJS_16_X,
});

// eslint-disable-next-line quotes
const OVERRIDE_HEADERS = 'OVERRIDE-DEFAULT-HEADERS';

const definition = new ApiDefinition(stack, {
source: new openapix.Schema(value),
defaultCors: new CorsIntegration(stack, {
headers: '*',
origins: '*',
methods: '*',
}),
paths: {
'/foo': {
get: new openapix.LambdaIntegration(stack, sampleLambdaFunction),
},
'/bar': {
get: new openapix.LambdaIntegration(stack, sampleLambdaFunction),
options: new CorsIntegration(stack, {
headers: OVERRIDE_HEADERS,
origins: '*',
methods: '*',
}),
},
},

});

const config = definition.bind(stack);


expect(config.inlineDefinition).toBeDefined();

// FOO
validateCommonDefaultCors('foo');
expect(config.inlineDefinition).toHaveProperty(
'paths./foo.options.x-amazon-apigateway-integration.responses.default.responseParameters',
{
'method.response.header.Access-Control-Allow-Headers': "'*'",
'method.response.header.Access-Control-Allow-Methods': "'*'",
},
);

// BAR
validateCommonDefaultCors('bar');
expect(config.inlineDefinition).toHaveProperty(
'paths./bar.options.x-amazon-apigateway-integration.responses.default.responseParameters',
{
'method.response.header.Access-Control-Allow-Headers': `'${ OVERRIDE_HEADERS }'`,
'method.response.header.Access-Control-Allow-Methods': "'*'",
},
);


function validateCommonDefaultCors(path:string) {
expect(config.inlineDefinition).toHaveProperty(
`paths./${path}.get.x-amazon-apigateway-integration.type`,
'AWS_PROXY',
);
expect(config.inlineDefinition).toHaveProperty(
`paths./${path}.options.responses`,
{
204: {
description: 'Default response for CORS method',
headers: {
'Access-Control-Allow-Headers': { type: 'string' },
'Access-Control-Allow-Methods': { type: 'string' },
'Access-Control-Allow-Origin': { type: 'string' },
},
},
},
);
expect(config.inlineDefinition).toHaveProperty(
`paths./${path}.options.x-amazon-apigateway-integration.requestTemplates`,

{ 'application/json': '{"statusCode": 204}' },

);
expect(config.inlineDefinition).toHaveProperty(
`paths./${path}.options.x-amazon-apigateway-integration.responses.default.statusCode`,
'204',
);
}

});


0 comments on commit a0048d0

Please sign in to comment.