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:
parent
1a5dae51d3
commit
919984c9c5
@ -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>();
|
||||
|
@ -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);
|
||||
|
@ -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";
|
||||
|
@ -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";
|
||||
|
@ -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,
|
||||
|
@ -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";
|
||||
|
@ -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";
|
||||
|
@ -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";
|
||||
|
@ -79,6 +79,7 @@ const SomeConfiguration: CredentialGeneratorConfiguration<SomeSettings, SomePoli
|
||||
category: SomeCategory,
|
||||
nameKey: SomeNameKey,
|
||||
onlyOnRequest: false,
|
||||
request: [],
|
||||
engine: {
|
||||
create: (_randomizer) => {
|
||||
return {
|
||||
|
@ -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";
|
||||
|
Loading…
Reference in New Issue
Block a user