import UrlBuilder from '~/services/connection/urlBuilder'
import { QUERY_TYPE } from '~/types/enums'
import User from '~/tests/unit/fixture/models/User'
import Organization from '~/tests/unit/fixture/models/Organization'
import { repositoryHelper } from '~/services/store/repository'
import {DataProviderArgs} from "~/types/interfaces";

describe('invoke()', () => {
  describe('getDefaultUrl()', () => {
    it('should throw an error if URL is missing', () => {
      expect(() => UrlBuilder.build({
        type: QUERY_TYPE.DEFAULT
      })).toThrowError('no url')
    })

    it('should return the URL concat with Root URL', () => {
      expect(UrlBuilder.build({
        type: QUERY_TYPE.DEFAULT,
        url: 'users'
      })).toEqual('users')
    })
  })

  describe('getEnumUrl()', () => {
    it('should throw an error if enumType is missing', () => {
      expect(() => UrlBuilder.build({
        type: QUERY_TYPE.ENUM
      })).toThrowError('enumType must be defined')
    })

    it('should return the Enum URL concat with Root URL', () => {
      expect(UrlBuilder.build({
        type: QUERY_TYPE.ENUM,
        enumType: 'billing_type'
      })).toEqual('/api/enum/billing_type')
    })
  })

  describe('getModelUrl()', () => {
    it('should throw an error if model is missing', () => {
      expect(() => UrlBuilder.build({
        type: QUERY_TYPE.MODEL
      })).toThrowError('model must be defined')
    })

    it('should return the Model URL concat with Root URL', () => {
      const repositoryHelperMock = repositoryHelper as jest.Mocked<typeof repositoryHelper>
      repositoryHelperMock.getEntity = jest.fn().mockReturnValue('users')

      expect(UrlBuilder.build({
        type: QUERY_TYPE.MODEL,
        model: User
      })).toEqual('/api/users')
    })

    it('should throw an error if rootModel is defined AND rootId is missing', () => {
      const repositoryHelperMock = repositoryHelper as jest.Mocked<typeof repositoryHelper>
      repositoryHelperMock.getEntity = jest.fn().mockReturnValue('users')

      expect(() => UrlBuilder.build({
        type: QUERY_TYPE.MODEL,
        model: User,
        rootModel: Organization
      })).toThrowError('Root ID must be defined')
    })

    it('should return the Root Model URL, Model Url concat with Root URL', () => {
      const repositoryHelperMock = repositoryHelper as jest.Mocked<typeof repositoryHelper>
      repositoryHelperMock.getEntity = jest.fn()
        .mockReturnValueOnce('users')
        .mockReturnValueOnce('organizations')

      expect(UrlBuilder.build({
        type: QUERY_TYPE.MODEL,
        model: User,
        rootModel: Organization,
        rootId: 1
      })).toEqual('/api/organizations/1/users')
    })

    it('should return a concatenated url from a base and a tail', () => {
      expect(UrlBuilder.concat('/api/', 'test')).toEqual('/api/test')
    })
    it('should return a concatenated url from a base and a any number of tails', () => {
      expect(UrlBuilder.concat('/api/', 'test', 'foo', 'bar')).toEqual('/api/test/foo/bar')
    })
    it('the parts of the url shall be properly joined with forward slashes', () => {
      expect(UrlBuilder.concat('/api', 'test/', '/foo')).toEqual('/api/test/foo')
    })
    it('shall return the base url if no tail is passed', () => {
      expect(UrlBuilder.concat('/api')).toEqual('/api')
    })
  })

  describe('getImageUrl()', () => {
    it('should throw an error if imgArgs is missing', () => {
      expect(() => UrlBuilder.build({
        type: QUERY_TYPE.IMAGE
      })).toThrowError('*args* is not a dataProviderArgs')
    })

    it('should return the File download URL concat with Root URL', () => {
      const args: DataProviderArgs = {
        type: QUERY_TYPE.IMAGE,
        imgArgs: {
          id: 1,
          height: 50,
          width: 50
        }
      }
      jest.useFakeTimers('modern');
      jest.setSystemTime(new Date(2020, 3, 1));
      expect(UrlBuilder.build(args)).toEqual('/api/files/1/download/50x50?1585692000000')
      jest.useRealTimers();
    })
  })

  describe('getFileUrl()', () => {
    it('should return the URL concat with Root URL and base URL', () => {
      expect(UrlBuilder.build({
        type: QUERY_TYPE.FILE,
        baseUrl: 'http://local.opentalent.fr'
      })).toEqual('http://local.opentalent.fr/api/files')
    })
  })
})
