Ejemplo n.º 1
0
 def test_completed_prompt(self):
     original = CompletedPrompt(
         phone_number="123456789",
         user_profile=UserProfile(True),
         prompt=self.prompt,
         response="hello",
         drill_instance_id=uuid.uuid4(),
     )
     serialized = original.to_dict()
     deserialized: CompletedPrompt = event_from_dict(
         serialized)  # type: ignore
     self._make_base_assertions(original, deserialized)
     self.assertEqual(original.prompt.slug, deserialized.prompt.slug)
     self.assertEqual(original.response, deserialized.response)
     self.assertEqual(original.drill_instance_id,
                      deserialized.drill_instance_id)
Ejemplo n.º 2
0
    def test_save_and_fetch(self):
        dialog_state = self.repo.fetch_dialog_state(self.phone_number)
        self.assertEqual(self.phone_number, dialog_state.phone_number)

        event1 = CompletedPrompt(
            phone_number=self.phone_number,
            user_profile=UserProfile(validated=True),
            prompt=Prompt(
                slug="one",
                messages=[
                    PromptMessage(text="one"),
                    PromptMessage(text="two")
                ],
            ),
            response="hi",
            drill_instance_id=uuid.uuid4(),
        )
        event2 = AdvancedToNextPrompt(
            phone_number=self.phone_number,
            user_profile=UserProfile(validated=True),
            prompt=Prompt(
                slug="two",
                messages=[
                    PromptMessage(text="three"),
                    PromptMessage(text="four")
                ],
            ),
            drill_instance_id=event1.drill_instance_id,
        )
        dialog_state = DialogState(
            phone_number=self.phone_number,
            seq="0",
            user_profile=UserProfile(validated=True, language="de"),
            drill_instance_id=event1.drill_instance_id,
        )
        batch = DialogEventBatch(phone_number=self.phone_number,
                                 events=[event1, event2],
                                 seq="216")

        self.repo.persist_dialog_state(batch, dialog_state)
        dialog_state2 = self.repo.fetch_dialog_state(self.phone_number)
        self.assertEqual(dialog_state.phone_number, dialog_state2.phone_number)
        self.assertEqual(dialog_state.user_profile.validated,
                         dialog_state2.user_profile.validated)
        self.assertEqual(dialog_state.user_profile.language,
                         dialog_state2.user_profile.language)

        batch_retrieved = self.repo.fetch_dialog_event_batch(
            self.phone_number, batch.batch_id)

        event1_retrieved = batch_retrieved.events[0]
        self.assertEqual(event1.response,
                         event1_retrieved.response)  # type: ignore

        event2_retrieved = batch_retrieved.events[1]
        self.assertEqual(event2.prompt.slug,
                         event2_retrieved.prompt.slug)  # type: ignore
Ejemplo n.º 3
0
 def test_completed_and_not_stored(self):
     profile = UserProfile(validated=True)
     event = CompletedPrompt(
         "123456789",
         user_profile=profile,
         prompt=DRILL.prompts[0],
         drill_instance_id=uuid.uuid4(),
         response="go",
     )
     dialog_state = DialogState(
         "123456789",
         "0",
         user_profile=profile,
         current_drill=DRILL,
         current_prompt_state=PromptState(DRILL.prompts[0].slug, NOW),
     )
     event.apply_to(dialog_state)
     self.assertEqual(profile, dialog_state.user_profile)
     self.assertIsNone(dialog_state.current_prompt_state)
Ejemplo n.º 4
0
 def test_completed_and_stored(self):
     profile = UserProfile(validated=True)
     event = CompletedPrompt(
         phone_number="123456789",
         user_profile=profile,
         prompt=DRILL.prompts[1],
         drill_instance_id=uuid.uuid4(),
         response="7",
     )
     dialog_state = DialogState(
         phone_number="123456789",
         seq="0",
         user_profile=profile,
         current_drill=DRILL,
         current_prompt_state=PromptState(slug=DRILL.prompts[0].slug,
                                          start_time=NOW),
     )
     event.apply_to(dialog_state)
     self.assertEqual(UserProfile(validated=True, self_rating_1="7"),
                      dialog_state.user_profile)
     self.assertIsNone(dialog_state.current_prompt_state)
