Exemple #1
0
async def test_remote_action_without_endpoint(default_channel, default_nlg,
                                              default_tracker, default_domain):
    remote_action = action.RemoteAction("my_action", None)

    with pytest.raises(Exception) as execinfo:
        await remote_action.run(default_channel, default_nlg, default_tracker,
                                default_domain)
    assert "Failed to execute custom action." in str(execinfo.value)
Exemple #2
0
async def test_remote_action_logs_events(default_dispatcher_collecting,
                                         default_domain):
    tracker = DialogueStateTracker("default",
                                   default_domain.slots)

    endpoint = EndpointConfig("https://example.com/webhooks/actions")
    remote_action = action.RemoteAction("my_action",
                                        endpoint)

    response = {
        "events": [
            {"event": "slot", "value": "rasa", "name": "name"}],
        "responses": [{"text": "test text",
                       "buttons": [{"title": "cheap", "payload": "cheap"}]},
                      {"template": "utter_greet"}]}

    with aioresponses() as mocked:
        mocked.post('https://example.com/webhooks/actions', payload=response)

        events = await remote_action.run(default_dispatcher_collecting,
                                         tracker,
                                         default_domain)

        r = latest_request(mocked, 'post',
                           "https://example.com/webhooks/actions")
        assert r

        assert json_of_latest_request(r) == {
            'domain': default_domain.as_dict(),
            'next_action': 'my_action',
            'sender_id': 'default',
            'version': rasa.__version__,
            'tracker': {
                'latest_message': {
                    'entities': [],
                    'intent': {},
                    'text': None
                },
                'active_form': {},
                'latest_action_name': None,
                'sender_id': 'default',
                'paused': False,
                'followup_action': 'action_listen',
                'latest_event_time': None,
                'slots': {'name': None},
                'events': [],
                'latest_input_channel': None
            }
        }

    assert events == [SlotSet("name", "rasa")]

    channel = default_dispatcher_collecting.output_channel
    assert channel.messages == [
        {"text": "test text", "recipient_id": "my-sender",
         "buttons": [{"title": "cheap", "payload": "cheap"}]},
        {"text": "hey there None!", "recipient_id": "my-sender"}]
Exemple #3
0
async def test_remote_action_endpoint_not_running(
    default_channel, default_nlg, default_tracker, domain: Domain
):
    endpoint = EndpointConfig("https://example.com/webhooks/actions")
    remote_action = action.RemoteAction("my_action", endpoint)

    with pytest.raises(Exception) as execinfo:
        await remote_action.run(default_channel, default_nlg, default_tracker, domain)
    assert "Failed to execute custom action." in str(execinfo.value)
Exemple #4
0
async def test_remote_action_runs(
    default_channel: OutputChannel,
    default_nlg: NaturalLanguageGenerator,
    default_tracker: DialogueStateTracker,
    domain: Domain,
):

    endpoint = EndpointConfig("https://example.com/webhooks/actions")
    remote_action = action.RemoteAction("my_action", endpoint)

    with aioresponses() as mocked:
        mocked.post(
            "https://example.com/webhooks/actions",
            payload={
                "events": [],
                "responses": []
            },
        )

        await remote_action.run(default_channel, default_nlg, default_tracker,
                                domain)

        r = latest_request(mocked, "post",
                           "https://example.com/webhooks/actions")

        assert r

        assert json_of_latest_request(r) == {
            "domain": domain.as_dict(),
            "next_action": "my_action",
            "sender_id": "my-sender",
            "version": rasa.__version__,
            "tracker": {
                "latest_message": {
                    "entities": [],
                    "intent": {},
                    "text": None,
                    "message_id": None,
                    "metadata": {},
                },
                ACTIVE_LOOP: {},
                "latest_action": {},
                "latest_action_name": None,
                "sender_id": "my-sender",
                "paused": False,
                "latest_event_time": None,
                FOLLOWUP_ACTION: "action_listen",
                "slots": {
                    "name": None,
                    REQUESTED_SLOT: None,
                    SESSION_START_METADATA_SLOT: None,
                },
                "events": [],
                "latest_input_channel": None,
            },
        }
