diff --git a/src/components/Admin/CompletedLearnersTable.jsx b/src/components/Admin/CompletedLearnersTable.jsx new file mode 100644 index 0000000000..2842139bfc --- /dev/null +++ b/src/components/Admin/CompletedLearnersTable.jsx @@ -0,0 +1,64 @@ +import React, { useMemo } from 'react'; +import { useIntl } from '@edx/frontend-platform/i18n'; +import { DataTable } from '@openedx/paragon'; +import { useGenericTableData } from './data/hooks'; +import EnterpriseDataApiService from '../../data/services/EnterpriseDataApiService'; +import EmailCell from './EmailCell'; + +const CompletedLearnersTable = (enterpriseId) => { + const intl = useIntl(); + const { + isLoading, + tableData, + fetchTableData, + } = useGenericTableData( + enterpriseId, + 'completed-learners', + EnterpriseDataApiService.fetchCompletedLearners, + useMemo(() => ({ + userEmail: { key: 'user_email' }, + completedCourses: { key: 'completed_courses' }, + }), []), + ); + + return ( + + ); +}; + +export default CompletedLearnersTable; diff --git a/src/components/CompletedLearnersTable/CompletedLearnersTable.test.jsx b/src/components/Admin/CompletedLearnersTable.test.jsx similarity index 72% rename from src/components/CompletedLearnersTable/CompletedLearnersTable.test.jsx rename to src/components/Admin/CompletedLearnersTable.test.jsx index ece4178180..3a79c64fb8 100644 --- a/src/components/CompletedLearnersTable/CompletedLearnersTable.test.jsx +++ b/src/components/Admin/CompletedLearnersTable.test.jsx @@ -6,26 +6,20 @@ import configureMockStore from 'redux-mock-store'; import thunk from 'redux-thunk'; import { Provider } from 'react-redux'; -import CompletedLearnersTable from '.'; +import CompletedLearnersTable from './CompletedLearnersTable'; +import { useGenericTableData } from './data/hooks'; const mockStore = configureMockStore([thunk]); const enterpriseId = 'test-enterprise'; + +jest.mock('./data/hooks/useGenericTableData', () => ( + jest.fn().mockReturnValue({}) +)); + const store = mockStore({ portalConfiguration: { enterpriseId, }, - table: { - 'completed-learners': { - data: { - results: [], - current_page: 1, - num_pages: 1, - }, - ordering: null, - loading: false, - error: null, - }, - }, }); const CompletedLearnersWrapper = props => ( @@ -42,6 +36,15 @@ const CompletedLearnersWrapper = props => ( describe('CompletedLearnersTable', () => { it('renders empty state correctly', () => { + useGenericTableData.mockReturnValue({ + isLoading: false, + tableData: { + results: [], + itemCount: 0, + pageCount: 0, + }, + fetchTableData: jest.fn(), + }); const tree = renderer .create(( diff --git a/src/components/Admin/EmailCell.jsx b/src/components/Admin/EmailCell.jsx new file mode 100644 index 0000000000..cf97e72ef3 --- /dev/null +++ b/src/components/Admin/EmailCell.jsx @@ -0,0 +1,16 @@ +import React from 'react'; +import PropTypes from 'prop-types'; + +const EmailCell = ({ row }) => ( + {row.original.userEmail} +); + +EmailCell.propTypes = { + row: PropTypes.shape({ + original: PropTypes.shape({ + userEmail: PropTypes.string.isRequired, + }).isRequired, + }).isRequired, +}; + +export default EmailCell; diff --git a/src/components/Admin/EmailCell.test.jsx b/src/components/Admin/EmailCell.test.jsx new file mode 100644 index 0000000000..f2c69eda0d --- /dev/null +++ b/src/components/Admin/EmailCell.test.jsx @@ -0,0 +1,42 @@ +import React from 'react'; +import { render, screen } from '@testing-library/react'; +import '@testing-library/jest-dom'; +import EmailCell from './EmailCell'; + +describe('Email Component', () => { + it('should display the user email and suppress highlighting', () => { + const mockRow = { + original: { + userEmail: 'test@example.com', + }, + }; + + render( + , + ); + + // Assert that the email is rendered correctly + const emailElement = screen.getByText('test@example.com'); + expect(emailElement).toBeInTheDocument(); + + // Assert that data-hj-suppress is present to suppress highlighting + expect(emailElement).toHaveAttribute('data-hj-suppress'); + }); + + it('should throw a prop-type warning if the email is not provided', () => { + const consoleSpy = jest.spyOn(console, 'error').mockImplementation(() => {}); + + const invalidRow = { + original: {}, + }; + + // Render with invalid props + render(); + + // Assert that a prop-types error has been logged + expect(consoleSpy).toHaveBeenCalled(); + + // Clean up the spy + consoleSpy.mockRestore(); + }); +}); diff --git a/src/components/Admin/__snapshots__/Admin.test.jsx.snap b/src/components/Admin/__snapshots__/Admin.test.jsx.snap index 93e82b2841..f7f4b78f98 100644 --- a/src/components/Admin/__snapshots__/Admin.test.jsx.snap +++ b/src/components/Admin/__snapshots__/Admin.test.jsx.snap @@ -1621,7 +1621,7 @@ exports[` renders correctly with dashboard analytics data renders # cou > @@ -1630,7 +1630,7 @@ exports[` renders correctly with dashboard analytics data renders # cou > renders correctly with dashboard analytics data renders # cou >