Files
floci-ui/packages/api/src/adapter-aws/AwsApiGatewayAdapter.test.ts
T
Zakaria bb5ca85a88
CI / checks (pull_request) Successful in 26m49s
feat(api): add HTTP and WebSocket APIs (API Gateway v2) to the API Gateway page
API Gateway v2 is a separate AWS API from REST APIs, so HTTP and WebSocket APIs
made with the SDK, SAM, CDK or Terraform never showed up. The API Gateway page
now lists all three kinds with a Type column, creates each from the same form,
and opens HTTP and WebSocket APIs in their own panel:

- Quick create: an HTTP API with a Lambda gets a catch-all route on an
  auto-deployed $default stage, plus the Lambda permission.
- Routes to Lambda (payload 2.0) or HTTP backends; deleting a route removes
  the integration and Lambda permission only it used.
- Stages with or without automatic deployment, and deploy on demand.
- JWT authorizers filled in from a Cognito pool's OpenID Connect discovery
  document and an app client, or from any issuer; protect routes with them.
- CORS configuration.
- A tester that sends a real request to a stage, and for WebSocket APIs one
  that connects, sends a message and collects the replies.

Capabilities are advertised under a new httpApiActions group, covered by the
cloudProxy guard test. Verified end to end against TheCloud's runtime.
2026-10-25 09:18:50 -04:00

576 lines
27 KiB
TypeScript

