import { ComponentFixture, TestBed } from "@angular/core/testing"; import { Router } from "@angular/router"; import { mock, MockProxy } from "jest-mock-extended"; import { LoginStrategyServiceAbstraction, LoginSuccessHandlerService, PasswordLoginCredentials, } from "@bitwarden/auth/common"; import { ApiService } from "@bitwarden/common/abstractions/api.service"; import { AuthResult } from "@bitwarden/common/auth/models/domain/auth-result"; import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service"; import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; import { LogService } from "@bitwarden/common/platform/abstractions/log.service"; import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; import { ToastService } from "@bitwarden/components"; import { KeyService } from "@bitwarden/key-management"; import { I18nPipe } from "@bitwarden/ui-common"; import { RecoverTwoFactorComponent } from "./recover-two-factor.component"; describe("RecoverTwoFactorComponent", () => { let component: RecoverTwoFactorComponent; let fixture: ComponentFixture; // Mock Services let mockRouter: MockProxy; let mockApiService: MockProxy; let mockPlatformUtilsService: MockProxy; let mockI18nService: MockProxy; let mockKeyService: MockProxy; let mockLoginStrategyService: MockProxy; let mockToastService: MockProxy; let mockConfigService: MockProxy; let mockLoginSuccessHandlerService: MockProxy; let mockLogService: MockProxy; beforeEach(() => { mockRouter = mock(); mockApiService = mock(); mockPlatformUtilsService = mock(); mockI18nService = mock(); mockKeyService = mock(); mockLoginStrategyService = mock(); mockToastService = mock(); mockConfigService = mock(); mockLoginSuccessHandlerService = mock(); mockLogService = mock(); TestBed.configureTestingModule({ declarations: [RecoverTwoFactorComponent], providers: [ { provide: Router, useValue: mockRouter }, { provide: ApiService, useValue: mockApiService }, { provide: PlatformUtilsService, mockPlatformUtilsService }, { provide: I18nService, useValue: mockI18nService }, { provide: KeyService, useValue: mockKeyService }, { provide: LoginStrategyServiceAbstraction, useValue: mockLoginStrategyService }, { provide: ToastService, useValue: mockToastService }, { provide: ConfigService, useValue: mockConfigService }, { provide: LoginSuccessHandlerService, useValue: mockLoginSuccessHandlerService }, { provide: LogService, useValue: mockLogService }, ], imports: [I18nPipe], // FIXME(PM-18598): Replace unknownElements and unknownProperties with actual imports errorOnUnknownElements: false, }); fixture = TestBed.createComponent(RecoverTwoFactorComponent); component = fixture.componentInstance; }); afterEach(() => { jest.resetAllMocks(); }); describe("handleRecoveryLogin", () => { it("should log in successfully and navigate to the two-factor settings page", async () => { // Arrange const email = "test@example.com"; const recoveryCode = "testRecoveryCode"; const authResult = new AuthResult(); mockLoginStrategyService.logIn.mockResolvedValue(authResult); // Act await component["loginWithRecoveryCode"](email, recoveryCode); // Assert expect(mockLoginStrategyService.logIn).toHaveBeenCalledWith( expect.any(PasswordLoginCredentials), ); expect(mockToastService.showToast).toHaveBeenCalledWith({ variant: "success", title: "", message: mockI18nService.t("youHaveBeenLoggedIn"), }); expect(mockRouter.navigate).toHaveBeenCalledWith(["/settings/security/two-factor"]); }); it("should handle login errors and redirect to login page", async () => { // Arrange const email = "test@example.com"; const recoveryCode = "testRecoveryCode"; const error = new Error("Login failed"); mockLoginStrategyService.logIn.mockRejectedValue(error); // Act await component["loginWithRecoveryCode"](email, recoveryCode); // Assert expect(mockLogService.error).toHaveBeenCalledWith( "Error logging in automatically: ", error.message, ); expect(mockRouter.navigate).toHaveBeenCalledWith(["/login"], { queryParams: { email: email }, }); }); }); });