diff --git a/.github/workflows/reusable-run-linting-check-and-unit-tests.yml b/.github/workflows/reusable-run-linting-check-and-unit-tests.yml index 9f5e7354de..f2276bd69c 100644 --- a/.github/workflows/reusable-run-linting-check-and-unit-tests.yml +++ b/.github/workflows/reusable-run-linting-check-and-unit-tests.yml @@ -47,6 +47,7 @@ jobs: "packages/idempotency", "packages/jmespath", "packages/logger", + "packages/parser", ] fail-fast: false steps: @@ -91,14 +92,12 @@ jobs: run: | npm run lint -w -w packages/tracer \ -w packages/metrics \ - -w packages/parameters \ - -w packages/parser + -w packages/parameters - name: Run unit tests run: | npm t -w packages/tracer \ -w packages/metrics \ - -w packages/parameters \ - -w packages/parser + -w packages/parameters check-examples: runs-on: ubuntu-latest env: diff --git a/packages/parser/jest.config.cjs b/packages/parser/jest.config.cjs deleted file mode 100644 index 23684da5b4..0000000000 --- a/packages/parser/jest.config.cjs +++ /dev/null @@ -1,30 +0,0 @@ -module.exports = { - displayName: { - name: 'Powertools for AWS Lambda (TypeScript) utility: PARSER', - color: 'blue', - }, - runner: 'groups', - preset: 'ts-jest', - moduleNameMapper: { - '^(\\.{1,2}/.*)\\.js$': '$1', - }, - transform: { - '^.+\\.ts?$': ['ts-jest'], - }, - moduleFileExtensions: ['js', 'ts'], - collectCoverageFrom: ['**/src/**/*.ts', '!**/node_modules/**'], - testMatch: ['**/?(*.)+(spec|test).ts'], - roots: ['/src', '/tests'], - testPathIgnorePatterns: ['/node_modules/'], - testEnvironment: 'node', - coveragePathIgnorePatterns: ['/node_modules/', '/types'], - coverageThreshold: { - global: { - statements: 100, - branches: 100, - functions: 100, - lines: 100, - }, - }, - coverageReporters: ['json-summary', 'text', 'lcov'], -}; diff --git a/packages/parser/package.json b/packages/parser/package.json index 34f3817c77..952e127507 100644 --- a/packages/parser/package.json +++ b/packages/parser/package.json @@ -10,10 +10,14 @@ "access": "public" }, "scripts": { - "test": "npm run test:unit", - "test:unit": "jest --group=unit --detectOpenHandles --coverage --verbose", - "jest": "jest --detectOpenHandles --coverage --verbose", - "watch": "jest --watch", + "test": "vitest --run tests/unit", + "test:unit": "vitest --run tests/unit", + "test:unit:coverage": "vitest --run tests/unit --coverage.enabled --coverage.thresholds.100 --coverage.include='src/**'", + "test:unit:types": "echo 'Not Implemented'", + "test:unit:watch": "vitest tests/unit", + "test:e2e:nodejs18x": "echo 'Not implemented'", + "test:e2e:nodejs20x": "echo 'Not implemented'", + "test:e2e": "echo 'Not implemented'", "build:cjs": "tsc --build tsconfig.json && echo '{ \"type\": \"commonjs\" }' > lib/cjs/package.json", "build:esm": "tsc --build tsconfig.esm.json && echo '{ \"type\": \"module\" }' > lib/esm/package.json", "build": "npm run build:esm & npm run build:cjs", diff --git a/packages/parser/src/parserDecorator.ts b/packages/parser/src/parserDecorator.ts index 0e9ee7ed87..77b5deabc7 100644 --- a/packages/parser/src/parserDecorator.ts +++ b/packages/parser/src/parserDecorator.ts @@ -23,7 +23,7 @@ import type { ParserOutput } from './types/parser.js'; * * class Lambda implements LambdaInterface { * - * @parser({ envelope: SqsEnvelope, schema: OrderSchema }) + * ⁣@parser({ envelope: SqsEnvelope, schema: OrderSchema }) * public async handler(event: Order, _context: Context): Promise { * // sqs event is parsed and the payload is extracted and parsed * // apply business logic to your Order event @@ -54,7 +54,7 @@ import type { ParserOutput } from './types/parser.js'; * * class Lambda implements LambdaInterface { * - * @parser({ envelope: SqsEnvelope, schema: OrderSchema, safeParse: true }) + * ⁣@parser({ envelope: SqsEnvelope, schema: OrderSchema, safeParse: true }) * public async handler(event: ParsedResult, _context: unknown): Promise { * if (event.success) { * // event.data is the parsed event object of type Order diff --git a/packages/parser/src/schemas/base.ts b/packages/parser/src/schemas/base.ts new file mode 100644 index 0000000000..a8f58d0776 --- /dev/null +++ b/packages/parser/src/schemas/base.ts @@ -0,0 +1,21 @@ +import z from 'zod'; + +/** + * A base schema for record objects with string keys and string values + */ +const RecordSchema = z.record(z.string()); + +/** + * A base schema for HTTP methods + */ +const HttpMethodSchema = z.enum([ + 'GET', + 'POST', + 'PUT', + 'PATCH', + 'DELETE', + 'HEAD', + 'OPTIONS', +]); + +export { RecordSchema, HttpMethodSchema }; diff --git a/packages/parser/tests/events/albEvent.json b/packages/parser/tests/events/alb/base.json similarity index 100% rename from packages/parser/tests/events/albEvent.json rename to packages/parser/tests/events/alb/base.json diff --git a/packages/parser/tests/events/albMultiValueHeadersEvent.json b/packages/parser/tests/events/alb/multi-value-header.json similarity index 100% rename from packages/parser/tests/events/albMultiValueHeadersEvent.json rename to packages/parser/tests/events/alb/multi-value-header.json diff --git a/packages/parser/tests/events/albEventPathTrailingSlash.json b/packages/parser/tests/events/albEventPathTrailingSlash.json deleted file mode 100644 index d365fa84b2..0000000000 --- a/packages/parser/tests/events/albEventPathTrailingSlash.json +++ /dev/null @@ -1,28 +0,0 @@ -{ - "requestContext": { - "elb": { - "targetGroupArn": "arn:aws:elasticloadbalancing:us-east-2:123456789012:targetgroup/lambda-279XGJDqGZ5rsrHC2Fjr/49e9d65c45c6791a" - } - }, - "httpMethod": "GET", - "path": "/lambda/", - "queryStringParameters": { - "query": "1234ABCD" - }, - "headers": { - "accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8", - "accept-encoding": "gzip", - "accept-language": "en-US,en;q=0.9", - "connection": "keep-alive", - "host": "lambda-alb-123578498.us-east-2.elb.amazonaws.com", - "upgrade-insecure-requests": "1", - "user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36", - "x-amzn-trace-id": "Root=1-5c536348-3d683b8b04734faae651f476", - "x-forwarded-for": "72.12.164.125", - "x-forwarded-port": "80", - "x-forwarded-proto": "http", - "x-imforwards": "20" - }, - "body": "Test", - "isBase64Encoded": false -} diff --git a/packages/parser/tests/events/apiGatewayAuthorizerRequestEvent.json b/packages/parser/tests/events/apiGatewayAuthorizerRequestEvent.json deleted file mode 100644 index 3177f389b4..0000000000 --- a/packages/parser/tests/events/apiGatewayAuthorizerRequestEvent.json +++ /dev/null @@ -1,72 +0,0 @@ -{ - "version": "1.0", - "type": "REQUEST", - "methodArn": "arn:aws:execute-api:us-east-1:123456789012:abcdef123/test/GET/request", - "identitySource": "user1,123", - "authorizationToken": "user1,123", - "resource": "/request", - "path": "/request", - "httpMethod": "GET", - "headers": { - "X-AMZ-Date": "20170718T062915Z", - "Accept": "*/*", - "HeaderAuth1": "headerValue1", - "CloudFront-Viewer-Country": "US", - "CloudFront-Forwarded-Proto": "https", - "CloudFront-Is-Tablet-Viewer": "false", - "CloudFront-Is-Mobile-Viewer": "false", - "User-Agent": "..." - }, - "queryStringParameters": { - "QueryString1": "queryValue1" - }, - "multiValueQueryStringParameters": { - "QueryString1": ["queryValue1"] - }, - "pathParameters": {}, - "stageVariables": { - "StageVar1": "stageValue1" - }, - "requestContext": { - "accountId": "123456789012", - "apiId": "abcdef123", - "domainName": "3npb9j1tlk.execute-api.us-west-1.amazonaws.com", - "domainPrefix": "3npb9j1tlk", - "extendedRequestId": "EXqgWgXxSK4EJug=", - "httpMethod": "GET", - "identity": { - "accessKey": null, - "accountId": null, - "caller": null, - "cognitoAuthenticationProvider": null, - "cognitoAuthenticationType": null, - "cognitoIdentityId": null, - "cognitoIdentityPoolId": null, - "principalOrgId": null, - "apiKey": "...", - "sourceIp": "192.168.0.1", - "user": null, - "userAgent": "PostmanRuntime/7.28.3", - "userArn": null, - "clientCert": { - "clientCertPem": "CERT_CONTENT", - "subjectDN": "www.example.com", - "issuerDN": "Example issuer", - "serialNumber": "a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1", - "validity": { - "notBefore": "May 28 12:30:02 2019 GMT", - "notAfter": "Aug 5 09:36:04 2021 GMT" - } - } - }, - "path": "/request", - "protocol": "HTTP/1.1", - "requestId": "EXqgWgXxSK4EJug=", - "requestTime": "20/Aug/2021:14:36:50 +0000", - "requestTimeEpoch": 1629470210043, - "resourceId": "ANY /request", - "resourcePath": "/request", - "stage": "test" - }, - "body": null -} diff --git a/packages/parser/tests/events/apiGatewayAuthorizerTokenEvent.json b/packages/parser/tests/events/apiGatewayAuthorizerTokenEvent.json deleted file mode 100644 index f30f360f6d..0000000000 --- a/packages/parser/tests/events/apiGatewayAuthorizerTokenEvent.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "type": "TOKEN", - "authorizationToken": "allow", - "methodArn": "arn:aws:execute-api:us-west-2:123456789012:ymy8tbxw7b/*/GET/" -} diff --git a/packages/parser/tests/events/apiGatewayAuthorizerV2Event.json b/packages/parser/tests/events/apiGatewayAuthorizerV2Event.json deleted file mode 100644 index f0528080c9..0000000000 --- a/packages/parser/tests/events/apiGatewayAuthorizerV2Event.json +++ /dev/null @@ -1,52 +0,0 @@ -{ - "version": "2.0", - "type": "REQUEST", - "routeArn": "arn:aws:execute-api:us-east-1:123456789012:abcdef123/test/GET/request", - "identitySource": ["user1", "123"], - "routeKey": "GET /merchants", - "rawPath": "/merchants", - "rawQueryString": "parameter1=value1¶meter1=value2¶meter2=value", - "cookies": ["cookie1", "cookie2"], - "headers": { - "x-amzn-trace-id": "Root=1-611cc4a7-0746ebee281cfd967db97b64", - "Header1": "value1", - "Header2": "value2", - "Authorization": "value" - }, - "queryStringParameters": { - "parameter1": "value1,value2", - "parameter2": "value" - }, - "requestContext": { - "accountId": "123456789012", - "apiId": "api-id", - "authentication": { - "clientCert": { - "clientCertPem": "CERT_CONTENT", - "subjectDN": "www.example.com", - "issuerDN": "Example issuer", - "serialNumber": "a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1", - "validity": { - "notBefore": "May 28 12:30:02 2019 GMT", - "notAfter": "Aug 5 09:36:04 2021 GMT" - } - } - }, - "domainName": "id.execute-api.us-east-1.amazonaws.com", - "domainPrefix": "id", - "http": { - "method": "POST", - "path": "/merchants", - "protocol": "HTTP/1.1", - "sourceIp": "IP", - "userAgent": "agent" - }, - "requestId": "id", - "routeKey": "GET /merchants", - "stage": "$default", - "time": "12/Mar/2020:19:03:58 +0000", - "timeEpoch": 1583348638390 - }, - "pathParameters": { "parameter1": "value1" }, - "stageVariables": { "stageVariable1": "value1", "stageVariable2": "value2" } -} diff --git a/packages/parser/tests/events/apiGatewayProxyEvent.json b/packages/parser/tests/events/apiGatewayProxyEvent.json deleted file mode 100644 index 5a40bf2f42..0000000000 --- a/packages/parser/tests/events/apiGatewayProxyEvent.json +++ /dev/null @@ -1,71 +0,0 @@ -{ - "version": "1.0", - "resource": "/my/path", - "path": "/my/path", - "httpMethod": "GET", - "headers": { - "Header1": "value1", - "Header2": "value2", - "Origin": "https://aws.amazon.com" - }, - "multiValueHeaders": { - "Header1": ["value1"], - "Header2": ["value1", "value2"] - }, - "queryStringParameters": { - "parameter1": "value1", - "parameter2": "value" - }, - "multiValueQueryStringParameters": { - "parameter1": ["value1", "value2"], - "parameter2": ["value"] - }, - "requestContext": { - "accountId": "123456789012", - "apiId": "id", - "authorizer": { - "claims": null, - "scopes": null - }, - "domainName": "id.execute-api.us-east-1.amazonaws.com", - "domainPrefix": "id", - "extendedRequestId": "request-id", - "httpMethod": "GET", - "identity": { - "accessKey": null, - "accountId": null, - "caller": null, - "cognitoAuthenticationProvider": null, - "cognitoAuthenticationType": null, - "cognitoIdentityId": null, - "cognitoIdentityPoolId": null, - "principalOrgId": null, - "sourceIp": "192.168.0.1", - "user": null, - "userAgent": "user-agent", - "userArn": null, - "clientCert": { - "clientCertPem": "CERT_CONTENT", - "subjectDN": "www.example.com", - "issuerDN": "Example issuer", - "serialNumber": "a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1", - "validity": { - "notBefore": "May 28 12:30:02 2019 GMT", - "notAfter": "Aug 5 09:36:04 2021 GMT" - } - } - }, - "path": "/my/path", - "protocol": "HTTP/1.1", - "requestId": "id=", - "requestTime": "04/Mar/2020:19:15:17 +0000", - "requestTimeEpoch": 1583349317135, - "resourceId": null, - "resourcePath": "/my/path", - "stage": "$default" - }, - "pathParameters": null, - "stageVariables": null, - "body": "Hello from Lambda!", - "isBase64Encoded": false -} diff --git a/packages/parser/tests/events/apiGatewayProxyEventAnotherPath.json b/packages/parser/tests/events/apiGatewayProxyEventAnotherPath.json deleted file mode 100644 index cc8b236234..0000000000 --- a/packages/parser/tests/events/apiGatewayProxyEventAnotherPath.json +++ /dev/null @@ -1,70 +0,0 @@ -{ - "version": "1.0", - "resource": "/my/anotherPath", - "path": "/my/anotherPath", - "httpMethod": "GET", - "headers": { - "Header1": "value1", - "Header2": "value2" - }, - "multiValueHeaders": { - "Header1": ["value1"], - "Header2": ["value1", "value2"] - }, - "queryStringParameters": { - "parameter1": "value1", - "parameter2": "value" - }, - "multiValueQueryStringParameters": { - "parameter1": ["value1", "value2"], - "parameter2": ["value"] - }, - "requestContext": { - "accountId": "123456789012", - "apiId": "id", - "authorizer": { - "claims": null, - "scopes": null - }, - "domainName": "id.execute-api.us-east-1.amazonaws.com", - "domainPrefix": "id", - "extendedRequestId": "request-id", - "httpMethod": "GET", - "identity": { - "accessKey": null, - "accountId": null, - "caller": null, - "cognitoAuthenticationProvider": null, - "cognitoAuthenticationType": null, - "cognitoIdentityId": null, - "cognitoIdentityPoolId": null, - "principalOrgId": null, - "sourceIp": "192.168.0.1", - "user": null, - "userAgent": "user-agent", - "userArn": null, - "clientCert": { - "clientCertPem": "CERT_CONTENT", - "subjectDN": "www.example.com", - "issuerDN": "Example issuer", - "serialNumber": "a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1", - "validity": { - "notBefore": "May 28 12:30:02 2019 GMT", - "notAfter": "Aug 5 09:36:04 2021 GMT" - } - } - }, - "path": "/my/anotherPath", - "protocol": "HTTP/1.1", - "requestId": "id=", - "requestTime": "04/Mar/2020:19:15:17 +0000", - "requestTimeEpoch": 1583349317135, - "resourceId": null, - "resourcePath": "/my/anotherPath", - "stage": "$default" - }, - "pathParameters": null, - "stageVariables": null, - "body": "Hello from Lambda!", - "isBase64Encoded": true -} diff --git a/packages/parser/tests/events/apiGatewayProxyEventPathTrailingSlash.json b/packages/parser/tests/events/apiGatewayProxyEventPathTrailingSlash.json deleted file mode 100644 index 2de7ae409b..0000000000 --- a/packages/parser/tests/events/apiGatewayProxyEventPathTrailingSlash.json +++ /dev/null @@ -1,70 +0,0 @@ -{ - "version": "1.0", - "resource": "/my/path", - "path": "/my/path/", - "httpMethod": "GET", - "headers": { - "Header1": "value1", - "Header2": "value2" - }, - "multiValueHeaders": { - "Header1": ["value1"], - "Header2": ["value1", "value2"] - }, - "queryStringParameters": { - "parameter1": "value1", - "parameter2": "value" - }, - "multiValueQueryStringParameters": { - "parameter1": ["value1", "value2"], - "parameter2": ["value"] - }, - "requestContext": { - "accountId": "123456789012", - "apiId": "id", - "authorizer": { - "claims": null, - "scopes": null - }, - "domainName": "id.execute-api.us-east-1.amazonaws.com", - "domainPrefix": "id", - "extendedRequestId": "request-id", - "httpMethod": "GET", - "identity": { - "accessKey": null, - "accountId": null, - "caller": null, - "cognitoAuthenticationProvider": null, - "cognitoAuthenticationType": null, - "cognitoIdentityId": null, - "cognitoIdentityPoolId": null, - "principalOrgId": null, - "sourceIp": "192.168.0.1", - "user": null, - "userAgent": "user-agent", - "userArn": null, - "clientCert": { - "clientCertPem": "CERT_CONTENT", - "subjectDN": "www.example.com", - "issuerDN": "Example issuer", - "serialNumber": "a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1", - "validity": { - "notBefore": "May 28 12:30:02 2019 GMT", - "notAfter": "Aug 5 09:36:04 2021 GMT" - } - } - }, - "path": "/my/path", - "protocol": "HTTP/1.1", - "requestId": "id=", - "requestTime": "04/Mar/2020:19:15:17 +0000", - "requestTimeEpoch": 1583349317135, - "resourceId": null, - "resourcePath": "/my/path", - "stage": "$default" - }, - "pathParameters": null, - "stageVariables": null, - "body": "Hello from Lambda!", - "isBase64Encoded": true -} diff --git a/packages/parser/tests/events/apiGatewayProxyEventPrincipalId.json b/packages/parser/tests/events/apiGatewayProxyEventPrincipalId.json deleted file mode 100644 index f18a2a44bb..0000000000 --- a/packages/parser/tests/events/apiGatewayProxyEventPrincipalId.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "resource": "/trip", - "path": "/trip", - "httpMethod": "POST", - "requestContext": { - "requestId": "34972478-2843-4ced-a657-253108738274", - "authorizer": { - "user_id": "fake_username", - "principalId": "fake", - "integrationLatency": 451 - } - } -} diff --git a/packages/parser/tests/events/apiGatewayProxyEventTestUI.json b/packages/parser/tests/events/apiGatewayProxyEventTestUI.json deleted file mode 100644 index 4c4b53557f..0000000000 --- a/packages/parser/tests/events/apiGatewayProxyEventTestUI.json +++ /dev/null @@ -1,71 +0,0 @@ -{ - "version": "1.0", - "resource": "/my/path", - "path": "/my/path", - "httpMethod": "GET", - "headers": { - "Header1": "value1", - "Header2": "value2", - "Origin": "https://aws.amazon.com" - }, - "multiValueHeaders": { - "Header1": ["value1"], - "Header2": ["value1", "value2"] - }, - "queryStringParameters": { - "parameter1": "value1", - "parameter2": "value" - }, - "multiValueQueryStringParameters": { - "parameter1": ["value1", "value2"], - "parameter2": ["value"] - }, - "requestContext": { - "accountId": "123456789012", - "apiId": "id", - "authorizer": { - "claims": null, - "scopes": null - }, - "domainName": "id.execute-api.us-east-1.amazonaws.com", - "domainPrefix": "id", - "extendedRequestId": "request-id", - "httpMethod": "GET", - "identity": { - "accessKey": null, - "accountId": null, - "caller": null, - "cognitoAuthenticationProvider": null, - "cognitoAuthenticationType": null, - "cognitoIdentityId": null, - "cognitoIdentityPoolId": null, - "principalOrgId": null, - "sourceIp": "test-invoke-source-ip", - "user": null, - "userAgent": "user-agent", - "userArn": null, - "clientCert": { - "clientCertPem": "CERT_CONTENT", - "subjectDN": "www.example.com", - "issuerDN": "Example issuer", - "serialNumber": "a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1", - "validity": { - "notBefore": "May 28 12:30:02 2019 GMT", - "notAfter": "Aug 5 09:36:04 2021 GMT" - } - } - }, - "path": "/my/path", - "protocol": "HTTP/1.1", - "requestId": "id=", - "requestTime": "04/Mar/2020:19:15:17 +0000", - "requestTimeEpoch": 1583349317135, - "resourceId": null, - "resourcePath": "/my/path", - "stage": "$default" - }, - "pathParameters": null, - "stageVariables": null, - "body": "Hello from Lambda!", - "isBase64Encoded": false -} diff --git a/packages/parser/tests/events/apiGatewayProxyEvent_noVersionAuth.json b/packages/parser/tests/events/apiGatewayProxyEvent_noVersionAuth.json deleted file mode 100644 index aa90582aa5..0000000000 --- a/packages/parser/tests/events/apiGatewayProxyEvent_noVersionAuth.json +++ /dev/null @@ -1,65 +0,0 @@ -{ - "resource": "/my/path", - "path": "/my/path", - "httpMethod": "GET", - "headers": { - "Header1": "value1", - "Header2": "value2" - }, - "multiValueHeaders": { - "Header1": ["value1"], - "Header2": ["value1", "value2"] - }, - "queryStringParameters": { - "parameter1": "value1", - "parameter2": "value" - }, - "multiValueQueryStringParameters": { - "parameter1": ["value1", "value2"], - "parameter2": ["value"] - }, - "requestContext": { - "accountId": "123456789012", - "apiId": "id", - "domainName": "id.execute-api.us-east-1.amazonaws.com", - "domainPrefix": "id", - "extendedRequestId": "request-id", - "httpMethod": "GET", - "identity": { - "accessKey": null, - "accountId": null, - "caller": null, - "cognitoAuthenticationProvider": null, - "cognitoAuthenticationType": null, - "cognitoIdentityId": null, - "cognitoIdentityPoolId": null, - "principalOrgId": null, - "sourceIp": "192.168.0.1", - "user": null, - "userAgent": "user-agent", - "userArn": null, - "clientCert": { - "clientCertPem": "CERT_CONTENT", - "subjectDN": "www.example.com", - "issuerDN": "Example issuer", - "serialNumber": "a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1", - "validity": { - "notBefore": "May 28 12:30:02 2019 GMT", - "notAfter": "Aug 5 09:36:04 2021 GMT" - } - } - }, - "path": "/my/path", - "protocol": "HTTP/1.1", - "requestId": "id=", - "requestTime": "04/Mar/2020:19:15:17 +0000", - "requestTimeEpoch": 1583349317135, - "resourceId": null, - "resourcePath": "/my/path", - "stage": "$default" - }, - "pathParameters": null, - "stageVariables": null, - "body": "Hello from Lambda!", - "isBase64Encoded": true -} diff --git a/packages/parser/tests/events/apiGatewayProxyOtherEvent.json b/packages/parser/tests/events/apiGatewayProxyOtherEvent.json deleted file mode 100644 index b5f484fde7..0000000000 --- a/packages/parser/tests/events/apiGatewayProxyOtherEvent.json +++ /dev/null @@ -1,71 +0,0 @@ -{ - "version": "1.0", - "resource": "/other/path", - "path": "/other/path", - "httpMethod": "GET", - "headers": { - "Header1": "value1", - "Header2": "value2", - "Origin": "https://aws.amazon.com" - }, - "multiValueHeaders": { - "Header1": ["value1"], - "Header2": ["value1", "value2"] - }, - "queryStringParameters": { - "parameter1": "value1", - "parameter2": "value" - }, - "multiValueQueryStringParameters": { - "parameter1": ["value1", "value2"], - "parameter2": ["value"] - }, - "requestContext": { - "accountId": "123456789012", - "apiId": "id", - "authorizer": { - "claims": null, - "scopes": null - }, - "domainName": "id.execute-api.us-east-1.amazonaws.com", - "domainPrefix": "id", - "extendedRequestId": "request-id", - "httpMethod": "GET", - "identity": { - "accessKey": null, - "accountId": null, - "caller": null, - "cognitoAuthenticationProvider": null, - "cognitoAuthenticationType": null, - "cognitoIdentityId": null, - "cognitoIdentityPoolId": null, - "principalOrgId": null, - "sourceIp": "192.168.0.1", - "user": null, - "userAgent": "user-agent", - "userArn": null, - "clientCert": { - "clientCertPem": "CERT_CONTENT", - "subjectDN": "www.example.com", - "issuerDN": "Example issuer", - "serialNumber": "a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1", - "validity": { - "notBefore": "May 28 12:30:02 2019 GMT", - "notAfter": "Aug 5 09:36:04 2021 GMT" - } - } - }, - "path": "/other/path", - "protocol": "HTTP/1.1", - "requestId": "id=", - "requestTime": "04/Mar/2020:19:15:17 +0000", - "requestTimeEpoch": 1583349317135, - "resourceId": null, - "resourcePath": "/other/path", - "stage": "$default" - }, - "pathParameters": null, - "stageVariables": null, - "body": "Hello from Lambda!", - "isBase64Encoded": false -} diff --git a/packages/parser/tests/events/apiGatewayProxyV2Event.json b/packages/parser/tests/events/apiGatewayProxyV2Event.json deleted file mode 100644 index c01ff40d82..0000000000 --- a/packages/parser/tests/events/apiGatewayProxyV2Event.json +++ /dev/null @@ -1,63 +0,0 @@ -{ - "version": "2.0", - "routeKey": "$default", - "rawPath": "/my/path", - "rawQueryString": "parameter1=value1¶meter1=value2¶meter2=value", - "cookies": ["cookie1", "cookie2"], - "headers": { - "Header1": "value1", - "Header2": "value1,value2" - }, - "queryStringParameters": { - "parameter1": "value1,value2", - "parameter2": "value" - }, - "requestContext": { - "accountId": "123456789012", - "apiId": "api-id", - "authentication": { - "clientCert": { - "clientCertPem": "CERT_CONTENT", - "subjectDN": "www.example.com", - "issuerDN": "Example issuer", - "serialNumber": "a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1", - "validity": { - "notBefore": "May 28 12:30:02 2019 GMT", - "notAfter": "Aug 5 09:36:04 2021 GMT" - } - } - }, - "authorizer": { - "jwt": { - "claims": { - "claim1": "value1", - "claim2": "value2" - }, - "scopes": ["scope1", "scope2"] - } - }, - "domainName": "id.execute-api.us-east-1.amazonaws.com", - "domainPrefix": "id", - "http": { - "method": "POST", - "path": "/my/path", - "protocol": "HTTP/1.1", - "sourceIp": "192.168.0.1", - "userAgent": "agent" - }, - "requestId": "id", - "routeKey": "$default", - "stage": "$default", - "time": "12/Mar/2020:19:03:58 +0000", - "timeEpoch": 1583348638390 - }, - "body": "{\"message\": \"hello world\", \"username\": \"tom\"}", - "pathParameters": { - "parameter1": "value1" - }, - "isBase64Encoded": false, - "stageVariables": { - "stageVariable1": "value1", - "stageVariable2": "value2" - } -} diff --git a/packages/parser/tests/events/apiGatewayProxyV2EventPathTrailingSlash.json b/packages/parser/tests/events/apiGatewayProxyV2EventPathTrailingSlash.json deleted file mode 100644 index b61beaa0e6..0000000000 --- a/packages/parser/tests/events/apiGatewayProxyV2EventPathTrailingSlash.json +++ /dev/null @@ -1,63 +0,0 @@ -{ - "version": "2.0", - "routeKey": "$default", - "rawPath": "/my/path/", - "rawQueryString": "parameter1=value1¶meter1=value2¶meter2=value", - "cookies": ["cookie1", "cookie2"], - "headers": { - "Header1": "value1", - "Header2": "value1,value2" - }, - "queryStringParameters": { - "parameter1": "value1,value2", - "parameter2": "value" - }, - "requestContext": { - "accountId": "123456789012", - "apiId": "api-id", - "authentication": { - "clientCert": { - "clientCertPem": "CERT_CONTENT", - "subjectDN": "www.example.com", - "issuerDN": "Example issuer", - "serialNumber": "a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1", - "validity": { - "notBefore": "May 28 12:30:02 2019 GMT", - "notAfter": "Aug 5 09:36:04 2021 GMT" - } - } - }, - "authorizer": { - "jwt": { - "claims": { - "claim1": "value1", - "claim2": "value2" - }, - "scopes": ["scope1", "scope2"] - } - }, - "domainName": "id.execute-api.us-east-1.amazonaws.com", - "domainPrefix": "id", - "http": { - "method": "POST", - "path": "/my/path", - "protocol": "HTTP/1.1", - "sourceIp": "192.168.0.1", - "userAgent": "agent" - }, - "requestId": "id", - "routeKey": "$default", - "stage": "$default", - "time": "12/Mar/2020:19:03:58 +0000", - "timeEpoch": 1583348638390 - }, - "body": "{\"message\": \"hello world\", \"username\": \"tom\"}", - "pathParameters": { - "parameter1": "value1" - }, - "isBase64Encoded": false, - "stageVariables": { - "stageVariable1": "value1", - "stageVariable2": "value2" - } -} diff --git a/packages/parser/tests/events/apiGatewayProxyV2Event_GET.json b/packages/parser/tests/events/apiGatewayProxyV2Event_GET.json deleted file mode 100644 index df84c046d4..0000000000 --- a/packages/parser/tests/events/apiGatewayProxyV2Event_GET.json +++ /dev/null @@ -1,62 +0,0 @@ -{ - "version": "2.0", - "routeKey": "$default", - "rawPath": "/my/path", - "rawQueryString": "parameter1=value1¶meter1=value2¶meter2=value", - "cookies": ["cookie1", "cookie2"], - "headers": { - "Header1": "value1", - "Header2": "value1,value2" - }, - "queryStringParameters": { - "parameter1": "value1,value2", - "parameter2": "value" - }, - "requestContext": { - "accountId": "123456789012", - "apiId": "api-id", - "authentication": { - "clientCert": { - "clientCertPem": "CERT_CONTENT", - "subjectDN": "www.example.com", - "issuerDN": "Example issuer", - "serialNumber": "a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1", - "validity": { - "notBefore": "May 28 12:30:02 2019 GMT", - "notAfter": "Aug 5 09:36:04 2021 GMT" - } - } - }, - "authorizer": { - "jwt": { - "claims": { - "claim1": "value1", - "claim2": "value2" - }, - "scopes": ["scope1", "scope2"] - } - }, - "domainName": "id.execute-api.us-east-1.amazonaws.com", - "domainPrefix": "id", - "http": { - "method": "GET", - "path": "/my/path", - "protocol": "HTTP/1.1", - "sourceIp": "192.168.0.1", - "userAgent": "agent" - }, - "requestId": "id", - "routeKey": "$default", - "stage": "$default", - "time": "12/Mar/2020:19:03:58 +0000", - "timeEpoch": 1583348638390 - }, - "pathParameters": { - "parameter1": "value1" - }, - "isBase64Encoded": false, - "stageVariables": { - "stageVariable1": "value1", - "stageVariable2": "value2" - } -} diff --git a/packages/parser/tests/events/apiGatewayProxyV2IamEvent.json b/packages/parser/tests/events/apiGatewayProxyV2IamEvent.json deleted file mode 100644 index 3bc003d656..0000000000 --- a/packages/parser/tests/events/apiGatewayProxyV2IamEvent.json +++ /dev/null @@ -1,57 +0,0 @@ -{ - "version": "2.0", - "routeKey": "$default", - "rawPath": "/my/path", - "rawQueryString": "parameter1=value1¶meter1=value2¶meter2=value", - "cookies": ["cookie1", "cookie2"], - "headers": { - "Header1": "value1", - "Header2": "value2" - }, - "queryStringParameters": { - "parameter1": "value1,value2", - "parameter2": "value" - }, - "pathParameters": { - "proxy": "hello/world" - }, - "requestContext": { - "routeKey": "$default", - "accountId": "123456789012", - "stage": "$default", - "requestId": "id", - "authorizer": { - "iam": { - "accessKey": "ARIA2ZJZYVUEREEIHAKY", - "accountId": "1234567890", - "callerId": "AROA7ZJZYVRE7C3DUXHH6:CognitoIdentityCredentials", - "cognitoIdentity": { - "amr": ["foo"], - "identityId": "us-east-1:3f291106-8703-466b-8f2b-3ecee1ca56ce", - "identityPoolId": "us-east-1:4f291106-8703-466b-8f2b-3ecee1ca56ce" - }, - "principalOrgId": "AwsOrgId", - "userArn": "arn:aws:iam::1234567890:user/Admin", - "userId": "AROA2ZJZYVRE7Y3TUXHH6" - } - }, - "apiId": "api-id", - "domainName": "id.execute-api.us-east-1.amazonaws.com", - "domainPrefix": "id", - "time": "12/Mar/2020:19:03:58+0000", - "timeEpoch": 1583348638390, - "http": { - "method": "GET", - "path": "/my/path", - "protocol": "HTTP/1.1", - "sourceIp": "192.168.0.1", - "userAgent": "agent" - } - }, - "stageVariables": { - "stageVariable1": "value1", - "stageVariable2": "value2" - }, - "body": "{\r\n\t\"a\": 1\r\n}", - "isBase64Encoded": false -} diff --git a/packages/parser/tests/events/apiGatewayProxyV2LambdaAuthorizerEvent.json b/packages/parser/tests/events/apiGatewayProxyV2LambdaAuthorizerEvent.json deleted file mode 100644 index 58ba0489e0..0000000000 --- a/packages/parser/tests/events/apiGatewayProxyV2LambdaAuthorizerEvent.json +++ /dev/null @@ -1,47 +0,0 @@ -{ - "version": "2.0", - "routeKey": "$default", - "rawPath": "/my/path", - "rawQueryString": "parameter1=value1¶meter1=value2¶meter2=value", - "cookies": ["cookie1", "cookie2"], - "headers": { - "Header1": "value1", - "Header2": "value2" - }, - "queryStringParameters": { - "parameter1": "value1,value2", - "parameter2": "value" - }, - "pathParameters": { - "proxy": "hello/world" - }, - "requestContext": { - "routeKey": "$default", - "accountId": "123456789012", - "stage": "$default", - "requestId": "id", - "authorizer": { - "lambda": { - "key": "value" - } - }, - "apiId": "api-id", - "domainName": "id.execute-api.us-east-1.amazonaws.com", - "domainPrefix": "id", - "time": "12/Mar/2020:19:03:58+0000", - "timeEpoch": 1583348638390, - "http": { - "method": "GET", - "path": "/my/path", - "protocol": "HTTP/1.1", - "sourceIp": "192.168.0.1", - "userAgent": "agent" - } - }, - "stageVariables": { - "stageVariable1": "value1", - "stageVariable2": "value2" - }, - "body": "{\r\n\t\"a\": 1\r\n}", - "isBase64Encoded": false -} diff --git a/packages/parser/tests/events/apiGatewayProxyV2OtherGetEvent.json b/packages/parser/tests/events/apiGatewayProxyV2OtherGetEvent.json deleted file mode 100644 index b600aa35c3..0000000000 --- a/packages/parser/tests/events/apiGatewayProxyV2OtherGetEvent.json +++ /dev/null @@ -1,62 +0,0 @@ -{ - "version": "2.0", - "routeKey": "$default", - "rawPath": "/other/path", - "rawQueryString": "parameter1=value1¶meter1=value2¶meter2=value", - "cookies": ["cookie1", "cookie2"], - "headers": { - "Header1": "value1", - "Header2": "value1,value2" - }, - "queryStringParameters": { - "parameter1": "value1,value2", - "parameter2": "value" - }, - "requestContext": { - "accountId": "123456789012", - "apiId": "api-id", - "authentication": { - "clientCert": { - "clientCertPem": "CERT_CONTENT", - "subjectDN": "www.example.com", - "issuerDN": "Example issuer", - "serialNumber": "a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1", - "validity": { - "notBefore": "May 28 12:30:02 2019 GMT", - "notAfter": "Aug 5 09:36:04 2021 GMT" - } - } - }, - "authorizer": { - "jwt": { - "claims": { - "claim1": "value1", - "claim2": "value2" - }, - "scopes": ["scope1", "scope2"] - } - }, - "domainName": "id.execute-api.us-east-1.amazonaws.com", - "domainPrefix": "id", - "http": { - "method": "GET", - "path": "/other/path", - "protocol": "HTTP/1.1", - "sourceIp": "192.168.0.1", - "userAgent": "agent" - }, - "requestId": "id", - "routeKey": "$default", - "stage": "$default", - "time": "12/Mar/2020:19:03:58 +0000", - "timeEpoch": 1583348638390 - }, - "pathParameters": { - "parameter1": "value1" - }, - "isBase64Encoded": false, - "stageVariables": { - "stageVariable1": "value1", - "stageVariable2": "value2" - } -} diff --git a/packages/parser/tests/events/apiGatewayProxyV2SchemaMiddlewareInvalidEvent.json b/packages/parser/tests/events/apiGatewayProxyV2SchemaMiddlewareInvalidEvent.json deleted file mode 100644 index 9ecf730d4b..0000000000 --- a/packages/parser/tests/events/apiGatewayProxyV2SchemaMiddlewareInvalidEvent.json +++ /dev/null @@ -1,63 +0,0 @@ -{ - "version": "2.0", - "routeKey": "$default", - "rawPath": "/my/path", - "rawQueryString": "parameter1=value1¶meter1=value2¶meter2=value", - "cookies": ["cookie1", "cookie2"], - "headers": { - "Header1": "value1", - "Header2": "value1,value2" - }, - "queryStringParameters": { - "parameter1": "value1,value2", - "parameter2": "value" - }, - "requestContext": { - "accountId": "123456789012", - "apiId": "api-id", - "authentication": { - "clientCert": { - "clientCertPem": "CERT_CONTENT", - "subjectDN": "www.example.com", - "issuerDN": "Example issuer", - "serialNumber": "a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1", - "validity": { - "notBefore": "May 28 12:30:02 2019 GMT", - "notAfter": "Aug 5 09:36:04 2021 GMT" - } - } - }, - "authorizer": { - "jwt": { - "claims": { - "claim1": "value1", - "claim2": "value2" - }, - "scopes": ["scope1", "scope2"] - } - }, - "domainName": "id.execute-api.us-east-1.amazonaws.com", - "domainPrefix": "id", - "http": { - "method": "POST", - "path": "/my/path", - "protocol": "HTTP/1.1", - "sourceIp": "192.168.0.1", - "userAgent": "agent" - }, - "requestId": "id", - "routeKey": "$default", - "stage": "$default", - "time": "12/Mar/2020:19:03:58 +0000", - "timeEpoch": 1583348638390 - }, - "body": "{\"username\": \"lessa\"}", - "pathParameters": { - "parameter1": "value1" - }, - "isBase64Encoded": false, - "stageVariables": { - "stageVariable1": "value1", - "stageVariable2": "value2" - } -} diff --git a/packages/parser/tests/events/apiGatewayProxyV2SchemaMiddlewareValidEvent.json b/packages/parser/tests/events/apiGatewayProxyV2SchemaMiddlewareValidEvent.json deleted file mode 100644 index 1e5802a685..0000000000 --- a/packages/parser/tests/events/apiGatewayProxyV2SchemaMiddlewareValidEvent.json +++ /dev/null @@ -1,63 +0,0 @@ -{ - "version": "2.0", - "routeKey": "$default", - "rawPath": "/my/path", - "rawQueryString": "parameter1=value1¶meter1=value2¶meter2=value", - "cookies": ["cookie1", "cookie2"], - "headers": { - "Header1": "value1", - "Header2": "value1,value2" - }, - "queryStringParameters": { - "parameter1": "value1,value2", - "parameter2": "value" - }, - "requestContext": { - "accountId": "123456789012", - "apiId": "api-id", - "authentication": { - "clientCert": { - "clientCertPem": "CERT_CONTENT", - "subjectDN": "www.example.com", - "issuerDN": "Example issuer", - "serialNumber": "a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1", - "validity": { - "notBefore": "May 28 12:30:02 2019 GMT", - "notAfter": "Aug 5 09:36:04 2021 GMT" - } - } - }, - "authorizer": { - "jwt": { - "claims": { - "claim1": "value1", - "claim2": "value2" - }, - "scopes": ["scope1", "scope2"] - } - }, - "domainName": "id.execute-api.us-east-1.amazonaws.com", - "domainPrefix": "id", - "http": { - "method": "POST", - "path": "/my/path", - "protocol": "HTTP/1.1", - "sourceIp": "192.168.0.1", - "userAgent": "agent" - }, - "requestId": "id", - "routeKey": "$default", - "stage": "$default", - "time": "12/Mar/2020:19:03:58 +0000", - "timeEpoch": 1583348638390 - }, - "body": "{\"message\": \"hello world\", \"username\": \"lessa\"}", - "pathParameters": { - "parameter1": "value1" - }, - "isBase64Encoded": false, - "stageVariables": { - "stageVariable1": "value1", - "stageVariable2": "value2" - } -} diff --git a/packages/parser/tests/events/apiGatewaySchemaMiddlewareInvalidEvent.json b/packages/parser/tests/events/apiGatewaySchemaMiddlewareInvalidEvent.json deleted file mode 100644 index bc5d7ae252..0000000000 --- a/packages/parser/tests/events/apiGatewaySchemaMiddlewareInvalidEvent.json +++ /dev/null @@ -1,71 +0,0 @@ -{ - "version": "1.0", - "resource": "/my/path", - "path": "/my/path", - "httpMethod": "POST", - "headers": { - "Header1": "value1", - "Header2": "value2", - "Origin": "https://aws.amazon.com" - }, - "multiValueHeaders": { - "Header1": ["value1"], - "Header2": ["value1", "value2"] - }, - "queryStringParameters": { - "parameter1": "value1", - "parameter2": "value" - }, - "multiValueQueryStringParameters": { - "parameter1": ["value1", "value2"], - "parameter2": ["value"] - }, - "requestContext": { - "accountId": "123456789012", - "apiId": "id", - "authorizer": { - "claims": null, - "scopes": null - }, - "domainName": "id.execute-api.us-east-1.amazonaws.com", - "domainPrefix": "id", - "extendedRequestId": "request-id", - "httpMethod": "GET", - "identity": { - "accessKey": null, - "accountId": null, - "caller": null, - "cognitoAuthenticationProvider": null, - "cognitoAuthenticationType": null, - "cognitoIdentityId": null, - "cognitoIdentityPoolId": null, - "principalOrgId": null, - "sourceIp": "192.168.0.1", - "user": null, - "userAgent": "user-agent", - "userArn": null, - "clientCert": { - "clientCertPem": "CERT_CONTENT", - "subjectDN": "www.example.com", - "issuerDN": "Example issuer", - "serialNumber": "a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1", - "validity": { - "notBefore": "May 28 12:30:02 2019 GMT", - "notAfter": "Aug 5 09:36:04 2021 GMT" - } - } - }, - "path": "/my/path", - "protocol": "HTTP/1.1", - "requestId": "id=", - "requestTime": "04/Mar/2020:19:15:17 +0000", - "requestTimeEpoch": 1583349317135, - "resourceId": null, - "resourcePath": "/my/path", - "stage": "$default" - }, - "pathParameters": null, - "stageVariables": null, - "body": "{\"username\": \"lessa\"}", - "isBase64Encoded": false -} diff --git a/packages/parser/tests/events/apiGatewaySchemaMiddlewareValidEvent.json b/packages/parser/tests/events/apiGatewaySchemaMiddlewareValidEvent.json deleted file mode 100644 index e3d5236ce5..0000000000 --- a/packages/parser/tests/events/apiGatewaySchemaMiddlewareValidEvent.json +++ /dev/null @@ -1,71 +0,0 @@ -{ - "version": "1.0", - "resource": "/my/path", - "path": "/my/path", - "httpMethod": "POST", - "headers": { - "Header1": "value1", - "Header2": "value2", - "Origin": "https://aws.amazon.com" - }, - "multiValueHeaders": { - "Header1": ["value1"], - "Header2": ["value1", "value2"] - }, - "queryStringParameters": { - "parameter1": "value1", - "parameter2": "value" - }, - "multiValueQueryStringParameters": { - "parameter1": ["value1", "value2"], - "parameter2": ["value"] - }, - "requestContext": { - "accountId": "123456789012", - "apiId": "id", - "authorizer": { - "claims": null, - "scopes": null - }, - "domainName": "id.execute-api.us-east-1.amazonaws.com", - "domainPrefix": "id", - "extendedRequestId": "request-id", - "httpMethod": "GET", - "identity": { - "accessKey": null, - "accountId": null, - "caller": null, - "cognitoAuthenticationProvider": null, - "cognitoAuthenticationType": null, - "cognitoIdentityId": null, - "cognitoIdentityPoolId": null, - "principalOrgId": null, - "sourceIp": "192.168.0.1", - "user": null, - "userAgent": "user-agent", - "userArn": null, - "clientCert": { - "clientCertPem": "CERT_CONTENT", - "subjectDN": "www.example.com", - "issuerDN": "Example issuer", - "serialNumber": "a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1", - "validity": { - "notBefore": "May 28 12:30:02 2019 GMT", - "notAfter": "Aug 5 09:36:04 2021 GMT" - } - } - }, - "path": "/my/path", - "protocol": "HTTP/1.1", - "requestId": "id=", - "requestTime": "04/Mar/2020:19:15:17 +0000", - "requestTimeEpoch": 1583349317135, - "resourceId": null, - "resourcePath": "/my/path", - "stage": "$default" - }, - "pathParameters": null, - "stageVariables": null, - "body": "{\"message\": \"hello world\", \"username\": \"lessa\"}", - "isBase64Encoded": false -} diff --git a/packages/parser/tests/events/apigw-http/invalid.json b/packages/parser/tests/events/apigw-http/invalid.json deleted file mode 100644 index 49b19388d6..0000000000 --- a/packages/parser/tests/events/apigw-http/invalid.json +++ /dev/null @@ -1,22 +0,0 @@ -{ - "resource": "/", - "path": "/invalid", - "httpMethod": "GET", - "headers": {}, - "multiValueHeaders": {}, - "isBase64Encoded": false, - "body": "Foo!", - "requestContext": { - "accountId": "1234", - "apiId": "myApi", - "httpMethod": "GET", - "identity": { - "sourceIp": "127.0.0.1" - }, - "path": "/", - "protocol": "Https", - "requestId": "1234", - "requestTime": "2018-09-07T16: 20: 46Z", - "requestTimeEpoch": 1536992496000 - } -} diff --git a/packages/parser/tests/events/appSyncAuthorizerEvent.json b/packages/parser/tests/events/appSyncAuthorizerEvent.json deleted file mode 100644 index 5b58de9dd4..0000000000 --- a/packages/parser/tests/events/appSyncAuthorizerEvent.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "authorizationToken": "BE9DC5E3-D410-4733-AF76-70178092E681", - "requestContext": { - "apiId": "giy7kumfmvcqvbedntjwjvagii", - "accountId": "254688921111", - "requestId": "b80ed838-14c6-4500-b4c3-b694c7bef086", - "queryString": "mutation MyNewTask($desc: String!) {\n createTask(description: $desc, owner: \"ccc\", taskStatus: \"cc\", title: \"ccc\") {\n id\n }\n}\n", - "operationName": "MyNewTask", - "variables": { - "desc": "Foo" - } - } -} diff --git a/packages/parser/tests/events/appSyncAuthorizerResponse.json b/packages/parser/tests/events/appSyncAuthorizerResponse.json deleted file mode 100644 index dfd52d9498..0000000000 --- a/packages/parser/tests/events/appSyncAuthorizerResponse.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "isAuthorized": true, - "resolverContext": { - "name": "Foo Man", - "balance": 100 - }, - "deniedFields": ["Mutation.createEvent"], - "ttlOverride": 15 -} diff --git a/packages/parser/tests/events/appSyncDirectResolver.json b/packages/parser/tests/events/appSyncDirectResolver.json deleted file mode 100644 index 64054c9acb..0000000000 --- a/packages/parser/tests/events/appSyncDirectResolver.json +++ /dev/null @@ -1,68 +0,0 @@ -{ - "arguments": { - "id": "my identifier" - }, - "identity": { - "claims": { - "sub": "192879fc-a240-4bf1-ab5a-d6a00f3063f9", - "email_verified": true, - "iss": "https://cognito-idp.us-west-2.amazonaws.com/us-west-xxxxxxxxxxx", - "phone_number_verified": false, - "cognito:username": "jdoe", - "aud": "7471s60os7h0uu77i1tk27sp9n", - "event_id": "bc334ed8-a938-4474-b644-9547e304e606", - "token_use": "id", - "auth_time": 1599154213, - "phone_number": "+19999999999", - "exp": 1599157813, - "iat": 1599154213, - "email": "jdoe@email.com" - }, - "defaultAuthStrategy": "ALLOW", - "groups": null, - "issuer": "https://cognito-idp.us-west-2.amazonaws.com/us-west-xxxxxxxxxxx", - "sourceIp": ["1.1.1.1"], - "sub": "192879fc-a240-4bf1-ab5a-d6a00f3063f9", - "username": "jdoe" - }, - "source": null, - "request": { - "headers": { - "x-forwarded-for": "1.1.1.1, 2.2.2.2", - "cloudfront-viewer-country": "US", - "cloudfront-is-tablet-viewer": "false", - "via": "2.0 xxxxxxxxxxxxxxxx.cloudfront.net (CloudFront)", - "cloudfront-forwarded-proto": "https", - "origin": "https://us-west-1.console.aws.amazon.com", - "content-length": "217", - "accept-language": "en-US,en;q=0.9", - "host": "xxxxxxxxxxxxxxxx.appsync-api.us-west-1.amazonaws.com", - "x-forwarded-proto": "https", - "user-agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.83 Safari/537.36", - "accept": "*/*", - "cloudfront-is-mobile-viewer": "false", - "cloudfront-is-smarttv-viewer": "false", - "accept-encoding": "gzip, deflate, br", - "referer": "https://us-west-1.console.aws.amazon.com/appsync/home?region=us-west-1", - "content-type": "application/json", - "sec-fetch-mode": "cors", - "x-amz-cf-id": "3aykhqlUwQeANU-HGY7E_guV5EkNeMMtwyOgiA==", - "x-amzn-trace-id": "Root=1-5f512f51-fac632066c5e848ae714", - "authorization": "eyJraWQiOiJScWFCSlJqYVJlM0hrSnBTUFpIcVRXazNOW...", - "sec-fetch-dest": "empty", - "x-amz-user-agent": "AWS-Console-AppSync/", - "cloudfront-is-desktop-viewer": "true", - "sec-fetch-site": "cross-site", - "x-forwarded-port": "443" - } - }, - "prev": null, - "info": { - "selectionSetList": ["id", "field1", "field2"], - "selectionSetGraphQL": "{\n id\n field1\n field2\n}", - "parentTypeName": "Mutation", - "fieldName": "createSomething", - "variables": {} - }, - "stash": {} -} diff --git a/packages/parser/tests/events/appSyncResolverEvent.json b/packages/parser/tests/events/appSyncResolverEvent.json deleted file mode 100644 index 6a5d72195c..0000000000 --- a/packages/parser/tests/events/appSyncResolverEvent.json +++ /dev/null @@ -1,69 +0,0 @@ -{ - "typeName": "Merchant", - "fieldName": "locations", - "arguments": { - "page": 2, - "size": 1, - "name": "value" - }, - "identity": { - "claims": { - "sub": "07920713-4526-4642-9c88-2953512de441", - "iss": "https://cognito-idp.us-east-1.amazonaws.com/us-east-1_POOL_ID", - "aud": "58rc9bf5kkti90ctmvioppukm9", - "event_id": "7f4c9383-abf6-48b7-b821-91643968b755", - "token_use": "id", - "auth_time": 1615366261, - "name": "Michael Brewer", - "exp": 1615369861, - "iat": 1615366261 - }, - "defaultAuthStrategy": "ALLOW", - "groups": null, - "issuer": "https://cognito-idp.us-east-1.amazonaws.com/us-east-1_POOL_ID", - "sourceIp": ["11.215.2.22"], - "sub": "07920713-4526-4642-9c88-2953512de441", - "username": "mike" - }, - "source": { - "name": "Value", - "nested": { - "name": "value", - "list": [] - } - }, - "request": { - "headers": { - "x-forwarded-for": "11.215.2.22, 64.44.173.11", - "cloudfront-viewer-country": "US", - "cloudfront-is-tablet-viewer": "false", - "via": "2.0 SOMETHING.cloudfront.net (CloudFront)", - "cloudfront-forwarded-proto": "https", - "origin": "https://console.aws.amazon.com", - "content-length": "156", - "accept-language": "en-US,en;q=0.9", - "host": "SOMETHING.appsync-api.us-east-1.amazonaws.com", - "x-forwarded-proto": "https", - "sec-gpc": "1", - "user-agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) etc.", - "accept": "*/*", - "cloudfront-is-mobile-viewer": "false", - "cloudfront-is-smarttv-viewer": "false", - "accept-encoding": "gzip, deflate, br", - "referer": "https://console.aws.amazon.com/", - "content-type": "application/json", - "sec-fetch-mode": "cors", - "x-amz-cf-id": "Fo5VIuvP6V6anIEt62WzFDCK45mzM4yEdpt5BYxOl9OFqafd-WR0cA==", - "x-amzn-trace-id": "Root=1-60488877-0b0c4e6727ab2a1c545babd0", - "authorization": "AUTH-HEADER", - "sec-fetch-dest": "empty", - "x-amz-user-agent": "AWS-Console-AppSync/", - "cloudfront-is-desktop-viewer": "true", - "sec-fetch-site": "cross-site", - "x-forwarded-port": "443" - } - }, - "prev": { - "result": {} - } -} diff --git a/packages/parser/tests/events/bedrockAgentEvent.json b/packages/parser/tests/events/bedrockAgentEvent.json deleted file mode 100644 index b7ad75b3c4..0000000000 --- a/packages/parser/tests/events/bedrockAgentEvent.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "actionGroup": "ClaimManagementActionGroup", - "messageVersion": "1.0", - "sessionId": "12345678912345", - "sessionAttributes": {}, - "promptSessionAttributes": {}, - "inputText": "I want to claim my insurance", - "agent": { - "alias": "TSTALIASID", - "name": "test", - "version": "DRAFT", - "id": "8ZXY0W8P1H" - }, - "httpMethod": "GET", - "apiPath": "/claims" -} diff --git a/packages/parser/tests/events/bedrockAgentPostEvent.json b/packages/parser/tests/events/bedrockAgentPostEvent.json deleted file mode 100644 index f223bfcd51..0000000000 --- a/packages/parser/tests/events/bedrockAgentPostEvent.json +++ /dev/null @@ -1,35 +0,0 @@ -{ - "actionGroup": "ClaimManagementActionGroup", - "messageVersion": "1.0", - "sessionId": "12345678912345", - "sessionAttributes": {}, - "promptSessionAttributes": {}, - "inputText": "Send reminders to all pending documents", - "agent": { - "alias": "TSTALIASID", - "name": "test", - "version": "DRAFT", - "id": "8ZXY0W8P1H" - }, - "httpMethod": "POST", - "apiPath": "/send-reminders", - "requestBody": { - "content": { - "application/json": { - "properties": [ - { - "name": "claimId", - "type": "string", - "value": "20" - }, - { - "name": "pendingDocuments", - "type": "string", - "value": "social number and vat" - } - ] - } - } - }, - "parameters": [] -} diff --git a/packages/parser/tests/events/cloudWatchDashboardEvent.json b/packages/parser/tests/events/cloudWatchDashboardEvent.json deleted file mode 100644 index fd2d3be62d..0000000000 --- a/packages/parser/tests/events/cloudWatchDashboardEvent.json +++ /dev/null @@ -1,38 +0,0 @@ -{ - "original": "param-to-widget", - "widgetContext": { - "dashboardName": "Name-of-current-dashboard", - "widgetId": "widget-16", - "domain": "https://us-east-1.console.aws.amazon.com", - "accountId": "123456789123", - "locale": "en", - "timezone": { - "label": "UTC", - "offsetISO": "+00:00", - "offsetInMinutes": 0 - }, - "period": 300, - "isAutoPeriod": true, - "timeRange": { - "mode": "relative", - "start": 1627236199729, - "end": 1627322599729, - "relativeStart": 86400012, - "zoom": { - "start": 1627276030434, - "end": 1627282956521 - } - }, - "theme": "light", - "linkCharts": true, - "title": "Tweets for Amazon website problem", - "forms": { - "all": {} - }, - "params": { - "original": "param-to-widget" - }, - "width": 588, - "height": 369 - } -} diff --git a/packages/parser/tests/events/cloudFormationCustomResourceCreateEvent.json b/packages/parser/tests/events/cloudformation/create.json similarity index 100% rename from packages/parser/tests/events/cloudFormationCustomResourceCreateEvent.json rename to packages/parser/tests/events/cloudformation/create.json diff --git a/packages/parser/tests/events/cloudFormationCustomResourceDeleteEvent.json b/packages/parser/tests/events/cloudformation/delete.json similarity index 100% rename from packages/parser/tests/events/cloudFormationCustomResourceDeleteEvent.json rename to packages/parser/tests/events/cloudformation/delete.json diff --git a/packages/parser/tests/events/cloudFormationCustomResourceUpdateEvent.json b/packages/parser/tests/events/cloudformation/update.json similarity index 100% rename from packages/parser/tests/events/cloudFormationCustomResourceUpdateEvent.json rename to packages/parser/tests/events/cloudformation/update.json diff --git a/packages/parser/tests/events/cloudWatchLogEvent.json b/packages/parser/tests/events/cloudwatch/base.json similarity index 100% rename from packages/parser/tests/events/cloudWatchLogEvent.json rename to packages/parser/tests/events/cloudwatch/base.json diff --git a/packages/parser/tests/events/codePipelineEvent.json b/packages/parser/tests/events/codePipelineEvent.json deleted file mode 100644 index 4c46b0172b..0000000000 --- a/packages/parser/tests/events/codePipelineEvent.json +++ /dev/null @@ -1,34 +0,0 @@ -{ - "CodePipeline.job": { - "id": "11111111-abcd-1111-abcd-111111abcdef", - "accountId": "111111111111", - "data": { - "actionConfiguration": { - "configuration": { - "FunctionName": "MyLambdaFunctionForAWSCodePipeline", - "UserParameters": "some-input-such-as-a-URL" - } - }, - "inputArtifacts": [ - { - "name": "ArtifactName", - "revision": null, - "location": { - "type": "S3", - "s3Location": { - "bucketName": "the name of the bucket configured as the pipeline artifact store in Amazon S3, for example codepipeline-us-east-2-1234567890", - "objectKey": "the name of the application, for example CodePipelineDemoApplication.zip" - } - } - } - ], - "outputArtifacts": [], - "artifactCredentials": { - "accessKeyId": "AKIAIOSFODNN7EXAMPLE", - "secretAccessKey": "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY", - "sessionToken": "MIICiTCCAfICCQD6m7oRw0uXOjANBgkqhkiG9w0BAQUFADCBiDELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAldBMRAwDgYDVQQHEwdTZWF0dGxlMQ8wDQYDVQQKEwZBbWF6b24xFDASBgNVBAsTC0lBTSBDb25zb2xlMRIwEAYDVQQDEwlUZXN0Q2lsYWMxHzAdBgkqhkiG9w0BCQEWEG5vb25lQGFtYXpvbi5jb20wHhcNMTEwNDI1MjA0NTIxWhcNMTIwNDI0MjA0NTIxWjCBiDELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAldBMRAwDgYDVQQHEwdTZWF0dGxlMQ8wDQYDVQQKEwZBbWF6b24xFDASBgNVBAsTC0lBTSBDb25zb2xlMRIwEAYDVQQDEwlUZXN0Q2lsYWMxHzAdBgkqhkiG9w0BCQEWEG5vb25lQGFtYXpvbi5jb20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMaK0dn+a4GmWIWJ21uUSfwfEvySWtC2XADZ4nB+BLYgVIk60CpiwsZ3G93vUEIO3IyNoH/f0wYK8m9TrDHudUZg3qX4waLG5M43q7Wgc/MbQITxOUSQv7c7ugFFDzQGBzZswY6786m86gpEIbb3OhjZnzcvQAaRHhdlQWIMm2nrAgMBAAEwDQYJKoZIhvcNAQEFBQADgYEAtCu4nUhVVxYUntneD9+h8Mg9q6q+auNKyExzyLwaxlAoo7TJHidbtS4J5iNmZgXL0FkbFFBjvSfpJIlJ00zbhNYS5f6GuoEDmFJl0ZxBHjJnyp378OD8uTs7fLvjx79LjSTbNYiytVbZPQUQ5Yaxu2jXnimvw3rrszlaEXAMPLE=" - }, - "continuationToken": "A continuation token if continuing job" - } - } -} diff --git a/packages/parser/tests/events/codePipelineEventData.json b/packages/parser/tests/events/codePipelineEventData.json deleted file mode 100644 index dbbc18ea7b..0000000000 --- a/packages/parser/tests/events/codePipelineEventData.json +++ /dev/null @@ -1,46 +0,0 @@ -{ - "CodePipeline.job": { - "id": "c0d76431-b0e7-xmpl-97e3-e8ee786eb6f6", - "accountId": "123456789012", - "data": { - "actionConfiguration": { - "configuration": { - "FunctionName": "my-function", - "UserParameters": "{\"KEY\": \"VALUE\"}" - } - }, - "inputArtifacts": [ - { - "name": "my-pipeline-SourceArtifact", - "revision": "e0c7xmpl2308ca3071aa7bab414de234ab52eea", - "location": { - "type": "S3", - "s3Location": { - "bucketName": "us-west-2-123456789012-my-pipeline", - "objectKey": "my-pipeline/test-api-2/TdOSFRV" - } - } - } - ], - "outputArtifacts": [ - { - "name": "invokeOutput", - "revision": null, - "location": { - "type": "S3", - "s3Location": { - "bucketName": "us-west-2-123456789012-my-pipeline", - "objectKey": "my-pipeline/invokeOutp/D0YHsJn" - } - } - } - ], - "artifactCredentials": { - "accessKeyId": "AKIAIOSFODNN7EXAMPLE", - "secretAccessKey": "6CGtmAa3lzWtV7a...", - "sessionToken": "IQoJb3JpZ2luX2VjEA...", - "expirationTime": 1575493418000 - } - } - } -} diff --git a/packages/parser/tests/events/codePipelineEventEmptyUserParameters.json b/packages/parser/tests/events/codePipelineEventEmptyUserParameters.json deleted file mode 100644 index cf395efc19..0000000000 --- a/packages/parser/tests/events/codePipelineEventEmptyUserParameters.json +++ /dev/null @@ -1,32 +0,0 @@ -{ - "CodePipeline.job": { - "id": "11111111-abcd-1111-abcd-111111abcdef", - "accountId": "111111111111", - "data": { - "actionConfiguration": { - "configuration": { - "FunctionName": "MyLambdaFunctionForAWSCodePipeline" - } - }, - "inputArtifacts": [ - { - "name": "ArtifactName", - "revision": null, - "location": { - "type": "S3", - "s3Location": { - "bucketName": "the name of the bucket configured as the pipeline artifact store in Amazon S3, for example codepipeline-us-east-2-1234567890", - "objectKey": "the name of the application, for example CodePipelineDemoApplication.zip" - } - } - } - ], - "outputArtifacts": [], - "artifactCredentials": { - "accessKeyId": "AKIAIOSFODNN7EXAMPLE", - "secretAccessKey": "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY", - "sessionToken": "MIICiTCCAfICCQD6m7oRw0uXOjANBgkqhkiG9w0BAQUFADCBiDELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAldBMRAwDgYDVQQHEwdTZWF0dGxlMQ8wDQYDVQQKEwZBbWF6b24xFDASBgNVBAsTC0lBTSBDb25zb2xlMRIwEAYDVQQDEwlUZXN0Q2lsYWMxHzAdBgkqhkiG9w0BCQEWEG5vb25lQGFtYXpvbi5jb20wHhcNMTEwNDI1MjA0NTIxWhcNMTIwNDI0MjA0NTIxWjCBiDELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAldBMRAwDgYDVQQHEwdTZWF0dGxlMQ8wDQYDVQQKEwZBbWF6b24xFDASBgNVBAsTC0lBTSBDb25zb2xlMRIwEAYDVQQDEwlUZXN0Q2lsYWMxHzAdBgkqhkiG9w0BCQEWEG5vb25lQGFtYXpvbi5jb20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMaK0dn+a4GmWIWJ21uUSfwfEvySWtC2XADZ4nB+BLYgVIk60CpiwsZ3G93vUEIO3IyNoH/f0wYK8m9TrDHudUZg3qX4waLG5M43q7Wgc/MbQITxOUSQv7c7ugFFDzQGBzZswY6786m86gpEIbb3OhjZnzcvQAaRHhdlQWIMm2nrAgMBAAEwDQYJKoZIhvcNAQEFBQADgYEAtCu4nUhVVxYUntneD9+h8Mg9q6q+auNKyExzyLwaxlAoo7TJHidbtS4J5iNmZgXL0FkbFFBjvSfpJIlJ00zbhNYS5f6GuoEDmFJl0ZxBHjJnyp378OD8uTs7fLvjx79LjSTbNYiytVbZPQUQ5Yaxu2jXnimvw3rrszlaEXAMPLE=" - } - } - } -} diff --git a/packages/parser/tests/events/codePipelineEventWithEncryptionKey.json b/packages/parser/tests/events/codePipelineEventWithEncryptionKey.json deleted file mode 100644 index 1e81b70b71..0000000000 --- a/packages/parser/tests/events/codePipelineEventWithEncryptionKey.json +++ /dev/null @@ -1,38 +0,0 @@ -{ - "CodePipeline.job": { - "id": "11111111-abcd-1111-abcd-111111abcdef", - "accountId": "111111111111", - "data": { - "actionConfiguration": { - "configuration": { - "FunctionName": "MyLambdaFunctionForAWSCodePipeline", - "UserParameters": "some-input-such-as-a-URL" - } - }, - "inputArtifacts": [ - { - "name": "ArtifactName", - "revision": null, - "location": { - "type": "S3", - "s3Location": { - "bucketName": "the name of the bucket configured as the pipeline artifact store in Amazon S3, for example codepipeline-us-east-2-1234567890", - "objectKey": "the name of the application, for example CodePipelineDemoApplication.zip" - } - } - } - ], - "outputArtifacts": [], - "artifactCredentials": { - "accessKeyId": "AKIAIOSFODNN7EXAMPLE", - "secretAccessKey": "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY", - "sessionToken": "MIICiTCCAfICCQD6m7oRw0uXOjANBgkqhkiG9w0BAQUFADCBiDELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAldBMRAwDgYDVQQHEwdTZWF0dGxlMQ8wDQYDVQQKEwZBbWF6b24xFDASBgNVBAsTC0lBTSBDb25zb2xlMRIwEAYDVQQDEwlUZXN0Q2lsYWMxHzAdBgkqhkiG9w0BCQEWEG5vb25lQGFtYXpvbi5jb20wHhcNMTEwNDI1MjA0NTIxWhcNMTIwNDI0MjA0NTIxWjCBiDELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAldBMRAwDgYDVQQHEwdTZWF0dGxlMQ8wDQYDVQQKEwZBbWF6b24xFDASBgNVBAsTC0lBTSBDb25zb2xlMRIwEAYDVQQDEwlUZXN0Q2lsYWMxHzAdBgkqhkiG9w0BCQEWEG5vb25lQGFtYXpvbi5jb20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMaK0dn+a4GmWIWJ21uUSfwfEvySWtC2XADZ4nB+BLYgVIk60CpiwsZ3G93vUEIO3IyNoH/f0wYK8m9TrDHudUZg3qX4waLG5M43q7Wgc/MbQITxOUSQv7c7ugFFDzQGBzZswY6786m86gpEIbb3OhjZnzcvQAaRHhdlQWIMm2nrAgMBAAEwDQYJKoZIhvcNAQEFBQADgYEAtCu4nUhVVxYUntneD9+h8Mg9q6q+auNKyExzyLwaxlAoo7TJHidbtS4J5iNmZgXL0FkbFFBjvSfpJIlJ00zbhNYS5f6GuoEDmFJl0ZxBHjJnyp378OD8uTs7fLvjx79LjSTbNYiytVbZPQUQ5Yaxu2jXnimvw3rrszlaEXAMPLE=" - }, - "continuationToken": "A continuation token if continuing job", - "encryptionKey": { - "id": "arn:aws:kms:us-west-2:111122223333:key/1234abcd-12ab-34cd-56ef-1234567890ab", - "type": "KMS" - } - } - } -} diff --git a/packages/parser/tests/events/cognitoCreateAuthChallengeEvent.json b/packages/parser/tests/events/cognito/cognitoCreateAuthChallengeEvent.json similarity index 100% rename from packages/parser/tests/events/cognitoCreateAuthChallengeEvent.json rename to packages/parser/tests/events/cognito/cognitoCreateAuthChallengeEvent.json diff --git a/packages/parser/tests/events/cognitoCustomMessageEvent.json b/packages/parser/tests/events/cognito/cognitoCustomMessageEvent.json similarity index 100% rename from packages/parser/tests/events/cognitoCustomMessageEvent.json rename to packages/parser/tests/events/cognito/cognitoCustomMessageEvent.json diff --git a/packages/parser/tests/events/cognitoDefineAuthChallengeEvent.json b/packages/parser/tests/events/cognito/cognitoDefineAuthChallengeEvent.json similarity index 100% rename from packages/parser/tests/events/cognitoDefineAuthChallengeEvent.json rename to packages/parser/tests/events/cognito/cognitoDefineAuthChallengeEvent.json diff --git a/packages/parser/tests/events/cognitoPostAuthenticationEvent.json b/packages/parser/tests/events/cognito/cognitoPostAuthenticationEvent.json similarity index 100% rename from packages/parser/tests/events/cognitoPostAuthenticationEvent.json rename to packages/parser/tests/events/cognito/cognitoPostAuthenticationEvent.json diff --git a/packages/parser/tests/events/cognitoPostConfirmationEvent.json b/packages/parser/tests/events/cognito/cognitoPostConfirmationEvent.json similarity index 100% rename from packages/parser/tests/events/cognitoPostConfirmationEvent.json rename to packages/parser/tests/events/cognito/cognitoPostConfirmationEvent.json diff --git a/packages/parser/tests/events/cognitoPreAuthenticationEvent.json b/packages/parser/tests/events/cognito/cognitoPreAuthenticationEvent.json similarity index 100% rename from packages/parser/tests/events/cognitoPreAuthenticationEvent.json rename to packages/parser/tests/events/cognito/cognitoPreAuthenticationEvent.json diff --git a/packages/parser/tests/events/cognitoPreSignUpEvent.json b/packages/parser/tests/events/cognito/cognitoPreSignUpEvent.json similarity index 100% rename from packages/parser/tests/events/cognitoPreSignUpEvent.json rename to packages/parser/tests/events/cognito/cognitoPreSignUpEvent.json diff --git a/packages/parser/tests/events/cognitoPreTokenGenerationEvent.json b/packages/parser/tests/events/cognito/cognitoPreTokenGenerationEvent.json similarity index 100% rename from packages/parser/tests/events/cognitoPreTokenGenerationEvent.json rename to packages/parser/tests/events/cognito/cognitoPreTokenGenerationEvent.json diff --git a/packages/parser/tests/events/cognitoUserMigrationEvent.json b/packages/parser/tests/events/cognito/cognitoUserMigrationEvent.json similarity index 100% rename from packages/parser/tests/events/cognitoUserMigrationEvent.json rename to packages/parser/tests/events/cognito/cognitoUserMigrationEvent.json diff --git a/packages/parser/tests/events/cognitoVerifyAuthChallengeResponseEvent.json b/packages/parser/tests/events/cognito/cognitoVerifyAuthChallengeResponseEvent.json similarity index 100% rename from packages/parser/tests/events/cognitoVerifyAuthChallengeResponseEvent.json rename to packages/parser/tests/events/cognito/cognitoVerifyAuthChallengeResponseEvent.json diff --git a/packages/parser/tests/events/awsConfigRuleConfigurationChanged.json b/packages/parser/tests/events/config/awsConfigRuleConfigurationChanged.json similarity index 100% rename from packages/parser/tests/events/awsConfigRuleConfigurationChanged.json rename to packages/parser/tests/events/config/awsConfigRuleConfigurationChanged.json diff --git a/packages/parser/tests/events/awsConfigRuleOversizedConfiguration.json b/packages/parser/tests/events/config/awsConfigRuleOversizedConfiguration.json similarity index 100% rename from packages/parser/tests/events/awsConfigRuleOversizedConfiguration.json rename to packages/parser/tests/events/config/awsConfigRuleOversizedConfiguration.json diff --git a/packages/parser/tests/events/awsConfigRuleScheduled.json b/packages/parser/tests/events/config/awsConfigRuleScheduled.json similarity index 100% rename from packages/parser/tests/events/awsConfigRuleScheduled.json rename to packages/parser/tests/events/config/awsConfigRuleScheduled.json diff --git a/packages/parser/tests/events/connectContactFlowEventAll.json b/packages/parser/tests/events/connect/connectContactFlowEventAll.json similarity index 100% rename from packages/parser/tests/events/connectContactFlowEventAll.json rename to packages/parser/tests/events/connect/connectContactFlowEventAll.json diff --git a/packages/parser/tests/events/connectContactFlowEventMin.json b/packages/parser/tests/events/connect/connectContactFlowEventMin.json similarity index 100% rename from packages/parser/tests/events/connectContactFlowEventMin.json rename to packages/parser/tests/events/connect/connectContactFlowEventMin.json diff --git a/packages/parser/tests/events/dynamoStreamEvent.json b/packages/parser/tests/events/dynamodb/base.json similarity index 100% rename from packages/parser/tests/events/dynamoStreamEvent.json rename to packages/parser/tests/events/dynamodb/base.json diff --git a/packages/parser/tests/events/eventBridgeEvent.json b/packages/parser/tests/events/eventbridge/base.json similarity index 100% rename from packages/parser/tests/events/eventBridgeEvent.json rename to packages/parser/tests/events/eventbridge/base.json diff --git a/packages/parser/tests/events/kafkaEventMsk.json b/packages/parser/tests/events/kafka/msk.json similarity index 100% rename from packages/parser/tests/events/kafkaEventMsk.json rename to packages/parser/tests/events/kafka/msk.json diff --git a/packages/parser/tests/events/kafkaEventSelfManaged.json b/packages/parser/tests/events/kafka/self-managed.json similarity index 100% rename from packages/parser/tests/events/kafkaEventSelfManaged.json rename to packages/parser/tests/events/kafka/self-managed.json diff --git a/packages/parser/tests/events/kinesisFirehosePutEvent.json b/packages/parser/tests/events/kinesis-firehose/direct-put.json similarity index 90% rename from packages/parser/tests/events/kinesisFirehosePutEvent.json rename to packages/parser/tests/events/kinesis-firehose/direct-put.json index 9b91f163ab..48566c73e2 100644 --- a/packages/parser/tests/events/kinesisFirehosePutEvent.json +++ b/packages/parser/tests/events/kinesis-firehose/direct-put.json @@ -11,7 +11,7 @@ { "recordId": "record2", "approximateArrivalTimestamp": 1664029186945, - "data": "eyJIZWxsbyI6ICJXb3JsZCJ9" + "data": "eyJIZWxsbyI6IldvcmxkIn0=" } ] -} +} \ No newline at end of file diff --git a/packages/parser/tests/events/kinesisFirehoseKinesisEvent.json b/packages/parser/tests/events/kinesis-firehose/from-data-stream.json similarity index 96% rename from packages/parser/tests/events/kinesisFirehoseKinesisEvent.json rename to packages/parser/tests/events/kinesis-firehose/from-data-stream.json index bfc2f34a2f..60a10c59b2 100644 --- a/packages/parser/tests/events/kinesisFirehoseKinesisEvent.json +++ b/packages/parser/tests/events/kinesis-firehose/from-data-stream.json @@ -17,7 +17,7 @@ } }, { - "data": "eyJIZWxsbyI6ICJXb3JsZCJ9", + "data": "eyJIZWxsbyI6IldvcmxkIn0=", "recordId": "record2", "approximateArrivalTimestamp": 1664028793294, "kinesisRecordMetadata": { @@ -29,4 +29,4 @@ } } ] -} +} \ No newline at end of file diff --git a/packages/parser/tests/events/kinesisFirehoseSQSEvent.json b/packages/parser/tests/events/kinesis-firehose/sqs-event-via-kinesis-firehose.json similarity index 100% rename from packages/parser/tests/events/kinesisFirehoseSQSEvent.json rename to packages/parser/tests/events/kinesis-firehose/sqs-event-via-kinesis-firehose.json diff --git a/packages/parser/tests/events/kinesisStreamEvent.json b/packages/parser/tests/events/kinesis-stream/base.json similarity index 100% rename from packages/parser/tests/events/kinesisStreamEvent.json rename to packages/parser/tests/events/kinesis-stream/base.json diff --git a/packages/parser/tests/events/kinesisStreamCloudWatchLogsEvent.json b/packages/parser/tests/events/kinesis-stream/cloudwatch-event-via-stream.json similarity index 100% rename from packages/parser/tests/events/kinesisStreamCloudWatchLogsEvent.json rename to packages/parser/tests/events/kinesis-stream/cloudwatch-event-via-stream.json diff --git a/packages/parser/tests/events/kinesisStreamEventOneRecord.json b/packages/parser/tests/events/kinesisStreamEventOneRecord.json deleted file mode 100644 index 1c65b949dd..0000000000 --- a/packages/parser/tests/events/kinesisStreamEventOneRecord.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "Records": [ - { - "kinesis": { - "kinesisSchemaVersion": "1.0", - "partitionKey": "1", - "sequenceNumber": "49590338271490256608559692538361571095921575989136588898", - "data": "eyJtZXNzYWdlIjogInRlc3QgbWVzc2FnZSIsICJ1c2VybmFtZSI6ICJ0ZXN0In0=", - "approximateArrivalTimestamp": 1545084650.987 - }, - "eventSource": "aws:kinesis", - "eventVersion": "1.0", - "eventID": "shardId-000000000006:49590338271490256608559692538361571095921575989136588898", - "eventName": "aws:kinesis:record", - "invokeIdentityArn": "arn:aws:iam::123456789012:role/lambda-role", - "awsRegion": "us-east-2", - "eventSourceARN": "arn:aws:kinesis:us-east-2:123456789012:stream/lambda-stream" - } - ] -} diff --git a/packages/parser/tests/events/lambdaFunctionUrlEvent.json b/packages/parser/tests/events/lambda/base.json similarity index 100% rename from packages/parser/tests/events/lambdaFunctionUrlEvent.json rename to packages/parser/tests/events/lambda/base.json diff --git a/packages/parser/tests/events/lambdaFunctionUrlEventPathTrailingSlash.json b/packages/parser/tests/events/lambda/iam-authorizer.json similarity index 90% rename from packages/parser/tests/events/lambdaFunctionUrlEventPathTrailingSlash.json rename to packages/parser/tests/events/lambda/iam-authorizer.json index 54f6560655..3f3e52c8e6 100644 --- a/packages/parser/tests/events/lambdaFunctionUrlEventPathTrailingSlash.json +++ b/packages/parser/tests/events/lambda/iam-authorizer.json @@ -1,9 +1,12 @@ { "version": "2.0", "routeKey": "$default", - "rawPath": "/my/path/", + "rawPath": "/my/path", "rawQueryString": "parameter1=value1¶meter1=value2¶meter2=value", - "cookies": ["cookie1", "cookie2"], + "cookies": [ + "cookie1", + "cookie2" + ], "headers": { "header1": "value1", "header2": "value1,value2" @@ -30,7 +33,7 @@ "domainName": ".lambda-url.us-west-2.on.aws", "domainPrefix": "", "http": { - "method": "POST", + "method": "GET", "path": "/my/path", "protocol": "HTTP/1.1", "sourceIp": "123.123.123.123", @@ -42,8 +45,7 @@ "time": "12/Mar/2020:19:03:58 +0000", "timeEpoch": 1583348638390 }, - "body": "Hello from client!", "pathParameters": null, "isBase64Encoded": false, "stageVariables": null -} +} \ No newline at end of file diff --git a/packages/parser/tests/events/lambdaFunctionUrlIAMEvent.json b/packages/parser/tests/events/lambda/with-body.json similarity index 94% rename from packages/parser/tests/events/lambdaFunctionUrlIAMEvent.json rename to packages/parser/tests/events/lambda/with-body.json index 5af79f2492..0208657f15 100644 --- a/packages/parser/tests/events/lambdaFunctionUrlIAMEvent.json +++ b/packages/parser/tests/events/lambda/with-body.json @@ -3,7 +3,10 @@ "routeKey": "$default", "rawPath": "/my/path", "rawQueryString": "parameter1=value1¶meter1=value2¶meter2=value", - "cookies": ["cookie1", "cookie2"], + "cookies": [ + "cookie1", + "cookie2" + ], "headers": { "header1": "value1", "header2": "value1,value2" @@ -42,8 +45,8 @@ "time": "12/Mar/2020:19:03:58 +0000", "timeEpoch": 1583348638390 }, - "body": "Hello from client!", "pathParameters": null, + "body": "Hello World!", "isBase64Encoded": false, "stageVariables": null -} +} \ No newline at end of file diff --git a/packages/parser/tests/events/activeMQEvent.json b/packages/parser/tests/events/mq/activeMQEvent.json similarity index 100% rename from packages/parser/tests/events/activeMQEvent.json rename to packages/parser/tests/events/mq/activeMQEvent.json diff --git a/packages/parser/tests/events/rabbitMQEvent.json b/packages/parser/tests/events/mq/rabbitMQEvent.json similarity index 100% rename from packages/parser/tests/events/rabbitMQEvent.json rename to packages/parser/tests/events/mq/rabbitMQEvent.json diff --git a/packages/parser/tests/events/s3Event.json b/packages/parser/tests/events/s3/s3Event.json similarity index 100% rename from packages/parser/tests/events/s3Event.json rename to packages/parser/tests/events/s3/s3Event.json diff --git a/packages/parser/tests/events/s3EventBridgeNotificationObjectCreatedEvent.json b/packages/parser/tests/events/s3/s3EventBridgeNotificationObjectCreatedEvent.json similarity index 100% rename from packages/parser/tests/events/s3EventBridgeNotificationObjectCreatedEvent.json rename to packages/parser/tests/events/s3/s3EventBridgeNotificationObjectCreatedEvent.json diff --git a/packages/parser/tests/events/s3EventBridgeNotificationObjectDeletedEvent.json b/packages/parser/tests/events/s3/s3EventBridgeNotificationObjectDeletedEvent.json similarity index 100% rename from packages/parser/tests/events/s3EventBridgeNotificationObjectDeletedEvent.json rename to packages/parser/tests/events/s3/s3EventBridgeNotificationObjectDeletedEvent.json diff --git a/packages/parser/tests/events/s3EventBridgeNotificationObjectExpiredEvent.json b/packages/parser/tests/events/s3/s3EventBridgeNotificationObjectExpiredEvent.json similarity index 100% rename from packages/parser/tests/events/s3EventBridgeNotificationObjectExpiredEvent.json rename to packages/parser/tests/events/s3/s3EventBridgeNotificationObjectExpiredEvent.json diff --git a/packages/parser/tests/events/s3EventBridgeNotificationObjectRestoreCompletedEvent.json b/packages/parser/tests/events/s3/s3EventBridgeNotificationObjectRestoreCompletedEvent.json similarity index 100% rename from packages/parser/tests/events/s3EventBridgeNotificationObjectRestoreCompletedEvent.json rename to packages/parser/tests/events/s3/s3EventBridgeNotificationObjectRestoreCompletedEvent.json diff --git a/packages/parser/tests/events/s3EventDecodedKey.json b/packages/parser/tests/events/s3/s3EventDecodedKey.json similarity index 100% rename from packages/parser/tests/events/s3EventDecodedKey.json rename to packages/parser/tests/events/s3/s3EventDecodedKey.json diff --git a/packages/parser/tests/events/s3EventDeleteObject.json b/packages/parser/tests/events/s3/s3EventDeleteObject.json similarity index 100% rename from packages/parser/tests/events/s3EventDeleteObject.json rename to packages/parser/tests/events/s3/s3EventDeleteObject.json diff --git a/packages/parser/tests/events/s3EventGlacier.json b/packages/parser/tests/events/s3/s3EventGlacier.json similarity index 100% rename from packages/parser/tests/events/s3EventGlacier.json rename to packages/parser/tests/events/s3/s3EventGlacier.json diff --git a/packages/parser/tests/events/s3ObjectEventIAMUser.json b/packages/parser/tests/events/s3/s3ObjectEventIAMUser.json similarity index 100% rename from packages/parser/tests/events/s3ObjectEventIAMUser.json rename to packages/parser/tests/events/s3/s3ObjectEventIAMUser.json diff --git a/packages/parser/tests/events/s3ObjectEventTempCredentials.json b/packages/parser/tests/events/s3/s3ObjectEventTempCredentials.json similarity index 100% rename from packages/parser/tests/events/s3ObjectEventTempCredentials.json rename to packages/parser/tests/events/s3/s3ObjectEventTempCredentials.json diff --git a/packages/parser/tests/events/s3SqsEvent.json b/packages/parser/tests/events/s3/s3SqsEvent.json similarity index 100% rename from packages/parser/tests/events/s3SqsEvent.json rename to packages/parser/tests/events/s3/s3SqsEvent.json diff --git a/packages/parser/tests/events/secretsManagerEvent.json b/packages/parser/tests/events/secrets-manager/secretsManagerEvent.json similarity index 100% rename from packages/parser/tests/events/secretsManagerEvent.json rename to packages/parser/tests/events/secrets-manager/secretsManagerEvent.json diff --git a/packages/parser/tests/events/sesEvent.json b/packages/parser/tests/events/ses/base.json similarity index 100% rename from packages/parser/tests/events/sesEvent.json rename to packages/parser/tests/events/ses/base.json diff --git a/packages/parser/tests/events/snsEvent.json b/packages/parser/tests/events/sns/base.json similarity index 100% rename from packages/parser/tests/events/snsEvent.json rename to packages/parser/tests/events/sns/base.json diff --git a/packages/parser/tests/events/sqsEvent.json b/packages/parser/tests/events/sqs/base.json similarity index 100% rename from packages/parser/tests/events/sqsEvent.json rename to packages/parser/tests/events/sqs/base.json diff --git a/packages/parser/tests/events/snsSqsFifoEvent.json b/packages/parser/tests/events/sqs/sns-event-fifo.json similarity index 100% rename from packages/parser/tests/events/snsSqsFifoEvent.json rename to packages/parser/tests/events/sqs/sns-event-fifo.json diff --git a/packages/parser/tests/events/snsSqsEvent.json b/packages/parser/tests/events/sqs/sns-event.json similarity index 100% rename from packages/parser/tests/events/snsSqsEvent.json rename to packages/parser/tests/events/sqs/sns-event.json diff --git a/packages/parser/tests/events/vpcLatticeV2Event.json b/packages/parser/tests/events/vpc-lattice/base-v2.json similarity index 100% rename from packages/parser/tests/events/vpcLatticeV2Event.json rename to packages/parser/tests/events/vpc-lattice/base-v2.json diff --git a/packages/parser/tests/events/vpcLatticeEvent.json b/packages/parser/tests/events/vpc-lattice/base.json similarity index 100% rename from packages/parser/tests/events/vpcLatticeEvent.json rename to packages/parser/tests/events/vpc-lattice/base.json diff --git a/packages/parser/tests/events/vpcLatticeEventPathTrailingSlash.json b/packages/parser/tests/events/vpcLatticeEventPathTrailingSlash.json deleted file mode 100644 index 7f6c0cfd9a..0000000000 --- a/packages/parser/tests/events/vpcLatticeEventPathTrailingSlash.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "raw_path": "/testpath/", - "method": "GET", - "headers": { - "user_agent": "curl/7.64.1", - "x-forwarded-for": "10.213.229.10", - "host": "test-lambda-service-3908sdf9u3u.dkfjd93.vpc-lattice-svcs.us-east-2.on.aws", - "accept": "*/*" - }, - "query_string_parameters": { - "order-id": "1" - }, - "body": "eyJ0ZXN0IjogImV2ZW50In0=", - "is_base64_encoded": true -} diff --git a/packages/parser/tests/events/vpcLatticeEventV2PathTrailingSlash.json b/packages/parser/tests/events/vpcLatticeEventV2PathTrailingSlash.json deleted file mode 100644 index 9c0005f99b..0000000000 --- a/packages/parser/tests/events/vpcLatticeEventV2PathTrailingSlash.json +++ /dev/null @@ -1,30 +0,0 @@ -{ - "version": "2.0", - "path": "/newpath/", - "method": "GET", - "headers": { - "user_agent": "curl/7.64.1", - "x-forwarded-for": "10.213.229.10", - "host": "test-lambda-service-3908sdf9u3u.dkfjd93.vpc-lattice-svcs.us-east-2.on.aws", - "accept": "*/*" - }, - "queryStringParameters": { - "order-id": "1" - }, - "body": "{\"message\": \"Hello from Lambda!\"}", - "isBase64Encoded": false, - "requestContext": { - "serviceNetworkArn": "arn:aws:vpc-lattice:us-east-2:123456789012:servicenetwork/sn-0bf3f2882e9cc805a", - "serviceArn": "arn:aws:vpc-lattice:us-east-2:123456789012:service/svc-0a40eebed65f8d69c", - "targetGroupArn": "arn:aws:vpc-lattice:us-east-2:123456789012:targetgroup/tg-6d0ecf831eec9f09", - "identity": { - "sourceVpcArn": "arn:aws:ec2:region:123456789012:vpc/vpc-0b8276c84697e7339", - "type": "AWS_IAM", - "principal": "arn:aws:sts::123456789012:assumed-role/example-role/057d00f8b51257ba3c853a0f248943cf", - "sessionName": "057d00f8b51257ba3c853a0f248943cf", - "x509SanDns": "example.com" - }, - "region": "us-east-2", - "timeEpoch": "1696331543569073" - } -} diff --git a/packages/parser/tests/unit/envelope.test.ts b/packages/parser/tests/unit/envelope.test.ts index 3b314bb6de..188de521c4 100644 --- a/packages/parser/tests/unit/envelope.test.ts +++ b/packages/parser/tests/unit/envelope.test.ts @@ -1,91 +1,133 @@ -/** - * Test decorator parser - * - * @group unit/parser - */ - +import { describe, expect, it } from 'vitest'; import { ZodError, z } from 'zod'; import { Envelope } from '../../src/envelopes/envelope.js'; import { ParseError } from '../../src/errors.js'; -describe('envelope: ', () => { - describe('parseSafe', () => { - it('returns success response when input is object', () => { - const result = Envelope.safeParse( - '{"name": "John"}', - z.object({ name: z.string() }) - ); +describe('Feature: Envelope', () => { + const schema = z.object({ name: z.string() }); + + describe('Method: safeParse', () => { + it('successfully parses a stringified object', () => { + // Prepare + const input = JSON.stringify({ name: 'John' }); + + // Act + const result = Envelope.safeParse(input, schema); + + // Assess expect(result).toEqual({ success: true, data: { name: 'John' }, }); }); - it('returns success response when input is string', () => { - const result = Envelope.safeParse( - { name: 'John' }, - z.object({ name: z.string() }) - ); + + it('successfully parses an object', () => { + // Prepare + const input = { name: 'John' }; + + // Act + const result = Envelope.safeParse(input, schema); + + // Assess expect(result).toEqual({ success: true, data: { name: 'John' }, }); }); + it('returns error when input does not match schema', () => { - const result = Envelope.safeParse( - { name: 123 }, - z.object({ name: z.string() }) - ); + // Prepare + const input = { name: 123 }; + + // Act + const result = Envelope.safeParse(input, schema); + + // Assess expect(result).toEqual({ success: false, error: expect.any(ParseError), - originalEvent: { name: 123 }, + originalEvent: input, }); }); it('returns error when input is invalid JSON string', () => { - const result = Envelope.safeParse( - '{name: "John"}', - z.object({ name: z.string() }) - ); + // Prepare + const input = '{name: "John"}'; // Missing quotes around key + + // Act + const result = Envelope.safeParse(input, schema); + + // Assess expect(result).toEqual({ success: false, error: expect.any(ParseError), - originalEvent: '{name: "John"}', + originalEvent: input, }); }); }); - describe('parse', () => { + describe('Method: parse', () => { it('returns parsed data when input is object', () => { - const result = Envelope.parse( - { name: 'John' }, - z.object({ name: z.string() }) - ); - expect(result).toEqual({ name: 'John' }); + // Prepare + const input = { name: 'John' }; + + // Act + const result = Envelope.parse(input, schema); + + // Assess + expect(result).toEqual(input); }); + it('returns parsed data when input is string', () => { - const result = Envelope.parse( - '{"name": "John"}', - z.object({ name: z.string() }) - ); - expect(result).toEqual({ name: 'John' }); + // Prepare + const data = { name: 'John' }; + const input = JSON.stringify(data); + + // Act + const result = Envelope.parse(input, schema); + + // Assess + expect(result).toEqual(data); }); + it('throw custom error if input is not string or object', () => { - expect(() => Envelope.parse(123, z.object({ name: z.string() }))).toThrow( + // Prepare + const input = 123; + + // Act & Assess + expect(() => Envelope.parse(input, schema)).toThrow( 'Invalid data type for envelope. Expected string or object, got number' ); }); + it('throws error when input does not match schema', () => { - expect(() => - Envelope.parse({ name: 123 }, z.object({ name: z.string() })) - ).toThrow(); + // Prepare + const input = { name: 123 }; + + // Act & Assess + expect(() => Envelope.parse(input, schema)).toThrow(ParseError); }); + it('includes the ZodError as the cause of the ParseError', () => { - try { - Envelope.parse('{"name": "John"}', z.object({ name: z.number() })); - } catch (error) { - expect((error as Error).cause).toBeInstanceOf(ZodError); - } + // Prepare + const input = JSON.stringify({ name: 'John' }); + const schema = z.object({ name: z.number() }); + + // Act & Assess + expect(() => Envelope.parse(input, schema)) + .throws(ParseError) + .property('cause') + .eql( + new ZodError([ + { + code: 'invalid_type', + expected: 'number', + received: 'string', + path: ['name'], + message: 'Expected number, received string', + }, + ]) + ); }); }); }); diff --git a/packages/parser/tests/unit/envelopes/apigw.test.ts b/packages/parser/tests/unit/envelopes/apigw.test.ts index 43ceda3a91..ca742b36a2 100644 --- a/packages/parser/tests/unit/envelopes/apigw.test.ts +++ b/packages/parser/tests/unit/envelopes/apigw.test.ts @@ -1,97 +1,100 @@ -/** - * Test built-in API Gateway REST envelope - * - * @group unit/parser/envelopes/apigw - */ - +import { describe, expect, it } from 'vitest'; +import { z } from 'zod'; import { ApiGatewayEnvelope } from '../../../src/envelopes/index.js'; import { ParseError } from '../../../src/errors.js'; import type { APIGatewayProxyEvent } from '../../../src/types/schema.js'; -import { TestSchema, getTestEvent } from '../schema/utils.js'; +import { getTestEvent } from '../helpers/utils.js'; -describe('API Gateway REST Envelope', () => { +describe('Envelope: API Gateway REST', () => { + const testSchema = z.object({ + name: z.string(), + age: z.number(), + }); + const mockBody = { + name: 'John', + age: 18, + }; + const mockJSONStringifiedBody = JSON.stringify(mockBody); const eventsPath = 'apigw-rest'; - const eventPrototype = getTestEvent({ + const baseEvent = getTestEvent({ eventsPath, filename: 'no-auth', }); describe('Method: parse', () => { - it('should throw if the payload does not match the schema', () => { + it('throws if the payload does not match the schema', () => { // Prepare - const event = { ...eventPrototype }; + const event = structuredClone(baseEvent); event.body = JSON.stringify({ name: 'foo' }); // Act & Assess - expect(() => ApiGatewayEnvelope.parse(event, TestSchema)).toThrow( + expect(() => ApiGatewayEnvelope.parse(event, testSchema)).toThrow( ParseError ); }); - it('should throw if the body is null', () => { + it('throws if the body is null', () => { // Prepare - const event = { ...eventPrototype }; + const event = structuredClone(baseEvent); event.body = null; // Act & Assess - expect(() => ApiGatewayEnvelope.parse(event, TestSchema)).toThrow( + expect(() => ApiGatewayEnvelope.parse(event, z.string())).toThrow( ParseError ); }); - it('should parse and return the inner schema in an envelope', () => { + it('parses an API Gateway event', () => { // Prepare - const event = { ...eventPrototype }; - const payload = { name: 'foo', age: 42 }; - event.body = JSON.stringify(payload); + const event = structuredClone(baseEvent); + event.body = mockJSONStringifiedBody; // Act - const parsedEvent = ApiGatewayEnvelope.parse(event, TestSchema); + const parsedEvent = ApiGatewayEnvelope.parse(event, testSchema); // Assess - expect(parsedEvent).toEqual(payload); + expect(parsedEvent).toEqual(mockBody); }); }); describe('Method: safeParse', () => { - it('should not throw if the payload does not match the schema', () => { + it('parses a SQS event', () => { // Prepare - const event = { ...eventPrototype }; - event.body = JSON.stringify({ name: 'foo' }); + const event = structuredClone(baseEvent); + event.body = mockJSONStringifiedBody; // Act - const parseResult = ApiGatewayEnvelope.safeParse(event, TestSchema); + const result = ApiGatewayEnvelope.safeParse(event, testSchema); // Assess - expect(parseResult).toEqual({ - success: false, - error: expect.any(ParseError), - originalEvent: event, + expect(result).toEqual({ + success: true, + data: mockBody, }); }); - it('should not throw if the body is null', () => { + it('returns error if event is not a SQS event', () => { // Prepare - const event = { ...eventPrototype }; - event.body = null; + const event = { foo: 'bar' }; // Act - const parseResult = ApiGatewayEnvelope.safeParse(event, TestSchema); + const result = ApiGatewayEnvelope.safeParse(event, testSchema); // Assess - expect(parseResult).toEqual({ + expect(result).toEqual({ success: false, error: expect.any(ParseError), originalEvent: event, }); }); - it('should not throw if the event is invalid', () => { + it('returns error if body does not match schema', () => { // Prepare - const event = getTestEvent({ eventsPath, filename: 'invalid' }); + const event = structuredClone(baseEvent); + event.body = JSON.stringify({ name: 'foo' }); // Act - const parseResult = ApiGatewayEnvelope.safeParse(event, TestSchema); + const parseResult = ApiGatewayEnvelope.safeParse(event, testSchema); // Assess expect(parseResult).toEqual({ @@ -100,21 +103,5 @@ describe('API Gateway REST Envelope', () => { originalEvent: event, }); }); - - it('should parse and return the inner schema in an envelope', () => { - // Prepare - const event = { ...eventPrototype }; - const payload = { name: 'foo', age: 42 }; - event.body = JSON.stringify(payload); - - // Act - const parsedEvent = ApiGatewayEnvelope.safeParse(event, TestSchema); - - // Assess - expect(parsedEvent).toEqual({ - success: true, - data: payload, - }); - }); }); }); diff --git a/packages/parser/tests/unit/envelopes/apigwv2.test.ts b/packages/parser/tests/unit/envelopes/apigwv2.test.ts index 0d4907380b..70390ae5ad 100644 --- a/packages/parser/tests/unit/envelopes/apigwv2.test.ts +++ b/packages/parser/tests/unit/envelopes/apigwv2.test.ts @@ -1,82 +1,70 @@ -/** - * Test built-in API Gateway HTTP API (v2) envelope - * - * @group unit/parser/envelopes/apigwv2 - */ - +import { describe, expect, it } from 'vitest'; +import { z } from 'zod'; import { ApiGatewayV2Envelope } from '../../../src/envelopes/index.js'; import { ParseError } from '../../../src/errors.js'; import type { APIGatewayProxyEventV2 } from '../../../src/types/schema.js'; -import { TestSchema, getTestEvent } from '../schema/utils.js'; +import { getTestEvent } from '../helpers/utils.js'; -describe('API Gateway HTTP Envelope', () => { +describe('Envelope: API Gateway HTTP (v2)', () => { + const testSchema = z.object({ + name: z.string(), + age: z.number(), + }); + const mockBody = { + name: 'John', + age: 18, + }; + const mockJSONStringifiedBody = JSON.stringify(mockBody); const eventsPath = 'apigw-http'; - const eventPrototype = getTestEvent({ + const baseEvent = getTestEvent({ eventsPath, filename: 'no-auth', }); describe('Method: parse', () => { - it('should throw if the payload does not match the schema', () => { + it('throws if the payload does not match the schema', () => { // Prepare - const event = { ...eventPrototype }; + const event = structuredClone(baseEvent); event.body = JSON.stringify({ name: 'foo' }); // Act & Assess - expect(() => ApiGatewayV2Envelope.parse(event, TestSchema)).toThrow( + expect(() => ApiGatewayV2Envelope.parse(event, testSchema)).toThrow( ParseError ); }); it('should throw if the body is undefined', () => { // Prepare - const event = { ...eventPrototype }; + const event = structuredClone(baseEvent); event.body = undefined; // Act & Assess - expect(() => ApiGatewayV2Envelope.parse(event, TestSchema)).toThrow( + expect(() => ApiGatewayV2Envelope.parse(event, testSchema)).toThrow( ParseError ); }); it('should parse and return the inner schema in an envelope', () => { // Prepare - const event = { ...eventPrototype }; - const payload = { name: 'foo', age: 42 }; - event.body = JSON.stringify(payload); + const event = structuredClone(baseEvent); + event.body = mockJSONStringifiedBody; // Act - const parsedEvent = ApiGatewayV2Envelope.parse(event, TestSchema); + const parsedEvent = ApiGatewayV2Envelope.parse(event, testSchema); // Assess - expect(parsedEvent).toEqual(payload); + expect(parsedEvent).toEqual(mockBody); }); }); describe('Method: safeParse', () => { it('should not throw if the payload does not match the schema', () => { // Prepare - const event = { ...eventPrototype }; + const event = structuredClone(baseEvent); event.body = JSON.stringify({ name: 'foo' }); // Act - const parseResult = ApiGatewayV2Envelope.safeParse(event, TestSchema); - - // Assess - expect(parseResult).toEqual({ - success: false, - error: expect.any(ParseError), - originalEvent: event, - }); - }); - - it('should not throw if the body is undefined', () => { - // Prepare - const event = { ...eventPrototype }; - event.body = undefined; - - // Act - const parseResult = ApiGatewayV2Envelope.safeParse(event, TestSchema); + const parseResult = ApiGatewayV2Envelope.safeParse(event, testSchema); // Assess expect(parseResult).toEqual({ @@ -88,10 +76,10 @@ describe('API Gateway HTTP Envelope', () => { it('should not throw if the event is invalid', () => { // Prepare - const event = getTestEvent({ eventsPath, filename: 'invalid' }); + const event = { foo: 'bar' }; // Act - const parseResult = ApiGatewayV2Envelope.safeParse(event, TestSchema); + const parseResult = ApiGatewayV2Envelope.safeParse(event, testSchema); // Assess expect(parseResult).toEqual({ @@ -103,17 +91,16 @@ describe('API Gateway HTTP Envelope', () => { it('should parse and return the inner schema in an envelope', () => { // Prepare - const event = { ...eventPrototype }; - const payload = { name: 'foo', age: 42 }; - event.body = JSON.stringify(payload); + const event = structuredClone(baseEvent); + event.body = mockJSONStringifiedBody; // Act - const parsedEvent = ApiGatewayV2Envelope.safeParse(event, TestSchema); + const parsedEvent = ApiGatewayV2Envelope.safeParse(event, testSchema); // Assess expect(parsedEvent).toEqual({ success: true, - data: payload, + data: mockBody, }); }); }); diff --git a/packages/parser/tests/unit/envelopes/cloudwatch.test.ts b/packages/parser/tests/unit/envelopes/cloudwatch.test.ts index bc562ef13f..8402483457 100644 --- a/packages/parser/tests/unit/envelopes/cloudwatch.test.ts +++ b/packages/parser/tests/unit/envelopes/cloudwatch.test.ts @@ -1,45 +1,55 @@ -/** - * Test built in schema envelopes for CloudWatch - * - * @group unit/parser/envelopes - */ - import { gzipSync } from 'node:zlib'; -import { generateMock } from '@anatine/zod-mock'; -import { ParseError } from '../../../src'; -import { CloudWatchEnvelope } from '../../../src/envelopes/index.js'; +import { describe, expect, it } from 'vitest'; +import { z } from 'zod'; +import { CloudWatchEnvelope } from '../../../src/envelopes'; +import { ParseError } from '../../../src/errors.js'; import { CloudWatchLogEventSchema, CloudWatchLogsDecodeSchema, } from '../../../src/schemas/'; -import { TestSchema } from '../schema/utils.js'; - -describe('CloudWatch', () => { - describe('parse', () => { - it('should parse custom schema in envelope', () => { - const testEvent = { - awslogs: { - data: '', - }, - }; - - const data = generateMock(TestSchema); - const eventMock = generateMock(CloudWatchLogEventSchema, { - stringMap: { - message: () => JSON.stringify(data), - }, - }); +import type { CloudWatchLogsEvent } from '../../../src/types/index.js'; +import { getTestEvent } from '../helpers/utils.js'; - const logMock = generateMock(CloudWatchLogsDecodeSchema); - logMock.logEvents = [eventMock]; - - testEvent.awslogs.data = gzipSync( - Buffer.from(JSON.stringify(logMock), 'utf8') - ).toString('base64'); - - expect(CloudWatchEnvelope.parse(testEvent, TestSchema)).toEqual([data]); +describe('Envelope: CloudWatchEnvelope', () => { + const baseEvent = getTestEvent({ + eventsPath: 'cloudwatch', + filename: 'base', + }); + const expectedData = [ + { + id: 'eventId1', + message: '[ERROR] First test message', + timestamp: 1440442987000, + }, + { + id: 'eventId2', + message: '[ERROR] Second test message', + timestamp: 1440442987001, + }, + ]; + + describe('Method: parse', () => { + it.fails('parses a CloudWatch logs event', () => { + // Prepare + const event = structuredClone(baseEvent); + + // Act + const parsedEvent = CloudWatchEnvelope.parse( + event, + // z.record(z.unknown()) + z.string() + ); + + // Assess + expect(parsedEvent).toEqual([ + expectedData[0].message, + expectedData[1].message, + ]); }); + it(''); + /* + it('should throw when schema does not match', () => { const testEvent = { awslogs: { @@ -61,10 +71,10 @@ describe('CloudWatch', () => { ).toString('base64'); expect(() => CloudWatchEnvelope.parse(testEvent, TestSchema)).toThrow(); - }); + }); */ }); - describe('safeParse', () => { + /* describe('safeParse', () => { it('should parse custom schema in envelope', () => { const testEvent = { awslogs: { @@ -127,5 +137,5 @@ describe('CloudWatch', () => { originalEvent: { foo: 'bar' }, }); }); - }); + }); */ }); diff --git a/packages/parser/tests/unit/envelopes/dynamodb.test.ts b/packages/parser/tests/unit/envelopes/dynamodb.ts similarity index 76% rename from packages/parser/tests/unit/envelopes/dynamodb.test.ts rename to packages/parser/tests/unit/envelopes/dynamodb.ts index df3720ae69..b7f2c10026 100644 --- a/packages/parser/tests/unit/envelopes/dynamodb.test.ts +++ b/packages/parser/tests/unit/envelopes/dynamodb.ts @@ -1,37 +1,36 @@ -/** - * Test built in schema envelopes for api gateway v2 - * - * @group unit/parser/envelopes - */ - -import { generateMock } from '@anatine/zod-mock'; -import type { AttributeValue, DynamoDBStreamEvent } from 'aws-lambda'; +import { marshall } from '@aws-sdk/util-dynamodb'; +import type { AttributeValue } from 'aws-lambda'; +import { describe, expect, it } from 'vitest'; import { z } from 'zod'; import { DynamoDBStreamEnvelope } from '../../../src/envelopes/index.js'; import { ParseError } from '../../../src/errors.js'; -import { TestEvents } from '../schema/utils.js'; +import type { DynamoDBStreamEvent } from '../../../src/types/schema.js'; +import { getTestEvent } from '../helpers/utils.js'; describe('DynamoDB', () => { - const schema = z.object({ - Message: z.record(z.literal('S'), z.string()), - Id: z.record(z.literal('N'), z.number().min(0).max(100)), + const testSchema = z.object({ + name: z.string(), + age: z.number(), + }); + const mockOldImage = { + name: 'John', + age: 18, + }; + const mockNewImage = { + name: 'Jane', + age: 21, + }; + const baseEvent = getTestEvent({ + eventsPath: 'dynamodb', + filename: 'base', }); - const mockOldImage = generateMock(schema); - const mockNewImage = generateMock(schema); - const dynamodbEvent = TestEvents.dynamoStreamEvent as DynamoDBStreamEvent; - // biome-ignore lint/style/noNonNullAssertion: it is ensured that this event has these properties - (dynamodbEvent.Records[0].dynamodb!.NewImage as typeof mockNewImage) = - mockNewImage; - // biome-ignore lint/style/noNonNullAssertion: it is ensured that this event has these properties - (dynamodbEvent.Records[1].dynamodb!.NewImage as typeof mockNewImage) = - mockNewImage; - // biome-ignore lint/style/noNonNullAssertion: it is ensured that this event has these properties - (dynamodbEvent.Records[0].dynamodb!.OldImage as typeof mockOldImage) = - mockOldImage; - // biome-ignore lint/style/noNonNullAssertion: it is ensured that this event has these properties - (dynamodbEvent.Records[1].dynamodb!.OldImage as typeof mockOldImage) = - mockOldImage; - describe('parse', () => { + baseEvent.Records[0].dynamodb.OldImage = mockOldImage; + baseEvent.Records[1].dynamodb.OldImage = mockOldImage; + baseEvent.Records[0].dynamodb.NewImage = mockNewImage; + baseEvent.Records[1].dynamodb.NewImage = mockNewImage; + + describe('Method: parse', () => { + it('parses a DynamoDB Stream event', () => {}); it('parse should parse dynamodb envelope', () => { const parsed = DynamoDBStreamEnvelope.parse(dynamodbEvent, schema); expect(parsed[0]).toEqual({ diff --git a/packages/parser/tests/unit/envelopes/eventbridge.test.ts b/packages/parser/tests/unit/envelopes/eventbridge.ts similarity index 93% rename from packages/parser/tests/unit/envelopes/eventbridge.test.ts rename to packages/parser/tests/unit/envelopes/eventbridge.ts index d713273544..b6c83e49be 100644 --- a/packages/parser/tests/unit/envelopes/eventbridge.test.ts +++ b/packages/parser/tests/unit/envelopes/eventbridge.ts @@ -1,14 +1,8 @@ -/** - * Test built in schema envelopes for event bridge - * - * @group unit/parser/envelopes - */ - -import { generateMock } from '@anatine/zod-mock'; import type { EventBridgeEvent } from 'aws-lambda'; +import { describe, expect, it } from 'vitest'; import { EventBridgeEnvelope } from '../../../src/envelopes/index.js'; import { ParseError } from '../../../src/errors.js'; -import { TestEvents, TestSchema } from '../schema/utils.js'; +import { getTestEvent } from '../helpers/utils.js'; describe('EventBridgeEnvelope ', () => { describe('parse', () => { diff --git a/packages/parser/tests/unit/envelopes/kafka.test.ts b/packages/parser/tests/unit/envelopes/kafka.ts similarity index 77% rename from packages/parser/tests/unit/envelopes/kafka.test.ts rename to packages/parser/tests/unit/envelopes/kafka.ts index e47712b911..98c3a9e231 100644 --- a/packages/parser/tests/unit/envelopes/kafka.test.ts +++ b/packages/parser/tests/unit/envelopes/kafka.ts @@ -1,17 +1,26 @@ -/** - * Test built in schema envelopes for api gateway v2 - * - * @group unit/parser/envelopes - */ - -import { generateMock } from '@anatine/zod-mock'; -import type { MSKEvent, SelfManagedKafkaEvent } from 'aws-lambda'; +import { describe, expect, it } from 'vitest'; +import { z } from 'zod'; import { KafkaEnvelope } from '../../../src/envelopes/index.js'; -import { TestEvents, TestSchema } from '../schema/utils.js'; - -describe('Kafka', () => { - describe('parse', () => { - it('should parse MSK kafka envelope', () => { +import { ParseError } from '../../../src/errors.js'; +import type { + KafkaMskEvent, + KafkaSelfManagedEvent, +} from '../../../src/types/index.js'; +import { getTestEvent } from '../helpers/utils.js'; + +describe('Envelope: Kafka', () => { + const testSchema = z.object({ + name: z.string(), + age: z.number(), + }); + const mockBody = { + name: 'John', + age: 18, + }; + const mockJSONStringifiedBody = JSON.stringify(mockBody); + + describe('Method: parse', () => { + /* it('should parse MSK kafka envelope', () => { const mock = generateMock(TestSchema); const kafkaEvent = TestEvents.kafkaEventMsk as MSKEvent; @@ -22,9 +31,8 @@ describe('Kafka', () => { const result = KafkaEnvelope.parse(kafkaEvent, TestSchema); expect(result).toEqual([[mock]]); - }); - - it('should parse Self Managed kafka envelope', () => { + }); */ + /* it('should parse Self Managed kafka envelope', () => { const mock = generateMock(TestSchema); const kafkaEvent = @@ -36,9 +44,8 @@ describe('Kafka', () => { const result = KafkaEnvelope.parse(kafkaEvent, TestSchema); expect(result).toEqual([[mock]]); - }); - - describe('safeParse', () => { + }); */ + /* describe('safeParse', () => { it('should parse MSK kafka envelope', () => { const mock = generateMock(TestSchema); @@ -91,6 +98,6 @@ describe('Kafka', () => { originalEvent: { foo: 'bar' }, }); }); - }); + }); */ }); }); diff --git a/packages/parser/tests/unit/envelopes/kinesis-firehose.test.ts b/packages/parser/tests/unit/envelopes/kinesis-firehose.ts similarity index 96% rename from packages/parser/tests/unit/envelopes/kinesis-firehose.test.ts rename to packages/parser/tests/unit/envelopes/kinesis-firehose.ts index 0137fa92e5..befeec6448 100644 --- a/packages/parser/tests/unit/envelopes/kinesis-firehose.test.ts +++ b/packages/parser/tests/unit/envelopes/kinesis-firehose.ts @@ -1,14 +1,8 @@ -/** - * Test built in schema envelopes for Kinesis Firehose - * - * @group unit/parser/envelopes - */ - -import { generateMock } from '@anatine/zod-mock'; +import { describe, expect, it } from 'vitest'; import type { z } from 'zod'; import { KinesisFirehoseEnvelope } from '../../../src/envelopes/index.js'; import type { KinesisFirehoseSchema } from '../../../src/schemas/'; -import { TestEvents, TestSchema } from '../schema/utils.js'; +import { getTestEvent } from '../helpers/utils.js'; describe('Kinesis Firehose Envelope', () => { describe('parse', () => { diff --git a/packages/parser/tests/unit/envelopes/kinesis.test.ts b/packages/parser/tests/unit/envelopes/kinesis.ts similarity index 90% rename from packages/parser/tests/unit/envelopes/kinesis.test.ts rename to packages/parser/tests/unit/envelopes/kinesis.ts index e84e74f528..505733fc8a 100644 --- a/packages/parser/tests/unit/envelopes/kinesis.test.ts +++ b/packages/parser/tests/unit/envelopes/kinesis.ts @@ -1,16 +1,10 @@ -/** - * Test built in schema envelopes for Kinesis - * - * @group unit/parser/envelopes - */ - -import { generateMock } from '@anatine/zod-mock'; import type { KinesisStreamEvent } from 'aws-lambda'; +import { describe, expect, it } from 'vitest'; import { KinesisEnvelope } from '../../../src/envelopes/index.js'; import { ParseError } from '../../../src/errors.js'; -import { TestEvents, TestSchema } from '../schema/utils.js'; +import { getTestEvent } from '../helpers/utils.js'; -describe('KinesisEnvelope', () => { +describe('Envelope: KinesisEnvelope', () => { describe('parse', () => { it('should parse Kinesis Stream event', () => { const mock = generateMock(TestSchema); diff --git a/packages/parser/tests/unit/envelopes/lambda.test.ts b/packages/parser/tests/unit/envelopes/lambda.test.ts index e9d0301969..04ab9dd489 100644 --- a/packages/parser/tests/unit/envelopes/lambda.test.ts +++ b/packages/parser/tests/unit/envelopes/lambda.test.ts @@ -1,91 +1,118 @@ -/** - * Test built in schema envelopes for Lambda Functions URL - * - * @group unit/parser/envelopes - */ - -import { generateMock } from '@anatine/zod-mock'; -import type { APIGatewayProxyEventV2 } from 'aws-lambda'; +import { describe, expect, it } from 'vitest'; +import { z } from 'zod'; import { LambdaFunctionUrlEnvelope } from '../../../src/envelopes/index.js'; -import { TestEvents, TestSchema } from '../schema/utils.js'; +import { ParseError } from '../../../src/errors.js'; +import type { LambdaFunctionUrlEvent } from '../../../src/types/index.js'; +import { getTestEvent } from '../helpers/utils.js'; -describe('Lambda Functions Url ', () => { - describe('parse', () => { - it('should parse custom schema in envelope', () => { - const testEvent = - TestEvents.lambdaFunctionUrlEvent as APIGatewayProxyEventV2; - const data = generateMock(TestSchema); +describe('Envelope: Lambda Functions Url ', () => { + const baseEvent = getTestEvent({ + eventsPath: 'lambda', + filename: 'with-body', + }); + + describe('Method: parse', () => { + it.fails('parses a Lambda FUrl event', () => { + // Prepare + const event = structuredClone(baseEvent); + + // Act + const parsedBody = LambdaFunctionUrlEnvelope.parse(event, z.string()); + + // Assess + expect(parsedBody).toEqual(event.body); + }); - testEvent.body = JSON.stringify(data); + it('parses a JSON body within a Lambda FUrl event', () => { + // Prepare + const event = structuredClone(baseEvent); + event.body = JSON.stringify({ name: 'John' }); - expect(LambdaFunctionUrlEnvelope.parse(testEvent, TestSchema)).toEqual( - data + // Act + const parsedBody = LambdaFunctionUrlEnvelope.parse( + event, + z.object({ name: z.string() }) ); + + // Assess + expect(parsedBody).toEqual({ name: 'John' }); }); - it('should throw when no body provided', () => { - const testEvent = - TestEvents.apiGatewayProxyV2Event as APIGatewayProxyEventV2; - testEvent.body = undefined; + it.fails('parses a binary body within a Lambda FUrl event', () => { + // Prepare + const event = structuredClone(baseEvent); + event.body = 'SGVsbG8gV29ybGQ='; // encoded 'Hello World' + event.isBase64Encoded = true; - expect(() => - LambdaFunctionUrlEnvelope.parse(testEvent, TestSchema) - ).toThrow(); + // Act + const parsedBody = LambdaFunctionUrlEnvelope.parse(event, z.string()); + + // Assess + expect(parsedBody).toEqual('Hello World'); }); - it('should throw when envelope is not valid', () => { - expect(() => - LambdaFunctionUrlEnvelope.parse({ foo: 'bar' }, TestSchema) - ).toThrow(); + it('throws if event is not a Lambda FUrl event', () => { + // Prepare + const event = { foo: 'bar' }; + + // Act & Assess + expect(() => LambdaFunctionUrlEnvelope.parse(event, z.any())).toThrow(); }); - it('should throw when body does not match schema', () => { - const testEvent = - TestEvents.lambdaFunctionUrlEvent as APIGatewayProxyEventV2; - testEvent.body = JSON.stringify({ foo: 'bar' }); + it('throws if body does not match schema', () => { + // Prepare + const event = structuredClone(baseEvent); + event.body = JSON.stringify({ foo: 'bar' }); + // Act & Assess expect(() => - LambdaFunctionUrlEnvelope.parse(testEvent, TestSchema) + LambdaFunctionUrlEnvelope.parse(event, z.object({ name: z.string() })) ).toThrow(); }); }); - describe('safeParse', () => { - it('should parse custom schema in envelope', () => { - const testEvent = - TestEvents.lambdaFunctionUrlEvent as APIGatewayProxyEventV2; - const data = generateMock(TestSchema); - testEvent.body = JSON.stringify(data); + describe('Method: safeParse', () => { + it.fails('parses a Lambda FUrl event', () => { + // Prepare + const event = structuredClone(baseEvent); - expect( - LambdaFunctionUrlEnvelope.safeParse(testEvent, TestSchema) - ).toEqual({ + // Act + const result = LambdaFunctionUrlEnvelope.safeParse(event, z.string()); + + // Assess + expect(result).toEqual({ success: true, - data, + data: event.body, }); }); - it('should return original event when envelope is not valid', () => { - expect( - LambdaFunctionUrlEnvelope.safeParse({ foo: 'bar' }, TestSchema) - ).toEqual({ + it('returns error if event is not a Lambda FUrl event', () => { + // Prepare + const event = { foo: 'bar' }; + + // Act + const result = LambdaFunctionUrlEnvelope.safeParse(event, z.any()); + + // Assess + expect(result).toEqual({ success: false, - error: expect.any(Error), - originalEvent: { foo: 'bar' }, + error: expect.any(ParseError), + originalEvent: event, }); }); - it('should return original event when body does not match schema', () => { - const testEvent = - TestEvents.lambdaFunctionUrlEvent as APIGatewayProxyEventV2; - testEvent.body = JSON.stringify({ foo: 'bar' }); + it('returns error if body does not match schema', () => { + // Prepare + const event = structuredClone(baseEvent); + + // Act + const result = LambdaFunctionUrlEnvelope.safeParse(event, z.number()); - expect( - LambdaFunctionUrlEnvelope.safeParse(testEvent, TestSchema) - ).toEqual({ + // Assess + expect(result).toEqual({ success: false, - error: expect.any(Error), - originalEvent: testEvent, + error: expect.any(ParseError), + originalEvent: event, }); }); }); diff --git a/packages/parser/tests/unit/envelopes/sns.test.ts b/packages/parser/tests/unit/envelopes/sns.ts similarity index 96% rename from packages/parser/tests/unit/envelopes/sns.test.ts rename to packages/parser/tests/unit/envelopes/sns.ts index 0e26511238..0975fdcc17 100644 --- a/packages/parser/tests/unit/envelopes/sns.test.ts +++ b/packages/parser/tests/unit/envelopes/sns.ts @@ -1,15 +1,9 @@ -/** - * Test built in schema envelopes for SNS - * - * @group unit/parser/envelopes - */ - -import { generateMock } from '@anatine/zod-mock'; import type { SNSEvent, SQSEvent } from 'aws-lambda'; +import { describe, expect, it } from 'vitest'; import type { z } from 'zod'; import { SnsEnvelope, SnsSqsEnvelope } from '../../../src/envelopes/index.js'; import { ParseError } from '../../../src/errors.js'; -import { TestEvents, TestSchema } from '../schema/utils.js'; +import { getTestEvent } from '../helpers/utils.js'; describe('Sns and SQS Envelope', () => { describe('SnsSqsEnvelope parse', () => { diff --git a/packages/parser/tests/unit/envelopes/sqs.test.ts b/packages/parser/tests/unit/envelopes/sqs.test.ts index 4979bccfcf..4cf2304f10 100644 --- a/packages/parser/tests/unit/envelopes/sqs.test.ts +++ b/packages/parser/tests/unit/envelopes/sqs.test.ts @@ -1,69 +1,104 @@ -/** - * Test built in schema envelopes for sqs - * - * @group unit/parser/envelopes - */ - -import { generateMock } from '@anatine/zod-mock'; -import type { SQSEvent } from 'aws-lambda'; +import { describe, expect, it } from 'vitest'; +import { z } from 'zod'; import { SqsEnvelope } from '../../../src/envelopes/sqs.js'; import { ParseError } from '../../../src/errors.js'; -import { TestEvents, TestSchema } from '../schema/utils.js'; +import type { SqsEvent } from '../../../src/types/index.js'; +import { getTestEvent } from '../helpers/utils.js'; -describe('SqsEnvelope ', () => { - describe('parse', () => { - it('should parse custom schema in envelope', () => { - const mock = generateMock(TestSchema); +describe('Envelope: SqsEnvelope ', () => { + const testSchema = z.object({ + name: z.string(), + age: z.number(), + }); + const mockBody = { + name: 'John', + age: 18, + }; + const mockJSONStringifiedBody = JSON.stringify(mockBody); + const baseEvent = getTestEvent({ + eventsPath: 'sqs', + filename: 'base', + }); + + describe('Method: parse', () => { + it('parses a SQS event', () => { + // Prepare + const event = structuredClone(baseEvent); + event.Records[0].body = mockJSONStringifiedBody; + event.Records[1].body = mockJSONStringifiedBody; - const sqsEvent = TestEvents.sqsEvent as SQSEvent; - sqsEvent.Records[0].body = JSON.stringify(mock); - sqsEvent.Records[1].body = JSON.stringify(mock); + // Act + const parsedBody = SqsEnvelope.parse(event, testSchema); - const resp = SqsEnvelope.parse(sqsEvent, TestSchema); - expect(resp).toEqual([mock, mock]); + // Assess + expect(parsedBody).toEqual([mockBody, mockBody]); }); - it('should throw error if invalid keys for a schema', () => { - expect(() => { - SqsEnvelope.parse({ Records: [{ foo: 'bar' }] }, TestSchema); - }).toThrow(); + it('throws if event is not a SQS event', () => { + // Prepare + const event = { foo: 'bar' }; + + // Act & Assess + expect(() => SqsEnvelope.parse(event, testSchema)).toThrow(); }); - it('should throw if invalid envelope', () => { - expect(() => { - SqsEnvelope.parse({ foo: 'bar' }, TestSchema); - }).toThrow(); + it('throws if body does not match schema', () => { + // Prepare + const event = structuredClone(baseEvent); + event.Records[0].body = JSON.stringify({ foo: 'bar' }); + event.Records[1].body = mockJSONStringifiedBody; + + // Act & Assess + expect(() => SqsEnvelope.parse(event, testSchema)).toThrow(); }); }); - describe('safeParse', () => { - it('should parse custom schema in envelope', () => { - const mock = generateMock(TestSchema); - const sqsEvent = TestEvents.sqsEvent as SQSEvent; - sqsEvent.Records[0].body = JSON.stringify(mock); - sqsEvent.Records[1].body = JSON.stringify(mock); + describe('Method: safeParse', () => { + it('parses a SQS event', () => { + // Prepare + const event = structuredClone(baseEvent); + event.Records[0].body = mockJSONStringifiedBody; + event.Records[1].body = mockJSONStringifiedBody; - expect(SqsEnvelope.safeParse(sqsEvent, TestSchema)).toEqual({ + // Act + const result = SqsEnvelope.safeParse(event, testSchema); + + // Assess + expect(result).toEqual({ success: true, - data: [mock, mock], + data: [mockBody, mockBody], }); }); - it('should return error if event does not match schema', () => { - const sqsEvent = TestEvents.sqsEvent as SQSEvent; - sqsEvent.Records[0].body = JSON.stringify({ foo: 'bar' }); - expect(SqsEnvelope.safeParse(sqsEvent, TestSchema)).toEqual({ + it('returns error if event is not a SQS event', () => { + // Prepare + const event = { foo: 'bar' }; + + // Act + const result = SqsEnvelope.safeParse(event, testSchema); + + // Assess + expect(result).toEqual({ success: false, error: expect.any(ParseError), - originalEvent: sqsEvent, + originalEvent: event, }); }); - it('should return error if envelope is invalid', () => { - expect(SqsEnvelope.safeParse({ foo: 'bar' }, TestSchema)).toEqual({ + it('returns error if body does not match schema', () => { + // Prepare + const event = structuredClone(baseEvent); + event.Records[0].body = JSON.stringify({ foo: 'bar' }); + event.Records[1].body = mockJSONStringifiedBody; + + // Act + const result = SqsEnvelope.safeParse(event, testSchema); + + // Assess + expect(result).toEqual({ success: false, error: expect.any(ParseError), - originalEvent: { foo: 'bar' }, + originalEvent: event, }); }); }); diff --git a/packages/parser/tests/unit/envelopes/vpc-lattice.test.ts b/packages/parser/tests/unit/envelopes/vpc-lattice.test.ts index a3eec5be00..994b3bc3ed 100644 --- a/packages/parser/tests/unit/envelopes/vpc-lattice.test.ts +++ b/packages/parser/tests/unit/envelopes/vpc-lattice.test.ts @@ -1,96 +1,109 @@ -/** - * Test built in schema envelopes for VPC Lattice - * - * @group unit/parser/envelopes - */ - -import { generateMock } from '@anatine/zod-mock'; -import { VpcLatticeEnvelope } from '../../../src/envelopes/index.js'; +import { describe, expect, it } from 'vitest'; +import { z } from 'zod'; +import { VpcLatticeEnvelope } from '../../../src/envelopes/vpc-lattice.js'; +import { ParseError } from '../../../src/errors.js'; import type { VpcLatticeEvent } from '../../../src/types/index.js'; -import { TestEvents, TestSchema } from '../schema/utils.js'; +import { getTestEvent } from '../helpers/utils.js'; -describe('VpcLatticeEnvelope', () => { - describe('parse', () => { - it('should parse VPC Lattice event', () => { - const mock = generateMock(TestSchema); - const testEvent = TestEvents.vpcLatticeEvent as VpcLatticeEvent; +describe('Envelope: VpcLatticeEnvelope', () => { + const testSchema = z.object({ + name: z.string(), + age: z.number(), + }); + const mockBody = { + name: 'John', + age: 18, + }; + const mockJSONStringifiedBody = JSON.stringify(mockBody); + const baseEvent = getTestEvent({ + eventsPath: 'vpc-lattice', + filename: 'base', + }); - testEvent.body = JSON.stringify(mock); + describe('Method: parse', () => { + it('parses a VPC Lattice event', () => { + // Prepare + const event = structuredClone(baseEvent); + event.body = mockJSONStringifiedBody; + event.is_base64_encoded = false; - const resp = VpcLatticeEnvelope.parse(testEvent, TestSchema); + // Act + const parsedBody = VpcLatticeEnvelope.parse(event, testSchema); - expect(resp).toEqual(mock); + // Assess + expect(parsedBody).toEqual(mockBody); }); - it('should parse VPC Lattice event with trailing slash', () => { - const mock = generateMock(TestSchema); - const testEvent = - TestEvents.vpcLatticeEventPathTrailingSlash as VpcLatticeEvent; - - testEvent.body = JSON.stringify(mock); + it('throws when the body is base64 encoded', () => { + // Prepare + const event = structuredClone(baseEvent); - const resp = VpcLatticeEnvelope.parse(testEvent, TestSchema); - expect(resp).toEqual(mock); + // Act & Assess + expect(() => VpcLatticeEnvelope.parse(event, testSchema)).toThrow(); }); - it('should throw if event is not a VPC Lattice event', () => { - expect(() => - VpcLatticeEnvelope.parse({ foo: 'bar' }, TestSchema) - ).toThrow(); - }); + it('throws if event is not a VPC Lattice event', () => { + // Prepare + const event = { foo: 'bar' }; - it('should throw if body does not match schema', () => { - const testEvent = TestEvents.vpcLatticeEvent as VpcLatticeEvent; + // Act & Assess + expect(() => VpcLatticeEnvelope.parse(event, testSchema)).toThrow(); + }); - testEvent.body = JSON.stringify({ foo: 'bar' }); + it('throws if body does not match schema', () => { + // Prepare + const event = structuredClone(baseEvent); + event.body = JSON.stringify({ foo: 'bar' }); + event.is_base64_encoded = false; - expect(() => VpcLatticeEnvelope.parse(testEvent, TestSchema)).toThrow(); + // Act & Assess + expect(() => VpcLatticeEnvelope.parse(event, testSchema)).toThrow(); }); }); - describe('safeParse', () => { - it('should parse VPC Lattice event', () => { - const mock = generateMock(TestSchema); - const testEvent = TestEvents.vpcLatticeEvent as VpcLatticeEvent; + describe('Method: safeParse', () => { + it('parses a VPC Lattice event', () => { + // Prepare + const event = structuredClone(baseEvent); + event.body = mockJSONStringifiedBody; + event.is_base64_encoded = false; - testEvent.body = JSON.stringify(mock); + // Act + const result = VpcLatticeEnvelope.safeParse(event, testSchema); - const resp = VpcLatticeEnvelope.safeParse(testEvent, TestSchema); - - expect(resp).toEqual({ success: true, data: mock }); + // Assess + expect(result).toEqual({ success: true, data: mockBody }); }); - it('should parse VPC Lattice event with trailing slash', () => { - const mock = generateMock(TestSchema); - const testEvent = - TestEvents.vpcLatticeEventPathTrailingSlash as VpcLatticeEvent; - - testEvent.body = JSON.stringify(mock); - - const resp = VpcLatticeEnvelope.safeParse(testEvent, TestSchema); - expect(resp).toEqual({ success: true, data: mock }); - }); + it('returns error if event is not a VPC Lattice event', () => { + // Prepare + const event = { foo: 'bar' }; - it('should return error if event is not a VPC Lattice event', () => { - const resp = VpcLatticeEnvelope.safeParse({ foo: 'bar' }, TestSchema); + // Act + const result = VpcLatticeEnvelope.safeParse(event, testSchema); - expect(resp).toEqual({ + // Assess + expect(result).toEqual({ success: false, - error: expect.any(Error), - originalEvent: { foo: 'bar' }, + error: expect.any(ParseError), + originalEvent: event, }); }); - it('should return error if body does not match schema', () => { - const testEvent = TestEvents.vpcLatticeEvent as VpcLatticeEvent; + it('returns error if body does not match schema', () => { + // Prepare + const event = structuredClone(baseEvent); + event.body = JSON.stringify({ foo: 'bar' }); + event.is_base64_encoded = false; - testEvent.body = JSON.stringify({ foo: 'bar' }); + // Act + const result = VpcLatticeEnvelope.safeParse(event, testSchema); - const resp = VpcLatticeEnvelope.safeParse(testEvent, TestSchema); - expect(resp).toEqual({ + // Assess + expect(result).toEqual({ success: false, - error: expect.any(Error), - originalEvent: testEvent, + error: expect.any(ParseError), + originalEvent: event, }); }); }); diff --git a/packages/parser/tests/unit/envelopes/vpc-latticev2.test.ts b/packages/parser/tests/unit/envelopes/vpc-latticev2.test.ts index a3412d8fe4..076c363e92 100644 --- a/packages/parser/tests/unit/envelopes/vpc-latticev2.test.ts +++ b/packages/parser/tests/unit/envelopes/vpc-latticev2.test.ts @@ -1,96 +1,109 @@ -/** - * Test built in schema envelopes for VPC Lattice V2 - * - * @group unit/parser/envelopes - */ - -import { generateMock } from '@anatine/zod-mock'; +import { describe, expect, it } from 'vitest'; +import { z } from 'zod'; import { VpcLatticeV2Envelope } from '../../../src/envelopes/index.js'; +import { ParseError } from '../../../src/errors.js'; import type { VpcLatticeEventV2 } from '../../../src/types/index.js'; -import { TestEvents, TestSchema } from '../schema/utils.js'; +import { getTestEvent } from '../helpers/utils.js'; -describe('VpcLatticeV2Envelope2', () => { - describe('parse', () => { - it('should parse VPC Lattice event', () => { - const mock = generateMock(TestSchema); - const testEvent = TestEvents.vpcLatticeV2Event as VpcLatticeEventV2; +describe('Envelope: VpcLatticeV2Envelope', () => { + const testSchema = z.object({ + name: z.string(), + age: z.number(), + }); + const mockBody = { + name: 'John', + age: 18, + }; + const mockJSONStringifiedBody = JSON.stringify(mockBody); + const baseEvent = getTestEvent({ + eventsPath: 'vpc-lattice', + filename: 'base-v2', + }); - testEvent.body = JSON.stringify(mock); + describe('Method: parse', () => { + it('parses a VPC Lattice v2 event', () => { + // Prepare + const event = structuredClone(baseEvent); + event.body = mockJSONStringifiedBody; + event.isBase64Encoded = false; - const resp = VpcLatticeV2Envelope.parse(testEvent, TestSchema); + // Act + const parsedBody = VpcLatticeV2Envelope.parse(event, testSchema); - expect(resp).toEqual(mock); + // Assess + expect(parsedBody).toEqual(mockBody); }); - it('should parse VPC Lattice event with trailing slash', () => { - const mock = generateMock(TestSchema); - const testEvent = - TestEvents.vpcLatticeEventV2PathTrailingSlash as VpcLatticeEventV2; + it('throws when the body is base64 encoded', () => { + // Prepare + const event = structuredClone(baseEvent); - testEvent.body = JSON.stringify(mock); - - const resp = VpcLatticeV2Envelope.parse(testEvent, TestSchema); - expect(resp).toEqual(mock); + // Act & Assess + expect(() => VpcLatticeV2Envelope.parse(event, testSchema)).toThrow(); }); - it('should throw if event is not a VPC Lattice event', () => { - expect(() => - VpcLatticeV2Envelope.parse({ foo: 'bar' }, TestSchema) - ).toThrow(); - }); + it('throws if event is not a VPC Lattice v2 event', () => { + // Prepare + const event = { foo: 'bar' }; - it('should throw if body does not match schema', () => { - const testEvent = TestEvents.vpcLatticeV2Event as VpcLatticeEventV2; + // Act & Assess + expect(() => VpcLatticeV2Envelope.parse(event, testSchema)).toThrow(); + }); - testEvent.body = JSON.stringify({ foo: 'bar' }); + it('throws if body does not match schema', () => { + // Prepare + const event = structuredClone(baseEvent); + event.body = JSON.stringify({ foo: 'bar' }); + event.isBase64Encoded = false; - expect(() => VpcLatticeV2Envelope.parse(testEvent, TestSchema)).toThrow(); + // Act & Assess + expect(() => VpcLatticeV2Envelope.parse(event, testSchema)).toThrow(); }); }); - describe('safeParse', () => { - it('should parse VPC Lattice event', () => { - const mock = generateMock(TestSchema); - const testEvent = TestEvents.vpcLatticeV2Event as VpcLatticeEventV2; - - testEvent.body = JSON.stringify(mock); + describe('Method: safeParse', () => { + it('parses a VPC Lattice v2 event', () => { + // Prepare + const event = structuredClone(baseEvent); + event.body = mockJSONStringifiedBody; + event.isBase64Encoded = false; - const resp = VpcLatticeV2Envelope.safeParse(testEvent, TestSchema); + // Act + const result = VpcLatticeV2Envelope.safeParse(event, testSchema); - expect(resp).toEqual({ success: true, data: mock }); + // Assess + expect(result).toEqual({ success: true, data: mockBody }); }); - it('should parse VPC Lattice event with trailing slash', () => { - const mock = generateMock(TestSchema); - const testEvent = - TestEvents.vpcLatticeEventV2PathTrailingSlash as VpcLatticeEventV2; - - testEvent.body = JSON.stringify(mock); - - const resp = VpcLatticeV2Envelope.safeParse(testEvent, TestSchema); - expect(resp).toEqual({ success: true, data: mock }); - }); + it('returns error if event is not a VPC Lattice v2 event', () => { + // Prepare + const event = { foo: 'bar' }; - it('should return error if event is not a VPC Lattice event', () => { - const resp = VpcLatticeV2Envelope.safeParse({ foo: 'bar' }, TestSchema); + // Act + const result = VpcLatticeV2Envelope.safeParse(event, testSchema); - expect(resp).toEqual({ + // Assess + expect(result).toEqual({ success: false, - error: expect.any(Error), - originalEvent: { foo: 'bar' }, + error: expect.any(ParseError), + originalEvent: event, }); }); - it('should return error if body does not match schema', () => { - const testEvent = TestEvents.vpcLatticeV2Event as VpcLatticeEventV2; + it('returns error if body does not match schema', () => { + // Prepare + const event = structuredClone(baseEvent); + event.body = JSON.stringify({ foo: 'bar' }); + event.isBase64Encoded = false; - testEvent.body = JSON.stringify({ foo: 'bar' }); + // Act + const result = VpcLatticeV2Envelope.safeParse(event, testSchema); - const resp = VpcLatticeV2Envelope.safeParse(testEvent, TestSchema); - expect(resp).toEqual({ + // Assess + expect(result).toEqual({ success: false, - error: expect.any(Error), - originalEvent: testEvent, + error: expect.any(ParseError), + originalEvent: event, }); }); }); diff --git a/packages/parser/tests/unit/helpers.test.ts b/packages/parser/tests/unit/helpers.test.ts index e46c36b2b6..7a74af1568 100644 --- a/packages/parser/tests/unit/helpers.test.ts +++ b/packages/parser/tests/unit/helpers.test.ts @@ -1,8 +1,4 @@ -/** - * Test decorator parser - * - * @group unit/parser - */ +import { describe, expect, it } from 'vitest'; import { z } from 'zod'; import { JSONStringified } from '../../src/helpers.js'; import { AlbSchema } from '../../src/schemas/alb.js'; @@ -12,7 +8,7 @@ import { } from '../../src/schemas/sns.js'; import { SqsRecordSchema, SqsSchema } from '../../src/schemas/sqs.js'; import type { SnsEvent, SqsEvent } from '../../src/types/schema.js'; -import { getTestEvent } from './schema/utils.js'; +import { getTestEvent } from './helpers/utils.js'; const bodySchema = z.object({ id: z.number(), @@ -28,7 +24,7 @@ const basePayload = { email: 'foo@bar.baz', }; -describe('JSONStringified', () => { +describe('Helper: JSONStringified', () => { it('should return a valid JSON', () => { // Prepare const data = { @@ -79,8 +75,8 @@ describe('JSONStringified', () => { it('should parse extended AlbSchema', () => { // Prepare const testEvent = getTestEvent({ - eventsPath: '.', - filename: 'albEvent', + eventsPath: 'alb', + filename: 'base', }); testEvent.body = JSON.stringify(structuredClone(basePayload)); @@ -99,8 +95,8 @@ describe('JSONStringified', () => { it('should parse extended SqsSchema', () => { // Prepare const testEvent = getTestEvent({ - eventsPath: '.', - filename: 'sqsEvent', + eventsPath: 'sqs', + filename: 'base', }); const stringifiedBody = JSON.stringify(basePayload); testEvent.Records[0].body = stringifiedBody; @@ -128,8 +124,8 @@ describe('JSONStringified', () => { it('should parse extended SnsSchema', () => { // Prepare const testEvent = getTestEvent({ - eventsPath: '.', - filename: 'snsEvent', + eventsPath: 'sns', + filename: 'base', }); testEvent.Records[0].Sns.Message = JSON.stringify(basePayload); diff --git a/packages/parser/tests/unit/helpers/utils.ts b/packages/parser/tests/unit/helpers/utils.ts new file mode 100644 index 0000000000..91fd98790d --- /dev/null +++ b/packages/parser/tests/unit/helpers/utils.ts @@ -0,0 +1,19 @@ +import { readFileSync } from 'node:fs'; +import { join } from 'node:path'; + +/** + * Get a test event from the events directory + */ +export const getTestEvent = >({ + eventsPath, + filename, +}: { + eventsPath: string; + filename: string; +}): T => + JSON.parse( + readFileSync( + join(__dirname, '..', '..', 'events', eventsPath, `${filename}.json`), + 'utf-8' + ) + ) as T; diff --git a/packages/parser/tests/unit/parser.decorator.test.ts b/packages/parser/tests/unit/parser.decorator.test.ts index ef87d96765..390622a66c 100644 --- a/packages/parser/tests/unit/parser.decorator.test.ts +++ b/packages/parser/tests/unit/parser.decorator.test.ts @@ -1,193 +1,122 @@ -/** - * Test decorator parser - * - * @group unit/parser - */ - -import { generateMock } from '@anatine/zod-mock'; -import type { LambdaInterface } from '@aws-lambda-powertools/commons/lib/esm/types'; +import type { LambdaInterface } from '@aws-lambda-powertools/commons/types'; import type { Context } from 'aws-lambda'; -import type { z } from 'zod'; +import { describe, expect, it } from 'vitest'; +import { z } from 'zod'; import { EventBridgeEnvelope } from '../../src/envelopes/index.js'; import { ParseError } from '../../src/errors.js'; import { parser } from '../../src/index.js'; import { EventBridgeSchema } from '../../src/schemas/index.js'; -import type { EventBridgeEvent, ParsedResult } from '../../src/types'; -import { TestEvents, TestSchema } from './schema/utils'; - -describe('Parser Decorator', () => { - const customEventBridgeSchema = EventBridgeSchema.extend({ - detail: TestSchema, - }); - - type TestEvent = z.infer; - - class TestClass implements LambdaInterface { - @parser({ schema: TestSchema }) - public async handler( - event: TestEvent, - _context: Context - ): Promise { - return event; - } - - @parser({ schema: customEventBridgeSchema }) - public async handlerWithCustomSchema( - event: unknown, - _context: Context - ): Promise { - return event; - } - - @parser({ schema: TestSchema, envelope: EventBridgeEnvelope }) - public async handlerWithParserCallsAnotherMethod( - event: TestEvent, - _context: Context - ): Promise { - return this.anotherMethod(event); - } - - @parser({ schema: TestSchema, envelope: EventBridgeEnvelope }) - public async handlerWithSchemaAndEnvelope( - event: TestEvent, - _context: Context - ): Promise { - return event; - } +import { getTestEvent } from './helpers/utils.js'; - @parser({ - schema: TestSchema, - safeParse: true, - }) - public async handlerWithSchemaAndSafeParse( - event: ParsedResult, - _context: Context - ): Promise { - return event; - } - - @parser({ - schema: TestSchema, - envelope: EventBridgeEnvelope, - safeParse: true, - }) - public async harndlerWithEnvelopeAndSafeParse( - event: ParsedResult, - _context: Context - ): Promise { - return event; - } - - private async anotherMethod(event: TestEvent): Promise { - return event; - } +class MockLambda { + protected echo(event: unknown) { + return event; } - - const lambda = new TestClass(); - - it('should parse custom schema event', async () => { - const testEvent = generateMock(TestSchema); - - const resp = await lambda.handler(testEvent, {} as Context); - - expect(resp).toEqual(testEvent); +} + +describe('Decorator: Parser', () => { + const event = { + ...getTestEvent({ + eventsPath: 'eventbridge', + filename: 'base', + }), + detail: { + name: 'John', + age: 42, + }, + }; + const TestSchema = z.object({ + name: z.string(), + age: z.number(), }); - it('should parse custom schema with envelope event', async () => { - const customPayload = generateMock(TestSchema); - const testEvent = TestEvents.eventBridgeEvent as EventBridgeEvent; - testEvent.detail = customPayload; - - const resp = await lambda.handlerWithSchemaAndEnvelope( - testEvent as unknown as TestEvent, - {} as Context - ); - - expect(resp).toEqual(customPayload); - }); - - it('should parse extended envelope event', async () => { - const customPayload = generateMock(TestSchema); - - const testEvent = generateMock(customEventBridgeSchema); - testEvent.detail = customPayload; - - const resp: z.infer = - (await lambda.handlerWithCustomSchema( - testEvent, - {} as Context - )) as z.infer; - - expect(customEventBridgeSchema.parse(resp)).toEqual(testEvent); - expect(resp.detail).toEqual(customPayload); - }); - - it('should parse and call private async method', async () => { - const customPayload = generateMock(TestSchema); - const testEvent = TestEvents.eventBridgeEvent as EventBridgeEvent; - testEvent.detail = customPayload; - - const resp = await lambda.handlerWithParserCallsAnotherMethod( - testEvent as unknown as TestEvent, - {} as Context - ); - - expect(resp).toEqual(customPayload); - }); - - it('should parse event with schema and safeParse', async () => { - const testEvent = generateMock(TestSchema); - - const resp = await lambda.handlerWithSchemaAndSafeParse( - testEvent as unknown as ParsedResult, - {} as Context - ); - - expect(resp).toEqual({ - success: true, - data: testEvent, + it('parses the event using the provided schema', async () => { + // Prepare + const schema = EventBridgeSchema.extend({ + detail: TestSchema, }); - }); + class Mock extends MockLambda implements LambdaInterface { + @parser({ schema }) + public async handler(event: unknown, _context = {} as Context) { + return this.echo(event); + } + } - it('should parse event with schema and safeParse and return error', async () => { - expect( - await lambda.handlerWithSchemaAndSafeParse( - { foo: 'bar' } as unknown as ParsedResult, - {} as Context - ) - ).toEqual({ - error: expect.any(ParseError), - success: false, - originalEvent: { foo: 'bar' }, - }); + // Act + const response = await new Mock().handler(event); + + // Assess + expect(response).toEqual(event); }); - it('should parse event with envelope and safeParse', async () => { - const testEvent = generateMock(TestSchema); - const event = TestEvents.eventBridgeEvent as EventBridgeEvent; - event.detail = testEvent; + it('extracts the paylaod from the envelope', async () => { + // Prepare + class Mock extends MockLambda implements LambdaInterface { + @parser({ schema: TestSchema, envelope: EventBridgeEnvelope }) + public async handler(event: unknown, _context = {} as Context) { + return this.echo(event); + } + } - const resp = await lambda.harndlerWithEnvelopeAndSafeParse( - event as unknown as ParsedResult, - {} as Context - ); + // Act + const response = await new Mock().handler(event); - expect(resp).toEqual({ - success: true, - data: testEvent, - }); + // Assess + expect(response).toEqual(event.detail); }); - it('should parse event with envelope and safeParse and return error', async () => { - expect( - await lambda.harndlerWithEnvelopeAndSafeParse( - { foo: 'bar' } as unknown as ParsedResult, - {} as Context - ) - ).toEqual({ - error: expect.any(ParseError), - success: false, - originalEvent: { foo: 'bar' }, - }); - }); + it.each([ + { + case: 'with valid event', + event, + expected: { success: true, data: event }, + }, + { + case: 'with invalid event', + event: { foo: 'bar' }, + expected: { + success: false, + error: expect.any(ParseError), + originalEvent: { foo: 'bar' }, + }, + }, + { + options: { envelope: EventBridgeEnvelope }, + case: 'with envelope', + event, + expected: { success: true, data: event.detail }, + }, + { + options: { envelope: EventBridgeEnvelope }, + case: 'with envelope and invalid event', + event: { foo: 'bar' }, + expected: { + success: false, + error: expect.any(ParseError), + originalEvent: { foo: 'bar' }, + }, + }, + ])( + 'parses the event with safeParse $case', + async ({ options, event, expected }) => { + // Prepare + const schema = options?.envelope + ? TestSchema + : EventBridgeSchema.extend({ + detail: TestSchema, + }); + class Mock extends MockLambda implements LambdaInterface { + @parser({ schema, safeParse: true, ...options }) + public async handler(event: unknown, _context = {} as Context) { + return this.echo(event); + } + } + + // Act + const response = await new Mock().handler(event); + + // Assess + expect(response).toEqual(expected); + } + ); }); diff --git a/packages/parser/tests/unit/parser.middy.test.ts b/packages/parser/tests/unit/parser.middy.test.ts index 686566b38c..14ece0e18f 100644 --- a/packages/parser/tests/unit/parser.middy.test.ts +++ b/packages/parser/tests/unit/parser.middy.test.ts @@ -1,246 +1,111 @@ -/** - * Test middleware parser - * - * @group unit/parser - */ - -import { generateMock } from '@anatine/zod-mock'; import middy from '@middy/core'; import type { Context } from 'aws-lambda'; -import type { ZodSchema, z } from 'zod'; -import { EventBridgeEnvelope, SqsEnvelope } from '../../src/envelopes'; +import { describe, expect, it } from 'vitest'; +import { z } from 'zod'; +import { EventBridgeEnvelope } from '../../src/envelopes/index.js'; +import { ParseError } from '../../src/errors.js'; import { parser } from '../../src/middleware/parser.js'; -import { SqsSchema } from '../../src/schemas'; -import type { EventBridgeEvent, ParsedResult, SqsEvent } from '../../src/types'; -import { TestEvents, TestSchema } from './schema/utils'; +import { EventBridgeSchema } from '../../src/schemas/index.js'; +import type { EventBridgeEvent } from '../../src/types/index.js'; +import { getTestEvent } from './helpers/utils.js'; describe('Middleware: parser', () => { - type TestEvent = z.infer; - const handler = async ( - event: unknown, - _context: Context - ): Promise => { - return event; + const event = { + ...getTestEvent({ + eventsPath: 'eventbridge', + filename: 'base', + }), + detail: { + name: 'John', + age: 42, + }, }; - - describe(' when envelope is provided ', () => { - const middyfiedHandlerSchemaEnvelope = middy() - .use(parser({ schema: TestSchema, envelope: SqsEnvelope })) - .handler(async (event, _): Promise => { - return event; - }); - it('should parse request body with schema and envelope', async () => { - const bodyMock = generateMock(TestSchema); - - const event = generateMock(SqsSchema, { - stringMap: { - body: () => JSON.stringify(bodyMock), - }, - }); - - const result = (await middyfiedHandlerSchemaEnvelope( - event as unknown as TestEvent[], - {} as Context - )) as TestEvent[]; - for (const item of result) { - expect(item).toEqual(bodyMock); - } - }); - - it('should throw when envelope does not match', async () => { - await expect(async () => { - await middyfiedHandlerSchemaEnvelope( - { name: 'John', age: 18 } as unknown as TestEvent[], - {} as Context - ); - }).rejects.toThrow(); - }); - - it('should throw when schema does not match', async () => { - const event = generateMock(SqsSchema, { - stringMap: { - body: () => '42', - }, - }); - - await expect( - middyfiedHandlerSchemaEnvelope( - event as unknown as TestEvent[], - {} as Context - ) - ).rejects.toThrow(); - }); - - it('should throw when provided schema is invalid', async () => { - const middyfiedHandler = middy(handler).use( - parser({ schema: {} as ZodSchema, envelope: SqsEnvelope }) - ); - - await expect( - middyfiedHandler(42 as unknown as TestEvent[], {} as Context) - ).rejects.toThrow(); - }); - - it('should throw when envelope is correct but schema is invalid', async () => { - const event = generateMock(SqsSchema, { - stringMap: { - body: () => JSON.stringify({ name: 'John', foo: 'bar' }), - }, - }); - - const middyfiedHandler = middy(handler).use( - parser({ schema: {} as ZodSchema, envelope: SqsEnvelope }) - ); - - await expect( - middyfiedHandler(event as unknown as TestEvent[], {} as Context) - ).rejects.toThrow(); - }); + const TestSchema = z.object({ + name: z.string(), + age: z.number(), }); - describe(' when envelope is not provided', () => { - it('should parse the event with built-in schema', async () => { - const event = generateMock(SqsSchema); - - const middyfiedHandler = middy() - .use(parser({ schema: SqsSchema })) - .handler(async (event, _) => { - return event; - }); - - expect( - await middyfiedHandler(event as unknown as SqsEvent, {} as Context) - ).toEqual(event); + it('parses the event using the provided schema', async () => { + // Prepare + const schema = EventBridgeSchema.extend({ + detail: TestSchema, }); + const handler = middy(async (event) => event).use(parser({ schema })); - it('should parse custom event', async () => { - const event = { name: 'John', age: 18 }; - const middyfiedHandler = middy() - .use(parser({ schema: TestSchema })) - .handler(async (event, _): Promise => { - return event; - }); + // Act + const response = await handler(event, {} as Context); - expect( - await middyfiedHandler(event as unknown as TestEvent, {} as Context) - ).toEqual(event); - }); - - it('should throw when the schema does not match', async () => { - const middyfiedHandler = middy(handler).use( - parser({ schema: TestSchema }) - ); - - await expect( - middyfiedHandler(42 as unknown as TestEvent, {} as Context) - ).rejects.toThrow(); - }); - - it('should throw when provided schema is invalid', async () => { - const middyfiedHandler = middy(handler).use( - parser({ schema: {} as ZodSchema }) - ); - - await expect( - middyfiedHandler({ foo: 'bar' } as unknown as TestEvent, {} as Context) - ).rejects.toThrow(); - }); - - it('should return the event when safeParse is true', async () => { - const event = { name: 'John', age: 18 }; - const middyfiedHandler = middy() - .use(parser({ schema: TestSchema, safeParse: true })) - .handler( - async (event, _): Promise> => { - return event; - } - ); - - expect( - await middyfiedHandler( - event as unknown as ParsedResult, - {} as Context - ) - ).toEqual({ - success: true, - data: event, - }); - }); + // Assess + expect(response).toEqual(event); + }); - it('should return error when safeParse is true and schema does not match', async () => { - const middyfiedHandler = middy(handler).use( - parser({ schema: TestSchema, safeParse: true }) - ); + it('extracts the paylaod from the envelope', async () => { + // Prepare + const handler = middy(async (event) => event).use( + parser({ + schema: TestSchema, + envelope: EventBridgeEnvelope, + }) + ); + + // Act + // @ts-expect-error - this is an issue we are tracking #3226 + const response = await handler(event, {} as Context); + + // Assess + expect(response).toEqual(event.detail); + }); - expect( - await middyfiedHandler( - 42 as unknown as ParsedResult, - {} as Context - ) - ).toEqual({ + it.each([ + { + case: 'with valid event', + event, + expected: { success: true, data: event }, + }, + { + case: 'with invalid event', + event: { foo: 'bar' }, + expected: { success: false, - error: expect.any(Error), - originalEvent: 42, - }); - }); - - it('should return event when envelope and safeParse are true', async () => { - const detail = generateMock(TestSchema); - const event = TestEvents.eventBridgeEvent as EventBridgeEvent; - - event.detail = detail; - - const middyfiedHandler = middy() - .use( - parser({ - schema: TestSchema, - envelope: EventBridgeEnvelope, - safeParse: true, - }) - ) - .handler( - async (event, _): Promise> => { - return event; - } - ); - - expect( - await middyfiedHandler( - event as unknown as ParsedResult, - {} as Context - ) - ).toEqual({ - success: true, - data: detail, - }); - }); + error: expect.any(ParseError), + originalEvent: { foo: 'bar' }, + }, + }, + { + options: { envelope: EventBridgeEnvelope }, + case: 'with envelope', + event, + expected: { success: true, data: event.detail }, + }, + { + options: { envelope: EventBridgeEnvelope }, + case: 'with envelope and invalid event', + event: { foo: 'bar' }, + expected: { + success: false, + error: expect.any(ParseError), + originalEvent: { foo: 'bar' }, + }, + }, + ])( + 'parses the event with safeParse $case', + async ({ options, event, expected }) => { + // Prepare + const schema = options?.envelope + ? TestSchema + : EventBridgeSchema.extend({ + detail: TestSchema, + }); + const handler = middy(async (event) => event).use( + parser({ schema, safeParse: true, ...options }) + ); - it('should return error when envelope provided, safeParse is true, and schema does not match', async () => { - const event = TestEvents.eventBridgeEvent as EventBridgeEvent; + // Act + // @ts-expect-error - We are testing events that might not be valid + const response = await handler(event, {} as Context); - const middyfiedHandler = middy() - .use( - parser({ - schema: TestSchema, - envelope: EventBridgeEnvelope, - safeParse: true, - }) - ) - .handler( - async (event, _): Promise> => { - return event; - } - ); - expect( - await middyfiedHandler( - event as unknown as ParsedResult, - {} as Context - ) - ).toEqual({ - success: false, - error: expect.any(Error), - originalEvent: event, - }); - }); - }); + // Assess + expect(response).toEqual(expected); + } + ); }); diff --git a/packages/parser/tests/unit/schema/alb.test.ts b/packages/parser/tests/unit/schema/alb.test.ts index 1d9a21c67e..cd31cc1bcd 100644 --- a/packages/parser/tests/unit/schema/alb.test.ts +++ b/packages/parser/tests/unit/schema/alb.test.ts @@ -1,27 +1,40 @@ -/** - * Test built in schema - * - * @group unit/parser/schema/ - */ -import { AlbMultiValueHeadersSchema, AlbSchema } from '../../../src/schemas/'; -import { TestEvents } from './utils.js'; - -describe('ALB ', () => { - it('should parse alb event', () => { - const albEvent = TestEvents.albEvent; - expect(AlbSchema.parse(albEvent)).toEqual(albEvent); +import { describe, expect, it } from 'vitest'; +import { + AlbMultiValueHeadersSchema, + AlbSchema, +} from '../../../src/schemas/alb.js'; +import { getTestEvent } from '../helpers/utils.js'; + +describe('Schema: ALB', () => { + const eventsPath = 'alb'; + + it('parses an ALB event', () => { + // Prepare + const event = getTestEvent({ eventsPath, filename: 'base' }); + + // Act + const parsedEvent = AlbSchema.parse(event); + + // Assess + expect(parsedEvent).toEqual(event); }); - it('should parse alb event path trailing slash', () => { - const albEventPathTrailingSlash = TestEvents.albEventPathTrailingSlash; - expect(AlbSchema.parse(albEventPathTrailingSlash)).toEqual( - albEventPathTrailingSlash - ); + + it('parses an ALB event with multi value headers', () => { + // Prepare + const event = getTestEvent({ eventsPath, filename: 'multi-value-header' }); + + // Act + const parsedEvent = AlbMultiValueHeadersSchema.parse(event); + + // Assess + expect(parsedEvent).toEqual(event); }); - it('should parse alb event with multi value headers event', () => { - const albMultiValueHeadersEvent = TestEvents.albMultiValueHeadersEvent; - expect(AlbMultiValueHeadersSchema.parse(albMultiValueHeadersEvent)).toEqual( - albMultiValueHeadersEvent - ); + it('throws if event is not a ALB event', () => { + // Prepare + const event = { foo: 'bar' }; + + // Act & Assess + expect(() => AlbSchema.parse(event)).toThrow(); }); }); diff --git a/packages/parser/tests/unit/schema/apigw.test.ts b/packages/parser/tests/unit/schema/apigw.test.ts index 64a3ea965d..ac51ad4467 100644 --- a/packages/parser/tests/unit/schema/apigw.test.ts +++ b/packages/parser/tests/unit/schema/apigw.test.ts @@ -1,28 +1,24 @@ -/** - * Test built-in API Gateway REST schemas - * - * @group unit/parser/schema/apigw - */ +import { describe, expect, it } from 'vitest'; import { APIGatewayProxyEventSchema, APIGatewayRequestAuthorizerEventSchema, APIGatewayTokenAuthorizerEventSchema, -} from '../../../src/schemas/index.js'; -import { getTestEvent } from './utils.js'; +} from '../../../src/schemas/apigw.js'; +import { getTestEvent } from '../helpers/utils.js'; -describe('API Gateway REST Schemas', () => { +describe('Schema: API Gateway REST', () => { const eventsPath = 'apigw-rest'; describe('APIGatewayProxyEventSchema', () => { - it('should throw when the event is invalid', () => { + it('throws when the event is invalid', () => { // Prepare - const event = getTestEvent({ eventsPath, filename: 'invalid' }); + const event = { foo: 'bar' }; // Act & Assess expect(() => APIGatewayProxyEventSchema.parse(event)).toThrow(); }); - it('should parse an event with no authorizer', () => { + it('parses an event with no authorizer', () => { // Prepare const event = getTestEvent({ eventsPath, filename: 'no-auth' }); @@ -33,7 +29,7 @@ describe('API Gateway REST Schemas', () => { expect(parsedEvent).toEqual(event); }); - it('should parse an event with a lambda authorizer', () => { + it('parses an event with a lambda authorizer', () => { // Prepare const event = getTestEvent({ eventsPath, @@ -47,7 +43,7 @@ describe('API Gateway REST Schemas', () => { expect(parsedEvent).toEqual(event); }); - it('should parse an event with a JWT authorizer', () => { + it('parses an event with a JWT authorizer', () => { // Prepare const event = getTestEvent({ eventsPath, @@ -61,7 +57,7 @@ describe('API Gateway REST Schemas', () => { expect(parsedEvent).toEqual(event); }); - it('should parse an event with an IAM authorizer', () => { + it('parses an event with an IAM authorizer', () => { // Prepare const event = getTestEvent({ eventsPath, @@ -75,7 +71,7 @@ describe('API Gateway REST Schemas', () => { expect(parsedEvent).toEqual(event); }); - it('should parse an event sent by the AWS console test UI', () => { + it('parses an event sent by the AWS console test UI', () => { // Prepare const event = getTestEvent({ eventsPath, @@ -89,7 +85,7 @@ describe('API Gateway REST Schemas', () => { expect(parsedEvent).toEqual(event); }); - it('should parse an event sent as a part of a websocket API', () => { + it('parses an event sent as a part of a websocket API', () => { // Prepare const event = getTestEvent({ eventsPath, @@ -105,7 +101,7 @@ describe('API Gateway REST Schemas', () => { }); describe('APIGatewayRequestAuthorizerEventSchema', () => { - it('should throw when the event is invalid', () => { + it('throws when the event is invalid', () => { // Prepare const event = getTestEvent({ eventsPath, filename: 'invalid' }); @@ -115,7 +111,7 @@ describe('API Gateway REST Schemas', () => { ).toThrow(); }); - it('should parse the authorizer event', () => { + it('parses the authorizer event', () => { // Prepare const event = getTestEvent({ eventsPath, @@ -131,7 +127,7 @@ describe('API Gateway REST Schemas', () => { }); describe('APIGatewayTokenAuthorizerEventSchema', () => { - it('should throw when the event is invalid', () => { + it('throws when the event is invalid', () => { // Prepare const event = getTestEvent({ eventsPath, filename: 'invalid' }); @@ -139,7 +135,7 @@ describe('API Gateway REST Schemas', () => { expect(() => APIGatewayTokenAuthorizerEventSchema.parse(event)).toThrow(); }); - it('should parse the event', () => { + it('parses the event', () => { // Prepare const event = getTestEvent({ eventsPath, filename: 'authorizer-token' }); diff --git a/packages/parser/tests/unit/schema/apigwv2.test.ts b/packages/parser/tests/unit/schema/apigwv2.test.ts index 15716ab30f..8df7f6f060 100644 --- a/packages/parser/tests/unit/schema/apigwv2.test.ts +++ b/packages/parser/tests/unit/schema/apigwv2.test.ts @@ -1,27 +1,23 @@ -/** - * Test built-in API Gateway HTTP API (v2) schemas - * - * @group unit/parser/schema/apigwv2 - */ +import { describe, expect, it } from 'vitest'; import { APIGatewayProxyEventV2Schema, APIGatewayRequestAuthorizerEventV2Schema, -} from '../../../src/schemas/index.js'; -import { getTestEvent } from './utils.js'; +} from '../../../src/schemas/apigwv2.js'; +import { getTestEvent } from '../helpers/utils.js'; -describe('API Gateway HTTP (v2) Schemas', () => { +describe('Schema: API Gateway HTTP (v2)', () => { const eventsPath = 'apigw-http'; describe('APIGatewayProxyEventV2Schema', () => { - it('should throw when the event is invalid', () => { + it('throws when the event is invalid', () => { // Prepare - const event = getTestEvent({ eventsPath, filename: 'invalid' }); + const event = { foo: 'bar' }; // Act & Assess expect(() => APIGatewayProxyEventV2Schema.parse(event)).toThrow(); }); - it('should parse an event with no authorizer', () => { + it('parses an event with no authorizer', () => { // Prepare const event = getTestEvent({ eventsPath, filename: 'no-auth' }); @@ -32,7 +28,7 @@ describe('API Gateway HTTP (v2) Schemas', () => { expect(parsedEvent).toEqual(event); }); - it('should parse an event with a lambda authorizer', () => { + it('parses an event with a lambda authorizer', () => { // Prepare const event = getTestEvent({ eventsPath, @@ -46,7 +42,7 @@ describe('API Gateway HTTP (v2) Schemas', () => { expect(parsedEvent).toEqual(event); }); - it('should parse an event with a JWT authorizer', () => { + it('parses an event with a JWT authorizer', () => { // Prepare const event = getTestEvent({ eventsPath, @@ -60,7 +56,7 @@ describe('API Gateway HTTP (v2) Schemas', () => { expect(parsedEvent).toEqual(event); }); - it('should parse an event with an IAM authorizer', () => { + it('parses an event with an IAM authorizer', () => { // Prepare const event = getTestEvent({ eventsPath, @@ -76,17 +72,7 @@ describe('API Gateway HTTP (v2) Schemas', () => { }); describe('APIGatewayRequestAuthorizerEventV2Schema', () => { - it('should throw when the event is invalid', () => { - // Prepare - const event = getTestEvent({ eventsPath, filename: 'invalid' }); - - // Act & Assess - expect(() => - APIGatewayRequestAuthorizerEventV2Schema.parse(event) - ).toThrow(); - }); - - it('should parse the authorizer event', () => { + it('parses the authorizer event', () => { // Prepare const event = getTestEvent({ eventsPath, diff --git a/packages/parser/tests/unit/schema/cloudformation-custom-resource.test.ts b/packages/parser/tests/unit/schema/cloudformation-custom-resource.test.ts index e00530f3bc..64e65f4f58 100644 --- a/packages/parser/tests/unit/schema/cloudformation-custom-resource.test.ts +++ b/packages/parser/tests/unit/schema/cloudformation-custom-resource.test.ts @@ -1,45 +1,65 @@ -/** - * Test built in schema - * - * @group unit/parser/schema/ - */ - +import { describe, expect, it } from 'vitest'; import { CloudFormationCustomResourceCreateSchema, CloudFormationCustomResourceDeleteSchema, CloudFormationCustomResourceUpdateSchema, -} from '../../../src/schemas/'; -import { TestEvents } from './utils.js'; - -describe('CloudFormationCustomResource ', () => { - it('should parse create event', () => { - const cloudFormationCustomResourceCreateEvent = - TestEvents.cloudFormationCustomResourceCreateEvent; - - expect( - CloudFormationCustomResourceCreateSchema.parse( - cloudFormationCustomResourceCreateEvent - ) - ).toEqual(cloudFormationCustomResourceCreateEvent); +} from '../../../src/schemas/cloudformation-custom-resource.js'; +import { getTestEvent } from '../helpers/utils.js'; + +describe('Schema: CloudFormationCustomResources', () => { + const eventsPath = 'cloudformation'; + + it('parses a CloudFormation create event', () => { + // Prepare + const event = getTestEvent({ + eventsPath, + filename: 'create', + }); + + // Act + const parsedEvent = CloudFormationCustomResourceCreateSchema.parse(event); + + // Assess + expect(parsedEvent).toEqual(event); + }); + + it('parses a CloudFormation delete event', () => { + // Prepare + const event = getTestEvent({ + eventsPath, + filename: 'delete', + }); + + // Act + const parsedEvent = CloudFormationCustomResourceDeleteSchema.parse(event); + + // Assess + expect(parsedEvent).toEqual(event); }); - it('should parse update event', () => { - const cloudFormationCustomResourceUpdateEvent = - TestEvents.cloudFormationCustomResourceUpdateEvent; - - expect( - CloudFormationCustomResourceUpdateSchema.parse( - cloudFormationCustomResourceUpdateEvent - ) - ).toEqual(cloudFormationCustomResourceUpdateEvent); + + it('parses a CloudFormation update event', () => { + // Prepare + const event = getTestEvent({ + eventsPath, + filename: 'update', + }); + + // Act + const parsedEvent = CloudFormationCustomResourceUpdateSchema.parse(event); + + // Assess + expect(parsedEvent).toEqual(event); }); - it('should parse delete event', () => { - const cloudFormationCustomResourceDeleteEvent = - TestEvents.cloudFormationCustomResourceDeleteEvent; - - expect( - CloudFormationCustomResourceDeleteSchema.parse( - cloudFormationCustomResourceDeleteEvent - ) - ).toEqual(cloudFormationCustomResourceDeleteEvent); + + it.each([ + { schema: CloudFormationCustomResourceCreateSchema, name: 'create' }, + { schema: CloudFormationCustomResourceDeleteSchema, name: 'delete' }, + { schema: CloudFormationCustomResourceUpdateSchema, name: 'update' }, + ])('throws when the event is invalid ($name)', ({ schema }) => { + // Prepare + const event = { foo: 'bar' }; + + // Act & Assess + expect(() => schema.parse(event)).toThrow(); }); }); diff --git a/packages/parser/tests/unit/schema/cloudwatch.test.ts b/packages/parser/tests/unit/schema/cloudwatch.test.ts index e126bdb7fb..9edd1b3da1 100644 --- a/packages/parser/tests/unit/schema/cloudwatch.test.ts +++ b/packages/parser/tests/unit/schema/cloudwatch.test.ts @@ -1,30 +1,52 @@ -/** - * Test built in schema - * - * @group unit/parser/schema/ - */ +import { describe, expect, it } from 'vitest'; +import { CloudWatchLogsSchema } from '../../../src/schemas/cloudwatch.js'; +import type { CloudWatchLogsEvent } from '../../../src/types/index.js'; +import { getTestEvent } from '../helpers/utils.js'; -import { CloudWatchLogsSchema } from '../../../src/schemas/'; -import { TestEvents } from './utils.js'; +describe('Schema: CloudWatchLogs', () => { + const baseEvent = getTestEvent({ + eventsPath: 'cloudwatch', + filename: 'base', + }); + + it('parses a CloudWatchLogs event', () => { + // Prepare + const event = structuredClone(baseEvent); -describe('CloudWatchLogs ', () => { - it('should parse cloudwatch logs event', () => { - const cloudWatchLogEvent = TestEvents.cloudWatchLogEvent; - const parsed = CloudWatchLogsSchema.parse(cloudWatchLogEvent); - expect(parsed.awslogs.data).toBeDefined(); - expect(parsed.awslogs.data?.logEvents[0]).toEqual({ - id: 'eventId1', - timestamp: 1440442987000, - message: '[ERROR] First test message', + // Act + const parsedEvent = CloudWatchLogsSchema.parse(event); + + // Assess + expect(parsedEvent).toStrictEqual({ + awslogs: { + data: { + logEvents: [ + { + id: 'eventId1', + message: '[ERROR] First test message', + timestamp: 1440442987000, + }, + { + id: 'eventId2', + message: '[ERROR] Second test message', + timestamp: 1440442987001, + }, + ], + logGroup: 'testLogGroup', + logStream: 'testLogStream', + messageType: 'DATA_MESSAGE', + owner: '123456789123', + subscriptionFilters: ['testFilter'], + }, + }, }); }); - it('should throw error if cloudwatch logs event is invalid', () => { - expect(() => - CloudWatchLogsSchema.parse({ - awslogs: { - data: 'invalid', - }, - }) - ).toThrowError(); + + it('throws if event is not a CloudWatchLogs event', () => { + // Prepare + const event = { foo: 'bar' }; + + // Act & Assess + expect(() => CloudWatchLogsSchema.parse(event)).toThrow(); }); }); diff --git a/packages/parser/tests/unit/schema/dynamodb.test.ts b/packages/parser/tests/unit/schema/dynamodb.test.ts index f0d90fbc5b..2d4b1c6ed7 100644 --- a/packages/parser/tests/unit/schema/dynamodb.test.ts +++ b/packages/parser/tests/unit/schema/dynamodb.test.ts @@ -1,17 +1,30 @@ -/** - * Test built in schema - * - * @group unit/parser/schema/ - */ +import { describe, expect, it } from 'vitest'; +import { DynamoDBStreamSchema } from '../../../src/schemas/dynamodb.js'; +import type { DynamoDBStreamEvent } from '../../../src/types/schema.js'; +import { getTestEvent } from '../helpers/utils.js'; -import { DynamoDBStreamSchema } from '../../../src/schemas/'; -import { TestEvents } from './utils.js'; +describe('Schema: DynamoDB ', () => { + const baseEvent = getTestEvent({ + eventsPath: 'dynamodb', + filename: 'base', + }); + + it('parses a DynamoDB Stream event', () => { + // Prepare + const event = structuredClone(baseEvent); + + // Act + const parsedEvent = DynamoDBStreamSchema.parse(event); + + // Assess + expect(parsedEvent).toEqual(event); + }); + + it('throws if event is not a DynamoDB Stream event', () => { + // Prepare + const event = { foo: 'bar' }; -describe('DynamoDB ', () => { - const dynamoStreamEvent = TestEvents.dynamoStreamEvent; - it('should parse a stream of records', () => { - expect(DynamoDBStreamSchema.parse(dynamoStreamEvent)).toEqual( - dynamoStreamEvent - ); + // Act & Assess + expect(() => DynamoDBStreamSchema.parse(event)).toThrow(); }); }); diff --git a/packages/parser/tests/unit/schema/eventbridge.test.ts b/packages/parser/tests/unit/schema/eventbridge.test.ts index 4423318874..17f0e0a7f6 100644 --- a/packages/parser/tests/unit/schema/eventbridge.test.ts +++ b/packages/parser/tests/unit/schema/eventbridge.test.ts @@ -1,16 +1,38 @@ -/** - * Test built in schema - * - * @group unit/parser/schema/ - */ +import { describe, expect, it } from 'vitest'; +import { z } from 'zod'; +import { EventBridgeSchema } from '../../../src/schemas/eventbridge.js'; +import type { EventBridgeEvent } from '../../../src/types/index.js'; +import { getTestEvent } from '../helpers/utils.js'; -import { EventBridgeSchema } from '../../../src/schemas/'; -import { TestEvents } from './utils.js'; +describe('Schema: EventBridge', () => { + const baseEvent = getTestEvent({ + eventsPath: 'eventbridge', + filename: 'base', + }); + + it('parses an EventBridge event', () => { + // Prepare + const event = structuredClone(baseEvent); + const schema = EventBridgeSchema.extend({ + detail: z.object({ + instance_id: z.string(), + state: z.string(), + }), + }); + + // Act + const parsedEvent = schema.parse(event); + + // Assess + expect(parsedEvent).toEqual(event); + expect(parsedEvent.detail.state).toEqual('terminated'); + }); -describe('EventBridge ', () => { - it('should parse eventbridge event', () => { - const eventBridgeEvent = TestEvents.eventBridgeEvent; + it('throws if event is not an EventBridge event', () => { + // Prepare + const event = { foo: 'bar' }; - expect(EventBridgeSchema.parse(eventBridgeEvent)).toEqual(eventBridgeEvent); + // Act & Assess + expect(() => EventBridgeSchema.parse(event)).toThrow(); }); }); diff --git a/packages/parser/tests/unit/schema/kafka.test.ts b/packages/parser/tests/unit/schema/kafka.test.ts index 6292f3001f..f281d040c3 100644 --- a/packages/parser/tests/unit/schema/kafka.test.ts +++ b/packages/parser/tests/unit/schema/kafka.test.ts @@ -1,34 +1,51 @@ -/** - * Test built in schema - * - * @group unit/parser/schema/ - */ - +import type { MSKEvent } from 'aws-lambda'; +import { describe, expect, it } from 'vitest'; import { KafkaMskEventSchema, KafkaRecordSchema, KafkaSelfManagedEventSchema, -} from '../../../src/schemas/'; -import type { KafkaSelfManagedEvent } from '../../../src/types'; -import type { KafkaRecord } from '../../../src/types/schema'; -import { TestEvents } from './utils.js'; +} from '../../../src/schemas/kafka.js'; +import type { + KafkaMskEvent, + KafkaRecord, + KafkaSelfManagedEvent, +} from '../../../src/types/schema.js'; +import { getTestEvent } from '../helpers/utils.js'; describe('Kafka ', () => { - const expectedTestEvent = { - key: 'recordKey', - value: JSON.stringify({ key: 'value' }), - partition: 0, - topic: 'mytopic', - offset: 15, - timestamp: 1545084650987, - timestampType: 'CREATE_TIME', - headers: [ - { - headerKey: 'headerValue', + it('parses a MSK event', () => { + // Prepare + const event = getTestEvent({ + eventsPath: 'kafka', + filename: 'msk', + }); + const expectedMSKParsedEvent: KafkaMskEvent = { + ...event, + bootstrapServers: event.bootstrapServers.split(','), + records: { + [Object.keys(event.records)[0]]: [ + { + ...event.records[Object.keys(event.records)[0]][0], + key: 'recordKey', + value: JSON.stringify({ key: 'value' }), + headers: [ + { + headerKey: 'headerValue', + }, + ], + }, + ], }, - ], - }; - it('should parse kafka MSK event', () => { + }; + + // Act + const parsedEvent = KafkaMskEventSchema.parse(event); + + // Assess + expect(parsedEvent).toEqual(expectedMSKParsedEvent); + }); + + /* it('should parse kafka MSK event', () => { const kafkaEventMsk = TestEvents.kafkaEventMsk; expect( @@ -70,5 +87,5 @@ describe('Kafka ', () => { kafkaEventMsk.records['mytopic-0'][0] ); expect(parsedRecord.topic).toEqual('mytopic'); - }); + }); */ }); diff --git a/packages/parser/tests/unit/schema/kinesis-firehose.test.ts b/packages/parser/tests/unit/schema/kinesis-firehose.test.ts new file mode 100644 index 0000000000..f3aac893ac --- /dev/null +++ b/packages/parser/tests/unit/schema/kinesis-firehose.test.ts @@ -0,0 +1,69 @@ +import { describe, expect, it } from 'vitest'; +import { + KinesisFirehoseSchema, + KinesisFirehoseSqsSchema, +} from '../../../src/schemas/kinesis-firehose.js'; +import type { KinesisFireHoseEvent } from '../../../src/types/index.js'; +import { getTestEvent } from '../helpers/utils.js'; + +describe('Schema: Kinesis Firehose', () => { + const putEvent = getTestEvent({ + eventsPath: 'kinesis-firehose', + filename: 'direct-put', + }); + const dataStreamEvent = getTestEvent({ + eventsPath: 'kinesis-firehose', + filename: 'from-data-stream', + }); + const sqsEvent = getTestEvent({ + eventsPath: 'kinesis-firehose', + filename: 'sqs-event-via-kinesis-firehose', + }); + + it.each([ + { event: putEvent, name: 'Direct Put' }, + { event: dataStreamEvent, name: 'From Data Stream' }, + ])('parses a Kinesis event ($name)', ({ event }) => { + // Act + const parsedEvent = KinesisFirehoseSchema.parse(event); + + // Assess + expect(parsedEvent.records).toHaveLength(2); + expect(parsedEvent.records[0].data).toEqual('Hello World'); + expect(parsedEvent.records[1].data).toEqual( + JSON.stringify({ Hello: 'World' }) + ); + }); + + it('throws if the event is not a Kinesis Firehose event', () => { + // Prepare + const event = { foo: 'bar' }; + + // Act & Assess + expect(() => KinesisFirehoseSchema.parse(event)).toThrow(); + }); + + it('parses a SQS record from a Kinesis Firehose event', () => { + // Prepare + const event = structuredClone(sqsEvent); + + // Act + const parsedEvent = KinesisFirehoseSqsSchema.parse(event); + + // Assess + expect(parsedEvent.records).toHaveLength(1); + expect(parsedEvent.records[0].data.body).toEqual('Test message.'); + }); + + it.fails( + 'throws if the SQS record within the Kinesis Firehose event is invalid', + () => { + // Prepare + const event = structuredClone(sqsEvent); + event.records[0].data = 'Invalid SQS record'; + + // Act & Assess + expect(() => KinesisFirehoseSqsSchema.parse(event)).toThrow(); + } + ); +}); diff --git a/packages/parser/tests/unit/schema/kinesis.test.ts b/packages/parser/tests/unit/schema/kinesis.test.ts index e107d1ae2f..a354d49639 100644 --- a/packages/parser/tests/unit/schema/kinesis.test.ts +++ b/packages/parser/tests/unit/schema/kinesis.test.ts @@ -1,113 +1,57 @@ -/** - * Test built in schema - * - * @group unit/parser/schema/ - */ +import { describe, expect, it } from 'vitest'; +import { KinesisDataStreamSchema } from '../../../src/schemas/kinesis.js'; +import type { KinesisDataStreamEvent } from '../../../src/types/index.js'; +import { getTestEvent } from '../helpers/utils.js'; -import { - KinesisDataStreamRecord, - KinesisDataStreamSchema, - KinesisFirehoseRecordSchema, - KinesisFirehoseSchema, - KinesisFirehoseSqsRecordSchema, - KinesisFirehoseSqsSchema, -} from '../../../src/schemas/'; -import type { - KinesisDataStreamEvent, - KinesisFireHoseEvent, - KinesisFireHoseSqsEvent, -} from '../../../src/types'; -import type { - KinesisFirehoseRecord, - KinesisFirehoseSqsRecord, -} from '../../../src/types/schema'; -import { TestEvents } from './utils.js'; +describe('Schema: Kinesis Stream', () => { + const baseEvent = getTestEvent({ + eventsPath: 'kinesis-stream', + filename: 'base', + }); -describe('Kinesis ', () => { - it('should parse kinesis event', () => { - const kinesisStreamEvent = TestEvents.kinesisStreamEvent; - const parsed = KinesisDataStreamSchema.parse(kinesisStreamEvent); + it('parses a Kinesis event', () => { + // Prepare + const event = structuredClone(baseEvent); - expect(parsed.Records[0].kinesis.data).toEqual('Hello, this is a test.'); - }); - it('should parse single kinesis record', () => { - const kinesisStreamEventOneRecord = TestEvents.kinesisStreamEventOneRecord; - const parsed = KinesisDataStreamSchema.parse(kinesisStreamEventOneRecord); + // Act + const parsedEvent = KinesisDataStreamSchema.parse(event); - expect(parsed.Records[0].kinesis.data).toEqual({ - message: 'test message', - username: 'test', - }); - }); - it('should parse Firehose event', () => { - const kinesisFirehoseKinesisEvent = TestEvents.kinesisFirehoseKinesisEvent; - const parsed = KinesisFirehoseSchema.parse(kinesisFirehoseKinesisEvent); - expect(parsed.records[0].data).toEqual('Hello World'); - }); - it('should parse Kinesis Firehose PutEvents event', () => { - const kinesisFirehosePutEvent = TestEvents.kinesisFirehosePutEvent; - const parsed = KinesisFirehoseSchema.parse(kinesisFirehosePutEvent); - expect(JSON.parse(parsed.records[1].data)).toEqual({ - Hello: 'World', - }); + // Assess + expect(parsedEvent.Records[0].kinesis.data).toEqual( + 'Hello, this is a test.' + ); + expect(parsedEvent.Records[1].kinesis.data).toEqual('This is only a test.'); }); - it('should parse Firehose event with SQS event', () => { - const kinesisFirehoseSQSEvent = TestEvents.kinesisFirehoseSQSEvent; - const parsed = KinesisFirehoseSqsSchema.parse(kinesisFirehoseSQSEvent); - expect(parsed.records[0].data).toMatchObject({ - messageId: '5ab807d4-5644-4c55-97a3-47396635ac74', - body: 'Test message.', + + it('parses a Kinesis event of a CloudWatch log', () => { + // Prepare + const event = getTestEvent({ + eventsPath: 'kinesis-stream', + filename: 'cloudwatch-event-via-stream', }); - }); - it('should parse Kinesis event with CloudWatch event', () => { - const kinesisStreamCloudWatchLogsEvent = - TestEvents.kinesisStreamCloudWatchLogsEvent; - const parsed = KinesisDataStreamSchema.parse( - kinesisStreamCloudWatchLogsEvent - ); - expect(parsed.Records[0].kinesis.data).toMatchObject({ + // Act + const parsedEvent = KinesisDataStreamSchema.parse(event); + + // Assess + expect(parsedEvent.Records).toHaveLength(2); + const expectedObject = expect.objectContaining({ + logEvents: expect.any(Array), + logGroup: expect.stringContaining('/aws/lambda/'), + logStream: expect.stringContaining('2022/11/10/[$LATEST]'), messageType: 'DATA_MESSAGE', owner: '231436140809', - logGroup: '/aws/lambda/pt-1488-DummyLogDataFunction-gnWXPvL6jJyG', - logStream: '2022/11/10/[$LATEST]26b6a45d574f442ea28438923cbf7bf7', + subscriptionFilters: expect.any(Array), }); - }); - it('should return original value if cannot parse KinesisFirehoseSqsRecord', () => { - const kinesisFirehoseSQSEvent = TestEvents.kinesisFirehoseSQSEvent as { - records: { data: string }[]; - }; - kinesisFirehoseSQSEvent.records[0].data = 'not a valid json'; - const parsed = KinesisFirehoseSqsSchema.parse(kinesisFirehoseSQSEvent); - expect(parsed.records[0].data).toEqual('not a valid json'); - }); - it('should parse a kinesis record from a kinesis event', () => { - const kinesisStreamEvent: KinesisDataStreamEvent = - TestEvents.kinesisStreamEvent as KinesisDataStreamEvent; - const parsedRecord = KinesisDataStreamRecord.parse( - kinesisStreamEvent.Records[0] - ); - - expect(parsedRecord.eventName).toEqual('aws:kinesis:record'); + expect(parsedEvent.Records[0].kinesis.data).toStrictEqual(expectedObject); + expect(parsedEvent.Records[1].kinesis.data).toStrictEqual(expectedObject); }); - it('should parse a kinesis firehose record from a kinesis firehose event', () => { - const kinesisFirehoseEvent: KinesisFireHoseEvent = - TestEvents.kinesisFirehoseKinesisEvent as KinesisFireHoseEvent; - const parsedRecord: KinesisFirehoseRecord = - KinesisFirehoseRecordSchema.parse(kinesisFirehoseEvent.records[0]); + it('throws if event is not a Kinesis Stream event', () => { + // Prepare + const event = { foo: 'bar' }; - expect(parsedRecord.data).toEqual('Hello World'); - }); - - it('should parse a sqs record from a kinesis firehose event', () => { - const kinesisFireHoseSqsEvent: KinesisFireHoseSqsEvent = - TestEvents.kinesisFirehoseSQSEvent as KinesisFireHoseSqsEvent; - const parsed: KinesisFirehoseSqsRecord = - KinesisFirehoseSqsRecordSchema.parse(kinesisFireHoseSqsEvent.records[0]); - - expect(parsed.recordId).toEqual( - '49640912821178817833517986466168945147170627572855734274000000' - ); + // Act & Assess + expect(() => KinesisDataStreamSchema.parse(event)).toThrow(); }); }); diff --git a/packages/parser/tests/unit/schema/lambda.test.ts b/packages/parser/tests/unit/schema/lambda.test.ts index e9b0a3449b..2375a2a50e 100644 --- a/packages/parser/tests/unit/schema/lambda.test.ts +++ b/packages/parser/tests/unit/schema/lambda.test.ts @@ -1,24 +1,57 @@ -/** - * Test built in schema - * - * @group unit/parser/schema/ - */ - -import { LambdaFunctionUrlSchema } from '../../../src/schemas/'; -import { TestEvents } from './utils.js'; - -describe('Lambda ', () => { - it('should parse lambda event', () => { - const lambdaFunctionUrlEvent = TestEvents.apiGatewayProxyV2Event; - - expect(LambdaFunctionUrlSchema.parse(lambdaFunctionUrlEvent)).toEqual( - lambdaFunctionUrlEvent - ); +import { describe, expect, it } from 'vitest'; +import { LambdaFunctionUrlSchema } from '../../../src/schemas/lambda.js'; +import { getTestEvent } from '../helpers/utils.js'; + +describe('Schema: Lambda', () => { + const eventsPath = 'lambda'; + + it('parses a Lambda FUrl event', () => { + // Prepare + const event = getTestEvent({ + eventsPath, + filename: 'base', + }); + + // Act + const parsedEvent = LambdaFunctionUrlSchema.parse(event); + + // Assess + expect(parsedEvent).toEqual(event); + }); + + it('parses a Lambda FUrl with IAM Auth', () => { + // Prepare + const event = getTestEvent({ + eventsPath, + filename: 'iam-authorizer', + }); + + // Act + const parsedEvent = LambdaFunctionUrlSchema.parse(event); + + // Assess + expect(parsedEvent).toEqual(event); + }); + + it('parses a Lambda FUrl with string body', () => { + // Prepare + const event = getTestEvent({ + eventsPath, + filename: 'with-body', + }); + + // Act + const parsedEvent = LambdaFunctionUrlSchema.parse(event); + + // Assess + expect(parsedEvent).toEqual(event); }); - it('should parse url IAM event', () => { - const urlIAMEvent = TestEvents.lambdaFunctionUrlIAMEvent; + it('throws if event is not a Lambda FUrl event', () => { + // Prepare + const event = { foo: 'bar' }; - expect(LambdaFunctionUrlSchema.parse(urlIAMEvent)).toEqual(urlIAMEvent); + // Act & Assess + expect(() => LambdaFunctionUrlSchema.parse(event)).toThrow(); }); }); diff --git a/packages/parser/tests/unit/schema/s3.test.ts b/packages/parser/tests/unit/schema/s3.ts similarity index 96% rename from packages/parser/tests/unit/schema/s3.test.ts rename to packages/parser/tests/unit/schema/s3.ts index 8798155472..ec23880581 100644 --- a/packages/parser/tests/unit/schema/s3.test.ts +++ b/packages/parser/tests/unit/schema/s3.ts @@ -1,16 +1,11 @@ -/** - * Test built in schema - * - * @group unit/parser/schema/ - */ - +import { describe, expect, it } from 'vitest'; import { S3EventNotificationEventBridgeSchema, S3ObjectLambdaEventSchema, S3Schema, S3SqsEventNotificationSchema, } from '../../../src/schemas/'; -import { TestEvents } from './utils.js'; +import { getTestEvent } from '../helpers/utils.js'; describe('S3 ', () => { it('should parse s3 event', () => { diff --git a/packages/parser/tests/unit/schema/ses.test.ts b/packages/parser/tests/unit/schema/ses.test.ts index 7c27a83d97..2d5f68af3b 100644 --- a/packages/parser/tests/unit/schema/ses.test.ts +++ b/packages/parser/tests/unit/schema/ses.test.ts @@ -1,24 +1,33 @@ -/** - * Test built in schema - * - * @group unit/parser/schema/ - */ +import { describe, expect, it } from 'vitest'; +import { SesSchema } from '../../../src/schemas/ses.js'; +import type { SesEvent } from '../../../src/types/index.js'; +import { getTestEvent } from '../helpers/utils.js'; -import { SesRecordSchema, SesSchema } from '../../../src/schemas/'; -import type { SesEvent } from '../../../src/types'; -import type { SesRecord } from '../../../src/types/schema'; -import { TestEvents } from './utils.js'; +describe('Schema: SES', () => { + const baseEvent = getTestEvent({ + eventsPath: 'ses', + filename: 'base', + }); + + it('parses a SES event', () => { + // Prepare + const event = structuredClone(baseEvent); + + // Act + const parsedEvent = SesSchema.parse(event); -describe('SES', () => { - it('should parse ses event', () => { - const sesEvent = TestEvents.sesEvent; - expect(SesSchema.parse(sesEvent)).toEqual(sesEvent); + // Assess + expect(parsedEvent).toEqual(event); + expect(parsedEvent.Records[0].ses.mail.source).toEqual( + 'janedoe@example.com' + ); }); - it('should parse record from ses event', () => { - const sesEvent: SesEvent = TestEvents.sesEvent as SesEvent; - const parsed: SesRecord = SesRecordSchema.parse(sesEvent.Records[0]); + it('throws if event is not a SES event', () => { + // Prepare + const event = { foo: 'bar' }; - expect(parsed.ses.mail.source).toEqual('janedoe@example.com'); + // Act & Assess + expect(() => SesSchema.parse(event)).toThrow(); }); }); diff --git a/packages/parser/tests/unit/schema/sns.test.ts b/packages/parser/tests/unit/schema/sns.test.ts index 7ddb7f1132..dd362cab79 100644 --- a/packages/parser/tests/unit/schema/sns.test.ts +++ b/packages/parser/tests/unit/schema/sns.test.ts @@ -1,48 +1,31 @@ -/** - * Test built in schema - * - * @group unit/parser/schema/ - */ +import { describe, expect, it } from 'vitest'; +import { SnsSchema } from '../../../src/schemas/sns.js'; +import type { SnsEvent } from '../../../src/types/index.js'; +import { getTestEvent } from '../helpers/utils.js'; -import { - SnsNotificationSchema, - SnsRecordSchema, - SnsSchema, - SnsSqsNotificationSchema, -} from '../../../src/schemas/'; -import type { SnsEvent, SqsEvent } from '../../../src/types'; -import type { - SnsNotification, - SnsRecord, - SnsSqsNotification, -} from '../../../src/types/schema'; -import { TestEvents } from './utils.js'; - -describe('SNS', () => { - it('should parse sns event', () => { - const snsEvent = TestEvents.snsEvent; - expect(SnsSchema.parse(snsEvent)).toEqual(snsEvent); - }); - it('should parse record from sns event', () => { - const snsEvent: SnsEvent = TestEvents.snsEvent as SnsEvent; - const parsed: SnsRecord = SnsRecordSchema.parse(snsEvent.Records[0]); - expect(parsed.Sns.Message).toEqual('Hello from SNS!'); +describe('Schema: SNS', () => { + const baseEvent = getTestEvent({ + eventsPath: 'sns', + filename: 'base', }); - it('should parse sns notification from sns event', () => { - const snsEvent: SnsEvent = TestEvents.snsEvent as SnsEvent; - const parsed: SnsNotification = SnsNotificationSchema.parse( - snsEvent.Records[0].Sns - ); - expect(parsed.Message).toEqual('Hello from SNS!'); + + it('parses a SNS event', () => { + // Prepare + const event = structuredClone(baseEvent); + + // Act + const parsedEvent = SnsSchema.parse(event); + + // Assess + expect(parsedEvent).toEqual(event); + expect(parsedEvent.Records[0].Sns.Message).toEqual('Hello from SNS!'); }); - it('should parse sns notification from sqs -> sns event', () => { - const sqsEvent: SqsEvent = TestEvents.snsSqsEvent as SqsEvent; - console.log(sqsEvent.Records[0].body); - const parsed: SnsSqsNotification = SnsSqsNotificationSchema.parse( - JSON.parse(sqsEvent.Records[0].body) - ); - expect(parsed.TopicArn).toEqual( - 'arn:aws:sns:eu-west-1:231436140809:powertools265' - ); + + it('throws if event is not a SNS event', () => { + // Prepare + const event = { foo: 'bar' }; + + // Act & Assess + expect(() => SnsSchema.parse(event)).toThrow(); }); }); diff --git a/packages/parser/tests/unit/schema/sqs.test.ts b/packages/parser/tests/unit/schema/sqs.test.ts index 9514338395..bf456ddb66 100644 --- a/packages/parser/tests/unit/schema/sqs.test.ts +++ b/packages/parser/tests/unit/schema/sqs.test.ts @@ -1,22 +1,30 @@ -/** - * Test built in schema - * - * @group unit/parser/schema/ - */ +import { describe, expect, it } from 'vitest'; +import { SqsSchema } from '../../../src/schemas/sqs.js'; +import type { SqsEvent } from '../../../src/types/schema.js'; +import { getTestEvent } from '../helpers/utils.js'; -import { SqsRecordSchema, SqsSchema } from '../../../src/schemas/'; -import type { SqsEvent } from '../../../src/types'; -import type { SqsRecord } from '../../../src/types/schema'; -import { TestEvents } from './utils.js'; +describe('Schema: SqsSchema ', () => { + const baseEvent = getTestEvent({ + eventsPath: 'sqs', + filename: 'base', + }); + + it('parses a SQS event', () => { + // Prepare + const event = structuredClone(baseEvent); + + // Act + const parsedEvent = SqsSchema.parse(event); -describe('SQS', () => { - it('should parse sqs event', () => { - const sqsEvent = TestEvents.sqsEvent; - expect(SqsSchema.parse(sqsEvent)).toEqual(sqsEvent); + // Assess + expect(parsedEvent).toEqual(event); }); - it('should parse record from sqs event', () => { - const sqsEvent: SqsEvent = TestEvents.sqsEvent as SqsEvent; - const parsed: SqsRecord = SqsRecordSchema.parse(sqsEvent.Records[0]); - expect(parsed.body).toEqual('Test message.'); + + it('throws if event is not a SQS event', () => { + // Prepare + const event = { foo: 'bar' }; + + // Act & Assess + expect(() => SqsSchema.parse(event)).toThrow(); }); }); diff --git a/packages/parser/tests/unit/schema/utils.ts b/packages/parser/tests/unit/schema/utils.ts deleted file mode 100644 index cb0647aed7..0000000000 --- a/packages/parser/tests/unit/schema/utils.ts +++ /dev/null @@ -1,133 +0,0 @@ -import { readFileSync } from 'node:fs'; -import { join } from 'node:path'; -import { z } from 'zod'; - -export const TestSchema = z.object({ - name: z.string(), - age: z.number().min(18).max(99), -}); - -const filenames = [ - 'activeMQEvent', - 'albEvent', - 'albEventPathTrailingSlash', - 'albMultiValueHeadersEvent', - 'apiGatewayAuthorizerRequestEvent', - 'apiGatewayAuthorizerTokenEvent', - 'apiGatewayAuthorizerV2Event', - 'apiGatewayProxyEvent', - 'apiGatewayProxyEventAnotherPath', - 'apiGatewayProxyEventPathTrailingSlash', - 'apiGatewayProxyEventPrincipalId', - 'apiGatewayProxyEvent_noVersionAuth', - 'apiGatewayProxyOtherEvent', - 'apiGatewayProxyEventTestUI', - 'apiGatewayProxyV2Event', - 'apiGatewayProxyV2EventPathTrailingSlash', - 'apiGatewayProxyV2Event_GET', - 'apiGatewayProxyV2IamEvent', - 'apiGatewayProxyV2LambdaAuthorizerEvent', - 'apiGatewayProxyV2OtherGetEvent', - 'apiGatewayProxyV2SchemaMiddlewareInvalidEvent', - 'apiGatewayProxyV2SchemaMiddlewareValidEvent', - 'apiGatewaySchemaMiddlewareInvalidEvent', - 'apiGatewaySchemaMiddlewareValidEvent', - 'appSyncAuthorizerEvent', - 'appSyncAuthorizerResponse', - 'appSyncDirectResolver', - 'appSyncResolverEvent', - 'awsConfigRuleConfigurationChanged', - 'awsConfigRuleOversizedConfiguration', - 'awsConfigRuleScheduled', - 'bedrockAgentEvent', - 'bedrockAgentPostEvent', - 'cloudFormationCustomResourceCreateEvent', - 'cloudFormationCustomResourceDeleteEvent', - 'cloudFormationCustomResourceUpdateEvent', - 'cloudWatchDashboardEvent', - 'cloudWatchLogEvent', - 'codePipelineEvent', - 'codePipelineEventData', - 'codePipelineEventEmptyUserParameters', - 'codePipelineEventWithEncryptionKey', - 'cognitoCreateAuthChallengeEvent', - 'cognitoCustomMessageEvent', - 'cognitoDefineAuthChallengeEvent', - 'cognitoPostAuthenticationEvent', - 'cognitoPostConfirmationEvent', - 'cognitoPreAuthenticationEvent', - 'cognitoPreSignUpEvent', - 'cognitoPreTokenGenerationEvent', - 'cognitoUserMigrationEvent', - 'cognitoVerifyAuthChallengeResponseEvent', - 'connectContactFlowEventAll', - 'connectContactFlowEventMin', - 'dynamoStreamEvent', - 'eventBridgeEvent', - 'kafkaEventMsk', - 'kafkaEventSelfManaged', - 'kinesisFirehoseKinesisEvent', - 'kinesisFirehosePutEvent', - 'kinesisFirehoseSQSEvent', - 'kinesisStreamCloudWatchLogsEvent', - 'kinesisStreamEvent', - 'kinesisStreamEventOneRecord', - 'lambdaFunctionUrlEvent', - 'lambdaFunctionUrlEventPathTrailingSlash', - 'lambdaFunctionUrlIAMEvent', - 'rabbitMQEvent', - 's3Event', - 's3EventBridgeNotificationObjectCreatedEvent', - 's3EventBridgeNotificationObjectDeletedEvent', - 's3EventBridgeNotificationObjectExpiredEvent', - 's3EventBridgeNotificationObjectRestoreCompletedEvent', - 's3EventDecodedKey', - 's3EventDeleteObject', - 's3EventDeleteObjectWithoutEtagSize', - 's3EventGlacier', - 's3ObjectEventIAMUser', - 's3ObjectEventTempCredentials', - 's3SqsEvent', - 'secretsManagerEvent', - 'sesEvent', - 'snsEvent', - 'snsSqsEvent', - 'snsSqsFifoEvent', - 'sqsEvent', - 'vpcLatticeEvent', - 'vpcLatticeEventPathTrailingSlash', - 'vpcLatticeEventV2PathTrailingSlash', - 'vpcLatticeV2Event', -] as const; - -type TestEvents = { [K in (typeof filenames)[number]]: unknown }; -const loadFileContent = (filename: string): string => - readFileSync(`./tests/events/${filename}.json`, 'utf-8'); - -const createTestEvents = (fileList: readonly string[]): TestEvents => { - const testEvents: Partial = {}; - - for (const filename of fileList) { - Object.defineProperty(testEvents, filename, { - get: () => JSON.parse(loadFileContent(filename)), - }); - } - - return testEvents as TestEvents; -}; - -export const TestEvents = createTestEvents(filenames); - -export const getTestEvent = >({ - eventsPath, - filename, -}: { - eventsPath: string; - filename: string; -}): T => - JSON.parse( - readFileSync( - join(__dirname, '..', '..', 'events', eventsPath, `${filename}.json`), - 'utf-8' - ) - ) as T; diff --git a/packages/parser/tests/unit/schema/vpc-lattice.test.ts b/packages/parser/tests/unit/schema/vpc-lattice.test.ts index 643714fb47..e0f60fed3e 100644 --- a/packages/parser/tests/unit/schema/vpc-lattice.test.ts +++ b/packages/parser/tests/unit/schema/vpc-lattice.test.ts @@ -1,22 +1,30 @@ -/** - * Test built in schema - * - * @group unit/parser/schema/ - */ +import { describe, expect, it } from 'vitest'; +import { VpcLatticeSchema } from '../../../src/schemas/vpc-lattice.js'; +import type { VpcLatticeEvent } from '../../../src/types/schema.js'; +import { getTestEvent } from '../helpers/utils.js'; -import { VpcLatticeSchema } from '../../../src/schemas/'; -import { TestEvents } from './utils.js'; +describe('Schema: VpcLattice ', () => { + const baseEvent = getTestEvent({ + eventsPath: 'vpc-lattice', + filename: 'base', + }); + + it('parses a VpcLattice event', () => { + // Prepare + const event = structuredClone(baseEvent); + + // Act + const parsedEvent = VpcLatticeSchema.parse(event); -describe('VPC Lattice ', () => { - it('should parse vpc lattice event', () => { - const vpcLatticeEvent = TestEvents.vpcLatticeEvent; - expect(VpcLatticeSchema.parse(vpcLatticeEvent)).toEqual(vpcLatticeEvent); + // Assess + expect(parsedEvent).toEqual(event); }); - it('should parse vpc lattice path trailing slash event', () => { - const vpcLatticeEventPathTrailingSlash = - TestEvents.vpcLatticeEventPathTrailingSlash; - expect(VpcLatticeSchema.parse(vpcLatticeEventPathTrailingSlash)).toEqual( - vpcLatticeEventPathTrailingSlash - ); + + it('throws if event is not a VpcLattice event', () => { + // Prepare + const event = { foo: 'bar' }; + + // Act & Assess + expect(() => VpcLatticeSchema.parse(event)).toThrow(); }); }); diff --git a/packages/parser/tests/unit/schema/vpc-latticev2.test.ts b/packages/parser/tests/unit/schema/vpc-latticev2.test.ts index 5e1b6c7343..9b2d782583 100644 --- a/packages/parser/tests/unit/schema/vpc-latticev2.test.ts +++ b/packages/parser/tests/unit/schema/vpc-latticev2.test.ts @@ -1,23 +1,30 @@ -/** - * Test built in schema - * - * @group unit/parser/schema/ - */ +import { describe, expect, it } from 'vitest'; +import { VpcLatticeV2Schema } from '../../../src/schemas/vpc-latticev2.js'; +import type { VpcLatticeEventV2 } from '../../../src/types/schema.js'; +import { getTestEvent } from '../helpers/utils.js'; -import { VpcLatticeV2Schema } from '../../../src/schemas/'; -import { TestEvents } from './utils.js'; +describe('Schema: VpcLatticeV2 ', () => { + const baseEvent = getTestEvent({ + eventsPath: 'vpc-lattice', + filename: 'base-v2', + }); + + it('parses a VpcLatticeV2 event', () => { + // Prepare + const event = structuredClone(baseEvent); -describe('VpcLatticeV2 ', () => { - it('should parse VpcLatticeV2 event', () => { - const vpcLatticeV2Event = TestEvents.vpcLatticeV2Event; - const parsed = VpcLatticeV2Schema.parse(vpcLatticeV2Event); - expect(parsed).toEqual(vpcLatticeV2Event); + // Act + const parsedEvent = VpcLatticeV2Schema.parse(event); + + // Assess + expect(parsedEvent).toEqual(event); }); - it('should parse VpcLatticeV2PathTrailingSlash event', () => { - const vpcLatticeEventV2PathTrailingSlash = - TestEvents.vpcLatticeEventV2PathTrailingSlash; - const parsed = VpcLatticeV2Schema.parse(vpcLatticeEventV2PathTrailingSlash); - expect(parsed).toEqual(vpcLatticeEventV2PathTrailingSlash); + it('throws if event is not a VpcLatticeV2 event', () => { + // Prepare + const event = { foo: 'bar' }; + + // Act & Assess + expect(() => VpcLatticeV2Schema.parse(event)).toThrow(); }); }); diff --git a/packages/parser/vitest.config.ts b/packages/parser/vitest.config.ts new file mode 100644 index 0000000000..9f1196ef1f --- /dev/null +++ b/packages/parser/vitest.config.ts @@ -0,0 +1,8 @@ +import { defineProject } from 'vitest/config'; + +export default defineProject({ + test: { + environment: 'node', + setupFiles: ['../testing/src/setupEnv.ts'], + }, +}); diff --git a/vitest.config.ts b/vitest.config.ts index 86ff981bfb..a31dac8817 100644 --- a/vitest.config.ts +++ b/vitest.config.ts @@ -21,7 +21,7 @@ export default defineConfig({ 'packages/logger/src/types/**', 'packages/metrics/**', 'packages/parameters/**', - 'packages/parser/**', + 'packages/parser/src/types/**', 'packages/testing/**', 'packages/tracer/**', ],