|
1 | 1 | import pytest
|
| 2 | +import respx |
2 | 3 | from core.integrations.github import (
|
| 4 | + GITHUB_API_URL, |
3 | 5 | GithubProjectV2Item,
|
4 | 6 | GithubSender,
|
5 | 7 | parse_github_webhook,
|
| 8 | + prep_github_webhook, |
6 | 9 | )
|
7 | 10 | from core.models import Webhook
|
8 | 11 | from httpx import Response
|
@@ -174,7 +177,78 @@ def test_github_project_item_edited_event_no_changes():
|
174 | 177 | )
|
175 | 178 |
|
176 | 179 |
|
177 |
| -class TestGithubProjectV2ItemSpecial: |
| 180 | +class TestGithubProjectV2Item: |
| 181 | + |
| 182 | + def test_changes_for_single_select(self): |
| 183 | + parser = GithubProjectV2Item( |
| 184 | + action="changed", |
| 185 | + headers={}, |
| 186 | + content={ |
| 187 | + "changes": { |
| 188 | + "field_value": { |
| 189 | + "field_name": "Status", |
| 190 | + "field_type": "single_select", |
| 191 | + "from": {"name": "To Do"}, |
| 192 | + "to": {"name": "In Progress"}, |
| 193 | + } |
| 194 | + }, |
| 195 | + }, |
| 196 | + extra={}, |
| 197 | + ) |
| 198 | + |
| 199 | + assert parser.changes() == { |
| 200 | + "from": "To Do", |
| 201 | + "to": "In Progress", |
| 202 | + "field": "Status", |
| 203 | + } |
| 204 | + |
| 205 | + def test_changes_for_date(self): |
| 206 | + parser = GithubProjectV2Item( |
| 207 | + action="changed", |
| 208 | + headers={}, |
| 209 | + content={ |
| 210 | + "changes": { |
| 211 | + "field_value": { |
| 212 | + "field_name": "Deadline", |
| 213 | + "field_type": "date", |
| 214 | + "from": "2024-01-01T10:20:30", |
| 215 | + "to": "2025-01-05T20:30:10", |
| 216 | + } |
| 217 | + }, |
| 218 | + }, |
| 219 | + extra={}, |
| 220 | + ) |
| 221 | + |
| 222 | + assert parser.changes() == { |
| 223 | + "from": "2024-01-01", |
| 224 | + "to": "2025-01-05", |
| 225 | + "field": "Deadline", |
| 226 | + } |
| 227 | + |
| 228 | + def test_changes_for_unsupported_format(self): |
| 229 | + parser = GithubProjectV2Item( |
| 230 | + action="changed", |
| 231 | + headers={}, |
| 232 | + content={ |
| 233 | + "changes": { |
| 234 | + "field_value": { |
| 235 | + "field_name": "Randomfield", |
| 236 | + "field_type": "unsupported", |
| 237 | + "from": "This", |
| 238 | + "to": "That", |
| 239 | + } |
| 240 | + }, |
| 241 | + }, |
| 242 | + extra={}, |
| 243 | + ) |
| 244 | + |
| 245 | + assert parser.changes() == { |
| 246 | + "from": "None", |
| 247 | + "to": "None", |
| 248 | + "field": "Randomfield", |
| 249 | + } |
| 250 | + |
| 251 | + |
178 | 252 | def test_get_project_parses_project_correctly(self, gh_data):
|
179 | 253 | wh = Webhook(
|
180 | 254 | meta={"X-Github-Event": "projects_v2_item"},
|
@@ -218,3 +292,78 @@ def test_sender_formats_sender_correctly(self, gh_data):
|
218 | 292 | "https://github.com/apps/github-project-automation"
|
219 | 293 | ")"
|
220 | 294 | )
|
| 295 | + |
| 296 | + |
| 297 | +def test_prep_github_webhook_fails_if_event_not_supported(): |
| 298 | + wh = Webhook(meta={"X-Github-Event": "issue.fixed"}) |
| 299 | + |
| 300 | + with pytest.raises(ValueError): |
| 301 | + prep_github_webhook(wh) |
| 302 | + |
| 303 | + |
| 304 | +@respx.mock |
| 305 | +@pytest.mark.django_db |
| 306 | +def test_prep_github_webhook_fetches_extra_data_for_project_v2_item(): |
| 307 | + wh = Webhook( |
| 308 | + meta={"X-Github-Event": "projects_v2_item"}, |
| 309 | + content={ |
| 310 | + "projects_v2_item": { |
| 311 | + "node_id": "PVTI_random_projectItemV2ID", |
| 312 | + "action": "random", |
| 313 | + } |
| 314 | + }, |
| 315 | + ) |
| 316 | + node = { |
| 317 | + "project": { |
| 318 | + "id": "PVT_Random_Project", |
| 319 | + "title": "Random Project", |
| 320 | + "url": "https://github.com/europython", |
| 321 | + }, |
| 322 | + "content": { |
| 323 | + "__typename": "Issue", |
| 324 | + "id": "I_randomIssueID", |
| 325 | + "title": "Test Issue", |
| 326 | + "url": "https://github.com/test-issue", |
| 327 | + }, |
| 328 | + } |
| 329 | + |
| 330 | + mocked_response = { |
| 331 | + "data": { |
| 332 | + "node": node, |
| 333 | + } |
| 334 | + } |
| 335 | + |
| 336 | + respx.post(GITHUB_API_URL).mock(return_value=Response(200, json=mocked_response)) |
| 337 | + wh = prep_github_webhook(wh) |
| 338 | + |
| 339 | + assert wh.event == "projects_v2_item.random" |
| 340 | + assert wh.extra == node |
| 341 | + |
| 342 | + |
| 343 | +@respx.mock |
| 344 | +def test_prep_github_webhook_reraises_exception_in_case_of_API_error(): |
| 345 | + wh = Webhook( |
| 346 | + meta={"X-Github-Event": "projects_v2_item"}, |
| 347 | + content={ |
| 348 | + "projects_v2_item": { |
| 349 | + "node_id": "PVTI_random_projectItemV2ID", |
| 350 | + "action": "random", |
| 351 | + } |
| 352 | + }, |
| 353 | + ) |
| 354 | + |
| 355 | + respx.post(GITHUB_API_URL).mock(return_value=Response(500, json={"lol": "failed"})) |
| 356 | + |
| 357 | + with pytest.raises(Exception, match='GitHub API error: 500 - {"lol":"failed"}'): |
| 358 | + wh = prep_github_webhook(wh) |
| 359 | + |
| 360 | + |
| 361 | +def test_parse_github_webhook_raises_exception_for_unsupported_events(): |
| 362 | + wh = Webhook( |
| 363 | + meta={"X-Github-Event": "long_form_content"}, |
| 364 | + content={}, |
| 365 | + extra={"something": "extra"}, |
| 366 | + ) |
| 367 | + |
| 368 | + with pytest.raises(ValueError, match="Event not supported `long_form_content`"): |
| 369 | + parse_github_webhook(wh) |
0 commit comments