Skip to content

Commit 3854b46

Browse files
authored
Merge pull request intercom#153 from jkeyes/lightweight-resource-type
Adding resource_type attribute to lightweight classes.
2 parents d5d706b + 9424913 commit 3854b46

File tree

6 files changed

+70
-28
lines changed

6 files changed

+70
-28
lines changed

intercom/traits/api_resource.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ def from_dict(self, dict):
7474
if hasattr(self, 'id'):
7575
# already exists in Intercom
7676
self.changed_attributes = []
77+
return self
7778

7879
def to_dict(self):
7980
a_dict = {}

intercom/utils.py

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ def entity_key_from_type(type):
2121

2222
def constantize_singular_resource_name(resource_name):
2323
class_name = inflection.camelize(resource_name)
24-
return create_class_instance(class_name)
24+
return define_lightweight_class(resource_name, class_name)
2525

2626

2727
def resource_class_to_collection_name(cls):
@@ -37,7 +37,8 @@ def resource_class_to_name(cls):
3737
CLASS_REGISTRY = {}
3838

3939

40-
def create_class_instance(class_name):
40+
def define_lightweight_class(resource_name, class_name):
41+
"""Return a lightweight class for deserialized payload objects."""
4142
from intercom.api_operations.load import Load
4243
from intercom.traits.api_resource import Resource
4344

@@ -51,8 +52,8 @@ def __new__(cls, name, bases, attributes):
5152

5253
@six.add_metaclass(Meta)
5354
class DynamicClass(Resource, Load):
54-
pass
55+
resource_type = resource_name
5556

56-
dyncls = DynamicClass()
57+
dyncls = DynamicClass
5758
CLASS_REGISTRY[class_name] = dyncls
5859
return dyncls

tests/unit/__init__.py

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -355,7 +355,23 @@ def page_of_companies(include_next_link=False):
355355
},
356356
"conversation_parts": {
357357
"type": "conversation_part.list",
358-
"conversation_parts": []
358+
"conversation_parts": [
359+
{
360+
"type": "conversation_part",
361+
"id": "4412",
362+
"part_type": "comment",
363+
"body": "<p>Hi Jane, it's all great thanks!</p>",
364+
"created_at": 1400857494,
365+
"updated_at": 1400857494,
366+
"notified_at": 1400857587,
367+
"assigned_to": None,
368+
"author": {
369+
"type": "user",
370+
"id": "536e564f316c83104c000020"
371+
},
372+
"attachments": []
373+
}
374+
]
359375
},
360376
"open": None,
361377
"read": True,

tests/unit/test_notification.py

Lines changed: 20 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
import unittest
44

55
from intercom.notification import Notification
6-
from intercom.utils import create_class_instance
6+
from intercom.utils import define_lightweight_class
77
from nose.tools import eq_
88
from nose.tools import istest
99
from tests.unit import test_conversation_notification
@@ -18,12 +18,12 @@ def it_converts_notification_hash_to_object(self):
1818
self.assertIsInstance(payload, Notification)
1919

2020
@istest
21-
def it_returns_correct_model_type_for_user(self):
21+
def it_returns_correct_resource_type_for_part(self):
2222
payload = Notification(**test_user_notification)
23-
User = create_class_instance('User') # noqa
23+
User = define_lightweight_class('user', 'User') # noqa
2424

25-
self.assertIsInstance(payload.model, User.__class__)
26-
eq_(payload.model_type, User.__class__)
25+
self.assertIsInstance(payload.model.__class__, User.__class__)
26+
eq_(payload.model_type.__class__, User.__class__)
2727

2828
@istest
2929
def it_returns_correct_user_notification_topic(self):
@@ -32,21 +32,21 @@ def it_returns_correct_user_notification_topic(self):
3232

3333
@istest
3434
def it_returns_instance_of_user(self):
35-
User = create_class_instance('User') # noqa
35+
User = define_lightweight_class('user', 'User') # noqa
3636
payload = Notification(**test_user_notification)
37-
self.assertIsInstance(payload.model, User.__class__)
37+
self.assertIsInstance(payload.model.__class__, User.__class__)
3838

3939
@istest
4040
def it_returns_instance_of_conversation(self):
41-
Conversation = create_class_instance('Conversation') # noqa
41+
Conversation = define_lightweight_class('conversation', 'Conversation') # noqa
4242
payload = Notification(**test_conversation_notification)
43-
self.assertIsInstance(payload.model, Conversation.__class__)
43+
self.assertIsInstance(payload.model.__class__, Conversation.__class__)
4444

4545
@istest
4646
def it_returns_correct_model_type_for_conversation(self):
47-
Conversation = create_class_instance('Conversation') # noqa
47+
Conversation = define_lightweight_class('conversation', 'Conversation') # noqa
4848
payload = Notification(**test_conversation_notification)
49-
eq_(payload.model_type, Conversation.__class__)
49+
eq_(payload.model_type.__class__, Conversation.__class__)
5050

