Coverage for tests/publisher/test_publisher_views.py: 100%
182 statements
« prev ^ index » next coverage.py v7.10.2, created at 2025-08-08 22:07 +0000
« prev ^ index » next coverage.py v7.10.2, created at 2025-08-08 22:07 +0000
1import unittest
2from webapp.app import app
3from tests.mock_data.mock_store_logic import sample_charm
4from unittest.mock import patch
6from canonicalwebteam.exceptions import StoreApiResponseErrorList
9class TestPublisherViews(unittest.TestCase):
10 @patch(
11 "webapp.decorators.login_required",
12 )
13 def setUp(self, mock_login_required):
14 mock_login_required.return_value = lambda: True
15 self.app = app
16 self.app.config["TESTING"] = True
17 self.app.config["WTF_CSRF_ENABLED"] = []
18 self.client = self.app.test_client()
19 self.set_session()
21 def set_session(self):
22 with self.client.session_transaction() as session:
23 session["account"] = {
24 "display-name": "test-display-name",
25 "email": "test-email",
26 "username": "test-username",
27 }
28 session["account-auth"] = "test-auth"
30 def test_get_account_details_no_login(self):
31 with self.client.session_transaction() as session:
32 del session["account-auth"]
33 del session["account"]
34 res = self.client.get("/account/details")
35 self.assertEqual(res.status_code, 302)
37 @patch(
38 "webapp.authentication.is_authenticated",
39 return_value=True,
40 )
41 def test_get_account_details(self, mock_is_authenticated):
42 res = self.client.get("/account/details")
43 self.assertEqual(res.status_code, 200)
44 self.assertIn(b"test-display-name", res.data)
45 self.assertIn(b"test-email", res.data)
46 self.assertIn(b"test-username", res.data)
48 @patch("webapp.store_api.publisher_gateway.get_package_metadata")
49 def test_get_publisher(self, mock_get_package_metadata):
50 mock_get_package_metadata.return_value = sample_charm
51 for endpoint in [
52 "listing",
53 "releases",
54 "publicise",
55 "collaboration",
56 "settings",
57 ]:
58 res = self.client.get(f"/test-entity/{endpoint}")
59 self.assertEqual(res.status_code, 200)
61 @patch("webapp.store_api.publisher_gateway.get_package_metadata")
62 def test_get_package(self, mock_get_package_metadata):
63 mock_get_package_metadata.return_value = {"name": "test-package"}
64 res = self.client.get("/api/packages/test-entity")
65 self.assertEqual(res.status_code, 200)
66 self.assertEqual(
67 res.json,
68 {"success": True, "data": mock_get_package_metadata.return_value},
69 )
71 @patch("webapp.store_api.publisher_gateway.update_package_metadata")
72 def test_update_package(self, mock_update_package_metadata):
73 mock_update_package_metadata.return_value = {"name": "test-package"}
74 res = self.client.patch(
75 "/api/packages/test-entity", json={"key": "value"}
76 )
77 self.assertEqual(res.status_code, 200)
79 @patch("webapp.store_api.publisher_gateway.update_package_metadata")
80 def test_update_package_failure(self, mock_update_package_metadata):
81 mock_update_package_metadata.side_effect = StoreApiResponseErrorList(
82 "test-error", 500, []
83 )
84 res = self.client.patch(
85 "/api/packages/test-entity", json={"key": "value"}
86 )
87 self.assertEqual(res.status_code, 500)
88 self.assertEqual(res.json["success"], False)
90 @patch("webapp.store_api.publisher_gateway.update_package_metadata")
91 def test_update_package_unauthorized(self, mock_update_package_metadata):
92 mock_update_package_metadata.side_effect = StoreApiResponseErrorList(
93 "test-error", 500, [{"message": "unauthorized"}]
94 )
95 res = self.client.patch(
96 "/api/packages/test-entity", json={"key": "value"}
97 )
98 self.assertEqual(res.status_code, 500)
99 self.assertEqual(res.json["success"], False)
100 self.assertEqual(res.json["message"], "Package not found")
102 @patch("webapp.store_api.publisher_gateway.get_account_packages")
103 def test_list_page(self, mock_get_account_packages):
104 mock_get_account_packages.return_value = [
105 {
106 "contact": "email",
107 "id": "ChgcZB3RhaDOnhkAv9cgRg52LhjBbDt8",
108 "media": [
109 {
110 "type": "icon",
111 "url": "https://example.com/icon.svg",
112 }
113 ],
114 "name": "postgresql",
115 "private": False,
116 "publisher": {
117 "id": "test-id",
118 "display-name": "Canonical Data Platform",
119 },
120 "status": "published",
121 "type": "charm",
122 },
123 ]
125 with self.client.session_transaction() as session:
126 session["account"] = {"id": "test-id"}
128 res = self.client.get("/charms")
129 self.assertEqual(res.status_code, 200)
130 self.assertIn(b"postgresql", res.data)
131 self.assertIn(b"Published charms", res.data)
132 res = self.client.get("/bundles")
133 self.assertEqual(res.status_code, 200)
134 self.assertNotIn(b"postgresql", res.data)
136 def test_accept_invite(self):
137 res = self.client.get("/accept-invite")
138 self.assertIn(b"Success", res.data)
139 self.assertEqual(res.status_code, 200)
141 @patch("webapp.store_api.publisher_gateway.accept_invite")
142 def test_accept_post_invite(self, mock_accept_invite):
143 mock_accept_invite.return_value.status_code = 204
144 res = self.client.post(
145 "/accept-invite",
146 data={"token": "test-token", "package": "test-package"},
147 )
148 self.assertEqual(res.status_code, 200)
150 @patch("webapp.store_api.publisher_gateway.accept_invite")
151 def test_accept_post_invite_failed(self, mock_accept_invite):
152 mock_accept_invite.return_value.status_code = 401
153 res = self.client.post(
154 "/accept-invite",
155 data={"token": "test-token", "package": "test-package"},
156 )
157 self.assertEqual(res.status_code, 500)
158 self.assertEqual(res.json["message"], "An error occured")
160 @patch("webapp.store_api.publisher_gateway.reject_invite")
161 def test_reject_post_invite(self, mock_reject_invite):
162 mock_reject_invite.return_value.status_code = 204
163 res = self.client.post(
164 "/reject-invite",
165 data={"token": "test-token", "package": "test-package"},
166 )
167 self.assertEqual(res.status_code, 200)
169 @patch("webapp.store_api.publisher_gateway.get_collaborators")
170 def test_get_collaborators(self, mock_get_collaborators):
171 mock_get_collaborators.return_value = [{"name": "collaborator"}]
172 res = self.client.get("/api/packages/test-entity/collaborators")
173 self.assertEqual(res.status_code, 200)
175 @patch("webapp.store_api.publisher_gateway.get_collaborators")
176 def test_get_collaborators_failed(self, mock_get_collaborators):
177 mock_get_collaborators.side_effect = StoreApiResponseErrorList(
178 "test-error", 500, []
179 )
180 res = self.client.get("/api/packages/test-entity/collaborators")
181 self.assertEqual(res.status_code, 500)
183 @patch("webapp.store_api.publisher_gateway.get_pending_invites")
184 def test_get_pending_invites(self, mock_get_pending_invites):
185 mock_get_pending_invites.return_value = {
186 "invites": [{"name": "invite"}]
187 }
188 res = self.client.get("/api/packages/test-entity/invites")
189 self.assertEqual(res.status_code, 200)
191 @patch("webapp.utils.emailer.Emailer.send_email_template")
192 @patch("webapp.store_api.publisher_gateway.invite_collaborators")
193 def test_invite_collaborators(
194 self, mock_invite_collaborators, mock_send_email_template
195 ):
196 mock_send_email_template.return_value = None
197 mock_invite_collaborators.return_value = {
198 "tokens": [{"token": "test-token"}]
199 }
200 res = self.client.post(
201 "/api/packages/test-entity/invites",
202 data={"collaborators": "collaborator"},
203 )
204 self.assertEqual(res.status_code, 200)
206 @patch("webapp.store_api.publisher_gateway.revoke_invites")
207 def test_revoke_invite(self, mock_revoke_invites):
208 mock_revoke_invites.return_value.status_code = 204
209 res = self.client.delete(
210 "/api/packages/test-entity/invites",
211 data={"collaborator": "collaborator"},
212 )
213 self.assertEqual(res.status_code, 200)
215 def test_register_name(self):
216 res = self.client.get("/register-name")
217 self.assertEqual(res.status_code, 200)
218 self.assertIn(b"Register a new", res.data)
220 @patch("webapp.store_api.publisher_gateway.register_package_name")
221 def test_post_register_name(self, mock_register_package_name):
222 mock_register_package_name.return_value = True
223 res = self.client.post(
224 "/register-name",
225 data={
226 "name": "test-name",
227 "type": "charm",
228 "private": "private",
229 },
230 )
231 self.assertEqual(res.status_code, 302)
233 @patch("webapp.store_api.publisher_gateway.register_package_name")
234 def test_post_register_name_already_owned(
235 self, mock_register_package_name
236 ):
237 mock_register_package_name.side_effect = StoreApiResponseErrorList(
238 "test-error", 500, [{"code": "already-owned"}]
239 )
240 res = self.client.post(
241 "/register-name",
242 data={
243 "name": "test-name",
244 "type": "charm",
245 "private": "private",
246 },
247 )
248 self.assertEqual(res.status_code, 302)
249 self.assertIn("already_owned=True", res.headers["Location"])
251 def test_register_name_dispute(self):
252 res = self.client.get("/register-name-dispute?entity-name=test-name")
253 self.assertEqual(res.status_code, 200)
254 self.assertIn(b"Claim the name", res.data)
256 def test_register_name_dispute_redirect(self):
257 res = self.client.get("/register-name-dispute")
258 self.assertEqual(res.status_code, 302)
260 def test_register_name_dispute_thank_you_redirect(self):
261 res = self.client.get("/register-name-dispute/thank-you")
262 self.assertEqual(res.status_code, 302)
264 def test_register_name_dispute_thank_you(self):
265 res = self.client.get(
266 "/register-name-dispute/thank-you?entity-name=test-name"
267 )
268 self.assertEqual(res.status_code, 200)
269 self.assertIn(
270 b"We will process the details provided with the name dispute.",
271 res.data,
272 )
274 @patch("webapp.store_api.publisher_gateway.unregister_package_name")
275 def test_delete_package(self, mock_unregister_package_name):
276 mock_unregister_package_name.return_value.status_code = 200
277 res = self.client.delete("/packages/test-package")
278 self.assertEqual(res.status_code, 200)
280 @patch("webapp.store_api.publisher_gateway.unregister_package_name")
281 def test_delete_package_failed(self, mock_unregister_package_name):
282 mock_unregister_package_name.return_value.status_code = 500
283 mock_unregister_package_name.return_value.json = {
284 "error-list": [{"message": "test-error"}]
285 }
286 res = self.client.delete("/packages/test-package")
287 self.assertEqual(res.status_code, 500)
289 @patch("webapp.store_api.publisher_gateway.create_track")
290 def test_post_create_track(self, mock_create_track):
291 mock_create_track.return_value.status_code = 201
292 mock_create_track.return_value.json = lambda: {"track": "test-track"}
293 res = self.client.post(
294 "/test-charm/create-track",
295 data={
296 "track-name": "test-track",
297 "version-pattern": "v1",
298 "auto-phasing-percentage": "50",
299 },
300 )
301 self.assertEqual(res.status_code, 201)
303 @patch("webapp.store_api.publisher_gateway.create_track")
304 def test_post_create_track_already_exists(self, mock_create_track):
305 mock_create_track.return_value.status_code = 409
306 mock_create_track.return_value.json = lambda: {"track": "test-track"}
307 res = self.client.post(
308 "/test-charm/create-track",
309 data={
310 "track-name": "test-track",
311 "version-pattern": "v1",
312 "auto-phasing-percentage": "50",
313 },
314 )
315 self.assertEqual(res.status_code, 409)
317 @patch("webapp.store_api.publisher_gateway.get_releases")
318 @patch("webapp.publisher.logic.process_releases")
319 @patch("webapp.publisher.logic.get_all_architectures")
320 def test_get_releases(
321 self,
322 mock_get_all_architectures,
323 mock_process_releases,
324 mock_get_releases,
325 ):
326 mock_get_releases.return_value = {
327 "channel-map": [],
328 "package": {"channels": []},
329 "revisions": [],
330 }
331 mock_process_releases.return_value = []
332 mock_get_all_architectures.return_value = []
333 self.set_session()
334 res = self.client.get("/api/packages/test-entity/releases")
335 self.assertEqual(res.status_code, 200)