Example #1
0
async def test_post_conversation_id_with_slash(rasa_app: SanicASGITestClient):
    conversation_id = str(uuid.uuid1())
    id_len = len(conversation_id) // 2
    conversation_id = conversation_id[:id_len] + "/+-_\\=" + conversation_id[id_len:]
    conversation = f"/conversations/{conversation_id}"

    events = [e.as_dict() for e in test_events]
    _, response = await rasa_app.post(
        f"{conversation}/tracker/events",
        json=events,
        headers={"Content-Type": "application/json"},
    )
    assert response.json() is not None
    assert response.status == 200

    _, tracker_response = await rasa_app.get(
        f"/conversations/{conversation_id}/tracker"
    )
    tracker = tracker_response.json()
    assert tracker is not None

    # there is a session start sequence at the start
    assert [
        Event.from_parameters(event) for event in tracker.get("events")
    ] == session_start_sequence + test_events
Example #2
0
async def test_pushing_event(rasa_app: SanicASGITestClient, event: Event):
    sender_id = str(uuid.uuid1())
    conversation = f"/conversations/{sender_id}"

    serialized_event = event.as_dict()
    # Remove timestamp so that a new one is assigned on the server
    serialized_event.pop("timestamp")

    time_before_adding_events = time.time()
    _, response = await rasa_app.post(
        f"{conversation}/tracker/events",
        json=serialized_event,
        headers={"Content-Type": rasa.server.JSON_CONTENT_TYPE},
    )
    assert response.json() is not None
    assert response.status == 200

    _, tracker_response = await rasa_app.get(f"/conversations/{sender_id}/tracker")
    tracker = tracker_response.json()
    assert tracker is not None

    assert len(tracker.get("events")) == 4

    deserialized_events = [Event.from_parameters(event) for event in tracker["events"]]

    # there is an initial session start sequence at the beginning of the tracker
    assert deserialized_events[:3] == session_start_sequence

    assert deserialized_events[3] == event
    assert deserialized_events[3].timestamp > time_before_adding_events
Example #3
0
def test_bot_output_format():
    message = {
        "event": "bot",
        "text": "Hello!",
        "data": {
            "image": "http://example.com/myimage.png",
            "attachment": "My Attachment",
            "buttons": [
                {"title": "yes", "payload": "/yes"},
                {"title": "no", "payload": "/no", "extra": "extra"},
            ],
            "elements": [
                {
                    "title": "element1",
                    "buttons": [{"title": "button1", "payload": "/button1"}],
                },
                {
                    "title": "element2",
                    "buttons": [{"title": "button2", "payload": "/button2"}],
                },
            ],
            "quick_replies": [
                {
                    "title": "quick_reply1",
                    "buttons": [{"title": "button3", "payload": "/button3"}],
                },
                {
                    "title": "quick_reply2",
                    "buttons": [{"title": "button4", "payload": "/button4"}],
                },
            ],
        },
    }
    from rasa.shared.core.events import Event

    bot_event = Event.from_parameters(message)

    assert isinstance(bot_event, BotUttered)

    formatted = interactive.format_bot_output(bot_event)
    assert formatted == (
        "Hello!\n"
        "Image: http://example.com/myimage.png\n"
        "Attachment: My Attachment\n"
        "Buttons:\n"
        "1: yes (/yes)\n"
        '2: no (/no) - {"extra": "extra"}\n'
        "Type out your own message...\n"
        "Elements:\n"
        '1: element1 - {"buttons": '
        '[{"payload": "/button1", "title": "button1"}]'
        '}\n2: element2 - {"buttons": '
        '[{"payload": "/button2", "title": "button2"}]'
        "}\nQuick replies:\n"
        '1: quick_reply1 - {"buttons": '
        '[{"payload": "/button3", "title": "button3"}'
        ']}\n2: quick_reply2 - {"buttons": '
        '[{"payload": "/button4", "title": "button4"}'
        "]}"
    )
Example #4
0
def test_json_parse_user():
    evt = {
        "event": "user",
        "text": "Hey",
        "parse_data": {
            "intent": {
                "name": "greet",
                "confidence": 0.9
            },
            "entities": []
        },
        "metadata": {},
    }
    assert Event.from_parameters(evt) == UserUttered(
        "Hey",
        intent={
            "name": "greet",
            "confidence": 0.9
        },
        entities=[],
        parse_data={
            "intent": {
                "name": "greet",
                "confidence": 0.9
            },
            "entities": []
        },
        metadata={},
    )
Example #5
0
def test_pushing_event(rasa_app: SanicTestClient, event: Event):
    sender_id = str(uuid.uuid1())
    conversation = f"/conversations/{sender_id}"

    serialized_event = event.as_dict()
    # Remove timestamp so that a new one is assigned on the server
    serialized_event.pop("timestamp")

    time_before_adding_events = time.time()
    _, response = rasa_app.post(
        f"{conversation}/tracker/events",
        json=serialized_event,
        headers={"Content-Type": rasa.server.JSON_CONTENT_TYPE},
    )
    assert response.json is not None
    assert response.status == 200

    _, tracker_response = rasa_app.get(f"/conversations/{sender_id}/tracker")
    tracker = tracker_response.json
    assert tracker is not None

    assert len(tracker.get("events")) == 1

    evt = tracker.get("events")[0]
    deserialised_event = Event.from_parameters(evt)
    assert deserialised_event == event
    assert deserialised_event.timestamp > time_before_adding_events
