import { Ability } from '@casl/ability'
import { createStore } from '~/tests/unit/Helpers'
import { AbilitiesType, AccessStore } from '~/types/interfaces'
import { $accessProfile } from '~/services/profile/accessProfile'
import { ABILITIES } from '~/types/enums'
import { accessProfile as accessModule } from '~/tests/unit/fixture/state/profile'

let ability: Ability, store: AccessStore

beforeEach(() => {
  ability = new Ability()
  store = createStore()
  store.registerModule('profile', {})
  store.registerModule(['profile', 'access'], accessModule)
  $accessProfile.setAbility(ability)
  $accessProfile.setStore(store)
})

describe('hasRole()', () => {
  it('should return true if there is no role', () => {
    expect($accessProfile.hasRole(null)).toBeTruthy()
  })

  it('should return false if profile dont have the role', () => {
    const role_to_have = ['ROLE_EVENT']
    expect($accessProfile.hasRole(role_to_have)).toBeFalsy()
  })

  it('should return true if profile have the role', () => {
    const role_to_have = ['ROLE_USERS']
    store.commit('access/setRoles', ['ROLE_USERS'])
    expect($accessProfile.hasRole(role_to_have)).toBeTruthy()
  })
})

describe('hasAbility()', () => {
  it('should return true if there is no ability', () => {
    expect($accessProfile.hasAbility(null)).toBeTruthy()
  })

  it('should return false if profile dont have the ability', () => {
    const ability_to_have:Array<AbilitiesType> = [{
      action: ABILITIES.MANAGE,
      subject: 'bills'
    }]
    expect($accessProfile.hasAbility(ability_to_have)).toBeFalsy()
  })

  it('should return true if profile dont have the ability', () => {
    const manage_bills:AbilitiesType = {
      action: ABILITIES.MANAGE,
      subject: 'bills'
    }
    const ability_to_have:Array<AbilitiesType> = [manage_bills]
    ability.update([manage_bills])
    expect($accessProfile.hasAbility(ability_to_have)).toBeTruthy()
  })
})

describe('hasProfile()', () => {
  it('should return true if there is no profile', () => {
    expect($accessProfile.hasProfile(null)).toBeTruthy()
  })

  it('should return false if user do not have the profile', () =>{
    const profile_to_have = ['admin']
    expect($accessProfile.hasProfile(profile_to_have)).toBeFalsy()
  })

  it('should return true if user have the profile', () =>{
    const profile_to_have = ['admin']
    store.commit('access/setIsAdmin', true)
    expect($accessProfile.hasProfile(profile_to_have)).toBeTruthy()
  })
})

describe('testProfile()', () => {
  it('should return false if profile do not exist', () => {
    expect($accessProfile.testProfile('none')).toBeFalsy()
  })
})
