Initial Commit
This commit is contained in:
@@ -0,0 +1,181 @@
|
||||
import { describe, expect, it } from "@suaveplan/testing/runner";
|
||||
import { AuditEventType, AuditSeverity } from "../constants/index.js";
|
||||
import {
|
||||
AuditActorSchema,
|
||||
AuditEventSchema,
|
||||
AuditEventTypeSchema,
|
||||
AuditQueryOptionsSchema,
|
||||
AuditRetentionPolicySchema,
|
||||
AuditSeveritySchema,
|
||||
AuditTargetSchema,
|
||||
ChainVerificationResultSchema,
|
||||
RetentionResultSchema,
|
||||
} from "./audit-logging.schemas.js";
|
||||
|
||||
describe("AuditSeveritySchema", () => {
|
||||
it("accepts valid values", { timeout: 5000 }, () => {
|
||||
for (const v of Object.values(AuditSeverity)) {
|
||||
expect(AuditSeveritySchema.parse(v)).toBe(v);
|
||||
}
|
||||
});
|
||||
|
||||
it("rejects invalid value", { timeout: 5000 }, () => {
|
||||
expect(() => AuditSeveritySchema.parse("trace")).toThrow();
|
||||
});
|
||||
});
|
||||
|
||||
describe("AuditEventTypeSchema", () => {
|
||||
it("accepts all built-in event types", { timeout: 5000 }, () => {
|
||||
for (const v of Object.values(AuditEventType)) {
|
||||
expect(AuditEventTypeSchema.parse(v)).toBe(v);
|
||||
}
|
||||
});
|
||||
|
||||
it("rejects unknown type", { timeout: 5000 }, () => {
|
||||
expect(() => AuditEventTypeSchema.parse("not_a_type")).toThrow();
|
||||
});
|
||||
});
|
||||
|
||||
describe("AuditActorSchema", () => {
|
||||
it("accepts empty object", { timeout: 5000 }, () => {
|
||||
expect(AuditActorSchema.parse({})).toEqual({});
|
||||
});
|
||||
|
||||
it("accepts all fields", { timeout: 5000 }, () => {
|
||||
const actor = {
|
||||
userId: "u1",
|
||||
sessionId: "s1",
|
||||
apiKeyId: "k1",
|
||||
ipAddress: "1.2.3.4",
|
||||
userAgent: "Mozilla",
|
||||
tenantId: "t1",
|
||||
};
|
||||
expect(AuditActorSchema.parse(actor)).toEqual(actor);
|
||||
});
|
||||
});
|
||||
|
||||
describe("AuditTargetSchema", () => {
|
||||
it("accepts required fields", { timeout: 5000 }, () => {
|
||||
expect(AuditTargetSchema.parse({ type: "doc", id: "d1" })).toEqual({
|
||||
type: "doc",
|
||||
id: "d1",
|
||||
});
|
||||
});
|
||||
|
||||
it("accepts metadata", { timeout: 5000 }, () => {
|
||||
const t = { type: "doc", id: "d1", metadata: { version: 2 } };
|
||||
expect(AuditTargetSchema.parse(t)).toEqual(t);
|
||||
});
|
||||
|
||||
it("rejects missing required fields", { timeout: 5000 }, () => {
|
||||
expect(() => AuditTargetSchema.parse({ type: "doc" })).toThrow();
|
||||
});
|
||||
});
|
||||
|
||||
describe("AuditEventSchema", () => {
|
||||
const base = {
|
||||
id: "evt-1",
|
||||
type: AuditEventType.AUTH_LOGIN,
|
||||
severity: AuditSeverity.INFO,
|
||||
actor: { userId: "u1" },
|
||||
timestamp: new Date("2024-01-01"),
|
||||
hash: "deadbeef",
|
||||
};
|
||||
|
||||
it("accepts valid event", { timeout: 5000 }, () => {
|
||||
const result = AuditEventSchema.parse(base);
|
||||
expect(result.id).toBe("evt-1");
|
||||
});
|
||||
|
||||
it("accepts custom event type string via union", { timeout: 5000 }, () => {
|
||||
const result = AuditEventSchema.parse({
|
||||
...base,
|
||||
type: "custom_event",
|
||||
});
|
||||
expect(result.type).toBe("custom_event");
|
||||
});
|
||||
|
||||
it("accepts all optional fields", { timeout: 5000 }, () => {
|
||||
const event = {
|
||||
...base,
|
||||
target: { type: "doc", id: "d1" },
|
||||
details: { key: "val" },
|
||||
previousHash: "prev",
|
||||
tenantId: "t1",
|
||||
correlationId: "corr",
|
||||
};
|
||||
expect(AuditEventSchema.parse(event)).toEqual(event);
|
||||
});
|
||||
|
||||
it("rejects missing required fields", { timeout: 5000 }, () => {
|
||||
expect(() =>
|
||||
AuditEventSchema.parse({ ...base, id: undefined })
|
||||
).toThrow();
|
||||
});
|
||||
});
|
||||
|
||||
describe("AuditQueryOptionsSchema", () => {
|
||||
it("accepts empty object", { timeout: 5000 }, () => {
|
||||
expect(AuditQueryOptionsSchema.parse({})).toEqual({});
|
||||
});
|
||||
|
||||
it("accepts severity as single value", { timeout: 5000 }, () => {
|
||||
const r = AuditQueryOptionsSchema.parse({
|
||||
severity: AuditSeverity.ERROR,
|
||||
});
|
||||
expect(r.severity).toBe(AuditSeverity.ERROR);
|
||||
});
|
||||
|
||||
it("accepts severity as array", { timeout: 5000 }, () => {
|
||||
const r = AuditQueryOptionsSchema.parse({
|
||||
severity: [AuditSeverity.ERROR, AuditSeverity.CRITICAL],
|
||||
});
|
||||
expect(Array.isArray(r.severity)).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
describe("AuditRetentionPolicySchema", () => {
|
||||
it("accepts valid policy", { timeout: 5000 }, () => {
|
||||
const p = {
|
||||
retentionDays: 90,
|
||||
archiveBeforeDelete: true,
|
||||
archiveLocation: "s3://bucket",
|
||||
};
|
||||
expect(AuditRetentionPolicySchema.parse(p)).toEqual(p);
|
||||
});
|
||||
|
||||
it("rejects retentionDays = 0", { timeout: 5000 }, () => {
|
||||
expect(() =>
|
||||
AuditRetentionPolicySchema.parse({
|
||||
retentionDays: 0,
|
||||
archiveBeforeDelete: false,
|
||||
})
|
||||
).toThrow();
|
||||
});
|
||||
});
|
||||
|
||||
describe("ChainVerificationResultSchema", () => {
|
||||
it("accepts valid result", { timeout: 5000 }, () => {
|
||||
expect(ChainVerificationResultSchema.parse({ valid: true })).toEqual({
|
||||
valid: true,
|
||||
});
|
||||
expect(
|
||||
ChainVerificationResultSchema.parse({
|
||||
valid: false,
|
||||
brokenAt: 3,
|
||||
reason: "mismatch",
|
||||
})
|
||||
).toBeDefined();
|
||||
});
|
||||
});
|
||||
|
||||
describe("RetentionResultSchema", () => {
|
||||
it("accepts valid result", { timeout: 5000 }, () => {
|
||||
const r = {
|
||||
eventsDeleted: 5,
|
||||
eventsArchived: 3,
|
||||
errors: ["some error"],
|
||||
};
|
||||
expect(RetentionResultSchema.parse(r)).toEqual(r);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user