Пример #1
0
    def test_code_validation_payload_json_serializable(self):
        payload = CodeValidationPayload(
            valid="True",
            is_demo="False",
            account_info=AccountInfo(
                employer_id=1,
                unit_id=1,
                employer_name="employer_name",
                unit_name="unit_name",
            ),
        )
        self.assertEqual(
            payload.dict(),
            {
                "valid": True,
                "is_demo": False,
                "account_info": {
                    "employer_id": 1,
                    "unit_id": 1,
                    "employer_name": "employer_name",
                    "unit_name": "unit_name",
                },
            },
        )

        # json serialization doesnt blow up
        payload.json()
Пример #2
0
    def test_revalidate_demo_user(self):
        validator = MagicMock()
        validation_payload = CodeValidationPayload(valid=True, is_demo=True)
        validator.validate_code = MagicMock(return_value=validation_payload)
        self.assertFalse(self.dialog_state.user_profile.validated)
        command = ProcessSMSMessage(self.phone_number, "hey", registration_validator=validator)

        batch = self._process_command(command)
        self._assert_event_types(batch, DialogEventType.USER_VALIDATED)

        command = StartDrill(self.phone_number, self.drill.slug, self.drill.dict(), uuid.uuid4())
        self._process_command(command)

        validation_payload = CodeValidationPayload(
            valid=True,
            account_info={
                "employer_id": 1,
                "unit_id": 1,
                "employer_name": "employer_name",
                "unit_name": "unit_name",
            },
        )
        validator.validate_code = MagicMock(return_value=validation_payload)
        command = ProcessSMSMessage(self.phone_number, "hey", registration_validator=validator)

        batch = self._process_command(command)
        self._assert_event_types(batch, DialogEventType.USER_VALIDATED)
Пример #3
0
    def test_advance_demo_user(self, get_drill_mock):
        validator = MagicMock()
        validation_payload = CodeValidationPayload(valid=True, is_demo=True)
        validator.validate_code = MagicMock(return_value=validation_payload)
        self.assertFalse(self.dialog_state.user_profile.validated)
        command = ProcessSMSMessage(self.phone_number,
                                    "hey",
                                    registration_validator=validator)

        batch = self._process_command(command)
        self._assert_event_types(batch, DialogEventType.USER_VALIDATED)

        command = StartDrill(self.phone_number, self.drill.slug)
        self._process_command(command)

        # the user's next message isn't a validation code - so we just keep going
        validation_payload = CodeValidationPayload(valid=False)
        validator.validate_code = MagicMock(return_value=validation_payload)
        command = ProcessSMSMessage(self.phone_number,
                                    "hey",
                                    registration_validator=validator)

        batch = self._process_command(command)
        self._assert_event_types(batch, DialogEventType.COMPLETED_PROMPT,
                                 DialogEventType.ADVANCED_TO_NEXT_PROMPT)
Пример #4
0
 def validate_code(self, code: str) -> CodeValidationPayload:
     if code in DRILLS.keys():
         return CodeValidationPayload(
             valid=True,
             account_info=AccountInfo(
                 employer_id=1,
                 employer_name=code,
                 unit_id=1,
                 unit_name="unit_name",
             ),
         )
     return CodeValidationPayload(valid=False)
Пример #5
0
 def test_user_revalidated(self):
     profile = UserProfile(validated=True, is_demo=True)
     dialog_state = DialogState(
         "123456789",
         "0",
         user_profile=profile,
         current_drill=DRILL,
         drill_instance_id=uuid.uuid4(),
         current_prompt_state=PromptState(slug=DRILL.prompts[0].slug,
                                          start_time=NOW),
     )
     event = UserValidated(
         phone_number="123456789",
         user_profile=profile,
         code_validation_payload=CodeValidationPayload(
             valid=True, is_demo=False, account_info={"foo": "bar"}),
     )
     event.apply_to(dialog_state)
     self.assertTrue(dialog_state.user_profile.validated)
     self.assertFalse(dialog_state.user_profile.is_demo)
     self.assertIsNone(dialog_state.current_drill)
     self.assertIsNone(dialog_state.current_prompt_state)
     self.assertIsNone(dialog_state.drill_instance_id)
     self.assertEqual({"foo": "bar"},
                      dialog_state.user_profile.account_info)
