def test_communicationtokencredential_token_expired_refresh_called(self):
     refresher = MagicMock(
         return_value=create_access_token(self.sample_token))
     credential = CommunicationTokenCredential(self.expired_token, token_refresher=refresher)
     access_token = credential.get_token()
     refresher.assert_called_once()
     self.assertEqual(access_token.token, self.sample_token)
    def test_proactive_refresher_should_be_called_after_specified_time(self):
        refresh_minutes = 10
        token_validity_minutes = 60
        start_timestamp = get_current_utc_as_int()
        skip_to_timestamp = start_timestamp + \
            (token_validity_minutes - refresh_minutes + 5) * 60

        initial_token = generate_token_with_custom_expiry(
            token_validity_minutes * 60)
        refreshed_token = generate_token_with_custom_expiry(
            2 * token_validity_minutes * 60)
        refresher = MagicMock(
            return_value=create_access_token(refreshed_token))

        with patch(user_credential.__name__+'.'+get_current_utc_as_int.__name__, return_value=skip_to_timestamp):
            credential = CommunicationTokenCredential(
                initial_token,
                token_refresher=refresher,
                proactive_refresh=True)
            access_token = credential.get_token()

            assert refresher.call_count == 1
            assert access_token.token == refreshed_token
            # check that next refresh is always scheduled
            assert credential._timer is not None
    def test_fractional_backoff_applied_when_token_expiring(self):
        token_validity_seconds = 5 * 60
        expiring_token = generate_token_with_custom_expiry(
            token_validity_seconds)

        refresher = MagicMock(side_effect=[
            create_access_token(expiring_token),
            create_access_token(expiring_token)
        ])

        credential = CommunicationTokenCredential(expiring_token,
                                                  token_refresher=refresher,
                                                  proactive_refresh=True)

        next_milestone = token_validity_seconds / 2

        with credential:
            assert credential._timer.interval == next_milestone
            with patch(user_credential.__name__ + '.' +
                       get_current_utc_as_int.__name__,
                       return_value=(get_current_utc_as_int() +
                                     next_milestone)):
                credential.get_token()
            assert refresher.call_count == 1
            next_milestone = next_milestone / 2
            assert credential._timer.interval == next_milestone
    def test_proactive_refresher_keeps_scheduling_again(self):
        refresh_minutes = 10
        token_validity_minutes = 60
        expired_token = generate_token_with_custom_expiry(-5 * 60)
        skip_to_timestamp = get_current_utc_as_int() + (token_validity_minutes -
                                                        refresh_minutes) * 60 + 1
        first_refreshed_token = create_access_token(
            generate_token_with_custom_expiry(token_validity_minutes * 60))
        last_refreshed_token = create_access_token(
            generate_token_with_custom_expiry(2 * token_validity_minutes * 60))
        refresher = MagicMock(
            side_effect=[first_refreshed_token, last_refreshed_token])

        credential = CommunicationTokenCredential(
            expired_token,
            token_refresher=refresher,
            proactive_refresh=True)
        access_token = credential.get_token()
        with patch(user_credential.__name__+'.'+get_current_utc_as_int.__name__, return_value=skip_to_timestamp):
            access_token = credential.get_token()
            
            assert refresher.call_count == 2
            assert access_token.token == last_refreshed_token.token
            # check that next refresh is always scheduled
            assert credential._timer is not None
 def test_communicationtokencredential_raises_if_refresher_returns_expired_token(self):
     refresher = MagicMock(
         return_value=create_access_token(self.expired_token))
     credential = CommunicationTokenCredential(self.expired_token, token_refresher=refresher)
     with self.assertRaises(ValueError):
         credential.get_token()
     self.assertEqual(refresher.call_count, 1)
    def test_uses_initial_token_as_expected(self):
        refresher = MagicMock(
            return_value=create_access_token(self.expired_token))
        credential = CommunicationTokenCredential(
            self.sample_token, token_refresher=refresher, proactive_refresh=True)
        access_token = credential.get_token()

        self.assertEqual(refresher.call_count, 0)
        self.assertEqual(access_token.token, self.sample_token)
 def test_communicationtokencredential_throws_if_proactive_refresh_enabled_without_token_refresher(self):
     with pytest.raises(ValueError) as err:
         CommunicationTokenCredential(self.sample_token, proactive_refresh=True)
     assert str(err.value) == "When 'proactive_refresh' is True, 'token_refresher' must not be None."
     with pytest.raises(ValueError) as err:
         CommunicationTokenCredential(
             self.sample_token, 
             proactive_refresh=True,
             token_refresher=None)
     assert str(err.value) == "When 'proactive_refresh' is True, 'token_refresher' must not be None."
    def test_refresher_should_not_be_called_when_token_still_valid(self):
        generated_token = generate_token_with_custom_expiry(15 * 60)
        new_token = generate_token_with_custom_expiry(10 * 60)
        refresher = MagicMock(return_value=create_access_token(new_token))

        credential = CommunicationTokenCredential(
            generated_token, token_refresher=refresher, proactive_refresh=False)
        for _ in range(10):
            access_token = credential.get_token()

        refresher.assert_not_called()
        assert generated_token == access_token.token
    def test_access_token_validation(self):
        """
        This is to make sure that consecutive calls made using the same chat_client or chat_thread_client
        does not throw an exception due to mismatch in the generation of azure.core.credentials.AccessToken
        """
        from azure.communication.identity._shared.user_token_refresh_options import \
            CommunicationTokenRefreshOptions as IdentityCommunicationTokenRefreshOptions

        # create ChatClient
        refresh_options = IdentityCommunicationTokenRefreshOptions(self.token)
        chat_client = ChatClient(self.endpoint, CommunicationTokenCredential(refresh_options))
        raised = False
        try:
            # create chat thread
            topic1 = "test topic1"
            create_chat_thread1_result = chat_client.create_chat_thread(topic1)
            self.thread_id = create_chat_thread1_result.chat_thread.id

            # get chat thread
            chat_thread1 = chat_client.get_chat_thread(create_chat_thread1_result.chat_thread.id)

            # get chat thread client
            chat_thread1_client = chat_client.get_chat_thread_client(self.thread_id)

            # list all chat threads
            chat_thead_infos = chat_client.list_chat_threads()
            for chat_threads_info_page in chat_thead_infos.by_page():
                for chat_thread_info in chat_threads_info_page:
                    print("ChatThreadInfo: ", chat_thread_info)
        except:
           raised = True

        assert raised is True
