From e392e13eef60bf9699a62bfb1f2c89b89b148cf6 Mon Sep 17 00:00:00 2001 From: bboure Date: Thu, 18 Jan 2024 17:36:02 +0100 Subject: [PATCH 01/16] doc: Add JSDoc on all exported functions --- src/helpers/dynamodb.ts | 8 ++++++-- src/helpers/s3.ts | 8 ++++++-- src/index.ts | 21 ++++++++++++++++++--- src/utils/cognito.ts | 18 ++++++++++++++++++ src/utils/dynamodb.ts | 18 ++++++++++++++++++ 5 files changed, 66 insertions(+), 7 deletions(-) diff --git a/src/helpers/dynamodb.ts b/src/helpers/dynamodb.ts index a75f49e..04a79b0 100644 --- a/src/helpers/dynamodb.ts +++ b/src/helpers/dynamodb.ts @@ -3,12 +3,16 @@ import { GetCommandInput } from '@aws-sdk/lib-dynamodb'; import { z } from 'zod'; import { HelperZodSchema, - RetryableMatcherHelper, + RetriableMatcherHelper, assertMatcherHelperInputValue, } from './internal'; /** * DynamoDB Item helper input + * + * @param {string} tableName The DynamoDB table name. + * @param {object} key The DynamoDB item key. + * @param {object} clientConfig An optional DynamoDB SDK client configuration. */ export type DynamodbItemInput = { tableName: string; @@ -27,7 +31,7 @@ const dynamodbItemInputSchema: HelperZodSchema = z.object({ /** * DynamoDB Item helper */ -export const dynamodbItem: RetryableMatcherHelper< +export const dynamodbItem: RetriableMatcherHelper< 'dynamodbItem', DynamodbItemInput > = (input) => { diff --git a/src/helpers/s3.ts b/src/helpers/s3.ts index e471364..c17f478 100644 --- a/src/helpers/s3.ts +++ b/src/helpers/s3.ts @@ -2,12 +2,16 @@ import { S3Client } from '@aws-sdk/client-s3'; import { z } from 'zod'; import { HelperZodSchema, - RetryableMatcherHelper, + RetriableMatcherHelper, assertMatcherHelperInputValue, } from './internal'; /** * S3 Object helper input + * + * @param {string} bucketName The S3 bucket name. + * @param {string} key The S3 object key. + * @param {object} clientConfig An optional S3 SDK client configuration. */ export type S3ObjectInput = { bucketName: string; @@ -26,7 +30,7 @@ const s3ObjectInputSchema: HelperZodSchema = z.object({ /** * S3 Object helper */ -export const s3Object: RetryableMatcherHelper<'s3Object', S3ObjectInput> = ( +export const s3Object: RetriableMatcherHelper<'s3Object', S3ObjectInput> = ( input, ) => { assertMatcherHelperInputValue('s3Object', s3ObjectInputSchema, input); diff --git a/src/index.ts b/src/index.ts index 1e5e641..ff7ae42 100644 --- a/src/index.ts +++ b/src/index.ts @@ -74,10 +74,11 @@ declare global { /** * Asserts that the received value exists and matches the expected object. - * @param params //FIXME: + * + * @param {object} expected The expected object. */ toExistAndMatchObject( - params: O.Partial, + expected: O.Partial, ): Promise; /** @@ -114,9 +115,23 @@ declare global { } interface EventBridgeMatchers { + /** + * Asserts the the EventBridge spy has received an + * event matching the expected object. + * + * @param {object} expected The expected object. + */ toHaveEventMatchingObject( expected: O.Partial, 'deep'>, ): Promise; + + /** + * Asserts the the EventBridge spy has received an + * event matching the expected object a certain number of times. + * + * @param {object} expected The expected object. + * @param {number} times The (exact) number of times the event should have been received. + */ toHaveEventMatchingObjectTimes( expected: O.Partial, 'deep'>, times: number, @@ -136,7 +151,7 @@ declare global { // or the "default" `any` matcher from jest. (actual: IfAny): JestMatchers; - // AppSync matchers overload + // AppSync resolver matchers overload >( actual: T, ): AndNot; diff --git a/src/utils/cognito.ts b/src/utils/cognito.ts index bc52d3d..a564c2f 100644 --- a/src/utils/cognito.ts +++ b/src/utils/cognito.ts @@ -11,6 +11,12 @@ import { getCognitoClient } from './internal'; /** * Sign in a user in cognito and return its credentials. + * + * @param {string} clientId The cognito user pool client id. + * @param {string} userPoolId The cognito user pool id. + * @param {string} username The cognito user username. + * @param {string} password The cognito user password. + * @param {CognitoIdentityProviderClientConfig} config An optional cognito client configuration. */ export const cognitoSignIn = async (params: { clientId: string; @@ -43,6 +49,14 @@ export const cognitoSignIn = async (params: { /** * Create a new user in cognito, auto confirm it and return its credentials. + * + * @param {string} clientId The cognito user pool client id. + * @param {string} userPoolId The cognito user pool id. + * @param {string} username The cognito user username. + * @param {string} password The cognito user password. + * @param {AttributeType[]} attributes The cognito user attributes. + * @param {CognitoIdentityProviderClientConfig} config An optional cognito client configuration. + * */ export const cognitoSignUp = async (params: { clientId: string; @@ -85,6 +99,10 @@ export const cognitoSignUp = async (params: { /** * Delete a user in cognito. + * + * @param {string} userPoolId The cognito user pool id. + * @param {string} username The cognito user username. + * @param {CognitoIdentityProviderClientConfig} config An optional cognito client configuration. */ export const cognitoDeleteUser = async (params: { userPoolId: string; diff --git a/src/utils/dynamodb.ts b/src/utils/dynamodb.ts index e4eb184..759e5bf 100644 --- a/src/utils/dynamodb.ts +++ b/src/utils/dynamodb.ts @@ -12,6 +12,12 @@ export type DynamoDBItemCollection = [itemName: string]: DynamoDBItem | DynamoDBItem[]; }; +/** + * Feed a table with items + * + * @param {string} tableName The table name + * @param {DynamoDBItemCollection} items The items to feed the table with + */ export const feedTable = async ( tableName: string, items: DynamoDBItemCollection, @@ -37,6 +43,11 @@ export const feedTable = async ( } }; +/** + * Feed multiple tables with items + * + * @param {Record} items A Key-Value pair of table name and items to insert + */ export const feedTables = async (items: { [tableName: string]: DynamoDBItemCollection; }) => { @@ -115,6 +126,13 @@ const getTableKeys = async (tableName: string) => { return tableKeys[tableName]; }; +/** + * Truncate a DynamoDB table + * + * @param {string} tableName The table name + * @param {string[]} keys Optional. They attribute names of the table keys (PK and optional SK). + * If not provided, the keys will be inferred from the table schema. + */ export const truncateTable = async (tableName: string, keys?: string[]) => { const client = getDynamoDBDocumentClient(); const key = keys ?? (await getTableKeys(tableName)); From 1d6d4ff11dcd7eb459a527496911caca1c17a494 Mon Sep 17 00:00:00 2001 From: bboure Date: Thu, 18 Jan 2024 17:36:09 +0100 Subject: [PATCH 02/16] more --- src/helpers/dynamodb.ts | 4 ++-- src/helpers/s3.ts | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/helpers/dynamodb.ts b/src/helpers/dynamodb.ts index 04a79b0..fd92cb1 100644 --- a/src/helpers/dynamodb.ts +++ b/src/helpers/dynamodb.ts @@ -3,7 +3,7 @@ import { GetCommandInput } from '@aws-sdk/lib-dynamodb'; import { z } from 'zod'; import { HelperZodSchema, - RetriableMatcherHelper, + RetryableMatcherHelper, assertMatcherHelperInputValue, } from './internal'; @@ -31,7 +31,7 @@ const dynamodbItemInputSchema: HelperZodSchema = z.object({ /** * DynamoDB Item helper */ -export const dynamodbItem: RetriableMatcherHelper< +export const dynamodbItem: RetryableMatcherHelper< 'dynamodbItem', DynamodbItemInput > = (input) => { diff --git a/src/helpers/s3.ts b/src/helpers/s3.ts index c17f478..b5a2515 100644 --- a/src/helpers/s3.ts +++ b/src/helpers/s3.ts @@ -2,7 +2,7 @@ import { S3Client } from '@aws-sdk/client-s3'; import { z } from 'zod'; import { HelperZodSchema, - RetriableMatcherHelper, + RetryableMatcherHelper, assertMatcherHelperInputValue, } from './internal'; @@ -30,7 +30,7 @@ const s3ObjectInputSchema: HelperZodSchema = z.object({ /** * S3 Object helper */ -export const s3Object: RetriableMatcherHelper<'s3Object', S3ObjectInput> = ( +export const s3Object: RetryableMatcherHelper<'s3Object', S3ObjectInput> = ( input, ) => { assertMatcherHelperInputValue('s3Object', s3ObjectInputSchema, input); From 595df296615e41b3c081ba0d66f9a6e15a26d8bf Mon Sep 17 00:00:00 2001 From: bboure Date: Thu, 18 Jan 2024 21:51:48 +0100 Subject: [PATCH 03/16] allow PR names without () --- src/utils/dynamodb.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/utils/dynamodb.ts b/src/utils/dynamodb.ts index 759e5bf..9bd930c 100644 --- a/src/utils/dynamodb.ts +++ b/src/utils/dynamodb.ts @@ -16,7 +16,7 @@ export type DynamoDBItemCollection = * Feed a table with items * * @param {string} tableName The table name - * @param {DynamoDBItemCollection} items The items to feed the table with + * @param {DynamoDBItemCollection} items The items to feed the table with. {@link DynamoDBItemCollection} */ export const feedTable = async ( tableName: string, @@ -46,7 +46,7 @@ export const feedTable = async ( /** * Feed multiple tables with items * - * @param {Record} items A Key-Value pair of table name and items to insert + * @param {Record} items A Key-Value pair of table name and items to insert. (@link DynamoDBItemCollection) */ export const feedTables = async (items: { [tableName: string]: DynamoDBItemCollection; From fc8e8be431fb7d500f6a3cc179a77cc2d18a51ef Mon Sep 17 00:00:00 2001 From: bboure Date: Fri, 19 Jan 2024 09:04:21 +0100 Subject: [PATCH 04/16] Improve JSDoc and types --- .github/workflows/naming.yml | 2 +- examples/__tests__/cognito.test.ts | 9 ++- src/helpers/appsync.ts | 78 +++++++++++++++---- src/helpers/cognito.ts | 22 +++++- src/helpers/dynamodb.ts | 29 ++++++-- src/helpers/s3.ts | 27 +++++-- src/index.ts | 30 ++++---- src/spies/eventBridge/index.ts | 18 +++++ src/utils/cognito.ts | 115 ++++++++++++++++++----------- src/utils/dynamodb.ts | 38 ++++++++-- 10 files changed, 279 insertions(+), 89 deletions(-) diff --git a/.github/workflows/naming.yml b/.github/workflows/naming.yml index 38bdeb3..9107098 100644 --- a/.github/workflows/naming.yml +++ b/.github/workflows/naming.yml @@ -13,4 +13,4 @@ jobs: steps: - uses: deepakputhraya/action-pr-title@master with: - regex: '(feat|fix|ci|docs|test|refactor|build|chore|script)\(.+\): .+' + regex: '(feat|fix|ci|docs|test|refactor|build|chore|script)(\(.+\))?: .+' diff --git a/examples/__tests__/cognito.test.ts b/examples/__tests__/cognito.test.ts index 21c6100..f86fdd1 100644 --- a/examples/__tests__/cognito.test.ts +++ b/examples/__tests__/cognito.test.ts @@ -1,5 +1,10 @@ import { Chance } from 'chance'; -import { cognitoSignIn, cognitoSignUp, cognitoUser } from 'sls-jest'; +import { + CognitoUserInput, + cognitoSignIn, + cognitoSignUp, + cognitoUser, +} from 'sls-jest'; const chance = new Chance(); @@ -84,8 +89,8 @@ describe('Utils', () => { }); const credentials = await cognitoSignIn({ - clientId, userPoolId, + clientId, username: email, password, }); diff --git a/src/helpers/appsync.ts b/src/helpers/appsync.ts index fdede8e..6dfb5bd 100644 --- a/src/helpers/appsync.ts +++ b/src/helpers/appsync.ts @@ -8,6 +8,9 @@ import { Context } from '@aws-appsync/utils'; import { O } from 'ts-toolbelt'; import { z } from 'zod'; +/** + * Partial AWS AppSync context + */ type PartialContext = O.Partial< Context< Record, @@ -23,8 +26,17 @@ type PartialContext = O.Partial< * AppSync mapping template helper input */ export type AppSyncMappingTemplateInput = { + /** + * The path to a file containing containing a mapping template. + */ template: string; + /** + * The context to pass to the resolver function. + */ context: PartialContext; + /** + * An optional AppSync SDK client configuration. + */ clientConfig?: AppSyncClientConfig; }; @@ -39,14 +51,28 @@ const appSyncMappingTemplateInputSchema: HelperZodSchema< }); /** - * AppSync mapping template matcher helper. + * Helper that represents an AppSync mapping template. + * + * Use with {@link expect} and any compatible matcher. + * @see https://serverlessguru.gitbook.io/sls-jest/matchers/appsync * - * Use it to evaluate a mapping template and assert on the result. + * @param input {@link AppSyncMappingTemplateInput} * - * @param {string} template The path to a file containing containing a mapping template. - * The path can either be absolute, or relative to the working directory (`process.cwd()`). - * @param {object} context The context to pass to the resolver function. - * @param {object} clientConfig An optional AppSync SDK client configuration. + * @example + * + * expect(appSyncMappingTemplate({ + * template: 'src/resolvers/request.vtl', + * context: { + * arguments: { + * id: '123' + * } + * } + * })).toEvaluateTo({ + * operation: 'GetItem', + * key: { + * id: { S: '123' } + * } + * }); */ export const appSyncMappingTemplate: MatcherHelper< 'appSyncMappingTemplate', @@ -68,9 +94,21 @@ export const appSyncMappingTemplate: MatcherHelper< * AppSync js resolver helper input */ export type AppSyncResolverInput = { + /** + * The path to a file containing an `APPSYNC_JS` resolver code. + */ code: string; + /** + * The function to evaluate. `request` or `response`. + */ function: 'request' | 'response'; + /** + * The context to pass to the resolver function. + */ context: PartialContext; + /** + * An optional AppSync SDK client configuration. + */ clientConfig?: AppSyncClientConfig; }; @@ -85,15 +123,29 @@ const appSyncResolverInputSchema: HelperZodSchema = }); /** - * AppSync Resolver matcher helper. + * Helper that represents an AppSync js resolver. + * + * Use with {@link expect} and any compatible matcher. + * @see https://serverlessguru.gitbook.io/sls-jest/matchers/appsync + * + * @param input {@link AppSyncResolverInput} * - * Use it to evaluate a js resolver and assert on the result. + * @example * - * @param {string} 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()`). - * @param {string} function The function to evaluate. `request` or `response`. - * @param {object} context The context to pass to the resolver function. - * @param {object} clientConfig An optional AppSync SDK client configuration. + * expect(appSyncResolver({ + * code: 'src/resolvers/request.js', + * function: 'request', + * context: { + * arguments: { + * id: '123' + * } + * } + * })).toEvaluateTo({ + * operation: 'GetItem', + * key: { + * id: { S: '123' } + * } + * }); */ export const appSyncResolver: MatcherHelper< 'appSyncResolver', diff --git a/src/helpers/cognito.ts b/src/helpers/cognito.ts index cce3583..986e6a1 100644 --- a/src/helpers/cognito.ts +++ b/src/helpers/cognito.ts @@ -10,8 +10,17 @@ import { * Cognito User helper input */ export type CognitoUserInput = { + /** + * The cognito user pool id. + */ userPoolId: string; + /** + * The cognito user username. + */ username: string; + /** + * An optional cognito client configuration. + */ clientConfig?: CognitoIdentityProviderClientConfig; }; @@ -24,7 +33,18 @@ const cognitoUserInputSchema: HelperZodSchema = z.object({ }); /** - * Cognito User helper + * Helper function that represents a Cognito User. + * + * Use with {@link expect} and any compatible matcher. + * + * @param input {@link CognitoUserInput} + * + * @example + * + * expect(cognitoUser({ + * userPoolId: 'us-east-1_123456789', + * username: 'john' + * })).toExist(); */ export const cognitoUser: RetryableMatcherHelper< 'cognitoUser', diff --git a/src/helpers/dynamodb.ts b/src/helpers/dynamodb.ts index fd92cb1..bd172a5 100644 --- a/src/helpers/dynamodb.ts +++ b/src/helpers/dynamodb.ts @@ -9,14 +9,19 @@ import { /** * DynamoDB Item helper input - * - * @param {string} tableName The DynamoDB table name. - * @param {object} key The DynamoDB item key. - * @param {object} clientConfig An optional DynamoDB SDK client configuration. */ export type DynamodbItemInput = { + /** + * The DynamoDB table name. + */ tableName: string; + /** + * The DynamoDB item key. + */ key: GetCommandInput['Key']; + /** + * An optional DynamoDB SDK client configuration. + */ clientConfig?: DynamoDBClientConfig; }; @@ -29,7 +34,21 @@ const dynamodbItemInputSchema: HelperZodSchema = z.object({ }); /** - * DynamoDB Item helper + * Helper function that represents a DynamoDB Item. + * + * Use with {@link expect} and any compatible matcher. + * @see https://serverlessguru.gitbook.io/sls-jest/matchers/dynamodb + * + * @param input {@link DynamodbItemInput} + * + * @example + * + * expect(dynamodbItem({ + * tableName: 'users', + * key: { + * id: '1' + * } + * })).toExist(); */ export const dynamodbItem: RetryableMatcherHelper< 'dynamodbItem', diff --git a/src/helpers/s3.ts b/src/helpers/s3.ts index b5a2515..b00112e 100644 --- a/src/helpers/s3.ts +++ b/src/helpers/s3.ts @@ -8,14 +8,19 @@ import { /** * S3 Object helper input - * - * @param {string} bucketName The S3 bucket name. - * @param {string} key The S3 object key. - * @param {object} clientConfig An optional S3 SDK client configuration. */ export type S3ObjectInput = { + /** + * The S3 bucket name. + */ bucketName: string; + /** + * The S3 object key. + */ key: string; + /** + * An optional S3 SDK client configuration. + */ clientConfig?: S3Client; }; @@ -28,7 +33,19 @@ const s3ObjectInputSchema: HelperZodSchema = z.object({ }); /** - * S3 Object helper + * Helper function that represents an S3 Object. + * + * Use with {@link expect} and any compatible matcher. + * @see https://serverlessguru.gitbook.io/sls-jest/matchers/s3 + * + * @param input {@link S3ObjectInput} + * + * @example + * + * expect(s3Object({ + * bucketName: 'my-bucket', + * key: 'invoice123.pdf' + * })).toExist(); */ export const s3Object: RetryableMatcherHelper<'s3Object', S3ObjectInput> = ( input, diff --git a/src/index.ts b/src/index.ts index ff7ae42..518274a 100644 --- a/src/index.ts +++ b/src/index.ts @@ -22,7 +22,7 @@ declare global { * Asserts that the received AppSync resolver evaluation * matches the expected object. * - * @param {object} expected The expected object. + * @param expected The expected object. */ toEvaluateTo(expected: E): Promise; @@ -30,7 +30,7 @@ declare global { * Asserts that the received AppSync resolver evaluation * matches the existing snapshot. * - * @param {string} snapshotName Optional snapshot name. + * @param snapshotName Optional snapshot name. */ toEvaluateToSnapshot(snapshotName?: string): Promise; @@ -38,8 +38,8 @@ declare global { * Asserts that the received AppSync resolver evaluation * matches the existing snapshot. * - * @param {object} propertyMatchers The snapshot properties. - * @param {string} snapshotName Optional snapshot name. + * @param propertyMatchers The snapshot properties. + * @param snapshotName Optional snapshot name. */ toEvaluateToSnapshot( propertyMatchers: Partial, @@ -57,8 +57,8 @@ declare global { * Asserts that the received AppSync resolver evaluation * matches the inline snapshot. * - * @param {object} propertyMatchers The snapshot properties. - * @param {string} snapshot The expected snapshot. + * @param propertyMatchers The snapshot properties. + * @param snapshot The expected snapshot. */ toEvaluateToInlineSnapshot( propertyMatchers: Partial, @@ -75,7 +75,7 @@ declare global { /** * Asserts that the received value exists and matches the expected object. * - * @param {object} expected The expected object. + * @param expected The expected object. */ toExistAndMatchObject( expected: O.Partial, @@ -83,14 +83,14 @@ declare global { /** * Asserts that the received value exists and matches the expected snapshot. - * @param {string} snapshotName Optional snapshot name. + * @param snapshotName Optional snapshot name. */ toExistAndMatchSnapshot(snapshotName?: string): Promise; /** * Asserts that the received value exists and matches the expected snapshot. - * @param {object} propertyMatchers The snapshot properties. - * @param {string} snapshotName Optional snapshot name. + * @param propertyMatchers The snapshot properties. + * @param snapshotName Optional snapshot name. */ toExistAndMatchSnapshot( propertyMatchers: Partial, @@ -105,8 +105,8 @@ declare global { /** * Asserts that the received value exists and matches the expected snapshot. - * @param {object} propertyMatchers The snapshot properties. - * @param {string} snapshotName Optional snapshot name. + * @param propertyMatchers The snapshot properties. + * @param snapshotName Optional snapshot name. */ toExistAndMatchInlineSnapshot( propertyMatchers: Partial, @@ -119,7 +119,7 @@ declare global { * Asserts the the EventBridge spy has received an * event matching the expected object. * - * @param {object} expected The expected object. + * @param expected The expected object. */ toHaveEventMatchingObject( expected: O.Partial, 'deep'>, @@ -129,8 +129,8 @@ declare global { * Asserts the the EventBridge spy has received an * event matching the expected object a certain number of times. * - * @param {object} expected The expected object. - * @param {number} times The (exact) number of times the event should have been received. + * @param expected The expected object. + * @param times The (exact) number of times the event should have been received. */ toHaveEventMatchingObjectTimes( expected: O.Partial, 'deep'>, diff --git a/src/spies/eventBridge/index.ts b/src/spies/eventBridge/index.ts index 0589716..04e5b67 100644 --- a/src/spies/eventBridge/index.ts +++ b/src/spies/eventBridge/index.ts @@ -7,6 +7,10 @@ import { EventBridgeSpy } from './EventBridgeSpy'; import { SQSEventBridgeSpy, SqsEventSpyConfig } from './SqsEventBridgeSpy'; export type { EventBridgeSpy } from './EventBridgeSpy'; + +/** + * EventBridge spy parameters + */ export type EventBridgeSpyParams = { eventBusName: string; } & ( @@ -20,6 +24,20 @@ export type EventBridgeSpyParams = { } ); +/** + * Creates an EventBridge spy. + * + * Use with {@link expect} and any compatible matcher. + * @see https://serverlessguru.gitbook.io/sls-jest/matchers/eventbridge + * + * @param params {@link EventBridgeSpyParams} + * + * @example + * + * const spy = await eventBridgeSpy({ + * eventBusName: 'default', + * }); + */ export const eventBridgeSpy = async (params: EventBridgeSpyParams) => { const { eventBusName, adapter, config } = params; diff --git a/src/utils/cognito.ts b/src/utils/cognito.ts index a564c2f..8cefaff 100644 --- a/src/utils/cognito.ts +++ b/src/utils/cognito.ts @@ -9,24 +9,45 @@ import { } from '@aws-sdk/client-cognito-identity-provider'; import { getCognitoClient } from './internal'; +type CognitoInput = { + /** + * An optional cognito client configuration. + */ + clientConfig?: CognitoIdentityProviderClientConfig; +}; + /** - * Sign in a user in cognito and return its credentials. - * - * @param {string} clientId The cognito user pool client id. - * @param {string} userPoolId The cognito user pool id. - * @param {string} username The cognito user username. - * @param {string} password The cognito user password. - * @param {CognitoIdentityProviderClientConfig} config An optional cognito client configuration. + * Cognito Sign In input */ -export const cognitoSignIn = async (params: { - clientId: string; +export type CognitoSignInInput = { + /** + * The cognito user pool id. + */ userPoolId: string; + /** + * The cognito user pool client id. + */ + clientId: string; + /** + * The cognito user username. + */ username: string; + /** + * The cognito user password. + */ password: string; - config?: CognitoIdentityProviderClientConfig; -}): Promise => { - const { clientId, userPoolId, username, password, config } = params; - const client = getCognitoClient(config); +} & CognitoInput; + +/** + * Sign in a user in cognito and return its credentials. + * + * @param input {@link CognitoSignInInput} + */ +export const cognitoSignIn = async ( + input: CognitoSignInInput, +): Promise => { + const { clientId, userPoolId, username, password, clientConfig } = input; + const client = getCognitoClient(clientConfig); const { AuthenticationResult } = await client.send( new AdminInitiateAuthCommand({ @@ -47,28 +68,27 @@ export const cognitoSignIn = async (params: { return AuthenticationResult; }; +/** + * Cognito Sign Up input + */ +export type CognitoSignUpInput = CognitoSignInInput & { + /** + * The cognito user attributes. + */ + attributes?: AttributeType[]; +}; + /** * Create a new user in cognito, auto confirm it and return its credentials. * - * @param {string} clientId The cognito user pool client id. - * @param {string} userPoolId The cognito user pool id. - * @param {string} username The cognito user username. - * @param {string} password The cognito user password. - * @param {AttributeType[]} attributes The cognito user attributes. - * @param {CognitoIdentityProviderClientConfig} config An optional cognito client configuration. - * + * @param input {@link CognitoSignUpInput} */ -export const cognitoSignUp = async (params: { - clientId: string; - userPoolId: string; - username: string; - password: string; - attributes?: AttributeType[]; - config?: CognitoIdentityProviderClientConfig; -}): Promise => { - const { clientId, userPoolId, username, password, attributes, config } = - params; - const client = getCognitoClient(config); +export const cognitoSignUp = async ( + input: CognitoSignUpInput, +): Promise => { + const { clientId, userPoolId, username, password, attributes, clientConfig } = + input; + const client = getCognitoClient(clientConfig); await client.send( new AdminCreateUserCommand({ @@ -93,24 +113,35 @@ export const cognitoSignUp = async (params: { userPoolId, password, username, - config, + clientConfig, }); }; +export type CognitoUserInput = { + /** + * The cognito user pool id. + */ + userPoolId: string; + /** + * The cognito user username. + */ + username: string; + /** + * An optional cognito client configuration. + */ + clientConfig?: CognitoIdentityProviderClientConfig; +} & CognitoInput; + /** * Delete a user in cognito. * - * @param {string} userPoolId The cognito user pool id. - * @param {string} username The cognito user username. - * @param {CognitoIdentityProviderClientConfig} config An optional cognito client configuration. + * @param input {@link CognitoUserInput} */ -export const cognitoDeleteUser = async (params: { - userPoolId: string; - username: string; - config?: CognitoIdentityProviderClientConfig; -}): Promise => { - const { userPoolId, username, config } = params; - const client = getCognitoClient(config); +export const cognitoDeleteUser = async ( + input: CognitoUserInput, +): Promise => { + const { userPoolId, username, clientConfig } = input; + const client = getCognitoClient(clientConfig); await client.send( new AdminDeleteUserCommand({ diff --git a/src/utils/dynamodb.ts b/src/utils/dynamodb.ts index 9bd930c..c9282be 100644 --- a/src/utils/dynamodb.ts +++ b/src/utils/dynamodb.ts @@ -4,8 +4,36 @@ import { chunk, flatten, groupBy, map, pick, reduce } from 'lodash'; import { getDynamoDBDocumentClient } from './internal'; import { BatchWriteCommandInput } from '@aws-sdk/lib-dynamodb'; +/** + * A DynamoDB item + */ export type DynamoDBItem = Record; +/** + * A collection of DynamoDB items + * + * It can be an array of items, or a key-value pair of item names and items. + * + * @example + * + * const items: DynamoDBItemCollection = [ + * { + * "id": "1", + * "name": "John Doe" + * } + * ]; + * + * const items: DynamoDBItemCollection = { + * "user1": { + * "id": "1", + * "name": "John Doe" + * }, + * "user2": { + * "id": "2", + * "name": "Jane Doe" + * }, + * }; + */ export type DynamoDBItemCollection = | DynamoDBItem[] | { @@ -15,8 +43,8 @@ export type DynamoDBItemCollection = /** * Feed a table with items * - * @param {string} tableName The table name - * @param {DynamoDBItemCollection} items The items to feed the table with. {@link DynamoDBItemCollection} + * @param tableName The table name + * @param items The items to feed the table with. {@link DynamoDBItemCollection} */ export const feedTable = async ( tableName: string, @@ -46,7 +74,7 @@ export const feedTable = async ( /** * Feed multiple tables with items * - * @param {Record} items A Key-Value pair of table name and items to insert. (@link DynamoDBItemCollection) + * @param items A Key-Value pair of table name and items to insert. {@link DynamoDBItemCollection} */ export const feedTables = async (items: { [tableName: string]: DynamoDBItemCollection; @@ -129,8 +157,8 @@ const getTableKeys = async (tableName: string) => { /** * Truncate a DynamoDB table * - * @param {string} tableName The table name - * @param {string[]} keys Optional. They attribute names of the table keys (PK and optional SK). + * @param tableName The table name + * @param keys Optional. They attribute names of the table keys (PK and optional SK). * If not provided, the keys will be inferred from the table schema. */ export const truncateTable = async (tableName: string, keys?: string[]) => { From bdb44d0d1a294285ec5b745769781af3dce0c877 Mon Sep 17 00:00:00 2001 From: bboure Date: Fri, 19 Jan 2024 09:53:44 +0100 Subject: [PATCH 05/16] fixes --- doc/matchers/cognito.md | 9 ++++----- doc/utils/cognito.md | 7 ++----- examples/__tests__/cognito.test.ts | 7 +------ src/utils/cognito.ts | 6 +++--- 4 files changed, 10 insertions(+), 19 deletions(-) diff --git a/doc/matchers/cognito.md b/doc/matchers/cognito.md index c630e41..a5af1ce 100644 --- a/doc/matchers/cognito.md +++ b/doc/matchers/cognito.md @@ -30,11 +30,11 @@ Asserts that a user exists in the given user pool, and matches a subset of the p await expect( cognitoUser({ userPoolId: 'my-pool', - username: 'user-1' + username: 'user-1', }), ).toExistAndMatchObject({ Enabled: true, - Username: 'user-1' + Username: 'user-1', }); ``` @@ -46,7 +46,7 @@ Asserts that a user exists in the given user pool, and that it matches the most await expect( cognitoUser({ userPoolId: 'my-pool', - username: 'user-1' + username: 'user-1', }), ).toExistAndMatchSnapshot(); ``` @@ -56,11 +56,10 @@ await expect( 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' + username: 'user-1', }), ).toExistAndMatchInlineSnapshot( { diff --git a/doc/utils/cognito.md b/doc/utils/cognito.md index 2656d63..7480224 100644 --- a/doc/utils/cognito.md +++ b/doc/utils/cognito.md @@ -4,7 +4,6 @@ ### `cognitoSignUp` - Create a new user in cognito, auto confirm it and return its credentials. example: @@ -25,6 +24,7 @@ const credentials = await cognitoSignUp({ // 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. @@ -33,7 +33,6 @@ Note: this function is not idempotent, if the user already exists it will fail. Sign in a user in cognito and return its credentials. - ```typescript const credentials = await cognitoSignIn({ clientId: 'client_id', @@ -49,8 +48,7 @@ The returned value is of type [AuthenticationResultType](https://docs.aws.amazon ### `cognitoDeleteUser` -Delete a user in cognito. - +Deletes a user in cognito. ```typescript await cognitoDeleteUser({ @@ -58,4 +56,3 @@ await cognitoDeleteUser({ username: 'someone@example.com', }); ``` - diff --git a/examples/__tests__/cognito.test.ts b/examples/__tests__/cognito.test.ts index f86fdd1..d1ab708 100644 --- a/examples/__tests__/cognito.test.ts +++ b/examples/__tests__/cognito.test.ts @@ -1,10 +1,5 @@ import { Chance } from 'chance'; -import { - CognitoUserInput, - cognitoSignIn, - cognitoSignUp, - cognitoUser, -} from 'sls-jest'; +import { cognitoSignIn, cognitoSignUp, cognitoUser } from 'sls-jest'; const chance = new Chance(); diff --git a/src/utils/cognito.ts b/src/utils/cognito.ts index 8cefaff..a1d3668 100644 --- a/src/utils/cognito.ts +++ b/src/utils/cognito.ts @@ -117,7 +117,7 @@ export const cognitoSignUp = async ( }); }; -export type CognitoUserInput = { +export type DeleteCognitoUserInput = { /** * The cognito user pool id. */ @@ -135,10 +135,10 @@ export type CognitoUserInput = { /** * Delete a user in cognito. * - * @param input {@link CognitoUserInput} + * @param input {@link DeleteCognitoUserInput} */ export const cognitoDeleteUser = async ( - input: CognitoUserInput, + input: DeleteCognitoUserInput, ): Promise => { const { userPoolId, username, clientConfig } = input; const client = getCognitoClient(clientConfig); From 136495b5771e7765a9db535195840acb73e9d39e Mon Sep 17 00:00:00 2001 From: bboure Date: Fri, 19 Jan 2024 11:02:00 +0100 Subject: [PATCH 06/16] more doc --- src/helpers/appsync.ts | 4 ++-- src/helpers/cognito.ts | 2 +- src/helpers/dynamodb.ts | 2 +- src/helpers/s3.ts | 2 +- src/spies/eventBridge/EventBridgeSpy.ts | 27 +++++++++++++++++++++++++ src/spies/eventBridge/index.ts | 6 ++++-- 6 files changed, 36 insertions(+), 7 deletions(-) diff --git a/src/helpers/appsync.ts b/src/helpers/appsync.ts index 6dfb5bd..df707aa 100644 --- a/src/helpers/appsync.ts +++ b/src/helpers/appsync.ts @@ -51,7 +51,7 @@ const appSyncMappingTemplateInputSchema: HelperZodSchema< }); /** - * Helper that represents an AppSync mapping template. + * Helper function to describe an AppSync mapping template to test. * * Use with {@link expect} and any compatible matcher. * @see https://serverlessguru.gitbook.io/sls-jest/matchers/appsync @@ -123,7 +123,7 @@ const appSyncResolverInputSchema: HelperZodSchema = }); /** - * Helper that represents an AppSync js resolver. + * Helper function that describes an AppSync js resolver to test. * * Use with {@link expect} and any compatible matcher. * @see https://serverlessguru.gitbook.io/sls-jest/matchers/appsync diff --git a/src/helpers/cognito.ts b/src/helpers/cognito.ts index 986e6a1..6b37d28 100644 --- a/src/helpers/cognito.ts +++ b/src/helpers/cognito.ts @@ -33,7 +33,7 @@ const cognitoUserInputSchema: HelperZodSchema = z.object({ }); /** - * Helper function that represents a Cognito User. + * Helper function that describes a Cognito User to test. * * Use with {@link expect} and any compatible matcher. * diff --git a/src/helpers/dynamodb.ts b/src/helpers/dynamodb.ts index bd172a5..0c3e279 100644 --- a/src/helpers/dynamodb.ts +++ b/src/helpers/dynamodb.ts @@ -34,7 +34,7 @@ const dynamodbItemInputSchema: HelperZodSchema = z.object({ }); /** - * Helper function that represents a DynamoDB Item. + * Helper function that describes a DynamoDB Item to test. * * Use with {@link expect} and any compatible matcher. * @see https://serverlessguru.gitbook.io/sls-jest/matchers/dynamodb diff --git a/src/helpers/s3.ts b/src/helpers/s3.ts index b00112e..e3210a6 100644 --- a/src/helpers/s3.ts +++ b/src/helpers/s3.ts @@ -33,7 +33,7 @@ const s3ObjectInputSchema: HelperZodSchema = z.object({ }); /** - * Helper function that represents an S3 Object. + * Helper function that describes an S3 Object to test. * * Use with {@link expect} and any compatible matcher. * @see https://serverlessguru.gitbook.io/sls-jest/matchers/s3 diff --git a/src/spies/eventBridge/EventBridgeSpy.ts b/src/spies/eventBridge/EventBridgeSpy.ts index b4777f0..fcaa653 100644 --- a/src/spies/eventBridge/EventBridgeSpy.ts +++ b/src/spies/eventBridge/EventBridgeSpy.ts @@ -35,6 +35,11 @@ export class EventBridgeSpy { this.subject.next(this.events); } + /** + * Returns a promise that resolves when the passed matcher function returns true. + * + * This method is used by matchers. You should probably never use this directly. + */ awaitEvents( matcher: EventMatcher, config?: EventBridgeMatcherOptions, @@ -55,12 +60,34 @@ export class EventBridgeSpy { }); } + /** + * Resets the spy and removes all the events that have been captured. + * + * Use this method in an `afterEach` block. + * + * @example + * + * afterEach(() => { + * spy.reset(); + * }); + */ reset() { this.events = []; this.subject.complete(); this.subject = new BehaviorSubject(this.events); } + /** + * Stop spying on the EventBridge bus. + * + * Use this method in an `afterAll` block. + * + * @example + * + * afterAll(async () => { + * await spy.stop(); + * }); + */ async stop() { await this.stopPolling(); this.reset(); diff --git a/src/spies/eventBridge/index.ts b/src/spies/eventBridge/index.ts index 04e5b67..3549147 100644 --- a/src/spies/eventBridge/index.ts +++ b/src/spies/eventBridge/index.ts @@ -34,8 +34,10 @@ export type EventBridgeSpyParams = { * * @example * - * const spy = await eventBridgeSpy({ - * eventBusName: 'default', + * let spy: EventBridgeSpy; + * + * beforeAll(async () => { + * spy = await eventBridgeSpy(config); * }); */ export const eventBridgeSpy = async (params: EventBridgeSpyParams) => { From bb71ba510e34e5fb1be6da25b5f96637ab32a423 Mon Sep 17 00:00:00 2001 From: bboure Date: Fri, 19 Jan 2024 11:27:58 +0100 Subject: [PATCH 07/16] fixes --- doc/utils/cognito.md | 2 +- src/helpers/appsync.ts | 4 ++-- src/helpers/cognito.ts | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/doc/utils/cognito.md b/doc/utils/cognito.md index 7480224..cdb4485 100644 --- a/doc/utils/cognito.md +++ b/doc/utils/cognito.md @@ -48,7 +48,7 @@ The returned value is of type [AuthenticationResultType](https://docs.aws.amazon ### `cognitoDeleteUser` -Deletes a user in cognito. +Delete a user in cognito. ```typescript await cognitoDeleteUser({ diff --git a/src/helpers/appsync.ts b/src/helpers/appsync.ts index df707aa..268d7c0 100644 --- a/src/helpers/appsync.ts +++ b/src/helpers/appsync.ts @@ -61,7 +61,7 @@ const appSyncMappingTemplateInputSchema: HelperZodSchema< * @example * * expect(appSyncMappingTemplate({ - * template: 'src/resolvers/request.vtl', + * template: 'src/resolvers/Query.getUser.request.vtl', * context: { * arguments: { * id: '123' @@ -133,7 +133,7 @@ const appSyncResolverInputSchema: HelperZodSchema = * @example * * expect(appSyncResolver({ - * code: 'src/resolvers/request.js', + * code: 'src/resolvers/Query.getUser.js', * function: 'request', * context: { * arguments: { diff --git a/src/helpers/cognito.ts b/src/helpers/cognito.ts index 6b37d28..56d408f 100644 --- a/src/helpers/cognito.ts +++ b/src/helpers/cognito.ts @@ -42,8 +42,8 @@ const cognitoUserInputSchema: HelperZodSchema = z.object({ * @example * * expect(cognitoUser({ - * userPoolId: 'us-east-1_123456789', - * username: 'john' + * userPoolId: 'us-east-1_123456789', + * username: 'john' * })).toExist(); */ export const cognitoUser: RetryableMatcherHelper< From ca5230bc63163f0845f29459001e252099cdefaf Mon Sep 17 00:00:00 2001 From: bboure Date: Fri, 19 Jan 2024 11:56:45 +0100 Subject: [PATCH 08/16] fixes --- src/helpers/cognito.ts | 2 +- src/index.ts | 4 ++-- src/spies/eventBridge/EventBridgeSpy.ts | 4 +++- src/spies/eventBridge/index.ts | 15 ++++++++++++++- src/utils/cognito.ts | 2 +- 5 files changed, 21 insertions(+), 6 deletions(-) diff --git a/src/helpers/cognito.ts b/src/helpers/cognito.ts index 56d408f..bbe4789 100644 --- a/src/helpers/cognito.ts +++ b/src/helpers/cognito.ts @@ -19,7 +19,7 @@ export type CognitoUserInput = { */ username: string; /** - * An optional cognito client configuration. + * An optional Cognito SDK client configuration. */ clientConfig?: CognitoIdentityProviderClientConfig; }; diff --git a/src/index.ts b/src/index.ts index 518274a..e79fcf2 100644 --- a/src/index.ts +++ b/src/index.ts @@ -116,7 +116,7 @@ declare global { interface EventBridgeMatchers { /** - * Asserts the the EventBridge spy has received an + * Asserts the the spied EventBridge has received an * event matching the expected object. * * @param expected The expected object. @@ -126,7 +126,7 @@ declare global { ): Promise; /** - * Asserts the the EventBridge spy has received an + * Asserts the the spied EventBridge has received an * event matching the expected object a certain number of times. * * @param expected The expected object. diff --git a/src/spies/eventBridge/EventBridgeSpy.ts b/src/spies/eventBridge/EventBridgeSpy.ts index fcaa653..6870f69 100644 --- a/src/spies/eventBridge/EventBridgeSpy.ts +++ b/src/spies/eventBridge/EventBridgeSpy.ts @@ -62,6 +62,7 @@ export class EventBridgeSpy { /** * Resets the spy and removes all the events that have been captured. + * This will avoid mixing events from different tests. * * Use this method in an `afterEach` block. * @@ -80,7 +81,8 @@ export class EventBridgeSpy { /** * Stop spying on the EventBridge bus. * - * Use this method in an `afterAll` block. + * You should always call this method at the end of your tests, + * usually in an `afterAll` block. * * @example * diff --git a/src/spies/eventBridge/index.ts b/src/spies/eventBridge/index.ts index 3549147..be0de0c 100644 --- a/src/spies/eventBridge/index.ts +++ b/src/spies/eventBridge/index.ts @@ -27,7 +27,10 @@ export type EventBridgeSpyParams = { /** * Creates an EventBridge spy. * - * Use with {@link expect} and any compatible matcher. + * Use it before your tests to spy on EventBridge events, + * usually in a `beforeAll` block. + * + * Then use the spy with {@link expect} and any compatible matcher. * @see https://serverlessguru.gitbook.io/sls-jest/matchers/eventbridge * * @param params {@link EventBridgeSpyParams} @@ -39,6 +42,16 @@ export type EventBridgeSpyParams = { * beforeAll(async () => { * spy = await eventBridgeSpy(config); * }); + * + * it('should have event matching object', async () => { + * // do something that triggers an event + * await expect(spy).toHaveEventMatchingObject({ + * 'detail-type': 'orderCreated', + * detail: { + * id: order.id, + * }, + * }); + * }); */ export const eventBridgeSpy = async (params: EventBridgeSpyParams) => { const { eventBusName, adapter, config } = params; diff --git a/src/utils/cognito.ts b/src/utils/cognito.ts index a1d3668..c2887a7 100644 --- a/src/utils/cognito.ts +++ b/src/utils/cognito.ts @@ -11,7 +11,7 @@ import { getCognitoClient } from './internal'; type CognitoInput = { /** - * An optional cognito client configuration. + * An optional Cognito Identity Provider SDK client configuration. */ clientConfig?: CognitoIdentityProviderClientConfig; }; From 2dddd638fcd7730cf420fc7f050b510272aa0560 Mon Sep 17 00:00:00 2001 From: bboure Date: Fri, 19 Jan 2024 12:07:22 +0100 Subject: [PATCH 09/16] more doc improvements --- src/spies/eventBridge/EventBridgeSpy.ts | 12 +++++++++--- src/spies/eventBridge/index.ts | 4 ++++ 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/src/spies/eventBridge/EventBridgeSpy.ts b/src/spies/eventBridge/EventBridgeSpy.ts index 6870f69..3d9eff5 100644 --- a/src/spies/eventBridge/EventBridgeSpy.ts +++ b/src/spies/eventBridge/EventBridgeSpy.ts @@ -17,15 +17,21 @@ export type EventBridgeSpyConfig = { * A basic class for spying on EventBridge events. */ export class EventBridgeSpy { - events: EventBridgeEvent[] = []; - subject: BehaviorSubject[]>; - matcherTimeout: number; + protected events: EventBridgeEvent[] = []; + protected subject: BehaviorSubject[]>; + protected matcherTimeout: number; constructor(private config: EventBridgeSpyConfig = {}) { this.subject = new BehaviorSubject(this.events); this.matcherTimeout = config.matcherDefaultTimeout ?? 10000; } + /** + * Start spying on the EventBridge bus. + * + * This method is called automatically by the `eventBridgeSpy` helper. + * You should never call this method directly. + */ async startPolling() { throw new Error('Not implemented. Implement this in a child class.'); } diff --git a/src/spies/eventBridge/index.ts b/src/spies/eventBridge/index.ts index be0de0c..e167afe 100644 --- a/src/spies/eventBridge/index.ts +++ b/src/spies/eventBridge/index.ts @@ -30,6 +30,10 @@ export type EventBridgeSpyParams = { * Use it before your tests to spy on EventBridge events, * usually in a `beforeAll` block. * + * The first time it is called, this function will create a CloudFormation stack + * with the resources needed to spy on the specified EventBridge bus. + * On subsequent calls, it will reuse the existing stack. + * * Then use the spy with {@link expect} and any compatible matcher. * @see https://serverlessguru.gitbook.io/sls-jest/matchers/eventbridge * From 47c032b8a3c3020eae00700606790e689c192e2d Mon Sep 17 00:00:00 2001 From: bboure Date: Fri, 19 Jan 2024 12:28:42 +0100 Subject: [PATCH 10/16] fix naming --- .github/workflows/naming.yml | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/.github/workflows/naming.yml b/.github/workflows/naming.yml index 9107098..80c6c99 100644 --- a/.github/workflows/naming.yml +++ b/.github/workflows/naming.yml @@ -2,7 +2,7 @@ name: Naming Conventions on: pull_request: - types: [opened, edited] + types: [opened, edited, synchronize] branches: - develop @@ -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 From f5cc06ef5cc4c7fa317bfd749bd5516e86472b18 Mon Sep 17 00:00:00 2001 From: bboure Date: Fri, 19 Jan 2024 12:29:33 +0100 Subject: [PATCH 11/16] fix naming --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 3dc24e7..1a4795a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -2,7 +2,7 @@ name: Continuous Integration on: pull_request: - types: [opened, synchronize, reopened] + types: [opened, edited, synchronize, reopened] push: branches: - main From fe06f4663329fc32cfe946b9b34f63441a668111 Mon Sep 17 00:00:00 2001 From: bboure Date: Fri, 19 Jan 2024 12:37:00 +0100 Subject: [PATCH 12/16] fix --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 1a4795a..3dc24e7 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -2,7 +2,7 @@ name: Continuous Integration on: pull_request: - types: [opened, edited, synchronize, reopened] + types: [opened, synchronize, reopened] push: branches: - main From 7985c7999c27a2713d1e47f63cc29960e1a77574 Mon Sep 17 00:00:00 2001 From: bboure Date: Tue, 23 Jan 2024 07:24:55 +0100 Subject: [PATCH 13/16] typos --- src/utils/cognito.ts | 33 ++++++++++++++++++--------------- 1 file changed, 18 insertions(+), 15 deletions(-) diff --git a/src/utils/cognito.ts b/src/utils/cognito.ts index c2887a7..74271eb 100644 --- a/src/utils/cognito.ts +++ b/src/utils/cognito.ts @@ -21,29 +21,29 @@ type CognitoInput = { */ export type CognitoSignInInput = { /** - * The cognito user pool id. + * The Cognito user pool id. */ userPoolId: string; /** - * The cognito user pool client id. + * The Cognito user pool client id. */ clientId: string; /** - * The cognito user username. + * The Cognito user username. */ username: string; /** - * The cognito user password. + * The Cognito user password. */ password: string; } & CognitoInput; /** - * Sign in a user in cognito and return its credentials. + * Sign in a user in Cognito and return its credentials. * * @param input {@link CognitoSignInInput} */ -export const cognitoSignIn = async ( +export const CognitoSignIn = async ( input: CognitoSignInInput, ): Promise => { const { clientId, userPoolId, username, password, clientConfig } = input; @@ -73,17 +73,17 @@ export const cognitoSignIn = async ( */ export type CognitoSignUpInput = CognitoSignInInput & { /** - * The cognito user attributes. + * The Cognito user attributes. */ attributes?: AttributeType[]; }; /** - * Create a new user in cognito, auto confirm it and return its credentials. + * Create a new user in Cognito, auto confirm it and return its credentials. * * @param input {@link CognitoSignUpInput} */ -export const cognitoSignUp = async ( +export const CognitoSignUp = async ( input: CognitoSignUpInput, ): Promise => { const { clientId, userPoolId, username, password, attributes, clientConfig } = @@ -108,7 +108,7 @@ export const cognitoSignUp = async ( }), ); - return cognitoSignIn({ + return CognitoSignIn({ clientId, userPoolId, password, @@ -117,27 +117,30 @@ export const cognitoSignUp = async ( }); }; +/** + * Cognito Delete User input + */ export type DeleteCognitoUserInput = { /** - * The cognito user pool id. + * The Cognito user pool id. */ userPoolId: string; /** - * The cognito user username. + * The Cognito user username. */ username: string; /** - * An optional cognito client configuration. + * An optional Cognito client configuration. */ clientConfig?: CognitoIdentityProviderClientConfig; } & CognitoInput; /** - * Delete a user in cognito. + * Delete a user from Cognito. * * @param input {@link DeleteCognitoUserInput} */ -export const cognitoDeleteUser = async ( +export const deleteCognitoUser = async ( input: DeleteCognitoUserInput, ): Promise => { const { userPoolId, username, clientConfig } = input; From ddd1380021096cbcb0c40a2d66f113ce47e43508 Mon Sep 17 00:00:00 2001 From: bboure Date: Tue, 23 Jan 2024 07:25:23 +0100 Subject: [PATCH 14/16] more --- doc/utils/cognito.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/utils/cognito.md b/doc/utils/cognito.md index cdb4485..fcbc807 100644 --- a/doc/utils/cognito.md +++ b/doc/utils/cognito.md @@ -46,12 +46,12 @@ const credentials = await cognitoSignIn({ 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. -### `cognitoDeleteUser` +### `deleteCognitoUser` Delete a user in cognito. ```typescript -await cognitoDeleteUser({ +await deleteCognitoUser({ userPoolId: 'user_pool_id', username: 'someone@example.com', }); From 2f7ef55325170911fc2012aebc5a1f3a2503f79f Mon Sep 17 00:00:00 2001 From: bboure Date: Wed, 24 Jan 2024 13:27:30 +0100 Subject: [PATCH 15/16] fixes --- examples/__tests__/cognito.test.ts | 24 ++++++++++++++---------- src/utils/cognito.ts | 18 +++++++++--------- 2 files changed, 23 insertions(+), 19 deletions(-) diff --git a/examples/__tests__/cognito.test.ts b/examples/__tests__/cognito.test.ts index d1ab708..c5c6d02 100644 --- a/examples/__tests__/cognito.test.ts +++ b/examples/__tests__/cognito.test.ts @@ -1,5 +1,9 @@ import { Chance } from 'chance'; -import { cognitoSignIn, cognitoSignUp, cognitoUser } from 'sls-jest'; +import { + signInWithCognitoUser, + signUpCognitoUser, + cognitoUser, +} from 'sls-jest'; const chance = new Chance(); @@ -8,11 +12,11 @@ const clientId = '3oed3rv2h43sleqojqtt2bb43a'; const userPoolId = 'us-east-1_2KFDP3x2n'; describe('Utils', () => { - describe('cognitoSignUp', () => { + describe('signUpCognitoUser', () => { it('should sign up a user and return its credentials, when user does not exist', async () => { const email = chance.email(); const password = chance.string({ length: 8 }); - const credentials = await cognitoSignUp({ + const credentials = await signUpCognitoUser({ clientId, userPoolId, username: email, @@ -35,7 +39,7 @@ describe('Utils', () => { const email = chance.email(); const password = chance.string({ length: 8 }); - await cognitoSignUp({ + await signUpCognitoUser({ clientId, userPoolId, username: email, @@ -49,7 +53,7 @@ describe('Utils', () => { }); await expect( - cognitoSignUp({ + signUpCognitoUser({ clientId, userPoolId, username: email, @@ -65,12 +69,12 @@ describe('Utils', () => { }); }); - describe('cognitoSignIn', () => { + describe('signInWithCognitoUser', () => { it('should sign in a user and return its credentials, when user exists', async () => { const email = chance.email(); const password = chance.string({ length: 8 }); - await cognitoSignUp({ + await signUpCognitoUser({ clientId, userPoolId, username: email, @@ -83,7 +87,7 @@ describe('Utils', () => { ], }); - const credentials = await cognitoSignIn({ + const credentials = await signInWithCognitoUser({ userPoolId, clientId, username: email, @@ -101,7 +105,7 @@ describe('Utils', () => { const password = chance.string({ length: 8 }); await expect( - cognitoSignIn({ + signInWithCognitoUser({ clientId, userPoolId, username: email, @@ -120,7 +124,7 @@ describe('Matchers', () => { beforeAll(async () => { existingUser = chance.email(); - await cognitoSignUp({ + await signUpCognitoUser({ clientId, userPoolId, username: existingUser, diff --git a/src/utils/cognito.ts b/src/utils/cognito.ts index 74271eb..2953e91 100644 --- a/src/utils/cognito.ts +++ b/src/utils/cognito.ts @@ -19,7 +19,7 @@ type CognitoInput = { /** * Cognito Sign In input */ -export type CognitoSignInInput = { +export type SignInWithCognitoUserInput = { /** * The Cognito user pool id. */ @@ -41,10 +41,10 @@ export type CognitoSignInInput = { /** * Sign in a user in Cognito and return its credentials. * - * @param input {@link CognitoSignInInput} + * @param input {@link SignInWithCognitoUserInput} */ -export const CognitoSignIn = async ( - input: CognitoSignInInput, +export const signInWithCognitoUser = async ( + input: SignInWithCognitoUserInput, ): Promise => { const { clientId, userPoolId, username, password, clientConfig } = input; const client = getCognitoClient(clientConfig); @@ -71,7 +71,7 @@ export const CognitoSignIn = async ( /** * Cognito Sign Up input */ -export type CognitoSignUpInput = CognitoSignInInput & { +export type SignUpCognitoUserInput = SignInWithCognitoUserInput & { /** * The Cognito user attributes. */ @@ -81,10 +81,10 @@ export type CognitoSignUpInput = CognitoSignInInput & { /** * Create a new user in Cognito, auto confirm it and return its credentials. * - * @param input {@link CognitoSignUpInput} + * @param input {@link SignUpCognitoUserInput} */ -export const CognitoSignUp = async ( - input: CognitoSignUpInput, +export const signUpCognitoUser = async ( + input: SignUpCognitoUserInput, ): Promise => { const { clientId, userPoolId, username, password, attributes, clientConfig } = input; @@ -108,7 +108,7 @@ export const CognitoSignUp = async ( }), ); - return CognitoSignIn({ + return signInWithCognitoUser({ clientId, userPoolId, password, From 06a205f74f4e81c4c0df3ddc2cde74610ff5d9ed Mon Sep 17 00:00:00 2001 From: bboure Date: Wed, 24 Jan 2024 13:32:42 +0100 Subject: [PATCH 16/16] freaking documentation --- doc/utils/cognito.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/doc/utils/cognito.md b/doc/utils/cognito.md index fcbc807..c5cc576 100644 --- a/doc/utils/cognito.md +++ b/doc/utils/cognito.md @@ -2,14 +2,14 @@ ## Functions -### `cognitoSignUp` +### `signUpCognitoUser` Create a new user in cognito, auto confirm it and return its credentials. example: ```typescript -const credentials = await cognitoSignUp({ +const credentials = await signUpCognitoUser({ clientId: 'client_id', userPoolId: 'user_pool_id', username: 'someone@example.com', @@ -29,12 +29,12 @@ The returned value is of type [AuthenticationResultType](https://docs.aws.amazon Note: this function is not idempotent, if the user already exists it will fail. -### `cognitoSignIn` +### `signInWithCognitoUser` Sign in a user in cognito and return its credentials. ```typescript -const credentials = await cognitoSignIn({ +const credentials = await signInWithCognitoUser({ clientId: 'client_id', userPoolId: 'user_pool_id', username: 'someone@example.com',