Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Release alpha #82

Merged
merged 4 commits into from
Feb 8, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 8 additions & 1 deletion .eslintrc
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,13 @@
],
"rules": {
"prettier/prettier": 2, // Means error,
"@typescript-eslint/no-explicit-any": ["off"]
"@typescript-eslint/no-explicit-any": ["off"],
"@typescript-eslint/no-unused-vars": [
"error",
{
"argsIgnorePattern": "^_",
"varsIgnorePattern": "^_"
}
]
}
}
14 changes: 11 additions & 3 deletions .github/workflows/naming.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ name: Naming Conventions

on:
pull_request:
types: [opened, edited]
types: [opened, edited, synchronize]
branches:
- develop

Expand All @@ -11,6 +11,14 @@ jobs:
name: Naming Conventions
runs-on: ubuntu-latest
steps:
- uses: deepakputhraya/action-pr-title@master
- uses: amannn/action-semantic-pull-request@v5
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
regex: '(feat|fix|ci|docs|test|refactor|build|chore|script)\(.+\): .+'
types: |
feat
fix
ci
docs
chore
requireScope: true
69 changes: 30 additions & 39 deletions doc/matchers/appsync.md
Original file line number Diff line number Diff line change
@@ -1,54 +1,43 @@
# AppSync

A collection of matchers to test mapping templates.
A collection of matchers to test AWS AppSync mapping templates and JS resolvers.

Use the `appSyncMappingTemplate` helper function with mapping template matchers.
## Helper Functions

- `template`: A string representing the mapping template
### `appSyncResolver(input: AppSyncResolverInput)`

Use the `appSyncResolver` helper function to test JS resolvers.

- `code`: The path to a file containing an `APPSYNC_JS` resolver code. The path can either be absolute, or relative to the working directory (`process.cwd()`).
- `function`: The function to test. Must be `request` or `response`.
- `context`: The [context object](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-context-reference-js.html) to be passed to the function

### `appSyncMappingTemplate(input: AppSyncMappingTemplateInput)`

Use the `appSyncMappingTemplate` helper function to test VTL mapping templates.

