From 94249130f9f9373233f1c21d7a7ebb47f283eb77 Mon Sep 17 00:00:00 2001 From: John Keyes Date: Mon, 13 Feb 2017 21:55:58 +0000 Subject: [PATCH] Adding resource_type attribute to lightweight classes. --- intercom/traits/api_resource.py | 1 + intercom/utils.py | 9 +++++---- tests/unit/__init__.py | 18 +++++++++++++++++- tests/unit/test_notification.py | 33 ++++++++++++++++++++------------- tests/unit/test_user.py | 20 ++++++++++---------- tests/unit/test_utils.py | 17 +++++++++++++++++ 6 files changed, 70 insertions(+), 28 deletions(-) create mode 100644 tests/unit/test_utils.py diff --git a/intercom/traits/api_resource.py b/intercom/traits/api_resource.py index e9ac2b70..af929846 100644 --- a/intercom/traits/api_resource.py +++ b/intercom/traits/api_resource.py @@ -74,6 +74,7 @@ def from_dict(self, dict): if hasattr(self, 'id'): # already exists in Intercom self.changed_attributes = [] + return self def to_dict(self): a_dict = {} diff --git a/intercom/utils.py b/intercom/utils.py index 0350f873..d46ea998 100644 --- a/intercom/utils.py +++ b/intercom/utils.py @@ -21,7 +21,7 @@ def entity_key_from_type(type): def constantize_singular_resource_name(resource_name): class_name = inflection.camelize(resource_name) - return create_class_instance(class_name) + return define_lightweight_class(resource_name, class_name) def resource_class_to_collection_name(cls): @@ -37,7 +37,8 @@ def resource_class_to_name(cls): CLASS_REGISTRY = {} -def create_class_instance(class_name): +def define_lightweight_class(resource_name, class_name): + """Return a lightweight class for deserialized payload objects.""" from intercom.api_operations.load import Load from intercom.traits.api_resource import Resource @@ -51,8 +52,8 @@ def __new__(cls, name, bases, attributes): @six.add_metaclass(Meta) class DynamicClass(Resource, Load): - pass + resource_type = resource_name - dyncls = DynamicClass() + dyncls = DynamicClass CLASS_REGISTRY[class_name] = dyncls return dyncls diff --git a/tests/unit/__init__.py b/tests/unit/__init__.py index 5a76c1e4..f697b3d0 100644 --- a/tests/unit/__init__.py +++ b/tests/unit/__init__.py @@ -355,7 +355,23 @@ def page_of_companies(include_next_link=False): }, "conversation_parts": { "type": "conversation_part.list", - "conversation_parts": [] + "conversation_parts": [ + { + "type": "conversation_part", + "id": "4412", + "part_type": "comment", + "body": "

Hi Jane, it's all great thanks!

