Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merge master into 4.5.0b5 #360

Merged
merged 2 commits into from
Oct 24, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 26 additions & 3 deletions libraries/botbuilder-core/botbuilder/core/turn_context.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,15 @@

import re
from copy import copy
from datetime import datetime
from typing import List, Callable, Union, Dict
from botbuilder.schema import Activity, ConversationReference, Mention, ResourceResponse
from botbuilder.schema import (
Activity,
ActivityTypes,
ConversationReference,
Mention,
ResourceResponse,
)


class TurnContext:
Expand Down Expand Up @@ -173,9 +180,11 @@ async def update_activity(self, activity: Activity):
:param activity:
:return:
"""
reference = TurnContext.get_conversation_reference(self.activity)

return await self._emit(
self._on_update_activity,
activity,
TurnContext.apply_conversation_reference(activity, reference),
self.adapter.update_activity(self, activity),
)

Expand Down Expand Up @@ -240,9 +249,23 @@ async def next_handler():
raise error

await emit_next(0)
# This should be changed to `return await logic()`
# logic does not use parentheses because it's a coroutine
return await logic

async def send_trace_activity(
self, name: str, value: object, value_type: str, label: str
) -> ResourceResponse:
trace_activity = Activity(
type=ActivityTypes.trace,
timestamp=datetime.utcnow(),
name=name,
value=value,
value_type=value_type,
label=label,
)

return await self.send_activity(trace_activity)

@staticmethod
def get_conversation_reference(activity: Activity) -> ConversationReference:
"""
Expand Down
54 changes: 51 additions & 3 deletions libraries/botbuilder-core/tests/test_turn_context.py
Original file line number Diff line number Diff line change
@@ -1,16 +1,18 @@
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License.

from typing import Callable, List
import aiounittest

from botbuilder.schema import (
Activity,
ActivityTypes,
ChannelAccount,
ConversationAccount,
Mention,
ResourceResponse,
)
from botbuilder.core import BotAdapter, TurnContext
from botbuilder.core import BotAdapter, MessageFactory, TurnContext

ACTIVITY = Activity(
id="1234",
Expand All @@ -33,18 +35,19 @@ async def send_activities(self, context, activities):
assert activities
for (idx, activity) in enumerate(activities): # pylint: disable=unused-variable
assert isinstance(activity, Activity)
assert activity.type == "message"
assert activity.type == "message" or activity.type == ActivityTypes.trace
responses.append(ResourceResponse(id="5678"))
return responses

async def update_activity(self, context, activity):
assert context is not None
assert activity is not None
return ResourceResponse(id=activity.id)

async def delete_activity(self, context, reference):
assert context is not None
assert reference is not None
assert reference.activity_id == "1234"
assert reference.activity_id == ACTIVITY.id


class TestBotContext(aiounittest.AsyncTestCase):
Expand Down Expand Up @@ -225,6 +228,26 @@ async def update_handler(context, activity, next_handler_coroutine):
await context.update_activity(ACTIVITY)
assert called is True

async def test_update_activity_should_apply_conversation_reference(self):
activity_id = "activity ID"
context = TurnContext(SimpleAdapter(), ACTIVITY)
called = False

async def update_handler(context, activity, next_handler_coroutine):
nonlocal called
called = True
assert context is not None
assert activity.id == activity_id
assert activity.conversation.id == ACTIVITY.conversation.id
await next_handler_coroutine()

context.on_update_activity(update_handler)
new_activity = MessageFactory.text("test text")
new_activity.id = activity_id
update_result = await context.update_activity(new_activity)
assert called is True
assert update_result.id == activity_id

def test_get_conversation_reference_should_return_valid_reference(self):
reference = TurnContext.get_conversation_reference(ACTIVITY)

Expand Down Expand Up @@ -298,3 +321,28 @@ def test_should_remove_at_mention_from_activity(self):

assert text, " test activity"
assert activity.text, " test activity"

async def test_should_send_a_trace_activity(self):
context = TurnContext(SimpleAdapter(), ACTIVITY)
called = False

# pylint: disable=unused-argument
async def aux_func(
ctx: TurnContext, activities: List[Activity], next: Callable
):
nonlocal called
called = True
assert isinstance(activities, list), "activities not array."
assert len(activities) == 1, "invalid count of activities."
assert activities[0].type == ActivityTypes.trace, "type wrong."
assert activities[0].name == "name-text", "name wrong."
assert activities[0].value == "value-text", "value worng."
assert activities[0].value_type == "valueType-text", "valeuType wrong."
assert activities[0].label == "label-text", "label wrong."
return []

context.on_send_activities(aux_func)
await context.send_trace_activity(
"name-text", "value-text", "valueType-text", "label-text"
)
assert called