<commit_before>/*
 * Copyright (C) 2021 - present Instructure, Inc.
 *
 * This file is part of Canvas.
 *
 * Canvas is free software: you can redistribute it and/or modify it under
 * the terms of the GNU Affero General Public License as published by the Free
 * Software Foundation, version 3 of the License.
 *
 * Canvas is distributed in the hope that it will be useful, but WITHOUT ANY
 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
 * A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
 * details.
 *
 * You should have received a copy of the GNU Affero General Public License along
 * with this program. If not, see <http://www.gnu.org/licenses/>.
 */

import React from 'react'
import {fireEvent, render, screen, waitFor} from '@testing-library/react'
import EquationEditorModal from '../index'
import mathml from '../mathml'
import advancedPreference from '../advancedPreference'

const defaultProps = () => {
  return {
    editor: {},
    label: '',
    onEquationSubmit: () => {},
    onModalDismiss: () => {},
    onModalClose: () => {},
    title: '',
    mountNode: null
  }
}

const renderModal = (overrideProps = {}) => {
  const props = defaultProps()
  return render(<EquationEditorModal {...props} {...overrideProps} />)
}

const basicEditor = () => document.body.querySelector('math-field')

const advancedEditor = () => document.body.querySelector('textarea')

const advancedPreview = () => screen.getByTestId('mathml-preview-element')

const toggle = () => screen.getByTestId('advanced-toggle')

const tooltip = () => screen.queryByText('This equation cannot be rendered in Basic View.')

const toggleMode = () => fireEvent.click(toggle())

const editInAdvancedMode = text => {
  fireEvent.change(advancedEditor(), {target: {value: text}})
}

jest.mock('../mathml', () => {
  const originalModule = jest.requireActual('../mathml').default

  return {
    ...originalModule,
    processNewMathInElem: jest.fn()
  }
})

jest.mock('../advancedPreference', () => {
  return {
    isSet: jest.fn(),
    set: jest.fn(),
    clear: jest.fn()
  }
})

