Mercurial > silorider
annotate tests/test_silos_bluesky.py @ 77:5381655e7f6d
Bluesky silo now tries to create link card embeds
author | Ludovic Chabant <ludovic@chabant.com> |
---|---|
date | Wed, 28 Aug 2024 08:40:52 -0700 |
parents | 08ee3ffbe508 |
children |
rev | line source |
---|---|
69
dafbbf25bfc8
Upgrade bluesky silo to atproto 0.0.35 and unit tests.
Ludovic Chabant <ludovic@chabant.com>
parents:
63
diff
changeset
|
1 import os.path |
46 | 2 import pytest |
69
dafbbf25bfc8
Upgrade bluesky silo to atproto 0.0.35 and unit tests.
Ludovic Chabant <ludovic@chabant.com>
parents:
63
diff
changeset
|
3 from atproto import models as atprotomodels |
46 | 4 from .mockutil import mock_urllib |
5 | |
6 | |
7 def test_one_article(cli, feedutil, bskymock): | |
8 feed = cli.createTempFeed(feedutil.makeFeed( | |
9 """<h1 class="p-name">A new article</h1> | |
10 <div class="e-content"> | |
11 <p>This is the text of the article.</p> | |
12 <p>It has 2 paragraphs.</p> | |
13 </div> | |
14 <a class="u-url" href="https://example.org/a-new-article">permalink</a>""" | |
15 )) | |
16 | |
17 cli.appendSiloConfig('test', 'bluesky') | |
18 cli.setFeedConfig('feed', feed) | |
19 bskymock.installCredentials(cli, 'test') | |
20 | |
21 ctx, _ = cli.run('process') | |
22 assert ctx.cache.wasPosted('test', 'https://example.org/a-new-article') | |
23 post = ctx.silos[0].client.posts[0] | |
69
dafbbf25bfc8
Upgrade bluesky silo to atproto 0.0.35 and unit tests.
Ludovic Chabant <ludovic@chabant.com>
parents:
63
diff
changeset
|
24 assert post == ( |
dafbbf25bfc8
Upgrade bluesky silo to atproto 0.0.35 and unit tests.
Ludovic Chabant <ludovic@chabant.com>
parents:
63
diff
changeset
|
25 'A new article https://example.org/a-new-article', |
dafbbf25bfc8
Upgrade bluesky silo to atproto 0.0.35 and unit tests.
Ludovic Chabant <ludovic@chabant.com>
parents:
63
diff
changeset
|
26 None, |
dafbbf25bfc8
Upgrade bluesky silo to atproto 0.0.35 and unit tests.
Ludovic Chabant <ludovic@chabant.com>
parents:
63
diff
changeset
|
27 [_make_link_facet('https://example.org/a-new-article', 14, 47)]) |
46 | 28 |
29 | |
30 def test_one_micropost(cli, feedutil, bskymock): | |
31 feed = cli.createTempFeed(feedutil.makeFeed( | |
32 """<p class="p-name">This is a quick update.</p> | |
33 <a class="u-url" href="/01234.html">permalink</a>""" | |
34 )) | |
35 | |
36 cli.appendSiloConfig('test', 'bluesky') | |
37 cli.setFeedConfig('feed', feed) | |
38 bskymock.installCredentials(cli, 'test') | |
39 | |
40 ctx, _ = cli.run('process') | |
41 assert ctx.cache.wasPosted('test', '/01234.html') | |
42 post = ctx.silos[0].client.posts[0] | |
43 assert post == ("This is a quick update.", None, None) | |
44 | |
45 | |
46 def test_one_micropost_with_one_photo(cli, feedutil, bskymock, monkeypatch): | |
47 feed = cli.createTempFeed(feedutil.makeFeed( | |
48 """<p class="p-name">This is a quick photo update.</p> | |
49 <div> | |
50 <a class="u-photo" href="/fullimg.jpg"><img src="/thumbimg.jpg"/></a> | |
51 </div> | |
52 <a class="u-url" href="/01234.html">permalink</a>""" | |
53 )) | |
54 | |
55 cli.appendSiloConfig('test', 'bluesky') | |
56 cli.setFeedConfig('feed', feed) | |
57 bskymock.installCredentials(cli, 'test') | |
58 | |
59 with monkeypatch.context() as m: | |
60 import silorider.silos.bluesky | |
61 mock_urllib(m) | |
69
dafbbf25bfc8
Upgrade bluesky silo to atproto 0.0.35 and unit tests.
Ludovic Chabant <ludovic@chabant.com>
parents:
63
diff
changeset
|
62 m.setattr(os.path, 'getsize', lambda path: 42) |
58
d65f6dced79f
Fix media callback patches in unit tests
Ludovic Chabant <ludovic@chabant.com>
parents:
48
diff
changeset
|
63 m.setattr(silorider.silos.bluesky.BlueskySilo, 'mediaCallback', |
46 | 64 _patched_media_callback) |
65 ctx, _ = cli.run('process') | |
66 | |
67 assert ctx.cache.wasPosted('test', '/01234.html') | |
68 blob = ctx.silos[0].client.blobs[0] | |
69 assert blob == ('/retrieved/fullimg.jpg', None) | |
70 post = ctx.silos[0].client.posts[0] | |
63
c4dbbbb4990a
Fix Bluesky unit tests
Ludovic Chabant <ludovic@chabant.com>
parents:
58
diff
changeset
|
71 assert post[1].images[0].__test_index == 0 |
c4dbbbb4990a
Fix Bluesky unit tests
Ludovic Chabant <ludovic@chabant.com>
parents:
58
diff
changeset
|
72 embed = atprotomodels.AppBskyEmbedImages.Main(images=[ |
c4dbbbb4990a
Fix Bluesky unit tests
Ludovic Chabant <ludovic@chabant.com>
parents:
58
diff
changeset
|
73 _make_atproto_image('/retrieved/fullimg.jpg', test_index=0)]) |
46 | 74 assert post == ("This is a quick photo update.", embed, None) |
75 | |
76 | |
77 def test_one_micropost_with_two_photos(cli, feedutil, bskymock, monkeypatch): | |
78 feed = cli.createTempFeed(feedutil.makeFeed( | |
79 """<p class="p-name">This is a photo update with 2 photos.</p> | |
80 <div> | |
81 <a class="u-photo" href="/fullimg1.jpg"><img src="/thumbimg1.jpg"/></a> | |
82 <a class="u-photo" href="/fullimg2.jpg"><img src="/thumbimg2.jpg"/></a> | |
83 </div> | |
84 <a class="u-url" href="/01234.html">permalink</a>""" | |
85 )) | |
86 | |
87 cli.appendSiloConfig('test', 'bluesky') | |
88 cli.setFeedConfig('feed', feed) | |
89 bskymock.installCredentials(cli, 'test') | |
90 | |
91 with monkeypatch.context() as m: | |
92 import silorider.silos.bluesky | |
93 mock_urllib(m) | |
69
dafbbf25bfc8
Upgrade bluesky silo to atproto 0.0.35 and unit tests.
Ludovic Chabant <ludovic@chabant.com>
parents:
63
diff
changeset
|
94 m.setattr(os.path, 'getsize', lambda path: 42) |
58
d65f6dced79f
Fix media callback patches in unit tests
Ludovic Chabant <ludovic@chabant.com>
parents:
48
diff
changeset
|
95 m.setattr(silorider.silos.bluesky.BlueskySilo, 'mediaCallback', |
46 | 96 _patched_media_callback) |
97 ctx, _ = cli.run('process') | |
98 | |
99 assert ctx.cache.wasPosted('test', '/01234.html') | |
100 blob = ctx.silos[0].client.blobs[0] | |
101 assert blob == ('/retrieved/fullimg1.jpg', None) | |
102 blob = ctx.silos[0].client.blobs[1] | |
103 assert blob == ('/retrieved/fullimg2.jpg', None) | |
104 post = ctx.silos[0].client.posts[0] | |
63
c4dbbbb4990a
Fix Bluesky unit tests
Ludovic Chabant <ludovic@chabant.com>
parents:
58
diff
changeset
|
105 embed = atprotomodels.AppBskyEmbedImages.Main(images=[ |
c4dbbbb4990a
Fix Bluesky unit tests
Ludovic Chabant <ludovic@chabant.com>
parents:
58
diff
changeset
|
106 _make_atproto_image('/retrieved/fullimg1.jpg', test_index=0), |
c4dbbbb4990a
Fix Bluesky unit tests
Ludovic Chabant <ludovic@chabant.com>
parents:
58
diff
changeset
|
107 _make_atproto_image('/retrieved/fullimg2.jpg', test_index=1)]) |
46 | 108 assert post == ("This is a photo update with 2 photos.", embed, None) |
109 | |
110 | |
111 def test_one_micropost_with_links(cli, feedutil, bskymock): | |
112 cli.appendSiloConfig('test', 'bluesky') | |
113 bskymock.installCredentials(cli, 'test') | |
114 | |
115 feed = cli.createTempFeed(feedutil.makeFeed( | |
116 """<p class="p-name">This is a link: http://example.org/blah</p> | |
117 <a class="u-url" href="/01234.html">permalink</a>""")) | |
118 | |
119 cli.setFeedConfig('feed', feed) | |
120 ctx, _ = cli.run('process') | |
121 post = ctx.silos[0].client.posts[0] | |
122 assert post[0] == "This is a link: http://example.org/blah" | |
123 assert post[2] == None | |
124 | |
125 feed = cli.createTempFeed(feedutil.makeFeed( | |
126 """<p class="e-content">This is another link: <a href="http://example.org/blah">http://example.org/blah</a></p> | |
127 <a class="u-url" href="/01234.html">permalink</a>""")) # NOQA | |
128 cli.setFeedConfig('feed', feed) | |
129 ctx, _ = cli.run('process') | |
130 post = ctx.silos[0].client.posts[0] | |
131 assert post[0] == "This is another link: http://example.org/blah" # NOQA | |
132 facet = _make_link_facet('http://example.org/blah', 22, 45) | |
133 assert post[2] == [facet] | |
134 | |
135 feed = cli.createTempFeed(feedutil.makeFeed( | |
136 """<p class="e-content">This is yet <a href="http://example.org/blah">another link</a></p> | |
137 <a class="u-url" href="/01234.html">permalink</a>""")) # NOQA | |
138 cli.setFeedConfig('feed', feed) | |
139 ctx, _ = cli.run('process') | |
140 post = ctx.silos[0].client.posts[0] | |
141 assert post[0] == "This is yet another link" # NOQA | |
142 facet = _make_link_facet('http://example.org/blah', 12, 24) | |
143 assert post[2] == [facet] | |
144 | |
145 | |
74
08ee3ffbe508
Fix Bluesky formatting for posts too long, or with a link
Ludovic Chabant <ludovic@chabant.com>
parents:
69
diff
changeset
|
146 def test_one_micropost_too_long(cli, feedutil, bskymock): |
08ee3ffbe508
Fix Bluesky formatting for posts too long, or with a link
Ludovic Chabant <ludovic@chabant.com>
parents:
69
diff
changeset
|
147 cli.appendSiloConfig('test', 'bluesky') |
08ee3ffbe508
Fix Bluesky formatting for posts too long, or with a link
Ludovic Chabant <ludovic@chabant.com>
parents:
69
diff
changeset
|
148 bskymock.installCredentials(cli, 'test') |
08ee3ffbe508
Fix Bluesky formatting for posts too long, or with a link
Ludovic Chabant <ludovic@chabant.com>
parents:
69
diff
changeset
|
149 |
08ee3ffbe508
Fix Bluesky formatting for posts too long, or with a link
Ludovic Chabant <ludovic@chabant.com>
parents:
69
diff
changeset
|
150 feed = cli.createTempFeed(feedutil.makeFeed( |
08ee3ffbe508
Fix Bluesky formatting for posts too long, or with a link
Ludovic Chabant <ludovic@chabant.com>
parents:
69
diff
changeset
|
151 """<p class="p-name">Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum</p> |
08ee3ffbe508
Fix Bluesky formatting for posts too long, or with a link
Ludovic Chabant <ludovic@chabant.com>
parents:
69
diff
changeset
|
152 <a class="u-url" href="/01234.html">permalink</a>""")) |
08ee3ffbe508
Fix Bluesky formatting for posts too long, or with a link
Ludovic Chabant <ludovic@chabant.com>
parents:
69
diff
changeset
|
153 |
08ee3ffbe508
Fix Bluesky formatting for posts too long, or with a link
Ludovic Chabant <ludovic@chabant.com>
parents:
69
diff
changeset
|
154 cli.setFeedConfig('feed', feed) |
08ee3ffbe508
Fix Bluesky formatting for posts too long, or with a link
Ludovic Chabant <ludovic@chabant.com>
parents:
69
diff
changeset
|
155 ctx, _ = cli.run('process') |
08ee3ffbe508
Fix Bluesky formatting for posts too long, or with a link
Ludovic Chabant <ludovic@chabant.com>
parents:
69
diff
changeset
|
156 post = ctx.silos[0].client.posts[0] |
08ee3ffbe508
Fix Bluesky formatting for posts too long, or with a link
Ludovic Chabant <ludovic@chabant.com>
parents:
69
diff
changeset
|
157 assert post[0] == "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate... /01234.html" |
08ee3ffbe508
Fix Bluesky formatting for posts too long, or with a link
Ludovic Chabant <ludovic@chabant.com>
parents:
69
diff
changeset
|
158 |
46 | 159 def _make_link_facet(url, start, end): |
160 return atprotomodels.AppBskyRichtextFacet.Main( | |
161 features=[atprotomodels.AppBskyRichtextFacet.Link(uri=url)], | |
162 index=atprotomodels.AppBskyRichtextFacet.ByteSlice( | |
163 byteStart=start, byteEnd=end), | |
164 ) | |
165 | |
166 | |
167 def _patched_media_callback(self, tmpfile, mt, url, desc): | |
168 return self.client.upload_blob(tmpfile, desc) | |
169 | |
170 | |
171 @pytest.fixture(scope='session') | |
172 def bskymock(): | |
173 from silorider.silos.bluesky import BlueskySilo | |
174 BlueskySilo._CLIENT_CLASS = BlueskyMock | |
175 return BlueskyMockUtil() | |
176 | |
177 | |
63
c4dbbbb4990a
Fix Bluesky unit tests
Ludovic Chabant <ludovic@chabant.com>
parents:
58
diff
changeset
|
178 def _make_atproto_image(link, alt="", mime_type="image/jpg", size=100, test_index=None): |
c4dbbbb4990a
Fix Bluesky unit tests
Ludovic Chabant <ludovic@chabant.com>
parents:
58
diff
changeset
|
179 # atproto will validate models and that forces us to create |
c4dbbbb4990a
Fix Bluesky unit tests
Ludovic Chabant <ludovic@chabant.com>
parents:
58
diff
changeset
|
180 # an actual Image object. |
c4dbbbb4990a
Fix Bluesky unit tests
Ludovic Chabant <ludovic@chabant.com>
parents:
58
diff
changeset
|
181 # Not sure why we need to use model_validate here -- the simple |
c4dbbbb4990a
Fix Bluesky unit tests
Ludovic Chabant <ludovic@chabant.com>
parents:
58
diff
changeset
|
182 # constructor with keywords throws a validation error :( |
69
dafbbf25bfc8
Upgrade bluesky silo to atproto 0.0.35 and unit tests.
Ludovic Chabant <ludovic@chabant.com>
parents:
63
diff
changeset
|
183 blob_link = atprotomodels.blob_ref.IpldLink.model_validate({'$link': link}) |
63
c4dbbbb4990a
Fix Bluesky unit tests
Ludovic Chabant <ludovic@chabant.com>
parents:
58
diff
changeset
|
184 blob = atprotomodels.blob_ref.BlobRef(mime_type=mime_type, ref=blob_link, size=size) |
c4dbbbb4990a
Fix Bluesky unit tests
Ludovic Chabant <ludovic@chabant.com>
parents:
58
diff
changeset
|
185 img = atprotomodels.AppBskyEmbedImages.Image(alt=alt, image=blob) |
c4dbbbb4990a
Fix Bluesky unit tests
Ludovic Chabant <ludovic@chabant.com>
parents:
58
diff
changeset
|
186 if test_index is not None: |
c4dbbbb4990a
Fix Bluesky unit tests
Ludovic Chabant <ludovic@chabant.com>
parents:
58
diff
changeset
|
187 img.__test_index = test_index |
c4dbbbb4990a
Fix Bluesky unit tests
Ludovic Chabant <ludovic@chabant.com>
parents:
58
diff
changeset
|
188 return img |
c4dbbbb4990a
Fix Bluesky unit tests
Ludovic Chabant <ludovic@chabant.com>
parents:
58
diff
changeset
|
189 |
c4dbbbb4990a
Fix Bluesky unit tests
Ludovic Chabant <ludovic@chabant.com>
parents:
58
diff
changeset
|
190 |
46 | 191 class BlueskyMock: |
192 def __init__(self, base_url): | |
193 # base_url is unused here. | |
194 self.posts = [] | |
195 self.blobs = [] | |
196 | |
197 def login(self, email, password): | |
198 assert email == 'TEST_EMAIL' | |
199 assert password == 'TEST_PASSWORD' | |
200 | |
201 def upload_blob(self, tmpfile, desc): | |
63
c4dbbbb4990a
Fix Bluesky unit tests
Ludovic Chabant <ludovic@chabant.com>
parents:
58
diff
changeset
|
202 img = _make_atproto_image(tmpfile, test_index=len(self.blobs)) |
46 | 203 self.blobs.append((tmpfile, desc)) |
63
c4dbbbb4990a
Fix Bluesky unit tests
Ludovic Chabant <ludovic@chabant.com>
parents:
58
diff
changeset
|
204 return img |
46 | 205 |
48
486affad656e
Rewrite posting process with card system and more structured API
Ludovic Chabant <ludovic@chabant.com>
parents:
46
diff
changeset
|
206 def send_post(self, text, post_datetime=None, embed=None, facets=None): |
46 | 207 self.posts.append((text, embed, facets)) |
208 | |
209 | |
210 class BlueskyMockUtil: | |
211 def installCredentials(self, cli, silo_name): | |
212 def do_install_credentials(ctx): | |
213 ctx.cache.setCustomValue( | |
214 '%s_email' % silo_name, | |
215 'TEST_EMAIL') | |
216 ctx.cache.setCustomValue( | |
217 '%s_password' % silo_name, | |
218 'TEST_PASSWORD') | |
219 | |
220 cli.preExecHook(do_install_credentials) |