77#
88
99from unittest import mock
10+ from urllib .parse import quote
1011
1112from django .contrib .contenttypes .models import ContentType
1213from django .test import TestCase
1314
1415from dje .models import Dataspace
1516from dje .tests import create_superuser
1617from workflow .integrations .github import GitHubIntegration
18+ from workflow .integrations .gitlab import GitLabIntegration
1719from workflow .models import Question
1820from workflow .models import RequestTemplate
1921
@@ -51,30 +53,30 @@ def setUp(self):
5153 )
5254 self .github = GitHubIntegration (dataspace = self .dataspace )
5355
54- def test_extract_github_repo_path_valid_url (self ):
56+ def test_github_extract_github_repo_path_valid_url (self ):
5557 url = "https://github.com/user/repo"
5658 result = GitHubIntegration .extract_github_repo_path (url )
5759 self .assertEqual (result , "user/repo" )
5860
59- def test_extract_github_repo_path_invalid_url (self ):
61+ def test_github_extract_github_repo_path_invalid_url (self ):
6062 with self .assertRaises (ValueError ):
6163 GitHubIntegration .extract_github_repo_path ("https://example.com/user/repo" )
6264
63- def test_get_headers_returns_auth_header (self ):
65+ def test_github_get_headers_returns_auth_header (self ):
6466 headers = self .github .get_headers ()
6567 self .assertEqual (headers , {"Authorization" : "token fake-token" })
6668
67- def test_make_issue_title (self ):
69+ def test_github_make_issue_title (self ):
6870 title = GitHubIntegration .make_issue_title (self .request )
6971 self .assertEqual (title , "[DEJACODE] Example Request" )
7072
71- def test_make_issue_body_contains_question (self ):
73+ def test_github_make_issue_body_contains_question (self ):
7274 body = GitHubIntegration .make_issue_body (self .request )
7375 self .assertIn ("### Example Question" , body )
7476 self .assertIn ("Some value" , body )
7577
7678 @mock .patch ("requests.Session.post" )
77- def test_create_issue_calls_post (self , mock_session_post ):
79+ def test_github_create_issue_calls_post (self , mock_session_post ):
7880 mock_session_post .return_value .json .return_value = {"number" : 10 }
7981 mock_session_post .return_value .raise_for_status .return_value = None
8082
@@ -89,7 +91,7 @@ def test_create_issue_calls_post(self, mock_session_post):
8991 mock_session_post .assert_called_once ()
9092
9193 @mock .patch ("requests.Session.patch" )
92- def test_update_issue_calls_patch (self , mock_session_patch ):
94+ def test_github_update_issue_calls_patch (self , mock_session_patch ):
9395 mock_session_patch .return_value .json .return_value = {"state" : "closed" }
9496 mock_session_patch .return_value .raise_for_status .return_value = None
9597
@@ -105,19 +107,142 @@ def test_update_issue_calls_patch(self, mock_session_patch):
105107 mock_session_patch .assert_called_once ()
106108
107109 @mock .patch ("requests.Session.post" )
108- def test_post_comment_calls_post (self , mock_session_post ):
110+ def test_github_post_comment_calls_post (self , mock_session_post ):
109111 mock_session_post .return_value .json .return_value = {"id" : 77 , "body" : "Test comment" }
110112 mock_session_post .return_value .raise_for_status .return_value = None
111113
112114 response = self .github .post_comment (
113115 repo_id = "user/repo" ,
114- issue_id = 42 ,
116+ issue_id = 10 ,
115117 comment_body = "Test comment" ,
116118 )
117119
118120 self .assertEqual (response ["body" ], "Test comment" )
119121 mock_session_post .assert_called_once_with (
120- "https://api.github.com/repos/user/repo/issues/42 /comments" ,
122+ "https://api.github.com/repos/user/repo/issues/10 /comments" ,
121123 json = {"body" : "Test comment" },
122124 timeout = self .github .default_timeout ,
123125 )
126+
127+
128+ class GitLabIntegrationTestCase (TestCase ):
129+ def setUp (self ):
130+ patcher = mock .patch ("workflow.models.Request.handle_integrations" , return_value = None )
131+ self .mock_handle_integrations = patcher .start ()
132+ self .addCleanup (patcher .stop )
133+
134+ self .dataspace = Dataspace .objects .create (name = "nexB" )
135+ self .dataspace .set_configuration ("gitlab_token" , "fake-token" )
136+ self .super_user = create_superuser ("nexb_user" , self .dataspace )
137+ self .component_ct = ContentType .objects .get (
138+ app_label = "component_catalog" , model = "component"
139+ )
140+ self .request_template = RequestTemplate .objects .create (
141+ name = "GitLab Template" ,
142+ description = "Integration test template" ,
143+ content_type = self .component_ct ,
144+ dataspace = self .dataspace ,
145+ issue_tracker_id = "https://gitlab.com/nexB/repo" ,
146+ )
147+ self .question = Question .objects .create (
148+ template = self .request_template ,
149+ label = "Example Question" ,
150+ input_type = "TextField" ,
151+ position = 0 ,
152+ dataspace = self .dataspace ,
153+ )
154+ self .request = self .request_template .create_request (
155+ title = "Example Request" ,
156+ requester = self .super_user ,
157+ serialized_data = '{"Example Question": "Some value"}' ,
158+ )
159+ self .gitlab = GitLabIntegration (dataspace = self .dataspace )
160+
161+ def test_gitlab_extract_gitlab_project_path_valid_url (self ):
162+ url = "https://gitlab.com/user/project"
163+ result = GitLabIntegration .extract_gitlab_project_path (url )
164+ self .assertEqual (result , "user/project" )
165+
166+ def test_gitlab_extract_gitlab_project_path_invalid_url (self ):
167+ with self .assertRaises (ValueError ):
168+ GitLabIntegration .extract_gitlab_project_path ("https://example.com/user/project" )
169+
170+ def test_gitlab_get_headers_returns_auth_header (self ):
171+ headers = self .gitlab .get_headers ()
172+ self .assertEqual (headers , {"PRIVATE-TOKEN" : "fake-token" })
173+
174+ def test_gitlab_make_issue_title (self ):
175+ title = self .gitlab .make_issue_title (self .request )
176+ self .assertEqual (title , "[DEJACODE] Example Request" )
177+
178+ def test_gitlab_make_issue_body_contains_question (self ):
179+ body = self .gitlab .make_issue_body (self .request )
180+ self .assertIn ("### Example Question" , body )
181+ self .assertIn ("Some value" , body )
182+
183+ @mock .patch ("requests.Session.post" )
184+ def test_gitlab_create_issue_calls_post (self , mock_session_post ):
185+ mock_session_post .return_value .json .return_value = {"iid" : 10 }
186+ mock_session_post .return_value .raise_for_status .return_value = None
187+
188+ issue = self .gitlab .create_issue (
189+ repo_id = "user/project" ,
190+ title = "Issue Title" ,
191+ body = "Issue Body" ,
192+ labels = ["High" ],
193+ )
194+
195+ self .assertEqual (issue ["iid" ], 10 )
196+ mock_session_post .assert_called_once_with (
197+ f"https://gitlab.com/api/v4/projects/{ quote ('user/project' , safe = '' )} /issues" ,
198+ json = {
199+ "title" : "Issue Title" ,
200+ "description" : "Issue Body" ,
201+ "labels" : "High" ,
202+ },
203+ timeout = self .gitlab .default_timeout ,
204+ )
205+
206+ @mock .patch ("requests.Session.put" )
207+ def test_gitlab_update_issue_calls_put (self , mock_session_put ):
208+ mock_session_put .return_value .json .return_value = {"state" : "closed" }
209+ mock_session_put .return_value .raise_for_status .return_value = None
210+
211+ response = self .gitlab .update_issue (
212+ repo_id = "user/project" ,
213+ issue_id = 123 ,
214+ title = "Updated title" ,
215+ body = "Updated body" ,
216+ state_event = "close" ,
217+ labels = ["Urgent" ],
218+ )
219+
220+ self .assertEqual (response ["state" ], "closed" )
221+ mock_session_put .assert_called_once_with (
222+ f"https://gitlab.com/api/v4/projects/{ quote ('user/project' , safe = '' )} /issues/123" ,
223+ json = {
224+ "title" : "Updated title" ,
225+ "description" : "Updated body" ,
226+ "state_event" : "close" ,
227+ "labels" : "Urgent" ,
228+ },
229+ timeout = self .gitlab .default_timeout ,
230+ )
231+
232+ @mock .patch ("requests.Session.post" )
233+ def test_gitlab_post_comment_calls_post (self , mock_session_post ):
234+ mock_session_post .return_value .json .return_value = {"id" : 77 , "body" : "Test comment" }
235+ mock_session_post .return_value .raise_for_status .return_value = None
236+
237+ response = self .gitlab .post_comment (
238+ repo_id = "user/project" ,
239+ issue_id = 10 ,
240+ comment_body = "Test comment" ,
241+ )
242+
243+ self .assertEqual (response ["body" ], "Test comment" )
244+ mock_session_post .assert_called_once_with (
245+ f"https://gitlab.com/api/v4/projects/{ quote ('user/project' , safe = '' )} /issues/10/notes" ,
246+ json = {"body" : "Test comment" },
247+ timeout = self .gitlab .default_timeout ,
248+ )
0 commit comments