def test_process_rescheduling_with_wrong_datetime_raises_error(self): """ Tests that error is raised if datetime in interview_rescheduled event does not match info in Acuity """ self.aa1.ddb_dump(update_allowed=True) # store original appointment in ddb test_eb_event = copy.deepcopy(test_data.TEST_INTERVIEW_RESCHEDULED_EB_EVENT) test_eb_event["detail"]["appointment_datetime"] = "2025-11-09T12:15:00+0000" if test_tools.tests_running_on_aws(): result = test_tools.test_eb_request( local_method=views.interview_rescheduled, aws_eb_event=test_eb_event, aws_processing_delay=12, ) self.assertEqual( HTTPStatus.OK, result["ResponseMetadata"]["HTTPStatusCode"] ) notifications = self.ddb_client.scan( table_name=self.notifications_table, table_name_verbatim=True, ) self.assertEqual(0, len(notifications)) else: with self.assertRaises(AssertionError) as context: test_tools.test_eb_request( local_method=views.interview_rescheduled, aws_eb_event=test_eb_event, aws_processing_delay=12, ) err = context.exception err_msg = err.args[0] self.assertIn( "Event datetime (2025-11-09T12:15:00+0000) does not match data in Acuity (2025-06-30T10:15:00+0100)", err_msg, )
def test_process_cancellation_before_booking_raises_error(self): test_eb_event = copy.deepcopy(test_data.TEST_INTERVIEW_CANCELLED_EB_EVENT) if test_tools.tests_running_on_aws(): result = test_tools.test_eb_request( local_method=views.interview_cancelled, aws_eb_event=test_eb_event, aws_processing_delay=12, ) self.assertEqual( HTTPStatus.OK, result["ResponseMetadata"]["HTTPStatusCode"] ) notifications = self.ddb_client.scan( table_name=self.notifications_table, table_name_verbatim=True, ) self.assertEqual(0, len(notifications)) else: with self.assertRaises(utils.ObjectDoesNotExistError) as context: test_tools.test_eb_request( local_method=views.interview_rescheduled, aws_eb_event=test_eb_event, aws_processing_delay=12, ) err = context.exception err_msg = err.args[0] self.assertIn( "Original booking of appointment 399682887 not found in Dynamodb", err_msg, )
def test_user_task_url_update_ok(self): test_tools.test_eb_request( local_method=ut.redirect_to_user_interview_task, aws_eb_event=TEST_USER_INTERVIEW_TASK_EB_EVENT, aws_processing_delay=1, ) user_task = ut.get_user_task("d4a47805-fbec-4e43-938c-94af7214326d")[0] self.assertEqual( f"https://{utils.get_environment_name()}-video.thiscovery.org?response_id=SV_b8jGMAQJjUfsIVU-R_27PS3xFkIH36j29", user_task.get("user_task_url"), )
def test_process_booking_no_notifications_ok(self): test_eb_event = copy.deepcopy(test_data.TEST_INTERVIEW_BOOKED_EB_EVENT) test_eb_event["detail"] = test_data.eb_event_detail_from_acuity_info( test_data.appointments["views3"]["acuity_info"] ) pprint(test_eb_event) result = test_tools.test_eb_request( local_method=views.interview_booked, aws_eb_event=test_eb_event, aws_processing_delay=12, ) if test_tools.tests_running_on_aws(): self.assertEqual( HTTPStatus.OK, result["ResponseMetadata"]["HTTPStatusCode"] ) expected_appointment = test_eb_event["detail"] self.check_dynamodb_appointment(expected_appointment=expected_appointment) # check notifications that were created in notifications table notifications = self.ddb_client.scan( table_name=self.notifications_table, table_name_verbatim=True, ) self.assertEqual(0, len(notifications)) else: ( storing_result, participant_and_researchers_notification_results, ) = result self.assertEqual( HTTPStatus.OK, storing_result["ResponseMetadata"]["HTTPStatusCode"] ) self.assertIsNone(participant_and_researchers_notification_results)
def test_user_consent_event_handler_email_instead_of_ids_ok(self): self.clear_consent_data_table() self.clear_notifications_table() consent_event = copy.deepcopy(USER_CONSENT_EB_EVENT) del consent_event["detail"]["anon_user_task_id"] del consent_event["detail"]["anon_project_specific_user_id"] consent_event["detail"]["to_recipient_email"] = secrets.TESTER_EMAIL consent_event["detail"]["project_short_name"] = "Consent project" result = test_utils.test_eb_request( local_method=consent.user_consent, aws_eb_event=consent_event, aws_processing_delay=10, ) if test_utils.tests_running_on_aws(): self.assertEqual(HTTPStatus.OK, result["ResponseMetadata"]["HTTPStatusCode"]) else: self.assertEqual(HTTPStatus.OK, result["statusCode"]) body = json.loads(result["body"]) self.assertEqual("aborted", body["store_result"]) self.assertEqual(HTTPStatus.NO_CONTENT, body["notification_result"]) # check Dynamodb for notification notification_items = self.scan_notifications_table() self.assertEqual(1, len(notification_items))
def test_process_rescheduling_of_cancelled_appointment_raises_error(self): """ Simulates EventBridge events being processed in the wrong order """ # setup test app_data = test_data.appointments["views2"] app_id = app_data.pop("appointment_id") original_app = views.ViewsAppointment(appointment_id=app_id, **app_data) original_app.ddb_dump() # fetches and saves Acuity app data original_app.acuity_info["canceled"] = False # simulate outdated data in ddb original_app.ddb_dump(update_allowed=True) # saves simulated outdated data # run test test_eb_event = copy.deepcopy(test_data.TEST_INTERVIEW_RESCHEDULED_EB_EVENT) test_eb_event["detail"].update( appointment_id=app_id, ) if test_tools.tests_running_on_aws(): result = test_tools.test_eb_request( local_method=views.interview_rescheduled, aws_eb_event=test_eb_event, aws_processing_delay=12, ) self.assertEqual( HTTPStatus.OK, result["ResponseMetadata"]["HTTPStatusCode"] ) # check notifications that were created in notifications table notifications = self.ddb_client.scan( table_name=self.notifications_table, table_name_verbatim=True, ) self.assertEqual(0, len(notifications)) else: with self.assertRaises(AssertionError) as context: test_tools.test_eb_request( local_method=views.interview_rescheduled, aws_eb_event=test_eb_event, aws_processing_delay=12, ) err = context.exception err_msg = err.args[0] self.assertIn( "Appointment 658731287 is cancelled", err_msg, )
def test_process_cancellation_ok(self): self.aa1.ddb_dump() # simulates original booking test_eb_event = copy.deepcopy(test_data.TEST_INTERVIEW_CANCELLED_EB_EVENT) result = test_tools.test_eb_request( local_method=views.interview_cancelled, aws_eb_event=test_eb_event, aws_processing_delay=12, ) if test_tools.tests_running_on_aws(): self.assertEqual( HTTPStatus.OK, result["ResponseMetadata"]["HTTPStatusCode"] ) else: ( storing_result, participant_and_researchers_notification_results, ) = result self.assertEqual( HTTPStatus.OK, storing_result["ResponseMetadata"]["HTTPStatusCode"] ) participant_result = participant_and_researchers_notification_results.get( "participant" ) self.assertEqual(HTTPStatus.NO_CONTENT, participant_result) researchers_result = participant_and_researchers_notification_results.get( "researchers" ) self.assertEqual([HTTPStatus.NO_CONTENT] * 2, researchers_result) expected_appointment = test_eb_event["detail"] self.check_dynamodb_appointment( expected_appointment=expected_appointment, cancelled=True ) # check notifications that were created in notifications table notifications = self.ddb_client.scan( table_name=self.notifications_table, table_name_verbatim=True, ) self.assertEqual(3, len(notifications)) notific_types = [x["type"] for x in notifications] self.assertEqual(["transactional-email"] * 3, notific_types) templates = [x["details"]["template_name"] for x in notifications] if test_tools.tests_running_on_aws(): expected_templates = ["views_interview_cancelled_researcher"] * 2 + [ "views_interview_cancelled_participant" ] else: expected_templates = ["NA_views_interview_cancelled_researcher"] * 2 + [ "NA_views_interview_cancelled_participant" ] self.assertCountEqual(expected_templates, templates)
def test_set_user_task_status_to_complete_ok(self): result = test_tools.test_eb_request( local_method=ut.user_task_completed_handler, aws_eb_event=test_events.TEST_USER_TASK_COMPLETED_EVENT, aws_processing_delay=10, ) if test_tools.tests_running_on_aws(): self.assertEqual(HTTPStatus.OK, result["ResponseMetadata"]["HTTPStatusCode"]) else: self.assertEqual(HTTPStatus.NO_CONTENT, result["statusCode"]) updated_ut = ut.get_user_task( "8bb74086-657e-4276-bad2-6285c6ede0fd")[0] self.assertEqual("complete", updated_ut["status"]) self.now_datetime_test_and_remove(updated_ut, "modified")
def test_user_group_membership_handler_ok(self): pg_utils.truncate_table("public.projects_usergroupmembership") result = test_tools.test_eb_request( local_method=user_group_membership_handler, aws_eb_event=TEST_USER_GROUP_MEMBERSHIP_EVENT, aws_processing_delay=10, ) if test_tools.tests_running_on_aws(): self.assertEqual(HTTPStatus.OK, result["ResponseMetadata"]["HTTPStatusCode"]) else: self.assertEqual(HTTPStatus.CREATED, result["statusCode"]) user_id = "8518c7ed-1df4-45e9-8dc4-d49b57ae0663" # Clive g3_group_id = "d279e19b-0995-4239-9640-80de966b09a3" result = pg_utils.execute_query(base_sql=SQL_USER_GROUP_MEMBERSHIP, params=(user_id, g3_group_id)) self.assertEqual(1, len(result))
def test_user_consent_event_handler_ok(self): self.clear_consent_data_table() self.clear_notifications_table() result = test_utils.test_eb_request( local_method=consent.user_consent, aws_eb_event=USER_CONSENT_EB_EVENT, aws_processing_delay=10, ) if test_utils.tests_running_on_aws(): self.assertEqual(HTTPStatus.OK, result["ResponseMetadata"]["HTTPStatusCode"]) else: self.assertEqual(HTTPStatus.OK, result["statusCode"]) body = json.loads(result["body"]) self.assertEqual(HTTPStatus.OK, body["store_result"]) self.assertEqual(HTTPStatus.NO_CONTENT, body["notification_result"]) # check Dynamodb for consent object consent_items = self.scan_consent_data_table() self.assertEqual(1, len(consent_items)) # check Dynamodb for notification notification_items = self.scan_notifications_table() self.assertEqual(1, len(notification_items))
def test_process_rescheduling_with_different_interviewer_ok(self): # clear booking notifications self.clear_notifications_table() # reschedule appointment self.acuity_client.reschedule_appointment( self.appointment_id, datetime(2022, 1, 31, 11, 15), calendarID=4038206, ) # generate Views rescheduling event rescheduling_info = { **self.acuity_info, "datetime": "2022-01-31T11:15:00+0000", "calendarID": 4038206, "calendar": "Andre", } test_eb_event = self.views_interview_rescheduled_event_from_acuity_info( rescheduling_info ) result = test_tools.test_eb_request( local_method=views.interview_rescheduled, aws_eb_event=test_eb_event, aws_processing_delay=12, ) if test_tools.tests_running_on_aws(): self.assertEqual( HTTPStatus.OK, result["ResponseMetadata"]["HTTPStatusCode"] ) expected_appointment = test_eb_event["detail"] self.check_dynamodb_appointment(expected_appointment=expected_appointment) # check notifications that were created in notifications table notifications = self.ddb_client.scan( table_name=self.notifications_table, table_name_verbatim=True, ) self.assertEqual(3, len(notifications)) notific_types = [x["type"] for x in notifications] self.assertEqual(["transactional-email"] * 3, notific_types) templates = [x["details"]["template_name"] for x in notifications] expected_templates = ["views_interview_rescheduled_researcher"] * 2 + [ "views_interview_rescheduled_participant" ] self.assertCountEqual(expected_templates, templates) else: ( storing_result, participant_and_researchers_notification_results, ) = result self.assertEqual( HTTPStatus.OK, storing_result["ResponseMetadata"]["HTTPStatusCode"] ) participant_result = participant_and_researchers_notification_results.get( "participant" ) self.assertEqual(HTTPStatus.NO_CONTENT, participant_result) researchers_result = participant_and_researchers_notification_results.get( "researchers" ) self.assertEqual([HTTPStatus.NO_CONTENT] * 4, researchers_result)