@@ -71,6 +71,50 @@ def _link(
7171 return _link
7272
7373
74+ @pytest .mark .parametrize (
75+ "linked_url, payload_url" ,
76+ [
77+ (
78+ "https://gitlab.example.com/testorg/testrepo/-/issues/42" ,
79+ "https://gitlab.example.com/testorg/testrepo/-/work_items/42" ,
80+ ),
81+ (
82+ "https://gitlab.example.com/testorg/testrepo/-/work_items/42" ,
83+ "https://gitlab.example.com/testorg/testrepo/-/issues/42" ,
84+ ),
85+ ],
86+ )
87+ def test_gitlab_webhook__issue_url_variants__still_matches_feature (
88+ api_client : APIClient ,
89+ feature : int ,
90+ webhook_url : str ,
91+ link_feature : LinkFeatureFixture ,
92+ linked_url : str ,
93+ payload_url : str ,
94+ ) -> None :
95+ # Given — GitLab may deliver ``work_items`` URLs even when the link uses the
96+ # legacy ``issues`` path (or vice versa). Both shapes refer to the same issue.
97+ link_feature (linked_url , ResourceType .GITLAB_ISSUE , metadata = {"state" : "opened" })
98+ payload = {
99+ "object_kind" : "issue" ,
100+ "object_attributes" : {"url" : payload_url , "state" : "closed" },
101+ }
102+
103+ # When
104+ response = api_client .post (
105+ webhook_url ,
106+ data = payload ,
107+ format = "json" ,
108+ HTTP_X_GITLAB_TOKEN = WEBHOOK_SECRET ,
109+ )
110+
111+ # Then
112+ assert response .status_code == status .HTTP_200_OK
113+ labels = set (Feature .objects .get (id = feature ).tags .values_list ("label" , flat = True ))
114+ assert GitLabTagLabel .ISSUE_CLOSED .value in labels
115+ assert GitLabTagLabel .ISSUE_OPEN .value not in labels
116+
117+
74118@pytest .mark .django_db ()
75119def test_gitlab_webhook__issue_close_event__switches_tag_to_issue_closed (
76120 api_client : APIClient ,
0 commit comments