Merge pull request #3195 from overleaf/ta-outline-tests

More outline tests

GitOrigin-RevId: d0f4d6137cf0bf5f408801983658a79bf230967d
This commit is contained in:
Chrystal Maria Griffiths 2020-09-18 12:05:05 +02:00 committed by Copybot
parent 170f996e5f
commit 512e76ef4e
6 changed files with 205 additions and 24 deletions

View file

@ -4,5 +4,7 @@
"we_cant_find_any_sections_or_subsections_in_this_file",
"find_out_more_about_the_file_outline",
"expand",
"collapse"
"collapse",
"show_outline",
"hide_outline"
]

View file

@ -5,7 +5,7 @@ import classNames from 'classnames'
import { useTranslation, Trans } from 'react-i18next'
import OutlineRoot from './outline-root'
import localStorage from '../../../modules/localStorage'
import localStorage from '../../../infrastructure/local-storage'
import withErrorBoundary from '../../../infrastructure/error-boundary'
function OutlinePane({
@ -21,7 +21,7 @@ function OutlinePane({
const storageKey = `file_outline.expanded.${projectId}`
const [expanded, setExpanded] = useState(() => {
const storedExpandedState = localStorage(storageKey) !== false
const storedExpandedState = localStorage.getItem(storageKey) !== false
return storedExpandedState
})
const isOpen = isTexFile && expanded
@ -44,7 +44,7 @@ function OutlinePane({
function handleExpandCollapseClick() {
if (isTexFile) {
localStorage(storageKey, !expanded)
localStorage.setItem(storageKey, !expanded)
eventTracking.sendMB(expanded ? 'outline-collapse' : 'outline-expand')
setExpanded(!expanded)
}
@ -68,6 +68,7 @@ function OutlinePane({
className="outline-header-expand-collapse-btn"
disabled={!isTexFile}
onClick={handleExpandCollapseClick}
aria-label={expanded ? t('hide_outline') : t('show_outline')}
>
<i className={expandCollapseIconClasses} />
<h4 className="outline-header-name">{t('file_outline')}</h4>

View file

@ -6,12 +6,10 @@ import { screen, render, fireEvent } from '@testing-library/react'
import OutlineItem from '../../../../../frontend/js/features/outline/components/outline-item'
describe('<OutlineItem />', function() {
before(function() {
this.jumpToLine = sinon.stub()
})
const jumpToLine = sinon.stub()
afterEach(function() {
this.jumpToLine.reset()
jumpToLine.reset()
})
it('renders basic item', function() {
@ -19,9 +17,7 @@ describe('<OutlineItem />', function() {
title: 'Test Title',
line: 1
}
render(
<OutlineItem outlineItem={outlineItem} jumpToLine={this.jumpToLine} />
)
render(<OutlineItem outlineItem={outlineItem} jumpToLine={jumpToLine} />)
screen.getByRole('treeitem', { current: false })
screen.getByRole('button', { name: outlineItem.title })
@ -34,9 +30,7 @@ describe('<OutlineItem />', function() {
line: 1,
children: [{ title: 'Child', line: 2 }]
}
render(
<OutlineItem outlineItem={outlineItem} jumpToLine={this.jumpToLine} />
)
render(<OutlineItem outlineItem={outlineItem} jumpToLine={jumpToLine} />)
const collapseButton = screen.getByRole('button', { name: 'Collapse' })
@ -59,7 +53,7 @@ describe('<OutlineItem />', function() {
render(
<OutlineItem
outlineItem={outlineItem}
jumpToLine={this.jumpToLine}
jumpToLine={jumpToLine}
highlightedLine={1}
/>
)
@ -76,7 +70,7 @@ describe('<OutlineItem />', function() {
render(
<OutlineItem
outlineItem={outlineItem}
jumpToLine={this.jumpToLine}
jumpToLine={jumpToLine}
highlightedLine={2}
/>
)
@ -94,19 +88,17 @@ describe('<OutlineItem />', function() {
title: 'Parent',
line: 1
}
render(
<OutlineItem outlineItem={outlineItem} jumpToLine={this.jumpToLine} />
)
render(<OutlineItem outlineItem={outlineItem} jumpToLine={jumpToLine} />)
const titleButton = screen.getByRole('button', { name: outlineItem.title })
fireEvent.click(titleButton)
sinon.assert.calledOnce(this.jumpToLine)
sinon.assert.calledWith(this.jumpToLine, 1, false)
expect(jumpToLine).to.be.calledOnce
expect(jumpToLine).to.be.calledWith(1, false)
this.jumpToLine.reset()
jumpToLine.reset()
fireEvent.doubleClick(titleButton)
sinon.assert.calledOnce(this.jumpToLine)
sinon.assert.calledWith(this.jumpToLine, 1, true)
expect(jumpToLine).to.be.calledOnce
expect(jumpToLine).to.be.calledWith(1, true)
})
})

View file

@ -0,0 +1,53 @@
import React from 'react'
import { screen, render } from '@testing-library/react'
import OutlineList from '../../../../../frontend/js/features/outline/components/outline-list'
describe('<OutlineList />', function() {
const jumpToLine = () => {}
it('renders items', function() {
const outline = [
{
title: 'Section 1',
line: 1,
level: 10
},
{
title: 'Section 2',
line: 2,
level: 10
}
]
render(<OutlineList outline={outline} isRoot jumpToLine={jumpToLine} />)
screen.getByRole('treeitem', { name: 'Section 1' })
screen.getByRole('treeitem', { name: 'Section 2' })
})
it('renders as root', function() {
const outline = [
{
title: 'Section',
line: 1,
level: 10
}
]
render(<OutlineList outline={outline} isRoot jumpToLine={jumpToLine} />)
screen.getByRole('tree')
})
it('renders as non-root', function() {
const outline = [
{
title: 'Section',
line: 1,
level: 10
}
]
render(<OutlineList outline={outline} jumpToLine={jumpToLine} />)
screen.getByRole('group')
})
})

View file

@ -0,0 +1,102 @@
import { expect } from 'chai'
import React from 'react'
import sinon from 'sinon'
import { screen, render, fireEvent } from '@testing-library/react'
import OutlinePane from '../../../../../frontend/js/features/outline/components/outline-pane'
describe('<OutlinePane />', function() {
const jumpToLine = () => {}
const projectId = '123abc'
const onToggle = sinon.stub()
const eventTracking = { sendMB: sinon.stub() }
before(function() {
global.localStorage = {
getItem: sinon.stub().returns(null),
setItem: sinon.stub()
}
})
afterEach(function() {
onToggle.reset()
eventTracking.sendMB.reset()
global.localStorage.getItem.resetHistory()
global.localStorage.setItem.resetHistory()
})
after(function() {
delete global.localStorage
})
it('renders expanded outline', function() {
const outline = [
{
title: 'Section',
line: 1,
level: 10
}
]
render(
<OutlinePane
isTexFile
outline={outline}
projectId={projectId}
jumpToLine={jumpToLine}
onToggle={onToggle}
eventTracking={eventTracking}
/>
)
screen.getByRole('tree')
screen.getByRole('link', { textMatch: 'The File outline is a new feature' })
})
it('renders disabled outline', function() {
const outline = []
render(
<OutlinePane
isTexFile={false}
outline={outline}
projectId={projectId}
jumpToLine={jumpToLine}
onToggle={onToggle}
eventTracking={eventTracking}
/>
)
expect(screen.queryByRole('tree')).to.be.null
})
it('expand outline and use local storage', function() {
global.localStorage.getItem.returns(false)
const outline = [
{
title: 'Section',
line: 1,
level: 10
}
]
render(
<OutlinePane
isTexFile
outline={outline}
projectId={projectId}
jumpToLine={jumpToLine}
onToggle={onToggle}
eventTracking={eventTracking}
/>
)
expect(screen.queryByRole('tree')).to.be.null
const collapseButton = screen.getByRole('button', {
name: 'Show File outline'
})
fireEvent.click(collapseButton)
screen.getByRole('tree')
expect(global.localStorage.setItem).to.be.calledOnce
expect(global.localStorage.setItem).to.be.calledWithMatch(/123abc/, 'true')
expect(onToggle).to.be.calledTwice
})
})

View file

@ -0,0 +1,31 @@
import { expect } from 'chai'
import React from 'react'
import { screen, render } from '@testing-library/react'
import OutlineRoot from '../../../../../frontend/js/features/outline/components/outline-root'
describe('<OutlineRoot />', function() {
const jumpToLine = () => {}
it('renders outline', function() {
const outline = [
{
title: 'Section',
line: 1,
level: 10
}
]
render(<OutlineRoot outline={outline} jumpToLine={jumpToLine} />)
screen.getByRole('tree')
expect(screen.queryByRole('link')).to.be.null
})
it('renders placeholder', function() {
const outline = []
render(<OutlineRoot outline={outline} jumpToLine={jumpToLine} />)
expect(screen.queryByRole('tree')).to.be.null
screen.getByRole('link')
})
})