diff --git a/backend/experiment/rules/base.py b/backend/experiment/rules/base.py index a11e4fc22..feffaa402 100644 --- a/backend/experiment/rules/base.py +++ b/backend/experiment/rules/base.py @@ -5,12 +5,12 @@ from django.conf import settings from experiment.actions import Final, Form, Trial -from experiment.models import Experiment from section.models import Playlist from experiment.questions.demographics import DEMOGRAPHICS from experiment.questions.goldsmiths import MSI_OTHER from experiment.questions.utils import question_by_key, unanswered_questions from result.score import SCORING_RULES +from session.models import Session from experiment.questions import get_questions_from_keys @@ -52,7 +52,11 @@ def calculate_score(self, result, data): if scoring_rule: return scoring_rule(result, data) return None - + + def get_play_again_url(self, session: Session): + participant_id_url_param = f'?participant_id={session.participant.participant_id_url}' if session.participant.participant_id_url else "" + return f'/{session.experiment.slug}{participant_id_url_param}' + def calculate_intermediate_score(self, session, result): """ process result data during a trial (i.e., between next_round calls) return score diff --git a/backend/experiment/rules/hooked.py b/backend/experiment/rules/hooked.py index dc97fd4bf..aa0c9ace4 100644 --- a/backend/experiment/rules/hooked.py +++ b/backend/experiment/rules/hooked.py @@ -111,8 +111,10 @@ def next_round(self, session): social=self.social_media_info( session.experiment, total_score), show_profile_link=True, - button={'text': _('Play again'), 'link': '{}/{}'.format( - settings.CORS_ORIGIN_WHITELIST[0], session.experiment.slug)} + button={ + 'text': _('Play again'), + 'link': self.get_play_again_url(session), + } ) ] diff --git a/backend/experiment/rules/matching_pairs.py b/backend/experiment/rules/matching_pairs.py index 76b8de1e9..739601d2e 100644 --- a/backend/experiment/rules/matching_pairs.py +++ b/backend/experiment/rules/matching_pairs.py @@ -81,7 +81,7 @@ def next_round(self, session): final_text='Can you score higher than your friends and family? Share and let them try!', button={ 'text': 'Play again', - 'link': f'/{session.experiment.slug}' + 'link': self.get_play_again_url(session) }, rank=self.rank(session, exclude_unfinished=False), social=social_info, diff --git a/backend/experiment/rules/tests/test_base.py b/backend/experiment/rules/tests/test_base.py index 6fbcdf164..1e96d1f2e 100644 --- a/backend/experiment/rules/tests/test_base.py +++ b/backend/experiment/rules/tests/test_base.py @@ -1,6 +1,8 @@ from django.test import TestCase from django.conf import settings from experiment.models import Experiment +from session.models import Session +from participant.models import Participant from section.models import Playlist from ..base import Base @@ -29,6 +31,35 @@ def test_social_media_info(self): self.assertNotIn(social_media_info['url'], '//') self.assertEqual(social_media_info['hashtags'], ['music-lab', 'amsterdammusiclab', 'citizenscience']) + def test_get_play_again_url(self): + experiment = Experiment.objects.create( + name='Music Lab', + slug='music-lab', + ) + session = Session.objects.create( + experiment=experiment, + participant=Participant.objects.create(), + ) + base = Base() + play_again_url = base.get_play_again_url(session) + self.assertEqual(play_again_url, '/music-lab') + + def test_get_play_again_url_with_participant_id(self): + experiment = Experiment.objects.create( + name='Music Lab', + slug='music-lab', + ) + participant = Participant.objects.create( + participant_id_url='42', + ) + session = Session.objects.create( + experiment=experiment, + participant=participant, + ) + base = Base() + play_again_url = base.get_play_again_url(session) + self.assertEqual(play_again_url, '/music-lab?participant_id=42') + def test_validate_playlist(self): base = Base() playlist = None diff --git a/backend/experiment/rules/thats_my_song.py b/backend/experiment/rules/thats_my_song.py index ab92ce0ba..59a4285a9 100644 --- a/backend/experiment/rules/thats_my_song.py +++ b/backend/experiment/rules/thats_my_song.py @@ -80,8 +80,10 @@ def next_round(self, session): rank=self.rank(session), social=social_info, show_profile_link=True, - button={'text': _('Play again'), 'link': '{}/{}{}'.format(settings.CORS_ORIGIN_WHITELIST[0], session.experiment.slug, - '?participant_id='+session.participant.participant_id_url if session.participant.participant_id_url else '')}, + button={ + 'text': _('Play again'), + 'link': self.get_play_again_url(session) + }, logo={'image': '/images/vumc_mcl_logo.png', 'link':'https://www.vumc.org/music-cognition-lab/welcome'} ) ] @@ -153,4 +155,4 @@ def next_round(self, session): actions.append( self.next_heard_before_action(session)) - return actions \ No newline at end of file + return actions diff --git a/backend/experiment/rules/visual_matching_pairs.py b/backend/experiment/rules/visual_matching_pairs.py index 23c355429..da9c4d69d 100644 --- a/backend/experiment/rules/visual_matching_pairs.py +++ b/backend/experiment/rules/visual_matching_pairs.py @@ -55,7 +55,7 @@ def first_round(self, experiment): playlist, explainer ] - + def next_round(self, session): if session.rounds_passed() < 1: trials = self.get_questionnaire(session) @@ -80,6 +80,7 @@ def next_round(self, session): final_text='Can you score higher than your friends and family? Share and let them try!', button={ 'text': 'Play again', + 'link': self.get_play_again_url(session) }, rank=self.rank(session, exclude_unfinished=False), social=social_info, @@ -88,7 +89,7 @@ def next_round(self, session): cont = self.get_visual_matching_pairs_trial(session) return [score, cont] - + def get_visual_matching_pairs_trial(self, session): player_sections = list(session.playlist.section_set.filter(tag__contains='vmp')) @@ -112,5 +113,5 @@ def calculate_score(self, result, data): for m in moves: m['filename'] = str(Section.objects.get(pk=m.get('selectedSection')).filename) score = data.get('result').get('score') - - return score \ No newline at end of file + + return score diff --git a/frontend/src/components/Experiment/Experiment.jsx b/frontend/src/components/Experiment/Experiment.jsx index 4a3cb5f99..cdcf64b62 100644 --- a/frontend/src/components/Experiment/Experiment.jsx +++ b/frontend/src/components/Experiment/Experiment.jsx @@ -93,7 +93,7 @@ const Experiment = ({ match }) => { }; // trigger next action from next_round array, or call session/next_round - const onNext = async (doBreak) => { + const onNext = async (doBreak = false) => { if (!doBreak && actions.length) { updateActions(actions); } else { diff --git a/frontend/src/components/Final/Final.jsx b/frontend/src/components/Final/Final.jsx index f8da6e60f..43996aa11 100644 --- a/frontend/src/components/Final/Final.jsx +++ b/frontend/src/components/Final/Final.jsx @@ -1,5 +1,5 @@ import React, { useState, useEffect, useRef } from "react"; -import { Link, withRouter } from "react-router-dom"; +import { withRouter } from "react-router-dom"; import Rank from "../Rank/Rank"; import Social from "../Social/Social"; @@ -9,6 +9,7 @@ import { finalizeSession } from "../../API"; import useBoundStore from "../../util/stores"; import ParticipantLink from "../ParticipantLink/ParticipantLink"; import UserFeedback from "../UserFeedback/UserFeedback"; +import FinalButton from "./FinalButton"; // Final is an experiment view that shows the final scores of the experiment // It can only be the last view of an experiment @@ -65,9 +66,10 @@ const Final = ({ experiment, participant, score, final_text, action_texts, butto {button && (
Please contact us at info@example.com if you have any questions.
', + '