diff --git a/studies/tasks.py b/studies/tasks.py index af5eb2728..aae154c13 100644 --- a/studies/tasks.py +++ b/studies/tasks.py @@ -74,7 +74,9 @@ FROM studies_response sr INNER JOIN accounts_child ac on sr.child_id = ac.id INNER JOIN studies_studytype sst on sr.study_type_id = sst.id - WHERE (sr.completed_consent_frame = true AND sst.id = 1) + -- Internal studies (EFP id 1, jsPsych id 3) count as participation once the + -- child has completed the consent frame; external studies (id 2) always count. + WHERE (sr.completed_consent_frame = true AND sst.id IN (1, 3)) OR (sst.id = 2) ) ), diff --git a/studies/tests.py b/studies/tests.py index 2aa712867..37fd48467 100644 --- a/studies/tests.py +++ b/studies/tests.py @@ -664,6 +664,72 @@ def test_potential_message_targets_external(self): # Check that the message target no longer has this child for this study self.assertNotIn(message_target, potential_message_targets()) + def _active_jspsych_study_target(self): + """Set up an active, public jsPsych study with an eligible user/child.""" + user = G(User, is_active=True) + child = G( + Child, + user=user, + birthday=date.today() - timedelta(days=365), + ) + study = G( + Study, + name="jsPsych Study", + study_type=StudyType.get_jspsych(), + image=SimpleUploadedFile("fake_image.png", b"", content_type="image/png"), + public=True, + max_age_years=2, + criteria_expression="", + ) + study.state = "active" + study.save() + + # Double check this is a jsPsych study + self.assertTrue(study.study_type.is_jspsych) + + return ( + child, + study, + MessageTarget( + user_id=user.pk, + child_id=child.pk, + study_id=study.pk, + ), + ) + + def test_potential_message_targets_jspsych(self): + child, study, message_target = self._active_jspsych_study_target() + + # Check that user/child are potential message targets in new jsPsych study + self.assertIn(message_target, potential_message_targets()) + + # Add response from this child for this study, past the consent trial + G( + Response, + study=study, + study_type=study.study_type, + child=child, + completed_consent_frame=True, + ) + + # Check that the message target no longer has this child for this study + self.assertNotIn(message_target, potential_message_targets()) + + def test_potential_message_targets_jspsych_without_consent(self): + child, study, message_target = self._active_jspsych_study_target() + + # A response that never got past the consent trial does not count as + # participation, so the child should still be a potential message target. + G( + Response, + study=study, + study_type=study.study_type, + child=child, + completed_consent_frame=False, + ) + + self.assertIn(message_target, potential_message_targets()) + def test_validated_skips_none_user(self): result = list(_validated([(None, [])])) self.assertEqual(result, [])