abilityBuilder.test.ts 22 KB

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