describe('EquationEditorModal', () => {
  let editor, mockFn

  beforeAll(() => {
    ENV = {
      FEATURES: {
        new_equation_editor: true
      }
    }

    HTMLElement.prototype.getValue = jest.fn().mockImplementation(function () {
      if (this.tagName === 'MATH-FIELD') {
        return this.innerHTML
      }
      return null
    })

    HTMLElement.prototype.setValue = jest.fn().mockImplementation(function (value) {
      if (this.tagName === 'MATH-FIELD') {
        this.innerHTML = value
      }
    })
  })

  beforeEach(() => {
    mockFn = jest.fn()
    editor = {
      insertContent: mockFn,
      selection: {
        getContent: () => '\\(latexcontent\\)',
        getNode: () => ({
          tagName: 'IMG',
          classList: {
            contains: str => str === 'equation_image'
          },
          src: 'http://canvas.docker/equation_images/%255Csqrt%257Bx%257D'
        }),
        getRng: () => ({
          startContainer: {
            wholeText: 'text',
            nodeValue: '\\\\\\((text)\\\\\\)'
          },
          startOffset: 0
        })
      }
    }
  })

  afterEach(() => {
    jest.clearAllMocks()
  })

  describe('loadExistingFormula', () => {
    describe('when the selected content is latex', () => {
      it('loads fromulas from displaystyle latex', async () => {
        editor.selection.getContent = () => '$$\\sqrt{x}$$'
        renderModal({editor})
        await waitFor(() => {
          const value = basicEditor().getValue()
          expect(value).toEqual('\\sqrt{x}')
        })
      })

      it('removes &nbsp; and whitespace from latex', async () => {
        editor.selection.getContent = () => '\\(&nbsp;&nbsp; \\sqrt{x} &nbsp;&nbsp;\\)'
        renderModal({editor})
        await waitFor(() => {
          const value = basicEditor().getValue()
          expect(value).toEqual('\\sqrt{x}')
        })
      })

      it('loads a basic formula in the basic editor', async () => {
        renderModal({editor})
        await waitFor(() => {
          const value = basicEditor().getValue()
          expect(value).toEqual('latexcontent')
        })
      })

      it('loads an advanced formula in the advanced editor', async () => {
        editor.selection.getContent = () => '\\(\\displaystyle\\)'
        renderModal({editor})
        await waitFor(() => {
          expect(toggle()).toBeChecked()
        })
        await waitFor(() => {
          const value = advancedEditor().value
          expect(value).toEqual('\\displaystyle')
        })
      })
    })

    describe('when the selected content is an image', () => {
      it('loads a basic formula in the basic editor', async () => {
        editor.selection.getContent = () => 'non-latex-content'
        renderModal({editor})
        await waitFor(() => {
          const value = basicEditor().getValue()
          expect(value).toEqual('\\sqrt{x}')
        })
      })

      it('loads an advanced formula in the advanced editor', async () => {
        editor.selection.getContent = () => 'non-latex-content'<commit_msg>skip flakey NEE tests<commit_after>/*
 * Copyright (C) 2021 - present Instructure, Inc.
 *
 * This file is part of Canvas.
 *
 * Canvas is free software: you can redistribute it and/or modify it under
 * the terms of the GNU Affero General Public License as published by the Free
 * Software Foundation, version 3 of the License.
 *
 * Canvas is distributed in the hope that it will be useful, but WITHOUT ANY
 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
 * A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
 * details.
 *
 * You should have received a copy of the GNU Affero General Public License along
 * with this program. If not, see <http://www.gnu.org/licenses/>.
 */

import React from 'react'
import {fireEvent, render, screen, waitFor} from '@testing-library/react'
import EquationEditorModal from '../index'
import mathml from '../mathml'
import advancedPreference from '../advancedPreference'

const defaultProps = () => {
  return {
    editor: {},
    label: '',
    onEquationSubmit: () => {},
    onModalDismiss: () => {},
    onModalClose: () => {},
    title: '',
    mountNode: null
  }
}

const renderModal = (overrideProps = {}) => {
  const props = defaultProps()
  return render(<EquationEditorModal {...props} {...overrideProps} />)
}

const basicEditor = () => document.body.querySelector('math-field')

const advancedEditor = () => document.body.querySelector('textarea')

const advancedPreview = () => screen.getByTestId('mathml-preview-element')

const toggle = () => screen.getByTestId('advanced-toggle')

const tooltip = () => screen.queryByText('This equation cannot be rendered in Basic View.')

const toggleMode = () => fireEvent.click(toggle())

const editInAdvancedMode = text => {
  fireEvent.change(advancedEditor(), {target: {value: text}})
}

jest.mock('../mathml', () => {
  const originalModule = jest.requireActual('../mathml').default

  return {
    ...originalModule,
    processNewMathInElem: jest.fn()
  }
})

jest.mock('../advancedPreference', () => {
  return {
    isSet: jest.fn(),
    set: jest.fn(),
    clear: jest.fn()
  }
})

describe('EquationEditorModal', () => {
  let editor, mockFn

  beforeAll(() => {
    ENV = {
      FEATURES: {
        new_equation_editor: true
      }
    }

    HTMLElement.prototype.getValue = jest.fn().mockImplementation(function () {
      if (this.tagName === 'MATH-FIELD') {
        return this.innerHTML
      }
      return null
    })

    HTMLElement.prototype.setValue = jest.fn().mockImplementation(function (value) {
      if (this.tagName === 'MATH-FIELD') {
        this.innerHTML = value
      }
    })
  })

  beforeEach(() => {
    mockFn = jest.fn()
    editor = {
      insertContent: mockFn,
      selection: {
        getContent: () => '\\(latexcontent\\)',
        getNode: () => ({
          tagName: 'IMG',
          classList: {
            contains: str => str === 'equation_image'
          },
          src: 'http://canvas.docker/equation_images/%255Csqrt%257Bx%257D'
        }),
        getRng: () => ({
          startContainer: {
            wholeText: 'text',
            nodeValue: '\\\\\\((text)\\\\\\)'
          },
          startOffset: 0
        })
      }
    }
  })

  afterEach(() => {
    jest.clearAllMocks()
  })

  describe('loadExistingFormula', () => {
    describe('when the selected content is latex', () => {
      it('loads fromulas from displaystyle latex', async () => {
        editor.selection.getContent = () => '$$\\sqrt{x}$$'
        renderModal({editor})
        await waitFor(() => {
          const value = basicEditor().getValue()
          expect(value).toEqual('\\sqrt{x}')
        })
      })

      it('removes &nbsp; and whitespace from latex', async () => {
        editor.selection.getContent = () => '\\(&nbsp;&nbsp; \\sqrt{x} &nbsp;&nbsp;\\)'
        renderModal({editor})
        await waitFor(() => {
          const value = basicEditor().getValue()
          expect(value).toEqual('\\sqrt{x}')
        })
      })

      it('loads a basic formula in the basic editor', async () => {
        renderModal({editor})
        await waitFor(() => {
          const value = basicEditor().getValue()
          expect(value).toEqual('latexcontent')
        })
      })

      it.skip('loads an advanced formula in the advanced editor', async () => {
        editor.selection.getContent = () => '\\(\\displaystyle\\)'
        renderModal({editor})
        await waitFor(() => {
          expect(toggle()).toBeChecked()
        })
        await waitFor(() => {
          const value = advancedEditor().value
          expect(value).toEqual('\\displaystyle')
        })
      })
    })

    describe('when the selected content is an image', () => {
      it('loads a basic formula in the basic editor', async () => {
        editor.selection.getContent = () => 'non-latex-content'
        renderModal({editor})
        await waitFor(() => {
          const value = basicEditor().getValue()
          expect(value).toEqual('\\sqrt{x}')
        })
      })

      it.skip('loads an advanced formula in the advanced editor', async () => {
        editor.selection.getContent = () => 'non-latex-content'
{'fraction_non_alphanumeric': 0.15893784875889935, 'fraction_numerical': 0.0028862805464691167, 'mean_word_length': 2.507085020242915, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 91, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4829091', 'n_tokens_mistral': 2985, 'n_tokens_neox': 2936, 'n_words': 734}