generated from openedx/frontend-template-application
-
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.
- Loading branch information
Showing
15 changed files
with
484 additions
and
8 deletions.
There are no files selected for viewing
57 changes: 57 additions & 0 deletions
57
src/features/Instructors/InstructorsPage/_test_/index.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,57 @@ | ||
import React from 'react'; | ||
import axios from 'axios'; | ||
import { | ||
render, | ||
waitFor, | ||
} from '@testing-library/react'; | ||
import InstructorsPage from 'features/Instructors/InstructorsPage'; | ||
import '@testing-library/jest-dom/extend-expect'; | ||
|
||
jest.mock('axios'); | ||
|
||
jest.mock('@edx/frontend-platform/logging', () => ({ | ||
logError: jest.fn(), | ||
})); | ||
|
||
const mockResponse = { | ||
data: { | ||
results: [ | ||
{ | ||
instructorUsername: 'Instructor1', | ||
instructorName: 'Instructor 1', | ||
instructorEmail: '[email protected]', | ||
ccxId: 'CCX1', | ||
ccxName: 'CCX 1', | ||
}, | ||
{ | ||
instructorUsername: 'Instructor2', | ||
instructorName: 'Instructor 2', | ||
instructorEmail: '[email protected]', | ||
ccxId: 'CCX2', | ||
ccxName: 'CCX 2', | ||
}, | ||
], | ||
count: 2, | ||
num_pages: 1, | ||
current_page: 1, | ||
}, | ||
}; | ||
|
||
describe('InstructorPage', () => { | ||
test('render instructor page', () => { | ||
axios.get.mockResolvedValue(mockResponse); | ||
|
||
const component = render(<InstructorsPage />); | ||
|
||
waitFor(() => { | ||
expect(component.container).toHaveTextContent('Instructor1'); | ||
expect(component.container).toHaveTextContent('Instructor2'); | ||
expect(component.container).toHaveTextContent('Instructor 1'); | ||
expect(component.container).toHaveTextContent('Instructor 2'); | ||
expect(component.container).toHaveTextContent('[email protected]'); | ||
expect(component.container).toHaveTextContent('[email protected]'); | ||
expect(component.container).toHaveTextContent('CCX1'); | ||
expect(component.container).toHaveTextContent('CCX 2'); | ||
}); | ||
}); | ||
}); |
70 changes: 70 additions & 0 deletions
70
src/features/Instructors/InstructorsPage/_test_/reducer.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,70 @@ | ||
import { | ||
FETCH_INSTRUCTOR_DATA_REQUEST, | ||
FETCH_INSTRUCTOR_DATA_SUCCESS, | ||
FETCH_INSTRUCTOR_DATA_FAILURE, | ||
UPDATE_CURRENT_PAGE, | ||
} from 'features/Instructors/actionTypes'; | ||
import { RequestStatus } from 'features/constants'; | ||
import reducer from 'features/Instructors/InstructorsPage/reducer'; | ||
|
||
describe('Instructor page reducers', () => { | ||
const initialState = { | ||
data: [], | ||
error: null, | ||
currentPage: 1, | ||
numPages: 0, | ||
}; | ||
|
||
test('should handle FETCH_INSTRUCTOR_DATA_REQUEST', () => { | ||
const state = { | ||
...initialState, | ||
status: RequestStatus.LOADING, | ||
}; | ||
const action = { | ||
type: FETCH_INSTRUCTOR_DATA_REQUEST, | ||
}; | ||
expect(reducer(state, action)).toEqual(state); | ||
}); | ||
|
||
test('should handle FFETCH_INSTRUCTOR_DATA_SUCCESS', () => { | ||
const state = { | ||
...initialState, | ||
status: RequestStatus.SUCCESS, | ||
count: 0, | ||
}; | ||
const action = { | ||
type: FETCH_INSTRUCTOR_DATA_SUCCESS, | ||
payload: { | ||
results: [], | ||
count: 0, | ||
numPages: 0, | ||
}, | ||
}; | ||
expect(reducer(state, action)).toEqual(state); | ||
}); | ||
|
||
test('should handle FETCH_INSTRUCTOR_DATA_FAILURE', () => { | ||
const state = { | ||
...initialState, | ||
status: RequestStatus.ERROR, | ||
error: '', | ||
}; | ||
const action = { | ||
type: FETCH_INSTRUCTOR_DATA_FAILURE, | ||
payload: '', | ||
}; | ||
expect(reducer(state, action)).toEqual(state); | ||
}); | ||
|
||
test('should handle UPDATE_CURRENT_PAGE', () => { | ||
const state = { | ||
...initialState, | ||
currentPage: 1, | ||
}; | ||
const action = { | ||
type: UPDATE_CURRENT_PAGE, | ||
payload: 1, | ||
}; | ||
expect(reducer(state, action)).toEqual(state); | ||
}); | ||
}); |
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,75 @@ | ||
import React, { useEffect, useState, useReducer } from 'react'; | ||
import { camelCaseObject } from '@edx/frontend-platform'; | ||
|
||
import { logError } from '@edx/frontend-platform/logging'; | ||
import Container from '@edx/paragon/dist/Container'; | ||
import { | ||
Pagination, | ||
} from '@edx/paragon'; | ||
import InstructorsTable from 'features/Instructors/InstructorsTable'; | ||
|
||
import { getInstructorData } from 'features/Instructors/data/api'; | ||
import { | ||
FETCH_INSTRUCTOR_DATA_REQUEST, | ||
FETCH_INSTRUCTOR_DATA_SUCCESS, | ||
FETCH_INSTRUCTOR_DATA_FAILURE, | ||
UPDATE_CURRENT_PAGE, | ||
} from 'features/Instructors/actionTypes'; | ||
import { RequestStatus } from 'features/constants'; | ||
import reducer from './reducer'; | ||
|
||
const initialState = { | ||
data: [], | ||
status: RequestStatus.SUCCESS, | ||
error: null, | ||
currentPage: 1, | ||
numPages: 0, | ||
}; | ||
|
||
const InstructorsPage = () => { | ||
const [state, dispatch] = useReducer(reducer, initialState); | ||
const [currentPage, setCurrentPage] = useState(1); | ||
|
||
const fetchData = async () => { | ||
dispatch({ type: FETCH_INSTRUCTOR_DATA_REQUEST }); | ||
|
||
try { | ||
const response = camelCaseObject(await getInstructorData(currentPage)); | ||
dispatch({ type: FETCH_INSTRUCTOR_DATA_SUCCESS, payload: response.data }); | ||
} catch (error) { | ||
dispatch({ type: FETCH_INSTRUCTOR_DATA_FAILURE, payload: error }); | ||
logError(error); | ||
} | ||
}; | ||
|
||
useEffect(() => { | ||
fetchData(); // eslint-disable-next-line react-hooks/exhaustive-deps | ||
}, [currentPage]); | ||
|
||
const handlePagination = (targetPage) => { | ||
setCurrentPage(targetPage); | ||
dispatch({ type: UPDATE_CURRENT_PAGE, payload: targetPage }); | ||
fetchData(); | ||
}; | ||
|
||
return ( | ||
<Container size="xl" className="px-3"> | ||
<h2>Instructors</h2> | ||
<InstructorsTable | ||
data={state.data} | ||
count={state.count} | ||
/> | ||
<Pagination | ||
paginationLabel="paginationNavigation" | ||
pageCount={state.numPages} | ||
currentPage={currentPage} | ||
onPageSelect={handlePagination} | ||
variant="reduced" | ||
className="mx-auto" | ||
size="small" | ||
/> | ||
</Container> | ||
); | ||
}; | ||
|
||
export default InstructorsPage; |
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,39 @@ | ||
import { | ||
FETCH_INSTRUCTOR_DATA_REQUEST, | ||
FETCH_INSTRUCTOR_DATA_SUCCESS, | ||
FETCH_INSTRUCTOR_DATA_FAILURE, | ||
UPDATE_CURRENT_PAGE, | ||
} from 'features/Instructors/actionTypes'; | ||
import { RequestStatus } from 'features/constants'; | ||
|
||
const reducer = (state, action) => { | ||
switch (action.type) { | ||
case FETCH_INSTRUCTOR_DATA_REQUEST: | ||
return { ...state, status: RequestStatus.LOADING }; | ||
case FETCH_INSTRUCTOR_DATA_SUCCESS: { | ||
const { results, count, numPages } = action.payload; | ||
return { | ||
...state, | ||
status: RequestStatus.SUCCESS, | ||
data: results, | ||
numPages, | ||
count, | ||
}; | ||
} | ||
case FETCH_INSTRUCTOR_DATA_FAILURE: | ||
return { | ||
...state, | ||
status: RequestStatus.ERROR, | ||
error: action.payload, | ||
}; | ||
case UPDATE_CURRENT_PAGE: | ||
return { | ||
...state, | ||
currentPage: action.payload, | ||
}; | ||
default: | ||
return state; | ||
} | ||
}; | ||
|
||
export default reducer; |
31 changes: 31 additions & 0 deletions
31
src/features/Instructors/InstructorsTable/_test_/columns.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,31 @@ | ||
import { columns } from 'features/Instructors/InstructorsTable/columns'; | ||
|
||
describe('columns', () => { | ||
test('returns an array of columns with correct properties', () => { | ||
expect(columns).toBeInstanceOf(Array); | ||
expect(columns).toHaveLength(5); | ||
|
||
const [ | ||
usernameColumn, | ||
nameColumn, | ||
emailColumn, | ||
courseNameColumn, | ||
courseKeyColumn, | ||
] = columns; | ||
|
||
expect(usernameColumn).toHaveProperty('Header', 'User Name'); | ||
expect(usernameColumn).toHaveProperty('accessor', 'instructorUsername'); | ||
|
||
expect(nameColumn).toHaveProperty('Header', 'Name'); | ||
expect(nameColumn).toHaveProperty('accessor', 'instructorName'); | ||
|
||
expect(emailColumn).toHaveProperty('Header', 'Email'); | ||
expect(emailColumn).toHaveProperty('accessor', 'instructorEmail'); | ||
|
||
expect(courseNameColumn).toHaveProperty('Header', 'Course key'); | ||
expect(courseNameColumn).toHaveProperty('accessor', 'ccxId'); | ||
|
||
expect(courseKeyColumn).toHaveProperty('Header', 'Course name'); | ||
expect(courseKeyColumn).toHaveProperty('accessor', 'ccxName'); | ||
}); | ||
}); |
49 changes: 49 additions & 0 deletions
49
src/features/Instructors/InstructorsTable/_test_/index.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,49 @@ | ||
import React from 'react'; | ||
import '@testing-library/jest-dom'; | ||
import { render, screen } from '@testing-library/react'; | ||
|
||
import InstructorsTable from 'features/Instructors/InstructorsTable'; | ||
import { columns } from 'features/Instructors/InstructorsTable/columns'; | ||
|
||
describe('Instructor Table', () => { | ||
test('renders InstructorsTable without data', () => { | ||
render(<InstructorsTable data={[]} count={0} columns={[]} />); | ||
const emptyTableText = screen.getByText('No instructors found.'); | ||
expect(emptyTableText).toBeInTheDocument(); | ||
}); | ||
|
||
test('renders InstructorsTable with data', () => { | ||
const data = [ | ||
{ | ||
instructorUsername: 'Instructor1', | ||
instructorName: 'Instructor 1', | ||
instructorEmail: '[email protected]', | ||
ccxId: 'CCX1', | ||
ccxName: 'CCX 1', | ||
}, | ||
{ | ||
instructorUsername: 'Instructor2', | ||
instructorName: 'Instructor 2', | ||
instructorEmail: '[email protected]', | ||
ccxId: 'CCX2', | ||
ccxName: 'CCX 2', | ||
}, | ||
]; | ||
|
||
const component = render( | ||
<InstructorsTable data={data} count={data.length} columns={columns} />, | ||
); | ||
|
||
// Check if the table rows are present | ||
const tableRows = screen.getAllByRole('row'); | ||
expect(tableRows).toHaveLength(data.length + 1); // Data rows + 1 header row | ||
expect(component.container).toHaveTextContent('Instructor1'); | ||
expect(component.container).toHaveTextContent('Instructor2'); | ||
expect(component.container).toHaveTextContent('Instructor 1'); | ||
expect(component.container).toHaveTextContent('Instructor 2'); | ||
expect(component.container).toHaveTextContent('[email protected]'); | ||
expect(component.container).toHaveTextContent('[email protected]'); | ||
expect(component.container).toHaveTextContent('CCX 1'); | ||
expect(component.container).toHaveTextContent('CCX 2'); | ||
}); | ||
}); |
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,26 @@ | ||
const columns = [ | ||
{ | ||
Header: 'User Name', | ||
accessor: 'instructorUsername', | ||
}, | ||
{ | ||
Header: 'Name', | ||
accessor: 'instructorName', | ||
}, | ||
{ | ||
Header: 'Email', | ||
accessor: 'instructorEmail', | ||
}, | ||
{ | ||
Header: 'Course key', | ||
accessor: 'ccxId', | ||
}, | ||
{ | ||
Header: 'Course name', | ||
accessor: 'ccxName', | ||
}, | ||
]; | ||
|
||
const hideColumns = { hiddenColumns: ['ccxId'] }; | ||
|
||
export { hideColumns, columns }; |
Oops, something went wrong.