1
0
mirror of https://github.com/bitwarden/browser synced 2025-12-17 16:53:34 +00:00

Ps/pm 2910/state framework improvements (#6860)

* Allow for update logic in state update callbacks

* Prefer reading updates to sending in stream

* Inform state providers when they must deserialize

* Update DefaultGlobalState to act more like DefaultUserState

* Fully Implement AbstractStorageService

* Add KeyDefinitionOptions

* Address PR feedback

* More Descriptive Error

---------

Co-authored-by: Justin Baur <19896123+justindbaur@users.noreply.github.com>
This commit is contained in:
Matt Gibson
2023-11-16 14:15:34 -05:00
committed by GitHub
parent bb46907951
commit 29aabeb4f5
25 changed files with 761 additions and 171 deletions

View File

@@ -0,0 +1,81 @@
import { Opaque } from "type-fest";
import { KeyDefinition } from "./key-definition";
import { StateDefinition } from "./state-definition";
const fakeStateDefinition = new StateDefinition("fake", "disk");
type FancyString = Opaque<string, "FancyString">;
describe("KeyDefinition", () => {
describe("constructor", () => {
it("throws on undefined deserializer", () => {
expect(() => {
new KeyDefinition<boolean>(fakeStateDefinition, "fake", {
deserializer: undefined,
});
});
});
});
describe("record", () => {
it("runs custom deserializer for each record value", () => {
const recordDefinition = KeyDefinition.record<boolean>(fakeStateDefinition, "fake", {
// Intentionally negate the value for testing
deserializer: (value) => !value,
});
expect(recordDefinition).toBeTruthy();
expect(recordDefinition.deserializer).toBeTruthy();
const deserializedValue = recordDefinition.deserializer({
test1: false,
test2: true,
});
expect(Object.keys(deserializedValue)).toHaveLength(2);
// Values should have swapped from their initial value
expect(deserializedValue["test1"]).toBeTruthy();
expect(deserializedValue["test2"]).toBeFalsy();
});
it("can handle fancy string type", () => {
// This test is more of a test that I got the typescript typing correctly than actually testing any business logic
const recordDefinition = KeyDefinition.record<boolean, FancyString>(
fakeStateDefinition,
"fake",
{
deserializer: (value) => !value,
}
);
const fancyRecord = recordDefinition.deserializer(
JSON.parse(`{ "myKey": false, "mySecondKey": true }`)
);
expect(fancyRecord).toBeTruthy();
expect(Object.keys(fancyRecord)).toHaveLength(2);
expect(fancyRecord["myKey" as FancyString]).toBeTruthy();
expect(fancyRecord["mySecondKey" as FancyString]).toBeFalsy();
});
});
describe("array", () => {
it("run custom deserializer for each array element", () => {
const arrayDefinition = KeyDefinition.array<boolean>(fakeStateDefinition, "fake", {
deserializer: (value) => !value,
});
expect(arrayDefinition).toBeTruthy();
expect(arrayDefinition.deserializer).toBeTruthy();
const deserializedValue = arrayDefinition.deserializer([false, true]);
expect(deserializedValue).toBeTruthy();
expect(deserializedValue).toHaveLength(2);
expect(deserializedValue[0]).toBeTruthy();
expect(deserializedValue[1]).toBeFalsy();
});
});
});