create-folder.spec.tsx 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282
  1. import FileTreeRoot from '../../../../../frontend/js/features/file-tree/components/file-tree-root'
  2. import { EditorProviders } from '../../../helpers/editor-providers'
  3. import { SocketIOMock } from '@/ide/connection/SocketIoShim'
  4. import type { Socket } from '@/features/ide-react/connection/types/socket'
  5. describe('FileTree Create Folder Flow', function () {
  6. let socket: SocketIOMock & Socket
  7. beforeEach(function () {
  8. socket = new SocketIOMock() as any
  9. cy.window().then(win => {
  10. win.metaAttributesCache.set('ol-user', { id: 'user1' })
  11. })
  12. })
  13. it('add to root when no files are selected', function () {
  14. const rootFolder = [
  15. {
  16. _id: 'root-folder-id',
  17. name: 'rootFolder',
  18. docs: [{ _id: '456def', name: 'main.tex' }],
  19. folders: [],
  20. fileRefs: [],
  21. },
  22. ]
  23. cy.mount(
  24. <EditorProviders
  25. rootFolder={rootFolder as any}
  26. projectId="123abc"
  27. socket={socket}
  28. >
  29. <FileTreeRoot
  30. refProviders={{}}
  31. setRefProviderEnabled={cy.stub()}
  32. setStartedFreeTrial={cy.stub()}
  33. onSelect={cy.stub()}
  34. onInit={cy.stub()}
  35. isConnected
  36. />
  37. </EditorProviders>
  38. )
  39. const name = 'Foo Bar In Root'
  40. cy.intercept('post', '/project/*/folder', {
  41. body: {
  42. folders: [],
  43. fileRefs: [],
  44. docs: [],
  45. _id: fakeId(),
  46. name,
  47. },
  48. }).as('createFolder')
  49. createFolder(name)
  50. cy.get('@createFolder').its('request.body').should('deep.equal', {
  51. parent_folder_id: 'root-folder-id',
  52. name,
  53. })
  54. cy.then(() => {
  55. socket.emitToClient('reciveNewFolder', 'root-folder-id', {
  56. _id: fakeId(),
  57. name,
  58. docs: [],
  59. fileRefs: [],
  60. folders: [],
  61. })
  62. })
  63. cy.findByRole('treeitem', { name })
  64. })
  65. it('add to folder from folder', function () {
  66. const rootFolder = [
  67. {
  68. _id: 'root-folder-id',
  69. name: 'rootFolder',
  70. docs: [],
  71. folders: [
  72. {
  73. _id: '789ghi',
  74. name: 'thefolder',
  75. docs: [],
  76. fileRefs: [],
  77. folders: [],
  78. },
  79. ],
  80. fileRefs: [],
  81. },
  82. ]
  83. cy.mount(
  84. <EditorProviders
  85. rootFolder={rootFolder as any}
  86. projectId="123abc"
  87. rootDocId="789ghi"
  88. socket={socket}
  89. >
  90. <FileTreeRoot
  91. refProviders={{}}
  92. setRefProviderEnabled={cy.stub()}
  93. setStartedFreeTrial={cy.stub()}
  94. onSelect={cy.stub()}
  95. onInit={cy.stub()}
  96. isConnected
  97. />
  98. </EditorProviders>
  99. )
  100. cy.findByRole('button', { name: 'Expand' }).click()
  101. const name = 'Foo Bar In thefolder'
  102. cy.intercept('post', '/project/*/folder', {
  103. body: {
  104. folders: [],
  105. fileRefs: [],
  106. docs: [],
  107. _id: fakeId(),
  108. name,
  109. },
  110. }).as('createFolder')
  111. createFolder(name)
  112. cy.get('@createFolder').its('request.body').should('deep.equal', {
  113. parent_folder_id: '789ghi',
  114. name,
  115. })
  116. cy.then(() => {
  117. socket.emitToClient('reciveNewFolder', '789ghi', {
  118. _id: fakeId(),
  119. name,
  120. docs: [],
  121. fileRefs: [],
  122. folders: [],
  123. })
  124. })
  125. // find the created folder
  126. cy.findByRole('treeitem', { name })
  127. // collapse the parent folder; created folder should not be rendered anymore
  128. cy.findByRole('button', { name: 'Collapse' }).click()
  129. cy.findByRole('treeitem', { name }).should('not.exist')
  130. })
  131. it('add to folder from child', function () {
  132. const rootFolder = [
  133. {
  134. _id: 'root-folder-id',
  135. name: 'rootFolder',
  136. docs: [],
  137. folders: [
  138. {
  139. _id: '789ghi',
  140. name: 'thefolder',
  141. docs: [],
  142. fileRefs: [{ _id: '456def', name: 'sub.tex' }],
  143. folders: [],
  144. },
  145. ],
  146. fileRefs: [],
  147. },
  148. ]
  149. cy.mount(
  150. <EditorProviders
  151. rootFolder={rootFolder as any}
  152. projectId="123abc"
  153. rootDocId="456def"
  154. socket={socket}
  155. >
  156. <FileTreeRoot
  157. refProviders={{}}
  158. setRefProviderEnabled={cy.stub()}
  159. setStartedFreeTrial={cy.stub()}
  160. onSelect={cy.stub()}
  161. onInit={cy.stub()}
  162. isConnected
  163. />
  164. </EditorProviders>
  165. )
  166. const name = 'Foo Bar In thefolder'
  167. cy.intercept('post', '/project/*/folder', {
  168. body: {
  169. folders: [],
  170. fileRefs: [],
  171. docs: [],
  172. _id: fakeId(),
  173. name,
  174. },
  175. }).as('createFolder')
  176. createFolder(name)
  177. cy.get('@createFolder').its('request.body').should('deep.equal', {
  178. parent_folder_id: '789ghi',
  179. name,
  180. })
  181. cy.then(() => {
  182. socket.emitToClient('reciveNewFolder', '789ghi', {
  183. _id: fakeId(),
  184. name,
  185. docs: [],
  186. fileRefs: [],
  187. folders: [],
  188. })
  189. })
  190. // find the created folder
  191. cy.findByRole('treeitem', { name })
  192. // collapse the parent folder; created folder should not be rendered anymore
  193. cy.findByRole('button', { name: 'Collapse' }).click()
  194. cy.findByRole('treeitem', { name }).should('not.exist')
  195. })
  196. it('prevents adding duplicate or invalid names', function () {
  197. const rootFolder = [
  198. {
  199. _id: 'root-folder-id',
  200. name: 'rootFolder',
  201. docs: [{ _id: '456def', name: 'existingFile' }],
  202. folders: [],
  203. fileRefs: [],
  204. },
  205. ]
  206. cy.mount(
  207. <EditorProviders
  208. rootFolder={rootFolder as any}
  209. projectId="123abc"
  210. rootDocId="456def"
  211. socket={socket}
  212. >
  213. <FileTreeRoot
  214. refProviders={{}}
  215. setRefProviderEnabled={cy.stub()}
  216. setStartedFreeTrial={cy.stub()}
  217. onSelect={cy.stub()}
  218. onInit={cy.stub()}
  219. isConnected
  220. />
  221. </EditorProviders>
  222. )
  223. const name = 'existingFile'
  224. cy.intercept('post', '/project/*/folder', cy.spy().as('createFolder'))
  225. createFolder(name)
  226. cy.get('@createFolder').should('not.have.been.called')
  227. cy.findByRole('alert', {
  228. name: 'A file or folder with this name already exists',
  229. })
  230. cy.findByRole('textbox').type('in/valid ')
  231. cy.findByRole('alert', {
  232. name: 'File name is empty or contains invalid characters',
  233. })
  234. })
  235. function createFolder(name: string) {
  236. cy.findByRole('button', { name: 'New folder' }).click()
  237. cy.findByRole('textbox').type(name)
  238. cy.findByRole('button', { name: 'Create' }).click()
  239. }
  240. function fakeId() {
  241. return Math.random().toString(16).replace(/0\./, 'random-test-id-')
  242. }
  243. })