Skip to content

Commit 6bc002a

Browse files
committed
more refactor
1 parent 34b4df5 commit 6bc002a

10 files changed

+229
-9
lines changed

lib/vuid/vuid_manager.spec.ts

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ describe('VuidCacheManager', () => {
4343
const vuid = await manager.load();
4444
const vuidInCache = await cache.get(vuidCacheKey);
4545
expect(vuidInCache).toBe(vuid);
46-
expect(isVuid(vuid)).toBe(true);
46+
expect(isVuid(vuid!)).toBe(true);
4747
});
4848

4949
it('should create and save a new vuid if old VUID from cache is not valid', async () => {
@@ -54,7 +54,7 @@ describe('VuidCacheManager', () => {
5454
const vuid = await manager.load();
5555
const vuidInCache = await cache.get(vuidCacheKey);
5656
expect(vuidInCache).toBe(vuid);
57-
expect(isVuid(vuid)).toBe(true);
57+
expect(isVuid(vuid!)).toBe(true);
5858
});
5959

6060
it('should return the same vuid without modifying the cache after creating a new vuid', async () => {
@@ -81,6 +81,23 @@ describe('VuidCacheManager', () => {
8181
expect(vuidInCache).toBe('vuid_valid');
8282
});
8383

84+
it('should use the new cache after setCache is called', async () => {
85+
const cache1 = getMockAsyncCache<string>();
86+
const cache2 = getMockAsyncCache<string>();
87+
88+
await cache1.set(vuidCacheKey, 'vuid_123');
89+
await cache2.set(vuidCacheKey, 'vuid_456');
90+
91+
const manager = new VuidCacheManager(cache1);
92+
const vuid1 = await manager.load();
93+
expect(vuid1).toBe('vuid_123');
94+
95+
manager.setCache(cache2);
96+
await manager.load();
97+
const vuid2 = await cache2.get(vuidCacheKey);
98+
expect(vuid2).toBe('vuid_456');
99+
});
100+
84101
it('should sequence remove and load calls', async() => {
85102
const cache = getMockAsyncCache<string>();
86103
const removeSpy = vi.spyOn(cache, 'remove');

lib/vuid/vuid_manager.ts

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,19 +27,24 @@ export interface VuidManager {
2727
export class VuidCacheManager {
2828
private logger?: LoggerFacade;
2929
private vuidCacheKey = 'optimizely-vuid';
30-
private cache: Cache<string>;
30+
private cache?: Cache<string>;
3131
// if this value is not undefined, this means the same value is in the cache.
3232
// if this is undefined, it could either mean that there is no value in the cache
3333
// or that there is a value in the cache but it has not been loaded yet or failed
3434
// to load.
3535
private vuid?: string;
3636
private waitPromise: Promise<unknown> = Promise.resolve();
3737

38-
constructor(cache: Cache<string>, logger?: LoggerFacade) {
38+
constructor(cache?: Cache<string>, logger?: LoggerFacade) {
3939
this.cache = cache;
4040
this.logger = logger;
4141
}
4242

43+
setCache(cache: Cache<string>): void {
44+
this.cache = cache;
45+
this.vuid = undefined;
46+
}
47+
4348
setLogger(logger: LoggerFacade): void {
4449
this.logger = logger;
4550
}
@@ -52,19 +57,25 @@ export class VuidCacheManager {
5257

5358
async remove(): Promise<unknown> {
5459
const removeFn = async () => {
60+
if (!this.cache) {
61+
return;
62+
}
5563
this.vuid = undefined;
5664
await this.cache.remove(this.vuidCacheKey);
5765
}
5866

5967
return this.serialize(removeFn);
6068
}
6169

62-
async load(): Promise<string> {
70+
async load(): Promise<Maybe<string>> {
6371
if (this.vuid) {
6472
return this.vuid;
6573
}
6674

6775
const loadFn = async () => {
76+
if (!this.cache) {
77+
return;
78+
}
6879
const cachedValue = await this.cache.get(this.vuidCacheKey);
6980
if (cachedValue && isVuid(cachedValue)) {
7081
this.vuid = cachedValue;
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
import { vi, describe, expect, it, beforeEach } from 'vitest';
2+
3+
vi.mock('../utils/cache/local_storage_cache.browser', () => {
4+
return {
5+
LocalStorageCache: vi.fn(),
6+
};
7+
});
8+
9+
vi.mock('./vuid_manager', () => {
10+
return {
11+
DefaultVuidManager: vi.fn(),
12+
VuidCacheManager: vi.fn(),
13+
};
14+
});
15+
16+
import { createVuidManager } from './vuid_manager_factory.browser';
17+
import { LocalStorageCache } from '../utils/cache/local_storage_cache.browser';
18+
import { DefaultVuidManager, VuidCacheManager } from './vuid_manager';
19+
20+
describe('createVuidManager', () => {
21+
const MockVuidCacheManager = vi.mocked(VuidCacheManager);
22+
const MockLocalStorageCache = vi.mocked(LocalStorageCache);
23+
const MockDefaultVuidManager = vi.mocked(DefaultVuidManager);
24+
25+
beforeEach(() => {
26+
MockDefaultVuidManager.mockClear();
27+
});
28+
29+
it('should pass the enableVuid option to the DefaultVuidManager', () => {
30+
const manager = createVuidManager({ enableVuid: true });
31+
expect(manager).toBe(MockDefaultVuidManager.mock.instances[0]);
32+
expect(MockDefaultVuidManager.mock.calls[0][0].enableVuid).toBe(true);
33+
34+
const manager2 = createVuidManager({ enableVuid: false });
35+
expect(manager2).toBe(MockDefaultVuidManager.mock.instances[1]);
36+
expect(MockDefaultVuidManager.mock.calls[1][0].enableVuid).toBe(false);
37+
});
38+
39+
it('should use a VuidCacheManager with a LocalStorageCache', () => {
40+
const manager = createVuidManager({ enableVuid: true });
41+
expect(manager).toBe(MockDefaultVuidManager.mock.instances[0]);
42+
43+
44+
const usedCacheManager = MockDefaultVuidManager.mock.calls[0][0].vuidCacheManager;
45+
expect(usedCacheManager).toBe(MockVuidCacheManager.mock.instances[0]);
46+
47+
const usedCache = MockVuidCacheManager.mock.calls[0][0];
48+
expect(usedCache).toBe(MockLocalStorageCache.mock.instances[0]);
49+
});
50+
51+
it('should use a single VuidCacheManager instance for all VuidManager instances', () => {
52+
const manager1 = createVuidManager({ enableVuid: true });
53+
const manager2 = createVuidManager({ enableVuid: true });
54+
expect(manager1).toBe(MockDefaultVuidManager.mock.instances[0]);
55+
expect(manager2).toBe(MockDefaultVuidManager.mock.instances[1]);
56+
expect(MockVuidCacheManager.mock.instances.length).toBe(1);
57+
58+
const usedCacheManager1 = MockDefaultVuidManager.mock.calls[0][0].vuidCacheManager;
59+
const usedCacheManager2 = MockDefaultVuidManager.mock.calls[1][0].vuidCacheManager;
60+
expect(usedCacheManager1).toBe(usedCacheManager2);
61+
expect(usedCacheManager1).toBe(MockVuidCacheManager.mock.instances[0]);
62+
});
63+
});

lib/vuid/vuid_manager_factory.browser.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,14 +13,18 @@
1313
* See the License for the specific language governing permissions and
1414
* limitations under the License.
1515
*/
16-
import { DefaultVuidMaanger, VuidCacheManager, VuidManager } from './vuid_manager';
16+
import { DefaultVuidManager, VuidCacheManager, VuidManager } from './vuid_manager';
1717
import { LocalStorageCache } from '../utils/cache/local_storage_cache.browser';
1818
import { VuidManagerOptions } from './vuid_manager_factory';
1919

2020
export const vuidCacheManager = new VuidCacheManager(new LocalStorageCache<string>());
2121

2222
export const createVuidManager = (options: VuidManagerOptions): VuidManager => {
23-
return new DefaultVuidMaanger({
23+
if (options.vuidCache) {
24+
vuidCacheManager.setCache(options.vuidCache);
25+
}
26+
27+
return new DefaultVuidManager({
2428
vuidCacheManager,
2529
enableVuid: options.enableVuid
2630
});
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import { vi, describe, expect, it } from 'vitest';
2+
3+
import { createVuidManager } from './vuid_manager_factory.node';
4+
5+
describe('createVuidManager', () => {
6+
it('should throw an error', () => {
7+
expect(() => createVuidManager({ enableVuid: true }))
8+
.toThrowError('VUID is not supported in Node.js environment');
9+
});
10+
});

lib/vuid/vuid_manager_factory.node.ts

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
/**
2+
* Copyright 2024, Optimizely
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
import { VuidManager } from './vuid_manager';
17+
import { VuidManagerOptions } from './vuid_manager_factory';
18+
19+
export const createVuidManager = (options: VuidManagerOptions): VuidManager => {
20+
throw new Error('VUID is not supported in Node.js environment');
21+
};
22+
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
import { vi, describe, expect, it, beforeEach } from 'vitest';
2+
3+
vi.mock('../utils/cache/local_storage_cache.react_native', () => {
4+
return {
5+
LocalStorageCache: vi.fn(),
6+
};
7+
});
8+
9+
vi.mock('./vuid_manager', () => {
10+
return {
11+
DefaultVuidManager: vi.fn(),
12+
VuidCacheManager: vi.fn(),
13+
};
14+
});
15+
16+
import { createVuidManager } from './vuid_manager_factory.browser';
17+
import { Async}
18+
import { DefaultVuidManager, VuidCacheManager } from './vuid_manager';
19+
20+
describe('createVuidManager', () => {
21+
const MockVuidCacheManager = vi.mocked(VuidCacheManager);
22+
const MockLocalStorageCache = vi.mocked(LocalStorageCache);
23+
const MockDefaultVuidManager = vi.mocked(DefaultVuidManager);
24+
25+
beforeEach(() => {
26+
MockDefaultVuidManager.mockClear();
27+
});
28+
29+
it('should pass the enableVuid option to the DefaultVuidManager', () => {
30+
const manager = createVuidManager({ enableVuid: true });
31+
expect(manager).toBe(MockDefaultVuidManager.mock.instances[0]);
32+
expect(MockDefaultVuidManager.mock.calls[0][0].enableVuid).toBe(true);
33+
34+
const manager2 = createVuidManager({ enableVuid: false });
35+
expect(manager2).toBe(MockDefaultVuidManager.mock.instances[1]);
36+
expect(MockDefaultVuidManager.mock.calls[1][0].enableVuid).toBe(false);
37+
});
38+
39+
it('should use a VuidCacheManager with a LocalStorageCache', () => {
40+
const manager = createVuidManager({ enableVuid: true });
41+
expect(manager).toBe(MockDefaultVuidManager.mock.instances[0]);
42+
43+
44+
const usedCacheManager = MockDefaultVuidManager.mock.calls[0][0].vuidCacheManager;
45+
expect(usedCacheManager).toBe(MockVuidCacheManager.mock.instances[0]);
46+
47+
const usedCache = MockVuidCacheManager.mock.calls[0][0];
48+
expect(usedCache).toBe(MockLocalStorageCache.mock.instances[0]);
49+
});
50+
51+
it('should use a single VuidCacheManager instance for all VuidManager instances', () => {
52+
const manager1 = createVuidManager({ enableVuid: true });
53+
const manager2 = createVuidManager({ enableVuid: true });
54+
expect(manager1).toBe(MockDefaultVuidManager.mock.instances[0]);
55+
expect(manager2).toBe(MockDefaultVuidManager.mock.instances[1]);
56+
expect(MockVuidCacheManager.mock.instances.length).toBe(1);
57+
58+
const usedCacheManager1 = MockDefaultVuidManager.mock.calls[0][0].vuidCacheManager;
59+
const usedCacheManager2 = MockDefaultVuidManager.mock.calls[1][0].vuidCacheManager;
60+
expect(usedCacheManager1).toBe(usedCacheManager2);
61+
expect(usedCacheManager1).toBe(MockVuidCacheManager.mock.instances[0]);
62+
});
63+
});
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
/**
2+
* Copyright 2024, Optimizely
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
import { DefaultVuidManager, VuidCacheManager, VuidManager } from './vuid_manager';
17+
import { AsyncStorageCache } from '../utils/cache/async_storage_cache.react_native';
18+
import { VuidManagerOptions } from './vuid_manager_factory';
19+
20+
export const vuidCacheManager = new VuidCacheManager(new AsyncStorageCache<string>());
21+
22+
export const createVuidManager = (options: VuidManagerOptions): VuidManager => {
23+
return new DefaultVuidManager({
24+
vuidCacheManager,
25+
enableVuid: options.enableVuid
26+
});
27+
}

lib/vuid/vuid_manager_factory.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
import { Cache } from '../utils/cache/cache';
2+
13
export type VuidManagerOptions = {
2-
enableVuid: boolean;
4+
vuidCache?: Cache<string>;
5+
enableVuid?: boolean;
36
}

vitest.config.mts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ export default defineConfig({
2020
test: {
2121
onConsoleLog: () => true,
2222
environment: 'happy-dom',
23-
include: ['**/vuid_manager.spec.ts'],
23+
include: ['**/vuid_manager_factory.browser.spec.ts'],
2424
typecheck: {
2525
tsconfig: 'tsconfig.spec.json',
2626
},

0 commit comments

Comments
 (0)