Coverage for tests/publisher/test_publisher_views.py: 100%
180 statements
« prev ^ index » next coverage.py v7.9.1, created at 2025-06-27 22:07 +0000
« prev ^ index » next coverage.py v7.9.1, created at 2025-06-27 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.store_api.publisher_gateway.invite_collaborators")
192 def test_invite_collaborators(self, mock_invite_collaborators):
193 mock_invite_collaborators.return_value = {"tokens": ["token"]}
194 res = self.client.post(
195 "/api/packages/test-entity/invites",
196 data={"collaborators": "collaborator"},
197 )
198 self.assertEqual(res.status_code, 200)
200 @patch("webapp.store_api.publisher_gateway.revoke_invites")
201 def test_revoke_invite(self, mock_revoke_invites):
202 mock_revoke_invites.return_value.status_code = 204
203 res = self.client.delete(
204 "/api/packages/test-entity/invites",
205 data={"collaborator": "collaborator"},
206 )
207 self.assertEqual(res.status_code, 200)
209 def test_register_name(self):
210 res = self.client.get("/register-name")
211 self.assertEqual(res.status_code, 200)
212 self.assertIn(b"Register a new", res.data)
214 @patch("webapp.store_api.publisher_gateway.register_package_name")
215 def test_post_register_name(self, mock_register_package_name):
216 mock_register_package_name.return_value = True
217 res = self.client.post(
218 "/register-name",
219 data={
220 "name": "test-name",
221 "type": "charm",
222 "private": "private",
223 },
224 )
225 self.assertEqual(res.status_code, 302)
227 @patch("webapp.store_api.publisher_gateway.register_package_name")
228 def test_post_register_name_already_owned(
229 self, mock_register_package_name
230 ):
231 mock_register_package_name.side_effect = StoreApiResponseErrorList(
232 "test-error", 500, [{"code": "already-owned"}]
233 )
234 res = self.client.post(
235 "/register-name",
236 data={
237 "name": "test-name",
238 "type": "charm",
239 "private": "private",
240 },
241 )
242 self.assertEqual(res.status_code, 302)
243 self.assertIn("already_owned=True", res.headers["Location"])
245 def test_register_name_dispute(self):
246 res = self.client.get("/register-name-dispute?entity-name=test-name")
247 self.assertEqual(res.status_code, 200)
248 self.assertIn(b"Claim the name", res.data)
250 def test_register_name_dispute_redirect(self):
251 res = self.client.get("/register-name-dispute")
252 self.assertEqual(res.status_code, 302)
254 def test_register_name_dispute_thank_you_redirect(self):
255 res = self.client.get("/register-name-dispute/thank-you")
256 self.assertEqual(res.status_code, 302)
258 def test_register_name_dispute_thank_you(self):
259 res = self.client.get(
260 "/register-name-dispute/thank-you?entity-name=test-name"
261 )
262 self.assertEqual(res.status_code, 200)
263 self.assertIn(
264 b"We will process the details provided with the name dispute.",
265 res.data,
266 )
268 @patch("webapp.store_api.publisher_gateway.unregister_package_name")
269 def test_delete_package(self, mock_unregister_package_name):
270 mock_unregister_package_name.return_value.status_code = 200
271 res = self.client.delete("/packages/test-package")
272 self.assertEqual(res.status_code, 200)
274 @patch("webapp.store_api.publisher_gateway.unregister_package_name")
275 def test_delete_package_failed(self, mock_unregister_package_name):
276 mock_unregister_package_name.return_value.status_code = 500
277 mock_unregister_package_name.return_value.json = {
278 "error-list": [{"message": "test-error"}]
279 }
280 res = self.client.delete("/packages/test-package")
281 self.assertEqual(res.status_code, 500)
283 @patch("webapp.store_api.publisher_gateway.create_track")
284 def test_post_create_track(self, mock_create_track):
285 mock_create_track.return_value.status_code = 201
286 mock_create_track.return_value.json = lambda: {"track": "test-track"}
287 res = self.client.post(
288 "/test-charm/create-track",
289 data={
290 "track-name": "test-track",
291 "version-pattern": "v1",
292 "auto-phasing-percentage": "50",
293 },
294 )
295 self.assertEqual(res.status_code, 201)
297 @patch("webapp.store_api.publisher_gateway.create_track")
298 def test_post_create_track_already_exists(self, mock_create_track):
299 mock_create_track.return_value.status_code = 409
300 mock_create_track.return_value.json = lambda: {"track": "test-track"}
301 res = self.client.post(
302 "/test-charm/create-track",
303 data={
304 "track-name": "test-track",
305 "version-pattern": "v1",
306 "auto-phasing-percentage": "50",
307 },
308 )
309 self.assertEqual(res.status_code, 409)
311 @patch("webapp.store_api.publisher_gateway.get_releases")
312 @patch("webapp.publisher.logic.process_releases")
313 @patch("webapp.publisher.logic.get_all_architectures")
314 def test_get_releases(
315 self,
316 mock_get_all_architectures,
317 mock_process_releases,
318 mock_get_releases,
319 ):
320 mock_get_releases.return_value = {
321 "channel-map": [],
322 "package": {"channels": []},
323 "revisions": [],
324 }
325 mock_process_releases.return_value = []
326 mock_get_all_architectures.return_value = []
327 self.set_session()
328 res = self.client.get("/api/packages/test-entity/releases")
329 self.assertEqual(res.status_code, 200)