Exemple #10
0
 def create_chat_thread_client(self):
     token = self.token
     endpoint = self.endpoint
     user = self.user
     # [START create_chat_thread_client]
     from datetime import datetime
     from azure.communication.identity import CommunicationUserIdentifier
     from azure.communication.identity._shared.user_credential import CommunicationTokenCredential
     from azure.communication.chat._shared.user_token_refresh_options import CommunicationTokenRefreshOptions
     from azure.communication.chat import (ChatClient,
                                           ChatThreadParticipant)
     # retrieve `token` using CommunicationIdentityClient.get_token method
     # set `endpoint` to ACS service endpoint
     # create `user` using CommunicationIdentityClient.create_user method for new users;
     # else for existing users set `user` = CommunicationUserIdentifier(some_user_id)
     refresh_options = CommunicationTokenRefreshOptions(token)
     chat_client = ChatClient(endpoint,
                              CommunicationTokenCredential(refresh_options))
     topic = "test topic"
     participants = [
         ChatThreadParticipant(user=user,
                               display_name='name',
                               share_history_time=datetime.utcnow())
     ]
     create_chat_thread_result = chat_client.create_chat_thread(
         topic, thread_participants=participants)
     chat_thread_client = chat_client.get_chat_thread_client(
         create_chat_thread_result.chat_thread.id)
     # [END create_chat_thread_client]
     self._thread_id = create_chat_thread_result.chat_thread.id
     print("chat_thread_client created")
    def setUp(self):
        super(ChatClientTest, self).setUp()

        self.recording_processors.extend([
            BodyReplacerProcessor(keys=[
                "id", "token", "createdBy", "participants", "multipleStatus",
                "value"
            ]),
            URIIdentityReplacer(),
            ChatURIReplacer()
        ])

        self.identity_client = CommunicationIdentityClient.from_connection_string(
            self.connection_str)

        endpoint, _ = parse_connection_str(self.connection_str)
        self.endpoint = endpoint

        # create user and issue token
        self.user = self.identity_client.create_user()
        tokenresponse = self.identity_client.get_token(self.user,
                                                       scopes=["chat"])
        self.token = tokenresponse.token

        # create ChatClient
        refresh_options = CommunicationTokenRefreshOptions(self.token)
        self.chat_client = ChatClient(
            self.endpoint, CommunicationTokenCredential(refresh_options))
 def test_exit_cancels_timer(self):
     refreshed_token = create_access_token(
         generate_token_with_custom_expiry(30 * 60))
     refresher = MagicMock(return_value=refreshed_token)
     credential = CommunicationTokenCredential(self.expired_token,
                                               token_refresher=refresher,
                                               proactive_refresh=True)
     with credential:
         assert credential._timer is not None
     assert credential._timer is None
    def test_exit_enter_scenario_throws_exception(self):
        refreshed_token = create_access_token(
            generate_token_with_custom_expiry(30 * 60))
        refresher = MagicMock(return_value=refreshed_token)
        credential = CommunicationTokenCredential(
             self.expired_token,token_refresher=refresher, proactive_refresh=True)
        credential.get_token()
        credential.close()
        assert credential._timer is None

        with pytest.raises(RuntimeError) as err:
            credential.get_token()
        assert str(err.value) == "An instance of CommunicationTokenCredential cannot be reused once it has been closed."
