mirror of
https://github.com/bitwarden/browser
synced 2026-02-10 13:40:06 +00:00
Replay without refcount for app state values
This commit is contained in:
@@ -46,6 +46,16 @@ export const mockFromJson = (stub: any) => (stub + "_fromJSON") as any;
|
||||
export function trackEmissions<T>(observable: Observable<T>): T[] {
|
||||
const emissions: T[] = [];
|
||||
observable.subscribe((value) => {
|
||||
switch (value) {
|
||||
case undefined:
|
||||
case null:
|
||||
emissions.push(value);
|
||||
return;
|
||||
default:
|
||||
// process by type
|
||||
break;
|
||||
}
|
||||
|
||||
switch (typeof value) {
|
||||
case "string":
|
||||
case "number":
|
||||
|
||||
@@ -30,6 +30,35 @@ describe("accountService", () => {
|
||||
jest.resetAllMocks();
|
||||
});
|
||||
|
||||
describe("activeAccount$", () => {
|
||||
it("should emit undefined if no account is active", () => {
|
||||
const emissions = trackEmissions(sut.activeAccount$);
|
||||
|
||||
expect(emissions).toEqual([undefined]);
|
||||
});
|
||||
|
||||
it("should emit the active account and status", async () => {
|
||||
const emissions = trackEmissions(sut.activeAccount$);
|
||||
sut.addAccount(userId, userInfo(AuthenticationStatus.Unlocked));
|
||||
sut.switchAccount(userId);
|
||||
|
||||
expect(emissions).toEqual([
|
||||
undefined, // initial value
|
||||
{ id: userId, ...userInfo(AuthenticationStatus.Unlocked) },
|
||||
]);
|
||||
});
|
||||
|
||||
it("should remember the last emitted value", async () => {
|
||||
sut.addAccount(userId, userInfo(AuthenticationStatus.Unlocked));
|
||||
sut.switchAccount(userId);
|
||||
|
||||
expect(await firstValueFrom(sut.activeAccount$)).toEqual({
|
||||
id: userId,
|
||||
...userInfo(AuthenticationStatus.Unlocked),
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe("addAccount", () => {
|
||||
it("should throw if the account already exists", () => {
|
||||
sut.addAccount(userId, userInfo(AuthenticationStatus.Unlocked));
|
||||
|
||||
@@ -4,7 +4,7 @@ import {
|
||||
combineLatestWith,
|
||||
distinctUntilChanged,
|
||||
map,
|
||||
share,
|
||||
shareReplay,
|
||||
} from "rxjs";
|
||||
|
||||
import { AccountInfo, InternalAccountService } from "../../auth/abstractions/account.service";
|
||||
@@ -24,7 +24,7 @@ export class AccountServiceImplementation implements InternalAccountService {
|
||||
combineLatestWith(this.accounts$),
|
||||
map(([id, accounts]) => (id ? { id, ...accounts[id] } : undefined)),
|
||||
distinctUntilChanged(),
|
||||
share()
|
||||
shareReplay({ bufferSize: 1, refCount: false })
|
||||
);
|
||||
accountLock$ = this.lock.asObservable();
|
||||
accountLogout$ = this.logout.asObservable();
|
||||
|
||||
@@ -5,6 +5,7 @@ import {
|
||||
firstValueFrom,
|
||||
map,
|
||||
share,
|
||||
shareReplay,
|
||||
switchMap,
|
||||
tap,
|
||||
} from "rxjs";
|
||||
@@ -95,7 +96,8 @@ class DefaultUserState<T> implements UserState<T> {
|
||||
account != null && account.id != null
|
||||
? userKeyBuilder(account.id, this.keyDefinition)
|
||||
: null
|
||||
)
|
||||
),
|
||||
shareReplay({ bufferSize: 1, refCount: false })
|
||||
);
|
||||
|
||||
const activeAccountData$ = this.formattedKey$.pipe(
|
||||
|
||||
Reference in New Issue
Block a user