From 37a154e4e6d004904152b12d3dde42863866a806 Mon Sep 17 00:00:00 2001 From: George Kalpakas Date: Wed, 20 Mar 2019 23:29:14 +0200 Subject: [PATCH] test(service-worker): do not create testing artifacts on environments that do not support SW (#27080) The tests will not be run anyway, so the artifacts are never used and there might be errors if creating the testing artifacts relies on APIs that are not available in that environment (e.g. `URL`). PR Close #27080 --- .../service-worker/test/integration_spec.ts | 92 ++-- .../service-worker/worker/test/data_spec.ts | 200 +++++---- .../service-worker/worker/test/happy_spec.ts | 395 +++++++++--------- .../service-worker/worker/test/idle_spec.ts | 3 +- .../worker/test/prefetch_spec.ts | 30 +- 5 files changed, 362 insertions(+), 358 deletions(-) diff --git a/packages/service-worker/test/integration_spec.ts b/packages/service-worker/test/integration_spec.ts index 44d70265f8..09e7a2f172 100644 --- a/packages/service-worker/test/integration_spec.ts +++ b/packages/service-worker/test/integration_spec.ts @@ -21,56 +21,58 @@ import {take} from 'rxjs/operators'; import {async_beforeEach, async_fit, async_it} from './async'; -const dist = new MockFileSystemBuilder().addFile('/only.txt', 'this is only').build(); - -const distUpdate = new MockFileSystemBuilder().addFile('/only.txt', 'this is only v2').build(); - -function obsToSinglePromise(obs: Observable): Promise { - return obs.pipe(take(1)).toPromise(); -} - -const manifest: Manifest = { - configVersion: 1, - timestamp: 1234567890123, - appData: {version: '1'}, - index: '/only.txt', - assetGroups: [{ - name: 'assets', - installMode: 'prefetch', - updateMode: 'prefetch', - urls: ['/only.txt'], - patterns: [], - }], - navigationUrls: [], - hashTable: tmpHashTableForFs(dist), -}; - -const manifestUpdate: Manifest = { - configVersion: 1, - timestamp: 1234567890123, - appData: {version: '2'}, - index: '/only.txt', - assetGroups: [{ - name: 'assets', - installMode: 'prefetch', - updateMode: 'prefetch', - urls: ['/only.txt'], - patterns: [], - }], - navigationUrls: [], - hashTable: tmpHashTableForFs(distUpdate), -}; - -const server = new MockServerStateBuilder().withStaticFiles(dist).withManifest(manifest).build(); - -const serverUpdate = - new MockServerStateBuilder().withStaticFiles(distUpdate).withManifest(manifestUpdate).build(); - (function() { // Skip environments that don't support the minimum APIs needed to run the SW tests. if (!SwTestHarness.envIsSupported()) { return; } + + const dist = new MockFileSystemBuilder().addFile('/only.txt', 'this is only').build(); + + const distUpdate = new MockFileSystemBuilder().addFile('/only.txt', 'this is only v2').build(); + + function obsToSinglePromise(obs: Observable): Promise { + return obs.pipe(take(1)).toPromise(); + } + + const manifest: Manifest = { + configVersion: 1, + timestamp: 1234567890123, + appData: {version: '1'}, + index: '/only.txt', + assetGroups: [{ + name: 'assets', + installMode: 'prefetch', + updateMode: 'prefetch', + urls: ['/only.txt'], + patterns: [], + }], + navigationUrls: [], + hashTable: tmpHashTableForFs(dist), + }; + + const manifestUpdate: Manifest = { + configVersion: 1, + timestamp: 1234567890123, + appData: {version: '2'}, + index: '/only.txt', + assetGroups: [{ + name: 'assets', + installMode: 'prefetch', + updateMode: 'prefetch', + urls: ['/only.txt'], + patterns: [], + }], + navigationUrls: [], + hashTable: tmpHashTableForFs(distUpdate), + }; + + const server = new MockServerStateBuilder().withStaticFiles(dist).withManifest(manifest).build(); + + const serverUpdate = + new MockServerStateBuilder().withStaticFiles(distUpdate).withManifest(manifestUpdate).build(); + + describe('ngsw + companion lib', () => { let mock: MockServiceWorkerContainer; let comm: NgswCommChannel; diff --git a/packages/service-worker/worker/test/data_spec.ts b/packages/service-worker/worker/test/data_spec.ts index 1474dd12c5..80fdee082e 100644 --- a/packages/service-worker/worker/test/data_spec.ts +++ b/packages/service-worker/worker/test/data_spec.ts @@ -15,112 +15,110 @@ import {SwTestHarness, SwTestHarnessBuilder} from '../testing/scope'; import {async_beforeEach, async_fit, async_it} from './async'; -const dist = new MockFileSystemBuilder() - .addFile('/foo.txt', 'this is foo') - .addFile('/bar.txt', 'this is bar') - .addFile('/api/test', 'version 1') - .addFile('/api/a', 'version A') - .addFile('/api/b', 'version B') - .addFile('/api/c', 'version C') - .addFile('/api/d', 'version D') - .addFile('/api/e', 'version E') - .addFile('/fresh/data', 'this is fresh data') - .addFile('/refresh/data', 'this is some data') - .build(); - - -const distUpdate = new MockFileSystemBuilder() - .addFile('/foo.txt', 'this is foo v2') - .addFile('/bar.txt', 'this is bar') - .addFile('/api/test', 'version 2') - .addFile('/fresh/data', 'this is fresher data') - .addFile('/refresh/data', 'this is refreshed data') - .build(); - -const manifest: Manifest = { - configVersion: 1, - timestamp: 1234567890123, - index: '/index.html', - assetGroups: [ - { - name: 'assets', - installMode: 'prefetch', - updateMode: 'prefetch', - urls: [ - '/foo.txt', - '/bar.txt', - ], - patterns: [], - }, - ], - dataGroups: [ - { - name: 'testPerf', - maxSize: 3, - strategy: 'performance', - patterns: ['^/api/.*$'], - timeoutMs: 1000, - maxAge: 5000, - version: 1, - }, - { - name: 'testRefresh', - maxSize: 3, - strategy: 'performance', - patterns: ['^/refresh/.*$'], - timeoutMs: 1000, - refreshAheadMs: 1000, - maxAge: 5000, - version: 1, - }, - { - name: 'testFresh', - maxSize: 3, - strategy: 'freshness', - patterns: ['^/fresh/.*$'], - timeoutMs: 1000, - maxAge: 5000, - version: 1, - }, - ], - navigationUrls: [], - hashTable: tmpHashTableForFs(dist), -}; - -const seqIncreasedManifest: Manifest = { - ...manifest, - dataGroups: [ - { - ...manifest.dataGroups ![0], - version: 2, - }, - manifest.dataGroups ![1], - manifest.dataGroups ![2], - ], -}; - - -const server = new MockServerStateBuilder().withStaticFiles(dist).withManifest(manifest).build(); - -const serverUpdate = - new MockServerStateBuilder().withStaticFiles(distUpdate).withManifest(manifest).build(); - -const serverSeqUpdate = new MockServerStateBuilder() - .withStaticFiles(distUpdate) - .withManifest(seqIncreasedManifest) - .build(); - -const scope = new SwTestHarnessBuilder().withServerState(server).build(); - -function asyncWrap(fn: () => Promise): (done: DoneFn) => void { - return (done: DoneFn) => { fn().then(() => done(), err => done.fail(err)); }; -} - (function() { // Skip environments that don't support the minimum APIs needed to run the SW tests. if (!SwTestHarness.envIsSupported()) { return; } + + const dist = new MockFileSystemBuilder() + .addFile('/foo.txt', 'this is foo') + .addFile('/bar.txt', 'this is bar') + .addFile('/api/test', 'version 1') + .addFile('/api/a', 'version A') + .addFile('/api/b', 'version B') + .addFile('/api/c', 'version C') + .addFile('/api/d', 'version D') + .addFile('/api/e', 'version E') + .addFile('/fresh/data', 'this is fresh data') + .addFile('/refresh/data', 'this is some data') + .build(); + + + const distUpdate = new MockFileSystemBuilder() + .addFile('/foo.txt', 'this is foo v2') + .addFile('/bar.txt', 'this is bar') + .addFile('/api/test', 'version 2') + .addFile('/fresh/data', 'this is fresher data') + .addFile('/refresh/data', 'this is refreshed data') + .build(); + + const manifest: Manifest = { + configVersion: 1, + timestamp: 1234567890123, + index: '/index.html', + assetGroups: [ + { + name: 'assets', + installMode: 'prefetch', + updateMode: 'prefetch', + urls: [ + '/foo.txt', + '/bar.txt', + ], + patterns: [], + }, + ], + dataGroups: [ + { + name: 'testPerf', + maxSize: 3, + strategy: 'performance', + patterns: ['^/api/.*$'], + timeoutMs: 1000, + maxAge: 5000, + version: 1, + }, + { + name: 'testRefresh', + maxSize: 3, + strategy: 'performance', + patterns: ['^/refresh/.*$'], + timeoutMs: 1000, + refreshAheadMs: 1000, + maxAge: 5000, + version: 1, + }, + { + name: 'testFresh', + maxSize: 3, + strategy: 'freshness', + patterns: ['^/fresh/.*$'], + timeoutMs: 1000, + maxAge: 5000, + version: 1, + }, + ], + navigationUrls: [], + hashTable: tmpHashTableForFs(dist), + }; + + const seqIncreasedManifest: Manifest = { + ...manifest, + dataGroups: [ + { + ...manifest.dataGroups ![0], + version: 2, + }, + manifest.dataGroups ![1], + manifest.dataGroups ![2], + ], + }; + + + const server = new MockServerStateBuilder().withStaticFiles(dist).withManifest(manifest).build(); + + const serverUpdate = + new MockServerStateBuilder().withStaticFiles(distUpdate).withManifest(manifest).build(); + + const serverSeqUpdate = new MockServerStateBuilder() + .withStaticFiles(distUpdate) + .withManifest(seqIncreasedManifest) + .build(); + + const scope = new SwTestHarnessBuilder().withServerState(server).build(); + + describe('data cache', () => { let scope: SwTestHarness; let driver: Driver; diff --git a/packages/service-worker/worker/test/happy_spec.ts b/packages/service-worker/worker/test/happy_spec.ts index a4c744b109..59ce6d6d1f 100644 --- a/packages/service-worker/worker/test/happy_spec.ts +++ b/packages/service-worker/worker/test/happy_spec.ts @@ -18,207 +18,210 @@ import {SwTestHarness, SwTestHarnessBuilder} from '../testing/scope'; import {async_beforeEach, async_fit, async_it} from './async'; -const dist = - new MockFileSystemBuilder() - .addFile('/foo.txt', 'this is foo') - .addFile('/bar.txt', 'this is bar') - .addFile('/baz.txt', 'this is baz') - .addFile('/qux.txt', 'this is qux') - .addFile('/quux.txt', 'this is quux') - .addFile('/quuux.txt', 'this is quuux') - .addFile('/lazy/unchanged1.txt', 'this is unchanged (1)') - .addFile('/lazy/unchanged2.txt', 'this is unchanged (2)') - .addUnhashedFile('/unhashed/a.txt', 'this is unhashed', {'Cache-Control': 'max-age=10'}) - .addUnhashedFile('/unhashed/b.txt', 'this is unhashed b', {'Cache-Control': 'no-cache'}) - .build(); - -const distUpdate = - new MockFileSystemBuilder() - .addFile('/foo.txt', 'this is foo v2') - .addFile('/bar.txt', 'this is bar') - .addFile('/baz.txt', 'this is baz v2') - .addFile('/qux.txt', 'this is qux v2') - .addFile('/quux.txt', 'this is quux v2') - .addFile('/quuux.txt', 'this is quuux v2') - .addFile('/lazy/unchanged1.txt', 'this is unchanged (1)') - .addFile('/lazy/unchanged2.txt', 'this is unchanged (2)') - .addUnhashedFile('/unhashed/a.txt', 'this is unhashed v2', {'Cache-Control': 'max-age=10'}) - .addUnhashedFile('/ignored/file1', 'this is not handled by the SW') - .addUnhashedFile('/ignored/dir/file2', 'this is not handled by the SW either') - .build(); - -const brokenFs = new MockFileSystemBuilder().addFile('/foo.txt', 'this is foo').build(); - -const brokenManifest: Manifest = { - configVersion: 1, - timestamp: 1234567890123, - index: '/foo.txt', - assetGroups: [{ - name: 'assets', - installMode: 'prefetch', - updateMode: 'prefetch', - urls: [ - '/foo.txt', - ], - patterns: [], - }], - dataGroups: [], - navigationUrls: processNavigationUrls(''), - hashTable: tmpHashTableForFs(brokenFs, {'/foo.txt': true}), -}; - -// Manifest without navigation urls to test backward compatibility with -// versions < 6.0.0. -export interface ManifestV5 { - configVersion: number; - appData?: {[key: string]: string}; - index: string; - assetGroups?: AssetGroupConfig[]; - dataGroups?: DataGroupConfig[]; - hashTable: {[url: string]: string}; -} - -// To simulate versions < 6.0.0 -const manifestOld: ManifestV5 = { - configVersion: 1, - index: '/foo.txt', - hashTable: tmpHashTableForFs(dist), -}; - -const manifest: Manifest = { - configVersion: 1, - timestamp: 1234567890123, - appData: { - version: 'original', - }, - index: '/foo.txt', - assetGroups: [ - { - name: 'assets', - installMode: 'prefetch', - updateMode: 'prefetch', - urls: [ - '/foo.txt', - '/bar.txt', - '/redirected.txt', - ], - patterns: [ - '/unhashed/.*', - ], - }, - { - name: 'other', - installMode: 'lazy', - updateMode: 'lazy', - urls: [ - '/baz.txt', - '/qux.txt', - ], - patterns: [], - }, - { - name: 'lazy_prefetch', - installMode: 'lazy', - updateMode: 'prefetch', - urls: [ - '/quux.txt', - '/quuux.txt', - '/lazy/unchanged1.txt', - '/lazy/unchanged2.txt', - ], - patterns: [], - } - ], - navigationUrls: processNavigationUrls(''), - hashTable: tmpHashTableForFs(dist), -}; - -const manifestUpdate: Manifest = { - configVersion: 1, - timestamp: 1234567890123, - appData: { - version: 'update', - }, - index: '/foo.txt', - assetGroups: [ - { - name: 'assets', - installMode: 'prefetch', - updateMode: 'prefetch', - urls: [ - '/foo.txt', - '/bar.txt', - '/redirected.txt', - ], - patterns: [ - '/unhashed/.*', - ], - }, - { - name: 'other', - installMode: 'lazy', - updateMode: 'lazy', - urls: [ - '/baz.txt', - '/qux.txt', - ], - patterns: [], - }, - { - name: 'lazy_prefetch', - installMode: 'lazy', - updateMode: 'prefetch', - urls: [ - '/quux.txt', - '/quuux.txt', - '/lazy/unchanged1.txt', - '/lazy/unchanged2.txt', - ], - patterns: [], - } - ], - navigationUrls: processNavigationUrls( - '', - [ - '/**/file1', - '/**/file2', - '!/ignored/file1', - '!/ignored/dir/**', - ]), - hashTable: tmpHashTableForFs(distUpdate), -}; - -const serverBuilderBase = - new MockServerStateBuilder() - .withStaticFiles(dist) - .withRedirect('/redirected.txt', '/redirect-target.txt', 'this was a redirect') - .withError('/error.txt'); - -const server = serverBuilderBase.withManifest(manifest).build(); - -const serverRollback = - serverBuilderBase.withManifest({...manifest, timestamp: manifest.timestamp + 1}).build(); - -const serverUpdate = - new MockServerStateBuilder() - .withStaticFiles(distUpdate) - .withManifest(manifestUpdate) - .withRedirect('/redirected.txt', '/redirect-target.txt', 'this was a redirect') - .build(); - -const brokenServer = - new MockServerStateBuilder().withStaticFiles(brokenFs).withManifest(brokenManifest).build(); - -const server404 = new MockServerStateBuilder().withStaticFiles(dist).build(); - -const manifestHash = sha1(JSON.stringify(manifest)); -const manifestUpdateHash = sha1(JSON.stringify(manifestUpdate)); - (function() { // Skip environments that don't support the minimum APIs needed to run the SW tests. if (!SwTestHarness.envIsSupported()) { return; } + + const dist = + new MockFileSystemBuilder() + .addFile('/foo.txt', 'this is foo') + .addFile('/bar.txt', 'this is bar') + .addFile('/baz.txt', 'this is baz') + .addFile('/qux.txt', 'this is qux') + .addFile('/quux.txt', 'this is quux') + .addFile('/quuux.txt', 'this is quuux') + .addFile('/lazy/unchanged1.txt', 'this is unchanged (1)') + .addFile('/lazy/unchanged2.txt', 'this is unchanged (2)') + .addUnhashedFile('/unhashed/a.txt', 'this is unhashed', {'Cache-Control': 'max-age=10'}) + .addUnhashedFile('/unhashed/b.txt', 'this is unhashed b', {'Cache-Control': 'no-cache'}) + .build(); + + const distUpdate = + new MockFileSystemBuilder() + .addFile('/foo.txt', 'this is foo v2') + .addFile('/bar.txt', 'this is bar') + .addFile('/baz.txt', 'this is baz v2') + .addFile('/qux.txt', 'this is qux v2') + .addFile('/quux.txt', 'this is quux v2') + .addFile('/quuux.txt', 'this is quuux v2') + .addFile('/lazy/unchanged1.txt', 'this is unchanged (1)') + .addFile('/lazy/unchanged2.txt', 'this is unchanged (2)') + .addUnhashedFile( + '/unhashed/a.txt', 'this is unhashed v2', {'Cache-Control': 'max-age=10'}) + .addUnhashedFile('/ignored/file1', 'this is not handled by the SW') + .addUnhashedFile('/ignored/dir/file2', 'this is not handled by the SW either') + .build(); + + const brokenFs = new MockFileSystemBuilder().addFile('/foo.txt', 'this is foo').build(); + + const brokenManifest: Manifest = { + configVersion: 1, + timestamp: 1234567890123, + index: '/foo.txt', + assetGroups: [{ + name: 'assets', + installMode: 'prefetch', + updateMode: 'prefetch', + urls: [ + '/foo.txt', + ], + patterns: [], + }], + dataGroups: [], + navigationUrls: processNavigationUrls(''), + hashTable: tmpHashTableForFs(brokenFs, {'/foo.txt': true}), + }; + + // Manifest without navigation urls to test backward compatibility with + // versions < 6.0.0. + interface ManifestV5 { + configVersion: number; + appData?: {[key: string]: string}; + index: string; + assetGroups?: AssetGroupConfig[]; + dataGroups?: DataGroupConfig[]; + hashTable: {[url: string]: string}; + } + + // To simulate versions < 6.0.0 + const manifestOld: ManifestV5 = { + configVersion: 1, + index: '/foo.txt', + hashTable: tmpHashTableForFs(dist), + }; + + const manifest: Manifest = { + configVersion: 1, + timestamp: 1234567890123, + appData: { + version: 'original', + }, + index: '/foo.txt', + assetGroups: [ + { + name: 'assets', + installMode: 'prefetch', + updateMode: 'prefetch', + urls: [ + '/foo.txt', + '/bar.txt', + '/redirected.txt', + ], + patterns: [ + '/unhashed/.*', + ], + }, + { + name: 'other', + installMode: 'lazy', + updateMode: 'lazy', + urls: [ + '/baz.txt', + '/qux.txt', + ], + patterns: [], + }, + { + name: 'lazy_prefetch', + installMode: 'lazy', + updateMode: 'prefetch', + urls: [ + '/quux.txt', + '/quuux.txt', + '/lazy/unchanged1.txt', + '/lazy/unchanged2.txt', + ], + patterns: [], + } + ], + navigationUrls: processNavigationUrls(''), + hashTable: tmpHashTableForFs(dist), + }; + + const manifestUpdate: Manifest = { + configVersion: 1, + timestamp: 1234567890123, + appData: { + version: 'update', + }, + index: '/foo.txt', + assetGroups: [ + { + name: 'assets', + installMode: 'prefetch', + updateMode: 'prefetch', + urls: [ + '/foo.txt', + '/bar.txt', + '/redirected.txt', + ], + patterns: [ + '/unhashed/.*', + ], + }, + { + name: 'other', + installMode: 'lazy', + updateMode: 'lazy', + urls: [ + '/baz.txt', + '/qux.txt', + ], + patterns: [], + }, + { + name: 'lazy_prefetch', + installMode: 'lazy', + updateMode: 'prefetch', + urls: [ + '/quux.txt', + '/quuux.txt', + '/lazy/unchanged1.txt', + '/lazy/unchanged2.txt', + ], + patterns: [], + } + ], + navigationUrls: processNavigationUrls( + '', + [ + '/**/file1', + '/**/file2', + '!/ignored/file1', + '!/ignored/dir/**', + ]), + hashTable: tmpHashTableForFs(distUpdate), + }; + + const serverBuilderBase = + new MockServerStateBuilder() + .withStaticFiles(dist) + .withRedirect('/redirected.txt', '/redirect-target.txt', 'this was a redirect') + .withError('/error.txt'); + + const server = serverBuilderBase.withManifest(manifest).build(); + + const serverRollback = + serverBuilderBase.withManifest({...manifest, timestamp: manifest.timestamp + 1}).build(); + + const serverUpdate = + new MockServerStateBuilder() + .withStaticFiles(distUpdate) + .withManifest(manifestUpdate) + .withRedirect('/redirected.txt', '/redirect-target.txt', 'this was a redirect') + .build(); + + const brokenServer = + new MockServerStateBuilder().withStaticFiles(brokenFs).withManifest(brokenManifest).build(); + + const server404 = new MockServerStateBuilder().withStaticFiles(dist).build(); + + const manifestHash = sha1(JSON.stringify(manifest)); + const manifestUpdateHash = sha1(JSON.stringify(manifestUpdate)); + + describe('Driver', () => { let scope: SwTestHarness; let driver: Driver; diff --git a/packages/service-worker/worker/test/idle_spec.ts b/packages/service-worker/worker/test/idle_spec.ts index c7cd1da1d6..2170a83f2d 100644 --- a/packages/service-worker/worker/test/idle_spec.ts +++ b/packages/service-worker/worker/test/idle_spec.ts @@ -15,6 +15,7 @@ import {async_beforeEach, async_fit, async_it} from './async'; if (!SwTestHarness.envIsSupported()) { return; } + describe('IdleScheduler', () => { let scope: SwTestHarness; let idle: IdleScheduler; @@ -134,4 +135,4 @@ import {async_beforeEach, async_fit, async_it} from './async'; expect(completed).toEqual(true); }); }); -})(); \ No newline at end of file +})(); diff --git a/packages/service-worker/worker/test/prefetch_spec.ts b/packages/service-worker/worker/test/prefetch_spec.ts index d77cccee10..85011f61f9 100644 --- a/packages/service-worker/worker/test/prefetch_spec.ts +++ b/packages/service-worker/worker/test/prefetch_spec.ts @@ -14,26 +14,26 @@ import {SwTestHarness, SwTestHarnessBuilder} from '../testing/scope'; import {async_fit, async_it} from './async'; -const dist = new MockFileSystemBuilder() - .addFile('/foo.txt', 'this is foo') - .addFile('/bar.txt', 'this is bar') - .build(); - -const manifest = tmpManifestSingleAssetGroup(dist); - -const server = new MockServerStateBuilder().withStaticFiles(dist).withManifest(manifest).build(); - -const scope = new SwTestHarnessBuilder().withServerState(server).build(); - -const db = new CacheDatabase(scope, scope); - - - (function() { // Skip environments that don't support the minimum APIs needed to run the SW tests. if (!SwTestHarness.envIsSupported()) { return; } + + const dist = new MockFileSystemBuilder() + .addFile('/foo.txt', 'this is foo') + .addFile('/bar.txt', 'this is bar') + .build(); + + const manifest = tmpManifestSingleAssetGroup(dist); + + const server = new MockServerStateBuilder().withStaticFiles(dist).withManifest(manifest).build(); + + const scope = new SwTestHarnessBuilder().withServerState(server).build(); + + const db = new CacheDatabase(scope, scope); + + describe('prefetch assets', () => { let group: PrefetchAssetGroup; let idle: IdleScheduler;