diff --git a/src/views/SubmissionView/TextResponseEditor/LaTexPreview.test.jsx b/src/views/SubmissionView/TextResponseEditor/LaTexPreview.test.jsx
index e00bad5f..6164a392 100644
--- a/src/views/SubmissionView/TextResponseEditor/LaTexPreview.test.jsx
+++ b/src/views/SubmissionView/TextResponseEditor/LaTexPreview.test.jsx
@@ -1,19 +1,66 @@
import React from 'react';
-import { shallow } from '@edx/react-unit-test-utils';
+import { render } from '@testing-library/react';
+import '@testing-library/jest-dom';
import { renderMathJax } from 'utils/index';
import LatexPreview from './LaTexPreview';
+jest.unmock('@openedx/paragon');
+jest.unmock('react');
+jest.unmock('@edx/frontend-platform/i18n');
+
jest.mock('utils/index', () => ({
renderMathJax: jest.fn(),
}));
describe('', () => {
- it('renders', () => {
- const wrapper = shallow();
- expect(wrapper.snapshot).toMatchSnapshot();
+ const mockRenderMathJax = renderMathJax;
+
+ beforeEach(() => {
+ jest.clearAllMocks();
+ });
+
+ it('renders with latex value', () => {
+ const latexValue = 'some latex value';
+ const { container } = render();
+
+ const previewDiv = container.querySelector('.mt-2');
+ expect(previewDiv).toBeInTheDocument();
+
+ const contentDiv = previewDiv.querySelector('div');
+ expect(contentDiv).toBeInTheDocument();
+ });
+
+ it('calls renderMathJax on mount', () => {
+ render();
+
+ expect(mockRenderMathJax).toHaveBeenCalledTimes(1);
+ });
+
+ it('calls renderMathJax when latexValue changes', () => {
+ const { rerender } = render();
+
+ expect(mockRenderMathJax).toHaveBeenCalledTimes(1);
+
+ rerender();
+
+ expect(mockRenderMathJax).toHaveBeenCalledTimes(2);
+ });
+
+ it('renders with correct HTML content', () => {
+ const latexValue = '';
+ const { container } = render();
+
+ const previewDiv = container.querySelector('.mt-2');
+ const contentDiv = previewDiv.querySelector('div');
+ expect(contentDiv.innerHTML).toBe(latexValue);
+ });
+
+ it('has correct CSS structure', () => {
+ const { container } = render();
- React.useEffect.mock.calls[0][0]();
- expect(renderMathJax).toHaveBeenCalled();
+ const outerDiv = container.querySelector('.mt-2');
+ expect(outerDiv).toBeInTheDocument();
+ expect(outerDiv.children).toHaveLength(1);
});
});
diff --git a/src/views/SubmissionView/TextResponseEditor/TextEditor.test.jsx b/src/views/SubmissionView/TextResponseEditor/TextEditor.test.jsx
index 6d8fc91e..9600d5b5 100644
--- a/src/views/SubmissionView/TextResponseEditor/TextEditor.test.jsx
+++ b/src/views/SubmissionView/TextResponseEditor/TextEditor.test.jsx
@@ -1,21 +1,33 @@
-import { shallow } from '@edx/react-unit-test-utils';
+import { render, screen } from '@testing-library/react';
+import '@testing-library/jest-dom';
+import { IntlProvider } from '@edx/frontend-platform/i18n';
+
import TextEditor from './TextEditor';
+jest.unmock('@openedx/paragon');
+jest.unmock('react');
+jest.unmock('@edx/frontend-platform/i18n');
+
describe('', () => {
- const props = {
+ const renderWithIntl = (component) => render({component});
+
+ const defaultProps = {
optional: true,
disabled: false,
value: 'value',
- onChange: jest.fn().mockName('onChange'),
+ onChange: jest.fn(),
};
- it('render optional', () => {
- const wrapper = shallow();
- expect(wrapper.snapshot).toMatchSnapshot();
- });
+ it('has correct CSS classes and accessibility attributes', () => {
+ renderWithIntl();
- it('render required', () => {
- const wrapper = shallow();
- expect(wrapper.snapshot).toMatchSnapshot();
+ const textarea = screen.getByRole('textbox');
+ expect(textarea).toBeInTheDocument();
+ expect(textarea).toHaveAttribute('name', 'text-response');
+ expect(textarea).toHaveAttribute(
+ 'placeholder',
+ 'Enter your response to the prompt above',
+ );
+ expect(textarea).toHaveValue('value');
});
});
diff --git a/src/views/SubmissionView/TextResponseEditor/__snapshots__/LaTexPreview.test.jsx.snap b/src/views/SubmissionView/TextResponseEditor/__snapshots__/LaTexPreview.test.jsx.snap
deleted file mode 100644
index 4abbea20..00000000
--- a/src/views/SubmissionView/TextResponseEditor/__snapshots__/LaTexPreview.test.jsx.snap
+++ /dev/null
@@ -1,15 +0,0 @@
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[` renders 1`] = `
-
-`;
diff --git a/src/views/SubmissionView/TextResponseEditor/__snapshots__/TextEditor.test.jsx.snap b/src/views/SubmissionView/TextResponseEditor/__snapshots__/TextEditor.test.jsx.snap
deleted file mode 100644
index 52dbad22..00000000
--- a/src/views/SubmissionView/TextResponseEditor/__snapshots__/TextEditor.test.jsx.snap
+++ /dev/null
@@ -1,54 +0,0 @@
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[` render optional 1`] = `
-
-
- Your response
- (
- Optional
- )
-
- }
- name="text-response"
- onChange={[MockFunction onChange]}
- placeholder="Enter your response to the prompt above"
- value="value"
- />
-
-`;
-
-exports[` render required 1`] = `
-
-
- Your response
- (
- required
- )
-
- }
- name="text-response"
- onChange={[MockFunction onChange]}
- placeholder="Enter your response to the prompt above"
- value="value"
- />
-
- This field is required
-
-
-`;
diff --git a/src/views/XBlockStudioView/components/StudioViewRubric.test.jsx b/src/views/XBlockStudioView/components/StudioViewRubric.test.jsx
index e816da96..8eda42cf 100644
--- a/src/views/XBlockStudioView/components/StudioViewRubric.test.jsx
+++ b/src/views/XBlockStudioView/components/StudioViewRubric.test.jsx
@@ -1,68 +1,126 @@
-import { shallow } from '@edx/react-unit-test-utils';
+import { render, screen } from '@testing-library/react';
+import '@testing-library/jest-dom';
+import { IntlProvider } from '@edx/frontend-platform/i18n';
import { useRubricConfig } from 'hooks/app';
import StudioViewRubric from './StudioViewRubric';
+jest.unmock('@openedx/paragon');
+jest.unmock('react');
+jest.unmock('@edx/frontend-platform/i18n');
+
jest.mock('hooks/app', () => ({
useRubricConfig: jest.fn(),
}));
jest.mock('./XBlockStudioViewProvider', () => ({
useXBlockStudioViewContext: () => ({
rubricIsOpen: true,
- toggleRubric: jest.fn().mockName('toggleRubric'),
+ toggleRubric: jest.fn(),
}),
}));
describe('', () => {
- it('render with criteria and options', () => {
- useRubricConfig.mockReturnValue({
- criteria: [
+ const renderWithIntl = (component) => render({component});
+
+ const sampleCriteria = [
+ {
+ name: 'criterion1',
+ description: 'description1',
+ options: [
{
- name: 'criterion1',
+ name: 'option1',
+ label: 'label1',
+ points: 1,
description: 'description1',
- options: [
- {
- name: 'option1',
- label: 'label1',
- points: 1,
- description: 'description1',
- },
- {
- name: 'option2',
- label: 'label2',
- points: 2,
- description: 'description2',
- },
- ],
},
{
- name: 'criterion2',
+ name: 'option2',
+ label: 'label2',
+ points: 2,
description: 'description2',
- options: [
- {
- name: 'option2',
- label: 'label2',
- points: 2,
- description: 'description2',
- },
- ],
},
],
+ },
+ {
+ name: 'criterion2',
+ description: 'description2',
+ options: [
+ {
+ name: 'option3',
+ label: 'label3',
+ points: 3,
+ description: 'description3',
+ },
+ ],
+ },
+ ];
+
+ beforeEach(() => {
+ jest.clearAllMocks();
+ });
+
+ it('renders rubric with criteria and options', () => {
+ useRubricConfig.mockReturnValue({
+ criteria: sampleCriteria,
+ });
+
+ renderWithIntl();
+
+ expect(screen.getByText('Rubric')).toBeInTheDocument();
+ expect(screen.getAllByTestId('criteria-test-id')).toHaveLength(2);
+
+ expect(screen.getByText('criterion1')).toBeInTheDocument();
+ expect(screen.getAllByText('description1')).toHaveLength(2);
+ expect(screen.getByText('criterion2')).toBeInTheDocument();
+ expect(screen.getAllByText('description2')).toHaveLength(2);
+ });
+
+ it('renders criterion options with points', () => {
+ useRubricConfig.mockReturnValue({
+ criteria: sampleCriteria,
});
- const wrapper = shallow();
- expect(wrapper.snapshot).toMatchSnapshot();
+ renderWithIntl();
- expect(wrapper.instance.findByTestId('criteria-test-id').length).toBe(2);
+ expect(screen.getByText(/label1: 1/)).toBeInTheDocument();
+ expect(screen.getByText(/label2: 2/)).toBeInTheDocument();
+ expect(screen.getByText(/label3: 3/)).toBeInTheDocument();
+ expect(screen.getAllByText(/point/)).toHaveLength(3);
});
- it('render without criteria', () => {
+ it('renders without criteria when empty', () => {
useRubricConfig.mockReturnValue({ criteria: [] });
- const wrapper = shallow();
- expect(wrapper.snapshot).toMatchSnapshot();
+ renderWithIntl();
+
+ expect(screen.getByText('Rubric')).toBeInTheDocument();
+ expect(screen.queryAllByTestId('criteria-test-id')).toHaveLength(0);
+ });
+
+ it('renders criterion labels correctly', () => {
+ useRubricConfig.mockReturnValue({
+ criteria: sampleCriteria,
+ });
+
+ renderWithIntl();
+
+ expect(screen.getAllByText('Criteria name:')).toHaveLength(2);
+ expect(screen.getAllByText('Criteria description:')).toHaveLength(2);
+ expect(screen.getAllByText('Criteria options:')).toHaveLength(2);
+ });
+
+ it('renders multiple criteria with different option counts', () => {
+ useRubricConfig.mockReturnValue({
+ criteria: sampleCriteria,
+ });
+
+ renderWithIntl();
+
+ const criteria = screen.getAllByTestId('criteria-test-id');
+ expect(criteria).toHaveLength(2);
- expect(wrapper.instance.findByTestId('criteria-test-id').length).toBe(0);
+ const lists = screen.getAllByRole('list');
+ expect(lists).toHaveLength(2);
});
});
diff --git a/src/views/XBlockStudioView/components/__snapshots__/StudioViewRubric.test.jsx.snap b/src/views/XBlockStudioView/components/__snapshots__/StudioViewRubric.test.jsx.snap
deleted file mode 100644
index 9d21574c..00000000
--- a/src/views/XBlockStudioView/components/__snapshots__/StudioViewRubric.test.jsx.snap
+++ /dev/null
@@ -1,122 +0,0 @@
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[` render with criteria and options 1`] = `
-
- Rubric
-
- }
->
-
-
-
- Criteria name:
-
- criterion1
-
-
-
- Criteria description:
-
- description1
-
-
-
- Criteria options:
-
-
-
- -
-
- label1
- :
- 1
-
- points
-
-
- description1
-
-
- -
-
- label2
- :
- 2
-
- points
-
-
- description2
-
-
-
-
-
-
-
- Criteria name:
-
- criterion2
-
-
-
- Criteria description:
-
- description2
-
-
-
- Criteria options:
-
-
-
- -
-
- label2
- :
- 2
-
- points
-
-
- description2
-
-
-
-
-
-`;
-
-exports[` render without criteria 1`] = `
-
- Rubric
-
- }
-/>
-`;
diff --git a/src/views/XBlockView/StatusRow/DueDateMessage/__snapshots__/index.test.jsx.snap b/src/views/XBlockView/StatusRow/DueDateMessage/__snapshots__/index.test.jsx.snap
deleted file mode 100644
index 6bda50b0..00000000
--- a/src/views/XBlockView/StatusRow/DueDateMessage/__snapshots__/index.test.jsx.snap
+++ /dev/null
@@ -1,9 +0,0 @@
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[` should render the due date message 1`] = `
-
- Due in 1 day
-
-`;
diff --git a/src/views/XBlockView/StatusRow/DueDateMessage/index.test.jsx b/src/views/XBlockView/StatusRow/DueDateMessage/index.test.jsx
index 9c30370c..6488fb11 100644
--- a/src/views/XBlockView/StatusRow/DueDateMessage/index.test.jsx
+++ b/src/views/XBlockView/StatusRow/DueDateMessage/index.test.jsx
@@ -1,15 +1,21 @@
-import { shallow } from '@edx/react-unit-test-utils';
+import { render, screen } from '@testing-library/react';
+import '@testing-library/jest-dom';
import useDueDateMessage from './useDueDateMessage';
-
import DueDateMessage from './index';
+jest.unmock('@openedx/paragon');
+jest.unmock('react');
+jest.unmock('@edx/frontend-platform/i18n');
+
jest.mock('./useDueDateMessage');
describe('', () => {
- it('should render the due date message', () => {
- useDueDateMessage.mockReturnValue('Due in 1 day');
- const wrapper = shallow();
- expect(wrapper.snapshot).toMatchSnapshot();
+ it('renders the due date message from hook', () => {
+ useDueDateMessage.mockReturnValue('Due tomorrow');
+ render();
+
+ const messageElement = screen.getByText('Due tomorrow');
+ expect(messageElement).toBeInTheDocument();
});
});
diff --git a/src/views/XBlockView/StatusRow/StatusBadge/__snapshots__/index.test.jsx.snap b/src/views/XBlockView/StatusRow/StatusBadge/__snapshots__/index.test.jsx.snap
deleted file mode 100644
index ae3955e0..00000000
--- a/src/views/XBlockView/StatusRow/StatusBadge/__snapshots__/index.test.jsx.snap
+++ /dev/null
@@ -1,9 +0,0 @@
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`StatusBadge renders 1`] = `
-
- defaultMessage
-
-`;
diff --git a/src/views/XBlockView/StatusRow/StatusBadge/index.test.jsx b/src/views/XBlockView/StatusRow/StatusBadge/index.test.jsx
index bcd9f0f0..ab99ac8a 100644
--- a/src/views/XBlockView/StatusRow/StatusBadge/index.test.jsx
+++ b/src/views/XBlockView/StatusRow/StatusBadge/index.test.jsx
@@ -1,7 +1,13 @@
-import { shallow } from '@edx/react-unit-test-utils';
+import { render, screen } from '@testing-library/react';
+import '@testing-library/jest-dom';
+import { IntlProvider } from '@edx/frontend-platform/i18n';
import StatusBadge from './index';
+jest.unmock('@openedx/paragon');
+jest.unmock('react');
+jest.unmock('@edx/frontend-platform/i18n');
+
jest.mock('./useBadgeConfig', () => () => ({
variant: 'variant',
message: {
@@ -10,9 +16,27 @@ jest.mock('./useBadgeConfig', () => () => ({
},
}));
-describe('StatusBadge', () => {
- it('renders', () => {
- const wrapper = shallow();
- expect(wrapper.snapshot).toMatchSnapshot();
+describe('', () => {
+ const renderWithIntl = (component) => render({component});
+
+ it('renders badge with message from hook', () => {
+ renderWithIntl();
+
+ expect(screen.getByText('defaultMessage')).toBeInTheDocument();
+ });
+
+ it('renders badge component with correct role', () => {
+ renderWithIntl();
+
+ const badge = screen.getByText('defaultMessage');
+ expect(badge).toBeInTheDocument();
+ expect(badge.closest('.badge')).toBeInTheDocument();
+ });
+
+ it('applies variant class from hook', () => {
+ renderWithIntl();
+
+ const badge = screen.getByText('defaultMessage');
+ expect(badge).toHaveClass('badge');
});
});