Пример #6
0
 def test_user_validated(self):
     profile = UserProfile(validated=False)
     dialog_state = DialogState(phone_number="123456789",
                                seq="0",
                                user_profile=profile)
     event = UserValidated(
         phone_number="123456789",
         user_profile=profile,
         code_validation_payload=CodeValidationPayload(
             valid=True,
             is_demo=False,
             account_info={
                 "employer_id": 1,
                 "unit_id": 1,
                 "employer_name": "employer_name",
                 "unit_name": "unit_name",
             },
         ),
     )
     event.apply_to(dialog_state)
     self.assertTrue(dialog_state.user_profile.validated)
     self.assertEqual(
         {
             "employer_id": 1,
             "unit_id": 1,
             "employer_name": "employer_name",
             "unit_name": "unit_name",
         },
         dialog_state.user_profile.account_info,
     )
Пример #7
0
    def test_first_message_validates_user(self):
        validator = MagicMock()
        validation_payload = CodeValidationPayload(
            valid=True,
            account_info={
                "employer_id": 1,
                "unit_id": 1,
                "employer_name": "employer_name",
                "unit_name": "unit_name",
            },
        )
        validator.validate_code = MagicMock(return_value=validation_payload)
        command = ProcessSMSMessage(self.phone_number, "hey", registration_validator=validator)
        self.assertFalse(self.dialog_state.user_profile.validated)

        batch = self._process_command(command)
        self._assert_event_types(batch, DialogEventType.USER_VALIDATED)
        self.assertEqual(
            validation_payload, batch.events[0].code_validation_payload  # type: ignore
        )
        # and account info is set on the event and user profile
        self.assertEqual(
            batch.events[0].user_profile.account_info,
            AccountInfo(
                employer_id=1, unit_id=1, employer_name="employer_name", unit_name="unit_name"
            ),
        )
Пример #8
0
 def test_user_revalidated(self):
     user_id = self._make_user_and_get_id()
     for slug in get_all_drill_slugs():
         drill = copy(self.drill)
         drill.slug = slug
         event = DrillStarted(
             phone_number=self.phone_number,
             user_profile=UserProfile(True),
             drill=Drill(slug=slug, name="name", prompts=[]),
             first_prompt=self.prompt,
         )
         event2 = DrillCompleted(
             phone_number=self.phone_number,
             user_profile=UserProfile(True),
             drill_instance_id=event.drill_instance_id,
         )
         self.repo._mark_drill_started(user_id, event, self.repo.engine)
         self.repo._mark_drill_completed(event2, self.repo.engine)
         drill_status = self.repo.get_drill_status(user_id, slug)
         self.assertIsNotNone(drill_status.started_time)
         self.assertIsNotNone(drill_status.completed_time)
     self.repo.update_user(
         self._make_batch([
             UserValidated(
                 phone_number=self.phone_number,
                 user_profile=UserProfile(True),
                 code_validation_payload=CodeValidationPayload(valid=True),
             )
         ]))
     for slug in get_all_drill_slugs():
         drill_status = self.repo.get_drill_status(user_id, slug)
         self.assertIsNone(drill_status.drill_instance_id)
         self.assertIsNone(drill_status.started_time)
         self.assertIsNone(drill_status.completed_time)
Пример #9
0
 def test_initiates_subsequent_drill(self):
     batch1 = DialogEventBatch(
         phone_number="123456789",
         seq="0",
         events=[
             NextDrillRequested(
                 phone_number="123456789",
                 user_profile=UserProfile(True),
                 code_validation_payload=CodeValidationPayload(valid=True),
             ),
             DrillStarted(
                 phone_number="123456789",
                 user_profile=UserProfile(True),
                 drill=self.drill,
                 first_prompt=self.drill.prompts[0],
             ),
         ],
     )
     batch2 = DialogEventBatch(
         phone_number="987654321",
         seq="1",
         events=[
             DrillStarted(
                 phone_number="987654321",
                 user_profile=UserProfile(True),
                 drill=self.drill,
                 first_prompt=self.drill.prompts[0],
             )
         ],
     )
     self.assertTrue(initiates_subsequent_drill(batch1))
     self.assertFalse(initiates_subsequent_drill(batch2))
Пример #10
0
 def test_revalidate_user_without_org(self):
     validator = MagicMock()
     validation_payload = CodeValidationPayload(valid=True, is_demo=True)
     validator.validate_code = MagicMock(return_value=validation_payload)
     self.dialog_state.user_profile.validated = True
     self.dialog_state.user_profile.account_info = AccountInfo(employer_id=None)
     command = ProcessSMSMessage(self.phone_number, "hey", registration_validator=validator)
     batch = self._process_command(command)
     self._assert_event_types(batch, DialogEventType.USER_VALIDATED)
     validation_payload = CodeValidationPayload(
         valid=True,
         account_info={
             "employer_id": 1,
             "unit_id": 1,
             "employer_name": "employer_name",
             "unit_name": "unit_name",
         },
     )
