mirror of
https://github.com/overleaf/overleaf.git
synced 2024-11-07 20:31:06 -05:00
120 lines
3.1 KiB
TypeScript
120 lines
3.1 KiB
TypeScript
|
import sinon from 'sinon'
|
||
|
import { fireEvent, waitFor } from '@testing-library/react'
|
||
|
import { expect } from 'chai'
|
||
|
import { EditorView } from '@codemirror/view'
|
||
|
import { EditorState } from '@codemirror/state'
|
||
|
import {
|
||
|
restoreScrollPosition,
|
||
|
scrollPosition,
|
||
|
} from '../../../../../frontend/js/features/source-editor/extensions/scroll-position'
|
||
|
|
||
|
const doc = `
|
||
|
\\documentclass{article}
|
||
|
\\title{Your Paper}
|
||
|
\\author{You}
|
||
|
\\begin{document}
|
||
|
\\maketitle
|
||
|
\\begin{abstract}
|
||
|
Your abstract.
|
||
|
\\end{abstract}
|
||
|
\\section{Introduction}
|
||
|
Your introduction goes here!
|
||
|
\\end{document}`
|
||
|
|
||
|
const mockDoc = () => {
|
||
|
return {
|
||
|
doc_id: 'test-doc',
|
||
|
}
|
||
|
}
|
||
|
|
||
|
describe('CodeMirror scroll position extension', function () {
|
||
|
beforeEach(function () {
|
||
|
sinon.stub(HTMLElement.prototype, 'scrollHeight').returns(800)
|
||
|
sinon.stub(HTMLElement.prototype, 'scrollWidth').returns(500)
|
||
|
sinon.stub(HTMLElement.prototype, 'clientHeight').returns(200)
|
||
|
sinon.stub(HTMLElement.prototype, 'clientWidth').returns(500)
|
||
|
|
||
|
sinon
|
||
|
.stub(HTMLElement.prototype, 'getBoundingClientRect')
|
||
|
.returns({ top: 100, left: 0, right: 500, bottom: 200 } as DOMRect)
|
||
|
|
||
|
// Range.getClientRects doesn't exist yet in jsdom
|
||
|
window.Range.prototype.getClientRects = sinon.stub().returns([])
|
||
|
})
|
||
|
|
||
|
afterEach(function () {
|
||
|
sinon.restore()
|
||
|
// @ts-ignore
|
||
|
delete window.Range.prototype.getClientRects
|
||
|
})
|
||
|
|
||
|
it('stores scroll position when the view is destroyed', async function () {
|
||
|
const currentDoc = mockDoc()
|
||
|
|
||
|
sinon.stub(window.Storage.prototype, 'getItem').callsFake(key => {
|
||
|
switch (key) {
|
||
|
case 'doc.position.test-doc':
|
||
|
return JSON.stringify({
|
||
|
cursorPosition: { row: 2, column: 2 },
|
||
|
firstVisibleLine: 5,
|
||
|
})
|
||
|
default:
|
||
|
return null
|
||
|
}
|
||
|
})
|
||
|
|
||
|
const view = new EditorView({
|
||
|
state: EditorState.create({
|
||
|
doc,
|
||
|
extensions: [scrollPosition({ currentDoc })],
|
||
|
}),
|
||
|
})
|
||
|
|
||
|
const setItem = sinon.spy(window.Storage.prototype, 'setItem')
|
||
|
fireEvent.scroll(view.scrollDOM, { target: { scrollTop: 10 } })
|
||
|
|
||
|
view.destroy()
|
||
|
|
||
|
const expected = JSON.stringify({
|
||
|
cursorPosition: { row: 2, column: 2 },
|
||
|
firstVisibleLine: 12,
|
||
|
})
|
||
|
|
||
|
await waitFor(() => {
|
||
|
expect(setItem).to.have.been.calledWith('doc.position.test-doc', expected)
|
||
|
})
|
||
|
})
|
||
|
|
||
|
it('restores scroll position', async function () {
|
||
|
const currentDoc = mockDoc()
|
||
|
|
||
|
const getItem = sinon
|
||
|
.stub(window.Storage.prototype, 'getItem')
|
||
|
.callsFake(key => {
|
||
|
switch (key) {
|
||
|
case 'editor.position.test-doc':
|
||
|
return JSON.stringify({ firstVisibleLine: 12 })
|
||
|
default:
|
||
|
return null
|
||
|
}
|
||
|
})
|
||
|
|
||
|
const view = new EditorView({
|
||
|
state: EditorState.create({
|
||
|
doc,
|
||
|
extensions: [scrollPosition({ currentDoc })],
|
||
|
}),
|
||
|
})
|
||
|
view.dispatch(restoreScrollPosition())
|
||
|
|
||
|
await waitFor(() => {
|
||
|
expect(getItem).to.have.been.calledWith('doc.position.test-doc')
|
||
|
})
|
||
|
|
||
|
// TODO: scrollTop should be a higher value but requires more mocking
|
||
|
// await waitFor(() => {
|
||
|
// expect(view.scrollDOM.scrollTop).to.eq(0)
|
||
|
// })
|
||
|
})
|
||
|
})
|