Ejemplo n.º 5
0
 def test_prompt_completed(self):
     self.repo._save_drill_instance(self.drill_instance)
     event = CompletedPrompt(
         phone_number=self.phone_number,
         user_profile=UserProfile(True),
         prompt=self.prompt1,
         drill_instance_id=self.drill_instance.drill_instance_id,
         response="go",
     )
     self.repo.update_user(self._make_batch([event]))
     retrieved = self.repo.get_drill_instance(
         self.drill_instance.drill_instance_id)
     self.assertEqual(event.created_time,
                      retrieved.current_prompt_last_response_time)
Ejemplo n.º 6
0
    def _check_response(
        self, dialog_state: DialogState, base_args: Dict[str, Any]
    ) -> Optional[List[stopcovid.dialog.models.events.DialogEvent]]:
        prompt = dialog_state.get_prompt()
        if prompt is None:
            return
        events = []
        if prompt.should_advance_with_answer(
                self.content_lower, dialog_state.user_profile.language):
            events.append(
                CompletedPrompt(
                    prompt=prompt,
                    drill_instance_id=dialog_state.
                    drill_instance_id,  # type: ignore
                    response=self.content,
                    **base_args,
                ))
            should_advance = True
        else:
            should_advance = dialog_state.current_prompt_state.failures >= prompt.max_failures
            events.append(
                FailedPrompt(
                    prompt=prompt,
                    response=self.content,
                    drill_instance_id=dialog_state.
                    drill_instance_id,  # type: ignore
                    abandoned=should_advance,
                    **base_args,
                ))

        if should_advance:
            next_prompt = dialog_state.get_next_prompt()
            if next_prompt is not None:
                events.append(
                    AdvancedToNextPrompt(
                        prompt=next_prompt,
                        drill_instance_id=dialog_state.
                        drill_instance_id,  # type: ignore
                        **base_args,
                    ))
                if dialog_state.is_next_prompt_last():
                    # assume the last prompt doesn't wait for an answer
                    events.append(
                        DrillCompleted(
                            drill_instance_id=dialog_state.
                            drill_instance_id,  # type: ignore
                            **base_args,
                        ))
        return events
 def test_get_messages(self):
     dialog_event = CompletedPrompt(
         phone_number=self.phone,
         user_profile=self.validated_user_profile,
         prompt=self.drill.prompts[1],
         response="a",
         drill_instance_id=uuid.uuid4(),
     )
     messages = [
         PromptMessage(text="Hello Mario"),
         PromptMessage(text="You work for Tacombi"),
     ]
     output = get_messages(dialog_event=dialog_event, messages=messages)
     self.assertEqual(output[0].body, "Hello Mario")
     self.assertEqual(output[1].body, "You work for Tacombi")
 def test_completed_prompt_event(self):
     dialog_events: List[DialogEvent] = [
         CompletedPrompt(
             phone_number=self.phone,
             user_profile=self.validated_user_profile,
             prompt=self.drill.prompts[1],
             response="a",
             drill_instance_id=uuid.uuid4(),
         )
     ]
     outbound_messages = get_outbound_sms_commands(dialog_events)
     self.assertEqual(len(outbound_messages), 1)
     message = outbound_messages[0]
     self.assertEqual(message.phone_number, self.phone)
     self.assertEqual(message.event_id, dialog_events[0].event_id)
     self.assertTrue(message.body.endswith("Correct!"))
Ejemplo n.º 9
0
 def test_completed_prompt_event(self):
     dialog_events: List[DialogEvent] = [
         CompletedPrompt(
             self.phone,
             self.validated_user_profile,
             prompt=self.drill.prompts[1],
             response="a",
             drill_instance_id=uuid.uuid4(),
         )
     ]
     outbound_messages = get_outbound_sms_commands(dialog_events)
     self.assertEqual(len(outbound_messages), 1)
     message = outbound_messages[0]
     self.assertEqual(message.phone_number, self.phone)
     self.assertEqual(message.event_id, dialog_events[0].event_id)
     self.assertEqual(message.body,
                      localize(CORRECT_ANSWER_COPY, "en", emojis=""))