Example #6
0
def test_json_parse_action_executed_with_no_hide_rule():
    evt = {
        "event": "action",
        "name": "action_listen",
        "policy": None,
        "confidence": None,
        "timestamp": None,
    }
    deserialised: ActionExecuted = Event.from_parameters(evt)
    expected = ActionExecuted("action_listen", )
    assert deserialised == expected
    assert deserialised.hide_rule_turn == expected.hide_rule_turn
Example #7
0
def test_event_metadata_dict(event_class: Type[Event]):
    metadata = {"foo": "bar", "quux": 42}

    # Create the event from a `dict` that will be accepted by the
    # `_from_parameters` method of any `Event` subclass (the values themselves
    # are not important).
    event = Event.from_parameters({
        "metadata": metadata,
        "event": event_class.type_name,
        "parse_data": {},
        "date_time": "2019-11-20T16:09:16Z",
    })
    assert event.as_dict()["metadata"] == metadata
Example #8
0
    def from_parameters(cls, parameters: Dict[Text, Any]) -> "Dialogue":
        """Create `Dialogue` from parameters.

        Args:
            parameters: Serialised dialogue, should contain keys 'name' and 'events'.

        Returns:
            Deserialised `Dialogue`.

        """

        return cls(
            parameters.get("name"),
            [Event.from_parameters(evt) for evt in parameters.get("events")],
        )
Example #9
0
def test_json_parse_reminder():
    evt = {
        "event": "reminder",
        "intent": "my_intent",
        "entities": {"entity1": "value1", "entity2": "value2"},
        "date_time": "2018-09-03T11:41:10.128172",
        "name": "my_reminder",
        "kill_on_user_msg": True,
    }
    assert Event.from_parameters(evt) == ReminderScheduled(
        "my_intent",
        parser.parse("2018-09-03T11:41:10.128172"),
        name="my_reminder",
        kill_on_user_message=True,
    )
Example #10
0
def test_event_default_metadata(event_class: Type[Event]):
    # Create an event without metadata. When converting the `Event` to a
    # `dict`, it should not include a `metadata` property - unless it's a
    # `UserUttered` or a `BotUttered` event (or subclasses of them), in which
    # case the metadata should be included with a default value of {}.
    event = Event.from_parameters({
        "event": event_class.type_name,
        "parse_data": {},
        "date_time": "2019-11-20T16:09:16Z",
    })

    if isinstance(event, BotUttered) or isinstance(event, UserUttered):
        assert event.as_dict()["metadata"] == {}
    else:
        assert "metadata" not in event.as_dict()
Example #11
0
async def test_file_broker_logs_to_file(tmp_path: Path):
    log_file_path = str(tmp_path / "events.log")

    actual = await EventBroker.create(
        EndpointConfig(**{"type": "file", "path": log_file_path})
    )

    for e in TEST_EVENTS:
        actual.publish(e.as_dict())

    # reading the events from the file one event per line
    recovered = []
    with open(log_file_path, "r") as log_file:
        for line in log_file:
            recovered.append(Event.from_parameters(json.loads(line)))

    assert recovered == TEST_EVENTS
Example #12
0
def test_event_metadata_dict(event_class: Type[Event]):
    metadata = {"foo": "bar", "quux": 42}
    parameters = {
        "metadata": metadata,
        "event": event_class.type_name,
        "parse_data": {},
        "date_time": "2019-11-20T16:09:16Z",
    }
    # `ActionExecuted` class and its subclasses require either that action_name
    # is not None if it is not an end-to-end predicted action
    if event_class.type_name in ["action", "wrong_action", "warning_predicted"]:
        parameters["name"] = "test"

    # Create the event from a `dict` that will be accepted by the
    # `_from_parameters` method of any `Event` subclass (the values themselves
    # are not important).
    event = Event.from_parameters(parameters)
    assert event.as_dict()["metadata"] == metadata
Example #13
0
async def test_file_broker_properly_logs_newlines(tmp_path: Path):
    log_file_path = str(tmp_path / "events.log")

    actual = await EventBroker.create(
        EndpointConfig(**{"type": "file", "path": log_file_path})
    )

    event_with_newline = UserUttered("hello \n there")

    actual.publish(event_with_newline.as_dict())

    # reading the events from the file one event per line
    recovered = []
    with open(log_file_path, "r") as log_file:
        for line in log_file:
            recovered.append(Event.from_parameters(json.loads(line)))

    assert recovered == [event_with_newline]