Пример #11
0
 def test_user_validated_event(self):
     code_validation_payload = CodeValidationPayload(valid=True,
                                                     is_demo=False)
     dialog_events: List[DialogEvent] = [
         UserValidated(self.phone, self.validated_user_profile,
                       code_validation_payload)
     ]
     outbound_messages = get_outbound_sms_commands(dialog_events)
     self.assertEqual(len(outbound_messages), 0)
Пример #12
0
 def test_user_validated(self):
     original = UserValidated(
         "123456789",
         user_profile=UserProfile(True),
         code_validation_payload=CodeValidationPayload(valid=True,
                                                       is_demo=True),
     )
     serialized = original.to_dict()
     deserialized = event_from_dict(serialized)
     self._make_base_assertions(original, deserialized)
Пример #13
0
    def test_first_message_does_not_validate_user(self):
        validator = MagicMock()
        validation_payload = CodeValidationPayload(valid=False)
        validator.validate_code = MagicMock(return_value=validation_payload)
        command = ProcessSMSMessage(self.phone_number, "hey", registration_validator=validator)
        self.assertFalse(self.dialog_state.user_profile.validated)

        batch = self._process_command(command)

        self._assert_event_types(batch, DialogEventType.USER_VALIDATION_FAILED)
Пример #14
0
    def test_doesnt_revalidate_someone_with_an_org(self):
        validator = MagicMock()
        validation_payload = CodeValidationPayload(valid=True, is_demo=True)
        validator.validate_code = MagicMock(return_value=validation_payload)
        self.dialog_state.user_profile.validated = True
        self.dialog_state.user_profile.account_info = AccountInfo(employer_id=1)
        command = ProcessSMSMessage(self.phone_number, "hey", registration_validator=validator)
        batch = self._process_command(command)

        # not a USER_VALIDATED event
        self._assert_event_types(batch, DialogEventType.UNHANDLED_MESSAGE_RECEIVED)
Пример #15
0
 def test_advance_sequence_numbers(self, get_drill_mock):
     validator = MagicMock()
     validation_payload = CodeValidationPayload(
         valid=True, account_info={"company": "WeWork"})
     validator.validate_code = MagicMock(return_value=validation_payload)
     command = ProcessSMSMessage(self.phone_number,
                                 "hey",
                                 registration_validator=validator)
     batch = self._process_command(command)
     self.assertEqual(1, len(batch.events))
     self.assertEqual("1", self.dialog_state.seq)
Пример #16
0
 def _make_user_and_get_id(self, **overrides) -> uuid.UUID:
     return self.repo._create_or_update_user(
         self._make_batch([
             UserValidated(
                 phone_number=overrides.get("phone_number",
                                            self.phone_number),
                 user_profile=UserProfile(True),
                 code_validation_payload=CodeValidationPayload(valid=True),
             )
         ]),
         None,
         self.repo.engine,
     )
Пример #17
0
 def test_user_validated(self):
     profile = UserProfile(validated=False)
     dialog_state = DialogState("123456789", "0", user_profile=profile)
     event = UserValidated(
         phone_number="123456789",
         user_profile=profile,
         code_validation_payload=CodeValidationPayload(
             valid=True, is_demo=False, account_info={"foo": "bar"}),
     )
     event.apply_to(dialog_state)
     self.assertTrue(dialog_state.user_profile.validated)
     self.assertEqual({"foo": "bar"},
                      dialog_state.user_profile.account_info)
Пример #18
0
    def test_revalidate_demo_user(self, get_drill_mock):
        validator = MagicMock()
        validation_payload = CodeValidationPayload(valid=True, is_demo=True)
        validator.validate_code = MagicMock(return_value=validation_payload)
        self.assertFalse(self.dialog_state.user_profile.validated)
        command = ProcessSMSMessage(self.phone_number,
                                    "hey",
                                    registration_validator=validator)

        batch = self._process_command(command)
        self._assert_event_types(batch, DialogEventType.USER_VALIDATED)

        command = StartDrill(self.phone_number, self.drill.slug)
        self._process_command(command)

        validation_payload = CodeValidationPayload(
            valid=True, account_info={"company": "WeWork"})
        validator.validate_code = MagicMock(return_value=validation_payload)
        command = ProcessSMSMessage(self.phone_number,
                                    "hey",
                                    registration_validator=validator)

        batch = self._process_command(command)
        self._assert_event_types(batch, DialogEventType.USER_VALIDATED)