Exemple #5
0
async def test_remote_action_without_endpoint(default_dispatcher_collecting,
                                              default_domain):
    tracker = DialogueStateTracker("default", default_domain.slots)

    remote_action = action.RemoteAction("my_action", None)

    with pytest.raises(Exception) as execinfo:
        await remote_action.run(default_dispatcher_collecting, tracker,
                                default_domain)
    assert "you didn't configure an endpoint" in str(execinfo.value)
Exemple #6
0
async def test_remote_action_logs_events(
    default_channel, default_nlg, default_tracker, default_domain
):
    endpoint = EndpointConfig("https://example.com/webhooks/actions")
    remote_action = action.RemoteAction("my_action", endpoint)

    response = {
        "events": [{"event": "slot", "value": "rasa", "name": "name"}],
        "responses": [
            {"text": "test text", "buttons": [{"title": "cheap", "payload": "cheap"}]},
            {"template": "utter_greet"},
        ],
    }

    with aioresponses() as mocked:
        mocked.post("https://example.com/webhooks/actions", payload=response)

        events = await remote_action.run(
            default_channel, default_nlg, default_tracker, default_domain
        )

        r = latest_request(mocked, "post", "https://example.com/webhooks/actions")
        assert r

        assert json_of_latest_request(r) == {
            "domain": default_domain.as_dict(),
            "next_action": "my_action",
            "sender_id": "my-sender",
            "version": rasa.__version__,
            "tracker": {
                "latest_message": {
                    "entities": [],
                    "intent": {},
                    "text": None,
                    "message_id": None,
                    "metadata": None,
                },
                "active_form": {},
                "latest_action_name": None,
                "sender_id": "my-sender",
                "paused": False,
                "followup_action": "action_listen",
                "latest_event_time": None,
                "slots": {"name": None},
                "events": [],
                "latest_input_channel": None,
            },
        }

    assert len(events) == 3  # first two events are bot utterances
    assert events[0] == BotUttered(
        "test text", {"buttons": [{"title": "cheap", "payload": "cheap"}]}
    )
    assert events[1] == BotUttered("hey there None!")
    assert events[2] == SlotSet("name", "rasa")
Exemple #7
0
async def test_remote_action_endpoint_not_running(
        default_dispatcher_collecting, default_domain):
    tracker = DialogueStateTracker("default", default_domain.slots)

    endpoint = EndpointConfig("https://example.com/webhooks/actions")
    remote_action = action.RemoteAction("my_action", endpoint)

    with pytest.raises(Exception) as execinfo:
        await remote_action.run(default_dispatcher_collecting, tracker,
                                default_domain)
    assert "Failed to execute custom action." in str(execinfo.value)
Exemple #8
0
async def test_remote_action_logs_events(default_dispatcher_collecting, default_domain):
    tracker = DialogueStateTracker("default", default_domain.slots)

    endpoint = EndpointConfig("https://example.com/webhooks/actions")
    remote_action = action.RemoteAction("my_action", endpoint)

    response = {
        "events": [{"event": "slot", "value": "rasa", "name": "name"}],
        "responses": [
            {"text": "test text", "buttons": [{"title": "cheap", "payload": "cheap"}]},
            {"template": "utter_greet"},
        ],
    }

    with aioresponses() as mocked:
        mocked.post("https://example.com/webhooks/actions", payload=response)

        events = await remote_action.run(
            default_dispatcher_collecting, tracker, default_domain
        )

        r = latest_request(mocked, "post", "https://example.com/webhooks/actions")
        assert r

        assert json_of_latest_request(r) == {
            "domain": default_domain.as_dict(),
            "next_action": "my_action",
            "sender_id": "default",
            "version": rasa.__version__,
            "tracker": {
                "latest_message": {"entities": [], "intent": {}, "text": None},
                "active_form": {},
                "latest_action_name": None,
                "sender_id": "default",
                "paused": False,
                "followup_action": "action_listen",
                "latest_event_time": None,
                "slots": {"name": None},
                "events": [],
                "latest_input_channel": None,
            },
        }

    assert events == [SlotSet("name", "rasa")]

    channel = default_dispatcher_collecting.output_channel
    assert channel.messages == [
        {
            "text": "test text",
            "recipient_id": "my-sender",
            "buttons": [{"title": "cheap", "payload": "cheap"}],
        },
        {"text": "hey there None!", "recipient_id": "my-sender"},
    ]