Example #14
0
def test_json_parse_reminder_cancelled():
    evt = {
        "event": "cancel_reminder",
        "name": "my_reminder",
        "intent": "my_intent",
        "entities": [
            {"entity": "entity1", "value": "value1"},
            {"entity": "entity2", "value": "value2"},
        ],
        "date_time": "2018-09-03T11:41:10.128172",
    }
    assert Event.from_parameters(evt) == ReminderCancelled(
        name="my_reminder",
        intent="my_intent",
        entities=[
            {"entity": "entity1", "value": "value1"},
            {"entity": "entity2", "value": "value2"},
        ],
        timestamp=parser.parse("2018-09-03T11:41:10.128172"),
    )
Example #15
0
def test_event_default_metadata(event_class: Type[Event]):
    parameters = {
        "event": event_class.type_name,
        "parse_data": {},
        "date_time": "2019-11-20T16:09:16Z",
    }
    # `ActionExecuted` class and its subclasses require either that action_name
    # is not None if it is not an end-to-end predicted action
    if event_class.type_name in ["action", "wrong_action", "warning_predicted"]:
        parameters["name"] = "test"

    # Create an event without metadata. When converting the `Event` to a
    # `dict`, it should not include a `metadata` property - unless it's a
    # `UserUttered` or a `BotUttered` event (or subclasses of them), in which
    # case the metadata should be included with a default value of {}.
    event = Event.from_parameters(parameters)

    if isinstance(event, BotUttered) or isinstance(event, UserUttered):
        assert event.as_dict()["metadata"] == {}
    else:
        assert "metadata" not in event.as_dict()
Example #16
0
    def _get_events_from_request_body(request: Request) -> List[Event]:
        events = request.json

        if not isinstance(events, list):
            events = [events]

        events = [Event.from_parameters(event) for event in events]
        events = [event for event in events if event]

        if not events:
            rasa.shared.utils.io.raise_warning(
                f"Append event called, but could not extract a valid event. "
                f"Request JSON: {request.json}"
            )
            raise ErrorResponse(
                400,
                "BadRequest",
                "Couldn't extract a proper event from the request body.",
                {"parameter": "", "in": "body"},
            )

        return events
Example #17
0
async def test_push_multiple_events(rasa_app: SanicASGITestClient):
    conversation_id = str(uuid.uuid1())
    conversation = f"/conversations/{conversation_id}"

    events = [e.as_dict() for e in test_events]
    _, response = await rasa_app.post(
        f"{conversation}/tracker/events",
        json=events,
        headers={"Content-Type": rasa.server.JSON_CONTENT_TYPE},
    )
    assert response.json() is not None
    assert response.status == 200

    _, tracker_response = await rasa_app.get(
        f"/conversations/{conversation_id}/tracker"
    )
    tracker = tracker_response.json()
    assert tracker is not None

    # there is an initial session start sequence at the beginning
    assert [
        Event.from_parameters(event) for event in tracker.get("events")
    ] == session_start_sequence + test_events
Example #18
0
def test_json_parse_undo():
    evt = {"event": "undo"}
    assert Event.from_parameters(evt) == ActionReverted()
Example #19
0
def test_json_parse_rewind():
    evt = {"event": "rewind"}
    assert Event.from_parameters(evt) == UserUtteranceReverted()
Example #20
0
def test_json_parse_bot():
    evt = {"event": "bot", "text": "Hey there!", "data": {}}
    assert Event.from_parameters(evt) == BotUttered("Hey there!", {})
Example #21
0
def test_json_parse_pause():
    evt = {"event": "pause"}
    assert Event.from_parameters(evt) == ConversationPaused()
Example #22
0
def test_json_parse_restarted():
    evt = {"event": "restart"}
    assert Event.from_parameters(evt) == Restarted()
Example #23
0
def test_json_parse_action():
    evt = {"event": "action", "name": "my_action"}
    assert Event.from_parameters(evt) == ActionExecuted("my_action")
Example #24
0
def test_json_parse_export():
    evt = {"event": "export"}
    assert Event.from_parameters(evt) == StoryExported()
Example #25
0
def test_json_parse_followup():
    evt = {"event": "followup", "name": "my_action"}
    assert Event.from_parameters(evt) == FollowupAction("my_action")
Example #26
0
def test_json_parse_session_started():
    evt = {"event": "session_started"}
    assert Event.from_parameters(evt) == SessionStarted()
Example #27
0
def test_json_parse_resume():
    evt = {"event": "resume"}
    assert Event.from_parameters(evt) == ConversationResumed()
Example #28
0
def test_json_parse_reset():
    evt = {"event": "reset_slots"}
    assert Event.from_parameters(evt) == AllSlotsReset()
Example #29
0
def test_json_parse_agent():
    evt = {"event": "agent", "text": "Hey, how are you?"}
    assert Event.from_parameters(evt) == AgentUttered("Hey, how are you?")
Example #30
0
def test_json_parse_setslot():
    evt = {"event": "slot", "name": "departure_airport", "value": "BER"}
    assert Event.from_parameters(evt) == SlotSet("departure_airport", "BER")