Skip to content

Commit a57b082

Browse files
Unit tests
1 parent 978ad74 commit a57b082

File tree

5 files changed

+84
-16
lines changed

5 files changed

+84
-16
lines changed

src/storages/KeyBuilder.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ export class KeyBuilder {
4141
return `${this.prefix}.rbsegment.${splitName}`;
4242
}
4343

44-
buildRBSegmentTillKey() {
44+
buildRBSegmentsTillKey() {
4545
return `${this.prefix}.rbsegments.till`;
4646
}
4747

src/storages/__tests__/testUtils.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { ISplit } from '../../dtos/types';
1+
import { IRBSegment, ISplit } from '../../dtos/types';
22
import { IStorageSync, IStorageAsync, IImpressionsCacheSync, IEventsCacheSync } from '../types';
33

44
// Assert that instances created by storage factories have the expected interface
@@ -45,3 +45,9 @@ export const featureFlagTwo: ISplit = { name: 'ff_two', sets: ['t','w','o'] };
4545
export const featureFlagThree: ISplit = { name: 'ff_three', sets: ['t','h','r','e'] };
4646
//@ts-ignore
4747
export const featureFlagWithoutFS: ISplit = { name: 'ff_four' };
48+
49+
// Rule-based segments
50+
//@ts-ignore
51+
export const rbSegment: IRBSegment = { name: 'rb_segment', conditions: [{ matcherGroup: { matchers: [{ matcherType: 'EQUAL_TO', unaryNumericMatcherData: { value: 10 } }] } }] };
52+
//@ts-ignore
53+
export const rbSegmentWithInSegmentMatcher: IRBSegment = { name: 'rb_segment_with_in_segment_matcher', conditions: [{ matcherGroup: { matchers: [{ matcherType: 'IN_SEGMENT', userDefinedSegmentMatcherData: { segmentName: 'employees' } }] } }] };

src/storages/inLocalStorage/RBSegmentsCacheInLocal.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,9 @@ export class RBSegmentsCacheInLocal implements IRBSegmentsCacheSync {
2020
}
2121

2222
clear() {
23+
this.getNames().forEach(name => this.remove(name));
24+
localStorage.removeItem(this.keys.buildRBSegmentsTillKey());
2325
this.hasSync = false;
24-
// SplitsCacheInLocal.clear() does the rest of the job
2526
}
2627

2728
update(toAdd: IRBSegment[], toRemove: IRBSegment[], changeNumber: number): boolean {
@@ -32,7 +33,7 @@ export class RBSegmentsCacheInLocal implements IRBSegmentsCacheSync {
3233

3334
private setChangeNumber(changeNumber: number) {
3435
try {
35-
localStorage.setItem(this.keys.buildSplitsTillKey(), changeNumber + '');
36+
localStorage.setItem(this.keys.buildRBSegmentsTillKey(), changeNumber + '');
3637
localStorage.setItem(this.keys.buildLastUpdatedKey(), Date.now() + '');
3738
this.hasSync = true;
3839
} catch (e) {
@@ -42,7 +43,7 @@ export class RBSegmentsCacheInLocal implements IRBSegmentsCacheSync {
4243

4344
private updateSegmentCount(diff: number){
4445
const segmentsCountKey = this.keys.buildSplitsWithSegmentCountKey();
45-
const count = toNumber(localStorage.getItem(segmentsCountKey)) - diff;
46+
const count = toNumber(localStorage.getItem(segmentsCountKey)) + diff;
4647
// @ts-expect-error
4748
if (count > 0) localStorage.setItem(segmentsCountKey, count);
4849
else localStorage.removeItem(segmentsCountKey);
@@ -79,7 +80,6 @@ export class RBSegmentsCacheInLocal implements IRBSegmentsCacheSync {
7980
if (usesSegments(rbSegment)) this.updateSegmentCount(-1);
8081

8182
return true;
82-
8383
} catch (e) {
8484
this.log.error(LOG_PREFIX + e);
8585
return false;
@@ -116,7 +116,7 @@ export class RBSegmentsCacheInLocal implements IRBSegmentsCacheSync {
116116

117117
getChangeNumber(): number {
118118
const n = -1;
119-
let value: string | number | null = localStorage.getItem(this.keys.buildRBSegmentTillKey());
119+
let value: string | number | null = localStorage.getItem(this.keys.buildRBSegmentsTillKey());
120120

121121
if (value !== null) {
122122
value = parseInt(value, 10);

src/storages/inLocalStorage/SplitsCacheInLocal.ts

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -57,16 +57,14 @@ export class SplitsCacheInLocal extends AbstractSplitsCacheSync {
5757

5858
private _incrementCounts(split: ISplit) {
5959
try {
60-
if (split) {
61-
const ttKey = this.keys.buildTrafficTypeKey(split.trafficTypeName);
62-
// @ts-expect-error
63-
localStorage.setItem(ttKey, toNumber(localStorage.getItem(ttKey)) + 1);
60+
const ttKey = this.keys.buildTrafficTypeKey(split.trafficTypeName);
61+
// @ts-expect-error
62+
localStorage.setItem(ttKey, toNumber(localStorage.getItem(ttKey)) + 1);
6463

65-
if (usesSegments(split)) {
66-
const segmentsCountKey = this.keys.buildSplitsWithSegmentCountKey();
67-
// @ts-expect-error
68-
localStorage.setItem(segmentsCountKey, toNumber(localStorage.getItem(segmentsCountKey)) + 1);
69-
}
64+
if (usesSegments(split)) {
65+
const segmentsCountKey = this.keys.buildSplitsWithSegmentCountKey();
66+
// @ts-expect-error
67+
localStorage.setItem(segmentsCountKey, toNumber(localStorage.getItem(segmentsCountKey)) + 1);
7068
}
7169
} catch (e) {
7270
this.log.error(LOG_PREFIX + e);
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
import { RBSegmentsCacheInMemory } from '../RBSegmentsCacheInMemory';
2+
import { RBSegmentsCacheInLocal } from '../../inLocalStorage/RBSegmentsCacheInLocal';
3+
import { KeyBuilderCS } from '../../KeyBuilderCS';
4+
import { rbSegment, rbSegmentWithInSegmentMatcher } from '../../__tests__/testUtils';
5+
import { IRBSegmentsCacheSync } from '../../types';
6+
import { fullSettings } from '../../../utils/settingsValidation/__tests__/settings.mocks';
7+
8+
const cacheInMemory = new RBSegmentsCacheInMemory();
9+
const cacheInLocal = new RBSegmentsCacheInLocal(fullSettings, new KeyBuilderCS('SPLITIO', 'user'));
10+
11+
describe.each([cacheInMemory, cacheInLocal])('RB SEGMENTS CACHE', (cache: IRBSegmentsCacheSync) => {
12+
13+
beforeEach(() => {
14+
cache.clear();
15+
});
16+
17+
test('clear should reset the cache state', () => {
18+
cache.update([rbSegment], [], 1);
19+
expect(cache.getChangeNumber()).toBe(1);
20+
expect(cache.get(rbSegment.name)).not.toBeNull();
21+
22+
cache.clear();
23+
expect(cache.getChangeNumber()).toBe(-1);
24+
expect(cache.get(rbSegment.name)).toBeNull();
25+
});
26+
27+
test('update should add and remove segments correctly', () => {
28+
// Add segments
29+
const updated1 = cache.update([rbSegment, rbSegmentWithInSegmentMatcher], [], 1);
30+
expect(updated1).toBe(true);
31+
expect(cache.get(rbSegment.name)).toEqual(rbSegment);
32+
expect(cache.get(rbSegmentWithInSegmentMatcher.name)).toEqual(rbSegmentWithInSegmentMatcher);
33+
expect(cache.getChangeNumber()).toBe(1);
34+
35+
// Remove segments
36+
const updated2 = cache.update([], [rbSegment], 2);
37+
expect(updated2).toBe(true);
38+
expect(cache.get(rbSegment.name)).toBeNull();
39+
expect(cache.get(rbSegmentWithInSegmentMatcher.name)).toEqual(rbSegmentWithInSegmentMatcher);
40+
expect(cache.getChangeNumber()).toBe(2);
41+
});
42+
43+
test('contains should check for segment existence correctly', () => {
44+
cache.update([rbSegment, rbSegmentWithInSegmentMatcher], [], 1);
45+
46+
expect(cache.contains(new Set([rbSegment.name]))).toBe(true);
47+
expect(cache.contains(new Set([rbSegment.name, rbSegmentWithInSegmentMatcher.name]))).toBe(true);
48+
expect(cache.contains(new Set(['nonexistent']))).toBe(false);
49+
expect(cache.contains(new Set([rbSegment.name, 'nonexistent']))).toBe(false);
50+
});
51+
52+
test('usesSegments should track segments usage correctly', () => {
53+
expect(cache.usesSegments()).toBe(true); // Initially true when changeNumber is -1
54+
55+
cache.update([rbSegment], [], 1); // rbSegment doesn't have IN_SEGMENT matcher
56+
expect(cache.usesSegments()).toBe(false);
57+
58+
cache.update([rbSegmentWithInSegmentMatcher], [], 2); // rbSegmentWithInSegmentMatcher has IN_SEGMENT matcher
59+
expect(cache.usesSegments()).toBe(true);
60+
61+
cache.clear();
62+
expect(cache.usesSegments()).toBe(true); // True after clear since changeNumber is -1
63+
});
64+
});

0 commit comments

Comments
 (0)