forked from openedx/frontend-app-learning
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
fix: masquerade dropdown not showing current selection (#30)
* feat: remove child components from state and use data instead (cherry picked from commit 2d9807e) * fix: change active selection based on user input (cherry picked from commit d72eb23) * test: add test cases (cherry picked from commit 59d9db5) (cherry picked from commit 702c962)
- Loading branch information
1 parent
808ae55
commit 3a8c0dd
Showing
4 changed files
with
265 additions
and
22 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
137 changes: 137 additions & 0 deletions
137
src/instructor-toolbar/masquerade-widget/MasqueradeWidget.test.jsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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(<MasqueradeWidget {...mockData} />); | ||
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(<MasqueradeWidget {...mockData} />); | ||
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(<MasqueradeWidget {...mockData} />); | ||
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'); | ||
} | ||
}); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
97 changes: 97 additions & 0 deletions
97
src/instructor-toolbar/masquerade-widget/MasqueradeWidgetOption.test.jsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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(<MasqueradeWidgetOption {...mockDataStaff} />); | ||
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(<MasqueradeWidgetOption {...mockDataStudent} />); | ||
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(<MasqueradeWidgetOption {...mockDataStaff} onSubmit={onSubmit} />); | ||
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( | ||
<MasqueradeWidgetOption {...mockDataStudent} userNameInputToggle={userNameInputToggle} />, | ||
); | ||
const button = getAllByRole(container, 'button', { hidden: true })[0]; | ||
act(() => { | ||
fireEvent.click(button); | ||
}); | ||
expect(userNameInputToggle).toHaveBeenCalled(); | ||
}); | ||
}); |