JoinDocTests.js 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729
  1. /* eslint-disable
  2. no-return-assign,
  3. */
  4. // TODO: This file was created by bulk-decaffeinate.
  5. // Fix any style issues and re-enable lint.
  6. /*
  7. * decaffeinate suggestions:
  8. * DS101: Remove unnecessary use of Array.from
  9. * DS102: Remove unnecessary code created because of implicit returns
  10. * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
  11. */
  12. import { expect } from 'chai'
  13. import RealTimeClient from './helpers/RealTimeClient.js'
  14. import MockDocUpdaterServer from './helpers/MockDocUpdaterServer.js'
  15. import FixturesManager from './helpers/FixturesManager.js'
  16. import async from 'async'
  17. describe('joinDoc', function () {
  18. before(function () {
  19. this.lines = ['test', 'doc', 'lines']
  20. this.version = 42
  21. this.ops = ['mock', 'doc', 'ops']
  22. return (this.ranges = { mock: 'ranges' })
  23. })
  24. describe('when authorised readAndWrite', function () {
  25. before(function (done) {
  26. return async.series(
  27. [
  28. cb => {
  29. return FixturesManager.setUpProject(
  30. {
  31. privilegeLevel: 'readAndWrite',
  32. },
  33. (e, { project_id: projectId, user_id: userId }) => {
  34. this.project_id = projectId
  35. this.user_id = userId
  36. return cb(e)
  37. }
  38. )
  39. },
  40. cb => {
  41. return FixturesManager.setUpDoc(
  42. this.project_id,
  43. {
  44. lines: this.lines,
  45. version: this.version,
  46. ops: this.ops,
  47. ranges: this.ranges,
  48. },
  49. (e, { doc_id: docId }) => {
  50. this.doc_id = docId
  51. return cb(e)
  52. }
  53. )
  54. },
  55. cb => {
  56. this.client = RealTimeClient.connect(this.project_id, cb)
  57. },
  58. cb => {
  59. return this.client.emit(
  60. 'joinDoc',
  61. this.doc_id,
  62. (error, ...rest) => {
  63. ;[...this.returnedArgs] = Array.from(rest)
  64. return cb(error)
  65. }
  66. )
  67. },
  68. ],
  69. done
  70. )
  71. })
  72. it('should get the doc from the doc updater', function () {
  73. return MockDocUpdaterServer.getDocument
  74. .calledWith(this.project_id, this.doc_id, -1)
  75. .should.equal(true)
  76. })
  77. it('should return the doc lines, version, ranges and ops', function () {
  78. return this.returnedArgs.should.deep.equal([
  79. this.lines,
  80. this.version,
  81. this.ops,
  82. this.ranges,
  83. 'sharejs-text-ot',
  84. ])
  85. })
  86. return it('should have joined the doc room', function (done) {
  87. return RealTimeClient.getConnectedClient(
  88. this.client.socket.sessionid,
  89. (error, client) => {
  90. if (error) return done(error)
  91. expect(Array.from(client.rooms).includes(this.doc_id)).to.equal(true)
  92. return done()
  93. }
  94. )
  95. })
  96. })
  97. describe('when authorised readOnly', function () {
  98. before(function (done) {
  99. return async.series(
  100. [
  101. cb => {
  102. return FixturesManager.setUpProject(
  103. {
  104. privilegeLevel: 'readOnly',
  105. },
  106. (e, { project_id: projectId, user_id: userId }) => {
  107. this.project_id = projectId
  108. this.user_id = userId
  109. return cb(e)
  110. }
  111. )
  112. },
  113. cb => {
  114. return FixturesManager.setUpDoc(
  115. this.project_id,
  116. {
  117. lines: this.lines,
  118. version: this.version,
  119. ops: this.ops,
  120. ranges: this.ranges,
  121. },
  122. (e, { doc_id: docId }) => {
  123. this.doc_id = docId
  124. return cb(e)
  125. }
  126. )
  127. },
  128. cb => {
  129. this.client = RealTimeClient.connect(this.project_id, cb)
  130. },
  131. cb => {
  132. return this.client.emit(
  133. 'joinDoc',
  134. this.doc_id,
  135. (error, ...rest) => {
  136. ;[...this.returnedArgs] = Array.from(rest)
  137. return cb(error)
  138. }
  139. )
  140. },
  141. ],
  142. done
  143. )
  144. })
  145. it('should get the doc from the doc updater', function () {
  146. return MockDocUpdaterServer.getDocument
  147. .calledWith(this.project_id, this.doc_id, -1)
  148. .should.equal(true)
  149. })
  150. it('should return the doc lines, version, ranges and ops', function () {
  151. return this.returnedArgs.should.deep.equal([
  152. this.lines,
  153. this.version,
  154. this.ops,
  155. this.ranges,
  156. 'sharejs-text-ot',
  157. ])
  158. })
  159. return it('should have joined the doc room', function (done) {
  160. return RealTimeClient.getConnectedClient(
  161. this.client.socket.sessionid,
  162. (error, client) => {
  163. if (error) return done(error)
  164. expect(Array.from(client.rooms).includes(this.doc_id)).to.equal(true)
  165. return done()
  166. }
  167. )
  168. })
  169. })
  170. describe('when authorised as owner', function () {
  171. before(function (done) {
  172. return async.series(
  173. [
  174. cb => {
  175. return FixturesManager.setUpProject(
  176. {
  177. privilegeLevel: 'owner',
  178. },
  179. (e, { project_id: projectId, user_id: userId }) => {
  180. this.project_id = projectId
  181. this.user_id = userId
  182. return cb(e)
  183. }
  184. )
  185. },
  186. cb => {
  187. return FixturesManager.setUpDoc(
  188. this.project_id,
  189. {
  190. lines: this.lines,
  191. version: this.version,
  192. ops: this.ops,
  193. ranges: this.ranges,
  194. },
  195. (e, { doc_id: docId }) => {
  196. this.doc_id = docId
  197. return cb(e)
  198. }
  199. )
  200. },
  201. cb => {
  202. this.client = RealTimeClient.connect(this.project_id, cb)
  203. },
  204. cb => {
  205. return this.client.emit(
  206. 'joinDoc',
  207. this.doc_id,
  208. (error, ...rest) => {
  209. ;[...this.returnedArgs] = Array.from(rest)
  210. return cb(error)
  211. }
  212. )
  213. },
  214. ],
  215. done
  216. )
  217. })
  218. it('should get the doc from the doc updater', function () {
  219. return MockDocUpdaterServer.getDocument
  220. .calledWith(this.project_id, this.doc_id, -1)
  221. .should.equal(true)
  222. })
  223. it('should return the doc lines, version, ranges and ops', function () {
  224. return this.returnedArgs.should.deep.equal([
  225. this.lines,
  226. this.version,
  227. this.ops,
  228. this.ranges,
  229. 'sharejs-text-ot',
  230. ])
  231. })
  232. return it('should have joined the doc room', function (done) {
  233. return RealTimeClient.getConnectedClient(
  234. this.client.socket.sessionid,
  235. (error, client) => {
  236. if (error) return done(error)
  237. expect(Array.from(client.rooms).includes(this.doc_id)).to.equal(true)
  238. return done()
  239. }
  240. )
  241. })
  242. })
  243. // It is impossible to write an acceptance test to test joining an unauthorized
  244. // project, since joinProject already catches that. If you can join a project,
  245. // then you can join a doc in that project.
  246. describe('for an invalid doc', function () {
  247. before(function (done) {
  248. return async.series(
  249. [
  250. cb => {
  251. return FixturesManager.setUpProject(
  252. {
  253. privilegeLevel: 'owner',
  254. },
  255. (e, { project_id: projectId, user_id: userId }) => {
  256. this.project_id = projectId
  257. this.user_id = userId
  258. return cb(e)
  259. }
  260. )
  261. },
  262. cb => {
  263. return FixturesManager.setUpDoc(
  264. this.project_id,
  265. {
  266. lines: this.lines,
  267. version: this.version,
  268. ops: this.ops,
  269. ranges: this.ranges,
  270. },
  271. (e, { doc_id: docId }) => {
  272. this.doc_id = docId
  273. return cb(e)
  274. }
  275. )
  276. },
  277. cb => {
  278. this.client = RealTimeClient.connect(this.project_id, cb)
  279. },
  280. cb => {
  281. return this.client.emit(
  282. 'joinDoc',
  283. 'invalid-doc-id',
  284. (error, ...rest) => {
  285. this.error = error
  286. return cb()
  287. }
  288. )
  289. },
  290. ],
  291. done
  292. )
  293. })
  294. it('should not get the doc from the doc updater', function () {
  295. return MockDocUpdaterServer.getDocument
  296. .calledWith(this.project_id, 'invalid-doc-id')
  297. .should.equal(false)
  298. })
  299. it('should return an invalid id error', function () {
  300. this.error.message.should.equal('invalid Mongo ObjectId')
  301. })
  302. return it('should not have joined the doc room', function (done) {
  303. return RealTimeClient.getConnectedClient(
  304. this.client.socket.sessionid,
  305. (error, client) => {
  306. if (error) return done(error)
  307. expect(Array.from(client.rooms).includes('invalid-doc-id')).to.equal(
  308. false
  309. )
  310. return done()
  311. }
  312. )
  313. })
  314. })
  315. describe('with a fromVersion', function () {
  316. before(function (done) {
  317. this.fromVersion = 36
  318. return async.series(
  319. [
  320. cb => {
  321. return FixturesManager.setUpProject(
  322. {
  323. privilegeLevel: 'readAndWrite',
  324. },
  325. (e, { project_id: projectId, user_id: userId }) => {
  326. this.project_id = projectId
  327. this.user_id = userId
  328. return cb(e)
  329. }
  330. )
  331. },
  332. cb => {
  333. return FixturesManager.setUpDoc(
  334. this.project_id,
  335. {
  336. lines: this.lines,
  337. version: this.version,
  338. ops: this.ops,
  339. ranges: this.ranges,
  340. },
  341. (e, { doc_id: docId }) => {
  342. this.doc_id = docId
  343. return cb(e)
  344. }
  345. )
  346. },
  347. cb => {
  348. this.client = RealTimeClient.connect(this.project_id, cb)
  349. },
  350. cb => {
  351. return this.client.emit(
  352. 'joinDoc',
  353. this.doc_id,
  354. this.fromVersion,
  355. (error, ...rest) => {
  356. ;[...this.returnedArgs] = Array.from(rest)
  357. return cb(error)
  358. }
  359. )
  360. },
  361. ],
  362. done
  363. )
  364. })
  365. it('should get the doc from the doc updater with the fromVersion', function () {
  366. return MockDocUpdaterServer.getDocument
  367. .calledWith(this.project_id, this.doc_id, this.fromVersion)
  368. .should.equal(true)
  369. })
  370. it('should return the doc lines, version, ranges and ops', function () {
  371. return this.returnedArgs.should.deep.equal([
  372. this.lines,
  373. this.version,
  374. this.ops,
  375. this.ranges,
  376. 'sharejs-text-ot',
  377. ])
  378. })
  379. return it('should have joined the doc room', function (done) {
  380. return RealTimeClient.getConnectedClient(
  381. this.client.socket.sessionid,
  382. (error, client) => {
  383. if (error) return done(error)
  384. expect(Array.from(client.rooms).includes(this.doc_id)).to.equal(true)
  385. return done()
  386. }
  387. )
  388. })
  389. })
  390. describe('with options', function () {
  391. before(function (done) {
  392. this.options = { encodeRanges: true }
  393. return async.series(
  394. [
  395. cb => {
  396. return FixturesManager.setUpProject(
  397. {
  398. privilegeLevel: 'readAndWrite',
  399. },
  400. (e, { project_id: projectId, user_id: userId }) => {
  401. this.project_id = projectId
  402. this.user_id = userId
  403. return cb(e)
  404. }
  405. )
  406. },
  407. cb => {
  408. return FixturesManager.setUpDoc(
  409. this.project_id,
  410. {
  411. lines: this.lines,
  412. version: this.version,
  413. ops: this.ops,
  414. ranges: this.ranges,
  415. },
  416. (e, { doc_id: docId }) => {
  417. this.doc_id = docId
  418. return cb(e)
  419. }
  420. )
  421. },
  422. cb => {
  423. this.client = RealTimeClient.connect(this.project_id, cb)
  424. },
  425. cb => {
  426. return this.client.emit(
  427. 'joinDoc',
  428. this.doc_id,
  429. this.options,
  430. (error, ...rest) => {
  431. ;[...this.returnedArgs] = Array.from(rest)
  432. return cb(error)
  433. }
  434. )
  435. },
  436. ],
  437. done
  438. )
  439. })
  440. it('should get the doc from the doc updater with the default fromVersion', function () {
  441. return MockDocUpdaterServer.getDocument
  442. .calledWith(this.project_id, this.doc_id, -1)
  443. .should.equal(true)
  444. })
  445. it('should return the doc lines, version, ranges and ops', function () {
  446. return this.returnedArgs.should.deep.equal([
  447. this.lines,
  448. this.version,
  449. this.ops,
  450. this.ranges,
  451. 'sharejs-text-ot',
  452. ])
  453. })
  454. return it('should have joined the doc room', function (done) {
  455. return RealTimeClient.getConnectedClient(
  456. this.client.socket.sessionid,
  457. (error, client) => {
  458. if (error) return done(error)
  459. expect(Array.from(client.rooms).includes(this.doc_id)).to.equal(true)
  460. return done()
  461. }
  462. )
  463. })
  464. })
  465. describe('with fromVersion and options', function () {
  466. before(function (done) {
  467. this.fromVersion = 36
  468. this.options = { encodeRanges: true }
  469. return async.series(
  470. [
  471. cb => {
  472. return FixturesManager.setUpProject(
  473. {
  474. privilegeLevel: 'readAndWrite',
  475. },
  476. (e, { project_id: projectId, user_id: userId }) => {
  477. this.project_id = projectId
  478. this.user_id = userId
  479. return cb(e)
  480. }
  481. )
  482. },
  483. cb => {
  484. return FixturesManager.setUpDoc(
  485. this.project_id,
  486. {
  487. lines: this.lines,
  488. version: this.version,
  489. ops: this.ops,
  490. ranges: this.ranges,
  491. },
  492. (e, { doc_id: docId }) => {
  493. this.doc_id = docId
  494. return cb(e)
  495. }
  496. )
  497. },
  498. cb => {
  499. this.client = RealTimeClient.connect(this.project_id, cb)
  500. },
  501. cb => {
  502. return this.client.emit(
  503. 'joinDoc',
  504. this.doc_id,
  505. this.fromVersion,
  506. this.options,
  507. (error, ...rest) => {
  508. ;[...this.returnedArgs] = Array.from(rest)
  509. return cb(error)
  510. }
  511. )
  512. },
  513. ],
  514. done
  515. )
  516. })
  517. it('should get the doc from the doc updater with the fromVersion', function () {
  518. return MockDocUpdaterServer.getDocument
  519. .calledWith(this.project_id, this.doc_id, this.fromVersion)
  520. .should.equal(true)
  521. })
  522. it('should return the doc lines, version, ranges and ops', function () {
  523. return this.returnedArgs.should.deep.equal([
  524. this.lines,
  525. this.version,
  526. this.ops,
  527. this.ranges,
  528. 'sharejs-text-ot',
  529. ])
  530. })
  531. return it('should have joined the doc room', function (done) {
  532. return RealTimeClient.getConnectedClient(
  533. this.client.socket.sessionid,
  534. (error, client) => {
  535. if (error) return done(error)
  536. expect(Array.from(client.rooms).includes(this.doc_id)).to.equal(true)
  537. return done()
  538. }
  539. )
  540. })
  541. })
  542. describe('with type=history-ot', function () {
  543. before(function (done) {
  544. async.series(
  545. [
  546. cb => {
  547. FixturesManager.setUpProject(
  548. { privilegeLevel: 'owner' },
  549. (e, { project_id: projectId, user_id: userId }) => {
  550. this.project_id = projectId
  551. this.user_id = userId
  552. cb(e)
  553. }
  554. )
  555. },
  556. cb => {
  557. FixturesManager.setUpDoc(
  558. this.project_id,
  559. {
  560. lines: this.lines,
  561. version: this.version,
  562. ops: this.ops,
  563. ranges: this.ranges,
  564. type: 'history-ot',
  565. },
  566. (e, { doc_id: docId }) => {
  567. this.doc_id = docId
  568. cb(e)
  569. }
  570. )
  571. },
  572. ],
  573. done
  574. )
  575. })
  576. describe('when support is indicated', function () {
  577. before(function (done) {
  578. MockDocUpdaterServer.getDocument.resetHistory()
  579. async.series(
  580. [
  581. cb => {
  582. this.client = RealTimeClient.connect(this.project_id, cb)
  583. },
  584. cb =>
  585. this.client.emit(
  586. 'joinDoc',
  587. this.doc_id,
  588. { supportsHistoryOT: true },
  589. (error, ...rest) => {
  590. ;[...this.returnedArgs] = Array.from(rest)
  591. cb(error)
  592. }
  593. ),
  594. ],
  595. done
  596. )
  597. })
  598. it('should get the doc from the doc updater', function () {
  599. MockDocUpdaterServer.getDocument
  600. .calledWith(this.project_id, this.doc_id, -1)
  601. .should.equal(true)
  602. })
  603. it('should return the doc lines, version, ranges and ops', function () {
  604. this.returnedArgs.should.deep.equal([
  605. this.lines,
  606. this.version,
  607. this.ops,
  608. this.ranges,
  609. 'history-ot',
  610. ])
  611. })
  612. it('should have joined the doc room', function (done) {
  613. RealTimeClient.getConnectedClient(
  614. this.client.socket.sessionid,
  615. (error, client) => {
  616. if (error) return done(error)
  617. expect(client.rooms).to.deep.equal([this.project_id, this.doc_id])
  618. done()
  619. }
  620. )
  621. })
  622. })
  623. describe('when support is not indicated', function () {
  624. before(function (done) {
  625. MockDocUpdaterServer.getDocument.resetHistory()
  626. async.series(
  627. [
  628. cb => {
  629. this.client = RealTimeClient.connect(this.project_id, cb)
  630. },
  631. cb =>
  632. this.client.emit('joinDoc', this.doc_id, (error, ...rest) => {
  633. this.error = error
  634. ;[...this.returnedArgs] = Array.from(rest)
  635. cb()
  636. }),
  637. ],
  638. done
  639. )
  640. })
  641. it('should get the doc from the doc updater', function () {
  642. MockDocUpdaterServer.getDocument
  643. .calledWith(this.project_id, this.doc_id, -1)
  644. .should.equal(true)
  645. })
  646. it('should return an error', function () {
  647. expect(this.error).to.deep.equal({
  648. message: 'client does not support history-ot',
  649. })
  650. })
  651. it('should not return the doc lines, version, ranges and ops', function () {
  652. this.returnedArgs.should.deep.equal([])
  653. })
  654. it('should leave the doc room again', function (done) {
  655. RealTimeClient.getConnectedClient(
  656. this.client.socket.sessionid,
  657. (error, client) => {
  658. if (error) return done(error)
  659. expect(client.rooms).to.deep.equal([this.project_id])
  660. done()
  661. }
  662. )
  663. })
  664. })
  665. })
  666. })