Ejemplo n.º 10
0
 def test_last_interacted(self):
     user_id = self._make_user_and_get_id()
     event = DrillStarted(
         phone_number=self.phone_number,
         user_profile=UserProfile(True),
         drill=self.drill,
         first_prompt=self.prompt,
     )
     self.repo.update_user(self._make_batch([event]))
     user = self.repo.get_user(user_id)
     self.assertEqual(event.created_time, user.last_interacted_time)
     event2 = CompletedPrompt(
         phone_number=self.phone_number,
         user_profile=UserProfile(True),
         prompt=self.prompt,
         drill_instance_id=event.drill_instance_id,
         response="go",
     )
     self.repo.update_user(self._make_batch([event2]))
     user = self.repo.get_user(user_id)
     self.assertEqual(event2.created_time, user.last_interacted_time)
Ejemplo n.º 11
0
 def test_advanced_to_next_prompt(self):
     self.repo._save_drill_instance(self.drill_instance)
     event = CompletedPrompt(
         phone_number=self.phone_number,
         user_profile=UserProfile(True),
         prompt=self.prompt1,
         drill_instance_id=self.drill_instance.drill_instance_id,
         response="go",
     )
     self.repo.update_user(self._make_batch([event]))
     event = AdvancedToNextPrompt(
         phone_number=self.phone_number,
         user_profile=UserProfile(True),
         prompt=self.prompt2,
         drill_instance_id=self.drill_instance.drill_instance_id,
     )
     self.repo.update_user(self._make_batch([event]))
     retrieved = self.repo.get_drill_instance(
         self.drill_instance.drill_instance_id)
     self.assertEqual(self.prompt2.slug, retrieved.current_prompt_slug)
     self.assertIsNone(retrieved.current_prompt_last_response_time)
     self.assertEqual(event.created_time,
                      retrieved.current_prompt_start_time)
Ejemplo n.º 12
0
    def _check_response(
            self, dialog_state: DialogState,
            base_args: Dict[str, Any]) -> Optional[List[DialogEvent]]:
        prompt = dialog_state.get_prompt()
        if prompt is None:
            return None
        events: List[DialogEvent] = []
        if prompt.should_advance_with_answer(self.content_lower):
            user_profile_updates = None
            if prompt.response_user_profile_key:
                user_profile_updates = {
                    prompt.response_user_profile_key: self.content
                }
            events.append(
                CompletedPrompt(
                    prompt=prompt,
                    drill_instance_id=dialog_state.drill_instance_id,
                    response=self.content,
                    user_profile_updates=user_profile_updates,
                    **base_args,
                ))
            should_advance = True
        else:
            assert dialog_state.current_prompt_state
            should_advance = dialog_state.current_prompt_state.failures >= (
                prompt.max_failures or 1)
            events.append(
                FailedPrompt(
                    prompt=prompt,
                    response=self.content or None,
                    drill_instance_id=dialog_state.drill_instance_id,
                    abandoned=should_advance,
                    **base_args,
                ))

        if should_advance:
            assert dialog_state.current_drill
            next_prompt = dialog_state.get_next_prompt()
            if next_prompt is not None:
                events.append(
                    AdvancedToNextPrompt(
                        prompt=next_prompt,
                        drill_instance_id=dialog_state.drill_instance_id,
                        **base_args,
                    ))
                if dialog_state.is_next_prompt_last():
                    # assume the last prompt doesn't wait for an answer
                    events.append(
                        DrillCompleted(
                            drill_instance_id=dialog_state.drill_instance_id,
                            **base_args,
                        ))
            elif len(dialog_state.current_drill.prompts) == 1:
                events.append(
                    DrillCompleted(
                        drill_instance_id=dialog_state.drill_instance_id,
                        last_prompt_response=self.content or None,
                        **base_args,
                    ))

        return events