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;