1
0
mirror of https://github.com/bitwarden/browser.git synced 2024-10-30 08:10:34 +01:00
bitwarden-browser/libs/common/spec/fake-storage.service.ts

74 lines
2.2 KiB
TypeScript
Raw Normal View History

Add State Provider Framework (#6640) * Add StateDefinition Add a class for encapsulation information about state this will often be for a domain but creations of this will exist outside of a specific domain, hence just the name State. * Add KeyDefinition This adds a type that extends state definition into another sub-key and forces creators to define the data that will be stored and how to read the data that they expect to be stored. * Add key-builders helper functions Adds to function to help building keys for both keys scoped to a specific user and for keys scoped to global storage. Co-authored-by: Matt Gibson <MGibson1@users.noreply.github.com> * Add updates$ stream to existing storageServices Original commit by Matt: 823d9546fe059da23ce3353782b4f4134bb36262 Co-authored-by: Matt Gibson <MGibson1@users.noreply.github.com> * Add fromChromeEvent helper Create a helper that creats an Observable from a chrome event and removes the listener when the subscription is completed. * Implement `updates$` property for chrome storage Use fromChromeEvent to create an observable from chrome event and map that into our expected shape. * Add GlobalState Abstractions * Add UserState Abstractions * Add Default Implementations of User/Global state Co-authored-by: Matt Gibson <MGibson1@users.noreply.github.com> * Add Barrel File for state Co-authored-by: Matt Gibson <MGibson1@users.noreply.github.com> * Fix ChromeStorageServices * Rework fromChromeEvent Rework fromChromeEvent so we have to lie to TS less and remove unneeded generics. I did this by caring less about the function and more about the parameters only. Co-authored-by: Matt Gibson <MGibson1@users.noreply.github.com> * Fix UserStateProvider Test * Add Inner Mock & Assert Calls * Update Tests to use new keys Use different key format * Prefer returns over mutations in update * Update Tests * Address PR Feedback * Be stricter with userId parameter * Add Better Way To Determine if it was a remove * Fix Web & Browser Storage Services * Fix Desktop & CLI Storage Services * Fix Test Storage Service * Use createKey Helper * Prefer implement to extending * Determine storage location in providers * Export default providers publicly * Fix user state tests * Name tests * Fix CLI * Prefer Implement In Chrome Storage * Remove Secure Storage Option Also throw an exception for subscribes to the secure storage observable. * Update apps/browser/src/platform/browser/from-chrome-event.ts Co-authored-by: Oscar Hinton <Hinton@users.noreply.github.com> * Enforce state module barrel file * Fix Linting Error * Allow state module import from other modules * Globally Unregister fromChromeEvent Listeners Changed fromChromeEvent to add its listeners through the BrowserApi, so that they will be unregistered when safari closes. * Test default global state * Use Proper Casing in Parameter * Address Feedback * Update libs/common/src/platform/state/key-definition.ts Co-authored-by: Oscar Hinton <Hinton@users.noreply.github.com> * Add `buildCacheKey` Method * Fix lint errors * Add Comment Co-authored-by: Oscar Hinton <Hinton@users.noreply.github.com> * Use Generic in callback parameter * Refactor Out DerivedStateDefinition * Persist Listener Return Type * Add Ticket Link --------- Co-authored-by: Matt Gibson <MGibson1@users.noreply.github.com> Co-authored-by: Matt Gibson <mgibson@bitwarden.com> Co-authored-by: Oscar Hinton <Hinton@users.noreply.github.com>
2023-11-09 23:06:42 +01:00
import { MockProxy, mock } from "jest-mock-extended";
import { Subject } from "rxjs";
import {
AbstractStorageService,
StorageUpdate,
} from "../src/platform/abstractions/storage.service";
import { StorageOptions } from "../src/platform/models/domain/storage-options";
export class FakeStorageService implements AbstractStorageService {
private store: Record<string, unknown>;
private updatesSubject = new Subject<StorageUpdate>();
private _valuesRequireDeserialization = false;
Add State Provider Framework (#6640) * Add StateDefinition Add a class for encapsulation information about state this will often be for a domain but creations of this will exist outside of a specific domain, hence just the name State. * Add KeyDefinition This adds a type that extends state definition into another sub-key and forces creators to define the data that will be stored and how to read the data that they expect to be stored. * Add key-builders helper functions Adds to function to help building keys for both keys scoped to a specific user and for keys scoped to global storage. Co-authored-by: Matt Gibson <MGibson1@users.noreply.github.com> * Add updates$ stream to existing storageServices Original commit by Matt: 823d9546fe059da23ce3353782b4f4134bb36262 Co-authored-by: Matt Gibson <MGibson1@users.noreply.github.com> * Add fromChromeEvent helper Create a helper that creats an Observable from a chrome event and removes the listener when the subscription is completed. * Implement `updates$` property for chrome storage Use fromChromeEvent to create an observable from chrome event and map that into our expected shape. * Add GlobalState Abstractions * Add UserState Abstractions * Add Default Implementations of User/Global state Co-authored-by: Matt Gibson <MGibson1@users.noreply.github.com> * Add Barrel File for state Co-authored-by: Matt Gibson <MGibson1@users.noreply.github.com> * Fix ChromeStorageServices * Rework fromChromeEvent Rework fromChromeEvent so we have to lie to TS less and remove unneeded generics. I did this by caring less about the function and more about the parameters only. Co-authored-by: Matt Gibson <MGibson1@users.noreply.github.com> * Fix UserStateProvider Test * Add Inner Mock & Assert Calls * Update Tests to use new keys Use different key format * Prefer returns over mutations in update * Update Tests * Address PR Feedback * Be stricter with userId parameter * Add Better Way To Determine if it was a remove * Fix Web & Browser Storage Services * Fix Desktop & CLI Storage Services * Fix Test Storage Service * Use createKey Helper * Prefer implement to extending * Determine storage location in providers * Export default providers publicly * Fix user state tests * Name tests * Fix CLI * Prefer Implement In Chrome Storage * Remove Secure Storage Option Also throw an exception for subscribes to the secure storage observable. * Update apps/browser/src/platform/browser/from-chrome-event.ts Co-authored-by: Oscar Hinton <Hinton@users.noreply.github.com> * Enforce state module barrel file * Fix Linting Error * Allow state module import from other modules * Globally Unregister fromChromeEvent Listeners Changed fromChromeEvent to add its listeners through the BrowserApi, so that they will be unregistered when safari closes. * Test default global state * Use Proper Casing in Parameter * Address Feedback * Update libs/common/src/platform/state/key-definition.ts Co-authored-by: Oscar Hinton <Hinton@users.noreply.github.com> * Add `buildCacheKey` Method * Fix lint errors * Add Comment Co-authored-by: Oscar Hinton <Hinton@users.noreply.github.com> * Use Generic in callback parameter * Refactor Out DerivedStateDefinition * Persist Listener Return Type * Add Ticket Link --------- Co-authored-by: Matt Gibson <MGibson1@users.noreply.github.com> Co-authored-by: Matt Gibson <mgibson@bitwarden.com> Co-authored-by: Oscar Hinton <Hinton@users.noreply.github.com>
2023-11-09 23:06:42 +01:00
/**
* Returns a mock of a {@see AbstractStorageService} for asserting the expected
* amount of calls. It is not recommended to use this to mock implementations as
* they are not respected.
*/
mock: MockProxy<AbstractStorageService>;
constructor(initial?: Record<string, unknown>) {
this.store = initial ?? {};
this.mock = mock<AbstractStorageService>();
}
/**
* Updates the internal store for this fake implementation, this bypasses any mock calls
* or updates to the {@link updates$} observable.
* @param store
*/
internalUpdateStore(store: Record<string, unknown>) {
this.store = store;
}
get internalStore() {
return this.store;
}
internalUpdateValuesRequireDeserialization(value: boolean) {
this._valuesRequireDeserialization = value;
}
get valuesRequireDeserialization(): boolean {
return this._valuesRequireDeserialization;
}
Add State Provider Framework (#6640) * Add StateDefinition Add a class for encapsulation information about state this will often be for a domain but creations of this will exist outside of a specific domain, hence just the name State. * Add KeyDefinition This adds a type that extends state definition into another sub-key and forces creators to define the data that will be stored and how to read the data that they expect to be stored. * Add key-builders helper functions Adds to function to help building keys for both keys scoped to a specific user and for keys scoped to global storage. Co-authored-by: Matt Gibson <MGibson1@users.noreply.github.com> * Add updates$ stream to existing storageServices Original commit by Matt: 823d9546fe059da23ce3353782b4f4134bb36262 Co-authored-by: Matt Gibson <MGibson1@users.noreply.github.com> * Add fromChromeEvent helper Create a helper that creats an Observable from a chrome event and removes the listener when the subscription is completed. * Implement `updates$` property for chrome storage Use fromChromeEvent to create an observable from chrome event and map that into our expected shape. * Add GlobalState Abstractions * Add UserState Abstractions * Add Default Implementations of User/Global state Co-authored-by: Matt Gibson <MGibson1@users.noreply.github.com> * Add Barrel File for state Co-authored-by: Matt Gibson <MGibson1@users.noreply.github.com> * Fix ChromeStorageServices * Rework fromChromeEvent Rework fromChromeEvent so we have to lie to TS less and remove unneeded generics. I did this by caring less about the function and more about the parameters only. Co-authored-by: Matt Gibson <MGibson1@users.noreply.github.com> * Fix UserStateProvider Test * Add Inner Mock & Assert Calls * Update Tests to use new keys Use different key format * Prefer returns over mutations in update * Update Tests * Address PR Feedback * Be stricter with userId parameter * Add Better Way To Determine if it was a remove * Fix Web & Browser Storage Services * Fix Desktop & CLI Storage Services * Fix Test Storage Service * Use createKey Helper * Prefer implement to extending * Determine storage location in providers * Export default providers publicly * Fix user state tests * Name tests * Fix CLI * Prefer Implement In Chrome Storage * Remove Secure Storage Option Also throw an exception for subscribes to the secure storage observable. * Update apps/browser/src/platform/browser/from-chrome-event.ts Co-authored-by: Oscar Hinton <Hinton@users.noreply.github.com> * Enforce state module barrel file * Fix Linting Error * Allow state module import from other modules * Globally Unregister fromChromeEvent Listeners Changed fromChromeEvent to add its listeners through the BrowserApi, so that they will be unregistered when safari closes. * Test default global state * Use Proper Casing in Parameter * Address Feedback * Update libs/common/src/platform/state/key-definition.ts Co-authored-by: Oscar Hinton <Hinton@users.noreply.github.com> * Add `buildCacheKey` Method * Fix lint errors * Add Comment Co-authored-by: Oscar Hinton <Hinton@users.noreply.github.com> * Use Generic in callback parameter * Refactor Out DerivedStateDefinition * Persist Listener Return Type * Add Ticket Link --------- Co-authored-by: Matt Gibson <MGibson1@users.noreply.github.com> Co-authored-by: Matt Gibson <mgibson@bitwarden.com> Co-authored-by: Oscar Hinton <Hinton@users.noreply.github.com>
2023-11-09 23:06:42 +01:00
get updates$() {
return this.updatesSubject.asObservable();
}
get<T>(key: string, options?: StorageOptions): Promise<T> {
this.mock.get(key, options);
const value = this.store[key] as T;
return Promise.resolve(value);
}
has(key: string, options?: StorageOptions): Promise<boolean> {
this.mock.has(key, options);
return Promise.resolve(this.store[key] != null);
}
save<T>(key: string, obj: T, options?: StorageOptions): Promise<void> {
Ps/avoid state emit until updated (#7198) * Add a small default time to limit timing failures * Handle subscription race conditions * Add Symbols to tracked emission types This is a bit of a cheat, but Symbols can't be cloned, so we need to nudge them to something we can handle. They are rare enough that anyone hitting this is likely to expect some special handling. * Ref count state listeners to minimize storage activity * Ensure statuses are updated * Remove notes * Use `test` when gramatically more proper * Copy race and subscription improvements to single user * Simplify observer initialization * Correct parameter names * Simplify update promises test we don't accidentally deadlock along the `getFromState` path * Fix save mock * WIP: most tests working * Avoid infinite update loop * Avoid potential deadlocks with awaiting assigned promises We were awaiting a promise assigned in a thenable. It turns out that assignment occurs before all thenables are concatenated, which can cause deadlocks. Likely, these were not showing up in tests because we're using very quick memory storage. * Fix update deadlock test * Add user update tests * Assert no double emit for multiple observers * Add use intent to method name * Ensure new subscriptions receive only newest data TODO: is this worth doing for active user state? * Remove unnecessary design requirement We don't need to await an executing update promise, we can support two emissions as long as the observable is guaranteed to get the new data. * Cleanup await spam * test cleanup option behavior * Remove unnecessary typecast * Throw over coerce for definition options * Fix state$ observable durability on cleanup
2023-12-13 14:06:24 +01:00
this.mock.save(key, obj, options);
Add State Provider Framework (#6640) * Add StateDefinition Add a class for encapsulation information about state this will often be for a domain but creations of this will exist outside of a specific domain, hence just the name State. * Add KeyDefinition This adds a type that extends state definition into another sub-key and forces creators to define the data that will be stored and how to read the data that they expect to be stored. * Add key-builders helper functions Adds to function to help building keys for both keys scoped to a specific user and for keys scoped to global storage. Co-authored-by: Matt Gibson <MGibson1@users.noreply.github.com> * Add updates$ stream to existing storageServices Original commit by Matt: 823d9546fe059da23ce3353782b4f4134bb36262 Co-authored-by: Matt Gibson <MGibson1@users.noreply.github.com> * Add fromChromeEvent helper Create a helper that creats an Observable from a chrome event and removes the listener when the subscription is completed. * Implement `updates$` property for chrome storage Use fromChromeEvent to create an observable from chrome event and map that into our expected shape. * Add GlobalState Abstractions * Add UserState Abstractions * Add Default Implementations of User/Global state Co-authored-by: Matt Gibson <MGibson1@users.noreply.github.com> * Add Barrel File for state Co-authored-by: Matt Gibson <MGibson1@users.noreply.github.com> * Fix ChromeStorageServices * Rework fromChromeEvent Rework fromChromeEvent so we have to lie to TS less and remove unneeded generics. I did this by caring less about the function and more about the parameters only. Co-authored-by: Matt Gibson <MGibson1@users.noreply.github.com> * Fix UserStateProvider Test * Add Inner Mock & Assert Calls * Update Tests to use new keys Use different key format * Prefer returns over mutations in update * Update Tests * Address PR Feedback * Be stricter with userId parameter * Add Better Way To Determine if it was a remove * Fix Web & Browser Storage Services * Fix Desktop & CLI Storage Services * Fix Test Storage Service * Use createKey Helper * Prefer implement to extending * Determine storage location in providers * Export default providers publicly * Fix user state tests * Name tests * Fix CLI * Prefer Implement In Chrome Storage * Remove Secure Storage Option Also throw an exception for subscribes to the secure storage observable. * Update apps/browser/src/platform/browser/from-chrome-event.ts Co-authored-by: Oscar Hinton <Hinton@users.noreply.github.com> * Enforce state module barrel file * Fix Linting Error * Allow state module import from other modules * Globally Unregister fromChromeEvent Listeners Changed fromChromeEvent to add its listeners through the BrowserApi, so that they will be unregistered when safari closes. * Test default global state * Use Proper Casing in Parameter * Address Feedback * Update libs/common/src/platform/state/key-definition.ts Co-authored-by: Oscar Hinton <Hinton@users.noreply.github.com> * Add `buildCacheKey` Method * Fix lint errors * Add Comment Co-authored-by: Oscar Hinton <Hinton@users.noreply.github.com> * Use Generic in callback parameter * Refactor Out DerivedStateDefinition * Persist Listener Return Type * Add Ticket Link --------- Co-authored-by: Matt Gibson <MGibson1@users.noreply.github.com> Co-authored-by: Matt Gibson <mgibson@bitwarden.com> Co-authored-by: Oscar Hinton <Hinton@users.noreply.github.com>
2023-11-09 23:06:42 +01:00
this.store[key] = obj;
this.updatesSubject.next({ key: key, updateType: "save" });
Add State Provider Framework (#6640) * Add StateDefinition Add a class for encapsulation information about state this will often be for a domain but creations of this will exist outside of a specific domain, hence just the name State. * Add KeyDefinition This adds a type that extends state definition into another sub-key and forces creators to define the data that will be stored and how to read the data that they expect to be stored. * Add key-builders helper functions Adds to function to help building keys for both keys scoped to a specific user and for keys scoped to global storage. Co-authored-by: Matt Gibson <MGibson1@users.noreply.github.com> * Add updates$ stream to existing storageServices Original commit by Matt: 823d9546fe059da23ce3353782b4f4134bb36262 Co-authored-by: Matt Gibson <MGibson1@users.noreply.github.com> * Add fromChromeEvent helper Create a helper that creats an Observable from a chrome event and removes the listener when the subscription is completed. * Implement `updates$` property for chrome storage Use fromChromeEvent to create an observable from chrome event and map that into our expected shape. * Add GlobalState Abstractions * Add UserState Abstractions * Add Default Implementations of User/Global state Co-authored-by: Matt Gibson <MGibson1@users.noreply.github.com> * Add Barrel File for state Co-authored-by: Matt Gibson <MGibson1@users.noreply.github.com> * Fix ChromeStorageServices * Rework fromChromeEvent Rework fromChromeEvent so we have to lie to TS less and remove unneeded generics. I did this by caring less about the function and more about the parameters only. Co-authored-by: Matt Gibson <MGibson1@users.noreply.github.com> * Fix UserStateProvider Test * Add Inner Mock & Assert Calls * Update Tests to use new keys Use different key format * Prefer returns over mutations in update * Update Tests * Address PR Feedback * Be stricter with userId parameter * Add Better Way To Determine if it was a remove * Fix Web & Browser Storage Services * Fix Desktop & CLI Storage Services * Fix Test Storage Service * Use createKey Helper * Prefer implement to extending * Determine storage location in providers * Export default providers publicly * Fix user state tests * Name tests * Fix CLI * Prefer Implement In Chrome Storage * Remove Secure Storage Option Also throw an exception for subscribes to the secure storage observable. * Update apps/browser/src/platform/browser/from-chrome-event.ts Co-authored-by: Oscar Hinton <Hinton@users.noreply.github.com> * Enforce state module barrel file * Fix Linting Error * Allow state module import from other modules * Globally Unregister fromChromeEvent Listeners Changed fromChromeEvent to add its listeners through the BrowserApi, so that they will be unregistered when safari closes. * Test default global state * Use Proper Casing in Parameter * Address Feedback * Update libs/common/src/platform/state/key-definition.ts Co-authored-by: Oscar Hinton <Hinton@users.noreply.github.com> * Add `buildCacheKey` Method * Fix lint errors * Add Comment Co-authored-by: Oscar Hinton <Hinton@users.noreply.github.com> * Use Generic in callback parameter * Refactor Out DerivedStateDefinition * Persist Listener Return Type * Add Ticket Link --------- Co-authored-by: Matt Gibson <MGibson1@users.noreply.github.com> Co-authored-by: Matt Gibson <mgibson@bitwarden.com> Co-authored-by: Oscar Hinton <Hinton@users.noreply.github.com>
2023-11-09 23:06:42 +01:00
return Promise.resolve();
}
remove(key: string, options?: StorageOptions): Promise<void> {
this.mock.remove(key, options);
delete this.store[key];
this.updatesSubject.next({ key: key, updateType: "remove" });
Add State Provider Framework (#6640) * Add StateDefinition Add a class for encapsulation information about state this will often be for a domain but creations of this will exist outside of a specific domain, hence just the name State. * Add KeyDefinition This adds a type that extends state definition into another sub-key and forces creators to define the data that will be stored and how to read the data that they expect to be stored. * Add key-builders helper functions Adds to function to help building keys for both keys scoped to a specific user and for keys scoped to global storage. Co-authored-by: Matt Gibson <MGibson1@users.noreply.github.com> * Add updates$ stream to existing storageServices Original commit by Matt: 823d9546fe059da23ce3353782b4f4134bb36262 Co-authored-by: Matt Gibson <MGibson1@users.noreply.github.com> * Add fromChromeEvent helper Create a helper that creats an Observable from a chrome event and removes the listener when the subscription is completed. * Implement `updates$` property for chrome storage Use fromChromeEvent to create an observable from chrome event and map that into our expected shape. * Add GlobalState Abstractions * Add UserState Abstractions * Add Default Implementations of User/Global state Co-authored-by: Matt Gibson <MGibson1@users.noreply.github.com> * Add Barrel File for state Co-authored-by: Matt Gibson <MGibson1@users.noreply.github.com> * Fix ChromeStorageServices * Rework fromChromeEvent Rework fromChromeEvent so we have to lie to TS less and remove unneeded generics. I did this by caring less about the function and more about the parameters only. Co-authored-by: Matt Gibson <MGibson1@users.noreply.github.com> * Fix UserStateProvider Test * Add Inner Mock & Assert Calls * Update Tests to use new keys Use different key format * Prefer returns over mutations in update * Update Tests * Address PR Feedback * Be stricter with userId parameter * Add Better Way To Determine if it was a remove * Fix Web & Browser Storage Services * Fix Desktop & CLI Storage Services * Fix Test Storage Service * Use createKey Helper * Prefer implement to extending * Determine storage location in providers * Export default providers publicly * Fix user state tests * Name tests * Fix CLI * Prefer Implement In Chrome Storage * Remove Secure Storage Option Also throw an exception for subscribes to the secure storage observable. * Update apps/browser/src/platform/browser/from-chrome-event.ts Co-authored-by: Oscar Hinton <Hinton@users.noreply.github.com> * Enforce state module barrel file * Fix Linting Error * Allow state module import from other modules * Globally Unregister fromChromeEvent Listeners Changed fromChromeEvent to add its listeners through the BrowserApi, so that they will be unregistered when safari closes. * Test default global state * Use Proper Casing in Parameter * Address Feedback * Update libs/common/src/platform/state/key-definition.ts Co-authored-by: Oscar Hinton <Hinton@users.noreply.github.com> * Add `buildCacheKey` Method * Fix lint errors * Add Comment Co-authored-by: Oscar Hinton <Hinton@users.noreply.github.com> * Use Generic in callback parameter * Refactor Out DerivedStateDefinition * Persist Listener Return Type * Add Ticket Link --------- Co-authored-by: Matt Gibson <MGibson1@users.noreply.github.com> Co-authored-by: Matt Gibson <mgibson@bitwarden.com> Co-authored-by: Oscar Hinton <Hinton@users.noreply.github.com>
2023-11-09 23:06:42 +01:00
return Promise.resolve();
}
}