async def test_undo_latest_msg(mock_endpoint): tracker_dump = rasa.shared.utils.io.read_file( "data/test_trackers/tracker_moodbot.json" ) sender_id = uuid.uuid4().hex url = "{}/conversations/{}/tracker?include_events=ALL".format( mock_endpoint.url, sender_id ) append_url = "{}/conversations/{}/tracker/events".format( mock_endpoint.url, sender_id ) with aioresponses() as mocked: mocked.get(url, body=tracker_dump) mocked.post(append_url) await interactive._undo_latest(sender_id, mock_endpoint) r = utilities.latest_request(mocked, "post", append_url) assert r # this should be the events the interactive call send to the endpoint # these events should have the last utterance omitted corrected_event = utilities.json_of_latest_request(r) assert corrected_event["event"] == "undo"
async def test_slackbot_send_image_url_threaded(): from rasa.core.channels.slack import SlackBot with aioresponses() as mocked: mocked.post( "https://www.slack.com/api/chat.postMessage", payload={ "ok": True, "purpose": "Testing bots" }, ) bot = SlackBot("DummyToken", "General", thread_id="DummyThread") url = "http://www.rasa.net" await bot.send_image_url("ID", url) r = latest_request(mocked, "POST", "https://www.slack.com/api/chat.postMessage") assert r request_params = json_of_latest_request(r) assert request_params["as_user"] is True assert request_params["channel"] == "General" assert request_params["thread_ts"] == "DummyThread" assert len(request_params["blocks"]) == 1 assert request_params["blocks"][0].get("type") == "image" assert request_params["blocks"][0].get( "alt_text") == "http://www.rasa.net" assert request_params["blocks"][0].get( "image_url") == "http://www.rasa.net"
async def test_slackbot_send_text(): from rasa.core.channels.slack import SlackBot with aioresponses() as mocked: mocked.post( "https://www.slack.com/api/chat.postMessage", payload={ "ok": True, "purpose": "Testing bots" }, ) bot = SlackBot("DummyToken", "General") await bot.send_text_message("ID", "my message") r = latest_request(mocked, "POST", "https://www.slack.com/api/chat.postMessage") assert r request_params = json_of_latest_request(r) assert request_params == { "as_user": True, "channel": "General", "text": "my message", "type": "mrkdwn", }
async def test_console_input(): from rasa.core.channels import console # Overwrites the input() function and when someone else tries to read # something from the command line this function gets called. with utilities.mocked_cmd_input(console, text="Test Input"): with aioresponses() as mocked: mocked.post( "https://example.com/webhooks/rest/webhook?stream=true", repeat=True, payload={}, ) await console.record_messages( server_url="https://example.com", max_message_limit=3 ) r = latest_request( mocked, "POST", "https://example.com/webhooks/rest/webhook?stream=true" ) assert r b = json_of_latest_request(r) assert b == {"message": "Test Input", "sender": "default"}
async def test_undo_latest_msg(mock_endpoint): tracker_dump = rasa.utils.io.read_file( "data/test_trackers/tracker_moodbot.json") tracker_json = json.loads(tracker_dump) evts = tracker_json.get("events") sender_id = uuid.uuid4().hex url = "{}/conversations/{}/tracker?include_events=ALL".format( mock_endpoint.url, sender_id) replace_url = "{}/conversations/{}/tracker/events".format( mock_endpoint.url, sender_id) with aioresponses() as mocked: mocked.get(url, body=tracker_dump) mocked.put(replace_url) await interactive._undo_latest(sender_id, mock_endpoint) r = latest_request(mocked, "put", replace_url) assert r # this should be the events the interactive call send to the endpoint # these events should have the last utterance omitted replaced_evts = json_of_latest_request(r) assert len(replaced_evts) == 6 assert replaced_evts == evts[:6]
async def test_slackbot_send_custom_json_threaded(): from rasa.core.channels.slack import SlackBot with aioresponses() as mocked: mocked.post( "https://www.slack.com/api/chat.postMessage", payload={ "ok": True, "purpose": "Testing bots" }, ) bot = SlackBot("DummyToken", "General", thread_id="DummyThread") await bot.send_custom_json("ID", {"test_key": "test_value"}) r = latest_request(mocked, "POST", "https://www.slack.com/api/chat.postMessage") assert r request_params = json_of_latest_request(r) assert request_params == { "as_user": True, "channel": "General", "thread_ts": "DummyThread", "test_key": "test_value", }
async def test_slackbot_send_attachment_with_text_threaded(): from rasa.core.channels.slack import SlackBot with aioresponses() as mocked: mocked.post( "https://www.slack.com/api/chat.postMessage", payload={ "ok": True, "purpose": "Testing bots" }, ) bot = SlackBot("DummyToken", "General", thread_id="DummyThread") attachment = SLACK_TEST_ATTACHMENT attachment["text"] = "Here is the summary:" await bot.send_attachment("ID", attachment) r = latest_request(mocked, "POST", "https://www.slack.com/api/chat.postMessage") assert r request_params = json_of_latest_request(r) assert request_params == { "channel": "General", "as_user": True, "attachments": [attachment], "thread_ts": "DummyThread", }
async def test_pushing_event_while_executing_side_effects( rasa_server: Sanic, params: Text ): input_channel = CallbackInput(EndpointConfig("https://example.com/callback")) channel.register([input_channel], rasa_server, "/webhooks/") rasa_app = rasa_server.asgi_client sender_id = str(uuid.uuid1()) conversation = f"/conversations/{sender_id}" serialized_event = test_events[1].as_dict() with aioresponses() as mocked: mocked.post( "https://example.com/callback", repeat=True, headers={"Content-Type": "application/json"}, ) await rasa_app.post( f"{conversation}/tracker/events{params}", json=serialized_event, headers={"Content-Type": rasa.server.JSON_CONTENT_TYPE}, ) r = latest_request(mocked, "post", "https://example.com/callback") if not params: assert r is None else: message_received = json_of_latest_request(r) assert message_received.get("recipient_id") == sender_id assert message_received.get("text") == serialized_event.get("text")
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"}]
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, }, }
async def test_slackbot_send_attachment_with_text(): from rasa.core.channels.slack import SlackBot with aioresponses() as mocked: mocked.post( "https://www.slack.com/api/chat.postMessage", payload={"ok": True, "purpose": "Testing bots"}, ) bot = SlackBot("DummyToken", "General") attachment = { "fallback": "Financial Advisor Summary", "color": "#36a64f", "author_name": "ABE", "title": "Financial Advisor Summary", "title_link": "http://tenfactorialrocks.com", "text": "Here is the summary:", "image_url": "https://r.com/cancel/r12", "thumb_url": "https://r.com/cancel/r12", "actions": [ { "type": "button", "text": "\ud83d\udcc8 Dashboard", "url": "https://r.com/cancel/r12", "style": "primary", }, { "type": "button", "text": "\ud83d\udccb XL", "url": "https://r.com/cancel/r12", "style": "danger", }, { "type": "button", "text": "\ud83d\udce7 E-Mail", "url": "https://r.com/cancel/r123", "style": "danger", }, ], "footer": "Powered by 1010rocks", "ts": 1531889719, } await bot.send_attachment("ID", attachment) r = latest_request(mocked, "POST", "https://www.slack.com/api/chat.postMessage") assert r request_params = json_of_latest_request(r) assert request_params == { "channel": "General", "as_user": True, "attachments": [attachment], }
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")
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"}, ]
async def test_http_interpreter(): with aioresponses() as mocked: mocked.post("https://example.com/model/parse") endpoint = EndpointConfig("https://example.com") interpreter = RasaNLUHttpInterpreter(endpoint=endpoint) await interpreter.parse(text="message_text") r = latest_request(mocked, "POST", "https://example.com/model/parse") query = json_of_latest_request(r) response = {"text": "message_text", "token": None} assert query == response
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, }, }
async def test_slackbot_send_text_with_buttons_threaded(): from rasa.core.channels.slack import SlackBot with aioresponses() as mocked: mocked.post( "https://www.slack.com/api/chat.postMessage", payload={ "ok": True, "purpose": "Testing bots" }, ) bot = SlackBot("DummyToken", "General", thread_id="DummyThread") buttons = [{"title": "title", "payload": "payload"}] await bot.send_text_with_buttons("ID", "my message", buttons) r = latest_request(mocked, "POST", "https://www.slack.com/api/chat.postMessage") assert r request_params = json_of_latest_request(r) text_block = { "type": "section", "text": { "type": "plain_text", "text": "my message" }, } button_block = { "type": "actions", "elements": [{ "type": "button", "text": { "type": "plain_text", "text": "title" }, "value": "payload", }], } assert request_params == { "as_user": True, "channel": "General", "text": "my message", "blocks": [text_block, button_block], "thread_ts": "DummyThread", }
async def test_endpoint_config(): with aioresponses() as mocked: endpoint = EndpointConfig( "https://example.com/", params={"A": "B"}, headers={"X-Powered-By": "Rasa"}, basic_auth={ "username": "******", "password": "******" }, token="mytoken", token_name="letoken", type="redis", port=6379, db=0, password="******", timeout=30000, ) mocked.post( "https://example.com/test?A=B&P=1&letoken=mytoken", payload={"ok": True}, repeat=True, status=200, ) await endpoint.request( "post", subpath="test", content_type="application/text", json={"c": "d"}, params={"P": "1"}, ) r = latest_request(mocked, "post", "https://example.com/test?A=B&P=1&letoken=mytoken") assert r assert json_of_latest_request(r) == {"c": "d"} assert r[-1].kwargs.get("params", {}).get("A") == "B" assert r[-1].kwargs.get("params", {}).get("P") == "1" assert r[-1].kwargs.get("params", {}).get("letoken") == "mytoken" # unfortunately, the mock library won't report any headers stored on # the session object, so we need to verify them separately async with endpoint.session() as s: assert s._default_headers.get("X-Powered-By") == "Rasa" assert s._default_auth.login == "user" assert s._default_auth.password == "pass"
async def test_send_message(mock_endpoint: EndpointConfig): sender_id = uuid.uuid4().hex url = f"{mock_endpoint.url}/conversations/{sender_id}/messages" with aioresponses() as mocked: mocked.post(url, payload={}) await interactive.send_message(mock_endpoint, sender_id, "Hello") r = utilities.latest_request(mocked, "post", url) assert r expected = {"sender": "user", "text": "Hello", "parse_data": None} assert utilities.json_of_latest_request(r) == expected
async def test_send_message(mock_endpoint): sender_id = uuid.uuid4().hex url = "{}/conversations/{}/messages".format(mock_endpoint.url, sender_id) with aioresponses() as mocked: mocked.post(url, payload={}) await interactive.send_message(mock_endpoint, sender_id, "Hello") r = latest_request(mocked, "post", url) assert r expected = {"sender": "user", "text": "Hello", "parse_data": None} assert json_of_latest_request(r) == expected
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_core.__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 } }
async def test_http_interpreter(endpoint_url, joined_url): with aioresponses() as mocked: mocked.post(joined_url) endpoint = EndpointConfig(endpoint_url) interpreter = RasaNLUHttpInterpreter(endpoint_config=endpoint) await interpreter.parse(text="message_text", message_id="message_id") r = latest_request(mocked, "POST", joined_url) query = json_of_latest_request(r) response = { "text": "message_text", "token": None, "message_id": "message_id" } assert query == response
async def test_http_parsing(): message = UserMessage("lunch?") endpoint = EndpointConfig("https://interpreter.com") with aioresponses() as mocked: mocked.post("https://interpreter.com/parse", repeat=True, status=200) inter = RasaNLUHttpInterpreter(endpoint=endpoint) try: await MessageProcessor(inter, None, None, None, None)._parse_message(message) except KeyError: pass # logger looks for intent and entities, so we except r = latest_request(mocked, "POST", "https://interpreter.com/parse") assert r assert json_of_latest_request(r)["message_id"] == message.message_id
async def test_http_interpreter(): with aioresponses() as mocked: mocked.post("https://example.com/parse") endpoint = EndpointConfig('https://example.com') interpreter = RasaNLUHttpInterpreter(endpoint=endpoint) await interpreter.parse(text='message_text', message_id='1134') r = latest_request(mocked, "POST", "https://example.com/parse") query = json_of_latest_request(r) response = { 'project': 'default', 'q': 'message_text', 'message_id': '1134', 'model': None, 'token': None } assert query == response
async def test_segment_gets_called(monkeypatch: MonkeyPatch): monkeypatch.setenv("RASA_TELEMETRY_WRITE_KEY", "foobar") monkeypatch.setenv("RASA_TELEMETRY_ENABLED", "true") telemetry.initialize_telemetry() with aioresponses() as mocked: mocked.post( "https://api.segment.io/v1/track", payload={}, ) await telemetry.track("test event", {"foo": "bar"}, {"foobar": "baz"}) r = utilities.latest_request(mocked, "POST", "https://api.segment.io/v1/track") assert r b = utilities.json_of_latest_request(r) assert "userId" in b assert b["event"] == "test event" assert b["properties"].get("foo") == "bar" assert b["context"].get("foobar") == "baz"
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")