- `template`: The path to a file containing a mapping template. The path can either be absolute, or relative to the working directory (`process.cwd()`).
- `context`: The [context object](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-context-reference.html#accessing-the-context) to be injected into the template

### `toEvaluateTo<E>(expected: E)`
## Matchers

Asserts that a mapping template evaluates to a given string or object for a given context.
### `toEvaluateTo<E>(expected: E)`

If you pass an object as `value`, the matcher will try to parse the generated template into a javascript object before comparing the values.
Asserts that a mapping template or resolver evaluates to a given object for a given context.

```typescript
// matching as a string
await expect(
appSyncMappingTemplate({
template: fs.readFileSync('tempalte.vtl', { encoding: 'utf8' }),
appSyncResolver({
code: __dirname + '/resolver.js',
function: 'request',
context: {
arguments: {
id: '123',
},
},
}),
).toEvaluateTo(`
{
"version" : "2017-02-28",
"operation" : "GetItem",
"key" : {
"pk" : {"S":"123"}
}
}
`);
```

```typescript
// matching as an object also works as long as the mapping template evaluates to a valid JSON
// otherwise, an error will be thrown
await expect(
appSyncMappingTemplate({
template: fs.readFileSync('tempalte.vtl', { encoding: 'utf8' }),
context: {
arguments: {
id: '123',
},
},
}),
).toEvaluateTo<DynamoDBGetItem>({
version: '2017-02-28',
).toEvaluateTo<DynamoDBGetItemRequest>({
operation: 'GetItem',
key: {
pk: { S: '123' },
Expand Down Expand Up @@ -88,12 +77,14 @@ await expect(
},
}),
).toEvaluateToInlineSnapshot(`
{
"version" : "2017-02-28",
"operation" : "GetItem",
"key" : {
"pk" : {"S":"123"}
}
Object {
"key": Object {
"pk": Object {
"S": "789",
},
},
"operation": "GetItem",
"version": "2017-02-28",
}
`);
```
94 changes: 94 additions & 0 deletions doc/matchers/cognito.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
# Cognito

A collection of matchers that you can use to assert on Cognito users.

Use the `cognitoUser()` helper function to specify which Cognito User you are testing. It takes the following input parameters:

- `userPoolId`: The user pool id where the user should be found.
- `username`: The user id you are looking for
- `retryPolicy`: An optional [node-retry](https://github.com/tim-kos/node-retry) options config. `sls-jest` will retry using the given retry policy until the test passes or all the retries are exhausted. This is useful in an asynchronous context.

### `toExist()`

Asserts whether a Cognito user exists in the given user pool.

```typescript
await expect(
cognitoUser({
userPoolId: 'my-pool',
username: 'user-1'
},
}),
).toExist();
```

### `toExistAndMatchObject<E>(expected: DeepPartial<E>)`

Asserts that a user exists in the given user pool, and matches a subset of the properties of an object. It works similarly to jest's [toMatchObject](https://jestjs.io/docs/expect#tomatchobjectobject).

```typescript
await expect(
cognitoUser({
userPoolId: 'my-pool',
username: 'user-1',
}),
).toExistAndMatchObject({
Enabled: true,
Username: 'user-1',
});
```

### `toExistAndMatchSnapshot<E>(propertyMatchers?: DeepPartial<E>, hint?: string)`

Asserts that a user exists in the given user pool, and that it matches the most recent snapshot. It works similarly to jest's [toMatchSnapshot](https://jestjs.io/docs/expect#tomatchsnapshotpropertymatchers-hint).

```typescript
await expect(
cognitoUser({
userPoolId: 'my-pool',
username: 'user-1',
}),
).toExistAndMatchSnapshot();
```

### `toExistAndMatchInlineSnapshot<E>(propertyMatchers?: DeepPartial<E>, hint?: string)`

Asserts that a user exists in the given user pool, and that it matches the most recent inline snapshot. It works similarly to jest's [toMatchInlineSnapshot](https://jestjs.io/docs/expect#tomatchinlinesnapshotpropertymatchers-inlinesnapshot).

```typescript
await expect(
cognitoUser({
userPoolId: 'my-pool',
username: 'user-1',
}),
).toExistAndMatchInlineSnapshot(
{
Enabled: true,
UserAttributes: expect.arrayContaining([
{
Name: 'email',
Value: expect.any(String),
},
]),
UserCreateDate: expect.any(Date),
UserLastModifiedDate: expect.any(Date),
UserStatus: 'CONFIRMED',
Username: expect.any(String),
},
`
Object {
"Enabled": true,
"UserAttributes": ArrayContaining [
Object {
"Name": "email",
"Value": Any<String>,
},
],
"UserCreateDate": Any<Date>,
"UserLastModifiedDate": Any<Date>,
"UserStatus": "CONFIRMED",
"Username": Any<String>,
}
`,
);
```
58 changes: 58 additions & 0 deletions doc/utils/cognito.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
# Cognito

## Functions

### `signUpCognitoUser`

Create a new user in cognito, auto confirm it and return its credentials.

example:

```typescript
const credentials = await signUpCognitoUser({
clientId: 'client_id',
userPoolId: 'user_pool_id',
username: '[email protected]',
password: 'my_password',
attributes: [
{
Name: 'email',
Value: '[email protected]',
},
],
});

// credentials = {AccessToken: string, IdToken: string, ...}
```

The returned value is of type [AuthenticationResultType](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_AuthenticationResultType.html) from @aws-sdk/client-cognito-identity-provider.

Note: this function is not idempotent, if the user already exists it will fail.

### `signInWithCognitoUser`

Sign in a user in cognito and return its credentials.

```typescript
const credentials = await signInWithCognitoUser({
clientId: 'client_id',
userPoolId: 'user_pool_id',
username: '[email protected]',
password: 'my_password',
});

// credentials = {AccessToken: string, IdToken: string, ...}
```

The returned value is of type [AuthenticationResultType](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_AuthenticationResultType.html) from @aws-sdk/client-cognito-identity-provider.

### `deleteCognitoUser`

Delete a user in cognito.

```typescript
await deleteCognitoUser({
userPoolId: 'user_pool_id',
username: '[email protected]',
});
```
36 changes: 36 additions & 0 deletions doc/utils/lambda.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# Lambda

## Functions

### `invokeLambdaFunction(input:{functionName: string; payload: object})`

Invoke a Lambda function.

Parameters:
- `functionName`: the Lambda function name
- `payload`: the payload/event to send to the Lambda function

Note: `invokeLambdaFunction` automatically parses the response from the Lambda function and returns either a `string` or an `object` (JSON object) depending on the returned value of the Lambda function: if the Lambda function returns a string, the result will be of type string; if it returns an object, the result will be of type object.

example:
```typescript
const result1 = await invokeLambdaFunction({
functionName: 'sum',
payload: {
a: 1,
b: 2,
},
});

console.log(result1) // 3

const result2 = await invokeLambdaFunction({
functionName: 'sum-json',
payload: {
a: 1,
b: 2,
},
});

console.log(result2) // { "result" : 3 }
```
15 changes: 12 additions & 3 deletions examples/__tests__/__snapshots__/appSync.test.ts.snap
Original file line number Diff line number Diff line change
@@ -1,6 +1,17 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`Mapping Template should evaluate a template snapshot as object 1`] = `
exports[`JS resolvers should evaluate a js resolver with snapshot 1`] = `
Object {
"key": Object {
"id": Object {
"S": "123",
},
},
"operation": "GetItem",
}
`;

exports[`Mapping Template should evaluate a template snapshot 1`] = `
Object {
"key": Object {
"pk": Object {
Expand All @@ -11,5 +22,3 @@ Object {
"version": "2017-02-28",
}
`;

exports[`Mapping Template should evaluate a template snapshot as string 1`] = `"hello 456"`;
17 changes: 17 additions & 0 deletions examples/__tests__/__snapshots__/cognito.test.ts.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`Matchers toExistAndMatchSnapshot should print values when user exists 1`] = `
Object {
"Enabled": true,
"UserAttributes": ArrayContaining [
Object {
"Name": "email",
"Value": Any<String>,
},
],
"UserCreateDate": Any<Date>,
"UserLastModifiedDate": Any<Date>,
"UserStatus": "CONFIRMED",
"Username": Any<String>,
}
`;
Loading
Loading