Use Hunspell for client-side spellchecking (#20286)

GitOrigin-RevId: c4d0d9e06fe0cc9d7cb7a058fd0768eb024e44f5
This commit is contained in:
Alf Eaton
2024-10-14 10:58:36 +00:00
committed by Copybot
parent 2d737810d4
commit 24c8629cd4
40 changed files with 5391 additions and 514 deletions
@@ -0,0 +1,100 @@
import DictionaryModal from '@/features/dictionary/components/dictionary-modal'
import { EditorProviders } from '../../../helpers/editor-providers'
describe('<DictionaryModalContent />', function () {
beforeEach(function () {
cy.interceptCompile()
})
afterEach(function () {
cy.window().then(win => {
win.dispatchEvent(new CustomEvent('learnedWords:doreset'))
})
})
it('list words', function () {
cy.window().then(win => {
win.metaAttributesCache.set('ol-learnedWords', ['foo', 'bar'])
win.dispatchEvent(new CustomEvent('learnedWords:doreset'))
})
cy.mount(
<EditorProviders>
<DictionaryModal show handleHide={cy.stub()} />
</EditorProviders>
)
cy.findByText('foo')
cy.findByText('bar')
})
it('shows message when empty', function () {
cy.window().then(win => {
win.metaAttributesCache.set('ol-learnedWords', [])
win.dispatchEvent(new CustomEvent('learnedWords:doreset'))
})
cy.mount(
<EditorProviders>
<DictionaryModal show handleHide={cy.stub()} />
</EditorProviders>
)
cy.contains('Your custom dictionary is empty.')
})
it('removes words', function () {
cy.intercept('/spelling/unlearn', { statusCode: 200 })
cy.window().then(win => {
win.metaAttributesCache.set('ol-learnedWords', ['Foo', 'bar'])
win.dispatchEvent(new CustomEvent('learnedWords:doreset'))
})
cy.mount(
<EditorProviders>
<DictionaryModal show handleHide={cy.stub()} />
</EditorProviders>
)
cy.findByText('Foo')
cy.findByText('bar')
cy.findAllByRole('button', {
name: 'Remove from dictionary',
})
.eq(0)
.click()
cy.findByText('bar').should('not.exist')
cy.findByText('Foo')
})
it('handles errors', function () {
cy.intercept('/spelling/unlearn', { statusCode: 500 }).as('unlearn')
cy.window().then(win => {
win.metaAttributesCache.set('ol-learnedWords', ['foo'])
win.dispatchEvent(new CustomEvent('learnedWords:doreset'))
})
cy.mount(
<EditorProviders>
<DictionaryModal show handleHide={cy.stub()} />
</EditorProviders>
)
cy.findByText('foo')
cy.findAllByRole('button', {
name: 'Remove from dictionary',
})
.eq(0)
.click()
cy.wait('@unlearn')
cy.findByText('Sorry, something went wrong')
cy.findByText('foo')
})
})
@@ -1,60 +0,0 @@
import {
screen,
fireEvent,
waitForElementToBeRemoved,
} from '@testing-library/react'
import fetchMock from 'fetch-mock'
import DictionaryModal from '../../../../../frontend/js/features/dictionary/components/dictionary-modal'
import { renderWithEditorContext } from '../../../helpers/render-with-context'
function setLearnedWords(words) {
window.metaAttributesCache.set('ol-learnedWords', words)
window.dispatchEvent(new CustomEvent('learnedWords:doreset'))
}
describe('<DictionaryModalContent />', function () {
afterEach(function () {
fetchMock.reset()
setLearnedWords([])
})
it('list words', async function () {
setLearnedWords(['foo', 'bar'])
renderWithEditorContext(<DictionaryModal show handleHide={() => {}} />)
screen.getByText('foo')
screen.getByText('bar')
})
it('shows message when empty', async function () {
setLearnedWords([])
renderWithEditorContext(<DictionaryModal show handleHide={() => {}} />)
screen.getByText('Your custom dictionary is empty.')
})
it('removes words', async function () {
fetchMock.post('/spelling/unlearn', 200)
setLearnedWords(['Foo', 'bar'])
renderWithEditorContext(<DictionaryModal show handleHide={() => {}} />)
screen.getByText('Foo')
screen.getByText('bar')
const [firstButton] = screen.getAllByRole('button', {
name: 'Remove from dictionary',
})
fireEvent.click(firstButton)
await waitForElementToBeRemoved(() => screen.getByText('bar'))
screen.getByText('Foo')
})
it('handles errors', async function () {
fetchMock.post('/spelling/unlearn', 500)
setLearnedWords(['foo'])
renderWithEditorContext(<DictionaryModal show handleHide={() => {}} />)
screen.getByText('foo')
const [firstButton] = screen.getAllByRole('button', {
name: 'Remove from dictionary',
})
fireEvent.click(firstButton)
await fetchMock.flush()
screen.getByText('Sorry, something went wrong')
screen.getByText('foo')
})
})