Exemple #9
0
async def test_remote_action_multiple_events_payload(
    default_channel: OutputChannel,
    default_nlg: NaturalLanguageGenerator,
    default_tracker: DialogueStateTracker,
    domain: Domain,
):
    endpoint = EndpointConfig("https://example.com/webhooks/actions")
    remote_action = action.RemoteAction("my_action", endpoint)
    response = {
        "events": [
            {
                "event": "action",
                "name": "action_listen",
                "policy": None,
                "confidence": None,
                "timestamp": None,
            },
            {
                "event": "slot",
                "name": "name",
                "value": None,
                "timestamp": None
            },
            {
                "event": "user",
                "timestamp": None,
                "text": "hello",
                "parse_data": {
                    "intent": {
                        "name": "greet",
                        "confidence": 0.99
                    },
                    "entities": [],
                },
            },
        ],
        "responses": [],
    }

    with aioresponses() as mocked:
        mocked.post("https://example.com/webhooks/actions", payload=response)

        events = await remote_action.run(default_channel, default_nlg,
                                         default_tracker, domain)

    assert isinstance(events[0], ActionExecuted)
    assert events[0].as_dict().get("name") == "action_listen"

    assert isinstance(events[1], SlotSet)
    assert events[1].as_dict().get("name") == "name"

    assert isinstance(events[2], UserUttered)
    assert events[2].as_dict().get("text") == "hello"
Exemple #10
0
async def test_remote_action_runs(default_channel, default_nlg,
                                  default_tracker, default_domain):

    endpoint = EndpointConfig("https://example.com/webhooks/actions")
    remote_action = action.RemoteAction("my_action", endpoint)

    with aioresponses() as mocked:
        mocked.post(
            "https://example.com/webhooks/actions",
            payload={
                "events": [],
                "responses": []
            },
        )

        await remote_action.run(default_channel, default_nlg, default_tracker,
                                default_domain)

        r = latest_request(mocked, "post",
                           "https://example.com/webhooks/actions")

        assert r

        assert json_of_latest_request(r) == {
            "domain": default_domain.as_dict(),
            "next_action": "my_action",
            "sender_id": "my-sender",
            "version": rasa.__version__,
            "tracker": {
                "latest_message": {
                    "entities": [],
                    "intent": {},
                    "text": None,
                    "message_id": None,
                    "metadata": {},
                },
                ACTIVE_LOOP: {},
                "latest_action": {},
                "latest_action_name": None,
                "sender_id": "my-sender",
                "paused": False,
                "latest_event_time": None,
                "followup_action": "action_listen",
                "slots": {
                    "name": None
                },
                "events": [],
                "latest_input_channel": None,
            },
        }
Exemple #11
0
async def test_remote_action_with_template_param(
    default_channel: OutputChannel,
    default_tracker: DialogueStateTracker,
    domain: Domain,
):
    endpoint = EndpointConfig("https://example.com/webhooks/actions")
    remote_action = action.RemoteAction("my_action", endpoint)

    response = {
        "events": [
            {
                "event": "form",
                "name": "restaurant_form",
                "timestamp": None
            },
            {
                "event": "slot",
                "timestamp": None,
                "name": "requested_slot",
                "value": "cuisine",
            },
        ],
        "responses": [{
            "text": None,
            "buttons": [],
            "elements": [],
            "custom": {},
            "template": "utter_ask_cuisine",
            "image": None,
            "attachment": None,
        }],
    }

    nlg = TemplatedNaturalLanguageGenerator(
        {"utter_ask_cuisine": [{
            "text": "what dou want to eat?"
        }]})
    with aioresponses() as mocked:
        mocked.post("https://example.com/webhooks/actions", payload=response)

        with pytest.warns(FutureWarning):
            events = await remote_action.run(default_channel, nlg,
                                             default_tracker, domain)

    assert events == [
        BotUttered("what dou want to eat?",
                   metadata={"utter_action": "utter_ask_cuisine"}),
        ActiveLoop("restaurant_form"),
        SlotSet("requested_slot", "cuisine"),
    ]
