1
0
mirror of https://github.com/bitwarden/browser.git synced 2024-11-24 12:06:15 +01:00

[ADR-0006][AC-319] Migrate all tests to use jest mock instead of substitute (#6520)

Standardize on using jest mock instead of having two mocking frameworks which can be confusing.
This commit is contained in:
Oscar Hinton 2023-10-17 19:02:33 +02:00 committed by GitHub
parent 5cacd79d8c
commit ffb67be0a2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
17 changed files with 198 additions and 208 deletions

View File

@ -104,10 +104,7 @@
] ]
} }
], ],
"no-restricted-imports": [ "no-restricted-imports": ["error", { "patterns": ["src/**/*"] }]
"error",
{ "patterns": ["src/**/*"], "paths": ["@fluffy-spoon/substitute"] }
]
} }
}, },
{ {

View File

@ -1,10 +1,9 @@
// eslint-disable-next-line no-restricted-imports import { mock, MockProxy } from "jest-mock-extended";
import { Arg, Substitute, SubstituteOf } from "@fluffy-spoon/substitute";
import { EncryptService } from "@bitwarden/common/platform/abstractions/encrypt.service";
import { Utils } from "@bitwarden/common/platform/misc/utils"; import { Utils } from "@bitwarden/common/platform/misc/utils";
import { EncString } from "@bitwarden/common/platform/models/domain/enc-string"; import { EncString } from "@bitwarden/common/platform/models/domain/enc-string";
import { SymmetricCryptoKey } from "@bitwarden/common/platform/models/domain/symmetric-crypto-key"; import { SymmetricCryptoKey } from "@bitwarden/common/platform/models/domain/symmetric-crypto-key";
import { EncryptServiceImplementation } from "@bitwarden/common/platform/services/cryptography/encrypt.service.implementation";
import BrowserLocalStorageService from "./browser-local-storage.service"; import BrowserLocalStorageService from "./browser-local-storage.service";
import BrowserMemoryStorageService from "./browser-memory-storage.service"; import BrowserMemoryStorageService from "./browser-memory-storage.service";
@ -12,8 +11,8 @@ import { KeyGenerationService } from "./key-generation.service";
import { LocalBackedSessionStorageService } from "./local-backed-session-storage.service"; import { LocalBackedSessionStorageService } from "./local-backed-session-storage.service";
describe("Browser Session Storage Service", () => { describe("Browser Session Storage Service", () => {
let encryptService: SubstituteOf<EncryptServiceImplementation>; let encryptService: MockProxy<EncryptService>;
let keyGenerationService: SubstituteOf<KeyGenerationService>; let keyGenerationService: MockProxy<KeyGenerationService>;
let cache: Map<string, any>; let cache: Map<string, any>;
const testObj = { a: 1, b: 2 }; const testObj = { a: 1, b: 2 };
@ -28,8 +27,8 @@ describe("Browser Session Storage Service", () => {
let sut: LocalBackedSessionStorageService; let sut: LocalBackedSessionStorageService;
beforeEach(() => { beforeEach(() => {
encryptService = Substitute.for(); encryptService = mock<EncryptService>();
keyGenerationService = Substitute.for(); keyGenerationService = mock<KeyGenerationService>();
sut = new LocalBackedSessionStorageService(encryptService, keyGenerationService); sut = new LocalBackedSessionStorageService(encryptService, keyGenerationService);
@ -138,6 +137,8 @@ describe("Browser Session Storage Service", () => {
jest.spyOn(sessionStorage, "get").mockResolvedValue(null); jest.spyOn(sessionStorage, "get").mockResolvedValue(null);
jest.spyOn(localStorage, "save").mockResolvedValue(); jest.spyOn(localStorage, "save").mockResolvedValue();
jest.spyOn(sessionStorage, "save").mockResolvedValue(); jest.spyOn(sessionStorage, "save").mockResolvedValue();
encryptService.encrypt.mockResolvedValue(mockEnc("{}"));
}); });
it("should remove key from cache if value is null", async () => { it("should remove key from cache if value is null", async () => {
@ -205,7 +206,7 @@ describe("Browser Session Storage Service", () => {
describe("new key creation", () => { describe("new key creation", () => {
beforeEach(() => { beforeEach(() => {
jest.spyOn(sessionStorage, "get").mockResolvedValue(null); jest.spyOn(sessionStorage, "get").mockResolvedValue(null);
keyGenerationService.makeEphemeralKey().resolves(key); keyGenerationService.makeEphemeralKey.mockResolvedValue(key);
jest.spyOn(sut, "setSessionEncKey").mockResolvedValue(); jest.spyOn(sut, "setSessionEncKey").mockResolvedValue();
}); });
@ -213,7 +214,7 @@ describe("Browser Session Storage Service", () => {
const result = await sut.getSessionEncKey(); const result = await sut.getSessionEncKey();
expect(result).toStrictEqual(key); expect(result).toStrictEqual(key);
keyGenerationService.received(1).makeEphemeralKey(); expect(keyGenerationService.makeEphemeralKey).toBeCalledTimes(1);
}); });
it("should store a symmetric crypto key if it makes one", async () => { it("should store a symmetric crypto key if it makes one", async () => {
@ -244,19 +245,23 @@ describe("Browser Session Storage Service", () => {
}); });
it("should decrypt returned sessions", async () => { it("should decrypt returned sessions", async () => {
encryptService.decryptToUtf8(encSession, key).resolves(decryptedSession); encryptService.decryptToUtf8
.calledWith(expect.anything(), key)
.mockResolvedValue(decryptedSession);
await sut.getLocalSession(key); await sut.getLocalSession(key);
encryptService.received(1).decryptToUtf8(encSession, key); expect(encryptService.decryptToUtf8).toHaveBeenNthCalledWith(1, encSession, key);
}); });
it("should parse session", async () => { it("should parse session", async () => {
encryptService.decryptToUtf8(encSession, key).resolves(decryptedSession); encryptService.decryptToUtf8
.calledWith(expect.anything(), key)
.mockResolvedValue(decryptedSession);
const result = await sut.getLocalSession(key); const result = await sut.getLocalSession(key);
expect(result).toEqual(session); expect(result).toEqual(session);
}); });
it("should remove state if decryption fails", async () => { it("should remove state if decryption fails", async () => {
encryptService.decryptToUtf8(Arg.any(), Arg.any()).resolves(null); encryptService.decryptToUtf8.mockResolvedValue(null);
const setSessionEncKeySpy = jest.spyOn(sut, "setSessionEncKey").mockResolvedValue(); const setSessionEncKeySpy = jest.spyOn(sut, "setSessionEncKey").mockResolvedValue();
const removeLocalSessionSpy = jest.spyOn(localStorage, "remove").mockResolvedValue(); const removeLocalSessionSpy = jest.spyOn(localStorage, "remove").mockResolvedValue();
@ -274,15 +279,15 @@ describe("Browser Session Storage Service", () => {
const testJSON = JSON.stringify(testSession); const testJSON = JSON.stringify(testSession);
it("should encrypt a stringified session", async () => { it("should encrypt a stringified session", async () => {
encryptService.encrypt(Arg.any(), Arg.any()).mimicks(mockEnc); encryptService.encrypt.mockImplementation(mockEnc);
jest.spyOn(localStorage, "save").mockResolvedValue(); jest.spyOn(localStorage, "save").mockResolvedValue();
await sut.setLocalSession(testSession, key); await sut.setLocalSession(testSession, key);
encryptService.received(1).encrypt(testJSON, key); expect(encryptService.encrypt).toHaveBeenNthCalledWith(1, testJSON, key);
}); });
it("should remove local session if null", async () => { it("should remove local session if null", async () => {
encryptService.encrypt(Arg.any(), Arg.any()).resolves(null); encryptService.encrypt.mockResolvedValue(null);
const spy = jest.spyOn(localStorage, "remove").mockResolvedValue(); const spy = jest.spyOn(localStorage, "remove").mockResolvedValue();
await sut.setLocalSession(null, key); await sut.setLocalSession(null, key);
@ -290,7 +295,7 @@ describe("Browser Session Storage Service", () => {
}); });
it("should save encrypted string", async () => { it("should save encrypted string", async () => {
encryptService.encrypt(Arg.any(), Arg.any()).mimicks(mockEnc); encryptService.encrypt.mockImplementation(mockEnc);
const spy = jest.spyOn(localStorage, "save").mockResolvedValue(); const spy = jest.spyOn(localStorage, "save").mockResolvedValue();
await sut.setLocalSession(testSession, key); await sut.setLocalSession(testSession, key);

View File

@ -1,8 +1,6 @@
import { NO_ERRORS_SCHEMA } from "@angular/core"; import { NO_ERRORS_SCHEMA } from "@angular/core";
import { ComponentFixture, TestBed } from "@angular/core/testing"; import { ComponentFixture, TestBed } from "@angular/core/testing";
import { ActivatedRoute } from "@angular/router"; import { ActivatedRoute } from "@angular/router";
// eslint-disable-next-line no-restricted-imports
import { Substitute } from "@fluffy-spoon/substitute";
import { mock, MockProxy } from "jest-mock-extended"; import { mock, MockProxy } from "jest-mock-extended";
import { I18nPipe } from "@bitwarden/angular/platform/pipes/i18n.pipe"; import { I18nPipe } from "@bitwarden/angular/platform/pipes/i18n.pipe";
@ -28,15 +26,15 @@ describe("GeneratorComponent", () => {
providers: [ providers: [
{ {
provide: PasswordGenerationServiceAbstraction, provide: PasswordGenerationServiceAbstraction,
useClass: Substitute.for<PasswordGenerationServiceAbstraction>(), useValue: mock<PasswordGenerationServiceAbstraction>(),
}, },
{ {
provide: UsernameGenerationServiceAbstraction, provide: UsernameGenerationServiceAbstraction,
useClass: Substitute.for<UsernameGenerationServiceAbstraction>(), useValue: mock<UsernameGenerationServiceAbstraction>(),
}, },
{ {
provide: StateService, provide: StateService,
useClass: Substitute.for<StateService>(), useValue: mock<StateService>(),
}, },
{ {
provide: PlatformUtilsService, provide: PlatformUtilsService,
@ -44,15 +42,15 @@ describe("GeneratorComponent", () => {
}, },
{ {
provide: I18nService, provide: I18nService,
useClass: Substitute.for<I18nService>(), useValue: mock<I18nService>(),
}, },
{ {
provide: ActivatedRoute, provide: ActivatedRoute,
useClass: Substitute.for<ActivatedRoute>(), useValue: mock<ActivatedRoute>(),
}, },
{ {
provide: LogService, provide: LogService,
useClass: Substitute.for<LogService>(), useValue: mock<LogService>(),
}, },
], ],
schemas: [NO_ERRORS_SCHEMA], schemas: [NO_ERRORS_SCHEMA],

View File

@ -15,8 +15,7 @@
"@bitwarden/web-vault/*", "@bitwarden/web-vault/*",
"src/**/*", "src/**/*",
"bitwarden_license" "bitwarden_license"
], ]
"paths": ["@fluffy-spoon/substitute"]
} }
] ]
} }

View File

@ -1,5 +1,4 @@
// eslint-disable-next-line no-restricted-imports import { mock, MockProxy } from "jest-mock-extended";
import { Substitute, Arg } from "@fluffy-spoon/substitute";
import { EncString } from "@bitwarden/common/platform/models/domain/enc-string"; import { EncString } from "@bitwarden/common/platform/models/domain/enc-string";
@ -22,11 +21,11 @@ export function BuildTestObject<T, K extends keyof T = keyof T>(
return Object.assign(constructor === null ? {} : new constructor(), def) as T; return Object.assign(constructor === null ? {} : new constructor(), def) as T;
} }
export function mockEnc(s: string): EncString { export function mockEnc(s: string): MockProxy<EncString> {
const mock = Substitute.for<EncString>(); const mocked = mock<EncString>();
mock.decrypt(Arg.any(), Arg.any()).resolves(s); mocked.decrypt.mockResolvedValue(s);
return mock; return mocked;
} }
export function makeStaticByteArray(length: number, start = 0) { export function makeStaticByteArray(length: number, start = 0) {

View File

@ -1,7 +1,6 @@
// eslint-disable-next-line no-restricted-imports
import { Substitute, Arg } from "@fluffy-spoon/substitute";
import { mock, MockProxy } from "jest-mock-extended"; import { mock, MockProxy } from "jest-mock-extended";
import { makeStaticByteArray } from "../../../../spec";
import { EncryptionType } from "../../../enums"; import { EncryptionType } from "../../../enums";
import { EncryptService } from "../../../platform/abstractions/encrypt.service"; import { EncryptService } from "../../../platform/abstractions/encrypt.service";
import { import {
@ -64,11 +63,16 @@ describe("EncString", () => {
describe("decrypt", () => { describe("decrypt", () => {
const encString = new EncString(EncryptionType.Rsa2048_OaepSha256_B64, "data"); const encString = new EncString(EncryptionType.Rsa2048_OaepSha256_B64, "data");
const cryptoService = Substitute.for<CryptoService>(); const cryptoService = mock<CryptoService>();
cryptoService.getOrgKey(null).resolves(null); cryptoService.hasUserKey.mockResolvedValue(true);
cryptoService.getUserKeyWithLegacySupport.mockResolvedValue(
new SymmetricCryptoKey(makeStaticByteArray(32)) as UserKey
);
const encryptService = Substitute.for<EncryptService>(); const encryptService = mock<EncryptService>();
encryptService.decryptToUtf8(encString, Arg.any()).resolves("decrypted"); encryptService.decryptToUtf8
.calledWith(encString, expect.anything())
.mockResolvedValue("decrypted");
beforeEach(() => { beforeEach(() => {
(window as any).bitwardenContainerService = new ContainerService( (window as any).bitwardenContainerService = new ContainerService(
@ -85,7 +89,7 @@ describe("EncString", () => {
it("result should be cached", async () => { it("result should be cached", async () => {
const decrypted = await encString.decrypt(null); const decrypted = await encString.decrypt(null);
encryptService.received(1).decryptToUtf8(Arg.any(), Arg.any()); expect(encryptService.decryptToUtf8).toBeCalledTimes(1);
expect(decrypted).toBe("decrypted"); expect(decrypted).toBe("decrypted");
}); });

View File

@ -1,5 +1,4 @@
// eslint-disable-next-line no-restricted-imports import { mock } from "jest-mock-extended";
import { Substitute } from "@fluffy-spoon/substitute";
import { Utils } from "../../platform/misc/utils"; import { Utils } from "../../platform/misc/utils";
import { PlatformUtilsService } from "../abstractions/platform-utils.service"; import { PlatformUtilsService } from "../abstractions/platform-utils.service";
@ -582,8 +581,8 @@ function testRsaGenerateKeyPair(length: 1024 | 2048 | 4096) {
} }
function getWebCryptoFunctionService() { function getWebCryptoFunctionService() {
const platformUtilsMock = Substitute.for<PlatformUtilsService>(); const platformUtilsMock = mock<PlatformUtilsService>();
platformUtilsMock.isEdge().mimicks(() => navigator.userAgent.indexOf(" Edg/") !== -1); platformUtilsMock.isEdge.mockImplementation(() => navigator.userAgent.indexOf(" Edg/") !== -1);
return new WebCryptoFunctionService(window); return new WebCryptoFunctionService(window);
} }

View File

@ -1,5 +1,4 @@
// eslint-disable-next-line no-restricted-imports import { mock, MockProxy } from "jest-mock-extended";
import { Arg, Substitute, SubstituteOf } from "@fluffy-spoon/substitute";
import { BehaviorSubject, firstValueFrom } from "rxjs"; import { BehaviorSubject, firstValueFrom } from "rxjs";
import { OrganizationService } from "../admin-console/abstractions/organization/organization.service.abstraction"; import { OrganizationService } from "../admin-console/abstractions/organization/organization.service.abstraction";
@ -22,19 +21,19 @@ import { StateService } from "../platform/services/state.service";
describe("PolicyService", () => { describe("PolicyService", () => {
let policyService: PolicyService; let policyService: PolicyService;
let cryptoService: SubstituteOf<CryptoService>; let cryptoService: MockProxy<CryptoService>;
let stateService: SubstituteOf<StateService>; let stateService: MockProxy<StateService>;
let organizationService: SubstituteOf<OrganizationService>; let organizationService: MockProxy<OrganizationService>;
let encryptService: SubstituteOf<EncryptService>; let encryptService: MockProxy<EncryptService>;
let activeAccount: BehaviorSubject<string>; let activeAccount: BehaviorSubject<string>;
let activeAccountUnlocked: BehaviorSubject<boolean>; let activeAccountUnlocked: BehaviorSubject<boolean>;
beforeEach(() => { beforeEach(() => {
stateService = Substitute.for(); stateService = mock<StateService>();
organizationService = Substitute.for(); organizationService = mock<OrganizationService>();
organizationService organizationService.getAll
.getAll("user") .calledWith("user")
.resolves([ .mockResolvedValue([
new Organization( new Organization(
organizationData( organizationData(
"test-organization", "test-organization",
@ -45,24 +44,24 @@ describe("PolicyService", () => {
) )
), ),
]); ]);
organizationService.getAll(undefined).resolves([]); organizationService.getAll.calledWith(undefined).mockResolvedValue([]);
organizationService.getAll(null).resolves([]); organizationService.getAll.calledWith(null).mockResolvedValue([]);
activeAccount = new BehaviorSubject("123"); activeAccount = new BehaviorSubject("123");
activeAccountUnlocked = new BehaviorSubject(true); activeAccountUnlocked = new BehaviorSubject(true);
stateService.getDecryptedPolicies({ userId: "user" }).resolves(null); stateService.getDecryptedPolicies.calledWith({ userId: "user" }).mockResolvedValue(null);
stateService.getEncryptedPolicies({ userId: "user" }).resolves({ stateService.getEncryptedPolicies.calledWith({ userId: "user" }).mockResolvedValue({
"1": policyData("1", "test-organization", PolicyType.MaximumVaultTimeout, true, { "1": policyData("1", "test-organization", PolicyType.MaximumVaultTimeout, true, {
minutes: 14, minutes: 14,
}), }),
}); });
stateService.getEncryptedPolicies().resolves({ stateService.getEncryptedPolicies.mockResolvedValue({
"1": policyData("1", "test-organization", PolicyType.MaximumVaultTimeout, true, { "1": policyData("1", "test-organization", PolicyType.MaximumVaultTimeout, true, {
minutes: 14, minutes: 14,
}), }),
}); });
stateService.activeAccount$.returns(activeAccount); stateService.activeAccount$ = activeAccount;
stateService.activeAccountUnlocked$.returns(activeAccountUnlocked); stateService.activeAccountUnlocked$ = activeAccountUnlocked;
stateService.getUserId().resolves("user"); stateService.getUserId.mockResolvedValue("user");
(window as any).bitwardenContainerService = new ContainerService(cryptoService, encryptService); (window as any).bitwardenContainerService = new ContainerService(cryptoService, encryptService);
policyService = new PolicyService(stateService, organizationService); policyService = new PolicyService(stateService, organizationService);
@ -120,7 +119,7 @@ describe("PolicyService", () => {
it("null userId", async () => { it("null userId", async () => {
await policyService.clear(); await policyService.clear();
stateService.received(1).setEncryptedPolicies(Arg.any(), Arg.any()); expect(stateService.setEncryptedPolicies).toBeCalledTimes(1);
expect((await firstValueFrom(policyService.policies$)).length).toBe(0); expect((await firstValueFrom(policyService.policies$)).length).toBe(0);
}); });
@ -128,7 +127,7 @@ describe("PolicyService", () => {
it("matching userId", async () => { it("matching userId", async () => {
await policyService.clear("user"); await policyService.clear("user");
stateService.received(1).setEncryptedPolicies(Arg.any(), Arg.any()); expect(stateService.setEncryptedPolicies).toBeCalledTimes(1);
expect((await firstValueFrom(policyService.policies$)).length).toBe(0); expect((await firstValueFrom(policyService.policies$)).length).toBe(0);
}); });
@ -136,7 +135,7 @@ describe("PolicyService", () => {
it("mismatching userId", async () => { it("mismatching userId", async () => {
await policyService.clear("12"); await policyService.clear("12");
stateService.received(1).setEncryptedPolicies(Arg.any(), Arg.any()); expect(stateService.setEncryptedPolicies).toBeCalledTimes(1);
expect((await firstValueFrom(policyService.policies$)).length).toBe(1); expect((await firstValueFrom(policyService.policies$)).length).toBe(1);
}); });

View File

@ -1,20 +1,19 @@
// eslint-disable-next-line no-restricted-imports import { mock, MockProxy } from "jest-mock-extended";
import { Arg, Substitute, SubstituteOf } from "@fluffy-spoon/substitute";
import { BehaviorSubject, firstValueFrom } from "rxjs"; import { BehaviorSubject, firstValueFrom } from "rxjs";
import { CryptoService } from "../platform/abstractions/crypto.service"; import { CryptoService } from "../platform/abstractions/crypto.service";
import { EncryptService } from "../platform/abstractions/encrypt.service"; import { EncryptService } from "../platform/abstractions/encrypt.service";
import { StateService } from "../platform/abstractions/state.service";
import { ContainerService } from "../platform/services/container.service"; import { ContainerService } from "../platform/services/container.service";
import { StateService } from "../platform/services/state.service";
import { SettingsService } from "./settings.service"; import { SettingsService } from "./settings.service";
describe("SettingsService", () => { describe("SettingsService", () => {
let settingsService: SettingsService; let settingsService: SettingsService;
let cryptoService: SubstituteOf<CryptoService>; let cryptoService: MockProxy<CryptoService>;
let encryptService: SubstituteOf<EncryptService>; let encryptService: MockProxy<EncryptService>;
let stateService: SubstituteOf<StateService>; let stateService: MockProxy<StateService>;
let activeAccount: BehaviorSubject<string>; let activeAccount: BehaviorSubject<string>;
let activeAccountUnlocked: BehaviorSubject<boolean>; let activeAccountUnlocked: BehaviorSubject<boolean>;
@ -25,15 +24,15 @@ describe("SettingsService", () => {
]; ];
beforeEach(() => { beforeEach(() => {
cryptoService = Substitute.for(); cryptoService = mock<CryptoService>();
encryptService = Substitute.for(); encryptService = mock<EncryptService>();
stateService = Substitute.for(); stateService = mock<StateService>();
activeAccount = new BehaviorSubject("123"); activeAccount = new BehaviorSubject("123");
activeAccountUnlocked = new BehaviorSubject(true); activeAccountUnlocked = new BehaviorSubject(true);
stateService.getSettings().resolves({ equivalentDomains: mockEquivalentDomains }); stateService.getSettings.mockResolvedValue({ equivalentDomains: mockEquivalentDomains });
stateService.activeAccount$.returns(activeAccount); stateService.activeAccount$ = activeAccount;
stateService.activeAccountUnlocked$.returns(activeAccountUnlocked); stateService.activeAccountUnlocked$ = activeAccountUnlocked;
(window as any).bitwardenContainerService = new ContainerService(cryptoService, encryptService); (window as any).bitwardenContainerService = new ContainerService(cryptoService, encryptService);
settingsService = new SettingsService(stateService); settingsService = new SettingsService(stateService);
@ -66,7 +65,7 @@ describe("SettingsService", () => {
it("setEquivalentDomains", async () => { it("setEquivalentDomains", async () => {
await settingsService.setEquivalentDomains([["test2"], ["domains2"]]); await settingsService.setEquivalentDomains([["test2"], ["domains2"]]);
stateService.received(1).setSettings(Arg.any()); expect(stateService.setSettings).toBeCalledTimes(1);
expect((await firstValueFrom(settingsService.settings$)).equivalentDomains).toEqual([ expect((await firstValueFrom(settingsService.settings$)).equivalentDomains).toEqual([
["test2"], ["test2"],
@ -77,7 +76,7 @@ describe("SettingsService", () => {
it("clear", async () => { it("clear", async () => {
await settingsService.clear(); await settingsService.clear();
stateService.received(1).setSettings(Arg.any(), Arg.any()); expect(stateService.setSettings).toBeCalledTimes(1);
expect(await firstValueFrom(settingsService.settings$)).toEqual({}); expect(await firstValueFrom(settingsService.settings$)).toEqual({});
}); });

View File

@ -1,5 +1,4 @@
// eslint-disable-next-line no-restricted-imports import { mock } from "jest-mock-extended";
import { Substitute, Arg } from "@fluffy-spoon/substitute";
import { mockEnc } from "../../../../../spec"; import { mockEnc } from "../../../../../spec";
import { SendType } from "../../enums/send-type"; import { SendType } from "../../enums/send-type";
@ -61,8 +60,8 @@ describe("SendAccess", () => {
sendAccess.type = SendType.Text; sendAccess.type = SendType.Text;
sendAccess.name = mockEnc("name"); sendAccess.name = mockEnc("name");
const text = Substitute.for<SendText>(); const text = mock<SendText>();
text.decrypt(Arg.any()).resolves({} as any); text.decrypt.mockResolvedValue({} as any);
sendAccess.text = text; sendAccess.text = text;
sendAccess.expirationDate = new Date("2022-01-31T12:00:00.000Z"); sendAccess.expirationDate = new Date("2022-01-31T12:00:00.000Z");
@ -70,7 +69,7 @@ describe("SendAccess", () => {
const view = await sendAccess.decrypt(null); const view = await sendAccess.decrypt(null);
text.received(1).decrypt(Arg.any()); expect(text.decrypt).toHaveBeenCalledTimes(1);
expect(view).toEqual({ expect(view).toEqual({
id: "id", id: "id",

View File

@ -1,10 +1,8 @@
// eslint-disable-next-line no-restricted-imports import { mock } from "jest-mock-extended";
import { Substitute, Arg, SubstituteOf } from "@fluffy-spoon/substitute";
import { makeStaticByteArray, mockEnc } from "../../../../../spec"; import { makeStaticByteArray, mockEnc } from "../../../../../spec";
import { CryptoService } from "../../../../platform/abstractions/crypto.service"; import { CryptoService } from "../../../../platform/abstractions/crypto.service";
import { EncryptService } from "../../../../platform/abstractions/encrypt.service"; import { EncryptService } from "../../../../platform/abstractions/encrypt.service";
import { EncString } from "../../../../platform/models/domain/enc-string";
import { ContainerService } from "../../../../platform/services/container.service"; import { ContainerService } from "../../../../platform/services/container.service";
import { SendType } from "../../enums/send-type"; import { SendType } from "../../enums/send-type";
import { SendData } from "../data/send.data"; import { SendData } from "../data/send.data";
@ -89,8 +87,8 @@ describe("Send", () => {
}); });
it("Decrypt", async () => { it("Decrypt", async () => {
const text = Substitute.for<SendText>(); const text = mock<SendText>();
text.decrypt(Arg.any()).resolves("textView" as any); text.decrypt.mockResolvedValue("textView" as any);
const send = new Send(); const send = new Send();
send.id = "id"; send.id = "id";
@ -108,18 +106,20 @@ describe("Send", () => {
send.disabled = false; send.disabled = false;
send.hideEmail = true; send.hideEmail = true;
const cryptoService = Substitute.for<CryptoService>(); const cryptoService = mock<CryptoService>();
cryptoService.decryptToBytes(send.key, null).resolves(makeStaticByteArray(32)); cryptoService.decryptToBytes
cryptoService.makeSendKey(Arg.any()).resolves("cryptoKey" as any); .calledWith(send.key, null)
.mockResolvedValue(makeStaticByteArray(32));
cryptoService.makeSendKey.mockResolvedValue("cryptoKey" as any);
const encryptService = Substitute.for<EncryptService>(); const encryptService = mock<EncryptService>();
(window as any).bitwardenContainerService = new ContainerService(cryptoService, encryptService); (window as any).bitwardenContainerService = new ContainerService(cryptoService, encryptService);
const view = await send.decrypt(); const view = await send.decrypt();
text.received(1).decrypt("cryptoKey" as any); expect(text.decrypt).toHaveBeenNthCalledWith(1, "cryptoKey");
(send.name as SubstituteOf<EncString>).received(1).decrypt(null, "cryptoKey" as any); expect(send.name.decrypt).toHaveBeenNthCalledWith(1, null, "cryptoKey");
expect(view).toMatchObject({ expect(view).toMatchObject({
id: "id", id: "id",

View File

@ -1,5 +1,4 @@
// eslint-disable-next-line no-restricted-imports import { mock } from "jest-mock-extended";
import { Substitute, Arg } from "@fluffy-spoon/substitute";
import { Jsonify } from "type-fest"; import { Jsonify } from "type-fest";
import { makeStaticByteArray, mockEnc, mockFromJson } from "../../../../spec/utils"; import { makeStaticByteArray, mockEnc, mockFromJson } from "../../../../spec/utils";
@ -219,15 +218,15 @@ describe("Cipher DTO", () => {
loginView.username = "username"; loginView.username = "username";
loginView.password = "password"; loginView.password = "password";
const login = Substitute.for<Login>(); const login = mock<Login>();
login.decrypt(Arg.any(), Arg.any()).resolves(loginView); login.decrypt.mockResolvedValue(loginView);
cipher.login = login; cipher.login = login;
const cryptoService = Substitute.for<CryptoService>(); const cryptoService = mock<CryptoService>();
const encryptService = Substitute.for<EncryptService>(); const encryptService = mock<EncryptService>();
const cipherService = Substitute.for<CipherService>(); const cipherService = mock<CipherService>();
encryptService.decryptToBytes(Arg.any(), Arg.any()).resolves(makeStaticByteArray(64)); encryptService.decryptToBytes.mockResolvedValue(makeStaticByteArray(64));
(window as any).bitwardenContainerService = new ContainerService( (window as any).bitwardenContainerService = new ContainerService(
cryptoService, cryptoService,
@ -343,11 +342,11 @@ describe("Cipher DTO", () => {
cipher.secureNote.type = SecureNoteType.Generic; cipher.secureNote.type = SecureNoteType.Generic;
cipher.key = mockEnc("EncKey"); cipher.key = mockEnc("EncKey");
const cryptoService = Substitute.for<CryptoService>(); const cryptoService = mock<CryptoService>();
const encryptService = Substitute.for<EncryptService>(); const encryptService = mock<EncryptService>();
const cipherService = Substitute.for<CipherService>(); const cipherService = mock<CipherService>();
encryptService.decryptToBytes(Arg.any(), Arg.any()).resolves(makeStaticByteArray(64)); encryptService.decryptToBytes.mockResolvedValue(makeStaticByteArray(64));
(window as any).bitwardenContainerService = new ContainerService( (window as any).bitwardenContainerService = new ContainerService(
cryptoService, cryptoService,
@ -477,15 +476,15 @@ describe("Cipher DTO", () => {
cardView.cardholderName = "cardholderName"; cardView.cardholderName = "cardholderName";
cardView.number = "4111111111111111"; cardView.number = "4111111111111111";
const card = Substitute.for<Card>(); const card = mock<Card>();
card.decrypt(Arg.any(), Arg.any()).resolves(cardView); card.decrypt.mockResolvedValue(cardView);
cipher.card = card; cipher.card = card;
const cryptoService = Substitute.for<CryptoService>(); const cryptoService = mock<CryptoService>();
const encryptService = Substitute.for<EncryptService>(); const encryptService = mock<EncryptService>();
const cipherService = Substitute.for<CipherService>(); const cipherService = mock<CipherService>();
encryptService.decryptToBytes(Arg.any(), Arg.any()).resolves(makeStaticByteArray(64)); encryptService.decryptToBytes.mockResolvedValue(makeStaticByteArray(64));
(window as any).bitwardenContainerService = new ContainerService( (window as any).bitwardenContainerService = new ContainerService(
cryptoService, cryptoService,
@ -639,15 +638,15 @@ describe("Cipher DTO", () => {
identityView.firstName = "firstName"; identityView.firstName = "firstName";
identityView.lastName = "lastName"; identityView.lastName = "lastName";
const identity = Substitute.for<Identity>(); const identity = mock<Identity>();
identity.decrypt(Arg.any(), Arg.any()).resolves(identityView); identity.decrypt.mockResolvedValue(identityView);
cipher.identity = identity; cipher.identity = identity;
const cryptoService = Substitute.for<CryptoService>(); const cryptoService = mock<CryptoService>();
const encryptService = Substitute.for<EncryptService>(); const encryptService = mock<EncryptService>();
const cipherService = Substitute.for<CipherService>(); const cipherService = mock<CipherService>();
encryptService.decryptToBytes(Arg.any(), Arg.any()).resolves(makeStaticByteArray(64)); encryptService.decryptToBytes.mockResolvedValue(makeStaticByteArray(64));
(window as any).bitwardenContainerService = new ContainerService( (window as any).bitwardenContainerService = new ContainerService(
cryptoService, cryptoService,

View File

@ -1,5 +1,4 @@
// eslint-disable-next-line no-restricted-imports import { mock } from "jest-mock-extended";
import { Substitute, Arg } from "@fluffy-spoon/substitute";
import { mockEnc, mockFromJson } from "../../../../spec"; import { mockEnc, mockFromJson } from "../../../../spec";
import { UriMatchType } from "../../../enums"; import { UriMatchType } from "../../../enums";
@ -51,10 +50,10 @@ describe("Login DTO", () => {
}); });
it("Decrypts correctly", async () => { it("Decrypts correctly", async () => {
const loginUri = Substitute.for<LoginUri>(); const loginUri = mock<LoginUri>();
const loginUriView = new LoginUriView(); const loginUriView = new LoginUriView();
loginUriView.uri = "decrypted uri"; loginUriView.uri = "decrypted uri";
loginUri.decrypt(Arg.any()).resolves(loginUriView); loginUri.decrypt.mockResolvedValue(loginUriView);
const login = new Login(); const login = new Login();
login.uris = [loginUri]; login.uris = [loginUri];

View File

@ -1,13 +1,14 @@
// eslint-disable-next-line no-restricted-imports import { mock, MockProxy } from "jest-mock-extended";
import { Arg, Substitute, SubstituteOf } from "@fluffy-spoon/substitute";
import { BehaviorSubject, firstValueFrom } from "rxjs"; import { BehaviorSubject, firstValueFrom } from "rxjs";
import { makeStaticByteArray } from "../../../../spec";
import { CryptoService } from "../../../platform/abstractions/crypto.service"; import { CryptoService } from "../../../platform/abstractions/crypto.service";
import { EncryptService } from "../../../platform/abstractions/encrypt.service"; import { EncryptService } from "../../../platform/abstractions/encrypt.service";
import { I18nService } from "../../../platform/abstractions/i18n.service"; import { I18nService } from "../../../platform/abstractions/i18n.service";
import { StateService } from "../../../platform/abstractions/state.service";
import { EncString } from "../../../platform/models/domain/enc-string"; import { EncString } from "../../../platform/models/domain/enc-string";
import { SymmetricCryptoKey, UserKey } from "../../../platform/models/domain/symmetric-crypto-key";
import { ContainerService } from "../../../platform/services/container.service"; import { ContainerService } from "../../../platform/services/container.service";
import { StateService } from "../../../platform/services/state.service";
import { CipherService } from "../../abstractions/cipher.service"; import { CipherService } from "../../abstractions/cipher.service";
import { FolderData } from "../../models/data/folder.data"; import { FolderData } from "../../models/data/folder.data";
import { FolderView } from "../../models/view/folder.view"; import { FolderView } from "../../models/view/folder.view";
@ -16,28 +17,36 @@ import { FolderService } from "../../services/folder/folder.service";
describe("Folder Service", () => { describe("Folder Service", () => {
let folderService: FolderService; let folderService: FolderService;
let cryptoService: SubstituteOf<CryptoService>; let cryptoService: MockProxy<CryptoService>;
let encryptService: SubstituteOf<EncryptService>; let encryptService: MockProxy<EncryptService>;
let i18nService: SubstituteOf<I18nService>; let i18nService: MockProxy<I18nService>;
let cipherService: SubstituteOf<CipherService>; let cipherService: MockProxy<CipherService>;
let stateService: SubstituteOf<StateService>; let stateService: MockProxy<StateService>;
let activeAccount: BehaviorSubject<string>; let activeAccount: BehaviorSubject<string>;
let activeAccountUnlocked: BehaviorSubject<boolean>; let activeAccountUnlocked: BehaviorSubject<boolean>;
beforeEach(() => { beforeEach(() => {
cryptoService = Substitute.for(); cryptoService = mock<CryptoService>();
encryptService = Substitute.for(); encryptService = mock<EncryptService>();
i18nService = Substitute.for(); i18nService = mock<I18nService>();
cipherService = Substitute.for(); cipherService = mock<CipherService>();
stateService = Substitute.for(); stateService = mock<StateService>();
activeAccount = new BehaviorSubject("123"); activeAccount = new BehaviorSubject("123");
activeAccountUnlocked = new BehaviorSubject(true); activeAccountUnlocked = new BehaviorSubject(true);
stateService.getEncryptedFolders().resolves({ i18nService.collator = new Intl.Collator("en");
stateService.getEncryptedFolders.mockResolvedValue({
"1": folderData("1", "test"), "1": folderData("1", "test"),
}); });
stateService.activeAccount$.returns(activeAccount); stateService.activeAccount$ = activeAccount;
stateService.activeAccountUnlocked$.returns(activeAccountUnlocked); stateService.activeAccountUnlocked$ = activeAccountUnlocked;
cryptoService.hasUserKey.mockResolvedValue(true);
cryptoService.getUserKeyWithLegacySupport.mockResolvedValue(
new SymmetricCryptoKey(makeStaticByteArray(32)) as UserKey
);
encryptService.decryptToUtf8.mockResolvedValue("DEC");
(window as any).bitwardenContainerService = new ContainerService(cryptoService, encryptService); (window as any).bitwardenContainerService = new ContainerService(cryptoService, encryptService);
folderService = new FolderService(cryptoService, i18nService, cipherService, stateService); folderService = new FolderService(cryptoService, i18nService, cipherService, stateService);
@ -48,8 +57,8 @@ describe("Folder Service", () => {
model.id = "2"; model.id = "2";
model.name = "Test Folder"; model.name = "Test Folder";
cryptoService.encrypt(Arg.any()).resolves(new EncString("ENC")); cryptoService.encrypt.mockResolvedValue(new EncString("ENC"));
cryptoService.decryptToUtf8(Arg.any()).resolves("DEC"); cryptoService.decryptToUtf8.mockResolvedValue("DEC");
const result = await folderService.encrypt(model); const result = await folderService.encrypt(model);
@ -69,9 +78,9 @@ describe("Folder Service", () => {
expect(result).toEqual({ expect(result).toEqual({
id: "1", id: "1",
name: { name: {
decryptedValue: [],
encryptedString: "test", encryptedString: "test",
encryptionType: 0, encryptionType: 0,
decryptedValue: "DEC",
}, },
revisionDate: null, revisionDate: null,
}); });
@ -91,27 +100,27 @@ describe("Folder Service", () => {
{ {
id: "1", id: "1",
name: { name: {
decryptedValue: [],
encryptedString: "test", encryptedString: "test",
encryptionType: 0, encryptionType: 0,
decryptedValue: "DEC",
}, },
revisionDate: null, revisionDate: null,
}, },
{ {
id: "2", id: "2",
name: { name: {
decryptedValue: [],
encryptedString: "test 2", encryptedString: "test 2",
encryptionType: 0, encryptionType: 0,
decryptedValue: "DEC",
}, },
revisionDate: null, revisionDate: null,
}, },
]); ]);
expect(await firstValueFrom(folderService.folderViews$)).toEqual([ expect(await firstValueFrom(folderService.folderViews$)).toEqual([
{ id: "1", name: [], revisionDate: null }, { id: "1", name: "DEC", revisionDate: null },
{ id: "2", name: [], revisionDate: null }, { id: "2", name: "DEC", revisionDate: null },
{ id: null, name: [], revisionDate: null }, { id: null, name: undefined, revisionDate: null },
]); ]);
}); });
@ -122,7 +131,7 @@ describe("Folder Service", () => {
{ {
id: "2", id: "2",
name: { name: {
decryptedValue: [], decryptedValue: "DEC",
encryptedString: "test 2", encryptedString: "test 2",
encryptionType: 0, encryptionType: 0,
}, },
@ -131,8 +140,8 @@ describe("Folder Service", () => {
]); ]);
expect(await firstValueFrom(folderService.folderViews$)).toEqual([ expect(await firstValueFrom(folderService.folderViews$)).toEqual([
{ id: "2", name: [], revisionDate: null }, { id: "2", name: "DEC", revisionDate: null },
{ id: null, name: [], revisionDate: null }, { id: null, name: undefined, revisionDate: null },
]); ]);
}); });
@ -142,7 +151,7 @@ describe("Folder Service", () => {
expect((await firstValueFrom(folderService.folders$)).length).toBe(0); expect((await firstValueFrom(folderService.folders$)).length).toBe(0);
expect(await firstValueFrom(folderService.folderViews$)).toEqual([ expect(await firstValueFrom(folderService.folderViews$)).toEqual([
{ id: null, name: [], revisionDate: null }, { id: null, name: undefined, revisionDate: null },
]); ]);
}); });
@ -166,17 +175,17 @@ describe("Folder Service", () => {
it("null userId", async () => { it("null userId", async () => {
await folderService.clear(); await folderService.clear();
stateService.received(1).setEncryptedFolders(Arg.any(), Arg.any()); expect(stateService.setEncryptedFolders).toBeCalledTimes(1);
expect((await firstValueFrom(folderService.folders$)).length).toBe(0); expect((await firstValueFrom(folderService.folders$)).length).toBe(0);
expect((await firstValueFrom(folderService.folderViews$)).length).toBe(0); expect((await firstValueFrom(folderService.folderViews$)).length).toBe(0);
}); });
it("matching userId", async () => { it("matching userId", async () => {
stateService.getUserId().resolves("1"); stateService.getUserId.mockResolvedValue("1");
await folderService.clear("1"); await folderService.clear("1");
stateService.received(1).setEncryptedFolders(Arg.any(), Arg.any()); expect(stateService.setEncryptedFolders).toBeCalledTimes(1);
expect((await firstValueFrom(folderService.folders$)).length).toBe(0); expect((await firstValueFrom(folderService.folders$)).length).toBe(0);
expect((await firstValueFrom(folderService.folderViews$)).length).toBe(0); expect((await firstValueFrom(folderService.folderViews$)).length).toBe(0);
@ -185,7 +194,7 @@ describe("Folder Service", () => {
it("missmatching userId", async () => { it("missmatching userId", async () => {
await folderService.clear("12"); await folderService.clear("12");
stateService.received(1).setEncryptedFolders(Arg.any(), Arg.any()); expect(stateService.setEncryptedFolders).toBeCalledTimes(1);
expect((await firstValueFrom(folderService.folders$)).length).toBe(1); expect((await firstValueFrom(folderService.folders$)).length).toBe(1);
expect((await firstValueFrom(folderService.folderViews$)).length).toBe(2); expect((await firstValueFrom(folderService.folderViews$)).length).toBe(2);

View File

@ -1,5 +1,4 @@
// eslint-disable-next-line no-restricted-imports import { mock, MockProxy } from "jest-mock-extended";
import { Arg, Substitute, SubstituteOf } from "@fluffy-spoon/substitute";
import { ApiService } from "@bitwarden/common/abstractions/api.service"; import { ApiService } from "@bitwarden/common/abstractions/api.service";
import { KdfConfig } from "@bitwarden/common/auth/models/domain/kdf-config"; import { KdfConfig } from "@bitwarden/common/auth/models/domain/kdf-config";
@ -142,25 +141,26 @@ function expectEqualFolders(folders: Folder[], jsonResult: string) {
describe("VaultExportService", () => { describe("VaultExportService", () => {
let exportService: VaultExportService; let exportService: VaultExportService;
let apiService: SubstituteOf<ApiService>; let apiService: MockProxy<ApiService>;
let cryptoFunctionService: SubstituteOf<CryptoFunctionService>; let cryptoFunctionService: MockProxy<CryptoFunctionService>;
let cipherService: SubstituteOf<CipherService>; let cipherService: MockProxy<CipherService>;
let folderService: SubstituteOf<FolderService>; let folderService: MockProxy<FolderService>;
let cryptoService: SubstituteOf<CryptoService>; let cryptoService: MockProxy<CryptoService>;
let stateService: SubstituteOf<StateService>; let stateService: MockProxy<StateService>;
beforeEach(() => { beforeEach(() => {
apiService = Substitute.for<ApiService>(); apiService = mock<ApiService>();
cryptoFunctionService = Substitute.for<CryptoFunctionService>(); cryptoFunctionService = mock<CryptoFunctionService>();
cipherService = Substitute.for<CipherService>(); cipherService = mock<CipherService>();
folderService = Substitute.for<FolderService>(); folderService = mock<FolderService>();
cryptoService = Substitute.for<CryptoService>(); cryptoService = mock<CryptoService>();
stateService = Substitute.for<StateService>(); stateService = mock<StateService>();
folderService.getAllDecryptedFromState().resolves(UserFolderViews); folderService.getAllDecryptedFromState.mockResolvedValue(UserFolderViews);
folderService.getAllFromState().resolves(UserFolders); folderService.getAllFromState.mockResolvedValue(UserFolders);
stateService.getKdfType().resolves(KdfType.PBKDF2_SHA256); stateService.getKdfType.mockResolvedValue(KdfType.PBKDF2_SHA256);
stateService.getKdfConfig().resolves(new KdfConfig(DEFAULT_PBKDF2_ITERATIONS)); stateService.getKdfConfig.mockResolvedValue(new KdfConfig(DEFAULT_PBKDF2_ITERATIONS));
cryptoService.encrypt.mockResolvedValue(new EncString("encrypted"));
exportService = new VaultExportService( exportService = new VaultExportService(
folderService, folderService,
@ -173,7 +173,7 @@ describe("VaultExportService", () => {
}); });
it("exports unencrypted user ciphers", async () => { it("exports unencrypted user ciphers", async () => {
cipherService.getAllDecrypted().resolves(UserCipherViews.slice(0, 1)); cipherService.getAllDecrypted.mockResolvedValue(UserCipherViews.slice(0, 1));
const actual = await exportService.getExport("json"); const actual = await exportService.getExport("json");
@ -181,7 +181,7 @@ describe("VaultExportService", () => {
}); });
it("exports encrypted json user ciphers", async () => { it("exports encrypted json user ciphers", async () => {
cipherService.getAll().resolves(UserCipherDomains.slice(0, 1)); cipherService.getAll.mockResolvedValue(UserCipherDomains.slice(0, 1));
const actual = await exportService.getExport("encrypted_json"); const actual = await exportService.getExport("encrypted_json");
@ -189,7 +189,7 @@ describe("VaultExportService", () => {
}); });
it("does not unencrypted export trashed user items", async () => { it("does not unencrypted export trashed user items", async () => {
cipherService.getAllDecrypted().resolves(UserCipherViews); cipherService.getAllDecrypted.mockResolvedValue(UserCipherViews);
const actual = await exportService.getExport("json"); const actual = await exportService.getExport("json");
@ -197,7 +197,7 @@ describe("VaultExportService", () => {
}); });
it("does not encrypted export trashed user items", async () => { it("does not encrypted export trashed user items", async () => {
cipherService.getAll().resolves(UserCipherDomains); cipherService.getAll.mockResolvedValue(UserCipherDomains);
const actual = await exportService.getExport("encrypted_json"); const actual = await exportService.getExport("encrypted_json");
@ -207,21 +207,21 @@ describe("VaultExportService", () => {
describe("password protected export", () => { describe("password protected export", () => {
let exportString: string; let exportString: string;
let exportObject: any; let exportObject: any;
let mac: SubstituteOf<EncString>; let mac: MockProxy<EncString>;
let data: SubstituteOf<EncString>; let data: MockProxy<EncString>;
const password = "password"; const password = "password";
const salt = "salt"; const salt = "salt";
describe("export json object", () => { describe("export json object", () => {
beforeEach(async () => { beforeEach(async () => {
mac = Substitute.for<EncString>(); mac = mock<EncString>();
data = Substitute.for<EncString>(); data = mock<EncString>();
mac.encryptedString.returns("mac" as EncryptedString); mac.encryptedString = "mac" as EncryptedString;
data.encryptedString.returns("encData" as EncryptedString); data.encryptedString = "encData" as EncryptedString;
jest.spyOn(Utils, "fromBufferToB64").mockReturnValue(salt); jest.spyOn(Utils, "fromBufferToB64").mockReturnValue(salt);
cipherService.getAllDecrypted().resolves(UserCipherViews.slice(0, 1)); cipherService.getAllDecrypted.mockResolvedValue(UserCipherViews.slice(0, 1));
exportString = await exportService.getPasswordProtectedExport(password); exportString = await exportService.getPasswordProtectedExport(password);
exportObject = JSON.parse(exportString); exportObject = JSON.parse(exportString);
@ -248,7 +248,7 @@ describe("VaultExportService", () => {
}); });
it("has a mac property", async () => { it("has a mac property", async () => {
cryptoService.encrypt(Arg.any(), Arg.any()).resolves(mac); cryptoService.encrypt.mockResolvedValue(mac);
exportString = await exportService.getPasswordProtectedExport(password); exportString = await exportService.getPasswordProtectedExport(password);
exportObject = JSON.parse(exportString); exportObject = JSON.parse(exportString);
@ -256,7 +256,7 @@ describe("VaultExportService", () => {
}); });
it("has data property", async () => { it("has data property", async () => {
cryptoService.encrypt(Arg.any(), Arg.any()).resolves(data); cryptoService.encrypt.mockResolvedValue(data);
exportString = await exportService.getPasswordProtectedExport(password); exportString = await exportService.getPasswordProtectedExport(password);
exportObject = JSON.parse(exportString); exportObject = JSON.parse(exportString);
@ -271,7 +271,7 @@ describe("VaultExportService", () => {
}); });
it("exported unencrypted object contains folders", async () => { it("exported unencrypted object contains folders", async () => {
cipherService.getAllDecrypted().resolves(UserCipherViews.slice(0, 1)); cipherService.getAllDecrypted.mockResolvedValue(UserCipherViews.slice(0, 1));
await folderService.getAllDecryptedFromState(); await folderService.getAllDecryptedFromState();
const actual = await exportService.getExport("json"); const actual = await exportService.getExport("json");
@ -279,7 +279,7 @@ describe("VaultExportService", () => {
}); });
it("exported encrypted json contains folders", async () => { it("exported encrypted json contains folders", async () => {
cipherService.getAll().resolves(UserCipherDomains.slice(0, 1)); cipherService.getAll.mockResolvedValue(UserCipherDomains.slice(0, 1));
await folderService.getAllFromState(); await folderService.getAllFromState();
const actual = await exportService.getExport("encrypted_json"); const actual = await exportService.getExport("encrypted_json");

14
package-lock.json generated
View File

@ -79,7 +79,6 @@
"@compodoc/compodoc": "1.1.21", "@compodoc/compodoc": "1.1.21",
"@electron/notarize": "1.2.4", "@electron/notarize": "1.2.4",
"@electron/rebuild": "3.2.13", "@electron/rebuild": "3.2.13",
"@fluffy-spoon/substitute": "1.208.0",
"@ngtools/webpack": "15.2.9", "@ngtools/webpack": "15.2.9",
"@storybook/addon-a11y": "7.3.0", "@storybook/addon-a11y": "7.3.0",
"@storybook/addon-actions": "7.3.0", "@storybook/addon-actions": "7.3.0",
@ -6011,19 +6010,6 @@
"integrity": "sha512-m0G6wlnhm/AX0H12IOWtK8gASEMffnX08RtKkCgTdHb9JpHKGloI7icFfLg9ZmQeavcvR0PKmzxClyuFPSjKWw==", "integrity": "sha512-m0G6wlnhm/AX0H12IOWtK8gASEMffnX08RtKkCgTdHb9JpHKGloI7icFfLg9ZmQeavcvR0PKmzxClyuFPSjKWw==",
"dev": true "dev": true
}, },
"node_modules/@fluffy-spoon/substitute": {
"version": "1.208.0",
"resolved": "https://registry.npmjs.org/@fluffy-spoon/substitute/-/substitute-1.208.0.tgz",
"integrity": "sha512-BU5vKRoK4OYlKzDtyg4HbtWnUNLOvV0ntqEZIphz+mq2G0HlVFywwJ7M+FbIcnJVDbUReS01FyL5x8R01r7zBg==",
"dev": true,
"engines": {
"node": ">=10"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/substitute-js#section-contribute"
}
},
"node_modules/@foliojs-fork/fontkit": { "node_modules/@foliojs-fork/fontkit": {
"version": "1.9.1", "version": "1.9.1",
"resolved": "https://registry.npmjs.org/@foliojs-fork/fontkit/-/fontkit-1.9.1.tgz", "resolved": "https://registry.npmjs.org/@foliojs-fork/fontkit/-/fontkit-1.9.1.tgz",

View File

@ -44,7 +44,6 @@
"@compodoc/compodoc": "1.1.21", "@compodoc/compodoc": "1.1.21",
"@electron/notarize": "1.2.4", "@electron/notarize": "1.2.4",
"@electron/rebuild": "3.2.13", "@electron/rebuild": "3.2.13",
"@fluffy-spoon/substitute": "1.208.0",
"@ngtools/webpack": "15.2.9", "@ngtools/webpack": "15.2.9",
"@storybook/addon-a11y": "7.3.0", "@storybook/addon-a11y": "7.3.0",
"@storybook/addon-actions": "7.3.0", "@storybook/addon-actions": "7.3.0",