preview-log-entry.test.js 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151
  1. import React from 'react'
  2. import { expect } from 'chai'
  3. import sinon from 'sinon'
  4. import { screen, render, fireEvent } from '@testing-library/react'
  5. import PreviewLogEntry from '../../../../../frontend/js/features/preview/components/preview-log-entry.js'
  6. describe('<PreviewLogEntry />', function() {
  7. const level = 'error'
  8. describe('log entry description', function() {
  9. for (const level of ['error', 'warning', 'typesetting', 'raw']) {
  10. it(`describes the log entry with ${level} information`, function() {
  11. render(<PreviewLogEntry level={level} />)
  12. const expectedLabel =
  13. level === 'raw'
  14. ? 'Raw logs from the LaTeX compiler'
  15. : `Log entry with level: ${level}`
  16. screen.getByLabelText(expectedLabel)
  17. })
  18. }
  19. })
  20. describe('log location link', function() {
  21. const file = 'foo.tex'
  22. const line = 42
  23. const column = 21
  24. const onLogEntryLocationClick = sinon.stub()
  25. afterEach(function() {
  26. onLogEntryLocationClick.reset()
  27. })
  28. it('renders both file and line', function() {
  29. render(<PreviewLogEntry file={file} line={line} level={level} />)
  30. screen.getByRole('button', {
  31. name: `Navigate to log position in source code: ${file}, ${line}`
  32. })
  33. })
  34. it('renders only file when line information is not available', function() {
  35. render(<PreviewLogEntry file={file} level={level} />)
  36. screen.getByRole('button', {
  37. name: `Navigate to log position in source code: ${file}`
  38. })
  39. })
  40. it('does not render when file information is not available', function() {
  41. render(<PreviewLogEntry level={level} />)
  42. expect(
  43. screen.queryByRole('button', {
  44. name: `Navigate to log position in source code: `
  45. })
  46. ).to.not.exist
  47. })
  48. it('calls the callback with file, line and column on click', function() {
  49. render(
  50. <PreviewLogEntry
  51. file={file}
  52. line={line}
  53. column={column}
  54. level={level}
  55. onLogEntryLocationClick={onLogEntryLocationClick}
  56. />
  57. )
  58. const linkToSourceButton = screen.getByRole('button', {
  59. name: `Navigate to log position in source code: ${file}, ${line}`
  60. })
  61. fireEvent.click(linkToSourceButton)
  62. expect(onLogEntryLocationClick).to.be.calledOnce
  63. expect(onLogEntryLocationClick).to.be.calledWith({
  64. file,
  65. line: line,
  66. column: column
  67. })
  68. })
  69. })
  70. describe('log entry contents', function() {
  71. const logContent = 'foo bar latex error stuff baz'
  72. it('renders collapsed contents by default', function() {
  73. render(<PreviewLogEntry content={logContent} level={level} />)
  74. screen.getByText(logContent)
  75. screen.getByRole('button', {
  76. name: 'Expand'
  77. })
  78. })
  79. it('supports expanding contents', function() {
  80. render(<PreviewLogEntry content={logContent} level={level} />)
  81. screen.getByText(logContent)
  82. const expandCollapseBtn = screen.getByRole('button', {
  83. name: 'Expand'
  84. })
  85. fireEvent.click(expandCollapseBtn)
  86. screen.getByRole('button', {
  87. name: 'Collapse'
  88. })
  89. })
  90. it('should not render at all when there are no log contents', function() {
  91. const { container } = render(<PreviewLogEntry level={level} />)
  92. expect(container.querySelector('.log-entry-content')).to.not.exist
  93. })
  94. })
  95. describe('human-readable hints', function() {
  96. const logContent = 'foo bar latex error stuff baz'
  97. const logHintText = 'foo bar baz'
  98. const logHint = <>{logHintText}</>
  99. const infoURL = 'www.overleaf.com/learn/latex'
  100. it('renders the hint', function() {
  101. render(
  102. <PreviewLogEntry
  103. content={logContent}
  104. humanReadableHintComponent={logHint}
  105. extraInfoURL={infoURL}
  106. level={level}
  107. />
  108. )
  109. screen.getByText(logHintText)
  110. })
  111. it('renders the link to learn more', function() {
  112. render(
  113. <PreviewLogEntry
  114. content={logContent}
  115. humanReadableHintComponent={logHint}
  116. extraInfoURL={infoURL}
  117. level={level}
  118. />
  119. )
  120. screen.getByRole('link', { name: 'Learn more' })
  121. })
  122. it('does not render the link when it is not available', function() {
  123. render(
  124. <PreviewLogEntry
  125. content={logContent}
  126. humanReadableHintComponent={logHint}
  127. level={level}
  128. />
  129. )
  130. expect(screen.queryByRole('link', { name: 'Learn more' })).to.not.exist
  131. })
  132. })
  133. })