Exemple #12
0
async def test_remote_action_endpoint_responds_500(default_channel,
                                                   default_nlg,
                                                   default_tracker,
                                                   default_domain):
    endpoint = EndpointConfig("https://example.com/webhooks/actions")
    remote_action = action.RemoteAction("my_action", endpoint)

    with aioresponses() as mocked:
        mocked.post("https://example.com/webhooks/actions", status=500)

        with pytest.raises(Exception) as execinfo:
            await remote_action.run(default_channel, default_nlg,
                                    default_tracker, default_domain)
        assert "Failed to execute custom action." in str(execinfo.value)
Exemple #13
0
async def test_remote_action_runs(default_dispatcher_collecting,
                                  default_domain):
    tracker = DialogueStateTracker("default", default_domain.slots)

    endpoint = EndpointConfig("https://example.com/webhooks/actions")
    remote_action = action.RemoteAction("my_action", endpoint)

    with aioresponses() as mocked:
        mocked.post('https://example.com/webhooks/actions',
                    payload={
                        "events": [],
                        "responses": []
                    })

        await remote_action.run(default_dispatcher_collecting, tracker,
                                default_domain)

        r = latest_request(mocked, 'post',
                           "https://example.com/webhooks/actions")

        assert r

        assert json_of_latest_request(r) == {
            'domain': default_domain.as_dict(),
            'next_action': 'my_action',
            'sender_id': 'default',
            'version': rasa.__version__,
            'tracker': {
                'latest_message': {
                    'entities': [],
                    'intent': {},
                    'text': None
                },
                'active_form': {},
                'latest_action_name': None,
                'sender_id': 'default',
                'paused': False,
                'latest_event_time': None,
                'followup_action': 'action_listen',
                'slots': {
                    'name': None
                },
                'events': [],
                'latest_input_channel': None
            }
        }
Exemple #14
0
async def test_remote_action_utterances_with_none_values(
        default_channel, default_tracker, default_domain):
    endpoint = EndpointConfig("https://example.com/webhooks/actions")
    remote_action = action.RemoteAction("my_action", endpoint)

    response = {
        "events": [
            {
                "event": "form",
                "name": "restaurant_form",
                "timestamp": None
            },
            {
                "event": "slot",
                "timestamp": None,
                "name": "requested_slot",
                "value": "cuisine",
            },
        ],
        "responses": [{
            "text": None,
            "buttons": None,
            "elements": [],
            "custom": None,
            "template": "utter_ask_cuisine",
            "image": None,
            "attachment": None,
        }],
    }

    nlg = TemplatedNaturalLanguageGenerator(
        {"utter_ask_cuisine": [{
            "text": "what dou want to eat?"
        }]})
    with aioresponses() as mocked:
        mocked.post("https://example.com/webhooks/actions", payload=response)

        events = await remote_action.run(default_channel, nlg, default_tracker,
                                         default_domain)

    assert events == [
        BotUttered("what dou want to eat?"),
        Form("restaurant_form"),
        SlotSet("requested_slot", "cuisine"),
    ]
Exemple #15
0
async def test_remote_action_valid_payload_all_events(
    default_channel: OutputChannel,
    default_nlg: NaturalLanguageGenerator,
    default_tracker: DialogueStateTracker,
    domain: Domain,
    event: Event,
):
    endpoint = EndpointConfig("https://example.com/webhooks/actions")
    remote_action = action.RemoteAction("my_action", endpoint)
    events = [event.as_dict()]
    response = {"events": events, "responses": []}
    with aioresponses() as mocked:
        mocked.post("https://example.com/webhooks/actions", payload=response)

        events = await remote_action.run(default_channel, default_nlg,
                                         default_tracker, domain)

    assert len(events) == 1