5151
@istest
5252
def it_returns_correct_conversation_notification_topic(self):
@@ -55,9 +55,16 @@ def it_returns_correct_conversation_notification_topic(self):
5555

5656
@istest
5757
def it_returns_inner_user_object_for_conversation(self):
58-
User = create_class_instance('User') # noqa
58+
User = define_lightweight_class('user', 'User') # noqa
5959
payload = Notification(**test_conversation_notification)
60-
self.assertIsInstance(payload.model.user, User.__class__)
60+
self.assertIsInstance(payload.model.user.__class__, User.__class__)
61+
62+
@istest
63+
def it_returns_inner_conversation_parts_for_conversation(self):
64+
payload = Notification(**test_conversation_notification)
65+
conversation_parts = payload.data.item.conversation_parts
66+
eq_(1, len(conversation_parts))
67+
eq_('conversation_part', conversation_parts[0].resource_type)
6168

6269
@istest
6370
def it_returns_inner_user_object_with_nil_tags(self):

tests/unit/test_user.py

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
from intercom.client import Client
1313
from intercom.user import User
1414
from intercom import MultipleMatchingUsersError
15-
from intercom.utils import create_class_instance
15+
from intercom.utils import define_lightweight_class
1616
from mock import patch
1717
from nose.tools import assert_raises
1818
from nose.tools import eq_
@@ -69,17 +69,17 @@ def it_presents_a_complete_user_record_correctly(self):
6969
eq_(1393613864, calendar.timegm(user.remote_created_at.utctimetuple()))
7070
eq_(1401970114, calendar.timegm(user.updated_at.utctimetuple()))
7171

72-
Avatar = create_class_instance('Avatar') # noqa
73-
Company = create_class_instance('Company') # noqa
74-
SocialProfile = create_class_instance('SocialProfile') # noqa
75-
LocationData = create_class_instance('LocationData') # noqa
76-
self.assertIsInstance(user.avatar, Avatar.__class__)
72+
Avatar = define_lightweight_class('avatar', 'Avatar') # noqa
73+
Company = define_lightweight_class('company', 'Company') # noqa
74+
SocialProfile = define_lightweight_class('social_profile', 'SocialProfile') # noqa
75+
LocationData = define_lightweight_class('locaion_data', 'LocationData') # noqa
76+
self.assertIsInstance(user.avatar.__class__, Avatar.__class__)
7777
img_url = 'https://graph.facebook.com/1/picture?width=24&height=24'
7878
eq_(img_url, user.avatar.image_url)
7979

8080
self.assertIsInstance(user.companies, list)
8181
eq_(1, len(user.companies))
82-
self.assertIsInstance(user.companies[0], Company.__class__)
82+
self.assertIsInstance(user.companies[0].__class__, Company.__class__)
8383
eq_('123', user.companies[0].company_id)
8484
eq_('bbbbbbbbbbbbbbbbbbbbbbbb', user.companies[0].id)
8585
eq_('the-app-id', user.companies[0].app_id)
@@ -103,12 +103,12 @@ def it_presents_a_complete_user_record_correctly(self):
103103

104104
eq_(4, len(user.social_profiles))
105105
twitter_account = user.social_profiles[0]
106-
self.assertIsInstance(twitter_account, SocialProfile.__class__)
106+
self.assertIsInstance(twitter_account.__class__, SocialProfile.__class__)
107107
eq_('twitter', twitter_account.name)
108108
eq_('abc', twitter_account.username)
109109
eq_('http://twitter.com/abc', twitter_account.url)
110110

111-
self.assertIsInstance(user.location_data, LocationData.__class__)
111+
self.assertIsInstance(user.location_data.__class__, LocationData.__class__)
112112
eq_('Dublin', user.location_data.city_name)
113113
eq_('EU', user.location_data.continent_code)
114114
eq_('Ireland', user.location_data.country_name)
@@ -182,7 +182,7 @@ def it_fetches_a_user(self):
182182

183183
@istest
184184
def it_gets_users_by_tag(self):
185-
with patch.object(Client, 'get', return_value=page_of_users(False)) as mock_method:
185+
with patch.object(Client, 'get', return_value=page_of_users(False)):
186186
users = self.client.users.by_tag(124)
187187
for user in users:
188188
ok_(hasattr(user, 'avatar'))

tests/unit/test_utils.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
# -*- coding: utf-8 -*-
2+
"""Unit test module for utils.py."""
3+
import unittest
4+
5+
from intercom.utils import define_lightweight_class
6+
from nose.tools import eq_
7+
from nose.tools import istest
8+
9+
10+
class UserTest(unittest.TestCase): # noqa
11+
12+
@istest
13+
def it_has_a_resource_type(self): # noqa
14+
Avatar = define_lightweight_class('avatar', 'Avatar') # noqa
15+
eq_('avatar', Avatar.resource_type)
16+
avatar = Avatar()
17+
eq_('avatar', avatar.resource_type)

0 commit comments

Comments
 (0)