Skip to content

Commit ea6f828

Browse files
roryhackneybennettsf
authored andcommitted
packages locally installed for unit test dependencies in rest-api-construct
1 parent 6ada159 commit ea6f828

File tree

10 files changed

+389
-6601
lines changed

10 files changed

+389
-6601
lines changed

package-lock.json

Lines changed: 275 additions & 6309 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,8 @@
5757
"devDependencies": {
5858
"@actions/core": "^1.10.1",
5959
"@actions/github": "^6.0.0",
60+
"@aws-amplify/backend": "^1.16.1",
61+
"@aws-amplify/backend-output-storage": "^1.3.1",
6062
"@aws-amplify/eslint-plugin-amplify-backend-rules": "^0.0.2",
6163
"@aws-sdk/client-amplify": "^3.750.0",
6264
"@aws-sdk/client-cloudformation": "^3.750.0",

packages/rest-api-construct/API.md

Lines changed: 13 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -6,32 +6,25 @@
66

77
import * as apiGateway from 'aws-cdk-lib/aws-apigateway';
88
import { Construct } from 'constructs';
9-
import * as lamb from 'aws-cdk-lib/aws-lambda';
9+
import { IFunction } from 'aws-cdk-lib/aws-lambda';
1010

1111
// @public (undocumented)
12-
export type ExistingDirectory = {
13-
path: string;
14-
};
15-
16-
// @public (undocumented)
17-
export type ExistingLambda = {
18-
id: string;
19-
name: string;
12+
export type AuthorizerConfig = {
13+
type: 'none';
14+
} | {
15+
type: 'userPool';
16+
} | {
17+
type: 'userPool';
18+
groups: string[];
2019
};
2120

2221
// @public (undocumented)
2322
export type HttpMethod = 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH' | 'HEAD' | 'OPTIONS';
2423

2524
// @public (undocumented)
26-
export type LambdaSource = {
27-
runtime: lamb.Runtime;
28-
source: ExistingDirectory | ExistingLambda | NewFromCode;
29-
};
30-
31-
// @public (undocumented)
32-
export type NewFromCode = {
33-
code: string;
34-
functionName: string;
25+
export type MethodsProps = {
26+
method: HttpMethod;
27+
authorizer?: AuthorizerConfig;
3528
};
3629

3730
// @public
@@ -50,8 +43,8 @@ export type RestApiConstructProps = {
5043
// @public (undocumented)
5144
export type RestApiPathConfig = {
5245
path: string;
53-
methods: HttpMethod[];
54-
lambdaEntry: LambdaSource;
46+
methods: MethodsProps[];
47+
lambdaEntry: IFunction;
5548
};
5649

5750
// (No @packageDocumentation comment for this package)

packages/rest-api-construct/package.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,5 +20,9 @@
2020
"peerDependencies": {
2121
"aws-cdk-lib": "^2.158.0",
2222
"constructs": "^10.0.0"
23+
},
24+
"dependencies": {
25+
"@aws-amplify/backend": "^1.16.1",
26+
"@aws-amplify/backend-output-storage": "^1.3.1"
2327
}
2428
}
Lines changed: 79 additions & 178 deletions
Original file line numberDiff line numberDiff line change
@@ -1,204 +1,105 @@
11
import { describe, it } from 'node:test';
22
import { RestApiConstruct } from './construct.js';
33
import { App, Stack } from 'aws-cdk-lib';
4-
import { Template } from 'aws-cdk-lib/assertions';
5-
import * as lambda from 'aws-cdk-lib/aws-lambda';
6-
import { strictEqual } from 'assert';
7-
import * as fs from 'fs';
4+
import { defineFunction } from '@aws-amplify/backend';
5+
import { StackMetadataBackendOutputStorageStrategy } from '@aws-amplify/backend-output-storage';
6+
import {
7+
ConstructContainerStub,
8+
ResourceNameValidatorStub,
9+
StackResolverStub,
10+
} from '@aws-amplify/backend-platform-test-stubs';
11+
import { ConstructFactoryGetInstanceProps } from '@aws-amplify/plugin-types';
812

913
void describe('RestApiConstruct Lambda Handling', () => {
10-
void it('loads an existing local lambda function if the directory is specified', () => {
14+
void it('integrates the result of defineFunction into the api', () => {
1115
const app = new App();
1216
const stack = new Stack(app);
13-
new RestApiConstruct(stack, 'RestApiLambdaTest', {
14-
apiName: 'RestApiLambdaTest',
15-
apiProps: [
16-
{
17-
path: 'items',
18-
defaultAuthorizer: { type: 'none' },
19-
methods: [
20-
{
21-
method: 'GET',
22-
authorizer: { type: 'none' },
23-
},
24-
],
25-
lambdaEntry: {
26-
runtime: lambda.Runtime.NODEJS_18_X,
27-
source: { path: 'packages/rest-api-construct/lib/test-assets' },
28-
},
29-
},
30-
],
31-
});
32-
const template = Template.fromStack(stack);
33-
template.hasResourceProperties('AWS::Lambda::Function', {
34-
Handler: 'index.handler',
35-
});
36-
});
37-
38-
void it('creates a new lambda function if the code is specified', () => {
39-
const app = new App();
40-
const stack = new Stack(app);
41-
new RestApiConstruct(stack, 'RestApiNewLambdaTest', {
42-
apiName: 'RestApiNewLambda',
43-
apiProps: [
44-
{
45-
path: 'items',
46-
defaultAuthorizer: { type: 'none' },
47-
methods: [
48-
{
49-
method: 'GET',
50-
authorizer: { type: 'none' },
51-
},
52-
],
53-
lambdaEntry: {
54-
runtime: lambda.Runtime.NODEJS_22_X,
55-
source: {
56-
functionName: 'MyFunction1',
57-
code: "export const handler = () => {return 'Hello World! This is a new lambda function.';};",
58-
},
59-
},
60-
},
61-
],
62-
});
63-
const template = Template.fromStack(stack);
64-
template.hasResourceProperties('AWS::Lambda::Function', {
65-
Handler: 'index.handler',
66-
});
67-
});
68-
69-
void it('creates local files for a new function if the code is specified', () => {
70-
//delete folder amplify/functions/MyFunction2 first if the test has failed
71-
72-
//function files should not originally exist
73-
let src = process.cwd();
74-
src += '/amplify/functions/MyFunction2/';
75-
strictEqual(fs.existsSync(src + 'resource.ts'), false);
76-
strictEqual(fs.existsSync(src + 'handler.ts'), false);
77-
78-
//create the api containing a new lambda from source code
79-
const app = new App();
80-
const stack = new Stack(app);
81-
new RestApiConstruct(stack, 'RestApiNewLambda2', {
82-
apiName: 'RestApiNewLambda2',
83-
apiProps: [
84-
{
85-
path: 'items',
86-
methods: ['GET'],
87-
lambdaEntry: {
88-
runtime: lambda.Runtime.NODEJS_22_X,
89-
source: {
90-
functionName: 'MyFunction2',
91-
code: "export const handler = () => {return 'Hello World! This is a new lambda function.';};",
92-
},
93-
},
94-
},
95-
],
96-
});
97-
98-
//function files should have been created
99-
strictEqual(fs.existsSync(src + 'resource.ts'), true);
100-
strictEqual(fs.existsSync(src + 'handler.ts'), true);
101-
});
102-
103-
void it('loads a function from aws if the id and name are specified', () => {
104-
const app = new App();
105-
const funcStack = new Stack(app, 'funcStack');
106-
107-
const func = new lambda.Function(funcStack, 'testFunc', {
108-
runtime: lambda.Runtime.NODEJS_22_X,
109-
handler: 'index.handler',
110-
code: lambda.Code.fromInline(
111-
"export const handler = () => {return 'Hello World! This is an existing lambda function.';};",
112-
),
17+
const factory = defineFunction({
18+
name: 'Test Function',
19+
entry: './test-assets/handler.js',
11320
});
21+
const func = factory.getInstance;
11422

115-
const stack = new Stack(app, 'stack');
116-
new RestApiConstruct(stack, 'RestApiLoadFunc', {
117-
apiName: 'RestApiLoad',
118-
apiProps: [
119-
{
120-
path: 'stuff',
121-
methods: ['GET'],
122-
lambdaEntry: {
123-
runtime: lambda.Runtime.NODEJS_22_X,
124-
source: { id: func.functionArn, name: func.functionName },
125-
},
126-
},
127-
],
128-
});
129-
130-
const template = Template.fromStack(stack);
131-
//there should be no functions in the stack
132-
template.resourcePropertiesCountIs(
133-
'AWS::Lambda::Function',
134-
{ Arn: func.functionArn },
135-
0,
23+
//stubs for the instance props
24+
const constructContainer = new ConstructContainerStub(
25+
new StackResolverStub(stack),
13626
);
137-
//should be allowed to call the function
138-
template.hasResourceProperties('AWS::Lambda::Permission', {
139-
Action: 'lambda:InvokeFunction',
140-
Principal: 'apigateway.amazonaws.com',
141-
FunctionName: { 'Fn::GetAtt': [func.functionName, 'Arn'] },
142-
});
143-
//api should reference ARN
144-
template.hasResourceProperties('AWS::ApiGateway::Method', {
145-
Integration: {
146-
Uri: {
147-
'Fn::Sub': [
148-
'arn:aws:apigateway:${AWS::REGION}:lambda:path/2015-03-31/functions/${LambdaArn}/invocations',
149-
{ LambdaArn: func.functionArn },
150-
],
151-
},
152-
},
153-
});
154-
});
155-
});
27+
const outputStorageStrategy = new StackMetadataBackendOutputStorageStrategy(
28+
stack,
29+
);
30+
const resourceNameValidator = new ResourceNameValidatorStub();
31+
const getInstanceProps: ConstructFactoryGetInstanceProps = {
32+
constructContainer,
33+
outputStorageStrategy,
34+
resourceNameValidator,
35+
};
36+
37+
const f = func(getInstanceProps).resources.lambda;
15638

157-
void describe('RestApiConstruct', () => {
158-
void it('creates a queue if specified', () => {
159-
const app = new App();
160-
const stack = new Stack(app);
16139
new RestApiConstruct(stack, 'RestApiTest', {
16240
apiName: 'RestApiTest',
16341
apiProps: [
16442
{
165-
path: '/test',
43+
path: 'items',
44+
lambdaEntry: f,
16645
methods: [
16746
{
16847
method: 'GET',
16948
authorizer: { type: 'none' },
17049
},
17150
],
172-
lambdaEntry: {
173-
runtime: lambda.Runtime.NODEJS_18_X,
174-
source: {
175-
path: './test-lambda',
176-
},
177-
},
178-
},
179-
{
180-
path: '/blog',
181-
methods: [
182-
{
183-
method: 'POST',
184-
authorizer: { type: 'userPool', groups: ['Admins'] },
185-
},
186-
{
187-
method: 'GET',
188-
authorizer: { type: 'userPool' },
189-
},
190-
],
191-
defaultAuthorizer: { type: 'userPool' },
192-
lambdaEntry: {
193-
runtime: lambda.Runtime.NODEJS_18_X,
194-
source: {
195-
path: './blog-lambda',
196-
},
197-
},
19851
},
19952
],
20053
});
201-
const template = Template.fromStack(stack);
202-
template.resourceCountIs('AWS::AGW::RestApi', 1);
20354
});
20455
});
56+
57+
//test needs to be updated to new lambda handling
58+
// void describe('RestApiConstruct', () => {
59+
// void it('creates a queue if specified', () => {
60+
// const app = new App();
61+
// const stack = new Stack(app);
62+
// new RestApiConstruct(stack, 'RestApiTest', {
63+
// apiName: 'RestApiTest',
64+
// apiProps: [
65+
// {
66+
// path: '/test',
67+
// methods: [
68+
// {
69+
// method: 'GET',
70+
// authorizer: { type: 'none' },
71+
// },
72+
// ],
73+
// lambdaEntry: {
74+
// runtime: lambda.Runtime.NODEJS_18_X,
75+
// source: {
76+
// path: './test-lambda',
77+
// },
78+
// },
79+
// },
80+
// {
81+
// path: '/blog',
82+
// methods: [
83+
// {
84+
// method: 'POST',
85+
// authorizer: { type: 'userPool', groups: ['Admins'] },
86+
// },
87+
// {
88+
// method: 'GET',
89+
// authorizer: { type: 'userPool' },
90+
// },
91+
// ],
92+
// defaultAuthorizer: { type: 'userPool' },
93+
// lambdaEntry: {
94+
// runtime: lambda.Runtime.NODEJS_18_X,
95+
// source: {
96+
// path: './blog-lambda',
97+
// },
98+
// },
99+
// },
100+
// ],
101+
// });
102+
// const template = Template.fromStack(stack);
103+
// template.resourceCountIs('AWS::AGW::RestApi', 1);
104+
// });
105+
// });

0 commit comments

Comments
 (0)