import {
  convertStringToCaption,
  isEmptyStringOrNotDefined,
  isExternalLink,
  sanitizeString,
  searchString,
  sanitizeHtml,
  getValueByPath,
} from '@/helpers/string.helper';
import { test } from 'vitest';
import { Caption } from '@/models/caption.model';

describe('test utils helpers methods', () => {
  describe('isEmptyStringOrNotDefined', () => {
    test.each([
      ['', true],
      [null, true],
      [undefined, true],
      ['  ', false],
      [[], false],
      [[1], false],
      [{}, false],
      [1, false],
      [{ test: true }, false],
    ])(
      'should test isEmptyStringOrNotDefined and for %o should return %o',
      (value, result) => {
        expect(isEmptyStringOrNotDefined(value)).equal(result);
      },
    );
  });

  describe('isExternalLink', () => {
    test.each([
      ['', false],
      [null, false],
      [undefined, false],
      ['  ', false],
      [{ to: true }, false],
      ['https://wwww.truc.com', true],
    ])(
      'should test isExternalLink and for %o should return %o',
      (value, result) => {
        //@ts-ignore
        expect(isExternalLink(value)).equal(result);
      },
    );
  });

  describe('searchString', () => {
    test.each([
      ['', 'val', false],
      [null, 'val', false],
      [undefined, 'val', false],
      ['value', 'val', true],
      ['Value', 'val', true],
      ['vàlué', 'val', true],
      ['vàlué', 'vàl', true],
      ['value', 'toto', false],
      ['value', '', true],
      ['value', null, false],
      ['value', undefined, false],
    ])(
      'In string %o should search string %o and return %o',
      (value, searchText, result) => {
        expect(searchString(value, searchText)).equal(result);
      },
    );
  });

  describe('sanitizeString', () => {
    test.each([
      ['', ''],
      [null, ''],
      [undefined, ''],
      ['àéö', 'aeo'],
      ['A éö', 'a eo'],
    ])('for value %o should return %o', (value, result) => {
      expect(sanitizeString(value)).equal(result);
    });
  });

  describe('convertStringToCaption', () => {
    test.each([
      ['This is a string', { label: 'This is a string', mode: 'default' }],
      [{ label: 'this is a caption' }, { label: 'this is a caption' }],
    ])('for value %o should return %o', (value, result) => {
      const resultFromHelper = convertStringToCaption(value);
      expect(resultFromHelper.label).equal((result as Caption).label);
      expect(resultFromHelper.mode).equal((result as Caption).mode);
    });
  });

  describe('sanitizeHtml', () => {
    it('supprime les balises non autorisées', () => {
      const input =
        '<script>alert("malveillant");</script><p>Texte autorisé</p>';
      const output = '<p>Texte autorisé</p>';
      expect(sanitizeHtml(input)).toBe(output);
    });

    it('conserve les balises autorisées', () => {
      const input =
        '<p>Texte avec <strong>du gras</strong> et <a href="https://example.com">un lien</a>.</p>';
      const output =
        '<p>Texte avec <strong>du gras</strong> et <a href="https://example.com">un lien</a>.</p>';
      expect(sanitizeHtml(input)).toBe(output);
    });

    it('supprime les événements inline', () => {
      const input = '<span onclick="alert(\'danger\')">Texte dangereux</span>';
      const output = '<span>Texte dangereux</span>';
      expect(sanitizeHtml(input)).toBe(output);
    });

    it('supprime les styles inline', () => {
      const input = '<p style="color:red;">Texte avec style</p>';
      const output = '<p>Texte avec style</p>';
      expect(sanitizeHtml(input)).toBe(output);
    });

    it('supprime les URLs malveillantes', () => {
      const input = '<a href="javascript:alert(\'danger\')">Lien dangereux</a>';
      const output = '<a>Lien dangereux</a>';
      expect(sanitizeHtml(input)).toBe(output);
    });

    it('supprime les images avec des sources dangereuses', () => {
      const input = '<img src="javascript:alert(\'danger\')">';
      const output = '';
      expect(sanitizeHtml(input)).toBe(output);
    });

    it('gère le HTML vide', () => {
      const input = '';
      const output = '';
      expect(sanitizeHtml(input)).toBe(output);
    });

    it('gère du texte sans HTML', () => {
      const input = 'Texte brut';
      const output = 'Texte brut';
      expect(sanitizeHtml(input)).toBe(output);
    });
  });

  describe('getValueByPath', () => {
    const obj = {
      one: {
        two: {
          tree: 'vrai!',
          four: null,
        },
        empty: {},
      },
    };

    test('accès à une valeur existante', () => {
      expect(getValueByPath(obj, 'one.two.tree')).toBe('vrai!');
    });

    test('accès à une clé inexistante', () => {
      expect(getValueByPath(obj, 'one.two.fake')).toBeUndefined();
    });

    test('accès à une clé partiellement manquante', () => {
      expect(getValueByPath(obj, 'one.nothing.tree')).toBeUndefined();
    });

    test('accès à un chemin vide', () => {
      expect(getValueByPath(obj, '')).toBe(obj);
    });

    test('accès à un chemin "root"', () => {
      expect(getValueByPath(obj, '.')).toBe(obj);
    });

    test('accès à une clé avec valeur nulle', () => {
      expect(getValueByPath(obj, 'one.two.four')).toBeNull();
    });

    test('accès à un objet vide', () => {
      expect(getValueByPath(obj, 'one.empty')).toEqual({});
    });
  });
});
