abilityBuilder.test.ts 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820
  1. import { describe, test, expect, vi, beforeEach } from 'vitest'
  2. import type { MongoAbility } from '@casl/ability/dist/types/Ability'
  3. import type {
  4. AbilitiesType,
  5. AccessProfile,
  6. organizationState,
  7. } from '~/types/interfaces'
  8. import AbilityBuilder from '~/services/rights/abilityBuilder'
  9. import { ABILITIES } from '~/types/enum/enums'
  10. let ability: MongoAbility
  11. let accessProfile: AccessProfile
  12. let organizationProfile: organizationState
  13. let abilityBuilder: AbilityBuilder
  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', () => {
  39. return {
  40. 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 AbilityBuilder(
  48. ability,
  49. accessProfile,
  50. organizationProfile,
  51. )
  52. })
  53. describe('buildAbilities', () => {
  54. test('base call', () => {
  55. const roleAbilities: Array<AbilitiesType> = [
  56. { action: ABILITIES.READ, subject: 'subject1' },
  57. { action: ABILITIES.READ, subject: 'subject2' },
  58. ]
  59. const configAbilities: Array<AbilitiesType> = [
  60. { action: ABILITIES.READ, subject: 'subject3' },
  61. { action: ABILITIES.READ, subject: 'subject4' },
  62. ]
  63. const allAbilities: Array<AbilitiesType> =
  64. roleAbilities.concat(configAbilities)
  65. abilityBuilder.buildAbilitiesFromRoles = vi.fn(() => roleAbilities)
  66. abilityBuilder.buildAbilitiesFromConfig = vi.fn(() => configAbilities)
  67. ability.update = vi.fn()
  68. const result = abilityBuilder.buildAbilities()
  69. expect(ability.update).toHaveBeenCalledTimes(2)
  70. expect(ability.update).toHaveBeenCalledWith(roleAbilities)
  71. expect(ability.update).toHaveBeenCalledWith(allAbilities)
  72. expect(abilityBuilder.buildAbilitiesFromRoles).toHaveBeenCalledOnce()
  73. expect(abilityBuilder.buildAbilitiesFromConfig).toHaveBeenCalledOnce()
  74. expect(result).toEqual(allAbilities)
  75. })
  76. })
  77. describe('buildAbilitiesFromRoles', () => {
  78. test('calls roleUtils', () => {
  79. accessProfile.roles = [
  80. 'ROLE_EVENTS_VIEW',
  81. 'ROLE_COURSES',
  82. 'ROLE_TEACHER_CORE',
  83. 'ROLE_OTHER',
  84. ]
  85. const expected = [
  86. { subject: 'events', action: 'read' },
  87. { subject: 'courses', action: 'manage' },
  88. { subject: 'other', action: 'manage' },
  89. ]
  90. expect(abilityBuilder.buildAbilitiesFromRoles()).toEqual(expected)
  91. })
  92. })
  93. describe('buildAbilitiesFromConfig', () => {
  94. test('calls roleUtils', () => {
  95. abilityBuilder.hasConfigAbility = vi.fn(() => true)
  96. expect(abilityBuilder.buildAbilitiesFromConfig()).toEqual([
  97. { action: 'read', subject: 'subject1', inverted: false },
  98. { action: 'read', subject: 'subject2', inverted: false },
  99. ])
  100. })
  101. })
  102. describe('hasConfigAbility', () => {
  103. beforeEach(() => {
  104. accessProfile.isGuardian = true
  105. // @ts-ignore
  106. organizationProfile.isSchool = true
  107. // @ts-ignore
  108. organizationProfile.isCmf = false
  109. })
  110. test('fulfill all conditions', () => {
  111. const conditions = [
  112. { function: 'accessHasAnyProfile', parameters: ['guardian', 'payer'] },
  113. { function: 'organizationIsSchool' },
  114. ]
  115. expect(abilityBuilder.hasConfigAbility(conditions)).toBeTruthy()
  116. })
  117. test('fulfill at least one condition', () => {
  118. const conditions = [
  119. { function: 'accessHasAnyProfile', parameters: ['guardian', 'payer'] },
  120. { function: 'organizationIsCmf' },
  121. ]
  122. expect(abilityBuilder.hasConfigAbility(conditions)).toBeFalsy()
  123. })
  124. test('fulfill none of the conditions', () => {
  125. const conditions = [{ function: 'organizationIsCmf' }]
  126. expect(abilityBuilder.hasConfigAbility(conditions)).toBeFalsy()
  127. })
  128. })
  129. describe('execAndValidateCondition', () => {
  130. test('accessHasAllRoleAbilities', () => {
  131. ability.can = vi.fn((action: string, subject: string) => {
  132. return (
  133. action === 'read' && (subject === 'subject1' || subject === 'subject2')
  134. )
  135. })
  136. expect(
  137. // @ts-ignore
  138. abilityBuilder.execAndValidateCondition({
  139. function: 'accessHasAllRoleAbilities',
  140. parameters: [
  141. { action: ABILITIES.READ, subject: 'subject1' },
  142. { action: ABILITIES.READ, subject: 'subject2' },
  143. ],
  144. }),
  145. ).toBeTruthy()
  146. expect(
  147. // @ts-ignore
  148. abilityBuilder.execAndValidateCondition({
  149. function: 'accessHasAllRoleAbilities',
  150. parameters: [
  151. { action: ABILITIES.READ, subject: 'subject1' },
  152. { action: ABILITIES.READ, subject: 'subject3' },
  153. ],
  154. }),
  155. ).toBeFalsy()
  156. })
  157. test('accessHasAnyRoleAbility', () => {
  158. ability.can = vi.fn((action: string, subject: string) => {
  159. return action === 'read' && subject === 'subject1'
  160. })
  161. expect(
  162. // @ts-ignore
  163. abilityBuilder.execAndValidateCondition({
  164. function: 'accessHasAnyRoleAbility',
  165. parameters: [
  166. { action: ABILITIES.READ, subject: 'subject1' },
  167. { action: ABILITIES.READ, subject: 'subject2' },
  168. ],
  169. }),
  170. ).toBeTruthy()
  171. expect(
  172. // @ts-ignore
  173. abilityBuilder.execAndValidateCondition({
  174. function: 'accessHasAnyRoleAbility',
  175. parameters: [{ action: ABILITIES.READ, subject: 'subject2' }],
  176. }),
  177. ).toBeFalsy()
  178. })
  179. test('accessHasAnyProfile', () => {
  180. accessProfile.isMember = true
  181. accessProfile.isGuardian = true
  182. accessProfile.isPayer = true
  183. expect(
  184. // @ts-ignore
  185. abilityBuilder.execAndValidateCondition({
  186. function: 'accessHasAnyProfile',
  187. parameters: ['guardian', 'payer'],
  188. }),
  189. ).toBeTruthy()
  190. expect(
  191. // @ts-ignore
  192. abilityBuilder.execAndValidateCondition({
  193. function: 'accessHasAnyProfile',
  194. parameters: ['guardian', 'caMember'],
  195. }),
  196. ).toBeTruthy()
  197. expect(
  198. // @ts-ignore
  199. abilityBuilder.execAndValidateCondition({
  200. function: 'accessHasAnyProfile',
  201. parameters: ['caMember'],
  202. }),
  203. ).toBeFalsy()
  204. })
  205. test('organizationHasAllModules', () => {
  206. // @ts-ignore
  207. organizationProfile.hasModule = vi.fn(
  208. (module: string) => module === 'module1' || module === 'module2',
  209. )
  210. expect(
  211. // @ts-ignore
  212. abilityBuilder.execAndValidateCondition({
  213. function: 'organizationHasAllModules',
  214. parameters: ['module1', 'module2'],
  215. }),
  216. ).toBeTruthy()
  217. expect(
  218. // @ts-ignore
  219. abilityBuilder.execAndValidateCondition({
  220. function: 'organizationHasAllModules',
  221. parameters: ['module1', 'module3'],
  222. }),
  223. ).toBeFalsy()
  224. expect(
  225. // @ts-ignore
  226. abilityBuilder.execAndValidateCondition({
  227. function: 'organizationHasAllModules',
  228. parameters: ['module3'],
  229. }),
  230. ).toBeFalsy()
  231. })
  232. test('organizationHasAnyModule', () => {
  233. // @ts-ignore
  234. organizationProfile.hasModule = vi.fn(
  235. (module: string) => module === 'module1' || module === 'module2',
  236. )
  237. expect(
  238. // @ts-ignore
  239. abilityBuilder.execAndValidateCondition({
  240. function: 'organizationHasAnyModule',
  241. parameters: ['module1', 'module2'],
  242. }),
  243. ).toBeTruthy()
  244. expect(
  245. // @ts-ignore
  246. abilityBuilder.execAndValidateCondition({
  247. function: 'organizationHasAnyModule',
  248. parameters: ['module1', 'module3'],
  249. }),
  250. ).toBeTruthy()
  251. expect(
  252. // @ts-ignore
  253. abilityBuilder.execAndValidateCondition({
  254. function: 'organizationHasAnyModule',
  255. parameters: ['module3'],
  256. }),
  257. ).toBeFalsy()
  258. })
  259. test('organizationHasAnyModule', () => {
  260. // @ts-ignore
  261. accessProfile.isAdminAccount = true
  262. // @ts-ignore
  263. expect(
  264. abilityBuilder.execAndValidateCondition({
  265. function: 'accessIsAdminAccount',
  266. }),
  267. ).toBeTruthy()
  268. // @ts-ignore
  269. accessProfile.isAdminAccount = false
  270. // @ts-ignore
  271. expect(
  272. abilityBuilder.execAndValidateCondition({
  273. function: 'accessIsAdminAccount',
  274. }),
  275. ).toBeFalsy()
  276. })
  277. test('organizationIsSchool', () => {
  278. // @ts-ignore
  279. organizationProfile.isSchool = true
  280. // @ts-ignore
  281. expect(
  282. abilityBuilder.execAndValidateCondition({
  283. function: 'organizationIsSchool',
  284. }),
  285. ).toBeTruthy()
  286. // @ts-ignore
  287. organizationProfile.isSchool = false
  288. // @ts-ignore
  289. expect(
  290. abilityBuilder.execAndValidateCondition({
  291. function: 'organizationIsSchool',
  292. }),
  293. ).toBeFalsy()
  294. })
  295. test('organizationIsArtist', () => {
  296. // @ts-ignore
  297. organizationProfile.isArtist = true
  298. // @ts-ignore
  299. expect(
  300. abilityBuilder.execAndValidateCondition({
  301. function: 'organizationIsArtist',
  302. }),
  303. ).toBeTruthy()
  304. // @ts-ignore
  305. organizationProfile.isArtist = false
  306. // @ts-ignore
  307. expect(
  308. abilityBuilder.execAndValidateCondition({
  309. function: 'organizationIsArtist',
  310. }),
  311. ).toBeFalsy()
  312. })
  313. test('organizationIsManagerProduct', () => {
  314. // @ts-ignore
  315. organizationProfile.isManagerProduct = true
  316. // @ts-ignore
  317. expect(
  318. abilityBuilder.execAndValidateCondition({
  319. function: 'organizationIsManagerProduct',
  320. }),
  321. ).toBeTruthy()
  322. // @ts-ignore
  323. organizationProfile.isManagerProduct = false
  324. // @ts-ignore
  325. expect(
  326. abilityBuilder.execAndValidateCondition({
  327. function: 'organizationIsManagerProduct',
  328. }),
  329. ).toBeFalsy()
  330. })
  331. test('organizationHasChildren', () => {
  332. // @ts-ignore
  333. organizationProfile.hasChildren = true
  334. // @ts-ignore
  335. expect(
  336. abilityBuilder.execAndValidateCondition({
  337. function: 'organizationHasChildren',
  338. }),
  339. ).toBeTruthy()
  340. // @ts-ignore
  341. organizationProfile.hasChildren = false
  342. // @ts-ignore
  343. expect(
  344. abilityBuilder.execAndValidateCondition({
  345. function: 'organizationHasChildren',
  346. }),
  347. ).toBeFalsy()
  348. })
  349. test('organizationIsAssociation', () => {
  350. // @ts-ignore
  351. organizationProfile.isAssociation = true
  352. // @ts-ignore
  353. expect(
  354. abilityBuilder.execAndValidateCondition({
  355. function: 'organizationIsAssociation',
  356. }),
  357. ).toBeTruthy()
  358. // @ts-ignore
  359. organizationProfile.isAssociation = false
  360. // @ts-ignore
  361. expect(
  362. abilityBuilder.execAndValidateCondition({
  363. function: 'organizationIsAssociation',
  364. }),
  365. ).toBeFalsy()
  366. })
  367. test('organizationIsShowAdherentList', () => {
  368. // @ts-ignore
  369. organizationProfile.isShowAdherentList = true
  370. // @ts-ignore
  371. expect(
  372. abilityBuilder.execAndValidateCondition({
  373. function: 'organizationIsShowAdherentList',
  374. }),
  375. ).toBeTruthy()
  376. // @ts-ignore
  377. organizationProfile.isShowAdherentList = false
  378. // @ts-ignore
  379. expect(
  380. abilityBuilder.execAndValidateCondition({
  381. function: 'organizationIsShowAdherentList',
  382. }),
  383. ).toBeFalsy()
  384. })
  385. test('organizationIsCmf', () => {
  386. // @ts-ignore
  387. organizationProfile.isCmf = true
  388. // @ts-ignore
  389. expect(
  390. abilityBuilder.execAndValidateCondition({
  391. function: 'organizationIsCmf',
  392. }),
  393. ).toBeTruthy()
  394. // @ts-ignore
  395. organizationProfile.isCmf = false
  396. // @ts-ignore
  397. expect(
  398. abilityBuilder.execAndValidateCondition({
  399. function: 'organizationIsCmf',
  400. }),
  401. ).toBeFalsy()
  402. })
  403. test('organizationHasWebsite', () => {
  404. // @ts-ignore
  405. organizationProfile.getWebsite = true
  406. // @ts-ignore
  407. expect(
  408. abilityBuilder.execAndValidateCondition({
  409. function: 'organizationHasWebsite',
  410. }),
  411. ).toBeTruthy()
  412. // @ts-ignore
  413. organizationProfile.getWebsite = false
  414. // @ts-ignore
  415. expect(
  416. abilityBuilder.execAndValidateCondition({
  417. function: 'organizationHasWebsite',
  418. }),
  419. ).toBeFalsy()
  420. })
  421. test('with expected result', () => {
  422. // @ts-ignore
  423. organizationProfile.getWebsite = true
  424. expect(
  425. // @ts-ignore
  426. abilityBuilder.execAndValidateCondition({
  427. function: 'organizationHasWebsite',
  428. expectedResult: true,
  429. }),
  430. ).toBeTruthy()
  431. expect(
  432. // @ts-ignore
  433. abilityBuilder.execAndValidateCondition({
  434. function: 'organizationHasWebsite',
  435. expectedResult: 'abc',
  436. }),
  437. ).toBeFalsy()
  438. })
  439. test('invalid function', () => {
  440. expect(
  441. // @ts-ignore
  442. () => abilityBuilder.execAndValidateCondition({ function: 'invalid' }),
  443. ).toThrowError('unknown condition function : invalid')
  444. })
  445. })
  446. describe('hasRoleAbility', () => {
  447. beforeEach(() => {
  448. ability.can = vi.fn((action: string, subject: string) => {
  449. return action === 'read' && subject === 'a_subject'
  450. })
  451. })
  452. test('owned ability', () => {
  453. expect(
  454. abilityBuilder.hasRoleAbility({
  455. action: ABILITIES.READ,
  456. subject: 'a_subject',
  457. }),
  458. ).toBeTruthy()
  459. })
  460. test('not owned ability', () => {
  461. expect(
  462. abilityBuilder.hasRoleAbility({
  463. action: ABILITIES.READ,
  464. subject: 'other_subject',
  465. }),
  466. ).toBeFalsy()
  467. })
  468. })
  469. describe('hasAllRoleAbilities', () => {
  470. beforeEach(() => {
  471. ability.can = vi.fn((action: string, subject: string) => {
  472. return (
  473. action === 'read' && (subject === 'subject1' || subject === 'subject2')
  474. )
  475. })
  476. })
  477. test('own all abilities', () => {
  478. const result = abilityBuilder.hasAllRoleAbilities([
  479. { action: ABILITIES.READ, subject: 'subject1' },
  480. { action: ABILITIES.READ, subject: 'subject2' },
  481. ])
  482. expect(result).toBeTruthy()
  483. })
  484. test('own at least one ability', () => {
  485. const result = abilityBuilder.hasAllRoleAbilities([
  486. { action: ABILITIES.READ, subject: 'subject1' },
  487. { action: ABILITIES.READ, subject: 'subject3' },
  488. ])
  489. expect(result).toBeFalsy()
  490. })
  491. test('own none of the abilities', () => {
  492. const result = abilityBuilder.hasAllRoleAbilities([
  493. { action: ABILITIES.READ, subject: 'subject3' },
  494. { action: ABILITIES.READ, subject: 'subject4' },
  495. ])
  496. expect(result).toBeFalsy()
  497. })
  498. })
  499. describe('hasAnyRoleAbility', () => {
  500. beforeEach(() => {
  501. ability.can = vi.fn((action: string, subject: string) => {
  502. return (
  503. action === 'read' && (subject === 'subject1' || subject === 'subject2')
  504. )
  505. })
  506. })
  507. test('has all abilities', () => {
  508. const result = abilityBuilder.hasAnyRoleAbility([
  509. { action: ABILITIES.READ, subject: 'subject1' },
  510. { action: ABILITIES.READ, subject: 'subject2' },
  511. ])
  512. expect(result).toBeTruthy()
  513. })
  514. test('has at least one ability', () => {
  515. const result = abilityBuilder.hasAnyRoleAbility([
  516. { action: ABILITIES.READ, subject: 'subject1' },
  517. { action: ABILITIES.READ, subject: 'subject3' },
  518. ])
  519. expect(result).toBeTruthy()
  520. })
  521. test('any none of the abilites', () => {
  522. const result = abilityBuilder.hasAnyRoleAbility([
  523. { action: ABILITIES.READ, subject: 'subject3' },
  524. { action: ABILITIES.READ, subject: 'subject4' },
  525. ])
  526. expect(result).toBeFalsy()
  527. })
  528. })
  529. describe('hasProfile', () => {
  530. test('owned profiles', () => {
  531. accessProfile.isAdmin = true
  532. accessProfile.isAdministratifManager = true
  533. accessProfile.isPedagogicManager = true
  534. accessProfile.isFinancialManager = true
  535. accessProfile.isCaMember = true
  536. accessProfile.isStudent = true
  537. accessProfile.isTeacher = true
  538. accessProfile.isMember = true
  539. accessProfile.isOther = true
  540. accessProfile.isGuardian = true
  541. accessProfile.isPayer = true
  542. expect(abilityBuilder.hasProfile('admin')).toBeTruthy()
  543. expect(abilityBuilder.hasProfile('administratifManager')).toBeTruthy()
  544. expect(abilityBuilder.hasProfile('pedagogicManager')).toBeTruthy()
  545. expect(abilityBuilder.hasProfile('financialManager')).toBeTruthy()
  546. expect(abilityBuilder.hasProfile('caMember')).toBeTruthy()
  547. expect(abilityBuilder.hasProfile('student')).toBeTruthy()
  548. expect(abilityBuilder.hasProfile('teacher')).toBeTruthy()
  549. expect(abilityBuilder.hasProfile('member')).toBeTruthy()
  550. expect(abilityBuilder.hasProfile('other')).toBeTruthy()
  551. expect(abilityBuilder.hasProfile('guardian')).toBeTruthy()
  552. expect(abilityBuilder.hasProfile('payor')).toBeTruthy()
  553. })
  554. test('not owned profiles', () => {
  555. accessProfile.isAdmin = false
  556. accessProfile.isAdministratifManager = false
  557. accessProfile.isPedagogicManager = false
  558. accessProfile.isFinancialManager = false
  559. accessProfile.isCaMember = false
  560. accessProfile.isStudent = false
  561. accessProfile.isTeacher = false
  562. accessProfile.isMember = false
  563. accessProfile.isOther = false
  564. accessProfile.isGuardian = false
  565. accessProfile.isPayer = false
  566. expect(abilityBuilder.hasProfile('admin')).toBeFalsy()
  567. expect(abilityBuilder.hasProfile('administratifManager')).toBeFalsy()
  568. expect(abilityBuilder.hasProfile('pedagogicManager')).toBeFalsy()
  569. expect(abilityBuilder.hasProfile('financialManager')).toBeFalsy()
  570. expect(abilityBuilder.hasProfile('caMember')).toBeFalsy()
  571. expect(abilityBuilder.hasProfile('student')).toBeFalsy()
  572. expect(abilityBuilder.hasProfile('teacher')).toBeFalsy()
  573. expect(abilityBuilder.hasProfile('member')).toBeFalsy()
  574. expect(abilityBuilder.hasProfile('other')).toBeFalsy()
  575. expect(abilityBuilder.hasProfile('guardian')).toBeFalsy()
  576. expect(abilityBuilder.hasProfile('payor')).toBeFalsy()
  577. })
  578. })
  579. describe('hasAnyProfile', () => {
  580. beforeEach(() => {
  581. accessProfile.isMember = true
  582. accessProfile.isGuardian = true
  583. accessProfile.isPayer = true
  584. })
  585. test('own all profiles', () => {
  586. expect(
  587. abilityBuilder.hasAnyProfile(['member', 'guardian', 'payor']),
  588. ).toBeTruthy()
  589. })
  590. test('own at least one profile', () => {
  591. expect(abilityBuilder.hasAnyProfile(['member', 'caMember'])).toBeTruthy()
  592. })
  593. test('own none of the profiles', () => {
  594. expect(
  595. abilityBuilder.hasAnyProfile(['caMember', 'isFinancialManager']),
  596. ).toBeFalsy()
  597. })
  598. })
  599. describe('hasAllProfiles', () => {
  600. beforeEach(() => {
  601. accessProfile.isMember = true
  602. accessProfile.isGuardian = true
  603. accessProfile.isPayer = true
  604. })
  605. test('own all profiles', () => {
  606. expect(
  607. abilityBuilder.hasAllProfiles(['member', 'guardian', 'payor']),
  608. ).toBeTruthy()
  609. })
  610. test('own only one of the profiles', () => {
  611. expect(abilityBuilder.hasAllProfiles(['member', 'caMember'])).toBeFalsy()
  612. })
  613. test('own none of the profiles', () => {
  614. expect(
  615. abilityBuilder.hasAllProfiles(['caMember', 'isFinancialManager']),
  616. ).toBeFalsy()
  617. })
  618. })
  619. describe('hasRole', () => {
  620. beforeEach(() => {
  621. // @ts-ignore
  622. accessProfile.hasRole = vi.fn((role: string) => role === 'foo')
  623. })
  624. test('has role', () => {
  625. expect(abilityBuilder.hasRole('foo')).toBeTruthy()
  626. })
  627. test('has not role', () => {
  628. expect(abilityBuilder.hasRole('bar')).toBeFalsy()
  629. })
  630. })
  631. describe('hasAnyRole', () => {
  632. beforeEach(() => {
  633. // @ts-ignore
  634. accessProfile.hasRole = vi.fn(
  635. (role: string) => role === 'role1' || role === 'role2',
  636. )
  637. })
  638. test('own all roles', () => {
  639. expect(abilityBuilder.hasAnyRole(['role1', 'role2'])).toBeTruthy()
  640. })
  641. test('own at least one role', () => {
  642. expect(abilityBuilder.hasAnyRole(['role1', 'role3'])).toBeTruthy()
  643. })
  644. test('own none of the roles', () => {
  645. expect(abilityBuilder.hasAnyRole(['role3'])).toBeFalsy()
  646. })
  647. })
  648. describe('hasAllRoles', () => {
  649. beforeEach(() => {
  650. // @ts-ignore
  651. accessProfile.hasRole = vi.fn(
  652. (role: string) => role === 'role1' || role === 'role2',
  653. )
  654. })
  655. test('own all roles', () => {
  656. expect(abilityBuilder.hasAllRoles(['role1', 'role2'])).toBeTruthy()
  657. })
  658. test('own at least one role', () => {
  659. expect(abilityBuilder.hasAllRoles(['role1', 'role3'])).toBeFalsy()
  660. })
  661. test('own none of the roles', () => {
  662. expect(abilityBuilder.hasAllRoles(['role3'])).toBeFalsy()
  663. })
  664. })
  665. describe('hasModule', () => {
  666. beforeEach(() => {
  667. // @ts-ignore
  668. organizationProfile.hasModule = vi.fn((module: string) => module === 'foo')
  669. })
  670. test('has module', () => {
  671. expect(abilityBuilder.hasModule('foo')).toBeTruthy()
  672. })
  673. test('has not module', () => {
  674. expect(abilityBuilder.hasModule('bar')).toBeFalsy()
  675. })
  676. })
  677. describe('hasAnyModule', () => {
  678. beforeEach(() => {
  679. // @ts-ignore
  680. organizationProfile.hasModule = vi.fn(
  681. (Module: string) => Module === 'Module1' || Module === 'Module2',
  682. )
  683. })
  684. test('own all modules', () => {
  685. expect(abilityBuilder.hasAnyModule(['Module1', 'Module2'])).toBeTruthy()
  686. })
  687. test('own at least one module', () => {
  688. expect(abilityBuilder.hasAnyModule(['Module1', 'Module3'])).toBeTruthy()
  689. })
  690. test('own none of the modules', () => {
  691. expect(abilityBuilder.hasAnyModule(['Module3'])).toBeFalsy()
  692. })
  693. })
  694. describe('hasAllModules', () => {
  695. beforeEach(() => {
  696. // @ts-ignore
  697. organizationProfile.hasModule = vi.fn(
  698. (Module: string) => Module === 'Module1' || Module === 'Module2',
  699. )
  700. })
  701. test('own all modules', () => {
  702. expect(abilityBuilder.hasAllModules(['Module1', 'Module2'])).toBeTruthy()
  703. })
  704. test('own at least one module', () => {
  705. expect(abilityBuilder.hasAllModules(['Module1', 'Module3'])).toBeFalsy()
  706. })
  707. test('own none of the modules', () => {
  708. expect(abilityBuilder.hasAllModules(['Module3'])).toBeFalsy()
  709. })
  710. })