project-search.test.tsx 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  1. import sinon from 'sinon'
  2. import { render, screen, fireEvent } from '@testing-library/react'
  3. import { expect } from 'chai'
  4. import SearchForm from '../../../../../frontend/js/features/project-list/components/search-form'
  5. import * as eventTracking from '@/infrastructure/event-tracking'
  6. import fetchMock from 'fetch-mock'
  7. import { Filter } from '../../../../../frontend/js/features/project-list/context/project-list-context'
  8. import { Tag } from '../../../../../app/src/Features/Tags/types'
  9. describe('Project list search form', function () {
  10. let sendMBSpy: sinon.SinonSpy
  11. beforeEach(function () {
  12. sendMBSpy = sinon.spy(eventTracking, 'sendMB')
  13. fetchMock.reset()
  14. })
  15. afterEach(function () {
  16. fetchMock.reset()
  17. sendMBSpy.restore()
  18. })
  19. it('renders the search form', function () {
  20. const filter: Filter = 'all'
  21. const selectedTag = undefined
  22. render(
  23. <SearchForm
  24. inputValue=""
  25. setInputValue={() => {}}
  26. filter={filter}
  27. selectedTag={selectedTag}
  28. />
  29. )
  30. screen.getByRole('search')
  31. screen.getByRole('textbox', { name: /search in all projects/i })
  32. })
  33. it('calls clear text when clear button is clicked', function () {
  34. const filter: Filter = 'all'
  35. const selectedTag = undefined
  36. const setInputValueMock = sinon.stub()
  37. render(
  38. <SearchForm
  39. inputValue="abc"
  40. setInputValue={setInputValueMock}
  41. filter={filter}
  42. selectedTag={selectedTag}
  43. />
  44. )
  45. const input = screen.getByRole<HTMLInputElement>('textbox', {
  46. name: /search in all projects/i,
  47. })
  48. expect(input.value).to.equal('abc')
  49. const clearBtn = screen.getByRole('button', { name: 'clear search' })
  50. fireEvent.click(clearBtn)
  51. expect(setInputValueMock).to.be.calledWith('')
  52. })
  53. it('changes text', function () {
  54. const setInputValueMock = sinon.stub()
  55. const filter: Filter = 'all'
  56. const selectedTag = undefined
  57. render(
  58. <SearchForm
  59. inputValue=""
  60. setInputValue={setInputValueMock}
  61. filter={filter}
  62. selectedTag={selectedTag}
  63. />
  64. )
  65. const input = screen.getByRole('textbox', {
  66. name: /search in all projects/i,
  67. })
  68. const value = 'abc'
  69. fireEvent.change(input, { target: { value } })
  70. expect(sendMBSpy).to.have.been.calledOnce
  71. expect(sendMBSpy).to.have.been.calledWith('project-list-page-interaction', {
  72. action: 'search',
  73. page: '/',
  74. isSmallDevice: true,
  75. })
  76. expect(setInputValueMock).to.be.calledWith(value)
  77. })
  78. type TestCase = {
  79. filter: Filter
  80. selectedTag: Tag | undefined
  81. expectedText: string
  82. }
  83. const placeholderTestCases: Array<TestCase> = [
  84. // Filter, without tag
  85. {
  86. filter: 'all',
  87. selectedTag: undefined,
  88. expectedText: 'search in all projects',
  89. },
  90. {
  91. filter: 'owned',
  92. selectedTag: undefined,
  93. expectedText: 'search in your projects',
  94. },
  95. {
  96. filter: 'shared',
  97. selectedTag: undefined,
  98. expectedText: 'search in projects shared with you',
  99. },
  100. {
  101. filter: 'archived',
  102. selectedTag: undefined,
  103. expectedText: 'search in archived projects',
  104. },
  105. {
  106. filter: 'trashed',
  107. selectedTag: undefined,
  108. expectedText: 'search in trashed projects',
  109. },
  110. // Tags
  111. {
  112. filter: 'all',
  113. selectedTag: { _id: '', user_id: '', name: 'sometag' },
  114. expectedText: 'search sometag',
  115. },
  116. {
  117. filter: 'shared',
  118. selectedTag: { _id: '', user_id: '', name: 'othertag' },
  119. expectedText: 'search othertag',
  120. },
  121. ]
  122. for (const testCase of placeholderTestCases) {
  123. it(`renders placeholder text for filter:${testCase.filter}, tag:${testCase?.selectedTag?.name}`, function () {
  124. render(
  125. <SearchForm
  126. inputValue=""
  127. setInputValue={() => {}}
  128. filter={testCase.filter}
  129. selectedTag={testCase.selectedTag}
  130. />
  131. )
  132. screen.getByRole('search')
  133. screen.getByRole('textbox', {
  134. name: new RegExp(testCase.expectedText, 'i'),
  135. })
  136. })
  137. }
  138. })