diff --git a/src/instructor-toolbar/masquerade-widget/MasqueradeWidget.test.jsx b/src/instructor-toolbar/masquerade-widget/MasqueradeWidget.test.jsx new file mode 100644 index 0000000000..7349858a37 --- /dev/null +++ b/src/instructor-toolbar/masquerade-widget/MasqueradeWidget.test.jsx @@ -0,0 +1,137 @@ +import React from 'react'; +import { getAllByRole } from '@testing-library/dom'; +import { act } from '@testing-library/react'; +import { getConfig } from '@edx/frontend-platform'; +import MockAdapter from 'axios-mock-adapter'; +import { getAuthenticatedHttpClient } from '@edx/frontend-platform/auth'; +import MasqueradeWidget from './MasqueradeWidget'; +import { + render, screen, fireEvent, initializeTestStore, waitFor, logUnhandledRequests, +} from '../../setupTest'; + +const originalConfig = jest.requireActual('@edx/frontend-platform').getConfig(); +jest.mock('@edx/frontend-platform', () => ({ + ...jest.requireActual('@edx/frontend-platform'), + getConfig: jest.fn(), +})); +getConfig.mockImplementation(() => originalConfig); + +describe('Masquerade Widget Dropdown', () => { + let mockData; + let courseware; + let mockResponse; + let axiosMock; + let masqueradeUrl; + const masqueradeOptions = [ + { + name: 'Staff', + role: 'staff', + }, + { + name: 'Specific Student...', + role: 'student', + user_name: '', + }, + { + group_id: 1, + name: 'Audit', + role: 'student', + user_partition_id: 50, + }, + ]; + + beforeAll(async () => { + const store = await initializeTestStore(); + courseware = store.getState().courseware; + axiosMock = new MockAdapter(getAuthenticatedHttpClient()); + masqueradeUrl = `${getConfig().LMS_BASE_URL}/courses/${courseware.courseId}/masquerade`; + mockData = { + courseId: courseware.courseId, + onError: () => {}, + }; + }); + + beforeEach(() => { + mockResponse = { + success: true, + active: { + course_key: courseware.courseId, + group_id: null, + role: 'staff', + user_name: null, + user_partition_id: null, + group_name: null, + }, + available: masqueradeOptions, + }; + axiosMock.reset(); + axiosMock.onGet(masqueradeUrl).reply(200, mockResponse); + logUnhandledRequests(axiosMock); + }); + + it('renders masquerade name correctly', async () => { + render(); + await waitFor(() => expect(axiosMock.history.get).toHaveLength(1)); + expect(screen.getByRole('button')).toHaveTextContent('Staff'); + }); + + masqueradeOptions.forEach((option) => { + it(`marks role ${option.role} as active`, async () => { + const active = { + course_key: courseware.courseId, + group_id: option.group_id ?? null, + role: option.role, + user_name: option.user_name ?? null, + user_partition_id: option.user_partition_id ?? null, + group_name: null, + }; + + mockResponse = { + success: true, + active, + available: masqueradeOptions, + }; + + axiosMock.reset(); + axiosMock.onGet(masqueradeUrl).reply(200, mockResponse); + + const { container } = render(); + const dropdownToggle = container.querySelector('.dropdown-toggle'); + await act(async () => { + await fireEvent.click(dropdownToggle); + }); + const dropdownMenu = container.querySelector('.dropdown-menu'); + getAllByRole(dropdownMenu, 'button', { hidden: true }).forEach(button => { + if (button.textContent === option.name) { + expect(button).toHaveClass('active'); + } else { + expect(button).not.toHaveClass('active'); + } + }); + }); + }); + + it('handles the clicks with toggle', async () => { + const { container } = render(); + await waitFor(() => expect(axiosMock.history.get).toHaveLength(1)); + + const dropdownToggle = container.querySelector('.dropdown-toggle'); + await act(async () => { + await fireEvent.click(dropdownToggle); + }); + const dropdownMenu = container.querySelector('.dropdown-menu'); + const studentOption = getAllByRole(dropdownMenu, 'button', { hidden: true }).filter( + button => (button.textContent === 'Specific Student...'), + )[0]; + await act(async () => { + await fireEvent.click(studentOption); + }); + getAllByRole(dropdownMenu, 'button', { hidden: true }).forEach(button => { + if (button.textContent === 'Specific Student...') { + expect(button).toHaveClass('active'); + } else { + expect(button).not.toHaveClass('active'); + } + }); + }); +}); diff --git a/src/instructor-toolbar/masquerade-widget/MasqueradeWidgetOption.test.jsx b/src/instructor-toolbar/masquerade-widget/MasqueradeWidgetOption.test.jsx new file mode 100644 index 0000000000..4e6dde1476 --- /dev/null +++ b/src/instructor-toolbar/masquerade-widget/MasqueradeWidgetOption.test.jsx @@ -0,0 +1,97 @@ +import React from 'react'; +import { getAllByRole } from '@testing-library/dom'; +import { act } from '@testing-library/react'; +import { getConfig } from '@edx/frontend-platform'; +import MasqueradeWidgetOption from './MasqueradeWidgetOption'; +import { + render, fireEvent, initializeTestStore, +} from '../../setupTest'; + +const originalConfig = jest.requireActual('@edx/frontend-platform').getConfig(); +jest.mock('@edx/frontend-platform', () => ({ + ...jest.requireActual('@edx/frontend-platform'), + getConfig: jest.fn(), +})); +getConfig.mockImplementation(() => originalConfig); + +describe('Masquerade Widget Dropdown', () => { + let courseware; + let mockDataStaff; + let mockDataStudent; + let active; + + beforeAll(async () => { + const store = await initializeTestStore(); + courseware = store.getState().courseware; + active = { + courseKey: courseware.courseId, + groupId: null, + role: 'staff', + userName: null, + userPartitionId: null, + groupName: null, + }; + mockDataStaff = { + groupId: null, + groupName: 'Staff', + key: 'Staff', + role: 'staff', + selected: active, + userName: null, + userPartitionId: null, + userNameInputToggle: () => {}, + onSubmit: () => {}, + }; + mockDataStudent = { + groupId: null, + groupName: 'Specific Student...', + key: 'Specific Student...', + role: 'student', + selected: active, + userName: '', + userPartitionId: null, + userNameInputToggle: () => {}, + onSubmit: () => {}, + }; + Object.defineProperty(global, 'location', { + configurable: true, + value: { reload: jest.fn() }, + }); + }); + + it('renders masquerade active option correctly', async () => { + const { container } = render(); + const button = getAllByRole(container, 'button', { hidden: true })[0]; + expect(button).toHaveTextContent('Staff'); + expect(button).toHaveClass('active'); + }); + + it('renders masquerade inactive option correctly', async () => { + const { container } = render(); + const button = getAllByRole(container, 'button', { hidden: true })[0]; + expect(button).toHaveTextContent('Specific Student...'); + expect(button).not.toHaveClass('active'); + }); + + it('handles the clicks regular option', () => { + const onSubmit = jest.fn().mockImplementation(() => Promise.resolve()); + const { container } = render(); + const button = getAllByRole(container, 'button', { hidden: true })[0]; + act(() => { + fireEvent.click(button); + }); + expect(onSubmit).toHaveBeenCalled(); + }); + + it('handles the clicks student option', () => { + const userNameInputToggle = jest.fn().mockImplementation(() => Promise.resolve()); + const { container } = render( + , + ); + const button = getAllByRole(container, 'button', { hidden: true })[0]; + act(() => { + fireEvent.click(button); + }); + expect(userNameInputToggle).toHaveBeenCalled(); + }); +});