Skip to content

Commit 7ca6895

Browse files
committed
Add SourceHutIntegrationTestCase test suite #348
Signed-off-by: tdruez <tdruez@nexb.com>
1 parent 7fdfd0f commit 7ca6895

2 files changed

Lines changed: 129 additions & 1 deletion

File tree

workflow/integrations/sourcehut.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,7 @@ def update_issue(self, repo_id, issue_id, title=None, body=None, state=None, lab
136136

137137
updated_ticket = response.get("data", {}).get("updateTicket")
138138

139-
if state != updated_ticket.get("status"):
139+
if state and state != updated_ticket.get("status"):
140140
self.update_ticket_status(tracker_id, ticket_id, state)
141141

142142
return updated_ticket

workflow/tests/test_integrations.py

Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -561,3 +561,131 @@ def test_forgejo_post_comment_calls_post(self, mock_request):
561561
json={"body": "Test comment"},
562562
timeout=self.forgejo.default_timeout,
563563
)
564+
565+
566+
class SourceHutIntegrationTestCase(TestCase):
567+
def setUp(self):
568+
patcher = mock.patch("workflow.models.Request.handle_integrations", return_value=None)
569+
self.mock_handle_integrations = patcher.start()
570+
self.addCleanup(patcher.stop)
571+
572+
self.dataspace = Dataspace.objects.create(name="nexB")
573+
self.dataspace.set_configuration("sourcehut_token", "fake-token")
574+
self.super_user = create_superuser("nexb_user", self.dataspace)
575+
self.component_ct = ContentType.objects.get(
576+
app_label="component_catalog", model="component"
577+
)
578+
self.request_template = RequestTemplate.objects.create(
579+
name="SourceHut Template",
580+
description="Integration test template",
581+
content_type=self.component_ct,
582+
dataspace=self.dataspace,
583+
issue_tracker_id="https://todo.sr.ht/~username/project-name",
584+
)
585+
self.question = Question.objects.create(
586+
template=self.request_template,
587+
label="Example Question",
588+
input_type="TextField",
589+
position=0,
590+
dataspace=self.dataspace,
591+
)
592+
self.request = self.request_template.create_request(
593+
title="Example Request",
594+
requester=self.super_user,
595+
serialized_data='{"Example Question": "Some value"}',
596+
)
597+
self.sourcehut = SourceHutIntegration(dataspace=self.dataspace)
598+
599+
def test_sourcehut_extract_sourcehut_project_valid_url(self):
600+
url = "https://todo.sr.ht/~user/project"
601+
result = SourceHutIntegration.extract_sourcehut_project(url)
602+
self.assertEqual(result, "~user/project")
603+
604+
def test_sourcehut_extract_sourcehut_project_invalid_host(self):
605+
with self.assertRaises(ValueError):
606+
SourceHutIntegration.extract_sourcehut_project("https://example.com/~user/project")
607+
608+
def test_sourcehut_extract_sourcehut_project_invalid_path_format(self):
609+
with self.assertRaises(ValueError):
610+
SourceHutIntegration.extract_sourcehut_project("https://todo.sr.ht/user/project")
611+
612+
def test_sourcehut_get_headers_returns_auth_header(self):
613+
headers = self.sourcehut.get_headers()
614+
self.assertEqual(
615+
headers,
616+
{
617+
"Authorization": "Bearer fake-token",
618+
"Content-Type": "application/json",
619+
},
620+
)
621+
622+
def test_sourcehut_make_issue_title(self):
623+
title = self.sourcehut.make_issue_title(self.request)
624+
self.assertEqual(title, "[DEJACODE] Example Request")
625+
626+
def test_sourcehut_make_issue_body_contains_question(self):
627+
body = self.sourcehut.make_issue_body(self.request)
628+
self.assertIn("### Example Question", body)
629+
self.assertIn("Some value", body)
630+
631+
@mock.patch.object(SourceHutIntegration, "post")
632+
@mock.patch.object(SourceHutIntegration, "get_tracker_id", return_value=1)
633+
def test_sourcehut_create_issue_calls_post(self, mock_get_tracker_id, mock_post):
634+
mock_post.return_value = {"data": {"submitTicket": {"id": 123, "subject": "Issue Title"}}}
635+
636+
issue = self.sourcehut.create_issue(
637+
repo_id="~user/project",
638+
title="Issue Title",
639+
body="Issue Body",
640+
)
641+
642+
self.assertEqual(issue["id"], 123)
643+
mock_post.assert_called_once()
644+
mock_get_tracker_id.assert_called_once_with("~user/project")
645+
646+
@mock.patch.object(SourceHutIntegration, "post")
647+
@mock.patch.object(SourceHutIntegration, "get_tracker_id", return_value=1)
648+
def test_sourcehut_update_issue_calls_post(self, mock_get_tracker_id, mock_post):
649+
mock_post.return_value = {
650+
"data": {
651+
"updateTicket": {
652+
"id": 123,
653+
"subject": "Updated title",
654+
"status": "REPORTED",
655+
}
656+
}
657+
}
658+
659+
response = self.sourcehut.update_issue(
660+
repo_id="~user/project",
661+
issue_id=123,
662+
title="Updated title",
663+
body="Updated body",
664+
)
665+
666+
self.assertEqual(response["id"], 123)
667+
mock_post.assert_called_once()
668+
mock_get_tracker_id.assert_called_once_with("~user/project")
669+
670+
@mock.patch.object(SourceHutIntegration, "post")
671+
@mock.patch.object(SourceHutIntegration, "get_tracker_id", return_value=1)
672+
def test_sourcehut_post_comment_calls_post(self, mock_get_tracker_id, mock_post):
673+
mock_post.return_value = {
674+
"data": {
675+
"submitComment": {
676+
"id": 77,
677+
"created": "2025-08-12T12:00:00Z",
678+
"ticket": {"id": 123, "subject": "Example Request"},
679+
}
680+
}
681+
}
682+
683+
response = self.sourcehut.post_comment(
684+
repo_id="~user/project",
685+
issue_id=123,
686+
comment_body="Test comment",
687+
)
688+
689+
self.assertEqual(response["id"], 77)
690+
mock_post.assert_called_once()
691+
mock_get_tracker_id.assert_called_once_with("~user/project")

0 commit comments

Comments
 (0)