settings-modal.test.tsx 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188
  1. import { screen, render, waitFor } from '@testing-library/react'
  2. import { expect } from 'chai'
  3. import fetchMock from 'fetch-mock'
  4. import { EditorProviders } from '../../helpers/editor-providers'
  5. import SettingsModal from '@/features/settings/components/settings-modal'
  6. import { Folder } from '@ol-types/folder'
  7. import { ImageName, OverallThemeMeta } from '@ol-types/project-settings'
  8. const selectTab = async (tabName: string) => {
  9. const tab = screen.getByRole('tab', { name: tabName })
  10. expect(tab).to.exist
  11. tab.click()
  12. }
  13. const assertSettingIsVisible = (settingName: string) => {
  14. expect(screen.getByLabelText(settingName)).to.exist
  15. }
  16. const TAB_SETTINGS = {
  17. Editor: [
  18. 'Auto-complete',
  19. 'Auto-close brackets',
  20. 'Code check',
  21. 'Keybindings',
  22. 'PDF Viewer',
  23. 'Reference search',
  24. 'Spellcheck language',
  25. 'Dictionary',
  26. 'Breadcrumbs',
  27. 'Equation preview',
  28. ],
  29. Compiler: [
  30. 'Main document',
  31. 'Compiler',
  32. 'TeX Live version',
  33. 'Compile mode',
  34. 'Stop on first error',
  35. 'Autocompile',
  36. ],
  37. Appearance: [
  38. 'Overall theme',
  39. 'Editor theme',
  40. 'Editor font size',
  41. 'Editor font family',
  42. 'Editor line height',
  43. ],
  44. }
  45. describe('<SettingsModal />', function () {
  46. const overallThemes: OverallThemeMeta[] = [
  47. {
  48. name: 'Overall Theme 1',
  49. val: '',
  50. },
  51. {
  52. name: 'Overall Theme 2',
  53. val: 'light-',
  54. },
  55. ]
  56. const editorThemes = [
  57. { name: 'editortheme-1', dark: false },
  58. { name: 'editortheme-2', dark: false },
  59. { name: 'editortheme-3', dark: false },
  60. ]
  61. const legacyEditorThemes = [
  62. { name: 'legacytheme-1', dark: false },
  63. { name: 'legacytheme-2', dark: false },
  64. { name: 'legacytheme-3', dark: false },
  65. ]
  66. const imageNames: ImageName[] = [
  67. {
  68. imageDesc: 'Image 1',
  69. imageName: 'img-1',
  70. allowed: true,
  71. },
  72. {
  73. imageDesc: 'Image 2',
  74. imageName: 'img-2',
  75. allowed: true,
  76. },
  77. ]
  78. const rootFolder: Folder = {
  79. _id: 'root-folder-id',
  80. name: 'rootFolder',
  81. docs: [
  82. {
  83. _id: '123abc',
  84. name: 'main.tex',
  85. },
  86. ],
  87. fileRefs: [],
  88. folders: [],
  89. }
  90. let originalSettings: typeof window.metaAttributesCache
  91. beforeEach(function () {
  92. originalSettings = window.metaAttributesCache.get('ol-ExposedSettings')
  93. window.metaAttributesCache.set('ol-ExposedSettings', {
  94. validRootDocExtensions: ['tex'],
  95. ieeeBrandId: 1234,
  96. })
  97. window.metaAttributesCache.set('ol-imageNames', imageNames)
  98. window.metaAttributesCache.set('ol-overallThemes', overallThemes)
  99. window.metaAttributesCache.set('ol-editorThemes', editorThemes)
  100. window.metaAttributesCache.set('ol-legacyEditorThemes', legacyEditorThemes)
  101. })
  102. afterEach(function () {
  103. fetchMock.removeRoutes().clearHistory()
  104. window.metaAttributesCache.set('ol-ExposedSettings', originalSettings)
  105. })
  106. it('Shows all settings options', async function () {
  107. render(
  108. <EditorProviders
  109. rootFolder={[rootFolder as any]}
  110. layoutContext={{ leftMenuShown: true }}
  111. >
  112. <SettingsModal />
  113. </EditorProviders>
  114. )
  115. Object.entries(TAB_SETTINGS).forEach(([tabName, settings]) => {
  116. selectTab(tabName)
  117. settings.forEach(setting => assertSettingIsVisible(setting))
  118. })
  119. })
  120. describe('when open=project-notifications query param is present', function () {
  121. beforeEach(function () {
  122. window.metaAttributesCache.set('ol-splitTestVariants', {
  123. 'email-notifications': 'enabled',
  124. })
  125. fetchMock.get(/\/notifications\/preferences\/project\//, {
  126. trackedChangesOnOwnProject: false,
  127. trackedChangesOnInvitedProject: false,
  128. commentOnOwnProject: false,
  129. commentOnInvitedProject: false,
  130. repliesOnOwnProject: false,
  131. repliesOnInvitedProject: false,
  132. repliesOnAuthoredThread: false,
  133. repliesOnParticipatingThread: false,
  134. })
  135. window.history.pushState({}, '', '?open=project-notifications')
  136. })
  137. afterEach(function () {
  138. window.history.pushState({}, '', window.location.pathname)
  139. window.metaAttributesCache.delete('ol-splitTestVariants')
  140. })
  141. it('opens the modal and selects the Project notifications tab', async function () {
  142. render(
  143. <EditorProviders rootFolder={[rootFolder as any]}>
  144. <SettingsModal />
  145. </EditorProviders>
  146. )
  147. await waitFor(
  148. () =>
  149. expect(
  150. screen.getByRole('tab', {
  151. name: /Project notifications/,
  152. selected: true,
  153. })
  154. ).to.exist
  155. )
  156. })
  157. it('removes the open param from the URL', async function () {
  158. render(
  159. <EditorProviders rootFolder={[rootFolder as any]}>
  160. <SettingsModal />
  161. </EditorProviders>
  162. )
  163. await waitFor(() => {
  164. expect(window.location.search).to.not.include(
  165. 'open=project-notifications'
  166. )
  167. })
  168. })
  169. })
  170. })