comparison tests/test_silos_twitter.py @ 39:c5f73ebb43a5

Replace python-twitter with tweepy to use Twitter's V2 API
author Ludovic Chabant <ludovic@chabant.com>
date Sun, 21 May 2023 09:42:11 -0700
parents 9e4eb3f2754e
children d65f6dced79f
comparison
equal deleted inserted replaced
38:0f98784bcc40 39:c5f73ebb43a5
1 import pytest 1 import pytest
2 from .mockutil import mock_urllib
2 3
3 4
4 def test_one_article(cli, feedutil, tweetmock): 5 def test_one_article(cli, feedutil, tweetmock):
5 feed = cli.createTempFeed(feedutil.makeFeed( 6 feed = cli.createTempFeed(feedutil.makeFeed(
6 """<h1 class="p-name">A new article</h1> 7 """<h1 class="p-name">A new article</h1>
65 66
66 cli.appendSiloConfig('test', 'twitter', url='/blah') 67 cli.appendSiloConfig('test', 'twitter', url='/blah')
67 cli.setFeedConfig('feed', feed) 68 cli.setFeedConfig('feed', feed)
68 tweetmock.installTokens(cli, 'test') 69 tweetmock.installTokens(cli, 'test')
69 70
70 ctx, _ = cli.run('process') 71 with monkeypatch.context() as m:
72 import silorider.silos.twitter
73 mock_urllib(m)
74 m.setattr(silorider.silos.twitter.TwitterSilo, '_media_callback',
75 _patched_media_callback)
76 ctx, _ = cli.run('process')
71 77
72 assert ctx.cache.wasPosted('test', '/01234.html') 78 assert ctx.cache.wasPosted('test', '/01234.html')
73 toot = ctx.silos[0].client.tweets[0] 79 toot = ctx.silos[0].client.tweets[0]
74 assert toot == ("This is a quick photo update.", ['/fullimg.jpg']) 80 assert toot == ("This is a quick photo update.", ['/fullimg.jpg'])
75 81
86 92
87 cli.appendSiloConfig('test', 'twitter', url='/blah') 93 cli.appendSiloConfig('test', 'twitter', url='/blah')
88 cli.setFeedConfig('feed', feed) 94 cli.setFeedConfig('feed', feed)
89 tweetmock.installTokens(cli, 'test') 95 tweetmock.installTokens(cli, 'test')
90 96
91 ctx, _ = cli.run('process') 97 with monkeypatch.context() as m:
98 import silorider.silos.twitter
99 mock_urllib(m)
100 m.setattr(silorider.silos.twitter.TwitterSilo, '_media_callback',
101 _patched_media_callback)
102 ctx, _ = cli.run('process')
92 103
93 assert ctx.cache.wasPosted('test', '/01234.html') 104 assert ctx.cache.wasPosted('test', '/01234.html')
94 toot = ctx.silos[0].client.tweets[0] 105 toot = ctx.silos[0].client.tweets[0]
95 assert toot == ("This is a photo update with 2 photos.", 106 assert toot == ("This is a photo update with 2 photos.",
96 ['/fullimg1.jpg', '/fullimg2.jpg']) 107 ['/fullimg1.jpg', '/fullimg2.jpg'])
97 108
98 109
99 def test_micropost_with_long_text_and_link(cli, feedutil, tweetmock, monkeypatch): 110 def test_micropost_with_long_text_and_link(cli, feedutil, tweetmock, monkeypatch):
100 feed = cli.createTempFeed(feedutil.makeFeed( 111 feed = cli.createTempFeed(feedutil.makeFeed(
101 """<div class="p-name"> 112 """<div class="p-name">
102 <p>This a pretty long text that has a link in it :) We want to make sure it gets to the limit of what Twitter allows, so that we can test there won't be any off-by-one errors in measurements. Here is a <a href="https://docs.python.org/3/library/textwrap.html">link to Python's textwrap module</a>, which is appropriate!!!</p> 113 <p>This a pretty long text that has a link in it :) We want to make sure it gets to the limit of what Twitter allows, so that we can test there won't be any off-by-one errors in measurements. Here is a <a href="https://docs.python.org/3/library/textwrap.html">link to Python's textwrap module</a>, which is appropriate!!!</p>
103 </div> 114 </div>
104 <a class="u-url" href="/01234.html">permalink</a>""" 115 <a class="u-url" href="/01234.html">permalink</a>"""
105 )) 116 ))
106 117
107 cli.appendSiloConfig('test', 'twitter', url='/blah') 118 cli.appendSiloConfig('test', 'twitter', url='/blah')
108 cli.setFeedConfig('feed', feed) 119 cli.setFeedConfig('feed', feed)
109 tweetmock.installTokens(cli, 'test') 120 tweetmock.installTokens(cli, 'test')
110 121
111 ctx, _ = cli.run('process') 122 ctx, _ = cli.run('process')
112 assert ctx.cache.wasPosted('test', '/01234.html') 123 assert ctx.cache.wasPosted('test', '/01234.html')
113 toot = ctx.silos[0].client.tweets[0] 124 toot = ctx.silos[0].client.tweets[0]
114 assert toot == ("This a pretty long text that has a link in it :) We want to make sure it gets to the limit of what Twitter allows, so that we can test there won't be any off-by-one errors in measurements. Here is a link to Python's textwrap module, which is appropriate!!! https://docs.python.org/3/library/textwrap.html", 125 assert toot == ("This a pretty long text that has a link in it :) We want to make sure it gets to the limit of what Twitter allows, so that we can test there won't be any off-by-one errors in measurements. Here is a link to Python's textwrap module, which is appropriate!!! https://docs.python.org/3/library/textwrap.html",
115 []) 126 [])
116 127
117 128
118 def test_micropost_with_too_long_text_and_link_1(cli, feedutil, tweetmock, monkeypatch): 129 def test_micropost_with_too_long_text_and_link_1(cli, feedutil, tweetmock, monkeypatch):
119 feed = cli.createTempFeed(feedutil.makeFeed( 130 feed = cli.createTempFeed(feedutil.makeFeed(
120 """<div class="p-name"> 131 """<div class="p-name">
121 <p>This time we have a text that's slightly too long, with <a href="https://thisdoesntmatter.com">a link here</a>. We'll be one character too long, with a short word at the end to test the shortening algorithm. Otherwise, don't worry about it. Blah blah blah. Trying to get to the limit. Almost here yes</p> 132 <p>This time we have a text that's slightly too long, with <a href="https://thisdoesntmatter.com">a link here</a>. We'll be one character too long, with a short word at the end to test the shortening algorithm. Otherwise, don't worry about it. Blah blah blah. Trying to get to the limit. Almost here yes</p>
122 </div> 133 </div>
123 <a class="u-url" href="/01234.html">permalink</a>""" 134 <a class="u-url" href="/01234.html">permalink</a>"""
124 )) 135 ))
125 136
126 cli.appendSiloConfig('test', 'twitter', url='/blah') 137 cli.appendSiloConfig('test', 'twitter', url='/blah')
127 cli.setFeedConfig('feed', feed) 138 cli.setFeedConfig('feed', feed)
128 tweetmock.installTokens(cli, 'test') 139 tweetmock.installTokens(cli, 'test')
129 140
130 ctx, _ = cli.run('process') 141 ctx, _ = cli.run('process')
131 assert ctx.cache.wasPosted('test', '/01234.html') 142 assert ctx.cache.wasPosted('test', '/01234.html')
132 toot = ctx.silos[0].client.tweets[0] 143 toot = ctx.silos[0].client.tweets[0]
133 assert toot == ("This time we have a text that's slightly too long, with a link here. We'll be one character too long, with a short word at the end to test the shortening algorithm. Otherwise, don't worry about it. Blah blah blah. Trying to get to the limit. Almost here... /01234.html", 144 assert toot == ("This time we have a text that's slightly too long, with a link here. We'll be one character too long, with a short word at the end to test the shortening algorithm. Otherwise, don't worry about it. Blah blah blah. Trying to get to the limit. Almost here... /01234.html",
134 []) 145 [])
135 146
136 147
137 def test_micropost_with_too_long_text_and_link_2(cli, feedutil, tweetmock, monkeypatch): 148 def test_micropost_with_too_long_text_and_link_2(cli, feedutil, tweetmock, monkeypatch):
138 feed = cli.createTempFeed(feedutil.makeFeed( 149 feed = cli.createTempFeed(feedutil.makeFeed(
139 """<div class="p-name"> 150 """<div class="p-name">
140 <p>This time we have a text that's slightly too long, with <a href="https://thisdoesntmatter.com">a link here</a>. We'll be one character too long, with a loooooong word at the end to test the shortening algorithm. Otherwise, don't worry about it. Blah blah blah. Our long word is: califragilisticastuff</p> 151 <p>This time we have a text that's slightly too long, with <a href="https://thisdoesntmatter.com">a link here</a>. We'll be one character too long, with a loooooong word at the end to test the shortening algorithm. Otherwise, don't worry about it. Blah blah blah. Our long word is: califragilisticastuff</p>
141 </div> 152 </div>
142 <a class="u-url" href="/01234.html">permalink</a>""" 153 <a class="u-url" href="/01234.html">permalink</a>"""
143 )) 154 ))
144 155
145 cli.appendSiloConfig('test', 'twitter', url='/blah') 156 cli.appendSiloConfig('test', 'twitter', url='/blah')
146 cli.setFeedConfig('feed', feed) 157 cli.setFeedConfig('feed', feed)
147 tweetmock.installTokens(cli, 'test') 158 tweetmock.installTokens(cli, 'test')
148 159
149 ctx, _ = cli.run('process') 160 ctx, _ = cli.run('process')
150 assert ctx.cache.wasPosted('test', '/01234.html') 161 assert ctx.cache.wasPosted('test', '/01234.html')
151 toot = ctx.silos[0].client.tweets[0] 162 toot = ctx.silos[0].client.tweets[0]
152 assert toot == ("This time we have a text that's slightly too long, with a link here. We'll be one character too long, with a loooooong word at the end to test the shortening algorithm. Otherwise, don't worry about it. Blah blah blah. Our long word is:... /01234.html", 163 assert toot == ("This time we have a text that's slightly too long, with a link here. We'll be one character too long, with a loooooong word at the end to test the shortening algorithm. Otherwise, don't worry about it. Blah blah blah. Our long word is:... /01234.html",
153 []) 164 [])
165
166
167 def _patched_media_callback(self, tmpfile, mt, url, desc):
168 return self.client.simple_upload(url)
154 169
155 170
156 @pytest.fixture(scope='session') 171 @pytest.fixture(scope='session')
157 def tweetmock(): 172 def tweetmock():
158 from silorider.silos.twitter import TwitterSilo 173 from silorider.silos.twitter import TwitterSilo
167 assert consumer_secret == 'TEST_CLIENT_SECRET' 182 assert consumer_secret == 'TEST_CLIENT_SECRET'
168 assert access_token_key == 'TEST_ACCESS_KEY' 183 assert access_token_key == 'TEST_ACCESS_KEY'
169 assert access_token_secret == 'TEST_ACCESS_SECRET' 184 assert access_token_secret == 'TEST_ACCESS_SECRET'
170 185
171 self.tweets = [] 186 self.tweets = []
172 187 self.media = []
173 def PostUpdate(self, tweet, media=None): 188
174 self.tweets.append((tweet, media)) 189 def create_tweet(self, text, media_ids=None):
190 media_names = []
191 if media_ids:
192 for mid in media_ids:
193 assert(self.media[mid] is not None)
194 media_names.append(self.media[mid])
195 self.media[mid] = None
196 assert all([m is None for m in self.media])
197
198 self.tweets.append((text, media_names))
199 self.media = []
200
201 def simple_upload(self, fname, file=None):
202 self.media.append(fname)
203 return len(self.media) - 1
175 204
176 205
177 class TwitterMockUtil: 206 class TwitterMockUtil:
178 def installTokens(self, cli, silo_name): 207 def installTokens(self, cli, silo_name):
179 def do_install_tokens(ctx): 208 def do_install_tokens(ctx):