LinkedFilesTests.coffee 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303
  1. async = require "async"
  2. expect = require("chai").expect
  3. _ = require 'underscore'
  4. mkdirp = require "mkdirp"
  5. Settings = require "settings-sharelatex"
  6. MockFileStoreApi = require './helpers/MockFileStoreApi'
  7. request = require "./helpers/request"
  8. User = require "./helpers/User"
  9. express = require("express")
  10. LinkedUrlProxy = express()
  11. LinkedUrlProxy.get "/", (req, res, next) =>
  12. if req.query.url == 'http://example.com/foo'
  13. res.send('foo foo foo')
  14. else if req.query.url == 'http://example.com/bar'
  15. res.send('bar bar bar')
  16. else
  17. res.sendStatus(404)
  18. describe "LinkedFiles", ->
  19. before (done) ->
  20. LinkedUrlProxy.listen 6543, (error) =>
  21. return done(error) if error?
  22. @owner = new User()
  23. @owner.login ->
  24. mkdirp Settings.path.dumpFolder, done
  25. describe "creating a project linked file", ->
  26. before (done) ->
  27. @source_doc_name = 'test.txt'
  28. async.series [
  29. (cb) =>
  30. @owner.createProject 'plf-test-one', {template: 'blank'}, (error, project_id) =>
  31. @project_one_id = project_id
  32. cb(error)
  33. (cb) =>
  34. @owner.getProject @project_one_id, (error, project) =>
  35. @project_one = project
  36. @project_one_root_folder_id = project.rootFolder[0]._id.toString()
  37. cb(error)
  38. (cb) =>
  39. @owner.createProject 'plf-test-two', {template: 'blank'}, (error, project_id) =>
  40. @project_two_id = project_id
  41. cb(error)
  42. (cb) =>
  43. @owner.getProject @project_two_id, (error, project) =>
  44. @project_two = project
  45. @project_two_root_folder_id = project.rootFolder[0]._id.toString()
  46. cb(error)
  47. (cb) =>
  48. @owner.createDocInProject @project_two_id,
  49. @project_two_root_folder_id,
  50. @source_doc_name,
  51. (error, doc_id) =>
  52. @source_doc_id = doc_id
  53. cb(error)
  54. (cb) =>
  55. @owner.createDocInProject @project_two_id,
  56. @project_two_root_folder_id,
  57. 'some-harmless-doc.txt',
  58. (error, doc_id) =>
  59. cb(error)
  60. ], done
  61. it 'should produce a list of the users projects', (done) ->
  62. @owner.request.get {
  63. url: "/user/projects",
  64. json: true
  65. }, (err, response, body) =>
  66. expect(err).to.not.exist
  67. expect(body).to.deep.equal {
  68. projects: [
  69. { _id: @project_one_id, name: 'plf-test-one', accessLevel: 'owner' },
  70. { _id: @project_two_id, name: 'plf-test-two', accessLevel: 'owner' }
  71. ]
  72. }
  73. done()
  74. it 'should produce a list of entities in the project', (done) ->
  75. @owner.request.get {
  76. url: "/project/#{@project_two_id}/entities",
  77. json: true
  78. }, (err, response, body) =>
  79. expect(err).to.not.exist
  80. expect(body).to.deep.equal {
  81. project_id: @project_two_id,
  82. entities: [
  83. { path: '/main.tex', type: 'doc' },
  84. { path: '/some-harmless-doc.txt', type: 'doc' },
  85. { path: '/test.txt', type: 'doc' }
  86. ]
  87. }
  88. done()
  89. it 'should import a file from the source project', (done) ->
  90. @owner.request.post {
  91. url: "/project/#{@project_one_id}/linked_file",
  92. json:
  93. name: 'test-link.txt',
  94. parent_folder_id: @project_one_root_folder_id,
  95. provider: 'project_file',
  96. data:
  97. source_project_id: @project_two_id,
  98. source_entity_path: "/#{@source_doc_name}",
  99. }, (error, response, body) =>
  100. new_file_id = body.new_file_id
  101. @existing_file_id = new_file_id
  102. expect(new_file_id).to.exist
  103. @owner.getProject @project_one_id, (error, project) =>
  104. return done(error) if error?
  105. firstFile = project.rootFolder[0].fileRefs[0]
  106. expect(firstFile._id.toString()).to.equal(new_file_id.toString())
  107. expect(firstFile.linkedFileData).to.deep.equal {
  108. provider: 'project_file',
  109. source_project_id: @project_two_id,
  110. source_entity_path: "/#{@source_doc_name}",
  111. source_project_display_name: "plf-test-two"
  112. }
  113. expect(firstFile.name).to.equal('test-link.txt')
  114. done()
  115. it 'should refresh the file', (done) ->
  116. @owner.request.post {
  117. url: "/project/#{@project_one_id}/linked_file",
  118. json:
  119. name: 'test-link.txt',
  120. parent_folder_id: @project_one_root_folder_id,
  121. provider: 'project_file',
  122. data:
  123. source_project_id: @project_two_id,
  124. source_entity_path: "/#{@source_doc_name}",
  125. }, (error, response, body) =>
  126. new_file_id = body.new_file_id
  127. expect(new_file_id).to.exist
  128. expect(new_file_id).to.not.equal @existing_file_id
  129. @owner.getProject @project_one_id, (error, project) =>
  130. return done(error) if error?
  131. firstFile = project.rootFolder[0].fileRefs[0]
  132. expect(firstFile._id.toString()).to.equal(new_file_id.toString())
  133. expect(firstFile.name).to.equal('test-link.txt')
  134. done()
  135. describe "creating a URL based linked file", ->
  136. before (done) ->
  137. @owner.createProject "url-linked-files-project", {template: "blank"}, (error, project_id) =>
  138. throw error if error?
  139. @project_id = project_id
  140. @owner.getProject project_id, (error, project) =>
  141. throw error if error?
  142. @project = project
  143. @root_folder_id = project.rootFolder[0]._id.toString()
  144. done()
  145. it "should download the URL and create a file with the contents and linkedFileData", (done) ->
  146. @owner.request.post {
  147. url: "/project/#{@project_id}/linked_file",
  148. json:
  149. provider: 'url'
  150. data: {
  151. url: 'http://example.com/foo'
  152. }
  153. parent_folder_id: @root_folder_id
  154. name: 'url-test-file-1'
  155. }, (error, response, body) =>
  156. throw error if error?
  157. expect(response.statusCode).to.equal 200
  158. @owner.getProject @project_id, (error, project) =>
  159. throw error if error?
  160. file = project.rootFolder[0].fileRefs[0]
  161. expect(file.linkedFileData).to.deep.equal({
  162. provider: 'url'
  163. url: 'http://example.com/foo'
  164. })
  165. @owner.request.get "/project/#{@project_id}/file/#{file._id}", (error, response, body) ->
  166. throw error if error?
  167. expect(response.statusCode).to.equal 200
  168. expect(body).to.equal "foo foo foo"
  169. done()
  170. it "should replace and update a URL based linked file", (done) ->
  171. @owner.request.post {
  172. url: "/project/#{@project_id}/linked_file",
  173. json:
  174. provider: 'url'
  175. data: {
  176. url: 'http://example.com/foo'
  177. }
  178. parent_folder_id: @root_folder_id
  179. name: 'url-test-file-2'
  180. }, (error, response, body) =>
  181. throw error if error?
  182. expect(response.statusCode).to.equal 200
  183. @owner.request.post {
  184. url: "/project/#{@project_id}/linked_file",
  185. json:
  186. provider: 'url'
  187. data: {
  188. url: 'http://example.com/bar'
  189. }
  190. parent_folder_id: @root_folder_id
  191. name: 'url-test-file-2'
  192. }, (error, response, body) =>
  193. throw error if error?
  194. expect(response.statusCode).to.equal 200
  195. @owner.getProject @project_id, (error, project) =>
  196. throw error if error?
  197. file = project.rootFolder[0].fileRefs[1]
  198. expect(file.linkedFileData).to.deep.equal({
  199. provider: 'url'
  200. url: 'http://example.com/bar'
  201. })
  202. @owner.request.get "/project/#{@project_id}/file/#{file._id}", (error, response, body) ->
  203. throw error if error?
  204. expect(response.statusCode).to.equal 200
  205. expect(body).to.equal "bar bar bar"
  206. done()
  207. it "should return an error if the URL does not succeed", (done) ->
  208. @owner.request.post {
  209. url: "/project/#{@project_id}/linked_file",
  210. json:
  211. provider: 'url'
  212. data: {
  213. url: 'http://example.com/does-not-exist'
  214. }
  215. parent_folder_id: @root_folder_id
  216. name: 'url-test-file-3'
  217. }, (error, response, body) =>
  218. throw error if error?
  219. expect(response.statusCode).to.equal 422 # unprocessable
  220. expect(body).to.equal(
  221. "Your URL could not be reached (404 status code). Please check it and try again."
  222. )
  223. done()
  224. it "should return an error if the URL is invalid", (done) ->
  225. @owner.request.post {
  226. url: "/project/#{@project_id}/linked_file",
  227. json:
  228. provider: 'url'
  229. data: {
  230. url: "!^$%"
  231. }
  232. parent_folder_id: @root_folder_id
  233. name: 'url-test-file-4'
  234. }, (error, response, body) =>
  235. throw error if error?
  236. expect(response.statusCode).to.equal 422 # unprocessable
  237. expect(body).to.equal(
  238. "Your URL is not valid. Please check it and try again."
  239. )
  240. done()
  241. it "should return an error if the URL uses a non-http protocol", (done) ->
  242. @owner.request.post {
  243. url: "/project/#{@project_id}/linked_file",
  244. json:
  245. provider: 'url'
  246. data: {
  247. url: "ftp://localhost"
  248. }
  249. parent_folder_id: @root_folder_id
  250. name: 'url-test-file-5'
  251. }, (error, response, body) =>
  252. throw error if error?
  253. expect(response.statusCode).to.equal 422 # unprocessable
  254. expect(body).to.equal(
  255. "Your URL is not valid. Please check it and try again."
  256. )
  257. done()
  258. it "should accept a URL withuot a leading http://, and add it", (done) ->
  259. @owner.request.post {
  260. url: "/project/#{@project_id}/linked_file",
  261. json:
  262. provider: 'url'
  263. data: {
  264. url: 'example.com/foo'
  265. }
  266. parent_folder_id: @root_folder_id
  267. name: 'url-test-file-6'
  268. }, (error, response, body) =>
  269. throw error if error?
  270. expect(response.statusCode).to.equal 200
  271. @owner.getProject @project_id, (error, project) =>
  272. throw error if error?
  273. file = _.find project.rootFolder[0].fileRefs, (file) ->
  274. file.name == 'url-test-file-6'
  275. expect(file.linkedFileData).to.deep.equal({
  276. provider: 'url'
  277. url: 'http://example.com/foo'
  278. })
  279. @owner.request.get "/project/#{@project_id}/file/#{file._id}", (error, response, body) ->
  280. throw error if error?
  281. expect(response.statusCode).to.equal 200
  282. expect(body).to.equal "foo foo foo"
  283. done()
  284. # TODO: Add test for asking for host that return ENOTFOUND
  285. # (This will probably end up handled by the proxy)