searching.spec.ts 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
  1. // Copyright (C) 2012-2024 Zammad Foundation, https://zammad-foundation.org/
  2. import {
  3. getGraphQLMockCalls,
  4. mockGraphQLResult,
  5. } from '#tests/graphql/builders/mocks.ts'
  6. import { getTestRouter } from '#tests/support/components/renderComponent.ts'
  7. import { visitView } from '#tests/support/components/visitView.ts'
  8. import { setupView } from '#tests/support/mock-user.ts'
  9. import type { SearchQuery } from '#shared/graphql/types.ts'
  10. import { convertToGraphQLId } from '#shared/graphql/utils.ts'
  11. import { SearchDocument } from '../graphql/queries/searchOverview.api.ts'
  12. describe('visiting search page', () => {
  13. beforeEach(() => {
  14. setupView('agent')
  15. })
  16. it('doesnt search if no type is selected', async () => {
  17. const view = await visitView('/search', { mockApollo: false })
  18. const searchInput = view.getByPlaceholderText('Search…')
  19. await view.events.type(searchInput, 'search')
  20. expect(getGraphQLMockCalls(SearchDocument)).toHaveLength(0)
  21. })
  22. it('allows searching', async () => {
  23. const view = await visitView('/search', { mockApollo: false })
  24. const mocker = mockGraphQLResult<SearchQuery>(SearchDocument, {
  25. search: [],
  26. })
  27. const searchInput = view.getByPlaceholderText('Search…')
  28. expect(searchInput).toHaveFocus()
  29. // don't show until query is entered
  30. expect(view.queryByTestId('selectTypesSection')).not.toBeInTheDocument()
  31. await view.events.type(searchInput, 'search')
  32. // show types when query is entered
  33. expect(view.getByTestId('selectTypesSection')).toBeInTheDocument()
  34. await view.events.click(view.getByText('Users with "search"'))
  35. // focus shifted to tab with the same type
  36. expect(view.getByRole('tab', { name: 'Users' })).toHaveFocus()
  37. const mockCalls = await mocker.waitForCalls()
  38. expect(mockCalls).toHaveLength(1)
  39. expect(mockCalls[0].variables).toEqual({
  40. onlyIn: 'User',
  41. search: 'search',
  42. limit: 30,
  43. })
  44. expect(view.container).toHaveTextContent('No entries')
  45. await view.events.click(view.getByText('Organizations'))
  46. expect(mockCalls).toHaveLength(2)
  47. expect(mockCalls[1].variables).toEqual({
  48. onlyIn: 'Organization',
  49. search: 'search',
  50. limit: 30,
  51. })
  52. expect(view.getByRole('tab', { name: 'Organizations' })).toHaveFocus()
  53. })
  54. it('renders correctly if queries are passed down', async () => {
  55. const view = await visitView('/search/invalid?search=search', {
  56. mockApollo: false,
  57. })
  58. expect(view.getByPlaceholderText('Search…')).toHaveDisplayValue('search')
  59. expect(view.getByTestId('selectTypesSection')).toBeInTheDocument()
  60. })
  61. it('opens with type, if there is only single type', async () => {
  62. // customer can only search for tickets
  63. setupView('customer')
  64. await visitView('/search', { mockApollo: false })
  65. expect(getTestRouter().currentRoute.value.fullPath).toBe('/search/ticket')
  66. })
  67. })
  68. describe('avatars', () => {
  69. it('renders user as inactive', async () => {
  70. setupView('agent')
  71. mockGraphQLResult<SearchQuery>(SearchDocument, {
  72. search: [
  73. {
  74. __typename: 'User',
  75. id: convertToGraphQLId('User', 100),
  76. internalId: 100,
  77. updatedAt: new Date().toISOString(),
  78. active: false,
  79. vip: true,
  80. firstname: 'Max',
  81. lastname: 'Mustermann',
  82. },
  83. {
  84. __typename: 'User',
  85. id: convertToGraphQLId('User', 200),
  86. internalId: 200,
  87. updatedAt: new Date().toISOString(),
  88. outOfOffice: true,
  89. active: true,
  90. vip: false,
  91. image: 'jon.png',
  92. firstname: 'Jon',
  93. lastname: 'Doe',
  94. },
  95. ],
  96. })
  97. const view = await visitView('/search/user?search=max', {
  98. mockApollo: false,
  99. })
  100. expect(
  101. await view.findByLabelText('Avatar (Max Mustermann) (VIP)'),
  102. ).toBeAvatarElement({
  103. active: false,
  104. vip: true,
  105. type: 'user',
  106. })
  107. expect(view.getByLabelText('Avatar (Jon Doe)')).toBeAvatarElement({
  108. active: true,
  109. vip: false,
  110. outOfOffice: true,
  111. image: 'jon.png',
  112. type: 'user',
  113. })
  114. })
  115. })
  116. test('correctly redirects from hash-based routes', async () => {
  117. setupView('agent')
  118. mockGraphQLResult<SearchQuery>(SearchDocument, {
  119. search: [],
  120. })
  121. await visitView('/#search/string', { mockApollo: false })
  122. const router = getTestRouter()
  123. const route = router.currentRoute.value
  124. expect(route.name).toBe('SearchOverview')
  125. expect(route.params).toEqual({ type: 'ticket' })
  126. expect(route.query).toEqual({ search: 'string' })
  127. })