abstractMenuBuilder.test.ts 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252
  1. import { describe, test, expect, vi, beforeEach } from 'vitest'
  2. import type { RuntimeConfig } from '@nuxt/schema'
  3. import type { AnyAbility } from '@casl/ability'
  4. import type { Router } from 'vue-router'
  5. import AbstractMenuBuilder from '~/services/layout/menuBuilder/abstractMenuBuilder'
  6. import type { IconItem, MenuGroup, MenuItem, MenuItems } from '~/types/layout'
  7. import { MENU_LINK_TYPE } from '~/types/enum/layout'
  8. import type { AccessProfile, organizationState } from '~/types/interfaces'
  9. import { LINK_TARGET } from '~/types/enum/enums'
  10. class TestableAbstractMenuBuilder extends AbstractMenuBuilder {
  11. static override readonly menuName = 'TestableMenu'
  12. public build(): MenuItem | MenuGroup | null {
  13. return { label: 'my_menu' }
  14. }
  15. public override createGroup(
  16. label: string,
  17. icon?: IconItem,
  18. children: MenuItems = [],
  19. actions: Array<MenuItem> = [],
  20. ): MenuGroup {
  21. return super.createGroup(label, icon, children, actions)
  22. }
  23. public override createItem(
  24. label: string,
  25. icon?: IconItem,
  26. to: string = '',
  27. type: MENU_LINK_TYPE = MENU_LINK_TYPE.INTERNAL,
  28. ): MenuItem {
  29. return super.createItem(label, icon, to, type)
  30. }
  31. public override buildSubmenu(menuBuilder: typeof AbstractMenuBuilder) {
  32. return super.buildSubmenu(menuBuilder)
  33. }
  34. public override makeChildren(
  35. items: Array<{ pageName: string; icon?: string }>,
  36. ) {
  37. return super.makeChildren(items)
  38. }
  39. }
  40. let runtimeConfig: RuntimeConfig
  41. let ability: AnyAbility
  42. let organizationProfile: organizationState
  43. let accessProfile: AccessProfile
  44. let menuBuilder: TestableAbstractMenuBuilder
  45. let router: Router
  46. beforeEach(() => {
  47. runtimeConfig = vi.fn() as any as RuntimeConfig
  48. ability = vi.fn() as any as AnyAbility
  49. organizationProfile = vi.fn() as any as organizationState
  50. accessProfile = vi.fn() as any as AccessProfile
  51. // @ts-ignore
  52. router = vi.fn() as Router
  53. menuBuilder = new TestableAbstractMenuBuilder(
  54. runtimeConfig,
  55. ability,
  56. organizationProfile,
  57. accessProfile,
  58. router,
  59. )
  60. })
  61. describe('getMenuName', () => {
  62. test('get name', () => {
  63. expect(menuBuilder.getMenuName()).toEqual('TestableMenu')
  64. })
  65. })
  66. describe('createGroup', () => {
  67. test('simple group', () => {
  68. const label = 'my_menu'
  69. const icon = { name: 'my_icon' }
  70. const children = [
  71. { label: 'submenu', type: MENU_LINK_TYPE.INTERNAL, active: true },
  72. ]
  73. const actions = [
  74. { label: 'action', type: MENU_LINK_TYPE.INTERNAL, active: true },
  75. ]
  76. const result = menuBuilder.createGroup(label, icon, children, actions)
  77. expect(result).toEqual({ label, icon, children, actions })
  78. })
  79. test('default values', () => {
  80. const result = menuBuilder.createGroup('my_menu')
  81. expect(result).toEqual({
  82. label: 'my_menu',
  83. icon: undefined,
  84. children: [],
  85. actions: [],
  86. })
  87. })
  88. })
  89. describe('createItem', () => {
  90. test('simple item', () => {
  91. const label = 'my_menu'
  92. const icon = { name: 'my_icon' }
  93. const to = 'https://domain.com/foo/bar'
  94. const target = LINK_TARGET.SELF
  95. const type = MENU_LINK_TYPE.EXTERNAL
  96. const result = menuBuilder.createItem(label, icon, to, type)
  97. expect(result).toEqual({
  98. icon,
  99. label,
  100. to,
  101. target,
  102. type,
  103. active: false,
  104. endOfSubsection: false,
  105. })
  106. })
  107. test('default values', () => {
  108. const result = menuBuilder.createItem('my_menu')
  109. expect(result).toEqual({
  110. label: 'my_menu',
  111. icon: undefined,
  112. to: '',
  113. target: '_self',
  114. type: MENU_LINK_TYPE.INTERNAL,
  115. active: false,
  116. endOfSubsection: false,
  117. })
  118. })
  119. test('prepend https on external url', () => {
  120. const item = menuBuilder.createItem(
  121. 'my_menu',
  122. undefined,
  123. 'domain.com',
  124. MENU_LINK_TYPE.EXTERNAL,
  125. )
  126. expect(item.to).toEqual('https://domain.com')
  127. })
  128. test('complete V1 links (server side)', () => {
  129. runtimeConfig.baseUrlAdminLegacy = 'https://admin.opentalent.fr'
  130. const item = menuBuilder.createItem(
  131. 'my_menu',
  132. undefined,
  133. '/my_page',
  134. MENU_LINK_TYPE.V1,
  135. )
  136. expect(item.to).toEqual('https://admin.opentalent.fr/#/my_page')
  137. })
  138. test('complete V1 links (client side)', () => {
  139. runtimeConfig.baseUrlAdminLegacy = ''
  140. // @ts-ignore
  141. runtimeConfig.public = { baseUrlAdminLegacy: 'https://admin.opentalent.fr' }
  142. const item = menuBuilder.createItem(
  143. 'my_menu',
  144. undefined,
  145. '/my_page',
  146. MENU_LINK_TYPE.V1,
  147. )
  148. expect(item.to).toEqual('https://admin.opentalent.fr/#/my_page')
  149. })
  150. })
  151. describe('buildSubmenu', () => {
  152. test('should call given menu build method', () => {
  153. expect(menuBuilder.buildSubmenu(TestableAbstractMenuBuilder)).toEqual({
  154. label: 'my_menu',
  155. })
  156. })
  157. })
  158. describe('makeChildren', () => {
  159. test('simple call', () => {
  160. ability.can = vi.fn(() => true)
  161. // @ts-ignore
  162. router.resolve = vi.fn(() => {
  163. return { href: 'foo' }
  164. })
  165. const children: MenuItems = menuBuilder.makeChildren([
  166. { pageName: 'foo_page', icon: 'fas fa-dog' },
  167. ])
  168. expect(children).toEqual([
  169. {
  170. label: 'foo_page',
  171. icon: { name: 'fas fa-dog' },
  172. to: 'foo',
  173. type: 0,
  174. active: false,
  175. endOfSubsection: false,
  176. },
  177. ])
  178. })
  179. test('no icon', () => {
  180. ability.can = vi.fn(() => true)
  181. // @ts-ignore
  182. router.resolve = vi.fn(() => {
  183. return { href: 'foo' }
  184. })
  185. const children: MenuItems = menuBuilder.makeChildren([
  186. { pageName: 'foo_page' },
  187. ])
  188. expect(children).toEqual([
  189. {
  190. label: 'foo_page',
  191. icon: undefined,
  192. to: 'foo',
  193. type: 0,
  194. active: false,
  195. endOfSubsection: false,
  196. },
  197. ])
  198. })
  199. test('not allowed', () => {
  200. ability.can = vi.fn(() => false)
  201. const children: MenuItems = menuBuilder.makeChildren([
  202. { pageName: 'foo_page' },
  203. ])
  204. expect(children).toEqual([])
  205. })
  206. test('unknown page name', () => {
  207. ability.can = vi.fn(() => true)
  208. // @ts-ignore
  209. router.resolve = vi.fn(() => {
  210. return null
  211. })
  212. expect(() =>
  213. menuBuilder.makeChildren([{ pageName: 'foo_page' }]),
  214. ).toThrowError()
  215. })
  216. })