Coverage for tests/store/test_get_packages.py: 98%
50 statements
« prev ^ index » next coverage.py v7.16.1, created at 2026-09-18 22:11 +0000
« prev ^ index » next coverage.py v7.16.1, created at 2026-09-18 22:11 +0000
1from unittest import TestCase
2from unittest.mock import patch
3from webapp.app import app
6FIND_RESULTS = [
7 {
8 "default-release": {
9 "channel": {
10 "base": {
11 "architecture": "amd64",
12 "channel": "22.04",
13 "name": "ubuntu",
14 },
15 "name": "3/stable",
16 "released-at": "2025-05-28T00:34:33.427207+00:00",
17 "risk": "stable",
18 "track": "3",
19 },
20 "revision": {"revision": 205},
21 },
22 "id": "3uPxmv77o1PrixpQFIf8o7SkOLsnMWmZ",
23 "name": "kafka",
24 "result": {
25 "categories": [
26 {
27 "featured": False,
28 "name": "databases",
29 },
30 ],
31 "deployable-on": [],
32 "media": [
33 {
34 "height": None,
35 "type": "icon",
36 "url": (
37 "https://api.charmhub.io/api/v1/media/download/"
38 "charm_3uPxmv77o1PrixpQFIf8o7SkOLsnMWmZ_icon_ad"
39 "1a94cf9bb9f68614cb6c17e54e2fbd9dcc7fecc514dc60"
40 "12b7f58fb5b87f8f.png"
41 ),
42 "width": None,
43 },
44 ],
45 "publisher": {
46 "display-name": "Canonical",
47 "id": "gVVkuxw4C56POG1eszt4RPR3L5Eak8XE",
48 "username": "data-platform",
49 "validation": "unproven",
50 },
51 "summary": "Charmed Apache Kafka Operator",
52 "title": "Apache Kafka",
53 },
54 "type": "charm",
55 },
56 {
57 "default-release": {
58 "channel": {
59 "base": {
60 "architecture": "amd64",
61 "channel": "22.04",
62 "name": "ubuntu",
63 },
64 "name": "3/stable",
65 "released-at": "2025-06-02T18:45:45.026540+00:00",
66 "risk": "stable",
67 "track": "3",
68 },
69 "revision": {"revision": 82},
70 },
71 "id": "zGwm8mNdJ0Tb45JNDYNgiRBRlzaw66oA",
72 "name": "kafka-k8s",
73 "result": {
74 "categories": [{"featured": False, "name": "databases"}],
75 "deployable-on": ["kubernetes"],
76 "media": [
77 {
78 "height": None,
79 "type": "icon",
80 "url": (
81 "https://api.charmhub.io/api/v1/media/download/charm_"
82 "zGwm8mNdJ0Tb45JNDYNgiRBRlzaw66oA_icon_ad1a94cf9bb9f6"
83 "8614cb6c17e54e2fbd9dcc7fecc514dc6012b7f58fb5b87f8f"
84 ".png"
85 ),
86 "width": None,
87 },
88 ],
89 "publisher": {
90 "display-name": "Canonical",
91 "id": "gVVkuxw4C56POG1eszt4RPR3L5Eak8XE",
92 "username": "data-platform",
93 "validation": "unproven",
94 },
95 "summary": "Charmed Apache Kafka K8s Operator",
96 "title": "Apache Kafka - K8s",
97 },
98 "type": "charm",
99 },
100 {
101 "default-release": {
102 "channel": {
103 "base": {
104 "architecture": "amd64",
105 "channel": "22.04",
106 "name": "ubuntu",
107 },
108 "name": "6/stable",
109 "released-at": "2025-08-20T21:22:15.968934+00:00",
110 "risk": "stable",
111 "track": "6",
112 },
113 "revision": {"revision": 229},
114 },
115 "id": "Jfd56ZWJ9IaNHuPjXVLP9d9Xa2XMTSKp",
116 "name": "mongodb",
117 "result": {
118 "categories": [{"featured": False, "name": "databases"}],
119 "deployable-on": [],
120 "media": [
121 {
122 "height": None,
123 "type": "icon",
124 "url": (
125 "https://api.charmhub.io/api/v1/media/download/"
126 "charm_Jfd56ZWJ9IaNHuPjXVLP9d9Xa2XMTSKp_icon_ad"
127 "1a94cf9bb9f68614cb6c17e54e2fbd9dcc7fecc514dc60"
128 "12b7f58fb5b87f8f.png"
129 ),
130 "width": None,
131 },
132 ],
133 "publisher": {
134 "display-name": "Canonical",
135 "id": "gVVkuxw4C56POG1eszt4RPR3L5Eak8XE",
136 "username": "data-platform",
137 "validation": "unproven",
138 },
139 "summary": "A MongoDB operator charm",
140 "title": "MongoDB",
141 },
142 "type": "charm",
143 },
144]
147class TestGetPackages(TestCase):
148 def setUp(self):
149 app.testing = True
150 self.client = app.test_client()
152 @patch("webapp.store_api.publisher_gateway.find")
153 def test_get_packages(self, mock_find):
154 mock_find.return_value = {"results": FIND_RESULTS}
155 response = self.client.get("/packages.json")
156 self.assertEqual(response.status_code, 200)
157 self.assertIn("packages", response.json)
158 self.assertEqual(len(response.json["packages"]), 3)
160 @patch("webapp.store_api.publisher_gateway.find")
161 def test_get_packages_with_query(self, mock_find):
162 mock_find.return_value = {"results": [FIND_RESULTS[0]]}
163 response = self.client.get("/packages.json?q=kafka")
164 self.assertEqual(response.status_code, 200)
165 self.assertIn("q", response.json)
166 self.assertEqual("kafka", response.json["q"])
167 self.assertIn("packages", response.json)
168 self.assertEqual(len(response.json["packages"]), 1)
170 @patch("webapp.store_api.publisher_gateway.find")
171 def test_get_packages_with_provides_and_requires(self, mock_find):
172 mock_find.return_value = {"results": [FIND_RESULTS[0]]}
173 response = self.client.get(
174 "/packages.json?provides=kafka-client&requires=certificates"
175 )
176 self.assertEqual(response.status_code, 200)
177 self.assertIn("provides", response.json)
178 self.assertEqual(["kafka-client"], response.json["provides"])
179 self.assertIn("requires", response.json)
180 self.assertEqual(["certificates"], response.json["requires"])
181 self.assertIn("packages", response.json)
182 self.assertEqual(len(response.json["packages"]), 1)
184 @patch("webapp.store_api.publisher_gateway.find")
185 def test_get_packages_error_handling(self, mock_find):
186 mock_find.side_effect = Exception("Mocked Error")
187 with self.client as client:
188 with self.assertRaises(Exception) as context:
189 response = client.get("/packages.json")
190 self.assertEqual(str(context.exception), "Mocked Error")
192 self.assertEqual(response.status_code, 500)
194 @patch("webapp.store_api.publisher_gateway.find")
195 def test_get_packages_empty_response(self, mock_find):
196 mock_find.return_value = {"results": []}
197 with self.client as client:
198 response = client.get(
199 "/packages.json?q=some-random-non-existent-package-name"
200 )
201 self.assertEqual(response.status_code, 200)
202 self.assertEqual(0, len(response.json["packages"]))