196 lines
7.1 KiB
TypeScript
196 lines
7.1 KiB
TypeScript
import { describe, test, expect } from "bun:test";
|
|
import { CredentialController } from "../../../src/controllers/CredentialController";
|
|
import { buildMockCredential } from "../../setup";
|
|
import { ValueType } from "../../../src/modules/credentials/credentialTypeDefs";
|
|
|
|
describe("CredentialController", () => {
|
|
// -------------------------------------------------------------------
|
|
// Constructor & _buildFields
|
|
// -------------------------------------------------------------------
|
|
describe("constructor", () => {
|
|
test("sets public properties from credential data", () => {
|
|
const data = buildMockCredential();
|
|
const ctrl = new CredentialController(data);
|
|
expect(ctrl.id).toBe("cred-1");
|
|
expect(ctrl.name).toBe("Test Credential");
|
|
expect(ctrl.notes).toBeNull();
|
|
expect(ctrl.typeId).toBe("ctype-1");
|
|
expect(ctrl.companyId).toBe("company-1");
|
|
expect(ctrl.subCredentialOfId).toBeNull();
|
|
});
|
|
|
|
test("builds fields from type definition", () => {
|
|
const data = buildMockCredential();
|
|
const ctrl = new CredentialController(data);
|
|
expect(Array.isArray(ctrl.fields)).toBe(true);
|
|
expect(ctrl.fields).toHaveLength(2);
|
|
});
|
|
|
|
test("plain fields have value from raw data", () => {
|
|
const data = buildMockCredential();
|
|
const ctrl = new CredentialController(data);
|
|
const usernameField = ctrl.fields.find((f: any) => f.id === "username");
|
|
expect(usernameField).toBeDefined();
|
|
expect(usernameField.value).toBe("admin");
|
|
expect(usernameField.secure).toBe(false);
|
|
});
|
|
|
|
test("secure fields reference secure value ID", () => {
|
|
const data = buildMockCredential();
|
|
const ctrl = new CredentialController(data);
|
|
const passwordField = ctrl.fields.find((f: any) => f.id === "password");
|
|
expect(passwordField).toBeDefined();
|
|
expect(passwordField.secure).toBe(true);
|
|
expect(passwordField.value).toBe("secure-sv-1");
|
|
});
|
|
|
|
test("handles sub-credentials in constructor", () => {
|
|
const subCred = buildMockCredential({
|
|
id: "sub-cred-1",
|
|
name: "Sub Cred",
|
|
subCredentialOfId: "cred-1",
|
|
type: {
|
|
id: "ctype-1",
|
|
name: "Login Credential",
|
|
permissionScope: "credential.login",
|
|
icon: null,
|
|
fields: [
|
|
{
|
|
id: "username",
|
|
name: "Username",
|
|
required: true,
|
|
secure: false,
|
|
valueType: "plain_text",
|
|
},
|
|
],
|
|
},
|
|
securevalues: [],
|
|
subCredentials: [],
|
|
});
|
|
const parent = buildMockCredential({
|
|
subCredentials: [subCred],
|
|
});
|
|
const ctrl = new CredentialController(parent);
|
|
// The parent should have the sub-credential processed
|
|
expect(ctrl.id).toBe("cred-1");
|
|
});
|
|
});
|
|
|
|
// -------------------------------------------------------------------
|
|
// getType / getCompany
|
|
// -------------------------------------------------------------------
|
|
describe("getType() / getCompany()", () => {
|
|
test("getType returns the credential type", () => {
|
|
const ctrl = new CredentialController(buildMockCredential());
|
|
const type = ctrl.getType();
|
|
expect(type.id).toBe("ctype-1");
|
|
expect(type.name).toBe("Login Credential");
|
|
});
|
|
|
|
test("getCompany returns the company", () => {
|
|
const ctrl = new CredentialController(buildMockCredential());
|
|
const company = ctrl.getCompany();
|
|
expect(company.id).toBe("company-1");
|
|
expect(company.name).toBe("Test Company");
|
|
});
|
|
});
|
|
|
|
// -------------------------------------------------------------------
|
|
// toJson
|
|
// -------------------------------------------------------------------
|
|
describe("toJson()", () => {
|
|
test("returns structured JSON without secure field IDs by default", () => {
|
|
const ctrl = new CredentialController(buildMockCredential());
|
|
const json = ctrl.toJson();
|
|
expect(json.id).toBe("cred-1");
|
|
expect(json.name).toBe("Test Credential");
|
|
expect(json.typeId).toBe("ctype-1");
|
|
expect(json.companyId).toBe("company-1");
|
|
expect(json.type.id).toBe("ctype-1");
|
|
expect(json.company.id).toBe("company-1");
|
|
expect(json.secureFieldIds).toBeUndefined();
|
|
});
|
|
|
|
test("includes secure field IDs when includeSecureValues is true", () => {
|
|
const ctrl = new CredentialController(buildMockCredential());
|
|
const json = ctrl.toJson({ includeSecureValues: true });
|
|
expect(json.secureFieldIds).toBeDefined();
|
|
expect(json.secureFieldIds).toContain("password");
|
|
});
|
|
|
|
test("includes subCredentialOfId when present", () => {
|
|
const data = buildMockCredential({ subCredentialOfId: "parent-1" });
|
|
const ctrl = new CredentialController(data);
|
|
const json = ctrl.toJson();
|
|
expect(json.subCredentialOfId).toBe("parent-1");
|
|
});
|
|
|
|
test("excludes subCredentialOfId when null", () => {
|
|
const ctrl = new CredentialController(buildMockCredential());
|
|
const json = ctrl.toJson();
|
|
expect(json.subCredentialOfId).toBeUndefined();
|
|
});
|
|
|
|
test("includes timestamp fields", () => {
|
|
const ctrl = new CredentialController(buildMockCredential());
|
|
const json = ctrl.toJson();
|
|
expect(json.createdAt).toBeDefined();
|
|
expect(json.updatedAt).toBeDefined();
|
|
});
|
|
|
|
test("subCredentials is undefined when empty", () => {
|
|
const ctrl = new CredentialController(buildMockCredential());
|
|
const json = ctrl.toJson();
|
|
expect(json.subCredentials).toBeUndefined();
|
|
});
|
|
});
|
|
|
|
// -------------------------------------------------------------------
|
|
// Sub-credential field building
|
|
// -------------------------------------------------------------------
|
|
describe("sub-credential field building", () => {
|
|
test("builds fields differently for sub-credentials", () => {
|
|
const subData = buildMockCredential({
|
|
id: "sub-1",
|
|
subCredentialOfId: "parent-1",
|
|
fields: { sub_user: "jdoe" },
|
|
type: {
|
|
id: "ctype-1",
|
|
name: "Login",
|
|
permissionScope: "credential.login",
|
|
icon: null,
|
|
fields: [
|
|
{
|
|
id: "sub_user",
|
|
name: "Sub User",
|
|
required: true,
|
|
secure: false,
|
|
valueType: ValueType.PLAIN_TEXT,
|
|
},
|
|
],
|
|
},
|
|
securevalues: [
|
|
{
|
|
id: "sv-2",
|
|
name: "sub_pass",
|
|
content: "enc",
|
|
hash: "hash",
|
|
credentialId: "sub-1",
|
|
createdAt: new Date("2025-01-01"),
|
|
updatedAt: new Date("2025-01-01"),
|
|
},
|
|
],
|
|
});
|
|
const ctrl = new CredentialController(subData);
|
|
// Sub-credential fields are built as array with id/value/secure
|
|
expect(Array.isArray(ctrl.fields)).toBe(true);
|
|
const plainField = ctrl.fields.find((f: any) => f.id === "sub_user");
|
|
expect(plainField).toBeDefined();
|
|
expect(plainField.secure).toBe(false);
|
|
const secureField = ctrl.fields.find((f: any) => f.id === "sub_pass");
|
|
expect(secureField).toBeDefined();
|
|
expect(secureField.secure).toBe(true);
|
|
});
|
|
});
|
|
});
|