overleaf/services/web/test/frontend/features/preview/components/preview-recompile-button.test.js

150 lines
4.7 KiB
JavaScript
Raw Normal View History

import React from 'react'
import sinon from 'sinon'
import { screen, render, fireEvent } from '@testing-library/react'
import PreviewRecompileButton from '../../../../../frontend/js/features/preview/components/preview-recompile-button'
const { expect } = require('chai')
describe('<PreviewRecompileButton />', function() {
let onRecompile, onRecompileFromScratch, onStopCompilation
beforeEach(function() {
onRecompile = sinon.stub().resolves()
onRecompileFromScratch = sinon.stub().resolves()
onStopCompilation = sinon.stub().resolves()
})
it('renders all items', function() {
renderPreviewRecompileButton()
const menuItems = screen.getAllByRole('menuitem')
expect(menuItems.length).to.equal(9)
expect(menuItems.map(item => item.textContent)).to.deep.equal([
'On',
'Off',
'Normal',
'Fast [draft]',
'Check syntax before compile',
"Don't check syntax",
'Run syntax check now',
'Stop compilation',
'Recompile from scratch'
])
const menuHeadingItems = screen.getAllByRole('heading')
expect(menuHeadingItems.length).to.equal(3)
expect(menuHeadingItems.map(item => item.textContent)).to.deep.equal([
'Auto Compile',
'Compile Mode',
'Syntax Checks'
])
})
describe('Recompile from scratch', function() {
describe('click', function() {
it('should call onRecompileFromScratch', async function() {
renderPreviewRecompileButton()
const button = screen.getByRole('menuitem', {
name: 'Recompile from scratch'
})
await fireEvent.click(button)
expect(onRecompileFromScratch).to.have.been.calledOnce
})
})
describe('processing', function() {
it('shows processing view and disable menuItem when recompiling', function() {
renderPreviewRecompileButton({ isCompiling: true })
screen.getByRole('button', { name: 'Compiling…' })
expect(
screen
.getByRole('menuitem', {
name: 'Recompile from scratch'
})
.getAttribute('aria-disabled')
).to.equal('true')
expect(
screen
.getByRole('menuitem', {
name: 'Recompile from scratch'
})
.closest('li')
.getAttribute('class')
).to.equal('disabled')
})
})
})
it('should show the button text when prop showText=true', function() {
const showText = true
renderPreviewRecompileButton({}, showText)
expect(screen.getByText('Recompile').getAttribute('style')).to.be.null
})
it('should not show the button text when prop showText=false', function() {
const showText = false
renderPreviewRecompileButton({}, showText)
expect(screen.getByText('Recompile').getAttribute('style')).to.equal(
'position: absolute; right: -100vw;'
)
})
describe('Autocompile feedback', function() {
it('shows animated visual feedback via CSS class when there are uncompiled changes', function() {
const { container } = renderPreviewRecompileButton({
autoCompileHasChanges: true,
autoCompileHasLintingError: false
})
const recompileBtnGroupEl = container.querySelector(
'.btn-recompile-group'
)
expect(
recompileBtnGroupEl.classList.contains(
'btn-recompile-group-has-changes'
)
).to.be.true
})
it('does not show animated visual feedback via CSS class when there are no uncompiled changes', function() {
const { container } = renderPreviewRecompileButton({
autoCompileHasChanges: false,
autoCompileHasLintingError: false
})
const recompileBtnGroupEl = container.querySelector(
'.btn-recompile-group'
)
expect(
recompileBtnGroupEl.classList.contains(
'btn-recompile-group-has-changes'
)
).to.be.false
})
})
function renderPreviewRecompileButton(compilerState = {}, showText) {
if (!compilerState.logEntries) {
compilerState.logEntries = {}
}
if (showText === undefined) showText = true
return render(
<PreviewRecompileButton
compilerState={{
autoCompileHasChanges: false,
isAutoCompileOn: true,
isClearingCache: false,
isCompiling: false,
isDraftModeOn: false,
isSyntaxCheckOn: false,
...compilerState
}}
onRecompile={onRecompile}
onRunSyntaxCheckNow={() => {}}
onSetAutoCompile={() => {}}
onSetDraftMode={() => {}}
onSetSyntaxCheck={() => {}}
onRecompileFromScratch={onRecompileFromScratch}
onStopCompilation={onStopCompilation}
showText={showText}
/>
)
}
})