Skip to content

Commit

Permalink
chore: [FC-0070] Some tests refactoring (#1518)
Browse files Browse the repository at this point in the history
  • Loading branch information
PKulkoRaccoonGang authored Nov 21, 2024
1 parent b5419ac commit bc8d59b
Show file tree
Hide file tree
Showing 13 changed files with 258 additions and 297 deletions.
63 changes: 15 additions & 48 deletions src/CourseAuthoringPage.test.jsx
Original file line number Diff line number Diff line change
@@ -1,19 +1,12 @@
import React from 'react';
import { getConfig } from '@edx/frontend-platform';

import { render } from '@testing-library/react';

import { getConfig, initializeMockApp } from '@edx/frontend-platform';
import MockAdapter from 'axios-mock-adapter';
import { getAuthenticatedHttpClient } from '@edx/frontend-platform/auth';
import { AppProvider } from '@edx/frontend-platform/react';
import { IntlProvider } from '@edx/frontend-platform/i18n';
import initializeStore from './store';
import CourseAuthoringPage from './CourseAuthoringPage';
import PagesAndResources from './pages-and-resources/PagesAndResources';
import { executeThunk } from './utils';
import { fetchCourseApps } from './pages-and-resources/data/thunks';
import { fetchCourseDetail, fetchWaffleFlags } from './data/thunks';
import { getApiWaffleFlagsUrl } from './data/api';
import { initializeMocks, render } from './testUtils';

const courseId = 'course-v1:edX+TestX+Test_Course';
let mockPathname = '/evilguy/';
Expand All @@ -27,16 +20,9 @@ let axiosMock;
let store;

beforeEach(async () => {
initializeMockApp({
authenticatedUser: {
userId: 3,
username: 'abc123',
administrator: true,
roles: [],
},
});
store = initializeStore();
axiosMock = new MockAdapter(getAuthenticatedHttpClient());
const mocks = initializeMocks();
store = mocks.reduxStore;
axiosMock = mocks.axiosMock;
axiosMock
.onGet(getApiWaffleFlagsUrl(courseId))
.reply(200, {});
Expand All @@ -56,13 +42,9 @@ describe('Editor Pages Load no header', () => {
mockPathname = '/editor/';
await mockStoreSuccess();
const wrapper = render(
<AppProvider store={store}>
<IntlProvider locale="en">
<CourseAuthoringPage courseId={courseId}>
<PagesAndResources courseId={courseId} />
</CourseAuthoringPage>
</IntlProvider>
</AppProvider>
<CourseAuthoringPage courseId={courseId}>
<PagesAndResources courseId={courseId} />
</CourseAuthoringPage>
,
);
expect(wrapper.queryByRole('status')).not.toBeInTheDocument();
Expand All @@ -71,13 +53,9 @@ describe('Editor Pages Load no header', () => {
mockPathname = '/evilguy/';
await mockStoreSuccess();
const wrapper = render(
<AppProvider store={store}>
<IntlProvider locale="en">
<CourseAuthoringPage courseId={courseId}>
<PagesAndResources courseId={courseId} />
</CourseAuthoringPage>
</IntlProvider>
</AppProvider>
<CourseAuthoringPage courseId={courseId}>
<PagesAndResources courseId={courseId} />
</CourseAuthoringPage>
,
);
expect(wrapper.queryByRole('status')).toBeInTheDocument();
Expand Down Expand Up @@ -105,14 +83,7 @@ describe('Course authoring page', () => {
};
test('renders not found page on non-existent course key', async () => {
await mockStoreNotFound();
const wrapper = render(
<AppProvider store={store}>
<IntlProvider locale="en">
<CourseAuthoringPage courseId={courseId} />
</IntlProvider>
</AppProvider>
,
);
const wrapper = render(<CourseAuthoringPage courseId={courseId} />);
expect(await wrapper.findByTestId('notFoundAlert')).toBeInTheDocument();
});
test('does not render not found page on other kinds of error', async () => {
Expand All @@ -123,13 +94,9 @@ describe('Course authoring page', () => {
// found alert is not present.
const contentTestId = 'courseAuthoringPageContent';
const wrapper = render(
<AppProvider store={store}>
<IntlProvider locale="en">
<CourseAuthoringPage courseId={courseId}>
<div data-testid={contentTestId} />
</CourseAuthoringPage>
</IntlProvider>
</AppProvider>
<CourseAuthoringPage courseId={courseId}>
<div data-testid={contentTestId} />
</CourseAuthoringPage>
,
);
expect(await wrapper.findByTestId(contentTestId)).toBeInTheDocument();
Expand Down
100 changes: 40 additions & 60 deletions src/CourseAuthoringRoutes.test.jsx
Original file line number Diff line number Diff line change
@@ -1,23 +1,17 @@
import React from 'react';
import { AppProvider } from '@edx/frontend-platform/react';
import { initializeMockApp } from '@edx/frontend-platform';
import { render, screen } from '@testing-library/react';
import { MemoryRouter } from 'react-router-dom';
import MockAdapter from 'axios-mock-adapter';
import { getAuthenticatedHttpClient } from '@edx/frontend-platform/auth';
import CourseAuthoringRoutes from './CourseAuthoringRoutes';
import initializeStore from './store';
import { executeThunk } from './utils';
import { getApiWaffleFlagsUrl } from './data/api';
import { fetchWaffleFlags } from './data/thunks';
import {
screen, initializeMocks, render, waitFor,
} from './testUtils';

const courseId = 'course-v1:edX+TestX+Test_Course';
const pagesAndResourcesMockText = 'Pages And Resources';
const editorContainerMockText = 'Editor Container';
const videoSelectorContainerMockText = 'Video Selector Container';
const customPagesMockText = 'Custom Pages';
let store;
let axiosMock;
const mockComponentFn = jest.fn();

jest.mock('react-router-dom', () => ({
Expand Down Expand Up @@ -57,72 +51,58 @@ jest.mock('./custom-pages/CustomPages', () => (props) => {

describe('<CourseAuthoringRoutes>', () => {
beforeEach(async () => {
initializeMockApp({
authenticatedUser: {
userId: 3,
username: 'abc123',
administrator: true,
roles: [],
},
});
store = initializeStore();
axiosMock = new MockAdapter(getAuthenticatedHttpClient());
const { axiosMock, reduxStore } = initializeMocks();
store = reduxStore;
axiosMock
.onGet(getApiWaffleFlagsUrl(courseId))
.reply(200, {});
await executeThunk(fetchWaffleFlags(courseId), store.dispatch);
});

fit('renders the PagesAndResources component when the pages and resources route is active', () => {
it('renders the PagesAndResources component when the pages and resources route is active', async () => {
render(
<AppProvider store={store} wrapWithRouter={false}>
<MemoryRouter initialEntries={['/pages-and-resources']}>
<CourseAuthoringRoutes />
</MemoryRouter>
</AppProvider>,
);

expect(screen.getByText(pagesAndResourcesMockText)).toBeVisible();
expect(mockComponentFn).toHaveBeenCalledWith(
expect.objectContaining({
courseId,
}),
<CourseAuthoringRoutes />,
{ routerProps: { initialEntries: ['/pages-and-resources'] } },
);
await waitFor(() => {
expect(screen.getByText(pagesAndResourcesMockText)).toBeVisible();
expect(mockComponentFn).toHaveBeenCalledWith(
expect.objectContaining({
courseId,
}),
);
});
});

it('renders the EditorContainer component when the course editor route is active', () => {
it('renders the EditorContainer component when the course editor route is active', async () => {
render(
<AppProvider store={store} wrapWithRouter={false}>
<MemoryRouter initialEntries={['/editor/video/block-id']}>
<CourseAuthoringRoutes />
</MemoryRouter>
</AppProvider>,
);

expect(screen.queryByText(editorContainerMockText)).toBeInTheDocument();
expect(screen.queryByText(pagesAndResourcesMockText)).not.toBeInTheDocument();
expect(mockComponentFn).toHaveBeenCalledWith(
expect.objectContaining({
courseId,
}),
<CourseAuthoringRoutes />,
{ routerProps: { initialEntries: ['/editor/video/block-id'] } },
);
await waitFor(() => {
expect(screen.queryByText(editorContainerMockText)).toBeInTheDocument();
expect(screen.queryByText(pagesAndResourcesMockText)).not.toBeInTheDocument();
expect(mockComponentFn).toHaveBeenCalledWith(
expect.objectContaining({
learningContextId: courseId,
}),
);
});
});

it('renders the VideoSelectorContainer component when the course videos route is active', () => {
it('renders the VideoSelectorContainer component when the course videos route is active', async () => {
render(
<AppProvider store={store} wrapWithRouter={false}>
<MemoryRouter initialEntries={['/editor/course-videos/block-id']}>
<CourseAuthoringRoutes />
</MemoryRouter>
</AppProvider>,
);

expect(screen.queryByText(videoSelectorContainerMockText)).toBeInTheDocument();
expect(screen.queryByText(pagesAndResourcesMockText)).not.toBeInTheDocument();
expect(mockComponentFn).toHaveBeenCalledWith(
expect.objectContaining({
courseId,
}),
<CourseAuthoringRoutes />,
{ routerProps: { initialEntries: ['/editor/course-videos/block-id'] } },
);
await waitFor(() => {
expect(screen.queryByText(videoSelectorContainerMockText)).toBeInTheDocument();
expect(screen.queryByText(pagesAndResourcesMockText)).not.toBeInTheDocument();
expect(mockComponentFn).toHaveBeenCalledWith(
expect.objectContaining({
courseId,
}),
);
});
});
});
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { within, screen } from '@testing-library/react';
import '@testing-library/jest-dom';
import { camelCaseObject } from '@edx/frontend-platform';

import { initializeMocks, render } from '../../testUtils';
import {
initializeMocks, render, screen, within,
} from '../../testUtils';
import { getApiWaffleFlagsUrl } from '../../data/api';
import { fetchWaffleFlags } from '../../data/thunks';
import { generateCourseLaunchData } from '../factories/mockApiResponses';
Expand Down
40 changes: 10 additions & 30 deletions src/custom-pages/CustomPages.test.jsx
Original file line number Diff line number Diff line change
@@ -1,18 +1,12 @@
import ReactDOM from 'react-dom';

import {
render,
act,
initializeMocks,
fireEvent,
screen,
} from '@testing-library/react';
import ReactDOM from 'react-dom';

import { initializeMockApp } from '@edx/frontend-platform';
import MockAdapter from 'axios-mock-adapter';
import { getAuthenticatedHttpClient } from '@edx/frontend-platform/auth';
import { AppProvider } from '@edx/frontend-platform/react';
import { IntlProvider } from '@edx/frontend-platform/i18n';

import initializeStore from '../store';
act,
render,
} from '../testUtils';
import { executeThunk } from '../utils';
import { RequestStatus } from '../data/constants';
import { getApiWaffleFlagsUrl } from '../data/api';
Expand All @@ -23,7 +17,6 @@ import {
generateNewPageApiResponse,
getStatusValue,
courseId,
initialState,
} from './factories/mockApiResponses';

import {
Expand All @@ -39,13 +32,7 @@ let store;
ReactDOM.createPortal = jest.fn(node => node);

const renderComponent = () => {
render(
<IntlProvider locale="en">
<AppProvider store={store}>
<CustomPages courseId={courseId} />
</AppProvider>
</IntlProvider>,
);
render(<CustomPages courseId={courseId} />);
};

const mockStore = async (status) => {
Expand All @@ -64,16 +51,9 @@ const mockStore = async (status) => {

describe('CustomPages', () => {
beforeEach(async () => {
initializeMockApp({
authenticatedUser: {
userId: 3,
username: 'abc123',
administrator: false,
roles: [],
},
});
store = initializeStore(initialState);
axiosMock = new MockAdapter(getAuthenticatedHttpClient());
const mocks = initializeMocks();
store = mocks.reduxStore;
axiosMock = mocks.axiosMock;
axiosMock
.onGet(getApiWaffleFlagsUrl(courseId))
.reply(200, {
Expand Down
55 changes: 55 additions & 0 deletions src/grading-settings/grading-scale/react-ranger.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import { renderHook, act } from '@testing-library/react-hooks';

import { useRanger } from './react-ranger';

describe('useRanger Hook', () => {
const mockOnChange = jest.fn();
const mockOnDrag = jest.fn();

const defaultProps = {
values: [20, 80],
min: 0,
max: 100,
stepSize: 10,
onChange: mockOnChange,
onDrag: mockOnDrag,
};

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

it('initializes with correct default properties', () => {
const { result } = renderHook(() => useRanger(defaultProps));

expect(result.current.ticks).toBeDefined();
expect(result.current.segments).toBeDefined();
expect(result.current.handles).toHaveLength(2); // Two handles for two values
expect(result.current.activeHandleIndex).toBeNull();
});

it('calculates ticks based on min, max, and stepSize', () => {
const { result } = renderHook(() => useRanger(defaultProps));

const tickValues = result.current.ticks.map((tick) => tick.value);
expect(tickValues).toEqual([0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100]);
});

it('resets active handle index after interaction', () => {
const { result } = renderHook(() => useRanger(defaultProps));

act(() => {
result.current.handles[0].getHandleProps().onMouseDown({ persist: jest.fn() }, 0);
document.dispatchEvent(new MouseEvent('mouseup'));
});

expect(result.current.activeHandleIndex).toBeNull();
});

it('computes segments based on values', () => {
const { result } = renderHook(() => useRanger(defaultProps));

const segmentValues = result.current.segments.map((segment) => segment.value);
expect(segmentValues).toEqual([20, 80, 100]);
});
});
Loading

0 comments on commit bc8d59b

Please sign in to comment.