import { FileSha256 } from '../../../../src/domain/value-objects/file-sha256.vo';
import { DomainException } from '../../../../src/shared/exceptions/domain.exception';

describe('FileSha256 Value Object', () => {
  const validSha256 = 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855';

  describe('create', () => {
    it('should create valid sha256 hash', () => {
      const sha256 = FileSha256.create(validSha256);
      expect(sha256.value).toBe(validSha256);
    });

    it('should normalize to lowercase', () => {
      const upperCase = 'E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855';
      const sha256 = FileSha256.create(upperCase);
      expect(sha256.value).toBe(validSha256);
    });

    it('should trim whitespace', () => {
      const sha256 = FileSha256.create(`  ${validSha256}  `);
      expect(sha256.value).toBe(validSha256);
    });

    it('should throw error for empty string', () => {
      expect(() => FileSha256.create('')).toThrow(DomainException);
      expect(() => FileSha256.create('  ')).toThrow(DomainException);
    });

    it('should throw error for invalid length', () => {
      const shortHash = 'e3b0c442';
      expect(() => FileSha256.create(shortHash)).toThrow(DomainException);
      expect(() => FileSha256.create(shortHash)).toThrow('FileSha256 must be 64 characters long');
    });

    it('should throw error for non-hex characters', () => {
      const invalidHash = 'g3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855';
      expect(() => FileSha256.create(invalidHash)).toThrow(DomainException);
      expect(() => FileSha256.create(invalidHash)).toThrow('FileSha256 must contain only hexadecimal characters');
    });
  });

  describe('equals', () => {
    it('should return true for same hashes', () => {
      const s1 = FileSha256.create(validSha256);
      const s2 = FileSha256.create(validSha256.toUpperCase());

      expect(s1.equals(s2)).toBe(true);
    });

    it('should return false for different hashes', () => {
      const s1 = FileSha256.create(validSha256);
      const s2 = FileSha256.create('0000000000000000000000000000000000000000000000000000000000000000');

      expect(s1.equals(s2)).toBe(false);
    });
  });

  describe('toString', () => {
    it('should return string representation', () => {
      const sha256 = FileSha256.create(validSha256);
      expect(sha256.toString()).toBe(validSha256);
    });
  });
});