Exemple #14
0
    def get_chat_thread_properties(self):
        thread_id = self._thread_id
        # [START get_thread]
        from azure.communication.chat import ChatClient
        from azure.communication.identity._shared.user_credential import CommunicationTokenCredential
        from azure.communication.chat._shared.user_token_refresh_options import CommunicationTokenRefreshOptions

        refresh_options = CommunicationTokenRefreshOptions(self.token)
        chat_client = ChatClient(self.endpoint,
                                 CommunicationTokenCredential(refresh_options))
        chat_thread_client = chat_client.get_chat_thread_client(thread_id)
        chat_thread_properties = chat_thread_client.get_properties()
        print('Expected Thread Id: ', thread_id, ' Actual Value: ',
              chat_thread_properties.id)
        # [END get_thread]

        print("get_chat_thread_properties succeeded, thread id: " +
              chat_thread.id + ", thread topic: " + chat_thread.topic)
 def test_communicationtokencredential_throws_if_invalid_token(self):
     refresh_options = CommunicationTokenRefreshOptions("foo.bar.tar")
     self.assertRaises(ValueError, lambda: CommunicationTokenCredential(refresh_options))
    def test_communicationtokencredential_decodes_token(self):
        refresh_options = CommunicationTokenRefreshOptions(self.sample_token)
        credential = CommunicationTokenCredential(refresh_options)
        access_token = credential.get_token()

        self.assertEqual(access_token.token, self.sample_token)
