1
0
mirror of https://github.com/bitwarden/browser.git synced 2024-10-22 07:50:04 +02:00

unit test withLatestReady

This commit is contained in:
✨ Audrey ✨ 2024-10-16 16:54:16 -04:00
parent 1a5dae51d3
commit 919984c9c5
No known key found for this signature in database
GPG Key ID: 0CF8B4C0D9088B97
10 changed files with 153 additions and 9 deletions

View File

@ -6,7 +6,14 @@ import { of, firstValueFrom, Subject, tap, EmptyError } from "rxjs";
import { awaitAsync, trackEmissions } from "../../spec";
import { anyComplete, distinctIfShallowMatch, on, ready, reduceCollection } from "./rx";
import {
anyComplete,
distinctIfShallowMatch,
on,
ready,
reduceCollection,
withLatestReady,
} from "./rx";
describe("reduceCollection", () => {
it.each([[null], [undefined], [[]]])(
@ -289,6 +296,142 @@ describe("ready", () => {
});
});
describe("withLatestReady", () => {
it("connects when subscribed", () => {
const watch$ = new Subject<string>();
let connected = false;
const source$ = new Subject<number>().pipe(tap({ subscribe: () => (connected = true) }));
// precondition: ready$ should be cold
const ready$ = source$.pipe(withLatestReady(watch$));
expect(connected).toBe(false);
ready$.subscribe();
expect(connected).toBe(true);
});
it("suppresses source emissions until its watch emits", () => {
const watch$ = new Subject<string>();
const source$ = new Subject<number>();
const ready$ = source$.pipe(withLatestReady(watch$));
const results: [number, string][] = [];
ready$.subscribe((n) => results.push(n));
// precondition: no emissions
source$.next(1);
expect(results).toEqual([]);
watch$.next("watch");
expect(results).toEqual([[1, "watch"]]);
});
it("emits the last source emission when its watch emits", () => {
const watch$ = new Subject<string>();
const source$ = new Subject<number>();
const ready$ = source$.pipe(withLatestReady(watch$));
const results: [number, string][] = [];
ready$.subscribe((n) => results.push(n));
// precondition: no emissions
source$.next(1);
expect(results).toEqual([]);
source$.next(2);
watch$.next("watch");
expect(results).toEqual([[2, "watch"]]);
});
it("emits all source emissions after its watch emits", () => {
const watch$ = new Subject<string>();
const source$ = new Subject<number>();
const ready$ = source$.pipe(withLatestReady(watch$));
const results: [number, string][] = [];
ready$.subscribe((n) => results.push(n));
watch$.next("watch");
source$.next(1);
source$.next(2);
expect(results).toEqual([
[1, "watch"],
[2, "watch"],
]);
});
it("appends the latest watch emission", () => {
const watch$ = new Subject<string>();
const source$ = new Subject<number>();
const ready$ = source$.pipe(withLatestReady(watch$));
const results: [number, string][] = [];
ready$.subscribe((n) => results.push(n));
watch$.next("ignored");
watch$.next("watch");
source$.next(1);
watch$.next("ignored");
watch$.next("watch");
source$.next(2);
expect(results).toEqual([
[1, "watch"],
[2, "watch"],
]);
});
it("completes when its source completes", () => {
const watch$ = new Subject<string>();
const source$ = new Subject<number>();
const ready$ = source$.pipe(withLatestReady(watch$));
let completed = false;
ready$.subscribe({ complete: () => (completed = true) });
source$.complete();
expect(completed).toBeTruthy();
});
it("errors when its source errors", () => {
const watch$ = new Subject<void>();
const source$ = new Subject<number>();
const ready$ = source$.pipe(withLatestReady(watch$));
const expected = { some: "error" };
let error = null;
ready$.subscribe({ error: (e: unknown) => (error = e) });
source$.error(expected);
expect(error).toEqual(expected);
});
it("errors when its watch errors", () => {
const watch$ = new Subject<string>();
const source$ = new Subject<number>();
const ready$ = source$.pipe(withLatestReady(watch$));
const expected = { some: "error" };
let error = null;
ready$.subscribe({ error: (e: unknown) => (error = e) });
watch$.error(expected);
expect(error).toEqual(expected);
});
it("errors when its watch completes before emitting", () => {
const watch$ = new Subject<string>();
const source$ = new Subject<number>();
const ready$ = source$.pipe(withLatestReady(watch$));
let error = null;
ready$.subscribe({ error: (e: unknown) => (error = e) });
watch$.complete();
expect(error).toBeInstanceOf(EmptyError);
});
});
describe("on", () => {
it("connects when subscribed", () => {
const watch$ = new Subject<void>();

View File

@ -112,7 +112,7 @@ export function ready<T>(watch$: Observable<any> | Observable<any>[]) {
export function withLatestReady<Source, Watch>(
watch$: Observable<Watch>,
): OperatorFunction<Source, [Source, Watch]> {
return pipe((source$) => {
return connect((source$) => {
// these subscriptions are safe because `source$` connects only after there
// is an external subscriber.
const source = new ReplaySubject<Source>(1);

View File

@ -12,7 +12,7 @@ import {
import { PrivateClassifier } from "@bitwarden/common/tools/private-classifier";
import { PublicClassifier } from "@bitwarden/common/tools/public-classifier";
import { BufferedKeyDefinition } from "@bitwarden/common/tools/state/buffered-key-definition";
import { ObjectKey } from "@bitwarden/common/tools/state/subject-key";
import { ObjectKey } from "@bitwarden/common/tools/state/object-key";
import { ForwarderConfiguration, ForwarderContext, EmailDomainSettings } from "../engine";
import { CreateForwardingEmailRpcDef } from "../engine/forwarder-configuration";

View File

@ -8,7 +8,7 @@ import { ApiSettings, IntegrationRequest } from "@bitwarden/common/tools/integra
import { PrivateClassifier } from "@bitwarden/common/tools/private-classifier";
import { PublicClassifier } from "@bitwarden/common/tools/public-classifier";
import { BufferedKeyDefinition } from "@bitwarden/common/tools/state/buffered-key-definition";
import { ObjectKey } from "@bitwarden/common/tools/state/subject-key";
import { ObjectKey } from "@bitwarden/common/tools/state/object-key";
import { ForwarderConfiguration, ForwarderContext } from "../engine";
import { CreateForwardingEmailRpcDef } from "../engine/forwarder-configuration";

View File

@ -8,7 +8,7 @@ import { ApiSettings, IntegrationRequest } from "@bitwarden/common/tools/integra
import { PrivateClassifier } from "@bitwarden/common/tools/private-classifier";
import { PublicClassifier } from "@bitwarden/common/tools/public-classifier";
import { BufferedKeyDefinition } from "@bitwarden/common/tools/state/buffered-key-definition";
import { ObjectKey } from "@bitwarden/common/tools/state/subject-key";
import { ObjectKey } from "@bitwarden/common/tools/state/object-key";
import {
ForwarderConfiguration,

View File

@ -8,7 +8,7 @@ import { ApiSettings, IntegrationRequest } from "@bitwarden/common/tools/integra
import { PrivateClassifier } from "@bitwarden/common/tools/private-classifier";
import { PublicClassifier } from "@bitwarden/common/tools/public-classifier";
import { BufferedKeyDefinition } from "@bitwarden/common/tools/state/buffered-key-definition";
import { ObjectKey } from "@bitwarden/common/tools/state/subject-key";
import { ObjectKey } from "@bitwarden/common/tools/state/object-key";
import { ForwarderConfiguration, ForwarderContext } from "../engine";
import { CreateForwardingEmailRpcDef } from "../engine/forwarder-configuration";

View File

@ -8,7 +8,7 @@ import { ApiSettings, IntegrationRequest } from "@bitwarden/common/tools/integra
import { PrivateClassifier } from "@bitwarden/common/tools/private-classifier";
import { PublicClassifier } from "@bitwarden/common/tools/public-classifier";
import { BufferedKeyDefinition } from "@bitwarden/common/tools/state/buffered-key-definition";
import { ObjectKey } from "@bitwarden/common/tools/state/subject-key";
import { ObjectKey } from "@bitwarden/common/tools/state/object-key";
import { ForwarderConfiguration, ForwarderContext, EmailDomainSettings } from "../engine";
import { CreateForwardingEmailRpcDef } from "../engine/forwarder-configuration";

View File

@ -12,7 +12,7 @@ import {
import { PrivateClassifier } from "@bitwarden/common/tools/private-classifier";
import { PublicClassifier } from "@bitwarden/common/tools/public-classifier";
import { BufferedKeyDefinition } from "@bitwarden/common/tools/state/buffered-key-definition";
import { ObjectKey } from "@bitwarden/common/tools/state/subject-key";
import { ObjectKey } from "@bitwarden/common/tools/state/object-key";
import { ForwarderConfiguration, ForwarderContext } from "../engine";
import { CreateForwardingEmailRpcDef } from "../engine/forwarder-configuration";

View File

@ -79,6 +79,7 @@ const SomeConfiguration: CredentialGeneratorConfiguration<SomeSettings, SomePoli
category: SomeCategory,
nameKey: SomeNameKey,
onlyOnRequest: false,
request: [],
engine: {
create: (_randomizer) => {
return {

View File

@ -1,7 +1,7 @@
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
import { UserKeyDefinition } from "@bitwarden/common/platform/state";
import { RestClient } from "@bitwarden/common/tools/integration/rpc";
import { ObjectKey } from "@bitwarden/common/tools/state/subject-key";
import { ObjectKey } from "@bitwarden/common/tools/state/object-key";
import { Constraints } from "@bitwarden/common/tools/types";
import { Randomizer } from "../abstractions";