prep for live mocks

This commit is contained in:
Matt Hill
2021-06-14 17:02:26 -06:00
committed by Aiden McClelland
parent 8b84bdefac
commit 53a16775fe
11 changed files with 69 additions and 101 deletions

View File

@@ -11,13 +11,24 @@ export function PatchDbModelFactory (
http: ApiService, http: ApiService,
): PatchDbModel { ): PatchDbModel {
const { patchDb: { usePollOverride, poll, websocket, timeoutForMissingRevision }, isConsulate } = config const { mocks, patchDb: { poll, timeoutForMissingRevision }, isConsulate, isLan } = config
let source: Source<DataModel> let source: Source<DataModel>
if (isConsulate || usePollOverride) {
source = new PollSource({ ...poll }, http) if (mocks.enabled) {
if (mocks.connection === 'poll') {
source = new PollSource({ ...poll }, http)
} else {
source = new WebsocketSource('ws://localhost:8081')
}
} else { } else {
source = new WebsocketSource({ ...websocket }) if (isConsulate) {
source = new PollSource({ ...poll }, http)
} else {
const protocol = window.location.protocol === 'http:' ? 'ws' : 'wss'
const host = window.location.host
source = new WebsocketSource(`${protocol}://${host}/ws/db`)
}
} }
return new PatchDbModel({ sources: [source, http], bootstrapper, http, timeoutForMissingRevision }) return new PatchDbModel({ sources: [source, http], bootstrapper, http, timeoutForMissingRevision })

View File

@@ -30,7 +30,7 @@ export class LoginPage {
async submit () { async submit () {
try { try {
await this.loader.displayDuringP( await this.loader.displayDuringP(
this.authService.submitPassword(this.password), this.authService.login(this.password),
) )
this.password = '' this.password = ''
await this.navCtrl.navigateForward(['/']) await this.navCtrl.navigateForward(['/'])

View File

@@ -16,11 +16,8 @@ export module RR {
// auth // auth
export type SubmitPinReq = { pin: string } // auth.pin - unauthed export type LoginReq = { password: string } // auth.login - unauthed
export type SubmitPinRes = null export type loginRes = null
export type SubmitPasswordReq = { password: string } // auth.password - unauthed
export type SubmitPasswordRes = null
export type LogoutReq = { } // auth.logout export type LogoutReq = { } // auth.logout
export type LogoutRes = null export type LogoutRes = null

View File

@@ -4,9 +4,9 @@ import { LiveApiService } from './live-api.service'
import { ConfigService } from '../config.service' import { ConfigService } from '../config.service'
export function ApiServiceFactory (config: ConfigService, http: HttpService) { export function ApiServiceFactory (config: ConfigService, http: HttpService) {
if (config.api.mocks) { if (config.mocks.enabled) {
return new MockApiService(config) return new MockApiService(http)
} else { } else {
return new LiveApiService(http, config) return new LiveApiService(http)
} }
} }

View File

@@ -16,7 +16,7 @@ export abstract class ApiService implements Source<DataModel>, Http<DataModel> {
} }
// used for determining internet connectivity // used for determining internet connectivity
abstract ping (): Promise<void> abstract echo (): Promise<string>
// for getting static files: ex icons, instructions, licenses // for getting static files: ex icons, instructions, licenses
abstract getStatic (url: string): Promise<string> abstract getStatic (url: string): Promise<string>
@@ -34,9 +34,7 @@ export abstract class ApiService implements Source<DataModel>, Http<DataModel> {
// auth // auth
abstract submitPin (params: RR.SubmitPinReq): Promise<RR.SubmitPinRes> abstract login (params: RR.LoginReq): Promise<RR.loginRes>
abstract submitPassword (params: RR.SubmitPasswordReq): Promise<RR.SubmitPasswordReq>
abstract logout (params: RR.LogoutReq): Promise<RR.LogoutRes> abstract logout (params: RR.LogoutReq): Promise<RR.LogoutRes>

View File

@@ -3,17 +3,15 @@ import { HttpService, Method } from '../http.service'
import { ApiService } from './api.service' import { ApiService } from './api.service'
import { RR } from './api-types' import { RR } from './api-types'
import { parsePropertiesPermissive } from 'src/app/util/properties.util' import { parsePropertiesPermissive } from 'src/app/util/properties.util'
import { ConfigService } from '../config.service'
@Injectable() @Injectable()
export class LiveApiService extends ApiService { export class LiveApiService extends ApiService {
constructor ( constructor (
private readonly http: HttpService, private readonly http: HttpService,
private readonly config: ConfigService,
) { super() } ) { super() }
async ping (): Promise<void> { async echo (): Promise<string> {
return this.http.rpcRequest({ method: 'ping', params: { } }) return this.http.rpcRequest({ method: 'echo', params: { } })
} }
async getStatic (url: string): Promise<string> { async getStatic (url: string): Promise<string> {
@@ -36,12 +34,8 @@ export class LiveApiService extends ApiService {
// auth // auth
async submitPin (params: RR.SubmitPinReq): Promise<RR.SubmitPinRes> { async login (params: RR.LoginReq): Promise<RR.loginRes> {
return this.http.rpcRequest({ method: 'auth.pin', params }) return this.http.rpcRequest({ method: 'auth.login', params })
}
async submitPassword (params: RR.SubmitPasswordReq): Promise<RR.SubmitPasswordRes> {
return this.http.rpcRequest({ method: 'auth.password', params })
} }
async logout (params: RR.LogoutReq): Promise<RR.LogoutRes> { async logout (params: RR.LogoutReq): Promise<RR.LogoutRes> {

View File

@@ -4,10 +4,10 @@ import { ApiService } from './api.service'
import { Observable } from 'rxjs' import { Observable } from 'rxjs'
import { PatchOp, Update } from 'patch-db-client' import { PatchOp, Update } from 'patch-db-client'
import { DataModel, PackageDataEntry, PackageMainStatus, PackageState, ServerStatus } from 'src/app/models/patch-db/data-model' import { DataModel, PackageDataEntry, PackageMainStatus, PackageState, ServerStatus } from 'src/app/models/patch-db/data-model'
import { ConfigService } from '../config.service'
import { RR } from './api-types' import { RR } from './api-types'
import { parsePropertiesPermissive } from 'src/app/util/properties.util' import { parsePropertiesPermissive } from 'src/app/util/properties.util'
import { Mock } from './mock-app-fixures' import { Mock } from './mock-app-fixures'
import { HttpService } from '../http.service'
@Injectable() @Injectable()
export class MockApiService extends ApiService { export class MockApiService extends ApiService {
@@ -15,7 +15,7 @@ export class MockApiService extends ApiService {
welcomeAck = false welcomeAck = false
constructor ( constructor (
private readonly config: ConfigService, private readonly http: HttpService,
) { super() } ) { 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`. // 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`.
@@ -24,9 +24,9 @@ export class MockApiService extends ApiService {
return super.watch$() return super.watch$()
} }
async ping (): Promise<void> { async echo (): Promise<string> {
console.log('pinging server') console.log('echo...echo')
return return ''
} }
async getStatic (url: string): Promise<string> { async getStatic (url: string): Promise<string> {
@@ -36,47 +36,20 @@ export class MockApiService extends ApiService {
// db // db
async getRevisions (since: number): Promise<RR.GetRevisionsRes> { async getRevisions (since: number): Promise<RR.GetRevisionsRes> {
await pauseFor(2000) return this.http.rpcRequest({ method: 'db.revisions', params: { since } })
return {
...Mock.DbDump,
id: this.nextSequence(),
}
} }
async getDump (): Promise<RR.GetDumpRes> { async getDump (): Promise<RR.GetDumpRes> {
await pauseFor(2000) return this.http.rpcRequest({ method: 'db.dump' })
return {
...Mock.DbDump,
id: this.nextSequence(),
}
} }
async setDbValueRaw (params: RR.SetDBValueReq): Promise<RR.SetDBValueRes> { async setDbValueRaw (params: RR.SetDBValueReq): Promise<RR.SetDBValueRes> {
await pauseFor(2000) return this.http.rpcRequest({ method: 'db.put.ui', params })
return {
response: null,
revision: {
id: this.nextSequence(),
patch: [
{
op: PatchOp.REPLACE,
path: params.pointer,
value: params.value,
},
],
expireId: null,
},
}
} }
// auth // auth
async submitPin (params: RR.SubmitPinReq): Promise<RR.SubmitPinRes> { async login (params: RR.LoginReq): Promise<RR.loginRes> {
await pauseFor(2000)
return null
}
async submitPassword (params: RR.SubmitPasswordReq): Promise<RR.SubmitPasswordRes> {
await pauseFor(2000) await pauseFor(2000)
return null return null
} }

View File

@@ -38,12 +38,8 @@ export class AuthService {
return this.authState$.pipe(distinctUntilChanged()) return this.authState$.pipe(distinctUntilChanged())
} }
async submitPin (pin: string): Promise<void> { async login (password: string): Promise<void> {
await this.api.submitPin({ pin }) await this.api.login({ password })
}
async submitPassword (password: string): Promise<void> {
await this.api.submitPassword({ password })
await this.storage.set(StorageKeys.LOGGED_IN_KEY, true) await this.storage.set(StorageKeys.LOGGED_IN_KEY, true)
this.authState$.next(AuthState.VERIFIED) this.authState$.next(AuthState.VERIFIED)
} }

View File

@@ -1,31 +1,28 @@
import { Injectable } from '@angular/core' import { Injectable } from '@angular/core'
import { InstalledPackageDataEntry, InterfaceDef, Manifest, PackageDataEntry, PackageMainStatus, PackageState } from '../models/patch-db/data-model' import { InstalledPackageDataEntry, InterfaceDef, Manifest, PackageDataEntry, PackageMainStatus, PackageState } from '../models/patch-db/data-model'
const { patchDb, maskAs, api, skipStartupAlerts } = require('../../../ui-config.json') as UiConfig const { patchDb, api, mocks } = require('../../../ui-config.json') as UiConfig
type UiConfig = { type UiConfig = {
patchDb: { patchDb: {
// If this is false (the default), poll will be used if in consulate only. If true it will be on regardless of env. This is useful in concert with api mocks.
usePollOverride: boolean
poll: { poll: {
cooldown: number /* in ms */ cooldown: number /* in ms */
} }
websocket: {
type: 'ws'
url: string
version: number
}
// Wait this long (ms) before asking BE for a dump when out of order messages are received // Wait this long (ms) before asking BE for a dump when out of order messages are received
timeoutForMissingRevision: number timeoutForMissingRevision: number
} }
api: { api: {
mocks: boolean
url: string url: string
version: string version: string
root: string
} }
maskAs: 'tor' | 'lan' | 'none' mocks: {
skipStartupAlerts: boolean enabled: boolean
connection: 'ws' | 'poll'
rpcPort: number
wsPort: number
maskAs: 'tor' | 'lan'
skipStartupAlerts: boolean
}
} }
@Injectable({ @Injectable({
providedIn: 'root', providedIn: 'root',
@@ -36,16 +33,21 @@ export class ConfigService {
patchDb = patchDb patchDb = patchDb
api = api api = api
mocks = mocks
skipStartupAlerts = skipStartupAlerts skipStartupAlerts = mocks.enabled && mocks.skipStartupAlerts
isConsulate = window['platform'] === 'ios' isConsulate = window['platform'] === 'ios'
isTor () : boolean { isTor (): boolean {
return (maskAs === 'tor') || this.origin.endsWith('.onion') return (mocks.enabled && mocks.maskAs === 'tor') || this.origin.endsWith('.onion')
} }
isLan () : boolean { isLan (): boolean {
return (maskAs === 'lan') || this.origin.endsWith('.local') return (mocks.enabled && mocks.maskAs === 'lan') || this.origin.endsWith('.local')
}
usePoll (): boolean {
return this.isConsulate || (mocks.enabled && mocks.connection === 'poll')
} }
isLaunchable (pkg: PackageDataEntry): boolean { isLaunchable (pkg: PackageDataEntry): boolean {

View File

@@ -66,11 +66,11 @@ export class ConnectionService {
// ping server every 10 seconds // ping server every 10 seconds
this.httpSubscription = timer(0, 10000) this.httpSubscription = timer(0, 10000)
.pipe( .pipe(
switchMap(() => this.apiService.ping()), switchMap(() => this.apiService.echo()),
retryWhen(errors => retryWhen(errors =>
errors.pipe( errors.pipe(
tap(val => { tap(val => {
console.error('Ping error: ', val) console.error('Echo error: ', val)
this.currentState.internet = true this.currentState.internet = true
this.emitEvent() this.emitEvent()
}), }),

View File

@@ -3,20 +3,17 @@
"timeoutForMissingRevision": 5000, "timeoutForMissingRevision": 5000,
"poll": { "poll": {
"cooldown": 40000 "cooldown": 40000
}, }
"websocket": {
"type": "ws",
"url": "",
"version": 0
},
"usePollOverride": true
}, },
"api": { "api": {
"mocks": true, "url": "/rpc",
"url": "/api", "version": "v1"
"version": "v1",
"root": ""
}, },
"maskAs": "tor", "mocks": {
"skipStartupAlerts": true "enabled": true,
"connection": "poll",
"websocketUrl": "",
"maskAs": "tor",
"skipStartupAlerts": true
}
} }