Skip to content

Commit d1e15bd

Browse files
committed
improve test coverage
1 parent 1fcbe8b commit d1e15bd

File tree

3 files changed

+154
-7
lines changed

3 files changed

+154
-7
lines changed

intbot/core/integrations/github.py

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -109,11 +109,11 @@ def from_webhook(cls, wh: Webhook):
109109
action=wh.event,
110110
)
111111

112-
def get_project(self):
112+
def get_project(self): # pragma: no cover
113113
"""Used in the discord channel router"""
114114
raise NotImplementedError("Implement in child class")
115115

116-
def get_repository(self):
116+
def get_repository(self): # pragma: no cover
117117
"""Used in the discord channel router"""
118118
raise NotImplementedError("Implement in child class")
119119

@@ -148,9 +148,6 @@ def get_repository(self):
148148
def get_sender(self) -> GithubSender:
149149
return GithubSender.parse_obj(self.content["sender"])
150150

151-
def project_name(self):
152-
return self.get_project().title
153-
154151
def changes(self) -> dict:
155152
if "changes" in self.content:
156153
fv = self.content["changes"]["field_value"]
@@ -211,7 +208,7 @@ def prep_github_webhook(wh: Webhook):
211208
if event == "projects_v2_item":
212209
node_id = wh.content["projects_v2_item"]["node_id"]
213210
project_item = fetch_github_project_item(node_id)
214-
wh.event = f"{event}.{wh.content['action']}"
211+
wh.event = f"{event}.{wh.content['projects_v2_item']['action']}"
215212
wh.extra = project_item
216213
wh.save()
217214
return wh

intbot/tests/test_integrations/test_github.py

Lines changed: 150 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
11
import pytest
2+
import respx
23
from core.integrations.github import (
4+
GITHUB_API_URL,
35
GithubProjectV2Item,
46
GithubSender,
57
parse_github_webhook,
8+
prep_github_webhook,
69
)
710
from core.models import Webhook
811
from httpx import Response
@@ -174,7 +177,78 @@ def test_github_project_item_edited_event_no_changes():
174177
)
175178

176179

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+
178252
def test_get_project_parses_project_correctly(self, gh_data):
179253
wh = Webhook(
180254
meta={"X-Github-Event": "projects_v2_item"},
@@ -218,3 +292,78 @@ def test_sender_formats_sender_correctly(self, gh_data):
218292
"https://github.com/apps/github-project-automation"
219293
")"
220294
)
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)

pyproject.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,4 +48,5 @@ exclude_lines = [
4848
"if 0:",
4949
"def __repr__",
5050
"def __str__",
51+
"pragma: no cover",
5152
]

0 commit comments

Comments
 (0)