206 lines
7.3 KiB
TypeScript
206 lines
7.3 KiB
TypeScript
import { handler } from '../../src/default-handler';
|
|
import { createCloudFrontEvent } from '../test-utils';
|
|
import {
|
|
CloudFrontRequest,
|
|
CloudFrontResultResponse,
|
|
CloudFrontHeaders,
|
|
CloudFrontOrigin,
|
|
} from 'aws-lambda';
|
|
|
|
jest.mock('../../src/manifest.json', () => require('./default-build-manifest.json'), {
|
|
virtual: true,
|
|
});
|
|
|
|
jest.mock('../../src/prerender-manifest.json', () => require('./prerender-manifest.json'), {
|
|
virtual: true,
|
|
});
|
|
|
|
const mockPageRequire = (mockPagePath: string): void => {
|
|
jest.mock(
|
|
`../../src/${mockPagePath}`,
|
|
() => require(`../shared-fixtures/built-artifact/${mockPagePath}`),
|
|
{
|
|
virtual: true,
|
|
}
|
|
);
|
|
};
|
|
|
|
describe('Lambda@Edge', () => {
|
|
describe('Routing', () => {
|
|
describe('HTML pages routing', () => {
|
|
it.each`
|
|
path | expectedPage
|
|
${'/'} | ${'/index.html'}
|
|
${'/index'} | ${'/index.html'}
|
|
${'/terms'} | ${'/terms.html'}
|
|
${'/users/batman'} | ${'/users/[user].html'}
|
|
${'/users/test/catch/all'} | ${'/users/[...user].html'}
|
|
${'/john/123'} | ${'/[username]/[id].html'}
|
|
${'/tests/prerender-manifest/example-static-page'} | ${'/tests/prerender-manifest/example-static-page.html'}
|
|
`('serves page $expectedPage from S3 for path $path', async ({ path, expectedPage }) => {
|
|
const event = createCloudFrontEvent({
|
|
uri: path,
|
|
host: 'mydistribution.cloudfront.net',
|
|
});
|
|
|
|
const result = await handler(event);
|
|
|
|
const request = result as CloudFrontRequest;
|
|
|
|
expect(request.origin).toEqual({
|
|
s3: {
|
|
authMethod: 'origin-access-identity',
|
|
domainName: 'my-bucket.s3.amazonaws.com',
|
|
path: '/static-pages',
|
|
region: 'us-east-1',
|
|
},
|
|
});
|
|
expect(request.uri).toEqual(expectedPage);
|
|
expect(request.headers.host[0].key).toEqual('host');
|
|
expect(request.headers.host[0].value).toEqual('my-bucket.s3.amazonaws.com');
|
|
});
|
|
});
|
|
|
|
describe('Public files routing', () => {
|
|
it('serves public file from S3 /public folder', async () => {
|
|
const event = createCloudFrontEvent({
|
|
uri: '/manifest.json',
|
|
host: 'mydistribution.cloudfront.net',
|
|
});
|
|
|
|
const result = await handler(event);
|
|
|
|
const request = result as CloudFrontRequest;
|
|
|
|
expect(request.origin).toEqual({
|
|
s3: {
|
|
authMethod: 'origin-access-identity',
|
|
domainName: 'my-bucket.s3.amazonaws.com',
|
|
path: '/public',
|
|
region: 'us-east-1',
|
|
},
|
|
});
|
|
expect(request.uri).toEqual('/manifest.json');
|
|
});
|
|
});
|
|
|
|
describe('SSR pages routing', () => {
|
|
it.each`
|
|
path | expectedPage
|
|
${'/abc'} | ${'pages/[root].js'}
|
|
${'/blog/foo'} | ${'pages/blog/[id].js'}
|
|
${'/customers'} | ${'pages/customers/index.js'}
|
|
${'/customers/superman'} | ${'pages/customers/[customer].js'}
|
|
${'/customers/superman/howtofly'} | ${'pages/customers/[customer]/[post].js'}
|
|
${'/customers/superman/profile'} | ${'pages/customers/[customer]/profile.js'}
|
|
${'/customers/test/catch/all'} | ${'pages/customers/[...catchAll].js'}
|
|
`('renders page $expectedPage for path $path', async ({ path, expectedPage }) => {
|
|
const event = createCloudFrontEvent({
|
|
uri: path,
|
|
host: 'mydistribution.cloudfront.net',
|
|
});
|
|
|
|
mockPageRequire(expectedPage);
|
|
|
|
const response = await handler(event);
|
|
|
|
const cfResponse = response as CloudFrontResultResponse;
|
|
const decodedBody = new Buffer(cfResponse.body as string, 'base64').toString('utf8');
|
|
|
|
expect(decodedBody).toEqual(expectedPage);
|
|
expect(cfResponse.status).toEqual(200);
|
|
});
|
|
});
|
|
|
|
describe('Data Requests', () => {
|
|
it.each`
|
|
path | expectedPage
|
|
${'/_next/data/build-id/customers.json'} | ${'pages/customers/index.js'}
|
|
${'/_next/data/build-id/customers/superman.json'} | ${'pages/customers/[customer].js'}
|
|
${'/_next/data/build-id/customers/superman/profile.json'} | ${'pages/customers/[customer]/profile.js'}
|
|
`('serves json data for path $path', async ({ path, expectedPage }) => {
|
|
const event = createCloudFrontEvent({
|
|
uri: path,
|
|
host: 'mydistribution.cloudfront.net',
|
|
});
|
|
|
|
mockPageRequire(expectedPage);
|
|
|
|
const result = await handler(event);
|
|
|
|
const response = result as CloudFrontResultResponse;
|
|
const decodedBody = new Buffer(response.body as string, 'base64').toString('utf8');
|
|
|
|
const headers = response.headers as CloudFrontHeaders;
|
|
expect(headers['content-type'][0].value).toEqual('application/json');
|
|
expect(JSON.parse(decodedBody)).toEqual({
|
|
page: expectedPage,
|
|
});
|
|
expect(response.status).toEqual(200);
|
|
});
|
|
});
|
|
|
|
it('uses default s3 endpoint when bucket region is us-east-1', async () => {
|
|
const event = createCloudFrontEvent({
|
|
uri: '/terms',
|
|
host: 'mydistribution.cloudfront.net',
|
|
s3Region: 'us-east-1',
|
|
});
|
|
|
|
const result = await handler(event);
|
|
|
|
const request = result as CloudFrontRequest;
|
|
const origin = request.origin as CloudFrontOrigin;
|
|
|
|
expect(origin.s3).toEqual(
|
|
expect.objectContaining({
|
|
domainName: 'my-bucket.s3.amazonaws.com',
|
|
})
|
|
);
|
|
expect(request.headers.host[0].key).toEqual('host');
|
|
expect(request.headers.host[0].value).toEqual('my-bucket.s3.amazonaws.com');
|
|
});
|
|
|
|
it('uses regional endpoint when bucket region is not us-east-1', async () => {
|
|
const event = createCloudFrontEvent({
|
|
uri: '/terms',
|
|
host: 'mydistribution.cloudfront.net',
|
|
s3DomainName: 'my-bucket.s3.amazonaws.com',
|
|
s3Region: 'eu-west-1',
|
|
});
|
|
|
|
const result = await handler(event);
|
|
|
|
const request = result as CloudFrontRequest;
|
|
const origin = request.origin as CloudFrontOrigin;
|
|
|
|
expect(origin).toEqual({
|
|
s3: {
|
|
authMethod: 'origin-access-identity',
|
|
domainName: 'my-bucket.s3.eu-west-1.amazonaws.com',
|
|
path: '/static-pages',
|
|
region: 'eu-west-1',
|
|
},
|
|
});
|
|
expect(request.uri).toEqual('/terms.html');
|
|
expect(request.headers.host[0].key).toEqual('host');
|
|
expect(request.headers.host[0].value).toEqual('my-bucket.s3.eu-west-1.amazonaws.com');
|
|
});
|
|
});
|
|
|
|
it("renders 404 page if request path can't be matched to any page / api routes", async () => {
|
|
const event = createCloudFrontEvent({
|
|
uri: '/page/does/not/exist',
|
|
host: 'mydistribution.cloudfront.net',
|
|
});
|
|
|
|
mockPageRequire('pages/_error.js');
|
|
|
|
const response = (await handler(event)) as CloudFrontResultResponse;
|
|
const body = response.body as string;
|
|
const decodedBody = new Buffer(body, 'base64').toString('utf8');
|
|
|
|
expect(decodedBody).toEqual('pages/_error.js');
|
|
expect(response.status).toEqual(200);
|
|
});
|
|
});
|