Skip to content
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
1 change: 1 addition & 0 deletions intercom/traits/api_resource.py
Original file line number Diff line number Diff line change
Expand Up @@ -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 = {}
Expand Down
9 changes: 5 additions & 4 deletions intercom/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -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):
Expand All @@ -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

Expand All @@ -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
18 changes: 17 additions & 1 deletion tests/unit/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -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": "<p>Hi Jane, it's all great thanks!</p>",
"created_at": 1400857494,
"updated_at": 1400857494,
"notified_at": 1400857587,
"assigned_to": None,
"author": {
"type": "user",
"id": "536e564f316c83104c000020"
},
"attachments": []
}
]
},
"open": None,
"read": True,
Expand Down
33 changes: 20 additions & 13 deletions tests/unit/test_notification.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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):
Expand All @@ -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):
Expand All @@ -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):
Expand Down
20 changes: 10 additions & 10 deletions tests/unit/test_user.py
Original file line number Diff line number Diff line change
Expand Up @@ -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_
Expand Down Expand Up @@ -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)
Expand All @@ -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)
Expand Down Expand Up @@ -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'))
Expand Down
17 changes: 17 additions & 0 deletions tests/unit/test_utils.py
Original file line number Diff line number Diff line change
@@ -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)