Пример #19
0
 def test_advance_sequence_numbers(self):
     validator = MagicMock()
     validation_payload = CodeValidationPayload(
         valid=True,
         account_info={
             "employer_id": 1,
             "unit_id": 1,
             "employer_name": "employer_name",
             "unit_name": "unit_name",
         },
     )
     validator.validate_code = MagicMock(return_value=validation_payload)
     command = ProcessSMSMessage(self.phone_number, "hey", registration_validator=validator)
     batch = self._process_command(command)
     self.assertEqual(1, len(batch.events))
     self.assertEqual("1", self.dialog_state.seq)
Пример #20
0
    def test_first_message_validates_user(self, get_drill_mock):
        validator = MagicMock()
        validation_payload = CodeValidationPayload(
            valid=True, account_info={"company": "WeWork"})
        validator.validate_code = MagicMock(return_value=validation_payload)
        command = ProcessSMSMessage(self.phone_number,
                                    "hey",
                                    registration_validator=validator)
        self.assertFalse(self.dialog_state.user_profile.validated)

        batch = self._process_command(command)
        self._assert_event_types(batch, DialogEventType.USER_VALIDATED)
        self.assertEqual(
            validation_payload,
            batch.events[0].code_validation_payload  # type: ignore
        )
    def setUp(self):
        os.environ["STAGE"] = "test"
        self.drill_progress_repo = DrillProgressRepository(
            db.get_test_sqlalchemy_engine)
        self.drill_progress_repo.drop_and_recreate_tables_testing_only()
        self.phone_number = "123456789"
        self.user_id = self.drill_progress_repo._create_or_update_user(
            DialogEventBatch(
                events=[
                    UserValidated(self.phone_number, UserProfile(True),
                                  CodeValidationPayload(True))
                ],
                phone_number=self.phone_number,
                seq="0",
                batch_id=uuid.uuid4(),
            ),
            None,
            self.drill_progress_repo.engine,
        )

        drill_db_patch = patch(
            "stopcovid.drill_progress.trigger_reminders.ReminderTriggerer._get_drill_progress_repo",
            return_value=self.drill_progress_repo,
        )
        drill_db_patch.start()

        self.addCleanup(drill_db_patch.stop)

        self.idempotency_checker = IdempotencyChecker(
            region_name="us-west-2",
            endpoint_url="http://localhost:9000",
            aws_access_key_id="fake-key",
            aws_secret_access_key="fake-secret",
        )
        self.idempotency_checker.drop_and_recreate_table()

        idempotency_patch = patch(
            "stopcovid.drill_progress.trigger_reminders.IdempotencyChecker",
            return_value=self.idempotency_checker,
        )
        idempotency_patch.start()
        self.addCleanup(idempotency_patch.stop)
Пример #22
0
    def test_user_revalidated(self):
        drill_instance1 = self._make_drill_instance()
        drill_instance2 = self._make_drill_instance()
        self.repo._save_drill_instance(drill_instance1)
        self.repo._save_drill_instance(drill_instance2)
        self.assertTrue(drill_instance1.is_valid)
        self.assertTrue(drill_instance2.is_valid)

        self.repo.update_user(
            self._make_batch([
                UserValidated(
                    phone_number=self.phone_number,
                    user_profile=UserProfile(True),
                    code_validation_payload=CodeValidationPayload(
                        valid=True, is_demo=True),
                )
            ]))
        drill_instance1 = self.repo.get_drill_instance(
            drill_instance1.drill_instance_id)
        drill_instance2 = self.repo.get_drill_instance(
            drill_instance2.drill_instance_id)
        self.assertFalse(drill_instance1.is_valid)
        self.assertFalse(drill_instance2.is_valid)
Пример #23
0
 def setUp(self):
     logging.disable(logging.CRITICAL)
     self.repo = DrillProgressRepository(db.get_test_sqlalchemy_engine)
     self.repo.drop_and_recreate_tables_testing_only()
     self.phone_number = "123456789"
     self.prompt1 = Prompt(slug="first", messages=[])
     self.prompt2 = Prompt(slug="second", messages=[])
     self.drill = Drill(slug="slug", name="name", prompts=[self.prompt1])
     self.seq = 1
     self.user_id = self.repo._create_or_update_user(
         DialogEventBatch(
             events=[
                 UserValidated(self.phone_number, UserProfile(True),
                               CodeValidationPayload(True))
             ],
             phone_number=self.phone_number,
             seq="0",
             batch_id=uuid.uuid4(),
         ),
         None,
         self.repo.engine,
     )
     self.drill_instance = self._make_drill_instance()
Пример #24
0
 def validate_code(self, code) -> CodeValidationPayload:
     if code in DRILLS.keys():
         return CodeValidationPayload(valid=True,
                                      account_info={"code": code})
     return CodeValidationPayload(valid=False)