/**
 * Redaction Utility Tests
 *
 * Tests for sensitive data redaction in logs.
 */

import { describe, it, expect } from "vitest";
import { redactSensitiveData, redactUserId, redactInstanceId } from "./redact.util";

describe("Redaction Utilities", () => {
  describe("redactUserId", () => {
    it("should redact user IDs", () => {
      expect(redactUserId("user-12345")).toBe("user-***");
    });

    it("should handle null/undefined", () => {
      expect(redactUserId(null)).toBe("user-***");
      expect(redactUserId(undefined)).toBe("user-***");
    });
  });

  describe("redactInstanceId", () => {
    it("should redact instance IDs", () => {
      expect(redactInstanceId("instance-abc-def")).toBe("instance-***");
    });

    it("should handle null/undefined", () => {
      expect(redactInstanceId(null)).toBe("instance-***");
      expect(redactInstanceId(undefined)).toBe("instance-***");
    });
  });

  describe("redactSensitiveData", () => {
    it("should redact user IDs", () => {
      const data = { userId: "user-123", name: "Test" };
      const redacted = redactSensitiveData(data);

      expect(redacted.userId).toBe("user-***");
      expect(redacted.name).toBe("Test");
    });

    it("should redact instance IDs", () => {
      const data = { instanceId: "instance-456", url: "https://example.com" };
      const redacted = redactSensitiveData(data);

      expect(redacted.instanceId).toBe("instance-***");
      expect(redacted.url).toBe("https://example.com");
    });

    it("should redact metadata objects", () => {
      const data = {
        metadata: { secret: "value", public: "data" },
        other: "field",
      };
      const redacted = redactSensitiveData(data);

      expect(redacted.metadata).toBe("[REDACTED]");
      expect(redacted.other).toBe("field");
    });

    it("should redact payloads", () => {
      const data = {
        payload: { command: "execute", args: ["secret"] },
        type: "command",
      };
      const redacted = redactSensitiveData(data);

      expect(redacted.payload).toBe("[REDACTED]");
      expect(redacted.type).toBe("command");
    });

    it("should redact private keys", () => {
      const data = {
        privateKey: "-----BEGIN PRIVATE KEY-----\n...",
        publicKey: "-----BEGIN PUBLIC KEY-----\n...",
      };
      const redacted = redactSensitiveData(data);

      expect(redacted.privateKey).toBe("[REDACTED]");
      expect(redacted.publicKey).toBe("-----BEGIN PUBLIC KEY-----\n...");
    });

    it("should redact tokens", () => {
      const data = {
        token: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
        oidcToken: "token-value",
      };
      const redacted = redactSensitiveData(data);

      expect(redacted.token).toBe("[REDACTED]");
      expect(redacted.oidcToken).toBe("[REDACTED]");
    });

    it("should handle nested objects", () => {
      const data = {
        user: {
          id: "user-789",
          email: "test@example.com",
        },
        metadata: { nested: "data" },
      };
      const redacted = redactSensitiveData(data);

      expect(redacted.user.id).toBe("user-***");
      expect(redacted.user.email).toBe("test@example.com");
      expect(redacted.metadata).toBe("[REDACTED]");
    });

    it("should handle arrays", () => {
      const data = {
        users: [{ userId: "user-1" }, { userId: "user-2" }],
      };
      const redacted = redactSensitiveData(data);

      expect(redacted.users[0].userId).toBe("user-***");
      expect(redacted.users[1].userId).toBe("user-***");
    });

    it("should preserve non-sensitive data", () => {
      const data = {
        id: "conn-123",
        status: "active",
        createdAt: "2024-01-01",
        remoteUrl: "https://remote.com",
      };
      const redacted = redactSensitiveData(data);

      expect(redacted).toEqual(data);
    });

    it("should handle null/undefined", () => {
      expect(redactSensitiveData(null)).toBeNull();
      expect(redactSensitiveData(undefined)).toBeUndefined();
    });

    it("should handle primitives", () => {
      expect(redactSensitiveData("string")).toBe("string");
      expect(redactSensitiveData(123)).toBe(123);
      expect(redactSensitiveData(true)).toBe(true);
    });
  });
});
