From cf7165aa0e224251b406c6e833c2d960bf9e1d1e Mon Sep 17 00:00:00 2001 From: harold Date: Sun, 23 Apr 2023 10:33:51 -0400 Subject: [PATCH 1/3] Add failing test for extra route --- packages/microapps-edge-to-origin/src/index.route.spec.ts | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/packages/microapps-edge-to-origin/src/index.route.spec.ts b/packages/microapps-edge-to-origin/src/index.route.spec.ts index 4ac82a31..b657dd8b 100644 --- a/packages/microapps-edge-to-origin/src/index.route.spec.ts +++ b/packages/microapps-edge-to-origin/src/index.route.spec.ts @@ -392,6 +392,11 @@ describe('edge-to-origin - routing - without prefix', () => { const AppName = 'BatDirect'; const SemVer = '1.2.1-beta.1'; const Locale = 'sv'; + // it('should route `direct` app request with *additional* appName to origin for actual appName', async () => { + // theConfig.replaceHostHeader = true; + // const AppName = 'BatDirect'; + // const SemVer = '1.2.1-beta.1'; + // const AppNameExtraRoute = 'BatDirectExtraRoute'; const app = new Application({ AppName, @@ -442,6 +447,7 @@ describe('edge-to-origin - routing - without prefix', () => { querystring: '', clientIp: '1.1.1.1', uri: `/${Locale}/${AppName.toLowerCase()}`, + // uri: `/${AppNameExtraRoute.toLowerCase()}`, origin: { custom: { customHeaders: {}, From 85ddc75155761ffe030de8b1dc450d3f6a12c2ff Mon Sep 17 00:00:00 2001 From: harold Date: Sun, 23 Apr 2023 10:45:28 -0400 Subject: [PATCH 2/3] Partial tests --- .../src/models/application.spec.ts | 96 +++++++++++++++++++ .../src/models/application.ts | 10 ++ .../src/index.route.spec.ts | 1 + 3 files changed, 107 insertions(+) diff --git a/packages/microapps-datalib/src/models/application.spec.ts b/packages/microapps-datalib/src/models/application.spec.ts index 0df01bf5..afa4388b 100644 --- a/packages/microapps-datalib/src/models/application.spec.ts +++ b/packages/microapps-datalib/src/models/application.spec.ts @@ -33,6 +33,9 @@ describe('application records', () => { await application.Save(dbManager); + // + // Single item key + // { const { Item } = await dbManager.ddbDocClient.get({ TableName: TEST_TABLE_NAME, @@ -45,6 +48,9 @@ describe('application records', () => { expect(Item?.DisplayName).toBe('Dog'); } + // + // List key + // { const { Item } = await dbManager.ddbDocClient.get({ TableName: TEST_TABLE_NAME, @@ -59,6 +65,96 @@ describe('application records', () => { } }); + it.only('saving an application with two extra appnames should create four records', async () => { + const application = new Application(); + application.AppName = 'Cat'; + application.DisplayName = 'Dog'; + application.ExtraAppNames = ['Kitty', 'Kitten']; + + await application.Save(dbManager); + + // + // Single item key + // + + // Get the primary app record + { + const { Item } = await dbManager.ddbDocClient.get({ + TableName: TEST_TABLE_NAME, + Key: { PK: 'appname#cat', SK: 'application' }, + }); + expect(Item).toBeDefined(); + expect(Item?.PK).toBe('appname#cat'); + expect(Item?.SK).toBe('application'); + expect(Item?.AppName).toBe('cat'); + expect(Item?.DisplayName).toBe('Dog'); + } + + // Get the secondary app records + { + const { Item } = await dbManager.ddbDocClient.get({ + TableName: TEST_TABLE_NAME, + Key: { PK: 'appname#kitty', SK: 'application' }, + }); + expect(Item).toBeDefined(); + expect(Item?.PK).toBe('appname#kitty'); + expect(Item?.SK).toBe('application'); + expect(Item?.AppName).toBe('cat'); + expect(Item?.DisplayName).toBe('Dog'); + } + { + const { Item } = await dbManager.ddbDocClient.get({ + TableName: TEST_TABLE_NAME, + Key: { PK: 'appname#kitten', SK: 'application' }, + }); + expect(Item).toBeDefined(); + expect(Item?.PK).toBe('appname#kitten'); + expect(Item?.SK).toBe('application'); + expect(Item?.AppName).toBe('cat'); + expect(Item?.DisplayName).toBe('Dog'); + } + + // + // List key + // + { + const { Item } = await dbManager.ddbDocClient.get({ + TableName: TEST_TABLE_NAME, + Key: { PK: 'applications', SK: 'appname#cat' }, + // ProjectionExpression: 'PK,SK,AppName,DisplayName', + }); + expect(Item).toBeDefined(); + expect(Item?.PK).toBe('applications'); + expect(Item?.SK).toBe('appname#cat'); + expect(Item?.AppName).toBe('cat'); + expect(Item?.DisplayName).toBe('Dog'); + } + { + const { Item } = await dbManager.ddbDocClient.get({ + TableName: TEST_TABLE_NAME, + Key: { PK: 'applications', SK: 'appname#keey' }, + // ProjectionExpression: 'PK,SK,AppName,DisplayName', + }); + expect(Item).toBeDefined(); + expect(Item?.PK).toBe('applications'); + expect(Item?.SK).toBe('appname#kitty'); + expect(Item?.AppName).toBe('cat'); + expect(Item?.DisplayName).toBe('Dog'); + } + { + const { Item } = await dbManager.ddbDocClient.get({ + TableName: TEST_TABLE_NAME, + Key: { PK: 'applications', SK: 'appname#kitten' }, + // ProjectionExpression: 'PK,SK,AppName,DisplayName', + }); + expect(Item).toBeDefined(); + expect(Item?.PK).toBe('applications'); + expect(Item?.SK).toBe('appname#kitten'); + expect(Item?.AppName).toBe('cat'); + expect(Item?.DisplayName).toBe('Dog'); + } + }); + it('load function should load records', async () => { let application = new Application(); application.AppName = 'App1'; diff --git a/packages/microapps-datalib/src/models/application.ts b/packages/microapps-datalib/src/models/application.ts index a8dc5eb0..bc628f5a 100644 --- a/packages/microapps-datalib/src/models/application.ts +++ b/packages/microapps-datalib/src/models/application.ts @@ -21,6 +21,7 @@ interface IApplicationRecord { SK: string; AppName: string; DisplayName: string; + ExtraAppNames: string[]; } export class Application implements IApplicationRecord { @@ -96,6 +97,7 @@ export class Application implements IApplicationRecord { private _keyBy: SaveBy; private _appName: string | undefined; private _displayName: string | undefined; + private _extraAppNames: string[] | undefined; public constructor(init?: Partial) { Object.assign(this, init); @@ -108,6 +110,7 @@ export class Application implements IApplicationRecord { SK: this.SK, AppName: this.AppName, DisplayName: this.DisplayName, + ExtraAppNames: this._extraAppNames ?? [], }; } @@ -170,4 +173,11 @@ export class Application implements IApplicationRecord { public set DisplayName(value: string) { this._displayName = value; } + + public get ExtraAppNames(): string[] { + return this._extraAppNames as string[]; + } + public set ExtraAppNames(value: string[]) { + this._extraAppNames = value; + } } diff --git a/packages/microapps-edge-to-origin/src/index.route.spec.ts b/packages/microapps-edge-to-origin/src/index.route.spec.ts index b657dd8b..0c316cd1 100644 --- a/packages/microapps-edge-to-origin/src/index.route.spec.ts +++ b/packages/microapps-edge-to-origin/src/index.route.spec.ts @@ -400,6 +400,7 @@ describe('edge-to-origin - routing - without prefix', () => { const app = new Application({ AppName, + // ExtraAppNames: [AppNameExtraRoute], DisplayName: 'Direct Bat App', }); await app.Save(dbManager); From 87299964152f27fc497ee050935d817d67d9a9b9 Mon Sep 17 00:00:00 2001 From: harold Date: Wed, 26 Apr 2023 08:13:05 -0400 Subject: [PATCH 3/3] Fix test (the one that should fail) --- .../src/index.route.spec.ts | 96 +++++++++++++++++++ 1 file changed, 96 insertions(+) diff --git a/packages/microapps-edge-to-origin/src/index.route.spec.ts b/packages/microapps-edge-to-origin/src/index.route.spec.ts index 0c316cd1..71944b12 100644 --- a/packages/microapps-edge-to-origin/src/index.route.spec.ts +++ b/packages/microapps-edge-to-origin/src/index.route.spec.ts @@ -489,6 +489,102 @@ describe('edge-to-origin - routing - without prefix', () => { expect(requestResponse?.origin?.custom?.domainName).toBe('abc123.lambda-url.us-east-1.on.aws'); }); + it('should route `direct` app request with *additional* appName to origin for actual appName', async () => { + theConfig.replaceHostHeader = true; + const AppName = 'BatDirect'; + const SemVer = '1.2.1-beta.1'; + const AppNameExtraRoute = 'BatDirectExtraRoute'; + + const app = new Application({ + AppName, + ExtraAppNames: [AppNameExtraRoute], + DisplayName: 'Direct Bat App', + }); + await app.Save(dbManager); + + const version = new Version({ + AppName, + SemVer, + Status: 'deployed', + Type: 'lambda-url', + StartupType: 'direct', + URL: 'https://abc123.lambda-url.us-east-1.on.aws/', + }); + await version.Save(dbManager); + + const rules = new Rules({ + AppName, + Version: 0, + RuleSet: { default: { SemVer, AttributeName: '', AttributeValue: '' } }, + }); + await rules.Save(dbManager); + + // Call the handler + // @ts-expect-error no callback + const response = await handler( + { + Records: [ + { + cf: { + config: { + distributionDomainName: 'zyz.cloudfront.net', + distributionId: '123', + eventType: 'origin-request', + requestId: '123', + }, + request: { + headers: { + host: [ + { + key: 'Host', + value: 'zyz.cloudfront.net', + }, + ], + }, + method: 'GET', + querystring: '', + clientIp: '1.1.1.1', + uri: `/${AppNameExtraRoute.toLowerCase()}`, + origin: { + custom: { + customHeaders: {}, + domainName: 'zyz.cloudfront.net', + keepaliveTimeout: 5, + path: '', + port: 443, + protocol: 'https', + readTimeout: 30, + sslProtocols: ['TLSv1.2'], + }, + }, + }, + }, + }, + ], + } as lambda.CloudFrontRequestEvent, + {} as lambda.Context, + ); + + const requestResponse = response as lambda.CloudFrontRequest; + expect(requestResponse).toBeDefined(); + expect(requestResponse).not.toHaveProperty('status'); + expect(requestResponse).not.toHaveProperty('body'); + expect(requestResponse).toHaveProperty('headers'); + expect(requestResponse.headers['x-microapps-appname'][0].key).toBe('X-MicroApps-AppName'); + expect(requestResponse.headers['x-microapps-appname'][0].value).toBe(AppName.toLowerCase()); + expect(requestResponse.headers).toHaveProperty('x-microapps-semver'); + expect(requestResponse.headers['x-microapps-semver'][0].key).toBe('X-MicroApps-SemVer'); + expect(requestResponse.headers['x-microapps-semver'][0].value).toBe(SemVer); + expect(requestResponse.headers).toHaveProperty('host'); + expect(requestResponse.headers.host).toHaveLength(1); + expect(requestResponse.headers.host[0].key).toBe('Host'); + expect(requestResponse.headers.host[0].value).toBe('abc123.lambda-url.us-east-1.on.aws'); + expect(requestResponse).toHaveProperty('origin'); + expect(requestResponse.origin).toHaveProperty('custom'); + expect(requestResponse?.origin?.custom).toHaveProperty('domainName'); + expect(requestResponse?.origin?.custom?.domainName).toBe('abc123.lambda-url.us-east-1.on.aws'); + }); + describe('/_next/data/ requests with no basePath', () => { const testCases = [ {