abilityBuilder.test.ts 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674
  1. import { describe, test, it, expect } from 'vitest'
  2. import {MongoAbility} from "@casl/ability/dist/types/Ability";
  3. import {AbilitiesType, AccessProfile, organizationState} from "~/types/interfaces";
  4. import AbilityBuilder from "~/services/rights/abilityBuilder";
  5. import {ABILITIES} from "~/types/enum/enums";
  6. import yaml from "yaml-import";
  7. let ability: MongoAbility
  8. let accessProfile: AccessProfile
  9. let organizationProfile: organizationState
  10. let abilityBuilder: TestableAbilityBuilder
  11. class TestableAbilityBuilder extends AbilityBuilder {
  12. public execAndValidateCondition(condition: any, subject: string = '') { return super.execAndValidateCondition(condition, subject) }
  13. }
  14. // Mock the content of the config yaml files
  15. // > This must be done in the global scope: https://vitest.dev/api/vi.html#vi-mock
  16. const doc = {
  17. abilities: {
  18. 'subject1': {
  19. action: ABILITIES.READ,
  20. conditions: [
  21. {
  22. 'function': 'fct1',
  23. 'parameters': ['param1'],
  24. 'expectedResult': true
  25. }
  26. ]
  27. },
  28. 'subject2': {
  29. action: ABILITIES.READ,
  30. conditions: {
  31. 'function': 'fct2',
  32. 'parameters': ['param2'],
  33. 'expectedResult': false
  34. }
  35. }
  36. }
  37. }
  38. vi.mock('yaml-import', async () => {
  39. return {
  40. default: { read: vi.fn((data: string) => doc) }
  41. }
  42. })
  43. beforeEach(() => {
  44. ability = vi.fn() as any as MongoAbility
  45. accessProfile = vi.fn() as any as AccessProfile
  46. organizationProfile = vi.fn() as any as organizationState
  47. abilityBuilder = new TestableAbilityBuilder(ability, accessProfile, organizationProfile)
  48. })
  49. describe('buildAbilities', () => {
  50. test('base call', () => {
  51. const roleAbilities: Array<AbilitiesType> = [
  52. {action: ABILITIES.READ, subject: 'subject1'},
  53. {action: ABILITIES.READ, subject: 'subject2'}
  54. ]
  55. const configAbilities: Array<AbilitiesType> = [
  56. {action: ABILITIES.READ, subject: 'subject3'},
  57. {action: ABILITIES.READ, subject: 'subject4'}
  58. ]
  59. const allAbilities: Array<AbilitiesType> = roleAbilities.concat(configAbilities)
  60. abilityBuilder.buildAbilitiesFromRoles = vi.fn(() => roleAbilities)
  61. abilityBuilder.buildAbilitiesFromConfig = vi.fn(() => configAbilities)
  62. ability.update = vi.fn()
  63. const result = abilityBuilder.buildAbilities()
  64. expect(ability.update).toHaveBeenCalledTimes(2)
  65. expect(ability.update).toHaveBeenCalledWith(roleAbilities)
  66. expect(ability.update).toHaveBeenCalledWith(allAbilities)
  67. expect(abilityBuilder.buildAbilitiesFromRoles).toHaveBeenCalledOnce()
  68. expect(abilityBuilder.buildAbilitiesFromConfig).toHaveBeenCalledOnce()
  69. expect(result).toEqual(allAbilities)
  70. })
  71. })
  72. describe('buildAbilitiesFromRoles', () => {
  73. test('calls roleUtils', () => {
  74. accessProfile.roles = ['ROLE_EVENTS_VIEW', 'ROLE_COURSES', 'ROLE_TEACHER_CORE', 'ROLE_OTHER']
  75. const expected = [
  76. { subject: 'events', action: 'read' },
  77. { subject: 'courses', action: 'manage' },
  78. { subject: 'other', action: 'manage' },
  79. ]
  80. expect(abilityBuilder.buildAbilitiesFromRoles()).toEqual(expected)
  81. })
  82. })
  83. describe('buildAbilitiesFromConfig', () => {
  84. test('calls roleUtils', () => {
  85. abilityBuilder.hasConfigAbility = vi.fn(() => true)
  86. expect(abilityBuilder.buildAbilitiesFromConfig()).toEqual([
  87. { action: 'read', subject: 'subject1' },
  88. { action: 'read', subject: 'subject2' },
  89. ])
  90. })
  91. })
  92. describe('hasConfigAbility', () => {
  93. beforeEach(() => {
  94. accessProfile.isGuardian = true
  95. // @ts-ignore
  96. organizationProfile.isSchool = true
  97. // @ts-ignore
  98. organizationProfile.isCmf = false
  99. })
  100. test('fulfill all conditions', () => {
  101. const conditions = [
  102. {'function': 'accessHasAnyProfile', parameters: ['guardian', 'payer']},
  103. {'function': 'organizationIsSchool'},
  104. ]
  105. expect(abilityBuilder.hasConfigAbility(conditions)).toBeTruthy()
  106. })
  107. test('fulfill at least one condition', () => {
  108. const conditions = [
  109. {'function': 'accessHasAnyProfile', parameters: ['guardian', 'payer']},
  110. {'function': 'organizationIsCmf'},
  111. ]
  112. expect(abilityBuilder.hasConfigAbility(conditions)).toBeFalsy()
  113. })
  114. test('fulfill none of the conditions', () => {
  115. const conditions = [
  116. {'function': 'organizationIsCmf'},
  117. ]
  118. expect(abilityBuilder.hasConfigAbility(conditions)).toBeFalsy()
  119. })
  120. })
  121. describe('execAndValidateCondition', () => {
  122. test('accessHasAllRoleAbilities', () => {
  123. ability.can = vi.fn((action: string, subject: string) => {
  124. return action === 'read' && (subject === 'subject1' || subject === 'subject2')
  125. })
  126. expect(
  127. abilityBuilder.execAndValidateCondition(
  128. {
  129. 'function': 'accessHasAllRoleAbilities',
  130. parameters: [
  131. {action: ABILITIES.READ, subject: 'subject1'},
  132. {action: ABILITIES.READ, subject: 'subject2'},
  133. ]
  134. })
  135. ).toBeTruthy()
  136. expect(
  137. abilityBuilder.execAndValidateCondition(
  138. {
  139. 'function': 'accessHasAllRoleAbilities',
  140. parameters: [
  141. {action: ABILITIES.READ, subject: 'subject1'},
  142. {action: ABILITIES.READ, subject: 'subject3'}
  143. ]
  144. })
  145. ).toBeFalsy()
  146. })
  147. test('accessHasAnyRoleAbility', () => {
  148. ability.can = vi.fn((action: string, subject: string) => {
  149. return action === 'read' && subject === 'subject1'
  150. })
  151. expect(
  152. abilityBuilder.execAndValidateCondition(
  153. {
  154. 'function': 'accessHasAnyRoleAbility',
  155. parameters: [
  156. {action: ABILITIES.READ, subject: 'subject1'},
  157. {action: ABILITIES.READ, subject: 'subject2'},
  158. ]
  159. })
  160. ).toBeTruthy()
  161. expect(
  162. abilityBuilder.execAndValidateCondition(
  163. {'function': 'accessHasAnyRoleAbility', parameters: [{action: ABILITIES.READ, subject: 'subject2'}]})
  164. ).toBeFalsy()
  165. })
  166. test('accessHasAnyProfile', () => {
  167. accessProfile.isMember = true
  168. accessProfile.isGuardian = true
  169. accessProfile.isPayer = true
  170. expect(
  171. abilityBuilder.execAndValidateCondition(
  172. {'function': 'accessHasAnyProfile', parameters: ['guardian', 'payer']}
  173. )
  174. ).toBeTruthy()
  175. expect(
  176. abilityBuilder.execAndValidateCondition(
  177. {'function': 'accessHasAnyProfile', parameters: ['guardian', 'caMember']}
  178. )
  179. ).toBeTruthy()
  180. expect(
  181. abilityBuilder.execAndValidateCondition(
  182. {'function': 'accessHasAnyProfile', parameters: ['caMember']}
  183. )
  184. ).toBeFalsy()
  185. })
  186. test('organizationHasAllModules', () => {
  187. // @ts-ignore
  188. organizationProfile.hasModule = vi.fn(
  189. (module: string) => module === 'module1' || module === 'module2'
  190. )
  191. expect(
  192. abilityBuilder.execAndValidateCondition(
  193. {'function': 'organizationHasAllModules', parameters: ['module1', 'module2']}
  194. )
  195. ).toBeTruthy()
  196. expect(
  197. abilityBuilder.execAndValidateCondition(
  198. {'function': 'organizationHasAllModules', parameters: ['module1', 'module3']}
  199. )
  200. ).toBeFalsy()
  201. expect(
  202. abilityBuilder.execAndValidateCondition(
  203. {'function': 'organizationHasAllModules', parameters: ['module3']}
  204. )
  205. ).toBeFalsy()
  206. })
  207. test('organizationHasAnyModule', () => {
  208. // @ts-ignore
  209. organizationProfile.hasModule = vi.fn(
  210. (module: string) => module === 'module1' || module === 'module2'
  211. )
  212. expect(
  213. abilityBuilder.execAndValidateCondition(
  214. {'function': 'organizationHasAnyModule', parameters: ['module1', 'module2']}
  215. )
  216. ).toBeTruthy()
  217. expect(
  218. abilityBuilder.execAndValidateCondition(
  219. {'function': 'organizationHasAnyModule', parameters: ['module1', 'module3']}
  220. )
  221. ).toBeTruthy()
  222. expect(
  223. abilityBuilder.execAndValidateCondition(
  224. {'function': 'organizationHasAnyModule', parameters: ['module3']}
  225. )
  226. ).toBeFalsy()
  227. })
  228. test('organizationHasAnyModule', () => {
  229. // @ts-ignore
  230. accessProfile.isAdminAccount = true
  231. expect(abilityBuilder.execAndValidateCondition({'function': 'accessIsAdminAccount'})).toBeTruthy()
  232. // @ts-ignore
  233. accessProfile.isAdminAccount = false
  234. expect(abilityBuilder.execAndValidateCondition({'function': 'accessIsAdminAccount'})).toBeFalsy()
  235. })
  236. test('organizationIsSchool', () => {
  237. // @ts-ignore
  238. organizationProfile.isSchool = true
  239. expect(abilityBuilder.execAndValidateCondition({'function': 'organizationIsSchool'})).toBeTruthy()
  240. // @ts-ignore
  241. organizationProfile.isSchool = false
  242. expect(abilityBuilder.execAndValidateCondition({'function': 'organizationIsSchool'})).toBeFalsy()
  243. })
  244. test('organizationIsArtist', () => {
  245. // @ts-ignore
  246. organizationProfile.isArtist = true
  247. expect(abilityBuilder.execAndValidateCondition({'function': 'organizationIsArtist'})).toBeTruthy()
  248. // @ts-ignore
  249. organizationProfile.isArtist = false
  250. expect(abilityBuilder.execAndValidateCondition({'function': 'organizationIsArtist'})).toBeFalsy()
  251. })
  252. test('organizationIsManagerProduct', () => {
  253. // @ts-ignore
  254. organizationProfile.isManagerProduct = true
  255. expect(abilityBuilder.execAndValidateCondition({'function': 'organizationIsManagerProduct'})).toBeTruthy()
  256. // @ts-ignore
  257. organizationProfile.isManagerProduct = false
  258. expect(abilityBuilder.execAndValidateCondition({'function': 'organizationIsManagerProduct'})).toBeFalsy()
  259. })
  260. test('organizationHasChildren', () => {
  261. // @ts-ignore
  262. organizationProfile.hasChildren = true
  263. expect(abilityBuilder.execAndValidateCondition({'function': 'organizationHasChildren'})).toBeTruthy()
  264. // @ts-ignore
  265. organizationProfile.hasChildren = false
  266. expect(abilityBuilder.execAndValidateCondition({'function': 'organizationHasChildren'})).toBeFalsy()
  267. })
  268. test('organizationIsAssociation', () => {
  269. // @ts-ignore
  270. organizationProfile.isAssociation = true
  271. expect(abilityBuilder.execAndValidateCondition({'function': 'organizationIsAssociation'})).toBeTruthy()
  272. // @ts-ignore
  273. organizationProfile.isAssociation = false
  274. expect(abilityBuilder.execAndValidateCondition({'function': 'organizationIsAssociation'})).toBeFalsy()
  275. })
  276. test('organizationIsShowAdherentList', () => {
  277. // @ts-ignore
  278. organizationProfile.isShowAdherentList = true
  279. expect(abilityBuilder.execAndValidateCondition({'function': 'organizationIsShowAdherentList'})).toBeTruthy()
  280. // @ts-ignore
  281. organizationProfile.isShowAdherentList = false
  282. expect(abilityBuilder.execAndValidateCondition({'function': 'organizationIsShowAdherentList'})).toBeFalsy()
  283. })
  284. test('organizationIsCmf', () => {
  285. // @ts-ignore
  286. organizationProfile.isCmf = true
  287. expect(abilityBuilder.execAndValidateCondition({'function': 'organizationIsCmf'})).toBeTruthy()
  288. // @ts-ignore
  289. organizationProfile.isCmf = false
  290. expect(abilityBuilder.execAndValidateCondition({'function': 'organizationIsCmf'})).toBeFalsy()
  291. })
  292. test('organizationHasWebsite', () => {
  293. // @ts-ignore
  294. organizationProfile.getWebsite = true
  295. expect(abilityBuilder.execAndValidateCondition({'function': 'organizationHasWebsite'})).toBeTruthy()
  296. // @ts-ignore
  297. organizationProfile.getWebsite = false
  298. expect(abilityBuilder.execAndValidateCondition({'function': 'organizationHasWebsite'})).toBeFalsy()
  299. })
  300. test('with expected result', () => {
  301. // @ts-ignore
  302. organizationProfile.getWebsite = true
  303. expect(
  304. abilityBuilder.execAndValidateCondition({'function': 'organizationHasWebsite', expectedResult: true})
  305. ).toBeTruthy()
  306. expect(
  307. abilityBuilder.execAndValidateCondition({'function': 'organizationHasWebsite', expectedResult: 'abc'})
  308. ).toBeFalsy()
  309. })
  310. test('invalid function', () => {
  311. expect(
  312. () => abilityBuilder.execAndValidateCondition({'function': 'invalid'})
  313. ).toThrowError('unknown condition function : invalid')
  314. })
  315. })
  316. describe('hasRoleAbility', () => {
  317. beforeEach(() => {
  318. ability.can = vi.fn((action: string, subject: string) => {
  319. return action === 'read' && subject === 'a_subject'
  320. })
  321. })
  322. test('owned ability', () => {
  323. expect(abilityBuilder.hasRoleAbility({action: ABILITIES.READ, subject: 'a_subject'})).toBeTruthy()
  324. })
  325. test('not owned ability', () => {
  326. expect(abilityBuilder.hasRoleAbility({action: ABILITIES.READ, subject: 'other_subject'})).toBeFalsy()
  327. })
  328. })
  329. describe('hasAllRoleAbilities', () => {
  330. beforeEach(() => {
  331. ability.can = vi.fn((action: string, subject: string) => {
  332. return action === 'read' && (subject === 'subject1' || subject === 'subject2')
  333. })
  334. })
  335. test('own all abilities', () => {
  336. const result = abilityBuilder.hasAllRoleAbilities(
  337. [
  338. {action: ABILITIES.READ, subject: 'subject1'},
  339. {action: ABILITIES.READ, subject: 'subject2'},
  340. ]
  341. )
  342. expect(result).toBeTruthy()
  343. })
  344. test('own at least one ability', () => {
  345. const result = abilityBuilder.hasAllRoleAbilities(
  346. [
  347. {action: ABILITIES.READ, subject: 'subject1'},
  348. {action: ABILITIES.READ, subject: 'subject3'},
  349. ]
  350. )
  351. expect(result).toBeFalsy()
  352. })
  353. test('own none of the abilities', () => {
  354. const result = abilityBuilder.hasAllRoleAbilities(
  355. [
  356. {action: ABILITIES.READ, subject: 'subject3'},
  357. {action: ABILITIES.READ, subject: 'subject4'},
  358. ]
  359. )
  360. expect(result).toBeFalsy()
  361. })
  362. })
  363. describe('hasAnyRoleAbility', () => {
  364. beforeEach(() => {
  365. ability.can = vi.fn((action: string, subject: string) => {
  366. return action === 'read' && (subject === 'subject1' || subject === 'subject2')
  367. })
  368. })
  369. test('has all abilities', () => {
  370. const result = abilityBuilder.hasAnyRoleAbility(
  371. [
  372. {action: ABILITIES.READ, subject: 'subject1'},
  373. {action: ABILITIES.READ, subject: 'subject2'},
  374. ]
  375. )
  376. expect(result).toBeTruthy()
  377. })
  378. test('has at least one ability', () => {
  379. const result = abilityBuilder.hasAnyRoleAbility(
  380. [
  381. {action: ABILITIES.READ, subject: 'subject1'},
  382. {action: ABILITIES.READ, subject: 'subject3'},
  383. ]
  384. )
  385. expect(result).toBeTruthy()
  386. })
  387. test('any none of the abilites', () => {
  388. const result = abilityBuilder.hasAnyRoleAbility(
  389. [
  390. {action: ABILITIES.READ, subject: 'subject3'},
  391. {action: ABILITIES.READ, subject: 'subject4'},
  392. ]
  393. )
  394. expect(result).toBeFalsy()
  395. })
  396. })
  397. describe('hasProfile', () => {
  398. test('owned profiles', () => {
  399. accessProfile.isAdmin = true
  400. accessProfile.isAdministratifManager = true
  401. accessProfile.isPedagogicManager = true
  402. accessProfile.isFinancialManager = true
  403. accessProfile.isCaMember = true
  404. accessProfile.isStudent = true
  405. accessProfile.isTeacher = true
  406. accessProfile.isMember = true
  407. accessProfile.isOther = true
  408. accessProfile.isGuardian = true
  409. accessProfile.isPayer = true
  410. expect(abilityBuilder.hasProfile('admin')).toBeTruthy()
  411. expect(abilityBuilder.hasProfile('administratifManager')).toBeTruthy()
  412. expect(abilityBuilder.hasProfile('pedagogicManager')).toBeTruthy()
  413. expect(abilityBuilder.hasProfile('financialManager')).toBeTruthy()
  414. expect(abilityBuilder.hasProfile('caMember')).toBeTruthy()
  415. expect(abilityBuilder.hasProfile('student')).toBeTruthy()
  416. expect(abilityBuilder.hasProfile('teacher')).toBeTruthy()
  417. expect(abilityBuilder.hasProfile('member')).toBeTruthy()
  418. expect(abilityBuilder.hasProfile('other')).toBeTruthy()
  419. expect(abilityBuilder.hasProfile('guardian')).toBeTruthy()
  420. expect(abilityBuilder.hasProfile('payor')).toBeTruthy()
  421. })
  422. test('not owned profiles', () => {
  423. accessProfile.isAdmin = false
  424. accessProfile.isAdministratifManager = false
  425. accessProfile.isPedagogicManager = false
  426. accessProfile.isFinancialManager = false
  427. accessProfile.isCaMember = false
  428. accessProfile.isStudent = false
  429. accessProfile.isTeacher = false
  430. accessProfile.isMember = false
  431. accessProfile.isOther = false
  432. accessProfile.isGuardian = false
  433. accessProfile.isPayer = false
  434. expect(abilityBuilder.hasProfile('admin')).toBeFalsy()
  435. expect(abilityBuilder.hasProfile('administratifManager')).toBeFalsy()
  436. expect(abilityBuilder.hasProfile('pedagogicManager')).toBeFalsy()
  437. expect(abilityBuilder.hasProfile('financialManager')).toBeFalsy()
  438. expect(abilityBuilder.hasProfile('caMember')).toBeFalsy()
  439. expect(abilityBuilder.hasProfile('student')).toBeFalsy()
  440. expect(abilityBuilder.hasProfile('teacher')).toBeFalsy()
  441. expect(abilityBuilder.hasProfile('member')).toBeFalsy()
  442. expect(abilityBuilder.hasProfile('other')).toBeFalsy()
  443. expect(abilityBuilder.hasProfile('guardian')).toBeFalsy()
  444. expect(abilityBuilder.hasProfile('payor')).toBeFalsy()
  445. })
  446. })
  447. describe('hasAnyProfile', () => {
  448. beforeEach(() => {
  449. accessProfile.isMember = true
  450. accessProfile.isGuardian = true
  451. accessProfile.isPayer = true
  452. })
  453. test('own all profiles', () => {
  454. expect(abilityBuilder.hasAnyProfile(['member', 'guardian', 'payor'])).toBeTruthy()
  455. })
  456. test('own at least one profile', () => {
  457. expect(abilityBuilder.hasAnyProfile(['member', 'caMember'])).toBeTruthy()
  458. })
  459. test('own none of the profiles', () => {
  460. expect(abilityBuilder.hasAnyProfile(['caMember', 'isFinancialManager'])).toBeFalsy()
  461. })
  462. })
  463. describe('hasAllProfiles', () => {
  464. beforeEach(() => {
  465. accessProfile.isMember = true
  466. accessProfile.isGuardian = true
  467. accessProfile.isPayer = true
  468. })
  469. test('own all profiles', () => {
  470. expect(abilityBuilder.hasAllProfiles(['member', 'guardian', 'payor'])).toBeTruthy()
  471. })
  472. test('own only one of the profiles', () => {
  473. expect(abilityBuilder.hasAllProfiles(['member', 'caMember'])).toBeFalsy()
  474. })
  475. test('own none of the profiles', () => {
  476. expect(abilityBuilder.hasAllProfiles(['caMember', 'isFinancialManager'])).toBeFalsy()
  477. })
  478. })
  479. describe('hasRole', () => {
  480. beforeEach(() => {
  481. // @ts-ignore
  482. accessProfile.hasRole = vi.fn((role: string) => role === 'foo')
  483. })
  484. test('has role', () => {
  485. expect(abilityBuilder.hasRole('foo')).toBeTruthy()
  486. })
  487. test('has not role', () => {
  488. expect(abilityBuilder.hasRole('bar')).toBeFalsy()
  489. })
  490. })
  491. describe('hasAnyRole', () => {
  492. beforeEach(() => {
  493. // @ts-ignore
  494. accessProfile.hasRole = vi.fn((role: string) => role === 'role1' || role === 'role2')
  495. })
  496. test('own all roles', () => {
  497. expect(abilityBuilder.hasAnyRole(['role1', 'role2'])).toBeTruthy()
  498. })
  499. test('own at least one role', () => {
  500. expect(abilityBuilder.hasAnyRole(['role1', 'role3'])).toBeTruthy()
  501. })
  502. test('own none of the roles', () => {
  503. expect(abilityBuilder.hasAnyRole(['role3'])).toBeFalsy()
  504. })
  505. })
  506. describe('hasAllRoles', () => {
  507. beforeEach(() => {
  508. // @ts-ignore
  509. accessProfile.hasRole = vi.fn((role: string) => role === 'role1' || role === 'role2')
  510. })
  511. test('own all roles', () => {
  512. expect(abilityBuilder.hasAllRoles(['role1', 'role2'])).toBeTruthy()
  513. })
  514. test('own at least one role', () => {
  515. expect(abilityBuilder.hasAllRoles(['role1', 'role3'])).toBeFalsy()
  516. })
  517. test('own none of the roles', () => {
  518. expect(abilityBuilder.hasAllRoles(['role3'])).toBeFalsy()
  519. })
  520. })
  521. describe('hasModule', () => {
  522. beforeEach(() => {
  523. // @ts-ignore
  524. organizationProfile.hasModule = vi.fn((module: string) => module === 'foo')
  525. })
  526. test('has module', () => {
  527. expect(abilityBuilder.hasModule('foo')).toBeTruthy()
  528. })
  529. test('has not module', () => {
  530. expect(abilityBuilder.hasModule('bar')).toBeFalsy()
  531. })
  532. })
  533. describe('hasAnyModule', () => {
  534. beforeEach(() => {
  535. // @ts-ignore
  536. organizationProfile.hasModule = vi.fn((Module: string) => Module === 'Module1' || Module === 'Module2')
  537. })
  538. test('own all modules', () => {
  539. expect(abilityBuilder.hasAnyModule(['Module1', 'Module2'])).toBeTruthy()
  540. })
  541. test('own at least one module', () => {
  542. expect(abilityBuilder.hasAnyModule(['Module1', 'Module3'])).toBeTruthy()
  543. })
  544. test('own none of the modules', () => {
  545. expect(abilityBuilder.hasAnyModule(['Module3'])).toBeFalsy()
  546. })
  547. })
  548. describe('hasAllModules', () => {
  549. beforeEach(() => {
  550. // @ts-ignore
  551. organizationProfile.hasModule = vi.fn((Module: string) => Module === 'Module1' || Module === 'Module2')
  552. })
  553. test('own all modules', () => {
  554. expect(abilityBuilder.hasAllModules(['Module1', 'Module2'])).toBeTruthy()
  555. })
  556. test('own at least one module', () => {
  557. expect(abilityBuilder.hasAllModules(['Module1', 'Module3'])).toBeFalsy()
  558. })
  559. test('own none of the modules', () => {
  560. expect(abilityBuilder.hasAllModules(['Module3'])).toBeFalsy()
  561. })
  562. })