import Assert from "@web-atoms/unit-test/dist/Assert"; import Category from "@web-atoms/unit-test/dist/Category"; import Test from "@web-atoms/unit-test/dist/Test"; import { Atom } from "../../Atom"; import CancelTokenFactory from "../../core/CancelTokenFactory"; import { CancelToken } from "../../core/types"; import DISingleton from "../../di/DISingleton"; import { Inject } from "../../di/Inject"; import { AtomTest } from "../../unit/AtomTest"; import Action from "../../view-model/Action"; import { AtomViewModel, Validate, waitForReady } from "../../view-model/AtomViewModel"; import Load from "../../view-model/Load"; import AtomWebTest from "../web/AtomWebTest"; @DISingleton() class RemoteService { public async list(p: string, ct: CancelToken): Promise { await Atom.delay(100, ct); if (ct.cancelled) { throw new Error(ct.cancelled); } if (p === undefined || p === null) { throw new Error("Search cannot be null/undefined"); } return `Success ${p}`; } } class ActionViewModel extends AtomViewModel { public type: string = ""; public search: string = ""; @Validate public get errorType(): string { return this.type ? "" : "Type cannot be empty"; } public list: any; public loaded: boolean; @Inject private remoteService: RemoteService; @Load({ init: true, watch: true }) public async loadList(ct: CancelToken): Promise { const s = this.search; this.list = await this.remoteService.list(s, ct); } @Load({ init: true}) public async load(): Promise { await Atom.delay(10); this.loaded = true; } } class ErrorViewModel extends AtomViewModel { @Load({ watch: true }) public async nothingToWatch() { await Atom.delay(1); } } @Category("View Model Load") export default class LoadTest extends AtomWebTest { @Test public async runOnLoadError(): Promise { await this.createViewModel(ActionViewModel); await Atom.delay(120); } @Test public async runOnSuccess(): Promise { const vm = this.app.resolve(ActionViewModel, true) as ActionViewModel; vm.type = "a"; await waitForReady(vm); await Atom.delay(120); Assert.equals("Success ", vm.list); Assert.equals(true, vm.loaded); } @Test public async watchError(): Promise { const vm = this.app.resolve(ActionViewModel, true) as ActionViewModel; vm.type = "a"; await waitForReady(vm); await Atom.delay(120); Assert.equals("Success ", vm.list); this.navigationService.expectAlert("Error: Search cannot be null/undefined"); // set search as null vm.list = null; vm.search = null; await Atom.delay(300); Assert.isNull(vm.list); } @Test public async watchSuccess(): Promise { const vm = this.app.resolve(ActionViewModel, true) as ActionViewModel; vm.type = "a"; await waitForReady(vm); await Atom.delay(120); Assert.equals("Success ", vm.list); // set search as null vm.list = null; vm.search = "b"; await Atom.delay(300); Assert.equals("Success b", vm.list); } @Test public async watchSuccessWithDelay(): Promise { const vm = this.app.resolve(ActionViewModel, true) as ActionViewModel; vm.type = "a"; await waitForReady(vm); await Atom.delay(120); Assert.equals("Success ", vm.list); // set search as null vm.list = null; vm.search = "b"; await Atom.delay(20); vm.search = "c"; await Atom.delay(300); Assert.equals("Success c", vm.list); } @Test public async error(): Promise { try { const vm = this.app.resolve(ErrorViewModel, true) as ErrorViewModel; await waitForReady(vm); // throw new Error("failed"); } catch (e) { // do nothing... // tslint:disable-next-line: no-console console.error(e); } } }