bitwarden-estensione-browser/apps/browser/src/autofill/browser/main-context-menu-handler.s...

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

141 lines
4.3 KiB
TypeScript
Raw Normal View History

import { mock, MockProxy } from "jest-mock-extended";
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
import { LogService } from "@bitwarden/common/platform/abstractions/log.service";
[SG-998] and [SG-999] Vault and Autofill team refactor (#4542) * Move DeprecatedVaultFilterService to vault folder * [libs] move VaultItemsComponent * [libs] move AddEditComponent * [libs] move AddEditCustomFields * [libs] move attachmentsComponent * [libs] folderAddEditComponent * [libs] IconComponent * [libs] PasswordRepormptComponent * [libs] PremiumComponent * [libs] ViewCustomFieldsComponent * [libs] ViewComponent * [libs] PasswordRepromptService * [libs] Move FolderService and FolderApiService abstractions * [libs] FolderService imports * [libs] PasswordHistoryComponent * [libs] move Sync and SyncNotifier abstractions * [libs] SyncService imports * [libs] fix file casing for passwordReprompt abstraction * [libs] SyncNotifier import fix * [libs] CipherServiceAbstraction * [libs] PasswordRepromptService abstraction * [libs] Fix file casing for angular passwordReprompt service * [libs] fix file casing for SyncNotifierService * [libs] CipherRepromptType * [libs] rename CipherRepromptType * [libs] CipherType * [libs] Rename CipherType * [libs] CipherData * [libs] FolderData * [libs] PasswordHistoryData * [libs] AttachmentData * [libs] CardData * [libs] FieldData * [libs] IdentityData * [libs] LocalData * [libs] LoginData * [libs] SecureNoteData * [libs] LoginUriData * [libs] Domain classes * [libs] SecureNote * [libs] Request models * [libs] Response models * [libs] View part 1 * [libs] Views part 2 * [libs] Move folder services * [libs] Views fixes * [libs] Move sync services * [libs] cipher service * [libs] Types * [libs] Sync file casing * [libs] Fix folder service import * [libs] Move spec files * [libs] casing fixes on spec files * [browser] Autofill background, clipboard, commands * [browser] Fix ContextMenusBackground casing * [browser] Rename fix * [browser] Autofill content * [browser] autofill.js * [libs] enpass importer spec fix * [browser] autofill models * [browser] autofill manifest path updates * [browser] Autofill notification files * [browser] autofill services * [browser] Fix file casing * [browser] Vault popup loose components * [browser] Vault components * [browser] Manifest fixes * [browser] Vault services * [cli] vault commands and models * [browser] File capitilization fixes * [desktop] Vault components and services * [web] vault loose components * [web] Vault components * [browser] Fix misc-utils import * [libs] Fix psono spec imports * [fix] Add comments to address lint rules
2023-01-31 22:08:37 +01:00
import { CipherType } from "@bitwarden/common/vault/enums/cipher-type";
import { Cipher } from "@bitwarden/common/vault/models/domain/cipher";
import { CipherView } from "@bitwarden/common/vault/models/view/cipher.view";
import { BrowserStateService } from "../../platform/services/abstractions/browser-state.service";
import { MainContextMenuHandler } from "./main-context-menu-handler";
describe("context-menu", () => {
let stateService: MockProxy<BrowserStateService>;
let i18nService: MockProxy<I18nService>;
let logService: MockProxy<LogService>;
let removeAllSpy: jest.SpyInstance<void, [callback?: () => void]>;
let createSpy: jest.SpyInstance<
string | number,
[createProperties: chrome.contextMenus.CreateProperties, callback?: () => void]
>;
let sut: MainContextMenuHandler;
beforeEach(() => {
stateService = mock();
i18nService = mock();
logService = mock();
removeAllSpy = jest
.spyOn(chrome.contextMenus, "removeAll")
.mockImplementation((callback) => callback());
createSpy = jest.spyOn(chrome.contextMenus, "create").mockImplementation((props, callback) => {
if (callback) {
callback();
}
return props.id;
});
sut = new MainContextMenuHandler(stateService, i18nService, logService);
});
afterEach(() => jest.resetAllMocks());
describe("init", () => {
it("has menu disabled", async () => {
stateService.getDisableContextMenuItem.mockResolvedValue(true);
const createdMenu = await sut.init();
expect(createdMenu).toBeFalsy();
expect(removeAllSpy).toHaveBeenCalledTimes(1);
});
it("has menu enabled, but does not have premium", async () => {
stateService.getDisableContextMenuItem.mockResolvedValue(false);
stateService.getCanAccessPremium.mockResolvedValue(false);
const createdMenu = await sut.init();
expect(createdMenu).toBeTruthy();
expect(createSpy).toHaveBeenCalledTimes(7);
});
it("has menu enabled and has premium", async () => {
stateService.getDisableContextMenuItem.mockResolvedValue(false);
stateService.getCanAccessPremium.mockResolvedValue(true);
const createdMenu = await sut.init();
expect(createdMenu).toBeTruthy();
expect(createSpy).toHaveBeenCalledTimes(8);
});
});
describe("loadOptions", () => {
const createCipher = (data?: {
id?: CipherView["id"];
username?: CipherView["login"]["username"];
password?: CipherView["login"]["password"];
totp?: CipherView["login"]["totp"];
viewPassword?: CipherView["viewPassword"];
}): CipherView => {
const { id, username, password, totp, viewPassword } = data || {};
const cipherView = new CipherView(
new Cipher({
id: id ?? "1",
type: CipherType.Login,
viewPassword: viewPassword ?? true,
} as any)
);
cipherView.login.username = username ?? "USERNAME";
cipherView.login.password = password ?? "PASSWORD";
cipherView.login.totp = totp ?? "TOTP";
return cipherView;
};
it("is not a login cipher", async () => {
await sut.loadOptions("TEST_TITLE", "1", "", {
...createCipher(),
type: CipherType.SecureNote,
} as any);
expect(createSpy).not.toHaveBeenCalled();
});
it("creates item for autofill", async () => {
await sut.loadOptions(
"TEST_TITLE",
"1",
"",
createCipher({
username: "",
totp: "",
viewPassword: false,
})
);
expect(createSpy).toHaveBeenCalledTimes(1);
});
it("create entry for each cipher piece", async () => {
stateService.getCanAccessPremium.mockResolvedValue(true);
await sut.loadOptions("TEST_TITLE", "1", "", createCipher());
// One for autofill, copy username, copy password, and copy totp code
expect(createSpy).toHaveBeenCalledTimes(4);
});
it("creates noop item for no cipher", async () => {
stateService.getCanAccessPremium.mockResolvedValue(true);
await sut.loadOptions("TEST_TITLE", "NOOP", "");
expect(createSpy).toHaveBeenCalledTimes(4);
});
});
});