From 1d9fd0d678f90844031276b4cda4f26f4e2974fe Mon Sep 17 00:00:00 2001 From: Matt Hill Date: Wed, 7 Jul 2021 19:19:03 -0600 Subject: [PATCH] backend mocking for reqs that alter state --- ui/src/app/services/api/mock-api.service.ts | 308 +++++++----------- .../app/services/patch-db/patch-db.factory.ts | 2 +- .../app/services/patch-db/patch-db.service.ts | 15 +- ui/ui-config.json | 2 +- 4 files changed, 128 insertions(+), 199 deletions(-) diff --git a/ui/src/app/services/api/mock-api.service.ts b/ui/src/app/services/api/mock-api.service.ts index d7f452c3d..afe2297c2 100644 --- a/ui/src/app/services/api/mock-api.service.ts +++ b/ui/src/app/services/api/mock-api.service.ts @@ -1,35 +1,23 @@ import { Injectable } from '@angular/core' import { pauseFor } from '../../util/misc.util' import { ApiService } from './api.service' -import { Observable } from 'rxjs' -import { PatchOp, Store, Update } from 'patch-db-client' -import { DataModel, PackageDataEntry, PackageMainStatus, PackageState, ServerStatus } from 'src/app/services/patch-db/data-model' -import { RR } from './api-types' +import { PatchOp } from 'patch-db-client' +import { PackageDataEntry, PackageMainStatus, PackageState, ServerStatus } from 'src/app/services/patch-db/data-model' +import { RR, WithRevision } from './api-types' import { parsePropertiesPermissive } from 'src/app/util/properties.util' import { Mock } from './mock-app-fixures' import { HttpService } from '../http.service' import markdown from 'raw-loader!src/assets/markdown/md-sample.md' +import { revision } from '@start9labs/emver' @Injectable() export class MockApiService extends ApiService { - sequence = 0 welcomeAck = false constructor ( private readonly http: HttpService, ) { super() } - // every time a patch is returned from the mock, we override its sequence to be 1 more than the last sequence in the patch-db as provided by `o`. - watch$ (store: Store): Observable> { - store.sequence$.subscribe(seq => { - console.log('INCOMING: ', seq) - if (this.sequence < seq) { - this.sequence = seq - } - }) - return super.watch$() - } - async getStatic (url: string): Promise { await pauseFor(2000) return markdown @@ -100,20 +88,14 @@ export class MockApiService extends ApiService { async updateServerRaw (params: RR.UpdateServerReq): Promise { await pauseFor(2000) - return { - response: null, - revision: { - id: this.nextSequence(), - patch: [ - { - op: PatchOp.REPLACE, - path: '/server-info/status', - value: ServerStatus.Updating, - }, - ], - expireId: null, + const patch = [ + { + op: PatchOp.REPLACE, + path: '/server-info/status', + value: ServerStatus.Updating, }, - } + ] + return this.http.rpcRequest({ method: 'db.patch', params: { patch } }) } async restartServer (params: RR.RestartServerReq): Promise { @@ -137,39 +119,31 @@ export class MockApiService extends ApiService { async setRegistryRaw (params: RR.SetRegistryReq): Promise { await pauseFor(2000) - return { - response: null, - revision: { - id: this.nextSequence(), - patch: [ - { - op: PatchOp.REPLACE, - path: '/server-info/registry', - value: params.url, - }, - ], - expireId: null, + const patch = [ + { + op: PatchOp.REPLACE, + path: '/server-info/registry', + value: params.url, }, - } + ] + return this.http.rpcRequest({ method: 'db.patch', params: { patch } }) } // notification async getNotificationsRaw (params: RR.GetNotificationsReq): Promise { await pauseFor(2000) + const patch = [ + { + op: PatchOp.REPLACE, + path: '/server-info/unread-notification-count', + value: 0, + }, + ] + const { revision } = await this.http.rpcRequest({ method: 'db.patch', params: { patch } }) as WithRevision return { response: Mock.Notifications, - revision: { - id: this.nextSequence(), - patch: [ - { - op: PatchOp.REPLACE, - path: '/server-info/unread-notification-count', - value: 0, - }, - ], - expireId: null, - }, + revision, } } @@ -187,48 +161,36 @@ export class MockApiService extends ApiService { async connectWifiRaw (params: RR.ConnectWifiReq): Promise { await pauseFor(2000) - return { - response: null, - revision: { - id: this.nextSequence(), - patch: [ - { - op: PatchOp.REPLACE, - path: '/server-info/wifi/selected', - value: params.ssid, - }, - { - op: PatchOp.REPLACE, - path: '/server-info/wifi/connected', - value: params.ssid, - }, - ], - expireId: null, + const patch = [ + { + op: PatchOp.REPLACE, + path: '/server-info/wifi/selected', + value: params.ssid, }, - } + { + op: PatchOp.REPLACE, + path: '/server-info/wifi/connected', + value: params.ssid, + }, + ] + return this.http.rpcRequest({ method: 'db.patch', params: { patch } }) } async deleteWifiRaw (params: RR.DeleteWifiReq): Promise { await pauseFor(2000) - return { - response: null, - revision: { - id: this.nextSequence(), - patch: [ - { - op: PatchOp.REPLACE, - path: '/server-info/wifi/selected', - value: null, - }, - { - op: PatchOp.REPLACE, - path: '/server-info/wifi/connected', - value: null, - }, - ], - expireId: null, + const patch = [ + { + op: PatchOp.REPLACE, + path: '/server-info/wifi/selected', + value: null, }, - } + { + op: PatchOp.REPLACE, + path: '/server-info/wifi/connected', + value: null, + }, + ] + return this.http.rpcRequest({ method: 'db.patch', params: { patch } }) } // ssh @@ -252,20 +214,14 @@ export class MockApiService extends ApiService { async createBackupRaw (params: RR.CreateBackupReq): Promise { await pauseFor(2000) - return { - response: null, - revision: { - id: this.nextSequence(), - patch: [ - { - op: PatchOp.REPLACE, - path: '/server-info/status', - value: ServerStatus.BackingUp, - }, - ], - expireId: null, + const patch = [ + { + op: PatchOp.REPLACE, + path: '/server-info/status', + value: ServerStatus.BackingUp, }, - } + ] + return this.http.rpcRequest({ method: 'db.patch', params: { patch } }) } async restoreBackupRaw (params: RR.RestoreBackupReq): Promise { @@ -314,20 +270,14 @@ export class MockApiService extends ApiService { 'read-complete': false, }, } - return { - response: null, - revision: { - id: this.nextSequence(), - patch: [ - { - op: PatchOp.ADD, - path: `/package-data/${params.id}`, - value: pkg, - }, - ], - expireId: null, + const patch = [ + { + op: PatchOp.ADD, + path: `/package-data/${params.id}`, + value: pkg, }, - } + ] + return this.http.rpcRequest({ method: 'db.patch', params: { patch } }) } async dryUpdatePackage (params: RR.DryUpdatePackageReq): Promise { @@ -347,43 +297,31 @@ export class MockApiService extends ApiService { async setPackageConfigRaw (params: RR.SetPackageConfigReq): Promise { await pauseFor(2000) - return { - response: null, - revision: { - id: this.nextSequence(), - patch: [ - { - op: PatchOp.REPLACE, - path: `/package-data/${params.id}/installed/status/configured`, - value: true, - }, - { - op: PatchOp.REPLACE, - path: `/package-data/${params.id}/installed/status/main/status`, - value: PackageMainStatus.Running, - }, - ], - expireId: null, + const patch = [ + { + op: PatchOp.REPLACE, + path: `/package-data/${params.id}/installed/status/configured`, + value: true, }, - } + { + op: PatchOp.REPLACE, + path: `/package-data/${params.id}/installed/status/main/status`, + value: PackageMainStatus.Running, + }, + ] + return this.http.rpcRequest({ method: 'db.patch', params: { patch } }) } async restorePackageRaw (params: RR.RestorePackageReq): Promise { await pauseFor(2000) - return { - response: null, - revision: { - id: this.nextSequence(), - patch: [ - { - op: PatchOp.REPLACE, - path: `/package-data/${params.id}/installed/status/main/status`, - value: PackageMainStatus.Restoring, - }, - ], - expireId: null, + const patch = [ + { + op: PatchOp.REPLACE, + path: `/package-data/${params.id}/installed/status/main/status`, + value: PackageMainStatus.Restoring, }, - } + ] + return this.http.rpcRequest({ method: 'db.patch', params: { patch } }) } async executePackageAction (params: RR.ExecutePackageActionReq): Promise { @@ -398,20 +336,14 @@ export class MockApiService extends ApiService { async startPackageRaw (params: RR.StartPackageReq): Promise { await pauseFor(2000) - return { - response: null, - revision: { - id: this.nextSequence(), - patch: [ - { - op: PatchOp.REPLACE, - path: `/package-data/${params.id}/installed/status/main/status`, - value: PackageMainStatus.Running, - }, - ], - expireId: null, + const patch = [ + { + op: PatchOp.REPLACE, + path: `/package-data/${params.id}/installed/status/main/status`, + value: PackageMainStatus.Running, }, - } + ] + return this.http.rpcRequest({ method: 'db.patch', params: { patch } }) } async dryStopPackage (params: RR.DryStopPackageReq): Promise { @@ -421,20 +353,26 @@ export class MockApiService extends ApiService { async stopPackageRaw (params: RR.StopPackageReq): Promise { await pauseFor(2000) - return { - response: null, - revision: { - id: this.nextSequence(), - patch: [ - { - op: PatchOp.REPLACE, - path: `/package-data/${params.id}/installed/status/main/status`, - value: PackageMainStatus.Stopping, - }, - ], - expireId: null, + const patch = [ + { + op: PatchOp.REPLACE, + path: `/package-data/${params.id}/installed/status/main/status`, + value: PackageMainStatus.Stopping, }, - } + ] + const res = await this.http.rpcRequest>({ method: 'db.patch', params: { patch } }) + setTimeout(() => { + const patch = [ + { + op: PatchOp.REPLACE, + path: `/package-data/${params.id}/installed/status/main/status`, + value: PackageMainStatus.Stopped, + }, + ] + this.http.rpcRequest>({ method: 'db.patch', params: { patch } }) + }, 2000) + + return res } async dryRemovePackage (params: RR.DryRemovePackageReq): Promise { @@ -444,20 +382,14 @@ export class MockApiService extends ApiService { async removePackageRaw (params: RR.RemovePackageReq): Promise { await pauseFor(2000) - return { - response: null, - revision: { - id: this.nextSequence(), - patch: [ - { - op: PatchOp.REPLACE, - path: `/package-data/${params.id}/state`, - value: PackageState.Removing, - }, - ], - expireId: null, + const patch = [ + { + op: PatchOp.REPLACE, + path: `/package-data/${params.id}/state`, + value: PackageState.Removing, }, - } + ] + return this.http.rpcRequest({ method: 'db.patch', params: { patch } }) } async dryConfigureDependency (params: RR.DryConfigureDependencyReq): Promise { @@ -488,10 +420,4 @@ export class MockApiService extends ApiService { await pauseFor(2000) return Mock.AvailableShow[params.id][params.version || 'latest'] } - - private nextSequence () { - console.log('next') - this.sequence++ - return this.sequence - } } diff --git a/ui/src/app/services/patch-db/patch-db.factory.ts b/ui/src/app/services/patch-db/patch-db.factory.ts index a6c5fdffe..313e8e31f 100644 --- a/ui/src/app/services/patch-db/patch-db.factory.ts +++ b/ui/src/app/services/patch-db/patch-db.factory.ts @@ -31,5 +31,5 @@ export function PatchDbModelFactory ( } } - return new PatchDbModel(bootstrapper, [source, apiService]) + return new PatchDbModel(source, apiService, bootstrapper) } \ No newline at end of file diff --git a/ui/src/app/services/patch-db/patch-db.service.ts b/ui/src/app/services/patch-db/patch-db.service.ts index cf0913341..b58af4ed7 100644 --- a/ui/src/app/services/patch-db/patch-db.service.ts +++ b/ui/src/app/services/patch-db/patch-db.service.ts @@ -1,11 +1,13 @@ import { Inject, Injectable, InjectionToken } from '@angular/core' import { Bootstrapper, PatchDB, Source, Store } from 'patch-db-client' import { BehaviorSubject, Observable, of, Subscription } from 'rxjs' -import { catchError, debounceTime, map, tap } from 'rxjs/operators' +import { catchError, debounceTime, finalize, map, tap } from 'rxjs/operators' +import { ApiService } from '../api/api.service' import { DataModel } from './data-model' -export const BOOTSTRAPPER = new InjectionToken>('app.config') +export const PATCH_HTTP = new InjectionToken>('app.config') export const PATCH_SOURCE = new InjectionToken>('app.config') +export const BOOTSTRAPPER = new InjectionToken>('app.config') export enum ConnectionStatus { Initializing = 'initializing', @@ -24,13 +26,14 @@ export class PatchDbModel { private patchSub: Subscription constructor ( + @Inject(PATCH_SOURCE) private readonly source: Source, + @Inject(PATCH_HTTP) private readonly http: ApiService, @Inject(BOOTSTRAPPER) private readonly bootstrapper: Bootstrapper, - @Inject(PATCH_SOURCE) private readonly sources: Source[], ) { } async init (): Promise { const cache = await this.bootstrapper.init() - this.patchDb = new PatchDB(this.sources, cache) + this.patchDb = new PatchDB([this.source, this.http], this.http, cache) this.sequence$ = this.patchDb.store.sequence$.asObservable() this.data = this.patchDb.store.cache.data @@ -81,14 +84,14 @@ export class PatchDbModel { } watch$: Store['watch$'] = (...args: (string | number)[]): Observable => { - // console.log('WATCHING') + console.log('WATCHING', ...args) return this.patchDb.store.watch$(...(args as [])).pipe( tap(cache => console.log('CHANGE IN STORE', cache)), catchError(e => { console.error(e) return of(e.message) }), - // finalize(() => console.log('unSUBSCRIBing')), + finalize(() => console.log('UNSUBSCRIBING')), ) } } diff --git a/ui/ui-config.json b/ui/ui-config.json index 7f06abd3a..65a58f496 100644 --- a/ui/ui-config.json +++ b/ui/ui-config.json @@ -10,7 +10,7 @@ }, "mocks": { "enabled": true, - "connection": "poll", + "connection": "ws", "rpcPort": "5959", "wsPort": "5960", "maskAs": "tor",