project-search.test.tsx 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154
  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 '../../../../../frontend/js/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. })
  75. expect(setInputValueMock).to.be.calledWith(value)
  76. })
  77. type TestCase = {
  78. filter: Filter
  79. selectedTag: Tag | undefined
  80. expectedText: string
  81. }
  82. const placeholderTestCases: Array<TestCase> = [
  83. // Filter, without tag
  84. {
  85. filter: 'all',
  86. selectedTag: undefined,
  87. expectedText: 'search in all projects',
  88. },
  89. {
  90. filter: 'owned',
  91. selectedTag: undefined,
  92. expectedText: 'search in your projects',
  93. },
  94. {
  95. filter: 'shared',
  96. selectedTag: undefined,
  97. expectedText: 'search in projects shared with you',
  98. },
  99. {
  100. filter: 'archived',
  101. selectedTag: undefined,
  102. expectedText: 'search in archived projects',
  103. },
  104. {
  105. filter: 'trashed',
  106. selectedTag: undefined,
  107. expectedText: 'search in trashed projects',
  108. },
  109. // Tags
  110. {
  111. filter: 'all',
  112. selectedTag: { _id: '', user_id: '', name: 'sometag' },
  113. expectedText: 'search sometag',
  114. },
  115. {
  116. filter: 'shared',
  117. selectedTag: { _id: '', user_id: '', name: 'othertag' },
  118. expectedText: 'search othertag',
  119. },
  120. ]
  121. for (const testCase of placeholderTestCases) {
  122. it(`renders placeholder text for filter:${testCase.filter}, tag:${testCase?.selectedTag?.name}`, function () {
  123. render(
  124. <SearchForm
  125. inputValue=""
  126. setInputValue={() => {}}
  127. filter={testCase.filter}
  128. selectedTag={testCase.selectedTag}
  129. />
  130. )
  131. screen.getByRole('search')
  132. screen.getByRole('textbox', {
  133. name: new RegExp(testCase.expectedText, 'i'),
  134. })
  135. })
  136. }
  137. })