Exemple #16
0
async def test_remote_action_endpoint_responds_400(
        default_dispatcher_collecting, default_domain):
    tracker = DialogueStateTracker("default", default_domain.slots)

    endpoint = EndpointConfig("https://example.com/webhooks/actions")
    remote_action = action.RemoteAction("my_action", endpoint)

    with aioresponses() as mocked:
        # noinspection PyTypeChecker
        mocked.post('https://example.com/webhooks/actions',
                    exception=ClientResponseError(
                        400, None, '{"action_name": "my_action"}'))

        with pytest.raises(Exception) as execinfo:
            await remote_action.run(default_dispatcher_collecting, tracker,
                                    default_domain)

    assert execinfo.type == ActionExecutionRejection
    assert "Custom action 'my_action' rejected to run" in str(execinfo.value)
Exemple #17
0
async def test_remote_action_endpoint_responds_400(
    default_channel, default_nlg, default_tracker, default_domain
):
    endpoint = EndpointConfig("https://example.com/webhooks/actions")
    remote_action = action.RemoteAction("my_action", endpoint)

    with aioresponses() as mocked:
        # noinspection PyTypeChecker
        mocked.post(
            "https://example.com/webhooks/actions",
            exception=ClientResponseError(400, None, '{"action_name": "my_action"}'),
        )

        with pytest.raises(Exception) as execinfo:
            await remote_action.run(
                default_channel, default_nlg, default_tracker, default_domain
            )

    assert execinfo.type == ActionExecutionRejection
    assert "Custom action 'my_action' rejected to run" in str(execinfo.value)
Exemple #18
0
async def test_remote_action_invalid_entities_payload(
    default_channel: OutputChannel,
    default_nlg: NaturalLanguageGenerator,
    default_tracker: DialogueStateTracker,
    domain: Domain,
    event: Event,
):

    endpoint = EndpointConfig("https://example.com/webhooks/actions")
    remote_action = action.RemoteAction("my_action", endpoint)
    response = {
        "events": [event],
        "responses": [],
    }
    with aioresponses() as mocked:
        mocked.post("https://example.com/webhooks/actions", payload=response)

        with pytest.raises(ValidationError) as e:
            await remote_action.run(default_channel, default_nlg,
                                    default_tracker, domain)

    assert "Failed to validate Action server response from API" in str(e.value)
Exemple #19
0
async def test_remote_action_logs_events(
    default_channel: OutputChannel,
    default_nlg: NaturalLanguageGenerator,
    default_tracker: DialogueStateTracker,
    domain: Domain,
):
    endpoint = EndpointConfig("https://example.com/webhooks/actions")
    remote_action = action.RemoteAction("my_action", endpoint)

    response = {
        "events": [{
            "event": "slot",
            "value": "rasa",
            "name": "name"
        }],
        "responses": [
            {
                "text": "test text",
                "response": None,
                "buttons": [{
                    "title": "cheap",
                    "payload": "cheap"
                }],
            },
            {
                "response": "utter_greet"
            },
        ],
    }

    with aioresponses() as mocked:
        mocked.post("https://example.com/webhooks/actions", payload=response)

        events = await remote_action.run(default_channel, default_nlg,
                                         default_tracker, domain)

        r = latest_request(mocked, "post",
                           "https://example.com/webhooks/actions")
        assert r

        assert json_of_latest_request(r) == {
            "domain": domain.as_dict(),
            "next_action": "my_action",
            "sender_id": "my-sender",
            "version": rasa.__version__,
            "tracker": {
                "latest_message": {
                    "entities": [],
                    "intent": {},
                    "text": None,
                    "message_id": None,
                    "metadata": {},
                },
                ACTIVE_LOOP: {},
                "latest_action": {},
                "latest_action_name": None,
                "sender_id": "my-sender",
                "paused": False,
                FOLLOWUP_ACTION: ACTION_LISTEN_NAME,
                "latest_event_time": None,
                "slots": {
                    "name": None,
                    REQUESTED_SLOT: None,
                    SESSION_START_METADATA_SLOT: None,
                },
                "events": [],
                "latest_input_channel": None,
            },
        }
    assert len(events) == 3  # first two events are bot utterances
    assert events[0] == BotUttered(
        "test text", {"buttons": [{
            "title": "cheap",
            "payload": "cheap"
        }]})
    assert events[1] == BotUttered("hey there None!",
                                   metadata={"utter_action": "utter_greet"})
    assert events[2] == SlotSet("name", "rasa")