import { describe, expect, it } from 'vitest';

import { ExtensionKit } from '../extension-kit';
import { isAllowedBlockEditorLinkUri } from './Link';

describe('isAllowedBlockEditorLinkUri', () => {
  it('allows relative URLs with an alphabetic first path segment', () => {
    expect(isAllowedBlockEditorLinkUri('company/access.html')).toBeTruthy();
    expect(isAllowedBlockEditorLinkUri('a/b.html')).toBeTruthy();
  });

  it('keeps allowing existing supported URL forms', () => {
    expect(isAllowedBlockEditorLinkUri('access.html')).toBeTruthy();
    expect(isAllowedBlockEditorLinkUri('#section')).toBeTruthy();
    expect(isAllowedBlockEditorLinkUri('/company/access.html')).toBeTruthy();
    expect(isAllowedBlockEditorLinkUri('./company/access.html')).toBeTruthy();
    expect(isAllowedBlockEditorLinkUri('../company/access.html')).toBeTruthy();
    expect(isAllowedBlockEditorLinkUri('https://example.com/company/access.html')).toBeTruthy();
    expect(isAllowedBlockEditorLinkUri('mailto:info@example.com')).toBeTruthy();
    expect(isAllowedBlockEditorLinkUri('tel:+1234567890')).toBeTruthy();
  });

  it('rejects script-style and unknown protocols', () => {
    // eslint-disable-next-line no-script-url
    expect(isAllowedBlockEditorLinkUri('javascript:alert(1)')).toBeFalsy();
    expect(isAllowedBlockEditorLinkUri('data:text/html,<script>alert(1)</script>')).toBeFalsy();
    expect(isAllowedBlockEditorLinkUri('vbscript:msgbox(1)')).toBeFalsy();
    expect(isAllowedBlockEditorLinkUri('unknown-protocol://test')).toBeFalsy();
  });

  it('honours additional protocols', () => {
    expect(isAllowedBlockEditorLinkUri('custom://thing', ['custom'])).toBeTruthy();
    expect(isAllowedBlockEditorLinkUri('another-custom://thing', [{ scheme: 'another-custom' }])).toBeTruthy();
    expect(isAllowedBlockEditorLinkUri('different-custom://thing', ['custom'])).toBeFalsy();
  });

  it('is used by the block editor Link extension configuration', () => {
    const link = ExtensionKit().find((extension) => extension.name === 'link');

    expect(
      link?.options.isAllowedUri('company/access.html', {
        defaultValidate: () => false,
        protocols: [],
        defaultProtocol: 'http',
      })
    ).toBe(true);
  });
});
