Skip to content

Commit 5d8cadd

Browse files
committed
test: [sdk-1577] add unit tests for file data initializer
1 parent 678e42f commit 5d8cadd

File tree

2 files changed

+730
-0
lines changed

2 files changed

+730
-0
lines changed
Lines changed: 230 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,230 @@
1+
import FDv2ChangeSetBuilder from '../../../src/internal/fdv2/FDv2ChangeSetBuilder';
2+
import { DeleteObject, Event, PutObject } from '../../../src/internal/fdv2/proto';
3+
4+
it('throws an error when finishing without starting', () => {
5+
const builder = new FDv2ChangeSetBuilder();
6+
expect(() => builder.finish()).toThrow('changeset: cannot complete without a server-intent');
7+
});
8+
9+
it('starts a new changeset with the given intent', () => {
10+
const builder = new FDv2ChangeSetBuilder();
11+
builder.start('xfer-full');
12+
const result = builder.finish();
13+
14+
expect(result).toBeDefined();
15+
expect(result.length).toBeGreaterThan(0);
16+
expect(result[0].event).toBe('server-intent');
17+
});
18+
19+
it('resets events when starting a new changeset', () => {
20+
const builder = new FDv2ChangeSetBuilder();
21+
builder.start('xfer-full');
22+
builder.putObject({ kind: 'flag', key: 'test-flag', version: 1, object: {} });
23+
builder.start('xfer-full');
24+
const result = builder.finish();
25+
26+
// Should only have server-intent and payload-transferred, no put-object events
27+
const putObjectEvents = result.filter((e) => e.event === 'put-object');
28+
expect(putObjectEvents.length).toBe(0);
29+
});
30+
31+
it('adds a put-object event to the changeset', () => {
32+
const builder = new FDv2ChangeSetBuilder();
33+
const putObj: PutObject = {
34+
kind: 'flag',
35+
key: 'test-flag',
36+
version: 1,
37+
object: { key: 'test-flag', on: true },
38+
};
39+
40+
builder.start('xfer-full');
41+
builder.putObject(putObj);
42+
const result = builder.finish();
43+
44+
const putObjectEvents = result.filter((e) => e.event === 'put-object');
45+
expect(putObjectEvents.length).toBe(1);
46+
expect(putObjectEvents[0].data).toEqual(putObj);
47+
});
48+
49+
it('adds a delete-object event to the changeset', () => {
50+
const builder = new FDv2ChangeSetBuilder();
51+
const deleteObj: DeleteObject = {
52+
kind: 'flag',
53+
key: 'test-flag',
54+
version: 2,
55+
};
56+
57+
builder.start('xfer-full');
58+
builder.deleteObject(deleteObj);
59+
const result = builder.finish();
60+
61+
const deleteObjectEvents = result.filter((e) => e.event === 'delete-object');
62+
expect(deleteObjectEvents.length).toBe(1);
63+
expect(deleteObjectEvents[0].data).toEqual(deleteObj);
64+
});
65+
66+
it('includes server-intent as the first event with correct structure', () => {
67+
const builder = new FDv2ChangeSetBuilder();
68+
builder.start('xfer-full');
69+
const result = builder.finish();
70+
71+
const serverIntentEvent = result[0] as Event;
72+
expect(serverIntentEvent.event).toBe('server-intent');
73+
expect(serverIntentEvent.data).toBeDefined();
74+
75+
const intentData = serverIntentEvent.data as any;
76+
expect(intentData.payloads).toBeDefined();
77+
expect(intentData.payloads.length).toBe(1);
78+
expect(intentData.payloads[0].intentCode).toBe('xfer-full');
79+
expect(intentData.payloads[0].id).toBe('dummy-id');
80+
expect(intentData.payloads[0].target).toBe(1);
81+
expect(intentData.payloads[0].reason).toBe('payload-missing');
82+
});
83+
84+
it('includes payload-transferred as the last event with empty state', () => {
85+
const builder = new FDv2ChangeSetBuilder();
86+
builder.start('xfer-full');
87+
const result = builder.finish();
88+
89+
const payloadTransferredEvent = result[result.length - 1] as Event;
90+
expect(payloadTransferredEvent.event).toBe('payload-transferred');
91+
expect(payloadTransferredEvent.data).toBeDefined();
92+
93+
const transferredData = payloadTransferredEvent.data as any;
94+
expect(transferredData.state).toBe('');
95+
expect(transferredData.version).toBe(1);
96+
expect(transferredData.id).toBe('dummy-id');
97+
});
98+
99+
it('includes all put and delete events between server-intent and payload-transferred', () => {
100+
const builder = new FDv2ChangeSetBuilder();
101+
const putObj1: PutObject = {
102+
kind: 'flag',
103+
key: 'flag-1',
104+
version: 1,
105+
object: { key: 'flag-1', on: true },
106+
};
107+
const deleteObj: DeleteObject = {
108+
kind: 'segment',
109+
key: 'segment-1',
110+
version: 2,
111+
};
112+
const putObj2: PutObject = {
113+
kind: 'flag',
114+
key: 'flag-2',
115+
version: 3,
116+
object: { key: 'flag-2', on: false },
117+
};
118+
119+
builder.start('xfer-full');
120+
builder.putObject(putObj1);
121+
builder.deleteObject(deleteObj);
122+
builder.putObject(putObj2);
123+
const result = builder.finish();
124+
125+
expect(result.length).toBe(5); // server-intent + 3 events + payload-transferred
126+
expect(result[0].event).toBe('server-intent');
127+
expect(result[1].event).toBe('put-object');
128+
expect((result[1].data as PutObject).key).toBe('flag-1');
129+
expect(result[2].event).toBe('delete-object');
130+
expect((result[2].data as DeleteObject).key).toBe('segment-1');
131+
expect(result[3].event).toBe('put-object');
132+
expect((result[3].data as PutObject).key).toBe('flag-2');
133+
expect(result[4].event).toBe('payload-transferred');
134+
});
135+
136+
it('supports method chaining', () => {
137+
const builder = new FDv2ChangeSetBuilder();
138+
const putObj: PutObject = {
139+
kind: 'flag',
140+
key: 'test-flag',
141+
version: 1,
142+
object: {},
143+
};
144+
const deleteObj: DeleteObject = {
145+
kind: 'flag',
146+
key: 'test-flag',
147+
version: 2,
148+
};
149+
150+
const result = builder.start('xfer-full').putObject(putObj).deleteObject(deleteObj).finish();
151+
152+
expect(result.length).toBe(4); // server-intent + 2 events + payload-transferred
153+
expect(result[0].event).toBe('server-intent');
154+
expect(result[1].event).toBe('put-object');
155+
expect(result[2].event).toBe('delete-object');
156+
expect(result[3].event).toBe('payload-transferred');
157+
});
158+
159+
it('handles multiple put objects for different keys', () => {
160+
const builder = new FDv2ChangeSetBuilder();
161+
const putObj1: PutObject = {
162+
kind: 'flag',
163+
key: 'flag-1',
164+
version: 1,
165+
object: { key: 'flag-1' },
166+
};
167+
const putObj2: PutObject = {
168+
kind: 'flag',
169+
key: 'flag-2',
170+
version: 1,
171+
object: { key: 'flag-2' },
172+
};
173+
const putObj3: PutObject = {
174+
kind: 'segment',
175+
key: 'segment-1',
176+
version: 1,
177+
object: { key: 'segment-1' },
178+
};
179+
180+
builder.start('xfer-full');
181+
builder.putObject(putObj1);
182+
builder.putObject(putObj2);
183+
builder.putObject(putObj3);
184+
const result = builder.finish();
185+
186+
const putObjectEvents = result.filter((e) => e.event === 'put-object');
187+
expect(putObjectEvents.length).toBe(3);
188+
expect((putObjectEvents[0].data as PutObject).key).toBe('flag-1');
189+
expect((putObjectEvents[1].data as PutObject).key).toBe('flag-2');
190+
expect((putObjectEvents[2].data as PutObject).key).toBe('segment-1');
191+
});
192+
193+
it('handles multiple delete objects', () => {
194+
const builder = new FDv2ChangeSetBuilder();
195+
const deleteObj1: DeleteObject = {
196+
kind: 'flag',
197+
key: 'flag-1',
198+
version: 1,
199+
};
200+
const deleteObj2: DeleteObject = {
201+
kind: 'segment',
202+
key: 'segment-1',
203+
version: 1,
204+
};
205+
206+
builder.start('xfer-full');
207+
builder.deleteObject(deleteObj1);
208+
builder.deleteObject(deleteObj2);
209+
const result = builder.finish();
210+
211+
const deleteObjectEvents = result.filter((e) => e.event === 'delete-object');
212+
expect(deleteObjectEvents.length).toBe(2);
213+
expect((deleteObjectEvents[0].data as DeleteObject).key).toBe('flag-1');
214+
expect((deleteObjectEvents[1].data as DeleteObject).key).toBe('segment-1');
215+
});
216+
217+
it('produces an empty changeset with only server-intent and payload-transferred when no events are added', () => {
218+
const builder = new FDv2ChangeSetBuilder();
219+
builder.start('xfer-full');
220+
const result = builder.finish();
221+
222+
expect(result.length).toBe(2);
223+
expect(result[0].event).toBe('server-intent');
224+
expect(result[1].event).toBe('payload-transferred');
225+
226+
const putObjectEvents = result.filter((e) => e.event === 'put-object');
227+
const deleteObjectEvents = result.filter((e) => e.event === 'delete-object');
228+
expect(putObjectEvents.length).toBe(0);
229+
expect(deleteObjectEvents.length).toBe(0);
230+
});

0 commit comments

Comments
 (0)