1
0
mirror of https://github.com/bitwarden/browser synced 2026-02-06 11:43:51 +00:00

PM-23826 added unit tests to the connect dialog

This commit is contained in:
voommen-livefront
2025-07-24 09:32:17 -05:00
parent 8aaee8fa99
commit b25a039eda
3 changed files with 160 additions and 2 deletions

View File

@@ -116,6 +116,7 @@ export class IntegrationCardComponent implements AfterViewInit, OnDestroy {
const result = await lastValueFrom(dialog.closed);
// for now we just log the result
// eslint-disable-next-line no-console
console.log(`Dialog closed with result: ${JSON.stringify(result)}`);
}

View File

@@ -0,0 +1,156 @@
import { ComponentFixture, TestBed } from "@angular/core/testing";
import { FormBuilder, ReactiveFormsModule } from "@angular/forms";
import { BrowserAnimationsModule } from "@angular/platform-browser/animations";
import { mock } from "jest-mock-extended";
import { IntegrationType } from "@bitwarden/common/enums";
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
import { DIALOG_DATA, DialogConfig, DialogRef, DialogService } from "@bitwarden/components";
import { I18nPipe } from "@bitwarden/ui-common";
import { SharedModule } from "@bitwarden/web-vault/app/shared";
import { Integration } from "../../models";
import {
ConnectDialogComponent,
ConnectDialogParams,
ConnectDialogResult,
openCrowdstrikeConnectDialog,
} from "./connect-dialog.component";
beforeAll(() => {
// Mock element.animate for jsdom
// the animate function is not available in jsdom, so we provide a mock implementation
// This is necessary for tests that rely on animations
// This mock does not perform any actual animations, it just provides a structure that allows tests
// to run without throwing errors related to missing animate function
if (!HTMLElement.prototype.animate) {
HTMLElement.prototype.animate = function () {
return {
play: () => {},
pause: () => {},
finish: () => {},
cancel: () => {},
reverse: () => {},
addEventListener: () => {},
removeEventListener: () => {},
dispatchEvent: () => false,
onfinish: null,
oncancel: null,
startTime: 0,
currentTime: 0,
playbackRate: 1,
playState: "idle",
replaceState: "active",
effect: null,
finished: Promise.resolve(),
id: "",
remove: () => {},
timeline: null,
ready: Promise.resolve(),
} as unknown as Animation;
};
}
});
describe("ConnectDialogComponent", () => {
let component: ConnectDialogComponent;
let fixture: ComponentFixture<ConnectDialogComponent>;
let dialogRefMock = mock<DialogRef<ConnectDialogResult>>();
const mockI18nService = mock<I18nService>();
const integrationMock: Integration = {
name: "Test Integration",
image: "test-image.png",
linkURL: "https://example.com",
imageDarkMode: "test-image-dark.png",
newBadgeExpiration: "2024-12-31",
description: "Test Description",
isConnected: false,
canSetupConnection: true,
type: IntegrationType.EVENT,
} as Integration;
const connectInfo: ConnectDialogParams = { settings: integrationMock };
beforeEach(async () => {
dialogRefMock = mock<DialogRef<ConnectDialogResult>>();
await TestBed.configureTestingModule({
imports: [ReactiveFormsModule, SharedModule, BrowserAnimationsModule],
providers: [
FormBuilder,
{ provide: DIALOG_DATA, useValue: connectInfo },
{ provide: DialogRef, useValue: dialogRefMock },
{ provide: I18nPipe, useValue: mock<I18nPipe>() },
{ provide: I18nService, useValue: mockI18nService },
],
}).compileComponents();
});
beforeEach(() => {
fixture = TestBed.createComponent(ConnectDialogComponent);
component = fixture.componentInstance;
fixture.detectChanges();
mockI18nService.t.mockImplementation((key) => key);
});
it("should create the component", () => {
expect(component).toBeTruthy();
});
it("should initialize form with empty values", () => {
expect(component.formGroup.value).toEqual({
url: "",
bearerToken: "",
index: "",
});
});
it("should have required validators for all fields", () => {
component.formGroup.setValue({ url: "", bearerToken: "", index: "" });
expect(component.formGroup.valid).toBeFalsy();
component.formGroup.setValue({ url: "https://test.com", bearerToken: "token", index: "1" });
expect(component.formGroup.valid).toBeTruthy();
});
it("should invalidate url if not matching pattern", () => {
component.formGroup.setValue({ url: "ftp://test.com", bearerToken: "token", index: "1" });
expect(component.formGroup.valid).toBeFalsy();
component.formGroup.setValue({ url: "https://test.com", bearerToken: "token", index: "1" });
expect(component.formGroup.valid).toBeTruthy();
});
it("should call dialogRef.close with correct result on submit", async () => {
component.formGroup.setValue({
url: "https://test.com",
bearerToken: "token",
index: "1",
});
await component.submit();
expect(dialogRefMock.close).toHaveBeenCalledWith({
integrationSettings: integrationMock,
url: "https://test.com",
bearerToken: "token",
index: "1",
success: true,
error: null,
});
});
});
describe("openCrowdstrikeConnectDialog", () => {
it("should call dialogService.open with correct params", () => {
const dialogServiceMock = mock<DialogService>();
const config: DialogConfig<ConnectDialogParams, DialogRef<ConnectDialogResult>> = {
data: { settings: { name: "Test" } as Integration },
} as any;
openCrowdstrikeConnectDialog(dialogServiceMock, config);
expect(dialogServiceMock.open).toHaveBeenCalledWith(ConnectDialogComponent, config);
});
});

View File

@@ -25,7 +25,7 @@ export interface ConnectDialogResult {
})
export class ConnectDialogComponent {
loading = false;
protected formGroup = this.formBuilder.group({
formGroup = this.formBuilder.group({
url: ["", [Validators.required, Validators.pattern("https?://.+")]],
bearerToken: ["", Validators.required],
index: ["", Validators.required],
@@ -37,7 +37,7 @@ export class ConnectDialogComponent {
private dialogRef: DialogRef<ConnectDialogResult>,
) {}
protected submit = async (): Promise<void> => {
submit = async (): Promise<void> => {
const formJson = this.formGroup.getRawValue();
// eslint-disable-next-line no-console
@@ -52,6 +52,7 @@ export class ConnectDialogComponent {
error: null,
};
// for now, we just log the result
// eslint-disable-next-line no-console
console.log(`Dialog closed with result: ${JSON.stringify(result)}`);