diff --git a/frontend/package.json b/frontend/package.json index 14303c68d..c123a94b7 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -87,6 +87,7 @@ "eslint": "^8.54.0", "eslint-config-react-app": "^7.0.1", "eslint-plugin-storybook": "^0.6.15", + "history": "^5.3.0", "prop-types": "15.8.1", "storybook": "7.6.6", "webpack": "5.89.0" diff --git a/frontend/src/components/Final/Final.js b/frontend/src/components/Final/Final.js index e3357f35a..fd5e39ef4 100644 --- a/frontend/src/components/Final/Final.js +++ b/frontend/src/components/Final/Final.js @@ -11,9 +11,9 @@ import UserFeedback from "../UserFeedback/UserFeedback"; // Final is an experiment view that shows the final scores of the experiment // It can only be the last view of an experiment -const Final= ({ experiment, participant, session, score, final_text, action_texts, button, - onNext, history, show_participant_link, participant_id_only, - show_profile_link, social, feedback_info, points, rank, logo }) => { +const Final = ({ experiment, participant, session, score, final_text, action_texts, button, + onNext, history, show_participant_link, participant_id_only, + show_profile_link, social, feedback_info, points, rank, logo }) => { const [showScore, setShowScore] = useState(0); // Use a ref to prevent doing multiple increments @@ -46,17 +46,17 @@ const Final= ({ experiment, participant, session, score, final_text, action_text }; }, [score, showScore]); - const finalize = () => { + useEffect(() => { finalizeSession({ session, participant }); - } + }, [session, participant]); return (
{rank && ( -
- -

{showScore} {points}

-
+
+ +

{showScore} {points}

+
)}
@@ -85,10 +85,9 @@ const Final= ({ experiment, participant, session, score, final_text, action_text {action_texts.all_experiments}
{ - history.push(URLS.profile); - }} + onClick={() => history.push(URLS.profile)} > {action_texts.profile}
diff --git a/frontend/src/components/Final/Final.test.js b/frontend/src/components/Final/Final.test.js new file mode 100644 index 000000000..2aeeb79eb --- /dev/null +++ b/frontend/src/components/Final/Final.test.js @@ -0,0 +1,116 @@ +import React from 'react'; +import { render, screen, fireEvent, waitFor } from '@testing-library/react'; +import { BrowserRouter, Router } from 'react-router-dom'; +import { createMemoryHistory } from 'history' + +import Final from './Final'; // Adjust the import path as necessary + + +jest.mock('../../API', () => ({ + finalizeSession: jest.fn(), +})); + +jest.mock('../../config', () => ({ + URLS: { + AMLHome: '/aml', + profile: '/profile', + }, +})); + +describe('Final Component', () => { + it('renders correctly with given props', () => { + render( + + + + ); + + expect(screen.getByText(/Final Text/i)).toBeInTheDocument(); + expect(screen.getByTestId('score')).toBeInTheDocument(); // Adjust based on how you display points + }); + + it('calls onNext prop when button is clicked', async () => { + const onNextMock = jest.fn(); + render( + + + + ); + + fireEvent.click(screen.getByText('Next')); + await waitFor(() => { + expect(onNextMock).toHaveBeenCalled(); + }); + }); + + it('does not render rank and social components when props are not provided', () => { + render( + + + + ); + + expect(screen.queryByText('Rank')).not.toBeInTheDocument(); + expect(screen.queryByText('Social')).not.toBeInTheDocument(); + }); + + it('navigates to profile page when profile link is clicked', async () => { + + const history = createMemoryHistory(); + + const mockActionTexts = { + all_experiments: 'All Experiments', + profile: 'Profile', + }; + + render( + + + + ); + + const profileLink = screen.getByTestId('profile-link'); + + expect(profileLink).toBeInTheDocument(); + + expect(history.location.pathname).toBe('/'); + + fireEvent.click(profileLink) + + expect(history.location.pathname).toBe('/profile'); + + }); + + it('calls finalizeSession with correct arguments', () => { + const { finalizeSession } = require('../../API'); + render( + + + + ); + + expect(finalizeSession).toHaveBeenCalledWith({ session: 'session-id', participant: 'participant-id' }); + }); +}); diff --git a/frontend/yarn.lock b/frontend/yarn.lock index 9d5da4a38..3ccdcea89 100644 --- a/frontend/yarn.lock +++ b/frontend/yarn.lock @@ -2862,6 +2862,15 @@ __metadata: languageName: node linkType: hard +"@babel/runtime@npm:^7.7.6": + version: 7.23.7 + resolution: "@babel/runtime@npm:7.23.7" + dependencies: + regenerator-runtime: "npm:^0.14.0" + checksum: 3e304133ee55b0750e03e53cb4efb47fb2bdcdb5795f85bbffa10595196c34b9be60eb65bd6d833c87f49fc827f0365f86f95f51d85b188004d3128bb5129c93 + languageName: node + linkType: hard + "@babel/template@npm:^7.22.15": version: 7.22.15 resolution: "@babel/template@npm:7.22.15" @@ -7374,6 +7383,7 @@ __metadata: eslint-config-react-app: "npm:^7.0.1" eslint-plugin-storybook: "npm:^0.6.15" file-saver: "npm:^2.0.5" + history: "npm:^5.3.0" next-share: "npm:0.25.0" prop-types: "npm:15.8.1" qs: "npm:^6.10.3" @@ -11643,6 +11653,15 @@ __metadata: languageName: node linkType: hard +"history@npm:^5.3.0": + version: 5.3.0 + resolution: "history@npm:5.3.0" + dependencies: + "@babel/runtime": "npm:^7.7.6" + checksum: 812ec839386222d6437bd78d9f05db32e47d105ada0ad8834b32626919dd2fee7a10001bc489510f93a8069d02f118214bd8d42a82f7cf9daf8e84fbcbbb2016 + languageName: node + linkType: hard + "hoist-non-react-statics@npm:^3.1.0, hoist-non-react-statics@npm:^3.3.1, hoist-non-react-statics@npm:^3.3.2": version: 3.3.2 resolution: "hoist-non-react-statics@npm:3.3.2"