/**
 * Copyright IBM Corp. 2024, 2025
 */
import { EnvironmentFactory } from '../../src/model-factories/environment.factory.js';
import {
  incompleteTestSuite,
  invalidKindTestSuite,
  invalidMetadataTestSuite,
  validEnvironmentData,
} from '../__mocks__/test-data/environment.data.js';

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

  it('should parse and return a valid TestSuite model', () => {
    const result = factory.create(validEnvironmentData);
    expect(result).toBeDefined();
    expect(result.kind).toBe(validEnvironmentData.kind);
    expect(result.metadata!.namespace).toBe(
      validEnvironmentData.metadata.namespace,
    );
    expect(result.metadata!.name).toBe(validEnvironmentData.metadata.name);
    expect(result.spec!.variables).toHaveLength(
      validEnvironmentData.spec.variables.length,
    );
  });

  it('should throw validation error for invalid input', () => {
    try {
      factory.create(invalidKindTestSuite);
    } catch (e: any) {
      expect(e).toBeInstanceOf(Error);
      expect(e.message).toContain(
        `Validation error at kind: Invalid input: expected \"environment\"`,
      );
      expect(e.message).toContain(
        `Validation error at spec.variables: Invalid input: expected array, received undefined`,
      );
    }
  });

  it('should throw validation error for invalid input', () => {
    try {
      factory.create(invalidMetadataTestSuite);
    } catch (e: any) {
      expect(e).toBeInstanceOf(Error);
      expect(e.message).toContain(
        `Validation error at kind: Invalid input: expected \"environment\"`,
      );
      expect(e.message).toContain(
        `Validation error at metadata.namespace: Invalid input: expected string, received number`,
      );
      expect(e.message).toContain(
        `Validation error at spec.variables: Invalid input: expected array, received undefined`,
      );
    }
  });

  it('should throw error if required fields are missing', () => {
    expect(() => factory.create(incompleteTestSuite)).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();
  });
});