", + "created_at": 1400857494, + "updated_at": 1400857494, + "notified_at": 1400857587, + "assigned_to": None, + "author": { + "type": "user", + "id": "536e564f316c83104c000020" + }, + "attachments": [] + } + ] }, "open": None, "read": True, diff --git a/tests/unit/test_notification.py b/tests/unit/test_notification.py index 0ab3cb83..35759aad 100644 --- a/tests/unit/test_notification.py +++ b/tests/unit/test_notification.py @@ -3,7 +3,7 @@ import unittest from intercom.notification import Notification -from intercom.utils import create_class_instance +from intercom.utils import define_lightweight_class from nose.tools import eq_ from nose.tools import istest from tests.unit import test_conversation_notification @@ -18,12 +18,12 @@ def it_converts_notification_hash_to_object(self): self.assertIsInstance(payload, Notification) @istest - def it_returns_correct_model_type_for_user(self): + def it_returns_correct_resource_type_for_part(self): payload = Notification(**test_user_notification) - User = create_class_instance('User') # noqa + User = define_lightweight_class('user', 'User') # noqa - self.assertIsInstance(payload.model, User.__class__) - eq_(payload.model_type, User.__class__) + self.assertIsInstance(payload.model.__class__, User.__class__) + eq_(payload.model_type.__class__, User.__class__) @istest def it_returns_correct_user_notification_topic(self): @@ -32,21 +32,21 @@ def it_returns_correct_user_notification_topic(self): @istest def it_returns_instance_of_user(self): - User = create_class_instance('User') # noqa + User = define_lightweight_class('user', 'User') # noqa payload = Notification(**test_user_notification) - self.assertIsInstance(payload.model, User.__class__) + self.assertIsInstance(payload.model.__class__, User.__class__) @istest def it_returns_instance_of_conversation(self): - Conversation = create_class_instance('Conversation') # noqa + Conversation = define_lightweight_class('conversation', 'Conversation') # noqa payload = Notification(**test_conversation_notification) - self.assertIsInstance(payload.model, Conversation.__class__) + self.assertIsInstance(payload.model.__class__, Conversation.__class__) @istest def it_returns_correct_model_type_for_conversation(self): - Conversation = create_class_instance('Conversation') # noqa + Conversation = define_lightweight_class('conversation', 'Conversation') # noqa payload = Notification(**test_conversation_notification) - eq_(payload.model_type, Conversation.__class__) + eq_(payload.model_type.__class__, Conversation.__class__) @istest def it_returns_correct_conversation_notification_topic(self): @@ -55,9 +55,16 @@ def it_returns_correct_conversation_notification_topic(self): @istest def it_returns_inner_user_object_for_conversation(self): - User = create_class_instance('User') # noqa + User = define_lightweight_class('user', 'User') # noqa payload = Notification(**test_conversation_notification) - self.assertIsInstance(payload.model.user, User.__class__) + self.assertIsInstance(payload.model.user.__class__, User.__class__) + + @istest + def it_returns_inner_conversation_parts_for_conversation(self): + payload = Notification(**test_conversation_notification) + conversation_parts = payload.data.item.conversation_parts + eq_(1, len(conversation_parts)) + eq_('conversation_part', conversation_parts[0].resource_type) @istest def it_returns_inner_user_object_with_nil_tags(self): diff --git a/tests/unit/test_user.py b/tests/unit/test_user.py index 52860868..5f1cbf53 100644 --- a/tests/unit/test_user.py +++ b/tests/unit/test_user.py @@ -12,7 +12,7 @@ from intercom.client import Client from intercom.user import User from intercom import MultipleMatchingUsersError -from intercom.utils import create_class_instance +from intercom.utils import define_lightweight_class from mock import patch from nose.tools import assert_raises from nose.tools import eq_ @@ -69,17 +69,17 @@ def it_presents_a_complete_user_record_correctly(self): eq_(1393613864, calendar.timegm(user.remote_created_at.utctimetuple())) eq_(1401970114, calendar.timegm(user.updated_at.utctimetuple())) - Avatar = create_class_instance('Avatar') # noqa - Company = create_class_instance('Company') # noqa - SocialProfile = create_class_instance('SocialProfile') # noqa - LocationData = create_class_instance('LocationData') # noqa - self.assertIsInstance(user.avatar, Avatar.__class__) + Avatar = define_lightweight_class('avatar', 'Avatar') # noqa + Company = define_lightweight_class('company', 'Company') # noqa + SocialProfile = define_lightweight_class('social_profile', 'SocialProfile') # noqa + LocationData = define_lightweight_class('locaion_data', 'LocationData') # noqa + self.assertIsInstance(user.avatar.__class__, Avatar.__class__) img_url = 'https://graph.facebook.com/1/picture?width=24&height=24' eq_(img_url, user.avatar.image_url) self.assertIsInstance(user.companies, list) eq_(1, len(user.companies)) - self.assertIsInstance(user.companies[0], Company.__class__) + self.assertIsInstance(user.companies[0].__class__, Company.__class__) eq_('123', user.companies[0].company_id) eq_('bbbbbbbbbbbbbbbbbbbbbbbb', user.companies[0].id) eq_('the-app-id', user.companies[0].app_id) @@ -103,12 +103,12 @@ def it_presents_a_complete_user_record_correctly(self): eq_(4, len(user.social_profiles)) twitter_account = user.social_profiles[0] - self.assertIsInstance(twitter_account, SocialProfile.__class__) + self.assertIsInstance(twitter_account.__class__, SocialProfile.__class__) eq_('twitter', twitter_account.name) eq_('abc', twitter_account.username) eq_('http://twitter.com/abc', twitter_account.url) - self.assertIsInstance(user.location_data, LocationData.__class__) + self.assertIsInstance(user.location_data.__class__, LocationData.__class__) eq_('Dublin', user.location_data.city_name) eq_('EU', user.location_data.continent_code) eq_('Ireland', user.location_data.country_name) @@ -182,7 +182,7 @@ def it_fetches_a_user(self): @istest def it_gets_users_by_tag(self): - with patch.object(Client, 'get', return_value=page_of_users(False)) as mock_method: + with patch.object(Client, 'get', return_value=page_of_users(False)): users = self.client.users.by_tag(124) for user in users: ok_(hasattr(user, 'avatar')) diff --git a/tests/unit/test_utils.py b/tests/unit/test_utils.py new file mode 100644 index 00000000..9a1d8f7c --- /dev/null +++ b/tests/unit/test_utils.py @@ -0,0 +1,17 @@ +# -*- coding: utf-8 -*- +"""Unit test module for utils.py.""" +import unittest + +from intercom.utils import define_lightweight_class +from nose.tools import eq_ +from nose.tools import istest + + +class UserTest(unittest.TestCase): # noqa + + @istest + def it_has_a_resource_type(self): # noqa + Avatar = define_lightweight_class('avatar', 'Avatar') # noqa + eq_('avatar', Avatar.resource_type) + avatar = Avatar() + eq_('avatar', avatar.resource_type)