create-folder.spec.tsx 6.5 KB

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