Skip to content
This repository has been archived by the owner on May 3, 2024. It is now read-only.

Commit

Permalink
feat(pwa/web-manifest): add middleware & config support
Browse files Browse the repository at this point in the history
  • Loading branch information
Francois-Esquire authored May 14, 2020
1 parent 0139c6c commit 9077f17
Show file tree
Hide file tree
Showing 15 changed files with 639 additions and 89 deletions.
112 changes: 60 additions & 52 deletions __tests__/integration/one-app.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -828,54 +828,62 @@ describe('Tests that require Docker setup', () => {
});

describe('progressive web app', () => {
let agent;
let scriptUrl;
const scriptUrl = `${appAtTestUrls.fetchUrl}/_/pwa/service-worker.js`;
const webManifestUrl = `${appAtTestUrls.fetchUrl}/_/pwa/manifest.webmanifest`;

beforeAll(async () => {
const https = require('https');
// using this to avoid erroring from a self signed certificate
agent = new https.Agent({
rejectUnauthorized: false,
const fetchServiceWorker = () => fetch(scriptUrl, defaultFetchOptions);
const fetchWebManifest = () => fetch(webManifestUrl, defaultFetchOptions);
const loadInitialRoot = async () => {
await addModuleToModuleMap({
moduleName: 'frank-lloyd-root',
version: '0.0.0',
});
// wait for change to be picked up
await waitFor(5000);
};
const loadPWARoot = async () => {
await addModuleToModuleMap({
moduleName: 'frank-lloyd-root',
version: '0.0.3',
});
// wait for change to be picked up
await waitFor(5000);
};

scriptUrl = [appAtTestUrls.fetchUrl, '/_/pwa/service-worker.js'].join('');
afterAll(() => {
writeModuleMap(originalModuleMap);
});

test('does not load PWA resources from server by default', async () => {
const serviceWorkerResponse = await fetch(scriptUrl, { agent });
describe('default pwa state', () => {
test('does not load PWA resources from server by default', async () => {
expect.assertions(2);

expect(serviceWorkerResponse.status).toBe(404);
});
const serviceWorkerResponse = await fetchServiceWorker();
const webManifestResponse = await fetchWebManifest();

describe('progressive web app enabled', () => {
beforeAll(async () => {
await Promise.all([
addModuleToModuleMap({
moduleName: 'frank-lloyd-root',
version: '0.0.3',
}),
// for data fetching
addModuleToModuleMap({
moduleName: 'needy-frank',
version: '0.0.1',
}),
]);
// wait for change to be picked up
await waitFor(5000);
expect(serviceWorkerResponse.status).toBe(404);
expect(webManifestResponse.status).toBe(404);
});
});

afterAll(async () => {
writeModuleMap(originalModuleMap);
});
describe('progressive web app enabled', () => {
// we load in the pwa enabled frank-lloyd-root
beforeAll(loadPWARoot);

test('loads PWA resources from server ', async () => {
expect.assertions(3);
expect.assertions(6);

const serviceWorkerResponse = await fetch(scriptUrl, { agent });
const serviceWorkerResponse = await fetchServiceWorker();

expect(serviceWorkerResponse.status).toBe(200);
expect(serviceWorkerResponse.headers.get('cache-control')).toEqual('no-store, no-cache');
expect(serviceWorkerResponse.headers.get('service-worker-allowed')).toEqual('/');

const webManifestResponse = await fetchWebManifest();

expect(webManifestResponse.status).toBe(200);
expect(webManifestResponse.headers.get('cache-control')).toBeDefined();
expect(webManifestResponse.headers.get('content-type')).toEqual('application/manifest+json');
});

test('service worker has a valid registration', async () => {
Expand All @@ -900,33 +908,33 @@ describe('Tests that require Docker setup', () => {
updateViaCache: 'none',
});
});
});

describe('progressive web app disabled', () => {
beforeAll(async () => {
await addModuleToModuleMap({
moduleName: 'frank-lloyd-root',
version: '0.0.0',
});
// wait for change to be picked up
await waitFor(5000);
});
describe('progressive web app disabled', () => {
// we load back up to frank-lloyd-root@0.0.0 to make sure the system is off
beforeAll(loadInitialRoot);

afterAll(async () => {
writeModuleMap(originalModuleMap);
});
test('does not load PWA resources from server after shutdown', async () => {
expect.assertions(2);

test('service worker is no longer registered and removed with root module change', async () => {
expect.assertions(1);
const serviceWorkerResponse = await fetchServiceWorker();
const webManifestResponse = await fetchWebManifest();

await browser.url(`${appAtTestUrls.browserUrl}/success`);
expect(serviceWorkerResponse.status).toBe(404);
expect(webManifestResponse.status).toBe(404);
});

// eslint-disable-next-line prefer-arrow-callback
const result = await browser.executeAsync(function getRegistration(done) {
navigator.serviceWorker.getRegistration().then(done);
});
test('service worker is no longer registered and removed with root module change', async () => {
expect.assertions(1);

await browser.url(`${appAtTestUrls.browserUrl}/success`);

expect(result).toBe(null);
// eslint-disable-next-line prefer-arrow-callback
const result = await browser.executeAsync(function getRegistration(done) {
navigator.serviceWorker.getRegistration().then(done);
});

expect(result).toBe(null);
});
});
});
Expand Down
89 changes: 85 additions & 4 deletions __tests__/server/middleware/pwa/config.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,14 @@
*/

import {
getWebAppManifestConfig,
getServerPWAConfig,
getClientPWAConfig,
configurePWA,
} from '../../../../src/server/middleware/pwa/config';

jest.mock('fs', () => ({
existsSync: () => false,
readFileSync: (filePath) => Buffer.from(filePath.endsWith('noop.js') ? '[service-worker-noop-script]' : '[service-worker-script]'),
}));

Expand All @@ -34,6 +36,10 @@ describe('pwa configuration', () => {
});

test('getters return default state', () => {
expect(getWebAppManifestConfig()).toMatchObject({
webManifest: null,
webManifestEnabled: false,
});
expect(getServerPWAConfig()).toMatchObject({
serviceWorker: false,
serviceWorkerRecoveryMode: false,
Expand All @@ -43,12 +49,13 @@ describe('pwa configuration', () => {
expect(getClientPWAConfig()).toMatchObject({
serviceWorker: false,
serviceWorkerRecoveryMode: false,
serviceWorkerScriptUrl: false,
serviceWorkerScope: null,
serviceWorkerScriptUrl: false,
webManifestUrl: false,
});
});

describe('configuration', () => {
describe('service worker configuration', () => {
test('enabling the service worker with minimum config', () => {
configurePWA({ serviceWorker: true });

Expand All @@ -64,6 +71,7 @@ describe('pwa configuration', () => {
serviceWorkerRecoveryMode: false,
serviceWorkerScope: '/',
serviceWorkerScriptUrl: '/_/pwa/service-worker.js',
webManifestUrl: false,
});
});

Expand All @@ -82,6 +90,7 @@ describe('pwa configuration', () => {
serviceWorkerRecoveryMode: true,
serviceWorkerScope: '/',
serviceWorkerScriptUrl: '/_/pwa/service-worker.js',
webManifestUrl: false,
});
});

Expand All @@ -100,6 +109,7 @@ describe('pwa configuration', () => {
serviceWorkerRecoveryMode: true,
serviceWorkerScope: '/',
serviceWorkerScriptUrl: '/_/pwa/service-worker.js',
webManifestUrl: false,
});
});

Expand All @@ -117,8 +127,9 @@ describe('pwa configuration', () => {
expect(getClientPWAConfig()).toMatchObject({
serviceWorker: false,
serviceWorkerRecoveryMode: false,
serviceWorkerScriptUrl: false,
serviceWorkerScope: null,
serviceWorkerScriptUrl: false,
webManifestUrl: false,
});

process.env.ONE_SERVICE_WORKER = true;
Expand All @@ -137,8 +148,9 @@ describe('pwa configuration', () => {
expect(getClientPWAConfig()).toMatchObject({
serviceWorker: false,
serviceWorkerRecoveryMode: false,
serviceWorkerScriptUrl: false,
serviceWorkerScope: null,
serviceWorkerScriptUrl: false,
webManifestUrl: false,
});
});

Expand All @@ -147,4 +159,73 @@ describe('pwa configuration', () => {
expect(configurePWA()).toMatchObject({ serviceWorker: false });
});
});

describe('web app manifest configuration', () => {
test('enabling the web manifest', () => {
configurePWA({
serviceWorker: true,
webManifest: {
name: 'One App Test',
},
});

expect(getServerPWAConfig()).toMatchObject({
webManifest: true,
serviceWorker: true,
serviceWorkerRecoveryMode: false,
serviceWorkerScope: '/',
});
expect(getClientPWAConfig()).toMatchObject({
serviceWorker: true,
serviceWorkerRecoveryMode: false,
serviceWorkerScope: '/',
serviceWorkerScriptUrl: '/_/pwa/service-worker.js',
webManifestUrl: '/_/pwa/manifest.webmanifest',
});
});

test('using a function for the web manifest', () => {
configurePWA({
serviceWorker: true,
webManifest: () => ({
name: 'One App Test',
}),
});

expect(getServerPWAConfig()).toMatchObject({
webManifest: true,
serviceWorker: true,
serviceWorkerRecoveryMode: false,
serviceWorkerScope: '/',
});
expect(getClientPWAConfig()).toMatchObject({
serviceWorker: true,
serviceWorkerRecoveryMode: false,
serviceWorkerScope: '/',
serviceWorkerScriptUrl: '/_/pwa/service-worker.js',
webManifestUrl: '/_/pwa/manifest.webmanifest',
});
});

test('opting out of the web manifest', () => {
configurePWA({
serviceWorker: true,
webManifest: null,
});

expect(getServerPWAConfig()).toMatchObject({
webManifest: false,
serviceWorker: true,
serviceWorkerRecoveryMode: false,
serviceWorkerScope: '/',
});
expect(getClientPWAConfig()).toMatchObject({
serviceWorker: true,
serviceWorkerRecoveryMode: false,
serviceWorkerScope: '/',
serviceWorkerScriptUrl: '/_/pwa/service-worker.js',
webManifestUrl: false,
});
});
});
});
Loading

0 comments on commit 9077f17

Please sign in to comment.