/**
 * Copyright IBM Corp. 2024, 2025
 */
import {
  invalidTestMissingKind,
  invalidTestSchema,
  validTest,
  validTestWithIf,
} from '../__mocks__/test-data/test.data.js';
import { TestFactory } from '../../src/model-factories/test.factory.js';

describe('TestFactory.create', () => {
  const factory = new TestFactory();

  it('should parse and return a valid Test model', () => {
    const result = factory.create(validTest);
    expect(result).toBeDefined();
    expect(result.kind).toBe('test');
    expect(result.metadata!.namespace).toBe('default');
    expect(result.metadata!.name).toBe('TestPayments');
    expect(result.spec!.request).toHaveLength(2);
    expect(result.spec!.request[0].if).toBeTruthy();
    expect(result.spec!.request[0].stopOnFail).toBeFalsy();
  });

  it('should parse and return a valid Test with if', () => {
    const result = factory.create(validTestWithIf);
    expect(result).toBeDefined();
    expect(result.kind).toBe('test');
    expect(result.metadata!.namespace).toBe('default');
    expect(result.metadata!.name).toBe('TestPayments');
    expect(result.spec!.request).toHaveLength(1);
    expect(result.spec!.request[0].if).toBeDefined();
    expect(result.spec!.request[0].stopOnFail).toBeDefined();
  });

  it('should throw validation error for invalid input kind', () => {
    try {
      factory.create(invalidTestMissingKind);
    } catch (e: any) {
      expect(e).toBeInstanceOf(Error);
      expect(e.message).toContain(
        `Validation error at kind: Invalid input: expected "test"`,
      );
      expect(e.message).toContain(
        `Validation error at spec.api: Invalid input: expected object, received undefined`,
      );
      expect(e.message).toContain(
        `Validation error at spec.request: Invalid input: expected array, received undefined`,
      );
    }
  });
  it('should throw validation error for invalid input', () => {
    try {
      factory.create(invalidTestSchema);
    } catch (e: any) {
      expect(e).toBeInstanceOf(Error);
      expect(e.message).toContain(
        `Validation error at metadata.version: Invalid input: expected string, received number`,
      );
      expect(e.message).toContain(
        `Validation error at spec.api: Invalid input: expected object, received undefined`,
      );
      expect(e.message).toContain(
        `Validation error at spec.request: Invalid input: expected array, received undefined`,
      );
    }
  });

  it('should throw error if required fields are missing', () => {
    const incompleteTest = {
      kind: 'test',
      metadata: {
        // missing namespace
        name: 'Incomplete',
        version: '1.0.0',
      },
      spec: {},
    };
    expect(() => factory.create(incompleteTest)).toThrow();
  });

  it("should throw error if kind is not 'test'", () => {
    const wrongKind = {
      kind: 'assertion',
      metadata: {
        namespace: 'ns1',
        name: 'WrongKind',
        version: '1.0.0',
      },
      spec: {},
    };
    expect(() => factory.create(wrongKind)).toThrow();
  });
});
