import { describe, test, it, expect } from 'vitest'
import RoleUtils from "~/services/rights/roleUtils";

describe('isA', () => {
    test('has role', () => {
        const roles = ['ROLE_PEDAGOGICS_MANAGER', 'ROLE_TEACHER_CORE', 'ROLE_OTHER']
        expect(RoleUtils.isA('teacher', roles)).toBeTruthy()
    })
    test('has not role', () => {
        const roles = ['ROLE_PEDAGOGICS_MANAGER', 'ROLE_TEACHER_CORE', 'ROLE_OTHER']
        expect(RoleUtils.isA('financial_manager', roles)).toBeFalsy()
    })
    test('invalid profile name', () => {
        expect(() => RoleUtils.isA('profile-123', [])).toThrowError('invalid role name')
    })
    test('unknown profile name', () => {
        const roles = ['ROLE_PEDAGOGICS_MANAGER', 'ROLE_TEACHER_CORE', 'ROLE_OTHER']
        expect(RoleUtils.isA('unknown', roles)).toBeFalsy()
    })
})

describe('filterFunctionRoles', () => {
    test('exclude roles', () => {
        const roles = ['ROLE_EVENTS', 'ROLE_COURSES', 'ROLE_TEACHER_CORE', 'ROLE_OTHER']
        expect(RoleUtils.filterFunctionRoles(roles)).toEqual(['ROLE_EVENTS', 'ROLE_COURSES'])
    })
});

describe('parseRole', () => {
    test('simple call', () => {
        expect(RoleUtils.parseRole('ROLE_MYSUBJECT_VIEW')).toEqual({ subject: 'MYSUBJECT', action: 'VIEW' })
        expect(RoleUtils.parseRole('ROLE_MYSUBJECT_CORE')).toEqual({ subject: 'MYSUBJECT', action: 'CORE' })
        expect(RoleUtils.parseRole('ROLE_MYSUBJECT_REFERENCE')).toEqual({ subject: 'MYSUBJECT', action: 'REFERENCE' })
        expect(RoleUtils.parseRole('ROLE_MYSUBJECT')).toEqual({ subject: 'MYSUBJECT', action: '' })
    })

    test('multi-word subject', () => {
        expect(RoleUtils.parseRole('ROLE_MY_SUBJECT_VIEW')).toEqual({ subject: 'MY-SUBJECT', action: 'VIEW' })
        expect(RoleUtils.parseRole('ROLE_MY_OTHER_SUBJECT')).toEqual({ subject: 'MY-OTHER-SUBJECT', action: '' })
    })

    test('invalid input', () => {
        expect(() => RoleUtils.parseRole('INVALID')).toThrowError('can not parse role')
    })
})

describe('roleToString', () => {
    test('simple calls', () => {
        expect(RoleUtils.roleToString({ subject: 'MYSUBJECT', action: '' })).toEqual('ROLE_MYSUBJECT')
        expect(RoleUtils.roleToString({ subject: 'MYSUBJECT', action: 'VIEW' })).toEqual('ROLE_MYSUBJECT_VIEW')
        expect(RoleUtils.roleToString({ subject: 'MY_SUBJECT', action: '' })).toEqual('ROLE_MY_SUBJECT')
        expect(RoleUtils.roleToString({ subject: 'MY_SUBJECT', action: 'VIEW' })).toEqual('ROLE_MY_SUBJECT_VIEW')
        expect(RoleUtils.roleToString({ subject: 'MY-SUBJECT', action: 'VIEW' })).toEqual('ROLE_MY-SUBJECT_VIEW')
        expect(RoleUtils.roleToString({ subject: 'MY-SUBJECT', action: 'VIEW' })).toEqual('ROLE_MY-SUBJECT_VIEW')
        expect(RoleUtils.roleToString({ subject: 'MY_OTHER-SUBJECT', action: '' })).toEqual('ROLE_MY_OTHER-SUBJECT')
        expect(RoleUtils.roleToString({ subject: 'MY_OTHER-SUBJECT', action: 'VIEW' })).toEqual('ROLE_MY_OTHER-SUBJECT_VIEW')
    })
})

describe('roleToAbility', () => {
  test('simple calls', () => {
      expect(RoleUtils.roleToAbility({ subject: 'MYSUBJECT', action: '' })).toEqual({ action: 'manage', subject: 'mysubject'})
      expect(RoleUtils.roleToAbility({ subject: 'MYSUBJECT', action: 'VIEW' })).toEqual({ action: 'read', subject: 'mysubject'})
      expect(RoleUtils.roleToAbility({ subject: 'MY-SUBJECT', action: '' })).toEqual({ action: 'manage', subject: 'my-subject'})
      expect(RoleUtils.roleToAbility({ subject: 'MY-SUBJECT', action: 'REFERENCE' })).toEqual(null)
      expect(RoleUtils.roleToAbility({ subject: 'MY-SUBJECT', action: 'CORE' })).toEqual(null)
  })
})

describe('rolesToAbilities', () => {
    test('exclude roles', () => {
        const roles = ['ROLE_EVENTS_VIEW', 'ROLE_COURSES', 'ROLE_TEACHER_CORE', 'ROLE_OTHER']
        const expected = [
            { subject: 'events', action: 'read' },
            { subject: 'courses', action: 'manage' },
            { subject: 'other', action: 'manage' },
        ]

        expect(RoleUtils.rolesToAbilities(roles)).toEqual(expected)
    })
})
