auto-select-file.test.ts 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722
  1. import { expect } from 'chai'
  2. import type { FileDiff } from '../../../../../frontend/js/features/history/services/types/file'
  3. import { autoSelectFile } from '../../../../../frontend/js/features/history/utils/auto-select-file'
  4. import type { User } from '../../../../../frontend/js/features/history/services/types/shared'
  5. import { LoadedUpdate } from '../../../../../frontend/js/features/history/services/types/update'
  6. describe('autoSelectFile', function () {
  7. const historyUsers: User[] = [
  8. {
  9. first_name: 'first_name',
  10. last_name: 'last_name',
  11. email: 'email@overleaf.com',
  12. id: '6266xb6b7a366460a66186xx',
  13. },
  14. ]
  15. describe('for comparing version with previous', function () {
  16. const comparing = false
  17. it('return the file with `edited` as the last operation', function () {
  18. const files: FileDiff[] = [
  19. {
  20. pathname: 'main.tex',
  21. },
  22. {
  23. pathname: 'sample.bib',
  24. },
  25. {
  26. pathname: 'frog.jpg',
  27. },
  28. {
  29. pathname: 'newfile5.tex',
  30. },
  31. {
  32. pathname: 'newfolder1/newfolder2/newfile2.tex',
  33. },
  34. {
  35. pathname: 'newfolder1/newfile10.tex',
  36. operation: 'edited',
  37. },
  38. ]
  39. const updates: LoadedUpdate[] = [
  40. {
  41. fromV: 25,
  42. toV: 26,
  43. meta: {
  44. users: historyUsers,
  45. start_ts: 1680888731881,
  46. end_ts: 1680888731881,
  47. },
  48. labels: [],
  49. pathnames: ['newfolder1/newfile10.tex'],
  50. project_ops: [],
  51. },
  52. {
  53. fromV: 23,
  54. toV: 25,
  55. meta: {
  56. users: historyUsers,
  57. start_ts: 1680888725098,
  58. end_ts: 1680888729123,
  59. },
  60. labels: [],
  61. pathnames: [],
  62. project_ops: [
  63. {
  64. rename: {
  65. pathname: 'newfolder1/newfile3.tex',
  66. newPathname: 'newfolder1/newfile10.tex',
  67. },
  68. atV: 24,
  69. },
  70. {
  71. rename: {
  72. pathname: 'newfile3.tex',
  73. newPathname: 'newfolder1/newfile3.tex',
  74. },
  75. atV: 23,
  76. },
  77. ],
  78. },
  79. {
  80. fromV: 22,
  81. toV: 23,
  82. meta: {
  83. users: historyUsers,
  84. start_ts: 1680888721015,
  85. end_ts: 1680888721015,
  86. },
  87. labels: [],
  88. pathnames: ['newfile3.tex'],
  89. project_ops: [],
  90. },
  91. {
  92. fromV: 19,
  93. toV: 22,
  94. meta: {
  95. users: historyUsers,
  96. start_ts: 1680888715364,
  97. end_ts: 1680888718726,
  98. },
  99. labels: [],
  100. pathnames: [],
  101. project_ops: [
  102. {
  103. rename: {
  104. pathname: 'newfolder1/newfolder2/newfile3.tex',
  105. newPathname: 'newfile3.tex',
  106. },
  107. atV: 21,
  108. },
  109. {
  110. rename: {
  111. pathname: 'newfolder1/newfile2.tex',
  112. newPathname: 'newfolder1/newfolder2/newfile2.tex',
  113. },
  114. atV: 20,
  115. },
  116. {
  117. rename: {
  118. pathname: 'newfolder1/newfile5.tex',
  119. newPathname: 'newfile5.tex',
  120. },
  121. atV: 19,
  122. },
  123. ],
  124. },
  125. {
  126. fromV: 16,
  127. toV: 19,
  128. meta: {
  129. users: historyUsers,
  130. start_ts: 1680888705042,
  131. end_ts: 1680888712662,
  132. },
  133. labels: [],
  134. pathnames: [
  135. 'main.tex',
  136. 'newfolder1/newfile2.tex',
  137. 'newfolder1/newfile5.tex',
  138. ],
  139. project_ops: [],
  140. },
  141. {
  142. fromV: 0,
  143. toV: 16,
  144. meta: {
  145. users: historyUsers,
  146. start_ts: 1680888456499,
  147. end_ts: 1680888640774,
  148. },
  149. labels: [],
  150. pathnames: [],
  151. project_ops: [
  152. {
  153. add: {
  154. pathname: 'newfolder1/newfile2.tex',
  155. },
  156. atV: 15,
  157. },
  158. {
  159. remove: {
  160. pathname: 'newfile2.tex',
  161. },
  162. atV: 14,
  163. },
  164. {
  165. rename: {
  166. pathname: 'newfolder1/frog.jpg',
  167. newPathname: 'frog.jpg',
  168. },
  169. atV: 13,
  170. },
  171. {
  172. rename: {
  173. pathname: 'newfolder1/newfile2.tex',
  174. newPathname: 'newfile2.tex',
  175. },
  176. atV: 12,
  177. },
  178. {
  179. rename: {
  180. pathname: 'newfile5.tex',
  181. newPathname: 'newfolder1/newfile5.tex',
  182. },
  183. atV: 11,
  184. },
  185. {
  186. rename: {
  187. pathname: 'newfile4.tex',
  188. newPathname: 'newfile5.tex',
  189. },
  190. atV: 10,
  191. },
  192. {
  193. add: {
  194. pathname: 'newfile4.tex',
  195. },
  196. atV: 9,
  197. },
  198. {
  199. remove: {
  200. pathname: 'newfolder1/newfolder2/newfile1.tex',
  201. },
  202. atV: 8,
  203. },
  204. {
  205. rename: {
  206. pathname: 'frog.jpg',
  207. newPathname: 'newfolder1/frog.jpg',
  208. },
  209. atV: 7,
  210. },
  211. {
  212. add: {
  213. pathname: 'newfolder1/newfolder2/newfile3.tex',
  214. },
  215. atV: 6,
  216. },
  217. {
  218. add: {
  219. pathname: 'newfolder1/newfile2.tex',
  220. },
  221. atV: 5,
  222. },
  223. {
  224. rename: {
  225. pathname: 'newfolder1/newfile1.tex',
  226. newPathname: 'newfolder1/newfolder2/newfile1.tex',
  227. },
  228. atV: 4,
  229. },
  230. {
  231. add: {
  232. pathname: 'newfolder1/newfile1.tex',
  233. },
  234. atV: 3,
  235. },
  236. {
  237. add: {
  238. pathname: 'frog.jpg',
  239. },
  240. atV: 2,
  241. },
  242. {
  243. add: {
  244. pathname: 'sample.bib',
  245. },
  246. atV: 1,
  247. },
  248. {
  249. add: {
  250. pathname: 'main.tex',
  251. },
  252. atV: 0,
  253. },
  254. ],
  255. },
  256. ]
  257. const { pathname } = autoSelectFile(
  258. files,
  259. updates[0].toV,
  260. comparing,
  261. updates
  262. )
  263. expect(pathname).to.equal('newfolder1/newfile10.tex')
  264. })
  265. it('return file with `added` operation on highest `atV` value if no other operation is available on the latest `updates` entry', function () {
  266. const files: FileDiff[] = [
  267. {
  268. pathname: 'main.tex',
  269. operation: 'added',
  270. },
  271. {
  272. pathname: 'sample.bib',
  273. operation: 'added',
  274. },
  275. {
  276. pathname: 'frog.jpg',
  277. operation: 'added',
  278. },
  279. {
  280. pathname: 'newfile1.tex',
  281. operation: 'added',
  282. },
  283. ]
  284. const updates: LoadedUpdate[] = [
  285. {
  286. fromV: 0,
  287. toV: 4,
  288. meta: {
  289. users: historyUsers,
  290. start_ts: 1680861468999,
  291. end_ts: 1680861491861,
  292. },
  293. labels: [],
  294. pathnames: [],
  295. project_ops: [
  296. {
  297. add: {
  298. pathname: 'newfile1.tex',
  299. },
  300. atV: 3,
  301. },
  302. {
  303. add: {
  304. pathname: 'frog.jpg',
  305. },
  306. atV: 2,
  307. },
  308. {
  309. add: {
  310. pathname: 'sample.bib',
  311. },
  312. atV: 1,
  313. },
  314. {
  315. add: {
  316. pathname: 'main.tex',
  317. },
  318. atV: 0,
  319. },
  320. ],
  321. },
  322. ]
  323. const { pathname } = autoSelectFile(
  324. files,
  325. updates[0].toV,
  326. comparing,
  327. updates
  328. )
  329. expect(pathname).to.equal('newfile1.tex')
  330. })
  331. it('return the last non-`removed` operation with the highest `atV` value', function () {
  332. const files: FileDiff[] = [
  333. {
  334. pathname: 'main.tex',
  335. operation: 'removed',
  336. deletedAtV: 6,
  337. },
  338. {
  339. pathname: 'sample.bib',
  340. },
  341. {
  342. pathname: 'main2.tex',
  343. operation: 'added',
  344. },
  345. {
  346. pathname: 'main3.tex',
  347. operation: 'added',
  348. },
  349. ]
  350. const updates: LoadedUpdate[] = [
  351. {
  352. fromV: 4,
  353. toV: 7,
  354. meta: {
  355. users: historyUsers,
  356. start_ts: 1680874742389,
  357. end_ts: 1680874755552,
  358. },
  359. labels: [],
  360. pathnames: [],
  361. project_ops: [
  362. {
  363. remove: {
  364. pathname: 'main.tex',
  365. },
  366. atV: 6,
  367. },
  368. {
  369. add: {
  370. pathname: 'main3.tex',
  371. },
  372. atV: 5,
  373. },
  374. {
  375. add: {
  376. pathname: 'main2.tex',
  377. },
  378. atV: 4,
  379. },
  380. ],
  381. },
  382. {
  383. fromV: 0,
  384. toV: 4,
  385. meta: {
  386. users: historyUsers,
  387. start_ts: 1680861975947,
  388. end_ts: 1680861988442,
  389. },
  390. labels: [],
  391. pathnames: [],
  392. project_ops: [
  393. {
  394. remove: {
  395. pathname: 'frog.jpg',
  396. },
  397. atV: 3,
  398. },
  399. {
  400. add: {
  401. pathname: 'frog.jpg',
  402. },
  403. atV: 2,
  404. },
  405. {
  406. add: {
  407. pathname: 'sample.bib',
  408. },
  409. atV: 1,
  410. },
  411. {
  412. add: {
  413. pathname: 'main.tex',
  414. },
  415. atV: 0,
  416. },
  417. ],
  418. },
  419. ]
  420. const { pathname } = autoSelectFile(
  421. files,
  422. updates[0].toV,
  423. comparing,
  424. updates
  425. )
  426. expect(pathname).to.equal('main3.tex')
  427. })
  428. it('if `removed` is the last operation, and no other operation is available on the latest `updates` entry, with `main.tex` available as a file name somewhere in the file tree, return `main.tex`', function () {
  429. const files: FileDiff[] = [
  430. {
  431. pathname: 'main.tex',
  432. },
  433. {
  434. pathname: 'sample.bib',
  435. },
  436. {
  437. pathname: 'frog.jpg',
  438. },
  439. {
  440. pathname: 'newfolder/maybewillbedeleted.tex',
  441. newPathname: 'newfolder2/maybewillbedeleted.tex',
  442. operation: 'removed',
  443. deletedAtV: 10,
  444. },
  445. ]
  446. const updates: LoadedUpdate[] = [
  447. {
  448. fromV: 9,
  449. toV: 11,
  450. meta: {
  451. users: historyUsers,
  452. start_ts: 1680904414419,
  453. end_ts: 1680904417538,
  454. },
  455. labels: [],
  456. pathnames: [],
  457. project_ops: [
  458. {
  459. remove: {
  460. pathname: 'newfolder2/maybewillbedeleted.tex',
  461. },
  462. atV: 10,
  463. },
  464. {
  465. rename: {
  466. pathname: 'newfolder/maybewillbedeleted.tex',
  467. newPathname: 'newfolder2/maybewillbedeleted.tex',
  468. },
  469. atV: 9,
  470. },
  471. ],
  472. },
  473. {
  474. fromV: 8,
  475. toV: 9,
  476. meta: {
  477. users: historyUsers,
  478. start_ts: 1680904410333,
  479. end_ts: 1680904410333,
  480. },
  481. labels: [],
  482. pathnames: ['newfolder/maybewillbedeleted.tex'],
  483. project_ops: [],
  484. },
  485. {
  486. fromV: 7,
  487. toV: 8,
  488. meta: {
  489. users: historyUsers,
  490. start_ts: 1680904407448,
  491. end_ts: 1680904407448,
  492. },
  493. labels: [],
  494. pathnames: [],
  495. project_ops: [
  496. {
  497. rename: {
  498. pathname: 'newfolder/tobedeleted.tex',
  499. newPathname: 'newfolder/maybewillbedeleted.tex',
  500. },
  501. atV: 7,
  502. },
  503. ],
  504. },
  505. {
  506. fromV: 6,
  507. toV: 7,
  508. meta: {
  509. users: historyUsers,
  510. start_ts: 1680904400839,
  511. end_ts: 1680904400839,
  512. },
  513. labels: [],
  514. pathnames: ['newfolder/tobedeleted.tex'],
  515. project_ops: [],
  516. },
  517. {
  518. fromV: 5,
  519. toV: 6,
  520. meta: {
  521. users: historyUsers,
  522. start_ts: 1680904398544,
  523. end_ts: 1680904398544,
  524. },
  525. labels: [],
  526. pathnames: [],
  527. project_ops: [
  528. {
  529. rename: {
  530. pathname: 'tobedeleted.tex',
  531. newPathname: 'newfolder/tobedeleted.tex',
  532. },
  533. atV: 5,
  534. },
  535. ],
  536. },
  537. {
  538. fromV: 4,
  539. toV: 5,
  540. meta: {
  541. users: historyUsers,
  542. start_ts: 1680904389891,
  543. end_ts: 1680904389891,
  544. },
  545. labels: [],
  546. pathnames: ['tobedeleted.tex'],
  547. project_ops: [],
  548. },
  549. {
  550. fromV: 0,
  551. toV: 4,
  552. meta: {
  553. users: historyUsers,
  554. start_ts: 1680904363778,
  555. end_ts: 1680904385308,
  556. },
  557. labels: [],
  558. pathnames: [],
  559. project_ops: [
  560. {
  561. add: {
  562. pathname: 'tobedeleted.tex',
  563. },
  564. atV: 3,
  565. },
  566. {
  567. add: {
  568. pathname: 'frog.jpg',
  569. },
  570. atV: 2,
  571. },
  572. {
  573. add: {
  574. pathname: 'sample.bib',
  575. },
  576. atV: 1,
  577. },
  578. {
  579. add: {
  580. pathname: 'main.tex',
  581. },
  582. atV: 0,
  583. },
  584. ],
  585. },
  586. ]
  587. const { pathname } = autoSelectFile(
  588. files,
  589. updates[0].toV,
  590. comparing,
  591. updates
  592. )
  593. expect(pathname).to.equal('main.tex')
  594. })
  595. it('if `removed` is the last operation, and no other operation is available on the latest `updates` entry, with `main.tex` is not available as a file name somewhere in the file tree, return any tex file based on ascending alphabetical order', function () {
  596. const files: FileDiff[] = [
  597. {
  598. pathname: 'certainly_not_main.tex',
  599. },
  600. {
  601. pathname: 'newfile.tex',
  602. },
  603. {
  604. pathname: 'file2.tex',
  605. },
  606. ]
  607. const updates: LoadedUpdate[] = [
  608. {
  609. fromV: 7,
  610. toV: 8,
  611. meta: {
  612. users: historyUsers,
  613. start_ts: 1680905536168,
  614. end_ts: 1680905536168,
  615. },
  616. labels: [],
  617. pathnames: [],
  618. project_ops: [
  619. {
  620. remove: {
  621. pathname: 'newfolder/tobedeleted.txt',
  622. },
  623. atV: 7,
  624. },
  625. ],
  626. },
  627. {
  628. fromV: 6,
  629. toV: 7,
  630. meta: {
  631. users: historyUsers,
  632. start_ts: 1680905531816,
  633. end_ts: 1680905531816,
  634. },
  635. labels: [],
  636. pathnames: ['newfolder/tobedeleted.txt'],
  637. project_ops: [],
  638. },
  639. {
  640. fromV: 0,
  641. toV: 6,
  642. meta: {
  643. users: historyUsers,
  644. start_ts: 1680905492130,
  645. end_ts: 1680905529186,
  646. },
  647. labels: [],
  648. pathnames: [],
  649. project_ops: [
  650. {
  651. rename: {
  652. pathname: 'tobedeleted.txt',
  653. newPathname: 'newfolder/tobedeleted.txt',
  654. },
  655. atV: 5,
  656. },
  657. {
  658. add: {
  659. pathname: 'file2.tex',
  660. },
  661. atV: 4,
  662. },
  663. {
  664. add: {
  665. pathname: 'newfile.tex',
  666. },
  667. atV: 3,
  668. },
  669. {
  670. add: {
  671. pathname: 'tobedeleted.txt',
  672. },
  673. atV: 2,
  674. },
  675. {
  676. rename: {
  677. pathname: 'main.tex',
  678. newPathname: 'certainly_not_main.tex',
  679. },
  680. atV: 1,
  681. },
  682. {
  683. add: {
  684. pathname: 'main.tex',
  685. },
  686. atV: 0,
  687. },
  688. ],
  689. },
  690. ]
  691. const { pathname } = autoSelectFile(
  692. files,
  693. updates[0].toV,
  694. comparing,
  695. updates
  696. )
  697. expect(pathname).to.equal('certainly_not_main.tex')
  698. })
  699. })
  700. })