Merge lp:~robru/friends/twitter-retweet into lp:friends

Proposed by Robert Bruce Park
Status: Merged
Approved by: Ken VanDine
Approved revision: 190
Merged at revision: 189
Proposed branch: lp:~robru/friends/twitter-retweet
Merge into: lp:friends
Diff against target: 159 lines (+67/-9)
5 files modified
friends/protocols/twitter.py (+16/-1)
friends/tests/data/twitter-retweet.dat (+1/-0)
friends/tests/mocks.py (+1/-0)
friends/tests/test_identica.py (+3/-2)
friends/tests/test_twitter.py (+46/-6)
To merge this branch: bzr merge lp:~robru/friends/twitter-retweet
Reviewer Review Type Date Requested Status
Ken VanDine Approve
PS Jenkins bot (community) continuous-integration Approve
Review via email: mp+158724@code.launchpad.net

Commit message

Fix Twitter.retweet (LP: #1168427)

Description of the change

Fixes Twitter.retweet method, which wasn't supplying sender name / avatar correctly due to the information being missing from twitter.

To post a comment you must log in.
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :

FAILED: Continuous integration, rev:189
http://jenkins.qa.ubuntu.com/job/friends-ci/28/
Executed test runs:
    FAILURE: http://jenkins.qa.ubuntu.com/job/friends-raring-amd64-ci/28/console

Click here to trigger a rebuild:
http://s-jenkins:8080/job/friends-ci/28/rebuild

review: Needs Fixing (continuous-integration)
lp:~robru/friends/twitter-retweet updated
190. By Robert Bruce Park

Add twitter-retweet.dat data file.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :

PASSED: Continuous integration, rev:190
http://jenkins.qa.ubuntu.com/job/friends-ci/29/
Executed test runs:
    SUCCESS: http://jenkins.qa.ubuntu.com/job/friends-raring-amd64-ci/29

Click here to trigger a rebuild:
http://s-jenkins:8080/job/friends-ci/29/rebuild

review: Approve (continuous-integration)
Revision history for this message
Ken VanDine (ken-vandine) wrote :

Great!

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'friends/protocols/twitter.py'
2--- friends/protocols/twitter.py 2013-04-03 03:47:39 +0000
3+++ friends/protocols/twitter.py 2013-04-12 22:22:26 +0000
4@@ -78,6 +78,11 @@
5 self._account.secret_token = authdata.get('TokenSecret')
6 self._account.user_id = authdata.get('UserId')
7 self._account.user_name = authdata.get('ScreenName')
8+ user = self._showuser(self._account.user_id)
9+ self._account.user_full_name = user.get('name', '')
10+ self._account.avatar_url = (user.get('profile_image_url_https') or
11+ user.get('profile_image_url') or
12+ '')
13
14 def _get_url(self, url, data=None):
15 """Access the Twitter API with correct OAuth signed headers."""
16@@ -284,6 +289,15 @@
17 """Republish somebody else's tweet with your name on it."""
18 url = self._retweet.format(message_id)
19 tweet = self._get_url(url, dict(trim_user='true'))
20+ user = tweet.get('user', {}) or tweet.get('sender', {})
21+
22+ # Fill in the blanks...
23+ user.update(
24+ name=self._account.user_full_name,
25+ screen_name=self._account.user_name,
26+ profile_image_url=self._account.avatar_url,
27+ )
28+
29 return self._publish_tweet(tweet)
30
31 # https://dev.twitter.com/docs/api/1.1/post/friendships/destroy
32@@ -356,7 +370,8 @@
33 # https://dev.twitter.com/docs/api/1.1/get/users/show
34 def _showuser(self, uid):
35 """Get all the information about a twitter user."""
36- url = self._api_base.format(endpoint="users/show") + "?user_id={}".format(uid)
37+ url = self._api_base.format(
38+ endpoint='users/show') + '?user_id={}'.format(uid)
39 return self._get_url(url)
40
41 def _create_contact(self, userdata):
42
43=== added file 'friends/tests/data/twitter-retweet.dat'
44--- friends/tests/data/twitter-retweet.dat 1970-01-01 00:00:00 +0000
45+++ friends/tests/data/twitter-retweet.dat 2013-04-12 22:22:26 +0000
46@@ -0,0 +1,1 @@
47+{"place":null,"user":{"id_str":"836242932","id":836242932},"retweet_count":6,"created_at":"Fri Apr 12 20:23:14 +0000 2013","geo":null,"contributors":null,"retweeted":true,"id_str":"322807141108944896","coordinates":null,"truncated":false,"retweeted_status":{"place":null,"user":{"id_str":"45840709","id":45840709},"retweet_count":6,"created_at":"Fri Apr 12 16:52:59 +0000 2013","geo":null,"contributors":null,"retweeted":true,"id_str":"322754231591387136","coordinates":null,"truncated":false,"in_reply_to_status_id":null,"in_reply_to_screen_name":null,"possibly_sensitive":false,"favorited":false,"text":"Reading 'Core utility apps visual exploration' at Design http:\/\/t.co\/36tT53C37n","in_reply_to_status_id_str":null,"source":"\u003Ca href=\"http:\/\/twitter.com\/tweetbutton\" rel=\"nofollow\"\u003ETweet Button\u003C\/a\u003E","id":322754231591387136,"in_reply_to_user_id_str":null,"entities":{"hashtags":[],"user_mentions":[],"urls":[{"url":"http:\/\/t.co\/36tT53C37n","display_url":"design.canonical.com\/2013\/04\/core-u\u2026","indices":[57,79],"expanded_url":"http:\/\/design.canonical.com\/2013\/04\/core-utility-apps-visual-exploration\/"}]},"in_reply_to_user_id":null},"in_reply_to_status_id":null,"in_reply_to_screen_name":null,"possibly_sensitive":false,"favorited":false,"text":"RT @ubuntudesigners: Reading 'Core utility apps visual exploration' at Design http:\/\/t.co\/36tT53C37n","in_reply_to_status_id_str":null,"source":"\u003Ca href=\"http:\/\/www.ubuntu.com\" rel=\"nofollow\"\u003EUbuntu Online Accounts\u003C\/a\u003E","id":322807141108944896,"in_reply_to_user_id_str":null,"entities":{"hashtags":[],"user_mentions":[{"name":"Ubuntu Designers","screen_name":"ubuntudesigners","id_str":"45840709","indices":[3,19],"id":45840709}],"urls":[{"url":"http:\/\/t.co\/36tT53C37n","display_url":"design.canonical.com\/2013\/04\/core-u\u2026","indices":[78,100],"expanded_url":"http:\/\/design.canonical.com\/2013\/04\/core-utility-apps-visual-exploration\/"}]},"in_reply_to_user_id":null}
48
49=== modified file 'friends/tests/mocks.py'
50--- friends/tests/mocks.py 2013-04-05 01:02:42 +0000
51+++ friends/tests/mocks.py 2013-04-12 22:22:26 +0000
52@@ -119,6 +119,7 @@
53 def __init__(self, service=None, account_id=88):
54 self.access_token = None
55 self.secret_token = None
56+ self.avatar_url = None
57 self.user_full_name = None
58 self.user_name = None
59 self.user_id = None
60
61=== modified file 'friends/tests/test_identica.py'
62--- friends/tests/test_identica.py 2013-04-03 03:47:39 +0000
63+++ friends/tests/test_identica.py 2013-04-12 22:22:26 +0000
64@@ -169,12 +169,13 @@
65 dict(trim_user='true'))
66
67 def test_retweet(self):
68- get_url = self.protocol._get_url = mock.Mock(return_value='tweet')
69+ tweet=dict(tweet='twit')
70+ get_url = self.protocol._get_url = mock.Mock(return_value=tweet)
71 publish = self.protocol._publish_tweet = mock.Mock()
72
73 self.protocol.retweet('1234')
74
75- publish.assert_called_with('tweet')
76+ publish.assert_called_with(tweet)
77 get_url.assert_called_with(
78 'http://identi.ca/api/statuses/retweet/1234.json',
79 dict(trim_user='true'))
80
81=== modified file 'friends/tests/test_twitter.py'
82--- friends/tests/test_twitter.py 2013-04-02 21:46:47 +0000
83+++ friends/tests/test_twitter.py 2013-04-12 22:22:26 +0000
84@@ -69,12 +69,17 @@
85 @mock.patch('friends.utils.authentication.Authentication.login',
86 return_value=dict(AccessToken='some clever fake data',
87 TokenSecret='sssssshhh!',
88- UserId='rickygervais',
89- ScreenName='Ricky Gervais'))
90+ UserId='1234',
91+ ScreenName='stephenfry'))
92+ @mock.patch('friends.protocols.twitter.Twitter._showuser',
93+ return_value=dict(name='Stephen Fry',
94+ profile_image_url='http://example.com/me.jpg'))
95 def test_successful_authentication(self, *mocks):
96 self.assertTrue(self.protocol._login())
97- self.assertEqual(self.account.user_name, 'Ricky Gervais')
98- self.assertEqual(self.account.user_id, 'rickygervais')
99+ self.assertEqual(self.account.avatar_url, 'http://example.com/me.jpg')
100+ self.assertEqual(self.account.user_full_name, 'Stephen Fry')
101+ self.assertEqual(self.account.user_name, 'stephenfry')
102+ self.assertEqual(self.account.user_id, '1234')
103 self.assertEqual(self.account.access_token, 'some clever fake data')
104 self.assertEqual(self.account.secret_token, 'sssssshhh!')
105
106@@ -440,17 +445,52 @@
107 dict(trim_user='true'))
108
109 def test_retweet(self):
110- get_url = self.protocol._get_url = mock.Mock(return_value='tweet')
111+ tweet = dict(tweet='twit')
112+ get_url = self.protocol._get_url = mock.Mock(return_value=tweet)
113 publish = self.protocol._publish_tweet = mock.Mock(
114 return_value='tweet permalink')
115
116 self.assertEqual(self.protocol.retweet('1234'), 'tweet permalink')
117
118- publish.assert_called_with('tweet')
119+ publish.assert_called_with(tweet)
120 get_url.assert_called_with(
121 'https://api.twitter.com/1.1/statuses/retweet/1234.json',
122 dict(trim_user='true'))
123
124+ @mock.patch('friends.utils.base.Model', TestModel)
125+ @mock.patch('friends.utils.http.Soup.Message',
126+ FakeSoupMessage('friends.tests.data', 'twitter-retweet.dat'))
127+ @mock.patch('friends.protocols.twitter.Twitter._login',
128+ return_value=True)
129+ @mock.patch('friends.utils.base._seen_ids', {})
130+ def test_retweet_with_data(self, *mocks):
131+ self.account.access_token = 'access'
132+ self.account.secret_token = 'secret'
133+ self.account.user_name = 'some_guy'
134+ self.account.user_full_name = 'Guy Man'
135+ self.account.avatar_url = 'http://example.com/me.jpg'
136+ self.account.auth.parameters = dict(
137+ ConsumerKey='key',
138+ ConsumerSecret='secret')
139+ self.assertEqual(0, TestModel.get_n_rows())
140+ self.assertEqual(
141+ self.protocol.retweet('240558470661799936'),
142+ 'https://twitter.com/some_guy/status/322807141108944896')
143+ self.assertEqual(1, TestModel.get_n_rows())
144+
145+ expected_row = [
146+ 'twitter', 88, '322807141108944896',
147+ 'messages', 'Guy Man', '836242932', 'some_guy', True,
148+ '2013-04-12T20:23:14Z', 'RT @ubuntudesigners: Reading \'Core utility'
149+ ' apps visual exploration\' at Design <a href="http://t.co/'
150+ '36tT53C37n">http://t.co/36tT53C37n</a>',
151+ GLib.get_user_cache_dir() +
152+ '/friends/avatars/6e8af1e6860da04a6f42cb1e6934e191f7c38c6d',
153+ 'https://twitter.com/some_guy/status/322807141108944896',
154+ 0, False, '', '', '', '', '', '', '', 0.0, 0.0,
155+ ]
156+ self.assertEqual(list(TestModel.get_row(0)), expected_row)
157+
158 def test_unfollow(self):
159 get_url = self.protocol._get_url = mock.Mock()
160

Subscribers

People subscribed via source and target branches