import { createAppLocalVue } from '@/../tests/utils' // should be the first to implement default mocks
import App from '@/app/App.vue'
import mockLoginForm from '../landing/components/LoginForm'
import mockResetPassword from '../landing/components/OTPResetPassword'
import { shallowMount, mount } from '@vue/test-utils'
import SecurityConfig from '@/config/security'
import { loggedInStore, loggedOutStore } from '../../../../tests/factories/auth-store'
import flushPromises from 'flush-promises'
import { store as appStore } from '@/store'
import { LOGIN_URL, LOGOUT_URL, RESET_PASSWORD_URL } from '@/config/defaults'

describe('Login - Routing', () => {
  let store
  let localVue
  let router

  beforeEach(async () => {
    router = await require('@/router').default

    SecurityConfig.router = router

    localVue = createAppLocalVue()
    let state = {
      resetPasswordStatus: false,
    }
    jest.resetModules()
    jest.clearAllMocks()
    store = loggedOutStore(appStore)

    await flushPromises()
  })

  it('Should not render component when logged in', async () => {
    store = loggedInStore(appStore)

    const wrapper = shallowMount(App, {
      localVue,
      router,
      store: store,
    })

    router.push(LOGIN_URL).catch(() => {})

    await flushPromises()

    expect(wrapper.vm.$route.path).not.toMatch(LOGIN_URL)
  })

  let urls = [
    { name: 'Login', path: LOGIN_URL },
    { name: 'ForgotPassword', path: LOGIN_URL + '/forgot' },
    { name: 'PreferredContact', path: LOGIN_URL + '/contact' },
    { name: 'ChangePassword', path: LOGIN_URL + '/change-password' },
    { name: 'OTPResetPassword', path: LOGIN_URL + '/otp-reset' },
  ]

  urls.forEach(url => {
    it('Should render ' + url.name + ' when not logged in', async () => {
      const wrapper = shallowMount(App, {
        localVue,
        router,
        store: store,
      })

      router.push(url.path)

      await flushPromises()

      expect(wrapper.vm.$route.path).toMatch(url.path)

      expect(wrapper.isVueInstance()).toBeTruthy()
    })
  })

  it('Should render reset password when user id exists', async () => {
    jest.mock('../landing/components/LoginForm', () => {
      mockLoginForm.mounted = () => {}
      mockLoginForm.created = () => {}
      return mockLoginForm
    })

    jest.mock('../landing/components/OTPResetPassword', () => {
      mockResetPassword.mounted = () => {}
      mockResetPassword.methods.setResetResponseData = jest.fn()
      return mockResetPassword
    })

    const wrapper = mount(App, {
      localVue,
      router,
      store: store,
      sync: false,
      stubs: {
        ChangePassword: `<div/>`,
      },
    })

    router.push(RESET_PASSWORD_URL + '/12313')

    await flushPromises()

    let resetPassword = wrapper.find(mockResetPassword)
    expect(resetPassword.exists()).toBe(true)
    expect(resetPassword.props('userId')).toBe('12313')
    expect(mockResetPassword.methods.setResetResponseData).toHaveBeenCalled()
  })
})
