Skip to content

Commit

Permalink
test-utils: freeze and serialize MockStorageApi values
Browse files Browse the repository at this point in the history
Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
  • Loading branch information
Rugvip committed Dec 24, 2021
1 parent 78b8229 commit c36b779
Show file tree
Hide file tree
Showing 3 changed files with 83 additions and 3 deletions.
5 changes: 5 additions & 0 deletions .changeset/curly-pillows-provide.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@backstage/test-utils': patch
---

JSON serialize and freeze values stored by the `MockStorageApi`.
Original file line number Diff line number Diff line change
Expand Up @@ -216,4 +216,73 @@ describe('WebStorage Storage API', () => {
newValue: undefined,
});
});

it('should freeze the snapshot value', async () => {
const storage = createMockStorage();

const data = { foo: 'bar', baz: [{ foo: 'bar' }] };
storage.set('foo', data);

const snapshot = storage.snapshot<typeof data>('foo');
expect(snapshot.value).not.toBe(data);

if (snapshot.presence !== 'present') {
throw new Error('Invalid presence');
}

expect(() => {
snapshot.value.foo = 'buzz';
}).toThrow(/Cannot assign to read only property/);
expect(() => {
snapshot.value.baz[0].foo = 'buzz';
}).toThrow(/Cannot assign to read only property/);
expect(() => {
snapshot.value.baz.push({ foo: 'buzz' });
}).toThrow(/Cannot add property 1, object is not extensible/);
});

it('should freeze observed values', async () => {
const storage = createMockStorage();

const snapshotPromise = new Promise<any>(resolve => {
storage.observe$('test').subscribe({
next: resolve,
});
});

storage.set('test', {
foo: {
bar: 'baz',
},
});

const snapshot = await snapshotPromise;
expect(snapshot.presence).toBe('present');
expect(() => {
snapshot.value!.foo.bar = 'qux';
}).toThrow(/Cannot assign to read only property 'bar' of object/);
});

it('should JSON serialize stored values', async () => {
const storage = createMockStorage();

storage.set<any>('test', {
foo: {
toJSON() {
return {
bar: 'baz',
};
},
},
});

expect(storage.snapshot('test')).toMatchObject({
presence: 'present',
value: {
foo: {
bar: 'baz',
},
},
});
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -84,12 +84,18 @@ export class MockStorageApi implements StorageApi {
}

async set<T>(key: string, data: T): Promise<void> {
this.data[this.getKeyName(key)] = data;
const serialized = JSON.parse(JSON.stringify(data), (_key, value) => {
if (typeof value === 'object' && value !== null) {
Object.freeze(value);
}
return value;
});
this.data[this.getKeyName(key)] = serialized;
this.notifyChanges({
key,
presence: 'present',
value: data,
newValue: data,
value: serialized,
newValue: serialized,
});
}

Expand Down

0 comments on commit c36b779

Please sign in to comment.