import { describe, expect, test, vi, beforeEach } from 'vitest'
import SubdomainValidation from '~/services/validation/subdomainValidation'
import ApiRequestService from '~/services/data/apiRequestService'
import type { AssociativeArray } from '~/types/data'

let subdomainValidation: SubdomainValidation
let apiRequestService: ApiRequestService

beforeEach(() => {
  // @ts-ignore
  apiRequestService = vi.fn() as ApiRequestService

  subdomainValidation = new SubdomainValidation(apiRequestService)
})

describe('isValid', () => {
  test('simple cases', () => {
    expect(SubdomainValidation.isValid('abcd')).toBeTruthy()
    expect(SubdomainValidation.isValid('abc-def')).toBeTruthy()
    expect(SubdomainValidation.isValid('abc-123')).toBeTruthy()
    expect(
      SubdomainValidation.isValid('abcdefghijklmnopqrstuvwxyz0123456789'),
    ).toBeTruthy()

    expect(
      SubdomainValidation.isValid(
        '0123456789-0123456789-0123456789-0123456789-0123456789-0123456789-0123456789',
      ),
    ).toBeFalsy() // Too long
    expect(SubdomainValidation.isValid('a')).toBeFalsy()
    expect(SubdomainValidation.isValid('abc_def')).toBeFalsy()
    expect(SubdomainValidation.isValid('abc%')).toBeFalsy()
    expect(SubdomainValidation.isValid('ab/')).toBeFalsy()
    expect(SubdomainValidation.isValid('ab cd')).toBeFalsy()
    expect(SubdomainValidation.isValid('-abcd')).toBeFalsy()
    expect(SubdomainValidation.isValid('abcd-')).toBeFalsy()
  })
})

describe('isAvailable', () => {
  test('is available', async () => {
    apiRequestService.get = vi.fn(
      async (url: string, query: AssociativeArray) => {
        if (
          url !== '/api/subdomains/is_available' ||
          !Object.prototype.hasOwnProperty.call(query, 'subdomain') ||
          query.subdomain !== 'abc'
        ) {
          throw new Error('Invalid arguments')
        }
        // @ts-ignore
        return { available: true } as Response
      },
    )

    expect(await subdomainValidation.isAvailable('abc')).toBeTruthy()
  })
  test('is not available', async () => {
    apiRequestService.get = vi.fn(
      async (url: string, query: AssociativeArray) => {
        if (
          url !== '/api/subdomains/is_available' ||
          !Object.prototype.hasOwnProperty.call(query, 'subdomain') ||
          query.subdomain !== 'abc'
        ) {
          throw new Error('Invalid arguments')
        }
        // @ts-ignore
        return { available: false } as Response
      },
    )

    expect(await subdomainValidation.isAvailable('abc')).toBeFalsy()
  })
})