Exemple #17
0
class ChatThreadClientSamples(object):
    from azure.communication.identity import CommunicationIdentityClient
    from azure.communication.identity._shared.user_credential import CommunicationTokenCredential
    from azure.communication.chat._shared.user_token_refresh_options import CommunicationTokenRefreshOptions
    from azure.communication.chat import (ChatClient)
    connection_string = os.environ.get(
        "AZURE_COMMUNICATION_SERVICE_CONNECTION_STRING", None)
    if not connection_string:
        raise ValueError(
            "Set AZURE_COMMUNICATION_SERVICE_CONNECTION_STRING env before run this sample."
        )

    identity_client = CommunicationIdentityClient.from_connection_string(
        connection_string)
    user = identity_client.create_user()
    tokenresponse = identity_client.get_token(user, scopes=["chat"])
    token = tokenresponse.token

    endpoint = os.environ.get("AZURE_COMMUNICATION_SERVICE_ENDPOINT", None)
    if not endpoint:
        raise ValueError(
            "Set AZURE_COMMUNICATION_SERVICE_ENDPOINT env before run this sample."
        )

    _thread_id = None
    _message_id = None
    new_user = identity_client.create_user()

    refresh_options = CommunicationTokenRefreshOptions(token)
    _chat_client = ChatClient(endpoint,
                              CommunicationTokenCredential(refresh_options))

    def create_chat_thread_client(self):
        token = self.token
        endpoint = self.endpoint
        user = self.user
        # [START create_chat_thread_client]
        from datetime import datetime
        from azure.communication.identity import CommunicationUserIdentifier
        from azure.communication.identity._shared.user_credential import CommunicationTokenCredential
        from azure.communication.chat._shared.user_token_refresh_options import CommunicationTokenRefreshOptions
        from azure.communication.chat import (ChatClient,
                                              ChatThreadParticipant)
        # retrieve `token` using CommunicationIdentityClient.get_token method
        # set `endpoint` to ACS service endpoint
        # create `user` using CommunicationIdentityClient.create_user method for new users;
        # else for existing users set `user` = CommunicationUserIdentifier(some_user_id)
        refresh_options = CommunicationTokenRefreshOptions(token)
        chat_client = ChatClient(endpoint,
                                 CommunicationTokenCredential(refresh_options))
        topic = "test topic"
        participants = [
            ChatThreadParticipant(user=user,
                                  display_name='name',
                                  share_history_time=datetime.utcnow())
        ]
        create_chat_thread_result = chat_client.create_chat_thread(
            topic, thread_participants=participants)
        chat_thread_client = chat_client.get_chat_thread_client(
            create_chat_thread_result.chat_thread.id)
        # [END create_chat_thread_client]
        self._thread_id = create_chat_thread_result.chat_thread.id
        print("chat_thread_client created")

    def get_chat_thread_properties(self):
        thread_id = self._thread_id
        # [START get_thread]
        from azure.communication.chat import ChatClient
        from azure.communication.identity._shared.user_credential import CommunicationTokenCredential
        from azure.communication.chat._shared.user_token_refresh_options import CommunicationTokenRefreshOptions

        refresh_options = CommunicationTokenRefreshOptions(self.token)
        chat_client = ChatClient(self.endpoint,
                                 CommunicationTokenCredential(refresh_options))
        chat_thread_client = chat_client.get_chat_thread_client(thread_id)
        chat_thread_properties = chat_thread_client.get_properties()
        print('Expected Thread Id: ', thread_id, ' Actual Value: ',
              chat_thread_properties.id)
        # [END get_thread]

        print("get_chat_thread_properties succeeded, thread id: " +
              chat_thread.id + ", thread topic: " + chat_thread.topic)

    def update_topic(self):
        thread_id = self._thread_id
        chat_client = self._chat_client
        # [START update_topic]
        # set `thread_id` to an existing thread id
        chat_thread_client = chat_client.get_chat_thread_client(
            thread_id=thread_id)
        chat_thread_properties = chat_thread_client.get_properties()
        previous_topic = chat_thread_properties.topic

        topic = "updated thread topic"
        chat_thread_client.update_topic(topic=topic)

        chat_thread_properties = chat_thread_client.get_properties()
        updated_topic = chat_thread_properties.topic
        print("Chat Thread Topic Update: Previous value: ", previous_topic,
              ", Current value: ", updated_topic)
        # [END update_topic]

        print("update_chat_thread succeeded")

    def send_message(self):
        thread_id = self._thread_id
        chat_client = self._chat_client
        # [START send_message]
        from azure.communication.chat import ChatMessageType

        # set `thread_id` to an existing thread id
        chat_thread_client = chat_client.get_chat_thread_client(
            thread_id=thread_id)

        # Scenario 1: Send message without specifying chat_message_type
        send_message_result_id = chat_thread_client.send_message(
            "Hello! My name is Fred Flinstone",
            sender_display_name="Fred Flinstone")

        # Scenario 2: Send message specifying chat_message_type
        send_message_result_w_type_id = chat_thread_client.send_message(
            "Hello! My name is Wilma Flinstone",
            sender_display_name="Wilma Flinstone",
            chat_message_type=ChatMessageType.TEXT
        )  # equivalent to setting chat_message_type='text'

        # Verify message content
        print(
            "First Message:",
            chat_thread_client.get_message(
                send_message_result_id).content.message)
        print(
            "Second Message:",
            chat_thread_client.get_message(
                send_message_result_w_type_id).content.message)
        # [END send_message]

        self._message_id = send_message_result_id
        print("send_message succeeded, message_id=", send_message_result_id)
        print("send_message succeeded with type specified, message_id:",
              send_message_result_w_type_id)

    def get_message(self):
        thread_id = self._thread_id
        chat_client = self._chat_client
        message_id = self._message_id
        # [START get_message]
        # set `thread_id` to an existing thread id
        chat_thread_client = chat_client.get_chat_thread_client(
            thread_id=thread_id)

        # set `message_id` to an existing message id
        chat_message = chat_thread_client.get_message(message_id)

        print("Message received: ChatMessage: content=",
              chat_message.content.message, ", id=", chat_message.id)
        # [END get_message]

        print("get_message succeeded, message id:", chat_message.id, \
            "content: ", chat_message.content.message)

    def list_messages(self):
        thread_id = self._thread_id
        chat_client = self._chat_client
        # [START list_messages]
        from datetime import datetime, timedelta

        # set `thread_id` to an existing thread id
        chat_thread_client = chat_client.get_chat_thread_client(
            thread_id=thread_id)

        start_time = datetime.utcnow() - timedelta(days=1)
        chat_messages = chat_thread_client.list_messages(results_per_page=1,
                                                         start_time=start_time)

        print(
            "list_messages succeeded with results_per_page is 1, and start time is yesterday UTC"
        )
        for chat_message_page in chat_messages.by_page():
            for chat_message in chat_message_page:
                print("ChatMessage: message=", chat_message.content.message)
        # [END list_messages]
        print("list_messages succeeded")

    def update_message(self):
        thread_id = self._thread_id
        chat_client = self._chat_client
        message_id = self._message_id
        # [START update_message]
        # set `thread_id` to an existing thread id
        chat_thread_client = chat_client.get_chat_thread_client(
            thread_id=thread_id)

        # set `message_id` to an existing message id
        previous_content = chat_thread_client.get_message(
            message_id).content.message
        content = "updated content"
        chat_thread_client.update_message(message_id, content=content)

        current_content = chat_thread_client.get_message(
            message_id).content.message

        print("Chat Message Updated: Previous value: ", previous_content,
              ", Current value: ", current_content)
        # [END update_message]

        print("update_message succeeded")

    def send_read_receipt(self):
        thread_id = self._thread_id
        chat_client = self._chat_client
        message_id = self._message_id
        # [START send_read_receipt]
        # set `thread_id` to an existing thread id
        chat_thread_client = chat_client.get_chat_thread_client(
            thread_id=thread_id)

        # set `message_id` to an existing message id
        chat_thread_client.send_read_receipt(message_id)
        # [END send_read_receipt]

        print("send_read_receipt succeeded")

    def list_read_receipts(self):
        thread_id = self._thread_id
        chat_client = self._chat_client

        # [START list_read_receipts]
        # set `thread_id` to an existing thread id
        chat_thread_client = chat_client.get_chat_thread_client(
            thread_id=thread_id)

        read_receipts = chat_thread_client.list_read_receipts()

        for read_receipt_page in read_receipts.by_page():
            for read_receipt in read_receipt_page:
                print(read_receipt)
        # [END list_read_receipts]
        print("list_read_receipts succeeded")

    def delete_message(self):
        thread_id = self._thread_id
        chat_client = self._chat_client
        message_id = self._message_id

        # [START delete_message]
        # set `thread_id` to an existing thread id
        chat_thread_client = chat_client.get_chat_thread_client(
            thread_id=thread_id)

        # set `message_id` to an existing message id
        chat_thread_client.delete_message(message_id)
        # [END delete_message]
        print("delete_message succeeded")

    def list_participants(self):
        thread_id = self._thread_id
        chat_client = self._chat_client

        # [START list_participants]

        # set `thread_id` to an existing thread id
        chat_thread_client = chat_client.get_chat_thread_client(
            thread_id=thread_id)

        chat_thread_participants = chat_thread_client.list_participants()

        for chat_thread_participant_page in chat_thread_participants.by_page():
            for chat_thread_participant in chat_thread_participant_page:
                print("ChatThreadParticipant: ", chat_thread_participant)
        # [END list_participants]
        print("list_participants succeeded")

    def add_participant_w_check(self):
        # initially remove already added user
        thread_id = self._thread_id
        chat_client = self._chat_client
        user = self.new_user
        chat_thread_client = chat_client.get_chat_thread_client(
            thread_id=thread_id)

        chat_thread_client.remove_participant(user)

        # [START add_participant]
        from azure.communication.chat import ChatThreadParticipant
        from datetime import datetime

        def decide_to_retry(error):
            """
            Custom logic to decide whether to retry to add or not
            """
            return True

        # set `thread_id` to an existing thread id
        chat_thread_client = chat_client.get_chat_thread_client(
            thread_id=thread_id)

        # create `user` using CommunicationIdentityClient.create_user method for new users;
        # else for existing users set `user` = CommunicationUserIdentifier(some_user_id)
        new_chat_thread_participant = ChatThreadParticipant(
            user=user,
            display_name='name',
            share_history_time=datetime.utcnow())

        # check if participant has been added successfully
        try:
            chat_thread_client.add_participant(new_chat_thread_participant)
        except RuntimeError as e:
            if e is not None and decide_to_retry(error=e):
                chat_thread_client.add_participant(new_chat_thread_participant)
        # [END add_participant]
        print("add_participant_w_check succeeded")

    def add_participants_w_check(self):
        # initially remove already added user
        thread_id = self._thread_id
        chat_client = self._chat_client
        user = self.new_user
        chat_thread_client = chat_client.get_chat_thread_client(
            thread_id=thread_id)

        chat_thread_client.remove_participant(user)

        # [START add_participants]
        from azure.communication.chat import ChatThreadParticipant
        from datetime import datetime

        def decide_to_retry(error):
            """
            Custom logic to decide whether to retry to add or not
            """
            return True

        # set `thread_id` to an existing thread id
        chat_thread_client = chat_client.get_chat_thread_client(
            thread_id=thread_id)

        # create `user` using CommunicationIdentityClient.create_user method for new users;
        # else for existing users set `user` = CommunicationUserIdentifier(some_user_id)
        new_participant = ChatThreadParticipant(
            user=user,
            display_name='name',
            share_history_time=datetime.utcnow())

        # create list containing one or more participants
        thread_participants = [new_participant]
        result = chat_thread_client.add_participants(thread_participants)

        # list of participants which were unsuccessful to be added to chat thread
        retry = [p for p, e in result if decide_to_retry(e)]
        if len(retry) > 0:
            chat_thread_client.add_participants(retry)
        # [END add_participants]
        print("add_participants_w_check succeeded")

    def remove_participant(self):
        thread_id = self._thread_id
        chat_client = self._chat_client
        identity_client = self.identity_client

        # [START remove_participant]
        from azure.communication.chat import ChatThreadParticipant
        from azure.communication.identity import CommunicationUserIdentifier
        from datetime import datetime

        # create 2 new users using CommunicationIdentityClient.create_user method
        user1 = identity_client.create_user()
        user2 = identity_client.create_user()

        # set `thread_id` to an existing thread id
        chat_thread_client = chat_client.get_chat_thread_client(
            thread_id=thread_id)

        # add user1 and user2 to chat thread
        participant1 = ChatThreadParticipant(
            user=user1,
            display_name='Fred Flinstone',
            share_history_time=datetime.utcnow())

        participant2 = ChatThreadParticipant(
            user=user2,
            display_name='Wilma Flinstone',
            share_history_time=datetime.utcnow())

        thread_participants = [participant1, participant2]
        chat_thread_client.add_participants(thread_participants)

        # Option 1 : Iterate through all participants, find and delete Fred Flinstone
        chat_thread_participants = chat_thread_client.list_participants()

        for chat_thread_participant_page in chat_thread_participants.by_page():
            for chat_thread_participant in chat_thread_participant_page:
                print("ChatThreadParticipant: ", chat_thread_participant)
                if chat_thread_participant.user.identifier == user1.identifier:
                    print("Found Fred!")
                    chat_thread_client.remove_participant(
                        chat_thread_participant.user)
                    print("Fred has been removed from the thread...")
                    break

        # Option 2: Directly remove Wilma Flinstone
        unique_identifier = user2.identifier  # in real scenario the identifier would need to be retrieved from elsewhere
        chat_thread_client.remove_participant(
            CommunicationUserIdentifier(unique_identifier))
        print("Wilma has been removed from the thread...")
        # [END remove_participant]

        # clean up temporary users
        self.identity_client.delete_user(user1)
        self.identity_client.delete_user(user2)
        print("remove_chat_participant succeeded")

    def send_typing_notification(self):
        thread_id = self._thread_id
        chat_client = self._chat_client

        # [START send_typing_notification]
        # set `thread_id` to an existing thread id
        chat_thread_client = chat_client.get_chat_thread_client(
            thread_id=thread_id)

        chat_thread_client.send_typing_notification()
        # [END send_typing_notification]

        print("send_typing_notification succeeded")

    def clean_up(self):
        print("cleaning up: deleting created users.")
        self.identity_client.delete_user(self.user)
        self.identity_client.delete_user(self.new_user)
 def test_communicationtokencredential_decodes_token(self):
     credential = CommunicationTokenCredential(self.sample_token)
     access_token = credential.get_token()
     self.assertEqual(access_token.token, self.sample_token)
 def test_communicationtokencredential_static_token_returns_expired_token(self):
     credential = CommunicationTokenCredential(self.expired_token)
     self.assertEqual(credential.get_token().token, self.expired_token)
 def test_communicationtokencredential_throws_if_invalid_token(self):
     self.assertRaises(
         ValueError, lambda: CommunicationTokenCredential("foo.bar.tar"))
 def test_communicationtokencredential_throws_if_nonstring_token(self):
     self.assertRaises(TypeError, lambda: CommunicationTokenCredential(454))