1
0
mirror of https://github.com/bitwarden/browser.git synced 2025-01-10 19:38:11 +01:00

[PM-2014] feat: add tests for new credential options

This commit is contained in:
Andreas Coroiu 2023-05-08 15:36:53 +02:00
parent 46ce822b30
commit c593339363
No known key found for this signature in database
GPG Key ID: E70B5FFC81DFEC1A
4 changed files with 69 additions and 11 deletions

View File

@ -0,0 +1,53 @@
import { mock, MockProxy } from "jest-mock-extended";
import { I18nService } from "@bitwarden/common/abstractions/i18n.service";
import { PlatformUtilsService } from "@bitwarden/common/abstractions/platformUtils.service";
import { VerificationType } from "@bitwarden/common/auth/enums/verification-type";
import { ChallengeResponse } from "@bitwarden/common/auth/models/response/two-factor-web-authn.response";
import { Verification } from "@bitwarden/common/types/verification";
import { WebauthnApiService } from "./webauthn-api.service";
import { WebauthnService } from "./webauthn.service";
describe("WebauthnService", () => {
let apiService!: MockProxy<WebauthnApiService>;
let platformUtilsService!: MockProxy<PlatformUtilsService>;
let i18nService!: MockProxy<I18nService>;
let webauthnService!: WebauthnService;
beforeAll(() => {
apiService = mock<WebauthnApiService>();
platformUtilsService = mock<PlatformUtilsService>();
i18nService = mock<I18nService>();
webauthnService = new WebauthnService(apiService, platformUtilsService, i18nService);
});
describe("getNewCredentialOptions", () => {
it("should return undefined and show toast when api service call throws", async () => {
apiService.getChallenge.mockRejectedValue(new Error("Mock error"));
const verification = createVerification();
const result = await webauthnService.getNewCredentialOptions(verification);
expect(result).toBeUndefined();
expect(platformUtilsService.showToast).toHaveBeenCalled();
});
it("should return options when api service call is successfull", async () => {
const challenge: ChallengeResponse = Symbol() as any;
apiService.getChallenge.mockResolvedValue(challenge);
const verification = createVerification();
const result = await webauthnService.getNewCredentialOptions(verification);
expect(result).toEqual({ challenge });
});
});
});
function createVerification(): Verification {
return {
type: VerificationType.MasterPassword,
secret: "secret",
};
}

View File

@ -2,18 +2,16 @@ import { Injectable } from "@angular/core";
import { I18nService } from "@bitwarden/common/abstractions/i18n.service";
import { PlatformUtilsService } from "@bitwarden/common/abstractions/platformUtils.service";
import { ChallengeResponse } from "@bitwarden/common/auth/models/response/two-factor-web-authn.response";
import { ErrorResponse } from "@bitwarden/common/models/response/error.response";
import { Verification } from "@bitwarden/common/types/verification";
import { CoreAuthModule } from "../../core.module";
import { NewCredentialOptionsView } from "../../views/new-credential-options.view";
import { WebauthnApiService } from "./webauthn-api.service";
type WebauthnCredentialView = unknown;
export class UserVerificationFailedError extends Error {}
@Injectable({ providedIn: CoreAuthModule })
export class WebauthnService {
constructor(
@ -22,9 +20,9 @@ export class WebauthnService {
private i18nService: I18nService
) {}
async newCredentialOptions(verification: Verification): Promise<ChallengeResponse> {
async getNewCredentialOptions(verification: Verification): Promise<NewCredentialOptionsView> {
try {
return await this.apiService.getChallenge(verification);
return { challenge: await this.apiService.getChallenge(verification) };
} catch (error) {
if (error instanceof ErrorResponse && error.statusCode === 400) {
this.platformUtilsService.showToast(
@ -39,7 +37,9 @@ export class WebauthnService {
}
}
async createCredential(challenge: ChallengeResponse): Promise<WebauthnCredentialView> {
async createCredential(
credentialOptions: NewCredentialOptionsView
): Promise<WebauthnCredentialView> {
await new Promise((_, reject) => setTimeout(() => reject(new Error("Not implemented")), 1000));
return undefined;
}

View File

@ -0,0 +1,5 @@
import { ChallengeResponse } from "@bitwarden/common/auth/models/response/two-factor-web-authn.response";
export class NewCredentialOptionsView {
constructor(readonly challenge: ChallengeResponse) {}
}

View File

@ -4,9 +4,9 @@ import { FormBuilder, Validators } from "@angular/forms";
import { DialogServiceAbstraction } from "@bitwarden/angular/services/dialog";
import { VerificationType } from "@bitwarden/common/auth/enums/verification-type";
import { ChallengeResponse } from "@bitwarden/common/auth/models/response/two-factor-web-authn.response";
import { WebauthnService } from "../../../core";
import { NewCredentialOptionsView } from "../../../core/views/new-credential-options.view";
import { CreatePasskeyFailedIcon } from "./create-passkey-failed.icon";
import { CreatePasskeyIcon } from "./create-passkey.icon";
@ -38,7 +38,7 @@ export class CreateCredentialDialogComponent {
name: ["", Validators.maxLength(50)],
}),
});
protected challenge?: ChallengeResponse;
protected credentialOptions?: NewCredentialOptionsView;
constructor(
private formBuilder: FormBuilder,
@ -56,11 +56,11 @@ export class CreateCredentialDialogComponent {
return;
}
this.challenge = await this.webauthnService.newCredentialOptions({
this.credentialOptions = await this.webauthnService.getNewCredentialOptions({
type: VerificationType.MasterPassword,
secret: this.formGroup.value.userVerification.masterPassword,
});
if (this.challenge === undefined) {
if (this.credentialOptions === undefined) {
return;
}
this.currentStep = "credentialCreation";
@ -72,7 +72,7 @@ export class CreateCredentialDialogComponent {
if (this.currentStep === "credentialCreation") {
try {
await this.webauthnService.createCredential(this.challenge);
await this.webauthnService.createCredential(this.credentialOptions);
} catch {
this.currentStep = "credentialCreationFailed";
}