Browse Source
* [EC-381] Deleted unused method clearCache from Settings Service
* [EC-381] Marked settings methods as obsolete on State service
* [EC-381] Using observables on settings service
* [EC-381] Added unit tests for Settings service
* [EC-381] Checking userId on clear
* [EC-381] Updated references to StateService activeAccountUnlocked$
* [EC-381] Updated getEquivalentDomains to return observable
* [EC-381] Updated settings service to user concatMap on activeAccountUnlocked$
* [EC-381] Renamed getEquivalentDomains to equivalentDomains
* [EC-381] Completing Behaviors on settings.service tests
* [EC-381] Removed unused settingsPrefix from settings service
* [EC-381] Removed equivalentDomains from settings service and added type AccountSettingsSettings
* [EC-381] Updated settings service settings$ to not be nullable
* [EC-381] Settings default to {}
pull/3418/head
8 changed files with 145 additions and 60 deletions
@ -0,0 +1,64 @@
@@ -0,0 +1,64 @@
|
||||
import { Arg, Substitute, SubstituteOf } from "@fluffy-spoon/substitute"; |
||||
import { BehaviorSubject, firstValueFrom } from "rxjs"; |
||||
|
||||
import { CryptoService } from "@bitwarden/common/abstractions/crypto.service"; |
||||
import { ContainerService } from "@bitwarden/common/services/container.service"; |
||||
import { SettingsService } from "@bitwarden/common/services/settings.service"; |
||||
import { StateService } from "@bitwarden/common/services/state.service"; |
||||
|
||||
describe("SettingsService", () => { |
||||
let settingsService: SettingsService; |
||||
|
||||
let cryptoService: SubstituteOf<CryptoService>; |
||||
let stateService: SubstituteOf<StateService>; |
||||
let activeAccount: BehaviorSubject<string>; |
||||
let activeAccountUnlocked: BehaviorSubject<boolean>; |
||||
|
||||
beforeEach(() => { |
||||
cryptoService = Substitute.for(); |
||||
stateService = Substitute.for(); |
||||
activeAccount = new BehaviorSubject("123"); |
||||
activeAccountUnlocked = new BehaviorSubject(true); |
||||
|
||||
stateService.getSettings().resolves({ equivalentDomains: [["test"], ["domains"]] }); |
||||
stateService.activeAccount$.returns(activeAccount); |
||||
stateService.activeAccountUnlocked$.returns(activeAccountUnlocked); |
||||
(window as any).bitwardenContainerService = new ContainerService(cryptoService); |
||||
|
||||
settingsService = new SettingsService(stateService); |
||||
}); |
||||
|
||||
afterEach(() => { |
||||
activeAccount.complete(); |
||||
activeAccountUnlocked.complete(); |
||||
}); |
||||
|
||||
describe("getEquivalentDomains", () => { |
||||
it("returns value", async () => { |
||||
const result = await firstValueFrom(settingsService.settings$); |
||||
|
||||
expect(result).toEqual({ |
||||
equivalentDomains: [["test"], ["domains"]], |
||||
}); |
||||
}); |
||||
}); |
||||
|
||||
it("setEquivalentDomains", async () => { |
||||
await settingsService.setEquivalentDomains([["test2"], ["domains2"]]); |
||||
|
||||
stateService.received(1).setSettings(Arg.any()); |
||||
|
||||
expect((await firstValueFrom(settingsService.settings$)).equivalentDomains).toEqual([ |
||||
["test2"], |
||||
["domains2"], |
||||
]); |
||||
}); |
||||
|
||||
it("clear", async () => { |
||||
await settingsService.clear(); |
||||
|
||||
stateService.received(1).setSettings(Arg.any(), Arg.any()); |
||||
|
||||
expect(await firstValueFrom(settingsService.settings$)).toEqual({}); |
||||
}); |
||||
}); |
||||
@ -1,6 +1,10 @@
@@ -1,6 +1,10 @@
|
||||
import { Observable } from "rxjs"; |
||||
|
||||
import { AccountSettingsSettings } from "../models/domain/account"; |
||||
|
||||
export abstract class SettingsService { |
||||
clearCache: () => Promise<void>; |
||||
getEquivalentDomains: () => Promise<any>; |
||||
settings$: Observable<AccountSettingsSettings>; |
||||
|
||||
setEquivalentDomains: (equivalentDomains: string[][]) => Promise<any>; |
||||
clear: (userId?: string) => Promise<void>; |
||||
} |
||||
|
||||
@ -1,56 +1,50 @@
@@ -1,56 +1,50 @@
|
||||
import { BehaviorSubject, concatMap } from "rxjs"; |
||||
|
||||
import { SettingsService as SettingsServiceAbstraction } from "../abstractions/settings.service"; |
||||
import { StateService } from "../abstractions/state.service"; |
||||
|
||||
const Keys = { |
||||
settingsPrefix: "settings_", |
||||
equivalentDomains: "equivalentDomains", |
||||
}; |
||||
import { Utils } from "../misc/utils"; |
||||
import { AccountSettingsSettings } from "../models/domain/account"; |
||||
|
||||
export class SettingsService implements SettingsServiceAbstraction { |
||||
constructor(private stateService: StateService) {} |
||||
private _settings: BehaviorSubject<AccountSettingsSettings> = new BehaviorSubject({}); |
||||
|
||||
async clearCache(): Promise<void> { |
||||
await this.stateService.setSettings(null); |
||||
} |
||||
settings$ = this._settings.asObservable(); |
||||
|
||||
getEquivalentDomains(): Promise<any> { |
||||
return this.getSettingsKey(Keys.equivalentDomains); |
||||
} |
||||
constructor(private stateService: StateService) { |
||||
this.stateService.activeAccountUnlocked$ |
||||
.pipe( |
||||
concatMap(async (unlocked) => { |
||||
if (Utils.global.bitwardenContainerService == null) { |
||||
return; |
||||
} |
||||
|
||||
async setEquivalentDomains(equivalentDomains: string[][]): Promise<void> { |
||||
await this.setSettingsKey(Keys.equivalentDomains, equivalentDomains); |
||||
} |
||||
if (!unlocked) { |
||||
this._settings.next({}); |
||||
return; |
||||
} |
||||
|
||||
async clear(userId?: string): Promise<void> { |
||||
await this.stateService.setSettings(null, { userId: userId }); |
||||
const data = await this.stateService.getSettings(); |
||||
|
||||
this._settings.next(data); |
||||
}) |
||||
) |
||||
.subscribe(); |
||||
} |
||||
|
||||
// Helpers
|
||||
async setEquivalentDomains(equivalentDomains: string[][]): Promise<void> { |
||||
const settings = this._settings.getValue() ?? {}; |
||||
|
||||
private async getSettings(): Promise<any> { |
||||
const settings = await this.stateService.getSettings(); |
||||
if (settings == null) { |
||||
// eslint-disable-next-line
|
||||
const userId = await this.stateService.getUserId(); |
||||
} |
||||
return settings; |
||||
} |
||||
settings.equivalentDomains = equivalentDomains; |
||||
|
||||
private async getSettingsKey(key: string): Promise<any> { |
||||
const settings = await this.getSettings(); |
||||
if (settings != null && settings[key]) { |
||||
return settings[key]; |
||||
} |
||||
return null; |
||||
this._settings.next(settings); |
||||
await this.stateService.setSettings(settings); |
||||
} |
||||
|
||||
private async setSettingsKey(key: string, value: any): Promise<void> { |
||||
let settings = await this.getSettings(); |
||||
if (!settings) { |
||||
settings = {}; |
||||
async clear(userId?: string): Promise<void> { |
||||
if (userId == null || userId == (await this.stateService.getUserId())) { |
||||
this._settings.next({}); |
||||
} |
||||
|
||||
settings[key] = value; |
||||
await this.stateService.setSettings(settings); |
||||
await this.stateService.setSettings(null, { userId: userId }); |
||||
} |
||||
} |
||||
|
||||
Loading…
Reference in new issue