From ad23ee9e34ce02fb593edbecef0ee0e4e29e6351 Mon Sep 17 00:00:00 2001 From: jaasen-livefront Date: Mon, 10 Nov 2025 13:33:38 -0800 Subject: [PATCH] add specs --- .../src/models/export/cipher.export.spec.ts | 34 ------ .../models/export/fido2-credential.export.ts | 3 +- .../export/fido2-credentials.export.spec.ts | 102 ++++++++++++++++++ .../export/password-history.export.spec.ts | 26 +++++ .../src/models/export/ssh-key.export.spec.ts | 35 ++++++ 5 files changed, 165 insertions(+), 35 deletions(-) create mode 100644 libs/common/src/models/export/fido2-credentials.export.spec.ts create mode 100644 libs/common/src/models/export/password-history.export.spec.ts create mode 100644 libs/common/src/models/export/ssh-key.export.spec.ts diff --git a/libs/common/src/models/export/cipher.export.spec.ts b/libs/common/src/models/export/cipher.export.spec.ts index 53541aa6758..42c01ccef15 100644 --- a/libs/common/src/models/export/cipher.export.spec.ts +++ b/libs/common/src/models/export/cipher.export.spec.ts @@ -3,8 +3,6 @@ import { SecureNoteExport } from "@bitwarden/common/models/export/secure-note.ex import { CipherType } from "@bitwarden/common/vault/enums"; import { CipherView } from "@bitwarden/common/vault/models/view/cipher.view"; -import { SshKeyExport } from "./ssh-key.export"; - describe("Cipher Export", () => { describe("toView", () => { it.each([[null], [undefined]])( @@ -43,36 +41,4 @@ describe("Cipher Export", () => { expect(resultView.deletedDate).toEqual(request.deletedDate); }); }); - - describe("SshKeyExport.toView", () => { - const validSshKey = { - privateKey: "PRIVATE_KEY", - publicKey: "PUBLIC_KEY", - keyFingerprint: "FINGERPRINT", - }; - - it.each([null, undefined, "", " "])("should throw when privateKey is %p", (value) => { - const sshKey = { ...validSshKey, privateKey: value } as any; - expect(() => SshKeyExport.toView(sshKey)).toThrow("SSH key private key is required."); - }); - - it.each([null, undefined, "", " "])("should throw when publicKey is %p", (value) => { - const sshKey = { ...validSshKey, publicKey: value } as any; - expect(() => SshKeyExport.toView(sshKey)).toThrow("SSH key public key is required."); - }); - - it.each([null, undefined, "", " "])("should throw when keyFingerprint is %p", (value) => { - const sshKey = { ...validSshKey, keyFingerprint: value } as any; - expect(() => SshKeyExport.toView(sshKey)).toThrow("SSH key fingerprint is required."); - }); - - it("should succeed with valid inputs", () => { - const sshKey = { ...validSshKey }; - const result = SshKeyExport.toView(sshKey); - expect(result).toBeDefined(); - expect(result?.privateKey).toBe(validSshKey.privateKey); - expect(result?.publicKey).toBe(validSshKey.publicKey); - expect(result?.keyFingerprint).toBe(validSshKey.keyFingerprint); - }); - }); }); diff --git a/libs/common/src/models/export/fido2-credential.export.ts b/libs/common/src/models/export/fido2-credential.export.ts index ea26607b0ab..8a4e8e178e6 100644 --- a/libs/common/src/models/export/fido2-credential.export.ts +++ b/libs/common/src/models/export/fido2-credential.export.ts @@ -144,7 +144,8 @@ export class Fido2CredentialExport { this.rpId = safeGetString(o.rpId) ?? ""; this.userHandle = safeGetString(o.userHandle); this.userName = safeGetString(o.userName); - this.counter = safeGetString(String(o.counter)) ?? ""; + this.counter = + safeGetString(typeof o.counter === "number" ? String(o.counter) : o.counter) ?? ""; this.rpName = safeGetString(o.rpName); this.userDisplayName = safeGetString(o.userDisplayName); this.discoverable = safeGetString(String(o.discoverable)) ?? ""; diff --git a/libs/common/src/models/export/fido2-credentials.export.spec.ts b/libs/common/src/models/export/fido2-credentials.export.spec.ts new file mode 100644 index 00000000000..0d4a4827ec5 --- /dev/null +++ b/libs/common/src/models/export/fido2-credentials.export.spec.ts @@ -0,0 +1,102 @@ +import { Fido2CredentialView } from "@bitwarden/common/vault/models/view/fido2-credential.view"; + +import { Fido2CredentialExport } from "./fido2-credential.export"; + +describe("Fido2CredentialsExport", () => { + describe("toView", () => { + const validFido2Credential = { + credentialId: "CREDENTIAL_ID", + keyType: "keyType", + keyAlgorithm: "keyAlgorithm", + keyCurve: "keyCurve", + keyValue: "keyValue", + rpId: "rpId", + userHandle: "userHandle", + userName: "userName", + counter: 123, + discoverable: "true", + creationDate: new Date(), + }; + + it.each([null, undefined, "", " "])("should throw when credentialId is %p", (value) => { + const fido2Credential = new Fido2CredentialExport({ + ...validFido2Credential, + credentialId: value, + }); + expect(() => Fido2CredentialExport.toView(fido2Credential)).toThrow( + "FIDO2 credential ID is required.", + ); + }); + + it.each([null, undefined, "", " "])("should throw when keyType is %p", (value) => { + const fido2Credential = new Fido2CredentialExport({ + ...validFido2Credential, + keyType: value, + }); + expect(() => Fido2CredentialExport.toView(fido2Credential)).toThrow( + "FIDO2 key type is required.", + ); + }); + + it.each([null, undefined, "", " "])("should throw when keyAlgorithm is %p", (value) => { + const fido2Credential = new Fido2CredentialExport({ + ...validFido2Credential, + keyAlgorithm: value, + }); + expect(() => Fido2CredentialExport.toView(fido2Credential)).toThrow( + "FIDO2 key algorithm is required.", + ); + }); + + it.each([null, undefined, "", " "])("should throw when keyCurve is %p", (value) => { + const fido2Credential = new Fido2CredentialExport({ + ...validFido2Credential, + keyCurve: value, + }); + expect(() => Fido2CredentialExport.toView(fido2Credential)).toThrow( + "FIDO2 key curve is required.", + ); + }); + + it.each([null, undefined, "", " "])("should throw when keyValue is %p", (value) => { + const fido2Credential = new Fido2CredentialExport({ + ...validFido2Credential, + keyValue: value, + }); + expect(() => Fido2CredentialExport.toView(fido2Credential)).toThrow( + "FIDO2 key value is required.", + ); + }); + + it.each([null, undefined, "", " "])("should throw when rpId is %p", (value) => { + const fido2Credential = new Fido2CredentialExport({ + ...validFido2Credential, + rpId: value, + }); + expect(() => Fido2CredentialExport.toView(fido2Credential)).toThrow( + "FIDO2 relying party ID is required.", + ); + }); + + it.each([null, undefined])("should throw when counter is %p", (value) => { + const fido2Credential = new Fido2CredentialExport({ + ...validFido2Credential, + counter: value as any, + }); + expect(() => Fido2CredentialExport.toView(fido2Credential)).toThrow( + "FIDO2 counter is required.", + ); + }); + + it("should succeed with valid inputs", () => { + const fido2Credential = new Fido2CredentialExport( + Fido2CredentialView.fromJSON({ ...validFido2Credential }), + ); + const result = Fido2CredentialExport.toView(fido2Credential); + expect(result).toBeDefined(); + expect(result?.credentialId).toBe(validFido2Credential.credentialId); + expect(result?.keyType).toBe(validFido2Credential.keyType); + expect(result?.counter).toBe(validFido2Credential.counter); + }); + }); +}); diff --git a/libs/common/src/models/export/password-history.export.spec.ts b/libs/common/src/models/export/password-history.export.spec.ts new file mode 100644 index 00000000000..14dad7ea177 --- /dev/null +++ b/libs/common/src/models/export/password-history.export.spec.ts @@ -0,0 +1,26 @@ +import { PasswordHistoryExport } from "./password-history.export"; + +describe("PasswordHistoryExport", () => { + describe("toView", () => { + it.each([null, undefined, "", " "])("should throw when password is %p", (value) => { + const passwordHistory = new PasswordHistoryExport({ + password: value as any, + lastUsedDate: new Date(), + }); + expect(() => PasswordHistoryExport.toView(passwordHistory)).toThrow( + "Password history password is required.", + ); + }); + + it("should map fields correctly", () => { + const validPasswordHistory = { + password: "PASSWORD", + lastUsedDate: new Date("2023-01-01T00:00:00Z"), + }; + const result = PasswordHistoryExport.toView(new PasswordHistoryExport(validPasswordHistory)); + expect(result).toBeDefined(); + expect(result.password).toBe(validPasswordHistory.password); + expect(result.lastUsedDate).toBe(validPasswordHistory.lastUsedDate); + }); + }); +}); diff --git a/libs/common/src/models/export/ssh-key.export.spec.ts b/libs/common/src/models/export/ssh-key.export.spec.ts new file mode 100644 index 00000000000..9e54c120a2a --- /dev/null +++ b/libs/common/src/models/export/ssh-key.export.spec.ts @@ -0,0 +1,35 @@ +import { SshKeyView } from "@bitwarden/common/vault/models/view/ssh-key.view"; + +import { SshKeyExport } from "./ssh-key.export"; + +describe("toView", () => { + const validSshKey = { + privateKey: "PRIVATE_KEY", + publicKey: "PUBLIC_KEY", + keyFingerprint: "FINGERPRINT", + }; + + it.each([null, undefined, "", " "])("should throw when privateKey is %p", (value) => { + const sshKey = new SshKeyExport({ ...validSshKey, privateKey: value }); + expect(() => SshKeyExport.toView(sshKey)).toThrow("SSH key private key is required."); + }); + + it.each([null, undefined, "", " "])("should throw when publicKey is %p", (value) => { + const sshKey = new SshKeyExport({ ...validSshKey, publicKey: value }); + expect(() => SshKeyExport.toView(sshKey)).toThrow("SSH key public key is required."); + }); + + it.each([null, undefined, "", " "])("should throw when keyFingerprint is %p", (value) => { + const sshKey = new SshKeyExport({ ...validSshKey, keyFingerprint: value }); + expect(() => SshKeyExport.toView(sshKey)).toThrow("SSH key fingerprint is required."); + }); + + it("should succeed with valid inputs", () => { + const sshKey = new SshKeyExport(SshKeyView.fromJSON({ ...validSshKey })); + const result = SshKeyExport.toView(sshKey); + expect(result).toBeDefined(); + expect(result?.privateKey).toBe(validSshKey.privateKey); + expect(result?.publicKey).toBe(validSshKey.publicKey); + expect(result?.keyFingerprint).toBe(validSshKey.keyFingerprint); + }); +});