abstractMenuBuilder.test.ts 6.0 KB

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