Skip to content

Commit

Permalink
update tests and cleanup
Browse files Browse the repository at this point in the history
  • Loading branch information
jprusik committed Dec 19, 2024
1 parent 1fe4232 commit ab2f085
Show file tree
Hide file tree
Showing 13 changed files with 243 additions and 101 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ import { JslibModule } from "@bitwarden/angular/jslib.module";
import { DomainSettingsService } from "@bitwarden/common/autofill/services/domain-settings.service";

Check warning on line 15 in apps/browser/src/autofill/popup/settings/blocked-domains.component.ts

View check run for this annotation

Codecov / codecov/patch

apps/browser/src/autofill/popup/settings/blocked-domains.component.ts#L14-L15

Added lines #L14 - L15 were not covered by tests
import { NeverDomains } from "@bitwarden/common/models/domain/domain-service";
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service";
import { Utils } from "@bitwarden/common/platform/misc/utils";
import {

Check warning on line 19 in apps/browser/src/autofill/popup/settings/blocked-domains.component.ts

View check run for this annotation

Codecov / codecov/patch

apps/browser/src/autofill/popup/settings/blocked-domains.component.ts#L17-L19

Added lines #L17 - L19 were not covered by tests
ButtonModule,
Expand All @@ -26,6 +25,7 @@ import {
LinkModule,
SectionComponent,
SectionHeaderComponent,
ToastService,
TypographyModule,
} from "@bitwarden/components";

Expand Down Expand Up @@ -59,7 +59,8 @@ import { PopupPageComponent } from "../../../platform/popup/layout/popup-page.co
],
})
export class BlockedDomainsComponent implements AfterViewInit, OnDestroy {
@ViewChildren("uriInput") uriInputElements: QueryList<ElementRef<HTMLInputElement>>;
@ViewChildren("uriInput") uriInputElements: QueryList<ElementRef<HTMLInputElement>> =

Check warning on line 62 in apps/browser/src/autofill/popup/settings/blocked-domains.component.ts

View check run for this annotation

Codecov / codecov/patch

apps/browser/src/autofill/popup/settings/blocked-domains.component.ts#L61-L62

Added lines #L61 - L62 were not covered by tests
new QueryList();

dataIsPristine = true;
isLoading = false;
Expand All @@ -73,7 +74,7 @@ export class BlockedDomainsComponent implements AfterViewInit, OnDestroy {
constructor(
private domainSettingsService: DomainSettingsService,
private i18nService: I18nService,
private platformUtilsService: PlatformUtilsService,
private toastService: ToastService,

Check warning on line 77 in apps/browser/src/autofill/popup/settings/blocked-domains.component.ts

View check run for this annotation

Codecov / codecov/patch

apps/browser/src/autofill/popup/settings/blocked-domains.component.ts#L77

Added line #L77 was not covered by tests
) {}

async ngAfterViewInit() {
Expand Down Expand Up @@ -150,11 +151,11 @@ export class BlockedDomainsComponent implements AfterViewInit, OnDestroy {
const validatedHost = Utils.getHostname(uri);

Check warning on line 151 in apps/browser/src/autofill/popup/settings/blocked-domains.component.ts

View check run for this annotation

Codecov / codecov/patch

apps/browser/src/autofill/popup/settings/blocked-domains.component.ts#L151

Added line #L151 was not covered by tests

if (!validatedHost) {
this.platformUtilsService.showToast(
"error",
null,
this.i18nService.t("excludedDomainsInvalidDomain", uri),
);
this.toastService.showToast({

Check warning on line 154 in apps/browser/src/autofill/popup/settings/blocked-domains.component.ts

View check run for this annotation

Codecov / codecov/patch

apps/browser/src/autofill/popup/settings/blocked-domains.component.ts#L154

Added line #L154 was not covered by tests
message: this.i18nService.t("excludedDomainsInvalidDomain", uri),
title: "",
variant: "error",
});

// Don't reset via `handleStateUpdate` to allow existing input value correction
this.isLoading = false;
Expand All @@ -176,21 +177,25 @@ export class BlockedDomainsComponent implements AfterViewInit, OnDestroy {
if (stateIsUnchanged) {
// Reset UI state directly
const constructedNeverDomainsState = this.storedBlockedDomains.reduce(
(neverDomains, uri) => ({ ...neverDomains, [uri]: null }),
(neverDomains: NeverDomains, uri: string) => ({ ...neverDomains, [uri]: null }),

Check warning on line 180 in apps/browser/src/autofill/popup/settings/blocked-domains.component.ts

View check run for this annotation

Codecov / codecov/patch

apps/browser/src/autofill/popup/settings/blocked-domains.component.ts#L179-L180

Added lines #L179 - L180 were not covered by tests
{},
);
this.handleStateUpdate(constructedNeverDomainsState);

Check warning on line 183 in apps/browser/src/autofill/popup/settings/blocked-domains.component.ts

View check run for this annotation

Codecov / codecov/patch

apps/browser/src/autofill/popup/settings/blocked-domains.component.ts#L183

Added line #L183 was not covered by tests
} else {
await this.domainSettingsService.setBlockedInteractionsUris(newBlockedDomainsSaveState);

Check warning on line 185 in apps/browser/src/autofill/popup/settings/blocked-domains.component.ts

View check run for this annotation

Codecov / codecov/patch

apps/browser/src/autofill/popup/settings/blocked-domains.component.ts#L185

Added line #L185 was not covered by tests
}

this.platformUtilsService.showToast(
"success",
null,
this.i18nService.t("blockedDomainsSavedSuccess"),
);
this.toastService.showToast({

Check warning on line 188 in apps/browser/src/autofill/popup/settings/blocked-domains.component.ts

View check run for this annotation

Codecov / codecov/patch

apps/browser/src/autofill/popup/settings/blocked-domains.component.ts#L188

Added line #L188 was not covered by tests
message: this.i18nService.t("blockedDomainsSavedSuccess"),
title: "",
variant: "success",
});
} catch {
this.platformUtilsService.showToast("error", null, this.i18nService.t("unexpectedError"));
this.toastService.showToast({

Check warning on line 194 in apps/browser/src/autofill/popup/settings/blocked-domains.component.ts

View check run for this annotation

Codecov / codecov/patch

apps/browser/src/autofill/popup/settings/blocked-domains.component.ts#L194

Added line #L194 was not covered by tests
message: this.i18nService.t("unexpectedError"),
title: "",
variant: "error",
});

// Don't reset via `handleStateUpdate` to preserve input values
this.isLoading = false;

Check warning on line 201 in apps/browser/src/autofill/popup/settings/blocked-domains.component.ts

View check run for this annotation

Codecov / codecov/patch

apps/browser/src/autofill/popup/settings/blocked-domains.component.ts#L201

Added line #L201 was not covered by tests
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
// FIXME: Update this file to be type safe and remove this and next line
// @ts-strict-ignore
import { CommonModule } from "@angular/common";
import {
QueryList,
Expand All @@ -17,7 +15,6 @@ import { JslibModule } from "@bitwarden/angular/jslib.module";
import { DomainSettingsService } from "@bitwarden/common/autofill/services/domain-settings.service";
import { NeverDomains } from "@bitwarden/common/models/domain/domain-service";
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service";
import { Utils } from "@bitwarden/common/platform/misc/utils";
import {
ButtonModule,
Expand All @@ -28,6 +25,7 @@ import {
LinkModule,
SectionComponent,
SectionHeaderComponent,
ToastService,
TypographyModule,
} from "@bitwarden/components";

Expand Down Expand Up @@ -62,7 +60,8 @@ import { PopupPageComponent } from "../../../platform/popup/layout/popup-page.co
],
})
export class ExcludedDomainsComponent implements AfterViewInit, OnDestroy {
@ViewChildren("uriInput") uriInputElements: QueryList<ElementRef<HTMLInputElement>>;
@ViewChildren("uriInput") uriInputElements: QueryList<ElementRef<HTMLInputElement>> =

Check warning on line 63 in apps/browser/src/autofill/popup/settings/excluded-domains.component.ts

View check run for this annotation

Codecov / codecov/patch

apps/browser/src/autofill/popup/settings/excluded-domains.component.ts#L63

Added line #L63 was not covered by tests
new QueryList();

accountSwitcherEnabled = false;
dataIsPristine = true;
Expand All @@ -77,7 +76,7 @@ export class ExcludedDomainsComponent implements AfterViewInit, OnDestroy {
constructor(
private domainSettingsService: DomainSettingsService,
private i18nService: I18nService,
private platformUtilsService: PlatformUtilsService,
private toastService: ToastService,

Check warning on line 79 in apps/browser/src/autofill/popup/settings/excluded-domains.component.ts

View check run for this annotation

Codecov / codecov/patch

apps/browser/src/autofill/popup/settings/excluded-domains.component.ts#L79

Added line #L79 was not covered by tests
) {
this.accountSwitcherEnabled = enableAccountSwitching();
}
Expand Down Expand Up @@ -156,11 +155,11 @@ export class ExcludedDomainsComponent implements AfterViewInit, OnDestroy {
const validatedHost = Utils.getHostname(uri);

if (!validatedHost) {
this.platformUtilsService.showToast(
"error",
null,
this.i18nService.t("excludedDomainsInvalidDomain", uri),
);
this.toastService.showToast({

Check warning on line 158 in apps/browser/src/autofill/popup/settings/excluded-domains.component.ts

View check run for this annotation

Codecov / codecov/patch

apps/browser/src/autofill/popup/settings/excluded-domains.component.ts#L158

Added line #L158 was not covered by tests
message: this.i18nService.t("excludedDomainsInvalidDomain", uri),
title: "",
variant: "error",
});

// Don't reset via `handleStateUpdate` to allow existing input value correction
this.isLoading = false;
Expand All @@ -182,21 +181,25 @@ export class ExcludedDomainsComponent implements AfterViewInit, OnDestroy {
if (stateIsUnchanged) {
// Reset UI state directly
const constructedNeverDomainsState = this.storedExcludedDomains.reduce(
(neverDomains, uri) => ({ ...neverDomains, [uri]: null }),
(neverDomains: NeverDomains, uri: string) => ({ ...neverDomains, [uri]: null }),

Check warning on line 184 in apps/browser/src/autofill/popup/settings/excluded-domains.component.ts

View check run for this annotation

Codecov / codecov/patch

apps/browser/src/autofill/popup/settings/excluded-domains.component.ts#L184

Added line #L184 was not covered by tests
{},
);
this.handleStateUpdate(constructedNeverDomainsState);
} else {
await this.domainSettingsService.setNeverDomains(newExcludedDomainsSaveState);
}

this.platformUtilsService.showToast(
"success",
null,
this.i18nService.t("excludedDomainsSavedSuccess"),
);
this.toastService.showToast({

Check warning on line 192 in apps/browser/src/autofill/popup/settings/excluded-domains.component.ts

View check run for this annotation

Codecov / codecov/patch

apps/browser/src/autofill/popup/settings/excluded-domains.component.ts#L192

Added line #L192 was not covered by tests
message: this.i18nService.t("excludedDomainsSavedSuccess"),
title: "",
variant: "success",
});
} catch {
this.platformUtilsService.showToast("error", null, this.i18nService.t("unexpectedError"));
this.toastService.showToast({

Check warning on line 198 in apps/browser/src/autofill/popup/settings/excluded-domains.component.ts

View check run for this annotation

Codecov / codecov/patch

apps/browser/src/autofill/popup/settings/excluded-domains.component.ts#L198

Added line #L198 was not covered by tests
message: this.i18nService.t("unexpectedError"),
title: "",
variant: "error",
});

// Don't reset via `handleStateUpdate` to preserve input values
this.isLoading = false;
Expand Down
5 changes: 4 additions & 1 deletion apps/browser/src/autofill/services/autofill.service.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,8 @@ describe("AutofillService", () => {
let messageListener: MockProxy<MessageListener>;

beforeEach(() => {
configService = mock<ConfigService>();
configService.getFeatureFlag$.mockImplementation(() => of(false));
scriptInjectorService = new BrowserScriptInjectorService(
domainSettingsService,
platformUtilsService,
Expand All @@ -110,10 +112,10 @@ describe("AutofillService", () => {
autofillSettingsService.inlineMenuVisibility$ = inlineMenuVisibilityMock$;
autofillSettingsService.showInlineMenuCards$ = showInlineMenuCardsMock$;
autofillSettingsService.showInlineMenuIdentities$ = showInlineMenuIdentitiesMock$;
autofillSettingsService.autofillOnPageLoad$ = of(true);
activeAccountStatusMock$ = new BehaviorSubject(AuthenticationStatus.Unlocked);
authService = mock<AuthService>();
authService.activeAccountStatus$ = activeAccountStatusMock$;
configService = mock<ConfigService>();
messageListener = mock<MessageListener>();
enableChangedPasswordPromptMock$ = new BehaviorSubject(true);
enableAddedLoginPromptMock$ = new BehaviorSubject(true);
Expand Down Expand Up @@ -389,6 +391,7 @@ describe("AutofillService", () => {
);
tabMock = createChromeTabMock();
sender = { tab: tabMock, frameId: 1 };
jest.spyOn(BrowserApi, "getTab").mockImplementation(async () => tabMock);
jest.spyOn(BrowserApi, "executeScriptInTab").mockImplementation();
jest
.spyOn(autofillService, "getInlineMenuVisibility")
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,22 @@
import { mock } from "jest-mock-extended";
import { mock, MockProxy } from "jest-mock-extended";
import { of } from "rxjs";

import { DomainSettingsService } from "@bitwarden/common/autofill/services/domain-settings.service";
import {
DomainSettingsService,
DefaultDomainSettingsService,
} from "@bitwarden/common/autofill/services/domain-settings.service";
import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service";
import { LogService } from "@bitwarden/common/platform/abstractions/log.service";
import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service";
import { Utils } from "@bitwarden/common/platform/misc/utils";
import {
FakeStateProvider,
FakeAccountService,
mockAccountServiceWith,
} from "@bitwarden/common/spec";
import { UserId } from "@bitwarden/common/types/guid";

import { createChromeTabMock } from "../../autofill/spec/autofill-mocks";
import { BrowserApi } from "../browser/browser-api";

import {
Expand All @@ -12,8 +25,19 @@ import {
} from "./abstractions/script-injector.service";
import { BrowserScriptInjectorService } from "./browser-script-injector.service";

const mockEquivalentDomains = [
["example.com", "exampleapp.com", "example.co.uk", "ejemplo.es"],
["bitwarden.com", "bitwarden.co.uk", "sm-bitwarden.com"],
["example.co.uk", "exampleapp.co.uk"],
];

describe("ScriptInjectorService", () => {
const tabId = 1;
const tabMock = createChromeTabMock({ id: tabId });
const mockBlockedURI = new URL(tabMock.url);
jest.spyOn(BrowserApi, "executeScriptInTab").mockImplementation();
jest.spyOn(BrowserApi, "isManifestVersion");

const combinedManifestVersionFile = "content/autofill-init.js";
const mv2SpecificFile = "content/autofill-init-mv2.js";
const mv2Details = { file: mv2SpecificFile };
Expand All @@ -23,14 +47,24 @@ describe("ScriptInjectorService", () => {
runAt: "document_start",
};
const manifestVersionSpy = jest.spyOn(BrowserApi, "manifestVersion", "get");

let scriptInjectorService: BrowserScriptInjectorService;
jest.spyOn(BrowserApi, "executeScriptInTab").mockImplementation();
jest.spyOn(BrowserApi, "isManifestVersion");
const domainSettingsService = mock<DomainSettingsService>();
const platformUtilsService = mock<PlatformUtilsService>();
const logService = mock<LogService>();
const platformUtilsService = mock<PlatformUtilsService>();
const mockUserId = Utils.newGuid() as UserId;
const accountService: FakeAccountService = mockAccountServiceWith(mockUserId);
const fakeStateProvider: FakeStateProvider = new FakeStateProvider(accountService);
let configService: MockProxy<ConfigService>;
let domainSettingsService: DomainSettingsService;
const expectedBlockedURIError = new Error("This URI of this tab is on the blocked domains list.");

beforeEach(() => {
jest.spyOn(BrowserApi, "getTab").mockImplementation(async () => tabMock);
configService = mock<ConfigService>();
configService.getFeatureFlag$.mockImplementation(() => of(false));
domainSettingsService = new DefaultDomainSettingsService(fakeStateProvider, configService);
domainSettingsService.equivalentDomains$ = of(mockEquivalentDomains);
domainSettingsService.blockedInteractionsUris$ = of(null);
scriptInjectorService = new BrowserScriptInjectorService(
domainSettingsService,
platformUtilsService,
Expand Down Expand Up @@ -77,6 +111,76 @@ describe("ScriptInjectorService", () => {
{ world: "ISOLATED" },
);
});

it("skips injecting the script in manifest v3 when the tab domain is a blocked domain", async () => {
domainSettingsService.blockedInteractionsUris$ = of({ [mockBlockedURI.host]: null });
manifestVersionSpy.mockReturnValue(3);

await expect(
scriptInjectorService.inject({
tabId,
injectDetails: {
file: combinedManifestVersionFile,
frame: 10,
...sharedInjectDetails,
},
}),
).rejects.toThrow(expectedBlockedURIError);
});

it("skips injecting the script in manifest v2 when the tab domain is a blocked domain", async () => {
domainSettingsService.blockedInteractionsUris$ = of({ [mockBlockedURI.host]: null });
manifestVersionSpy.mockReturnValue(2);

await expect(
scriptInjectorService.inject({
tabId,
injectDetails: {
file: combinedManifestVersionFile,
frame: "all_frames",
...sharedInjectDetails,
},
}),
).rejects.toThrow(expectedBlockedURIError);
});

it("injects the script in manifest v2 when given combined injection details", async () => {
manifestVersionSpy.mockReturnValue(2);

await scriptInjectorService.inject({
tabId,
injectDetails: {
file: combinedManifestVersionFile,
frame: "all_frames",
...sharedInjectDetails,
},
});

expect(BrowserApi.executeScriptInTab).toHaveBeenCalledWith(tabId, {
...sharedInjectDetails,
allFrames: true,
file: combinedManifestVersionFile,
});
});

it("injects the script in manifest v3 when given combined injection details", async () => {
manifestVersionSpy.mockReturnValue(3);

await scriptInjectorService.inject({
tabId,
injectDetails: {
file: combinedManifestVersionFile,
frame: 10,
...sharedInjectDetails,
},
});

expect(BrowserApi.executeScriptInTab).toHaveBeenCalledWith(
tabId,
{ ...sharedInjectDetails, frameId: 10, file: combinedManifestVersionFile },
{ world: "ISOLATED" },
);
});
});

describe("injection of mv2 specific details", () => {
Expand Down
Loading

0 comments on commit ab2f085

Please sign in to comment.