import {describe, expect, test} from 'bun:test'
import {
CreateDeploymentCommand,
CreateResourceCommand,
CreateRestApiCommand,
DeleteMethodCommand,
DeleteRestApiCommand,
GetRestApiCommand,
GetRestApisCommand,
GetMethodCommand,
GetResourcesCommand,
GetStagesCommand,
PutIntegrationCommand,
PutIntegrationResponseCommand,
PutMethodCommand,
PutMethodResponseCommand,
TestInvokeMethodCommand,
type APIGatewayClient,
} from '@aws-sdk/client-api-gateway'
import {AddPermissionCommand, GetFunctionCommand, RemovePermissionCommand, type LambdaClient} from '@aws-sdk/client-lambda'
import {GetApisCommand, type ApiGatewayV2Client} from '@aws-sdk/client-apigatewayv2'
import {AwsApiGatewayAdapter} from './AwsApiGatewayAdapter'
function fakeClient(handler: (command: unknown) => unknown): APIGatewayClient {
return {
send: async (command: unknown) => handler(command),
} as unknown as APIGatewayClient
}
function fakeLambda(handler: (command: unknown) => unknown): LambdaClient {
return {
send: async (command: unknown) => handler(command),
} as unknown as LambdaClient
}
/** An API Gateway v2 runtime with no HTTP or WebSocket APIs, for tests about REST APIs. */
const noHttpApis = {
send: async (command: unknown) => {
if (command instanceof GetApisCommand) return {Items: []}
throw Object.assign(new Error('NotFoundException'), {$metadata: {httpStatusCode: 404}})
},
} as unknown as ApiGatewayV2Client
function restOnlyAdapter(client: APIGatewayClient) {
return new AwsApiGatewayAdapter(client, fakeLambda(() => ({})), '000000000000', 'us-east-1', noHttpApis)
}
const orders = {
id: 'a1b2c3',
name: 'orders-api',
description: 'Orders REST API',
createdDate: new Date('2026-01-02T03:04:05.000Z'),
version: '1.0',
endpointConfiguration: {types: ['REGIONAL']},
rootResourceId: 'root123',
}
describe('AwsApiGatewayAdapter', () => {
test('lists every page and maps REST APIs to normalized resources', async () => {
const adapter = restOnlyAdapter(fakeClient((command) => {
if (!(command instanceof GetRestApisCommand)) throw new Error('Unexpected command')
if (!command.input.position) return {items: [orders], position: 'next'}
return {items: [{...orders, id: 'd4e5f6', name: 'accounts-api'}]}
}))
const result = await adapter.list()
expect(result).toHaveLength(2)
expect(result[0]).toMatchObject({
id: 'a1b2c3',
name: 'orders-api',
cloud: 'aws',
service: 'apigateway',
type: 'rest-api',
region: null,
createdAt: '2026-01-02T03:04:05.000Z',
})
expect(result[0].metadata).toMatchObject({
apigatewayService: 'rest',
description: 'Orders REST API',
rootResourceId: 'root123',
})
})
test('filters APIs by search term', async () => {
const adapter = restOnlyAdapter(fakeClient(() => ({
items: [orders, {...orders, id: 'd4e5f6', name: 'accounts-api'}],
})))
const result = await adapter.list({search: 'ORDERS'})
expect(result.map((resource) => resource.name)).toEqual(['orders-api'])
})
test('gets and maps one REST API', async () => {
const adapter = new AwsApiGatewayAdapter(fakeClient((command) => {
expect(command).toBeInstanceOf(GetRestApiCommand)
return orders
}))
const result = await adapter.get('a1b2c3')
expect(result?.id).toBe('a1b2c3')
expect(result?.metadata.rootResourceId).toBe('root123')
})
test('returns null when API Gateway reports a missing REST API', async () => {
const adapter = restOnlyAdapter(fakeClient(() => {
throw Object.assign(new Error('NotFoundException'), {$metadata: {httpStatusCode: 404}})
}))
await expect(adapter.get('missing')).resolves.toBeNull()
})
test('creates a REST API with an optional description', async () => {
const adapter = new AwsApiGatewayAdapter(fakeClient((command) => {
expect(command).toBeInstanceOf(CreateRestApiCommand)
expect((command as CreateRestApiCommand).input).toEqual({name: 'orders-api', description: 'Orders REST API'})
return orders
}))
const result = await adapter.create({values: {name: 'orders-api', description: 'Orders REST API'}})
expect(result.id).toBe('a1b2c3')
})
test('rejects a missing name before calling API Gateway', async () => {
let called = false
const adapter = new AwsApiGatewayAdapter(fakeClient(() => {
called = true
return {}
}))
await expect(adapter.create({values: {}})).rejects.toThrow('name is required')
expect(called).toBeFalse()
})
test('deletes the requested REST API', async () => {
const adapter = restOnlyAdapter(fakeClient((command) => {
expect(command).toBeInstanceOf(DeleteRestApiCommand)
expect((command as DeleteRestApiCommand).input.restApiId).toBe('a1b2c3')
return {}
}))
await adapter.delete('a1b2c3')
})
test('creates and deploys a Lambda proxy route', async () => {
const apiCommands: unknown[] = []
const lambdaCommands: unknown[] = []
const adapter = new AwsApiGatewayAdapter(
fakeClient((command) => {
apiCommands.push(command)
if (command instanceof GetResourcesCommand) return {items: [{id: 'root123', path: '/'}]}
if (command instanceof CreateResourceCommand) return {id: 'resource456'}
if (command instanceof CreateDeploymentCommand) return {id: 'deployment789'}
return {}
}),
fakeLambda((command) => {
lambdaCommands.push(command)
if (command instanceof GetFunctionCommand) {
return {Configuration: {FunctionArn: 'arn:aws:lambda:us-east-1:000000000000:function:hello'}}
}
return {}
}),
'000000000000',
'us-east-1',
)
const result = await adapter.createApiGatewayLambdaRoute('a1b2c3', {
path: '/hello', method: 'GET', stage: 'dev', functionName: 'hello',
})
expect(apiCommands.map((command) => (command as {constructor: {name: string}}).constructor.name)).toEqual([
'GetResourcesCommand', 'CreateResourceCommand', 'PutMethodCommand',
'PutIntegrationCommand', 'CreateDeploymentCommand',
])
expect((apiCommands[1] as CreateResourceCommand).input).toMatchObject({
restApiId: 'a1b2c3', parentId: 'root123', pathPart: 'hello',
})
expect((apiCommands[2] as PutMethodCommand).input).toMatchObject({
httpMethod: 'GET', authorizationType: 'NONE',
})
expect((apiCommands[3] as PutIntegrationCommand).input).toMatchObject({
type: 'AWS_PROXY', integrationHttpMethod: 'POST',
uri: 'arn:aws:apigateway:us-east-1:lambda:path/2015-03-31/functions/arn:aws:lambda:us-east-1:000000000000:function:hello/invocations',
})
expect((lambdaCommands[1] as AddPermissionCommand).input).toMatchObject({
FunctionName: 'hello', Principal: 'apigateway.amazonaws.com',
SourceArn: 'arn:aws:execute-api:us-east-1:000000000000:a1b2c3/dev/GET/hello',
})
expect(result).toEqual({
resourceId: 'resource456', deploymentId: 'deployment789',
invokeUrl: 'http://localhost:4566/execute-api/a1b2c3/dev/hello',
})
})
test('creates missing nested resources and reuses existing path segments', async () => {
const apiCommands: unknown[] = []
const adapter = new AwsApiGatewayAdapter(
fakeClient((command) => {
apiCommands.push(command)
if (command instanceof GetResourcesCommand) return {items: [
{id: 'root123', path: '/'},
{id: 'orders123', parentId: 'root123', pathPart: 'orders', path: '/orders'},
]}
if (command instanceof CreateResourceCommand) return {id: 'orderId123'}
if (command instanceof CreateDeploymentCommand) return {id: 'deployment789'}
return {}
}),
fakeLambda((command) => command instanceof GetFunctionCommand
? {Configuration: {FunctionArn: 'arn:aws:lambda:us-east-1:000000000000:function:hello'}}
: {}),
)
const result = await adapter.createApiGatewayLambdaRoute('a1b2c3', {
path: '/orders/{id}', method: 'PATCH', stage: 'dev', functionName: 'hello',
})
const creates = apiCommands.filter((command) => command instanceof CreateResourceCommand) as CreateResourceCommand[]
expect(creates).toHaveLength(1)
expect(creates[0]?.input).toMatchObject({parentId: 'orders123', pathPart: '{id}'})
expect((apiCommands.find((command) => command instanceof PutMethodCommand) as PutMethodCommand).input.httpMethod).toBe('PATCH')
expect(result).toMatchObject({resourceId: 'orderId123', invokeUrl: 'http://localhost:4566/execute-api/a1b2c3/dev/orders/{id}'})
})
test('creates a greedy child under the explicitly selected parent', async () => {
const commands: unknown[] = []
const lambdaCommands: unknown[] = []
const adapter = new AwsApiGatewayAdapter(fakeClient((command) => {
commands.push(command)
if (command instanceof GetResourcesCommand) return {items: [
{id: 'root123', path: '/'},
{id: 'files123', parentId: 'root123', pathPart: 'files', path: '/files'},
]}
if (command instanceof CreateResourceCommand) return {id: 'proxy123'}
if (command instanceof CreateDeploymentCommand) return {id: 'deployment789'}
return {}
}), fakeLambda((command) => {
lambdaCommands.push(command)
return command instanceof GetFunctionCommand
? {Configuration: {FunctionArn: 'arn:aws:lambda:us-east-1:000000000000:function:files'}}
: {}
}))
await adapter.createApiGatewayLambdaRoute('a1b2c3', {
path: '/files/{proxy+}', parentResourceId: 'files123', pathPart: '{proxy+}',
method: 'ANY', stage: 'dev', functionName: 'files',
})
expect((commands.find((command) => command instanceof CreateResourceCommand) as CreateResourceCommand).input).toMatchObject({
parentId: 'files123', pathPart: '{proxy+}',
})
expect((lambdaCommands.find((command) => command instanceof AddPermissionCommand) as AddPermissionCommand).input).toMatchObject({
SourceArn: 'arn:aws:execute-api:us-east-1:000000000000:a1b2c3/dev/*/files/*',
})
})
test('adds a method to an existing resource without creating a duplicate path', async () => {
const apiCommands: unknown[] = []
const adapter = new AwsApiGatewayAdapter(
fakeClient((command) => {
apiCommands.push(command)
if (command instanceof GetResourcesCommand) {
return {items: [
{id: 'resource456', parentId: 'root123', pathPart: 'hello', path: '/hello'},
{id: 'root123', path: '/'},
]}
}
if (command instanceof CreateDeploymentCommand) return {id: 'deployment789'}
return {}
}),
fakeLambda((command) => command instanceof GetFunctionCommand
? {Configuration: {FunctionArn: 'arn:aws:lambda:us-east-1:000000000000:function:hello'}}
: {}),
'000000000000',
'us-east-1',
)
await adapter.createApiGatewayLambdaRoute('a1b2c3', {
path: '/hello', method: 'POST', stage: 'dev', functionName: 'hello',
})
expect(apiCommands.some((command) => command instanceof CreateResourceCommand)).toBeFalse()
expect((apiCommands.find((command) => command instanceof PutMethodCommand) as PutMethodCommand).input).toMatchObject({
resourceId: 'resource456', httpMethod: 'POST',
})
})
test('tests a deployed route and preserves its HTTP response', async () => {
const originalFetch = globalThis.fetch
const requests: Request[] = []
globalThis.fetch = (async (input: RequestInfo | URL, init?: RequestInit) => {
requests.push(new Request(input, init))
return new Response(JSON.stringify({error: 'invalid request'}), {
status: 400,
headers: {'content-type': 'application/json', 'x-request-id': 'request-123'},
})
}) as typeof fetch
try {
const adapter = new AwsApiGatewayAdapter(fakeClient(() => ({})))
const result = await adapter.testApiGatewayRoute('a1b2c3', {
path: '/hello', method: 'POST', stage: 'dev', body: '{"name":"Ada"}',
headers: {'x-client': 'console'}, query: 'verbose=true',
})
expect(requests).toHaveLength(1)
expect(requests[0]?.url).toBe('http://localhost:4566/execute-api/a1b2c3/dev/hello?verbose=true')
expect(requests[0]?.method).toBe('POST')
expect(requests[0]?.headers.get('content-type')).toBe('application/json')
expect(requests[0]?.headers.get('x-client')).toBe('console')
expect(await requests[0]?.text()).toBe('{"name":"Ada"}')
expect(result).toMatchObject({
statusCode: 400,
headers: {'content-type': 'application/json', 'x-request-id': 'request-123'},
body: '{"error":"invalid request"}',
})
} finally {
globalThis.fetch = originalFetch
}
})
test('omits a body when testing a GET route', async () => {
const originalFetch = globalThis.fetch
const requests: Request[] = []
globalThis.fetch = (async (input: RequestInfo | URL, init?: RequestInit) => {
requests.push(new Request(input, init))
return new Response('{}')
}) as typeof fetch
try {
const adapter = new AwsApiGatewayAdapter(fakeClient(() => ({})))
await adapter.testApiGatewayRoute('a1b2c3', {
path: '/hello', method: 'GET', stage: 'dev', body: '{}', headers: {}, query: '',
})
expect(await requests[0]?.text()).toBe('')
} finally {
globalThis.fetch = originalFetch
}
})
test('uses PATCH and HEAD for deployed requests and rejects ANY', async () => {
const originalFetch = globalThis.fetch
const requests: Request[] = []
globalThis.fetch = (async (input: RequestInfo | URL, init?: RequestInit) => {
requests.push(new Request(input, init))
return new Response(null)
}) as typeof fetch
try {
const adapter = new AwsApiGatewayAdapter(fakeClient(() => ({})))
await adapter.testApiGatewayRoute('a1b2c3', {path: '/orders/1', method: 'PATCH', stage: 'dev', body: '{}', headers: {}, query: ''})
await adapter.testApiGatewayRoute('a1b2c3', {path: '/orders/1', method: 'HEAD', stage: 'dev', body: '{}', headers: {}, query: ''})
await expect(adapter.testApiGatewayRoute('a1b2c3', {path: '/orders/1', method: 'ANY', stage: 'dev', body: '', headers: {}, query: ''})).rejects.toThrow('method must be')
expect(requests.map((request) => request.method)).toEqual(['PATCH', 'HEAD'])
expect(await requests[1]?.text()).toBe('')
} finally {
globalThis.fetch = originalFetch
}
})
test('tests a configured method through the AWS SDK without a deployed stage', async () => {
const commands: unknown[] = []
const adapter = new AwsApiGatewayAdapter(fakeClient((command) => {
commands.push(command)
if (command instanceof TestInvokeMethodCommand) {
return {
status: 201,
body: '{"id":"order-123"}',
headers: {'x-request-id': 'request-123'},
multiValueHeaders: {'set-cookie': ['first', 'second']},
log: 'Execution completed',
latency: 17,
}
}
throw new Error('Unexpected command')
}))
await expect(adapter.testApiGatewayMethod('a1b2c3', {
resourceId: 'resource456',
httpMethod: 'ANY',
pathWithQueryString: '/orders?dryRun=true',
body: '{"name":"Ada"}',
headers: {'content-type': 'application/json'},
multiValueHeaders: {'x-tag': ['one', 'two']},
stageVariables: {environment: 'test'},
})).resolves.toEqual({
statusCode: 201,
body: '{"id":"order-123"}',
headers: {'x-request-id': 'request-123'},
multiValueHeaders: {'set-cookie': ['first', 'second']},
log: 'Execution completed',
latency: 17,
})
expect((commands[0] as TestInvokeMethodCommand).input).toEqual({
restApiId: 'a1b2c3', resourceId: 'resource456', httpMethod: 'ANY',
pathWithQueryString: '/orders?dryRun=true', body: '{"name":"Ada"}',
headers: {'content-type': 'application/json'}, multiValueHeaders: {'x-tag': ['one', 'two']},
stageVariables: {environment: 'test'},
})
})
test('lists deployed methods, Lambda integrations, and stages', async () => {
const adapter = new AwsApiGatewayAdapter(fakeClient((command) => {
if (command instanceof GetResourcesCommand) {
return {items: [
{id: 'root123', path: '/', resourceMethods: {}},
{id: 'resource456', parentId: 'root123', pathPart: 'hello', path: '/hello', resourceMethods: {GET: true, POST: true}},
]}
}
if (command instanceof GetMethodCommand) {
return {methodIntegration: {
uri: 'arn:aws:apigateway:us-east-1:lambda:path/2015-03-31/functions/arn:aws:lambda:us-east-1:000000000000:function:hello/invocations',
}}
}
if (command instanceof GetStagesCommand) return {item: [{stageName: 'prod'}, {stageName: 'dev'}]}
throw new Error('Unexpected command')
}))
await expect(adapter.listApiGatewayRoutes('a1b2c3')).resolves.toEqual({
resources: [
{resourceId: 'root123', parentId: null, path: '/', pathPart: null, methods: []},
{resourceId: 'resource456', parentId: 'root123', path: '/hello', pathPart: 'hello', methods: [
{resourceId: 'resource456', path: '/hello', method: 'GET', functionName: 'hello', integrationType: null},
{resourceId: 'resource456', path: '/hello', method: 'POST', functionName: 'hello', integrationType: null},
]},
],
routes: [
{resourceId: 'resource456', path: '/hello', method: 'GET', functionName: 'hello', integrationType: null},
{resourceId: 'resource456', path: '/hello', method: 'POST', functionName: 'hello', integrationType: null},
],
stages: ['dev', 'prod'],
})
})
test('paginates and returns resources that have no configured methods', async () => {
const adapter = new AwsApiGatewayAdapter(fakeClient((command) => {
if (command instanceof GetResourcesCommand && !command.input.position) {
return {items: [{id: 'root123', path: '/', resourceMethods: {}}], position: 'next'}
}
if (command instanceof GetResourcesCommand) {
return {items: [{id: 'orders123', parentId: 'root123', pathPart: 'orders', path: '/orders'}]}
}
if (command instanceof GetStagesCommand) return {item: []}
throw new Error('Unexpected command')
}))
await expect(adapter.listApiGatewayRoutes('a1b2c3')).resolves.toEqual({
resources: [
{resourceId: 'root123', parentId: null, path: '/', pathPart: null, methods: []},
{resourceId: 'orders123', parentId: 'root123', path: '/orders', pathPart: 'orders', methods: []},
],
routes: [],
stages: [],
})
})
test('deletes one method and redeploys its stage', async () => {
const commands: unknown[] = []
const lambdaCommands: unknown[] = []
const adapter = new AwsApiGatewayAdapter(fakeClient((command) => {
commands.push(command)
if (command instanceof GetMethodCommand) {
return {methodIntegration: {uri: 'arn:aws:apigateway:us-east-1:lambda:path/2015-03-31/functions/arn:aws:lambda:us-east-1:000000000000:function:hello/invocations'}}
}
return {}
}), fakeLambda((command) => {
lambdaCommands.push(command)
return {}
}))
await adapter.deleteApiGatewayRoute('a1b2c3', {resourceId: 'resource456', path: '/hello', method: 'POST', stage: 'dev'})
expect((commands[1] as DeleteMethodCommand).input).toMatchObject({restApiId: 'a1b2c3', resourceId: 'resource456', httpMethod: 'POST'})
expect((commands[2] as CreateDeploymentCommand).input).toMatchObject({restApiId: 'a1b2c3', stageName: 'dev'})
expect((lambdaCommands[0] as RemovePermissionCommand).input).toMatchObject({FunctionName: 'hello', StatementId: 'apigateway-a1b2c3-dev-POST-hello'})
})
test('deletes a CORS OPTIONS method and redeploys its stage', async () => {
const commands: unknown[] = []
const adapter = new AwsApiGatewayAdapter(fakeClient((command) => {
commands.push(command)
if (command instanceof GetMethodCommand) {
return {methodIntegration: {type: 'MOCK'}}
}
return {}
}), fakeLambda(() => ({})))
await adapter.deleteApiGatewayRoute('a1b2c3', {resourceId: 'resource456', path: '/hello', method: 'OPTIONS', stage: 'dev'})
expect(commands.map((command) => (command as {constructor: {name: string}}).constructor.name)).toEqual([
'GetMethodCommand', 'DeleteMethodCommand', 'CreateDeploymentCommand',
])
expect((commands[1] as DeleteMethodCommand).input).toMatchObject({httpMethod: 'OPTIONS'})
})
test('enables CORS for non-proxy methods, creates OPTIONS, and reports proxy methods', async () => {
const commands: unknown[] = []
const adapter = new AwsApiGatewayAdapter(fakeClient((command) => {
commands.push(command)
if (command instanceof GetMethodCommand && command.input.httpMethod === 'GET') {
return {
methodResponses: {200: {
responseParameters: {'method.response.header.X-Existing': true},
responseModels: {'application/json': 'ExistingModel'},
}},
methodIntegration: {type: 'HTTP', integrationResponses: {200: {
responseParameters: {'method.response.header.X-Existing': "'existing'"},
responseTemplates: {'application/json': '$input.body'},
}}},
}
}
if (command instanceof GetMethodCommand && command.input.httpMethod === 'POST') {
return {methodIntegration: {type: 'AWS_PROXY'}}
}
if (command instanceof GetMethodCommand && command.input.httpMethod === 'OPTIONS') {
return {
methodResponses: {200: {
responseParameters: {'method.response.header.Access-Control-Allow-Origin': true},
responseModels: {'application/json': 'OptionsModel'},
}},
methodIntegration: {timeoutInMillis: 29000, integrationResponses: {200: {
responseTemplates: {'text/plain': 'existing template'},
}}},
}
}
return {}
}))
await expect(adapter.enableApiGatewayCors('a1b2c3', {
resourceId: 'resource456', stage: 'dev', origin: '*', headers: 'Content-Type', methods: ['GET', 'POST'],
})).resolves.toEqual({configuredMethods: ['GET'], proxyMethods: ['POST']})
expect(commands.map((command) => (command as {constructor: {name: string}}).constructor.name)).toEqual([
'GetMethodCommand', 'PutMethodResponseCommand', 'PutIntegrationResponseCommand', 'GetMethodCommand', 'GetMethodCommand',
'PutMethodCommand', 'PutMethodResponseCommand', 'PutIntegrationCommand', 'PutIntegrationResponseCommand', 'CreateDeploymentCommand',
])
expect((commands[1] as PutMethodResponseCommand).input.responseParameters).toEqual({
'method.response.header.X-Existing': true,
'method.response.header.Access-Control-Allow-Origin': false,
'method.response.header.Access-Control-Allow-Headers': false,
'method.response.header.Access-Control-Allow-Methods': false,
})
expect((commands[1] as PutMethodResponseCommand).input.responseModels).toEqual({'application/json': 'ExistingModel'})
expect((commands[2] as PutIntegrationResponseCommand).input.responseParameters).toMatchObject({
'method.response.header.X-Existing': "'existing'",
'method.response.header.Access-Control-Allow-Origin': "'*'",
'method.response.header.Access-Control-Allow-Headers': "'Content-Type'",
'method.response.header.Access-Control-Allow-Methods': "'GET,POST,OPTIONS'",
})
expect((commands[2] as PutIntegrationResponseCommand).input.responseTemplates).toEqual({'application/json': '$input.body'})
expect((commands[5] as PutMethodCommand).input).toMatchObject({httpMethod: 'OPTIONS', authorizationType: 'NONE'})
expect((commands[6] as PutMethodResponseCommand).input).toMatchObject({
responseParameters: {'method.response.header.Access-Control-Allow-Origin': true},
responseModels: {'application/json': 'OptionsModel'},
})
expect((commands[7] as PutIntegrationCommand).input).toMatchObject({
type: 'MOCK', requestTemplates: {'application/json': '{"statusCode": 200}'}, timeoutInMillis: 29000,
})
expect((commands[8] as PutIntegrationResponseCommand).input.responseTemplates).toEqual({'text/plain': 'existing template'})
expect((commands[9] as CreateDeploymentCommand).input).toMatchObject({stageName: 'dev'})
})
test('returns the AWS API Gateway schema', () => {
const adapter = new AwsApiGatewayAdapter(fakeClient(() => ({})))
expect(adapter.schema()).toMatchObject({
cloud: 'aws',
service: 'apigateway',
displayName: 'AWS API Gateway',
actions: ['list', 'create', 'delete', 'inspect'],
})
})
})