Skip to content

Commit 23adc0e

Browse files
[Multi-Tab] Using WebStorage Mock with all IndexedDB tests (#1034)
1 parent 548e2bb commit 23adc0e

File tree

4 files changed

+42
-20
lines changed

4 files changed

+42
-20
lines changed

packages/firestore/test/unit/local/persistence_test_helpers.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,6 @@ import {
2929
OnlineState,
3030
TargetId
3131
} from '../../../src/core/types';
32-
import { BrowserPlatform } from '../../../src/platform_browser/browser_platform';
3332
import { AsyncQueue } from '../../../src/util/async_queue';
3433
import { User } from '../../../src/auth/user';
3534
import {
@@ -122,7 +121,7 @@ export async function populateWebStorage(
122121
// NOTE: We don't call shutdown() on it because that would delete the data.
123122
const secondaryClientState = new WebStorageSharedClientState(
124123
new AsyncQueue(),
125-
new BrowserPlatform(),
124+
PlatformSupport.getPlatform(),
126125
TEST_PERSISTENCE_PREFIX,
127126
existingClientId,
128127
user

packages/firestore/test/unit/local/web_storage_shared_client_state.test.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,6 @@ import {
4242
clearWebStorage,
4343
TEST_PERSISTENCE_PREFIX
4444
} from './persistence_test_helpers';
45-
import { BrowserPlatform } from '../../../src/platform_browser/browser_platform';
4645
import { PlatformSupport } from '../../../src/platform/platform';
4746
import * as objUtils from '../../../src/util/obj';
4847
import { targetIdSet } from '../../../src/model/collections';
@@ -174,6 +173,7 @@ describe('WebStorageSharedClientState', () => {
174173
let clientSyncer: TestSharedClientSyncer;
175174

176175
let previousAddEventListener;
176+
let previousRemoveEventListener;
177177

178178
let localStorageCallbacks = [];
179179

@@ -192,6 +192,7 @@ describe('WebStorageSharedClientState', () => {
192192
localStorageCallbacks = [];
193193

194194
previousAddEventListener = window.addEventListener;
195+
previousRemoveEventListener = window.removeEventListener;
195196

196197
// We capture the listener here so that we can invoke it from the local
197198
// client. If we directly relied on LocalStorage listeners, we would not
@@ -200,12 +201,13 @@ describe('WebStorageSharedClientState', () => {
200201
expect(type).to.equal('storage');
201202
localStorageCallbacks.push(callback);
202203
};
204+
window.removeEventListener = () => {};
203205

204206
primaryClientId = AutoId.newId();
205207
queue = new AsyncQueue();
206208
sharedClientState = new WebStorageSharedClientState(
207209
queue,
208-
new BrowserPlatform(),
210+
PlatformSupport.getPlatform(),
209211
TEST_PERSISTENCE_PREFIX,
210212
primaryClientId,
211213
AUTHENTICATED_USER
@@ -220,6 +222,7 @@ describe('WebStorageSharedClientState', () => {
220222
afterEach(() => {
221223
sharedClientState.shutdown();
222224
window.addEventListener = previousAddEventListener;
225+
window.removeEventListener = previousRemoveEventListener;
223226
});
224227

225228
function assertClientState(

packages/firestore/test/util/node_persistence.ts

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ import * as registerIndexedDBShim from 'indexeddbshim';
1818
import * as fs from 'fs';
1919
import * as os from 'os';
2020

21+
import { FakeWindow, SharedFakeWebStorage } from './test_platform';
22+
2123
// WARNING: The `indexeddbshim` installed via this module should only ever be
2224
// used during initial development. Always validate your changes via
2325
// `yarn test:browser` (which uses a browser-based IndexedDB implementation)
@@ -36,9 +38,13 @@ if (process.env.USE_MOCK_PERSISTENCE === 'YES') {
3638
databaseBasePath: dbDir,
3739
deleteDatabaseFiles: true
3840
});
39-
globalAny.window = Object.assign(globalAny.window || {}, {
40-
indexedDB: globalAny.indexedDB
41-
});
41+
42+
const fakeWindow = new FakeWindow(
43+
new SharedFakeWebStorage(),
44+
globalAny.indexedDB
45+
);
46+
47+
globalAny.window = fakeWindow;
4248

4349
// We need to define the `Event` type as it is used in Node to send events to
4450
// WebStorage when using both the IndexedDB mock and the WebStorage mock.

packages/firestore/test/util/test_platform.ts

Lines changed: 27 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -27,27 +27,36 @@ import { assert, fail } from '../../src/util/assert';
2727
* Firestore.
2828
*/
2929
export class FakeWindow {
30-
private readonly storageArea: Storage;
31-
private storageListener: EventListener = () => {};
30+
private readonly fakeStorageArea: Storage;
31+
private readonly fakeIndexedDb: IDBFactory;
3232

33-
constructor(sharedMockStorage: SharedFakeWebStorage) {
34-
this.storageArea = sharedMockStorage.getStorageArea(event =>
35-
this.storageListener(event)
36-
);
33+
private storageListeners: EventListener[] = [];
34+
35+
constructor(
36+
sharedFakeStorage: SharedFakeWebStorage,
37+
fakeIndexedDb?: IDBFactory
38+
) {
39+
this.fakeStorageArea = sharedFakeStorage.getStorageArea(event => {
40+
for (const listener of this.storageListeners) {
41+
listener(event);
42+
}
43+
});
44+
this.fakeIndexedDb =
45+
fakeIndexedDb || (typeof window !== 'undefined' && window.indexedDB);
3746
}
3847

3948
get localStorage(): Storage {
40-
return this.storageArea;
49+
return this.fakeStorageArea;
4150
}
4251

4352
get indexedDB(): IDBFactory {
44-
return window.indexedDB;
53+
return this.fakeIndexedDb;
4554
}
4655

4756
addEventListener(type: string, listener: EventListener): void {
4857
switch (type) {
4958
case 'storage':
50-
this.storageListener = listener;
59+
this.storageListeners.push(listener);
5160
break;
5261
case 'unload':
5362
// The spec tests currently do not rely on 'unload' listeners.
@@ -59,11 +68,15 @@ export class FakeWindow {
5968

6069
removeEventListener(type: string, listener: EventListener): void {
6170
if (type === 'storage') {
71+
const oldCount = this.storageListeners.length;
72+
this.storageListeners = this.storageListeners.filter(
73+
registeredListener => listener !== registeredListener
74+
);
75+
const newCount = this.storageListeners.length;
6276
assert(
63-
this.storageListener === listener,
64-
"Listener passed to 'removeEventListener' doesn't match the current listener."
77+
newCount === oldCount - 1,
78+
"Listener passed to 'removeEventListener' doesn't match any registered listener."
6579
);
66-
this.storageListener = () => {};
6780
}
6881
}
6982
}
@@ -150,7 +163,8 @@ export class SharedFakeWebStorage {
150163
}
151164

152165
private key(index: number): string | null {
153-
return Array.from(this.data.keys())[index];
166+
const key = Array.from(this.data.keys())[index];
167+
return key !== undefined ? key : null;
154168
}
155169

156170
private removeItem(key: string): void {

0 commit comments

Comments
 (0)