def __init__(self, parent, definition): """Constructor. Required Arguments: parent: Account object - parent is an Account object. definition: a dictionary of parameters. The 'gmail_thread_id' parameter is required to make method calls. """ super(Thread, self).__init__(parent, 'threads/{gmail_thread_id}', definition) # This is going to be gross - prepare yourself if "messages" in definition: from contextio.lib.resources.message import Message self.messages = [ Message(self.parent, message) for message in definition['messages'] ] if 'sources' in definition: from contextio.lib.resources.source import Source self.sources = [ Source(self.parent, source) for source in definition['sources'] ]
def test_get_thread_sets_thread_subject_if_message_has_subject(self, mock_request): mock_request.return_value = { "messages": [{"message_id": "foo", "gmail_thread_id": "foobar"} ] } params = { "include_body": 1, "include_headers": 1, "include_flags": 1, "body_type": "foobar", "limit": 1, "offset": 1 } message = Message(Mock(spec=[]), {"message_id": "fake_message_id", "subject": "catpants"}) message.get_thread(**params) self.assertEqual("catpants", message.thread.subject)
def test_get_thread_sets_thread_subject_if_message_has_subject( self, mock_request): mock_request.return_value = { "messages": [{ "message_id": "foo", "gmail_thread_id": "foobar" }] } params = { "include_body": 1, "include_headers": 1, "include_flags": 1, "body_type": "foobar", "limit": 1, "offset": 1 } message = Message(Mock(spec=[]), { "message_id": "fake_message_id", "subject": "catpants" }) message.get_thread(**params) self.assertEqual("catpants", message.thread.subject)
def get_messages(self, **params): """Get current listings of email messages in a given folder. NOTE: this gets all messages including since last sync. It's fresher, but expect slower performance than using Account.get_messages() Documentation: http://context.io/docs/2.0/accounts/sources/folders/messages#get Optional Arguments: include_thread_size: integer - Set to 1 to include thread size in the result. include_body: integer - Set to 1 to include message bodies in the result. Since message bodies must be retrieved from the IMAP server, expect a performance hit when setting this parameter. body_type: string - Used when include_body is set to get only body parts of a given MIME-type (for example text/html) include_headers: mixed - Can be set to 0 (default), 1 or raw. If set to 1, complete message headers, parsed into an array, are included in the results. If set to raw, the headers are also included but as a raw unparsed string. Since full original headers bodies must be retrieved from the IMAP server, expect a performance hit when setting this parameter. include_flags: integer - Set to 1 to include IMAP flags for this message in the result. Since message flags must be retrieved from the IMAP server, expect a performance hit when setting this parameter. flag_seen: integer - Set to 1 to restrict list to messages having the \Seen flag set, set to 0 to have the messages with that flag unset (ie. list unread messages in the folder). limit: integer - The maximum number of results to return. offset: integer - Start the list at this offset (zero-based). Returns: a list of Message objects. """ all_args = [ "include_thread_size", "include_body", "body_type", "include_headers", "include_flags", "flag_seen", "limit", "offset" ] params = helpers.sanitize_params(params, all_args) return [ Message(self, obj) for obj in self._request_uri('messages', params=params) ]
def test_constructor_creates_message_object_with_all_attributes_in_keys_list_for_v2_0_api( self): mock_parent = Mock() mock_parent.api_version = "2.0" message = Message(mock_parent, {"message_id": "fake_message_id"}) self.assertTrue(hasattr(message, 'date')) self.assertTrue(hasattr(message, 'date_indexed')) self.assertTrue(hasattr(message, 'addresses')) self.assertTrue(hasattr(message, 'person_info')) self.assertTrue(hasattr(message, 'email_message_id')) self.assertTrue(hasattr(message, 'message_id')) self.assertTrue(hasattr(message, 'gmail_message_id')) self.assertTrue(hasattr(message, 'gmail_thread_id')) self.assertTrue(hasattr(message, 'files')) self.assertTrue(hasattr(message, 'subject')) self.assertTrue(hasattr(message, 'folders')) self.assertTrue(hasattr(message, 'sources'))
def get_messages(self, **params): """List messages where a contact is present. Documentation: http://context.io/docs/2.0/accounts/contacts/messages#get Optional Arguments: limit: integer - The maximum number of results to return. offset: integer - Start the list at this offset (zero-based). Returns: A list of Message objects """ all_args = ['limit', 'offset'] params = helpers.sanitize_params(params, all_args) return [ Message(self.parent, obj) for obj in self._request_uri('messages', params=params) ]
def test_constructor_creates_message_object_with_all_attributes_in_keys_list_for_lite_api( self): mock_parent = Mock() mock_parent.api_version = "lite" message = Message(mock_parent, {"message_id": "fake_message_id"}) self.assertTrue(hasattr(message, "sent_at")) self.assertTrue(hasattr(message, "addresses")) self.assertTrue(hasattr(message, "subject")) self.assertTrue(hasattr(message, "email_message_id")) self.assertTrue(hasattr(message, "message_id")) self.assertTrue(hasattr(message, "list_headers")) self.assertTrue(hasattr(message, "in_reply_to")) self.assertTrue(hasattr(message, "references")) self.assertTrue(hasattr(message, "attachments")) self.assertTrue(hasattr(message, "bodies")) self.assertTrue(hasattr(message, "received_headers")) self.assertTrue(hasattr(message, "folders")) self.assertTrue(hasattr(message, "resource_url")) self.assertTrue(hasattr(message, "person_info"))
def get_messages(self, **params): """List email messages for an account. GET method for the messages resource. Each of the email, to, from, cc and bcc parameters can be set to a comma-separated list of email addresses. These multiple addresses are treated as an OR combination. You can set more than one parameter when doing this call. Multiple parameters are treated as an AND combination. Optional Arguments: subject: string - Get messages whose subject matches this search string. To use regular expressions instead of simple string matching, make sure the string starts and ends with /. email: string - Email address of the contact for whom you want the latest messages exchanged with. By "exchanged with contact X" we mean any email received from contact X, sent to contact X or sent by anyone to both contact X and the source owner. to: string - Email address of a contact messages have been sent to. sender: string - Email address of a contact messages have been received from. Same as "from" in documentation. "from" is a python keyword and we can't use that... cc: string - Email address of a contact CC'ed on the messages. bcc: string - Email address of a contact BCC'ed on the messages. folder: string - Filter messages by the folder (or Gmail label). This parameter can be the complete folder name with the appropriate hierarchy delimiter for the mail server being queried (eg. Inbox/My folder) or the "symbolic name" of the folder (eg. \Starred). The symbolic name refers to attributes used to refer to special use folders in a language-independant way. See http://code.google.com/apis/gmail/imap/#xlist (Gmail specific) and RFC-6154. source: string - Filter messages by the account source label. file_name: string - Search for files based on their name. You can filter names using typical shell wildcards such as *, ? and [] or regular expressions by enclosing the search expression in a leading / and trailing /. For example, *.pdf would give you all PDF files while /\.jpe?g$/ would return all files whose name ends with .jpg or .jpeg file_size_min: integer - Search for files based on their size (in bytes). file_size_max: integer - Search for files based on their size (in bytes). date_before: integer (unix time) - Only include messages before a given timestamp. The value this filter is applied to is the Date: header of the message which refers to the time the message is sent from the origin. date_after: integer (unix time) - Only include messages after a given timestamp. The value this filter is applied to is the Date: header of the message which refers to the time the message is sent from the origin. indexed_before: integer (unix time) - Only include messages indexed before a given timestamp. This is not the same as the date of the email, it is the time Context.IO indexed this message. indexed_after: integer (unix time) - Only include messages indexed after a given timestamp. This is not the same as the date of the email, it is the time Context.IO indexed this message. include_thread_size: integer - Set to 1 to include thread size in the result. include_body: integer - Set to 1 to include message bodies in the result. Since message bodies must be retrieved from the IMAP server, expect a performance hit when setting this parameter. include_headers: mixed - Can be set to 0 (default), 1 or raw. If set to 1, complete message headers, parsed into an array, are included in the results. If set to raw, the headers are also included but as a raw unparsed string. Since full original headers bodies must be retrieved from the IMAP server, expect a performance hit when setting this parameter. include_flags: integer - Set to 1 to include IMAP flags of messages in the result. Since message flags must be retrieved from the IMAP server, expect a performance hit when setting this parameter. body_type: string - Used when include_body is set to get only body parts of a given MIME-type (for example text/html) include_source: integer - Set to 1 to include message sources in the result. Since message sources must be retrieved from the IMAP server, expect a performance hit when setting this parameter. sort_order: string - The sort order of the returned results. Possible values are asc and desc limit: integer - The maximum number of results to return. offset: integer - Start the list at this offset (zero-based). Returns: A list of Message objects. """ all_args = [ "subject", "email", "to", "sender", "from_", "cc", "bcc", "folder", "date_before", "date_after", "indexed_before", "indexed_after", "include_thread_size", "include_body", "source", "file_name", "file_size_min", "file_size_max", "include_source", "include_headers", "include_flags", "body_type", "sort_order", "limit", "offset" ] params = helpers.sanitize_params(params, all_args) # workaround to send param "from" even though it's a reserved keyword # in python if 'sender' in params: params['from'] = params['sender'] del params['sender'] if 'from_' in params: params['from'] = params['from_'] del params['from_'] return [ Message(self, obj) for obj in self._request_uri('messages', params=params) ]
def setUp(self): self.message = Message(Mock(spec=[]), {"message_id": "fake_message_id"})
class TestMessage(unittest.TestCase): def setUp(self): self.message = Message(Mock(spec=[]), {"message_id": "fake_message_id"}) def test_constructor_creates_message_object_with_all_attributes_in_keys_list_for_v2_0_api( self): mock_parent = Mock() mock_parent.api_version = "2.0" message = Message(mock_parent, {"message_id": "fake_message_id"}) self.assertTrue(hasattr(message, 'date')) self.assertTrue(hasattr(message, 'date_indexed')) self.assertTrue(hasattr(message, 'addresses')) self.assertTrue(hasattr(message, 'person_info')) self.assertTrue(hasattr(message, 'email_message_id')) self.assertTrue(hasattr(message, 'message_id')) self.assertTrue(hasattr(message, 'gmail_message_id')) self.assertTrue(hasattr(message, 'gmail_thread_id')) self.assertTrue(hasattr(message, 'files')) self.assertTrue(hasattr(message, 'subject')) self.assertTrue(hasattr(message, 'folders')) self.assertTrue(hasattr(message, 'sources')) def test_constructor_creates_message_object_with_all_attributes_in_keys_list_for_lite_api( self): mock_parent = Mock() mock_parent.api_version = "lite" message = Message(mock_parent, {"message_id": "fake_message_id"}) self.assertTrue(hasattr(message, "sent_at")) self.assertTrue(hasattr(message, "addresses")) self.assertTrue(hasattr(message, "subject")) self.assertTrue(hasattr(message, "email_message_id")) self.assertTrue(hasattr(message, "message_id")) self.assertTrue(hasattr(message, "list_headers")) self.assertTrue(hasattr(message, "in_reply_to")) self.assertTrue(hasattr(message, "references")) self.assertTrue(hasattr(message, "attachments")) self.assertTrue(hasattr(message, "bodies")) self.assertTrue(hasattr(message, "received_headers")) self.assertTrue(hasattr(message, "folders")) self.assertTrue(hasattr(message, "resource_url")) self.assertTrue(hasattr(message, "person_info")) @patch("contextio.lib.resources.base_resource.BaseResource.post") def test_post_sends_params_and_returns_True(self, mock_post): params = { "flag_answered": 0, "flag_draft": 0, "dst_folder": "foo", "dst_source": "bar", "move": 0, "flag_seen": 0, "flag_flagged": 0, "flag_deleted": 0 } all_args = [ 'flag_answered', 'move', 'dst_folder', 'dst_source', 'flag_seen', 'flag_flagged', 'flag_deleted', 'flag_draft' ] self.message.post(**params) mock_post.assert_called_with(all_args=all_args, params=params, required_args=['dst_folder'], return_bool=True) @patch("contextio.lib.resources.base_resource.BaseResource.post") def test_post_is_called_with_correct_args(self, mock_post): mock_post.return_value = {"success": True} req_args = [ 'dst_folder', ] all_args = [ 'flag_answered', 'move', 'dst_folder', 'dst_source', 'flag_seen', 'flag_flagged', 'flag_deleted', 'flag_draft' ] self.message.post(return_bool=False, dst_folder="foobar") mock_post.assert_called_with(return_bool=False, params={"dst_folder": "foobar"}, all_args=all_args, required_args=req_args) @patch("contextio.lib.resources.base_resource.BaseResource._request_uri") def test_delete_returns_boolean(self, mock_request): deleted_message = self.message.delete() self.assertEqual(True, deleted_message) @patch("contextio.lib.resources.base_resource.BaseResource._request_uri") def test_get_body_returns_list_of_dictionaries(self, mock_request): mock_request.return_value = [{"foo": "bar"}] response = self.message.get_body(type="foobar") mock_request.assert_called_with("body", params={"type": "foobar"}) self.assertEqual(1, len(response)) self.assertEqual([{"foo": "bar"}], response) @patch("contextio.lib.resources.base_resource.BaseResource._request_uri") def test_get_flags_returns_a_dictionary(self, mock_request): mock_request.return_value = {"foo": "bar"} response = self.message.get_flags() mock_request.assert_called_with("flags") self.assertEqual({"foo": "bar"}, self.message.flags) self.assertEqual({"foo": "bar"}, response) @patch("contextio.lib.resources.base_resource.BaseResource._request_uri") def test_post_flag_calls_request_uri_with_correct_args(self, mock_request): params = { "seen": 1, "answered": 1, "flagged": 1, "deleted": 0, "draft": 1 } mock_request.return_value = {"success": True, "flags": ["foo", "bar"]} response = self.message.post_flag(**params) mock_request.assert_called_with("flags", method="POST", params=params) self.assertEqual(["foo", "bar"], self.message.flags) self.assertTrue(response) @patch("contextio.lib.resources.base_resource.BaseResource._request_uri") def test_get_folders_returns_a_list_of_dictionaries(self, mock_request): mock_request.return_value = [{"foo": "bar"}] response = self.message.get_folders() mock_request.assert_called_with("folders") self.assertEqual([{"foo": "bar"}], self.message.folders) self.assertEqual([{"foo": "bar"}], response) @patch("contextio.lib.resources.base_resource.BaseResource.post") def test_post_folder_calls_request_uri_with_correct_args( self, mock_request): params = {"add": "catpants", "remove": "dogpants"} mock_request.return_value = {"success": True} response = self.message.post_folder(**params) mock_request.assert_called_with("folders", params=params) self.assertTrue(response) @patch("contextio.lib.resources.base_resource.BaseResource._request_uri") def test_put_folders_calls_request_uri_with_correct_args( self, mock_request): body = "catpants" mock_request.return_value = {"success": True, "flags": ["foo", "bar"]} response = self.message.put_folders(body) mock_request.assert_called_with("folders", method="PUT", body=body) self.assertEqual("catpants", self.message.folders) self.assertTrue(response) @patch("contextio.lib.resources.base_resource.BaseResource._request_uri") def test_get_headers_returns_a_dictionary(self, mock_request): mock_request.return_value = {"foo": "bar"} response = self.message.get_headers(raw=1) mock_request.assert_called_with("headers", params={"raw": 1}) self.assertEqual({"foo": "bar"}, self.message.headers) self.assertEqual({"foo": "bar"}, response) @patch("contextio.lib.resources.base_resource.BaseResource._request_uri") def test_get_source_returns_a_string(self, mock_request): mock_request.return_value = "catpants" response = self.message.get_source() mock_request.assert_called_with("source") self.assertEqual("catpants", self.message.source) self.assertEqual("catpants", response) @patch("contextio.lib.resources.base_resource.BaseResource._request_uri") def test_get_thread_returns_response_body_object_when_thread_id_exists( self, mock_request): mock_request.return_value = "catpants" response = self.message.get_source() mock_request.assert_called_with("source") self.assertEqual("catpants", self.message.source) self.assertEqual("catpants", response) @patch("contextio.lib.resources.base_resource.BaseResource._request_uri") def test_get_thread_returns_a_Thread_object_when_thread_id_exists( self, mock_request): mock_request.return_value = { "messages": [{ "message_id": "foo", "gmail_thread_id": "foobar" }] } params = { "include_body": 1, "include_headers": 1, "include_flags": 1, "body_type": "foobar", "limit": 1, "offset": 1 } response = self.message.get_thread(**params) mock_request.assert_called_with("thread", params=params) self.assertEqual(response, self.message.thread) self.assertIsInstance(response, Thread) @patch("contextio.lib.resources.base_resource.BaseResource._request_uri") def test_get_thread_returns_response_body_when_thread_id_does_not_exist( self, mock_request): mock_request.return_value = {"foo": "bar"} params = { "include_body": 1, "include_headers": 1, "include_flags": 1, "body_type": "foobar", "limit": 1, "offset": 1 } response = self.message.get_thread(**params) mock_request.assert_called_with("thread", params=params) self.assertEqual({"foo": "bar"}, self.message.thread) self.assertEqual({"foo": "bar"}, response) @patch("contextio.lib.resources.base_resource.BaseResource._request_uri") def test_get_thread_sets_thread_subject_if_message_has_subject( self, mock_request): mock_request.return_value = { "messages": [{ "message_id": "foo", "gmail_thread_id": "foobar" }] } params = { "include_body": 1, "include_headers": 1, "include_flags": 1, "body_type": "foobar", "limit": 1, "offset": 1 } message = Message(Mock(spec=[]), { "message_id": "fake_message_id", "subject": "catpants" }) message.get_thread(**params) self.assertEqual("catpants", message.thread.subject)
class TestMessage(unittest.TestCase): def setUp(self): self.message = Message(Mock(spec=[]), {"message_id": "fake_message_id"}) def test_constructor_creates_message_object_with_all_attributes_in_keys_list_for_v2_0_api(self): mock_parent = Mock() mock_parent.api_version = "2.0" message = Message(mock_parent, {"message_id": "fake_message_id"}) self.assertTrue(hasattr(message, 'date')) self.assertTrue(hasattr(message, 'date_indexed')) self.assertTrue(hasattr(message, 'addresses')) self.assertTrue(hasattr(message, 'person_info')) self.assertTrue(hasattr(message, 'email_message_id')) self.assertTrue(hasattr(message, 'message_id')) self.assertTrue(hasattr(message, 'gmail_message_id')) self.assertTrue(hasattr(message, 'gmail_thread_id')) self.assertTrue(hasattr(message, 'files')) self.assertTrue(hasattr(message, 'subject')) self.assertTrue(hasattr(message, 'folders')) self.assertTrue(hasattr(message, 'sources')) def test_constructor_creates_message_object_with_all_attributes_in_keys_list_for_lite_api(self): mock_parent = Mock() mock_parent.api_version = "lite" message = Message(mock_parent, {"message_id": "fake_message_id"}) self.assertTrue(hasattr(message, "sent_at")) self.assertTrue(hasattr(message, "addresses")) self.assertTrue(hasattr(message, "subject")) self.assertTrue(hasattr(message, "email_message_id")) self.assertTrue(hasattr(message, "message_id")) self.assertTrue(hasattr(message, "list_headers")) self.assertTrue(hasattr(message, "in_reply_to")) self.assertTrue(hasattr(message, "references")) self.assertTrue(hasattr(message, "attachments")) self.assertTrue(hasattr(message, "bodies")) self.assertTrue(hasattr(message, "received_headers")) self.assertTrue(hasattr(message, "folders")) self.assertTrue(hasattr(message, "resource_url")) self.assertTrue(hasattr(message, "person_info")) @patch("contextio.lib.resources.base_resource.BaseResource.post") def test_post_sends_params_and_returns_True(self, mock_post): params = { "flag_answered": 0, "flag_draft": 0, "dst_folder": "foo", "dst_source": "bar", "move": 0, "flag_seen": 0, "flag_flagged": 0, "flag_deleted": 0 } all_args = ['flag_answered', 'move', 'dst_folder', 'dst_source', 'flag_seen', 'flag_flagged', 'flag_deleted', 'flag_draft'] self.message.post(**params) mock_post.assert_called_with( all_args=all_args, params=params, required_args=['dst_folder'], return_bool=True) @patch("contextio.lib.resources.base_resource.BaseResource.post") def test_post_is_called_with_correct_args(self, mock_post): mock_post.return_value = {"success": True} req_args = ['dst_folder', ] all_args = [ 'flag_answered', 'move', 'dst_folder', 'dst_source', 'flag_seen', 'flag_flagged', 'flag_deleted', 'flag_draft' ] self.message.post(return_bool=False, dst_folder="foobar") mock_post.assert_called_with(return_bool=False, params={"dst_folder": "foobar"}, all_args=all_args, required_args=req_args) @patch("contextio.lib.resources.base_resource.BaseResource._request_uri") def test_delete_returns_boolean(self, mock_request): deleted_message = self.message.delete() self.assertEqual(True, deleted_message) @patch("contextio.lib.resources.base_resource.BaseResource._request_uri") def test_get_body_returns_list_of_dictionaries(self, mock_request): mock_request.return_value = [{"foo": "bar"}] response = self.message.get_body(type="foobar") mock_request.assert_called_with("body", params={"type": "foobar"}) self.assertEqual(1, len(response)) self.assertEqual([{"foo": "bar"}], response) @patch("contextio.lib.resources.base_resource.BaseResource._request_uri") def test_get_flags_returns_a_dictionary(self, mock_request): mock_request.return_value = {"foo": "bar"} response = self.message.get_flags() mock_request.assert_called_with("flags") self.assertEqual({"foo": "bar"}, self.message.flags) self.assertEqual({"foo": "bar"}, response) @patch("contextio.lib.resources.base_resource.BaseResource._request_uri") def test_post_flag_calls_request_uri_with_correct_args(self, mock_request): params = {"seen":1, "answered":1, "flagged":1, "deleted":0, "draft":1} mock_request.return_value = {"success": True, "flags": ["foo", "bar"]} response = self.message.post_flag(**params) mock_request.assert_called_with("flags", method="POST", params=params) self.assertEqual(["foo", "bar"], self.message.flags) self.assertTrue(response) @patch("contextio.lib.resources.base_resource.BaseResource._request_uri") def test_get_folders_returns_a_list_of_dictionaries(self, mock_request): mock_request.return_value = [{"foo": "bar"}] response = self.message.get_folders() mock_request.assert_called_with("folders") self.assertEqual([{"foo": "bar"}], self.message.folders) self.assertEqual([{"foo": "bar"}], response) @patch("contextio.lib.resources.base_resource.BaseResource.post") def test_post_folder_calls_request_uri_with_correct_args(self, mock_request): params = {"add": "catpants", "remove": "dogpants"} mock_request.return_value = {"success": True} response = self.message.post_folder(**params) mock_request.assert_called_with("folders", params=params) self.assertTrue(response) @patch("contextio.lib.resources.base_resource.BaseResource._request_uri") def test_put_folders_calls_request_uri_with_correct_args(self, mock_request): body = "catpants" mock_request.return_value = {"success": True, "flags": ["foo", "bar"]} response = self.message.put_folders(body) mock_request.assert_called_with("folders", method="PUT", body=body) self.assertEqual("catpants", self.message.folders) self.assertTrue(response) @patch("contextio.lib.resources.base_resource.BaseResource._request_uri") def test_get_headers_returns_a_dictionary(self, mock_request): mock_request.return_value = {"foo": "bar"} response = self.message.get_headers(raw=1) mock_request.assert_called_with("headers", params={"raw": 1}) self.assertEqual({"foo": "bar"}, self.message.headers) self.assertEqual({"foo": "bar"}, response) @patch("contextio.lib.resources.base_resource.BaseResource._request_uri") def test_get_source_returns_a_string(self, mock_request): mock_request.return_value = "catpants" response = self.message.get_source() mock_request.assert_called_with("source") self.assertEqual("catpants", self.message.source) self.assertEqual("catpants", response) @patch("contextio.lib.resources.base_resource.BaseResource._request_uri") def test_get_thread_returns_response_body_object_when_thread_id_exists(self, mock_request): mock_request.return_value = "catpants" response = self.message.get_source() mock_request.assert_called_with("source") self.assertEqual("catpants", self.message.source) self.assertEqual("catpants", response) @patch("contextio.lib.resources.base_resource.BaseResource._request_uri") def test_get_thread_returns_a_Thread_object_when_thread_id_exists(self, mock_request): mock_request.return_value = { "messages": [{"message_id": "foo","gmail_thread_id": "foobar"}] } params = { "include_body": 1, "include_headers": 1, "include_flags": 1, "body_type": "foobar", "limit": 1, "offset": 1 } response = self.message.get_thread(**params) mock_request.assert_called_with("thread", params=params) self.assertEqual(response, self.message.thread) self.assertIsInstance(response, Thread) @patch("contextio.lib.resources.base_resource.BaseResource._request_uri") def test_get_thread_returns_response_body_when_thread_id_does_not_exist(self, mock_request): mock_request.return_value = {"foo": "bar"} params = { "include_body": 1, "include_headers": 1, "include_flags": 1, "body_type": "foobar", "limit": 1, "offset": 1 } response = self.message.get_thread(**params) mock_request.assert_called_with("thread", params=params) self.assertEqual({"foo": "bar"}, self.message.thread) self.assertEqual({"foo": "bar"}, response) @patch("contextio.lib.resources.base_resource.BaseResource._request_uri") def test_get_thread_sets_thread_subject_if_message_has_subject(self, mock_request): mock_request.return_value = { "messages": [{"message_id": "foo", "gmail_thread_id": "foobar"} ] } params = { "include_body": 1, "include_headers": 1, "include_flags": 1, "body_type": "foobar", "limit": 1, "offset": 1 } message = Message(Mock(spec=[]), {"message_id": "fake_message_id", "subject": "catpants"}) message.get_thread(**params) self.assertEqual("catpants", message.thread.subject)