mirror of
https://github.com/bitwarden/browser
synced 2025-12-12 14:23:32 +00:00
Require lifetime specification of user-scoped data (#8669)
* Require lifetime specification of user-scoped data * Decouple tests for different classes This coupling assumed constant interfaces with classes that isn't a guarantee and requires significant acrobatics to make types work, now that key definitions are not a consistent base. * Fix types
This commit is contained in:
@@ -7,6 +7,7 @@ import { StorageServiceProvider } from "../../services/storage-service.provider"
|
||||
import { KeyDefinition } from "../key-definition";
|
||||
import { StateDefinition } from "../state-definition";
|
||||
import { StateEventRegistrarService } from "../state-event-registrar.service";
|
||||
import { UserKeyDefinition } from "../user-key-definition";
|
||||
|
||||
import { DefaultActiveUserState } from "./default-active-user-state";
|
||||
import { DefaultActiveUserStateProvider } from "./default-active-user-state.provider";
|
||||
@@ -41,94 +42,132 @@ describe("Specific State Providers", () => {
|
||||
const fakeDiskStateDefinition = new StateDefinition("fake", "disk");
|
||||
const fakeAlternateDiskStateDefinition = new StateDefinition("fakeAlternate", "disk");
|
||||
const fakeMemoryStateDefinition = new StateDefinition("fake", "memory");
|
||||
|
||||
const fakeDiskKeyDefinition = new KeyDefinition<boolean>(fakeDiskStateDefinition, "fake", {
|
||||
deserializer: (b) => b,
|
||||
});
|
||||
const fakeAlternateKeyDefinition = new KeyDefinition<boolean>(
|
||||
fakeAlternateDiskStateDefinition,
|
||||
"fake",
|
||||
{
|
||||
const makeKeyDefinition = (stateDefinition: StateDefinition, key: string) =>
|
||||
new KeyDefinition<boolean>(stateDefinition, key, {
|
||||
deserializer: (b) => b,
|
||||
},
|
||||
);
|
||||
const fakeMemoryKeyDefinition = new KeyDefinition<boolean>(fakeMemoryStateDefinition, "fake", {
|
||||
deserializer: (b) => b,
|
||||
});
|
||||
const fakeDiskKeyDefinitionAlternate = new KeyDefinition<boolean>(
|
||||
fakeDiskStateDefinition,
|
||||
"fakeAlternate",
|
||||
{
|
||||
});
|
||||
const makeUserKeyDefinition = (stateDefinition: StateDefinition, key: string) =>
|
||||
new UserKeyDefinition<boolean>(stateDefinition, key, {
|
||||
deserializer: (b) => b,
|
||||
clearOn: [],
|
||||
});
|
||||
const keyDefinitions = {
|
||||
disk: {
|
||||
keyDefinition: makeKeyDefinition(fakeDiskStateDefinition, "fake"),
|
||||
userKeyDefinition: makeUserKeyDefinition(fakeDiskStateDefinition, "fake"),
|
||||
altKeyDefinition: makeKeyDefinition(fakeDiskStateDefinition, "fakeAlternate"),
|
||||
altUserKeyDefinition: makeUserKeyDefinition(fakeDiskStateDefinition, "fakeAlternate"),
|
||||
},
|
||||
);
|
||||
memory: {
|
||||
keyDefinition: makeKeyDefinition(fakeMemoryStateDefinition, "fake"),
|
||||
userKeyDefinition: makeUserKeyDefinition(fakeMemoryStateDefinition, "fake"),
|
||||
},
|
||||
alternateDisk: {
|
||||
keyDefinition: makeKeyDefinition(fakeAlternateDiskStateDefinition, "fake"),
|
||||
userKeyDefinition: makeUserKeyDefinition(fakeAlternateDiskStateDefinition, "fake"),
|
||||
},
|
||||
};
|
||||
|
||||
const globalAndSingle = [
|
||||
{
|
||||
getMethod: (keyDefinition: KeyDefinition<boolean>) => globalSut.get(keyDefinition),
|
||||
expectedInstance: DefaultGlobalState,
|
||||
},
|
||||
{
|
||||
// Use a static user id so that it has the same signature as the rest and then write special tests
|
||||
// handling differing user id
|
||||
getMethod: (keyDefinition: KeyDefinition<boolean>) => singleSut.get(fakeUser1, keyDefinition),
|
||||
expectedInstance: DefaultSingleUserState,
|
||||
},
|
||||
];
|
||||
describe("active provider", () => {
|
||||
it("returns a DefaultActiveUserState", () => {
|
||||
const state = activeSut.get(keyDefinitions.disk.userKeyDefinition);
|
||||
|
||||
describe.each([
|
||||
{
|
||||
getMethod: (keyDefinition: KeyDefinition<boolean>) => activeSut.get(keyDefinition),
|
||||
expectedInstance: DefaultActiveUserState,
|
||||
},
|
||||
...globalAndSingle,
|
||||
])("common behavior %s", ({ getMethod, expectedInstance }) => {
|
||||
it("returns expected instance", () => {
|
||||
const state = getMethod(fakeDiskKeyDefinition);
|
||||
|
||||
expect(state).toBeTruthy();
|
||||
expect(state).toBeInstanceOf(expectedInstance);
|
||||
expect(state).toBeInstanceOf(DefaultActiveUserState);
|
||||
});
|
||||
|
||||
it("returns different instances when the storage location differs", () => {
|
||||
const stateDisk = getMethod(fakeDiskKeyDefinition);
|
||||
const stateMemory = getMethod(fakeMemoryKeyDefinition);
|
||||
const stateDisk = activeSut.get(keyDefinitions.disk.userKeyDefinition);
|
||||
const stateMemory = activeSut.get(keyDefinitions.memory.userKeyDefinition);
|
||||
expect(stateDisk).not.toStrictEqual(stateMemory);
|
||||
});
|
||||
|
||||
it("returns different instances when the state name differs", () => {
|
||||
const state = getMethod(fakeDiskKeyDefinition);
|
||||
const stateAlt = getMethod(fakeAlternateKeyDefinition);
|
||||
const state = activeSut.get(keyDefinitions.disk.userKeyDefinition);
|
||||
const stateAlt = activeSut.get(keyDefinitions.alternateDisk.userKeyDefinition);
|
||||
expect(state).not.toStrictEqual(stateAlt);
|
||||
});
|
||||
|
||||
it("returns different instances when the key differs", () => {
|
||||
const state = getMethod(fakeDiskKeyDefinition);
|
||||
const stateAlt = getMethod(fakeDiskKeyDefinitionAlternate);
|
||||
const state = activeSut.get(keyDefinitions.disk.userKeyDefinition);
|
||||
const stateAlt = activeSut.get(keyDefinitions.disk.altUserKeyDefinition);
|
||||
expect(state).not.toStrictEqual(stateAlt);
|
||||
});
|
||||
});
|
||||
|
||||
describe.each(globalAndSingle)("Global And Single Behavior", ({ getMethod }) => {
|
||||
it("returns cached instance on repeated request", () => {
|
||||
const stateFirst = getMethod(fakeDiskKeyDefinition);
|
||||
const stateCached = getMethod(fakeDiskKeyDefinition);
|
||||
expect(stateFirst).toStrictEqual(stateCached);
|
||||
});
|
||||
});
|
||||
describe("single provider", () => {
|
||||
it("returns a DefaultSingleUserState", () => {
|
||||
const state = singleSut.get(fakeUser1, keyDefinitions.disk.userKeyDefinition);
|
||||
|
||||
expect(state).toBeInstanceOf(DefaultSingleUserState);
|
||||
});
|
||||
|
||||
it("returns different instances when the storage location differs", () => {
|
||||
const stateDisk = singleSut.get(fakeUser1, keyDefinitions.disk.userKeyDefinition);
|
||||
const stateMemory = singleSut.get(fakeUser1, keyDefinitions.memory.userKeyDefinition);
|
||||
expect(stateDisk).not.toStrictEqual(stateMemory);
|
||||
});
|
||||
|
||||
it("returns different instances when the state name differs", () => {
|
||||
const state = singleSut.get(fakeUser1, keyDefinitions.disk.userKeyDefinition);
|
||||
const stateAlt = singleSut.get(fakeUser1, keyDefinitions.alternateDisk.userKeyDefinition);
|
||||
expect(state).not.toStrictEqual(stateAlt);
|
||||
});
|
||||
|
||||
it("returns different instances when the key differs", () => {
|
||||
const state = singleSut.get(fakeUser1, keyDefinitions.disk.userKeyDefinition);
|
||||
const stateAlt = singleSut.get(fakeUser1, keyDefinitions.disk.altUserKeyDefinition);
|
||||
expect(state).not.toStrictEqual(stateAlt);
|
||||
});
|
||||
|
||||
describe("DefaultSingleUserStateProvider only behavior", () => {
|
||||
const fakeUser2 = "00000000-0000-1000-a000-000000000002" as UserId;
|
||||
|
||||
it("returns different instances when the user id differs", () => {
|
||||
const user1State = singleSut.get(fakeUser1, fakeDiskKeyDefinition);
|
||||
const user2State = singleSut.get(fakeUser2, fakeDiskKeyDefinition);
|
||||
const user1State = singleSut.get(fakeUser1, keyDefinitions.disk.userKeyDefinition);
|
||||
const user2State = singleSut.get(fakeUser2, keyDefinitions.disk.userKeyDefinition);
|
||||
expect(user1State).not.toStrictEqual(user2State);
|
||||
});
|
||||
|
||||
it("returns an instance with the userId property corresponding to the user id passed in", () => {
|
||||
const userState = singleSut.get(fakeUser1, fakeDiskKeyDefinition);
|
||||
const userState = singleSut.get(fakeUser1, keyDefinitions.disk.userKeyDefinition);
|
||||
expect(userState.userId).toBe(fakeUser1);
|
||||
});
|
||||
|
||||
it("returns cached instance on repeated request", () => {
|
||||
const stateFirst = singleSut.get(fakeUser1, keyDefinitions.disk.userKeyDefinition);
|
||||
const stateCached = singleSut.get(fakeUser1, keyDefinitions.disk.userKeyDefinition);
|
||||
expect(stateFirst).toStrictEqual(stateCached);
|
||||
});
|
||||
});
|
||||
|
||||
describe("global provider", () => {
|
||||
it("returns a DefaultGlobalState", () => {
|
||||
const state = globalSut.get(keyDefinitions.disk.keyDefinition);
|
||||
|
||||
expect(state).toBeInstanceOf(DefaultGlobalState);
|
||||
});
|
||||
|
||||
it("returns different instances when the storage location differs", () => {
|
||||
const stateDisk = globalSut.get(keyDefinitions.disk.keyDefinition);
|
||||
const stateMemory = globalSut.get(keyDefinitions.memory.keyDefinition);
|
||||
expect(stateDisk).not.toStrictEqual(stateMemory);
|
||||
});
|
||||
|
||||
it("returns different instances when the state name differs", () => {
|
||||
const state = globalSut.get(keyDefinitions.disk.keyDefinition);
|
||||
const stateAlt = globalSut.get(keyDefinitions.alternateDisk.keyDefinition);
|
||||
expect(state).not.toStrictEqual(stateAlt);
|
||||
});
|
||||
|
||||
it("returns different instances when the key differs", () => {
|
||||
const state = globalSut.get(keyDefinitions.disk.keyDefinition);
|
||||
const stateAlt = globalSut.get(keyDefinitions.disk.altKeyDefinition);
|
||||
expect(state).not.toStrictEqual(stateAlt);
|
||||
});
|
||||
|
||||
it("returns cached instance on repeated request", () => {
|
||||
const stateFirst = globalSut.get(keyDefinitions.disk.keyDefinition);
|
||||
const stateCached = globalSut.get(keyDefinitions.disk.keyDefinition);
|
||||
expect(stateFirst).toStrictEqual(stateCached);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user