Files
prowler/ui/lib/provider-credentials/provider-credential-values.test.ts
T

137 lines
3.8 KiB
TypeScript

import { describe, expect, it } from "vitest";
import templateSchema from "./fixtures/template-credential-schema.json";
import { parseRegistryCredentialSchema } from "./provider-credential-schema";
import {
getCredentialDefaults,
validateCredentialValues,
} from "./provider-credential-values";
const schema = parseRegistryCredentialSchema({
type: "object",
properties: {
token: { type: "string", format: "password", writeOnly: true },
region: { type: "string", enum: ["eu", "us"], default: "eu" },
notes: { type: "string", "x-prowler-widget": "textarea" },
},
required: ["token"],
})!;
describe("dynamic credential validation", () => {
const template = () => parseRegistryCredentialSchema(templateSchema)!;
const templateValues = {
api_url: "https://api.example.test",
api_key: "fixture-key-not-a-secret",
verify_tls: false,
timeout_seconds: "60",
};
it("preserves typed Template defaults and submits booleans and integers", () => {
// Given / When / Then
expect(getCredentialDefaults(template())).toEqual({
ca_bundle: "",
verify_tls: true,
timeout_seconds: 30,
auth_scheme: "bearer",
});
expect(validateCredentialValues(template(), templateValues)).toEqual({
valid: true,
secret: { ...templateValues, timeout_seconds: 60 },
errors: {},
});
});
it.each([1, 300, "1", "300"])("accepts timeout boundary %j", (timeout) => {
expect(
validateCredentialValues(template(), {
...templateValues,
timeout_seconds: timeout,
}),
).toMatchObject({
valid: true,
secret: { timeout_seconds: Number(timeout) },
});
});
it.each([
0,
301,
1.5,
"1.5",
" ",
"1second",
"0x10",
true,
null,
Infinity,
NaN,
])("rejects invalid Template timeouts: %j", (timeout) => {
expect(
validateCredentialValues(template(), {
...templateValues,
timeout_seconds: timeout,
}),
).toMatchObject({
valid: false,
errors: { timeout_seconds: expect.any(String) },
});
});
it.each(["true", "false", 0, 1, null])(
"rejects non-boolean TLS values: %j",
(verifyTls) => {
expect(
validateCredentialValues(template(), {
...templateValues,
verify_tls: verifyTls,
}),
).toMatchObject({
valid: false,
errors: { verify_tls: expect.any(String) },
});
},
);
it("accepts false and zero for required fields without treating them as missing", () => {
const requiredSchema = parseRegistryCredentialSchema({
type: "object",
properties: {
enabled: { type: "boolean" },
retries: { type: "integer" },
},
required: ["enabled", "retries"],
})!;
expect(getCredentialDefaults(requiredSchema)).toEqual({ enabled: false });
expect(
validateCredentialValues(requiredSchema, { enabled: false, retries: 0 }),
).toEqual({
valid: true,
secret: { enabled: false, retries: 0 },
errors: {},
});
expect(validateCredentialValues(requiredSchema, {})).toMatchObject({
valid: false,
errors: { enabled: expect.any(String), retries: expect.any(String) },
});
});
it("uses declared defaults and preserves credential bytes", () => {
expect(getCredentialDefaults(schema)).toEqual({ region: "eu" });
expect(
validateCredentialValues(schema, { token: " secret ", region: "eu" }),
).toEqual({
valid: true,
secret: { token: " secret ", region: "eu" },
errors: {},
});
});
it.each([
{},
{ token: "" },
{ token: "secret", region: "invalid" },
{ token: 12 },
{ token: "secret", extra: "hidden" },
])("rejects invalid or undeclared values: %j", (values) => {
expect(validateCredentialValues(schema, values).valid).toBe(false);
});
});