11from pr_agent .git_providers import BitbucketServerProvider
22from pr_agent .git_providers .bitbucket_provider import BitbucketProvider
3+ from unittest .mock import MagicMock
4+ from atlassian .bitbucket import Bitbucket
5+ from pr_agent .algo .types import EDIT_TYPE , FilePatchInfo
36
47
58class TestBitbucketProvider :
@@ -10,9 +13,285 @@ def test_parse_pr_url(self):
1013 assert repo_slug == "MY_TEST_REPO"
1114 assert pr_number == 321
1215
13- def test_bitbucket_server_pr_url (self ):
16+
17+ class TestBitbucketServerProvider :
18+ def test_parse_pr_url (self ):
1419 url = "https://git.onpreminstance.com/projects/AAA/repos/my-repo/pull-requests/1"
1520 workspace_slug , repo_slug , pr_number = BitbucketServerProvider ._parse_pr_url (url )
1621 assert workspace_slug == "AAA"
1722 assert repo_slug == "my-repo"
1823 assert pr_number == 1
24+
25+ def mock_get_content_of_file (self , project_key , repository_slug , filename , at = None , markup = None ):
26+ content_map = {
27+ '9c1cffdd9f276074bfb6fb3b70fbee62d298b058' : 'file\n with\n some\n lines\n to\n emulate\n a\n real\n file\n ' ,
28+ '2a1165446bdf991caf114d01f7c88d84ae7399cf' : 'file\n with\n multiple \n lines\n to\n emulate\n a\n fake\n file\n ' ,
29+ 'f617708826cdd0b40abb5245eda71630192a17e3' : 'file\n with\n multiple \n lines\n to\n emulate\n a\n real\n file\n ' ,
30+ 'cb68a3027d6dda065a7692ebf2c90bed1bcdec28' : 'file\n with\n some\n changes\n to\n emulate\n a\n real\n file\n ' ,
31+ '1905dcf16c0aac6ac24f7ab617ad09c73dc1d23b' : 'file\n with\n some\n lines\n to\n emulate\n a\n fake\n test\n ' ,
32+ 'ae4eca7f222c96d396927d48ab7538e2ee13ca63' : 'readme\n without\n some\n lines\n to\n simulate\n a\n real\n file' ,
33+ '548f8ba15abc30875a082156314426806c3f4d97' : 'file\n with\n some\n lines\n to\n emulate\n a\n real\n file' ,
34+ '0e898cb355a5170d8c8771b25d43fcaa1d2d9489' : 'file\n with\n multiple\n lines\n to\n emulate\n a\n real\n file'
35+ }
36+ return content_map .get (at , '' )
37+
38+ def mock_get_from_bitbucket_60 (self , url ):
39+ response_map = {
40+ "rest/api/1.0/application-properties" : {
41+ "version" : "6.0"
42+ }
43+ }
44+ return response_map .get (url , '' )
45+
46+ def mock_get_from_bitbucket_70 (self , url ):
47+ response_map = {
48+ "rest/api/1.0/application-properties" : {
49+ "version" : "7.0"
50+ }
51+ }
52+ return response_map .get (url , '' )
53+
54+ def mock_get_from_bitbucket_816 (self , url ):
55+ response_map = {
56+ "rest/api/1.0/application-properties" : {
57+ "version" : "8.16"
58+ },
59+ "rest/api/latest/projects/AAA/repos/my-repo/pull-requests/1/merge-base" : {
60+ 'id' : '548f8ba15abc30875a082156314426806c3f4d97'
61+ }
62+ }
63+ return response_map .get (url , '' )
64+
65+
66+ '''
67+ tests the 2-way diff functionality where the diff should be between the HEAD of branch b and node c
68+ NOT between the HEAD of main and the HEAD of branch b
69+
70+ - o branch b
71+ /
72+ o - o - o main
73+ ^ node c
74+ '''
75+ def test_get_diff_files_simple_diverge_70 (self ):
76+ bitbucket_client = MagicMock (Bitbucket )
77+ bitbucket_client .get_pull_request .return_value = {
78+ 'toRef' : {'latestCommit' : '9c1cffdd9f276074bfb6fb3b70fbee62d298b058' },
79+ 'fromRef' : {'latestCommit' : '2a1165446bdf991caf114d01f7c88d84ae7399cf' }
80+ }
81+ bitbucket_client .get_pull_requests_commits .return_value = [
82+ {'id' : '2a1165446bdf991caf114d01f7c88d84ae7399cf' ,
83+ 'parents' : [{'id' : 'f617708826cdd0b40abb5245eda71630192a17e3' }]}
84+ ]
85+ bitbucket_client .get_commits .return_value = [
86+ {'id' : '9c1cffdd9f276074bfb6fb3b70fbee62d298b058' },
87+ {'id' : 'dbca09554567d2e4bee7f07993390153280ee450' }
88+ ]
89+ bitbucket_client .get_pull_requests_changes .return_value = [
90+ {
91+ 'path' : {'toString' : 'Readme.md' },
92+ 'type' : 'MODIFY' ,
93+ }
94+ ]
95+
96+ bitbucket_client .get .side_effect = self .mock_get_from_bitbucket_70
97+ bitbucket_client .get_content_of_file .side_effect = self .mock_get_content_of_file
98+
99+ provider = BitbucketServerProvider (
100+ "https://git.onpreminstance.com/projects/AAA/repos/my-repo/pull-requests/1" ,
101+ bitbucket_client = bitbucket_client
102+ )
103+
104+ expected = [
105+ FilePatchInfo (
106+ 'file\n with\n multiple \n lines\n to\n emulate\n a\n real\n file\n ' ,
107+ 'file\n with\n multiple \n lines\n to\n emulate\n a\n fake\n file\n ' ,
108+ '--- \n +++ \n @@ -5,5 +5,5 @@\n to\n emulate\n a\n -real\n +fake\n file\n ' ,
109+ 'Readme.md' ,
110+ edit_type = EDIT_TYPE .MODIFIED ,
111+ )
112+ ]
113+
114+ actual = provider .get_diff_files ()
115+
116+ assert actual == expected
117+
118+
119+ '''
120+ tests the 2-way diff functionality where the diff should be between the HEAD of branch b and node c
121+ NOT between the HEAD of main and the HEAD of branch b
122+
123+ - o - o - o branch b
124+ / /
125+ o - o -- o - o main
126+ ^ node c
127+ '''
128+ def test_get_diff_files_diverge_with_merge_commit_70 (self ):
129+ bitbucket_client = MagicMock (Bitbucket )
130+ bitbucket_client .get_pull_request .return_value = {
131+ 'toRef' : {'latestCommit' : 'cb68a3027d6dda065a7692ebf2c90bed1bcdec28' },
132+ 'fromRef' : {'latestCommit' : '1905dcf16c0aac6ac24f7ab617ad09c73dc1d23b' }
133+ }
134+ bitbucket_client .get_pull_requests_commits .return_value = [
135+ {'id' : '1905dcf16c0aac6ac24f7ab617ad09c73dc1d23b' ,
136+ 'parents' : [{'id' : '692772f456c3db77a90b11ce39ea516f8c2bad93' }]},
137+ {'id' : '692772f456c3db77a90b11ce39ea516f8c2bad93' , 'parents' : [
138+ {'id' : '2a1165446bdf991caf114d01f7c88d84ae7399cf' },
139+ {'id' : '9c1cffdd9f276074bfb6fb3b70fbee62d298b058' },
140+ ]},
141+ {'id' : '2a1165446bdf991caf114d01f7c88d84ae7399cf' ,
142+ 'parents' : [{'id' : 'f617708826cdd0b40abb5245eda71630192a17e3' }]}
143+ ]
144+ bitbucket_client .get_commits .return_value = [
145+ {'id' : 'cb68a3027d6dda065a7692ebf2c90bed1bcdec28' },
146+ {'id' : '9c1cffdd9f276074bfb6fb3b70fbee62d298b058' },
147+ {'id' : 'dbca09554567d2e4bee7f07993390153280ee450' }
148+ ]
149+ bitbucket_client .get_pull_requests_changes .return_value = [
150+ {
151+ 'path' : {'toString' : 'Readme.md' },
152+ 'type' : 'MODIFY' ,
153+ }
154+ ]
155+
156+ bitbucket_client .get .side_effect = self .mock_get_from_bitbucket_70
157+ bitbucket_client .get_content_of_file .side_effect = self .mock_get_content_of_file
158+
159+ provider = BitbucketServerProvider (
160+ "https://git.onpreminstance.com/projects/AAA/repos/my-repo/pull-requests/1" ,
161+ bitbucket_client = bitbucket_client
162+ )
163+
164+ expected = [
165+ FilePatchInfo (
166+ 'file\n with\n some\n lines\n to\n emulate\n a\n real\n file\n ' ,
167+ 'file\n with\n some\n lines\n to\n emulate\n a\n fake\n test\n ' ,
168+ '--- \n +++ \n @@ -5,5 +5,5 @@\n to\n emulate\n a\n -real\n -file\n +fake\n +test\n ' ,
169+ 'Readme.md' ,
170+ edit_type = EDIT_TYPE .MODIFIED ,
171+ )
172+ ]
173+
174+ actual = provider .get_diff_files ()
175+
176+ assert actual == expected
177+
178+
179+ '''
180+ tests the 2-way diff functionality where the diff should be between the HEAD of branch c and node d
181+ NOT between the HEAD of main and the HEAD of branch c
182+
183+ ---- o - o branch c
184+ / /
185+ ---- o branch b
186+ / /
187+ o - o - o main
188+ ^ node d
189+ '''
190+ def get_multi_merge_diverge_mock_client (self , api_version ):
191+ bitbucket_client = MagicMock (Bitbucket )
192+ bitbucket_client .get_pull_request .return_value = {
193+ 'toRef' : {'latestCommit' : '9569922b22fe4fd0968be6a50ed99f71efcd0504' },
194+ 'fromRef' : {'latestCommit' : 'ae4eca7f222c96d396927d48ab7538e2ee13ca63' }
195+ }
196+ bitbucket_client .get_pull_requests_commits .return_value = [
197+ {'id' : 'ae4eca7f222c96d396927d48ab7538e2ee13ca63' ,
198+ 'parents' : [{'id' : 'bbf300fb3af5129af8c44659f8cc7a526a6a6f31' }]},
199+ {'id' : 'bbf300fb3af5129af8c44659f8cc7a526a6a6f31' , 'parents' : [
200+ {'id' : '10b7b8e41cb370b48ceda8da4e7e6ad033182213' },
201+ {'id' : 'd1bb183c706a3ebe4c2b1158c25878201a27ad8c' },
202+ ]},
203+ {'id' : 'd1bb183c706a3ebe4c2b1158c25878201a27ad8c' , 'parents' : [
204+ {'id' : '5bd76251866cb415fc5ff232f63a581e89223bda' },
205+ {'id' : '548f8ba15abc30875a082156314426806c3f4d97' }
206+ ]},
207+ {'id' : '5bd76251866cb415fc5ff232f63a581e89223bda' ,
208+ 'parents' : [{'id' : '0e898cb355a5170d8c8771b25d43fcaa1d2d9489' }]},
209+ {'id' : '10b7b8e41cb370b48ceda8da4e7e6ad033182213' ,
210+ 'parents' : [{'id' : '0e898cb355a5170d8c8771b25d43fcaa1d2d9489' }]}
211+ ]
212+ bitbucket_client .get_commits .return_value = [
213+ {'id' : '9569922b22fe4fd0968be6a50ed99f71efcd0504' },
214+ {'id' : '548f8ba15abc30875a082156314426806c3f4d97' }
215+ ]
216+ bitbucket_client .get_pull_requests_changes .return_value = [
217+ {
218+ 'path' : {'toString' : 'Readme.md' },
219+ 'type' : 'MODIFY' ,
220+ }
221+ ]
222+
223+ bitbucket_client .get_content_of_file .side_effect = self .mock_get_content_of_file
224+ if api_version == 60 :
225+ bitbucket_client .get .side_effect = self .mock_get_from_bitbucket_60
226+ elif api_version == 70 :
227+ bitbucket_client .get .side_effect = self .mock_get_from_bitbucket_70
228+ elif api_version == 816 :
229+ bitbucket_client .get .side_effect = self .mock_get_from_bitbucket_816
230+
231+ return bitbucket_client
232+
233+ def test_get_diff_files_multi_merge_diverge_60 (self ):
234+ bitbucket_client = self .get_multi_merge_diverge_mock_client (60 )
235+
236+ provider = BitbucketServerProvider (
237+ "https://git.onpreminstance.com/projects/AAA/repos/my-repo/pull-requests/1" ,
238+ bitbucket_client = bitbucket_client
239+ )
240+
241+ expected = [
242+ FilePatchInfo (
243+ 'file\n with\n multiple\n lines\n to\n emulate\n a\n real\n file' ,
244+ 'readme\n without\n some\n lines\n to\n simulate\n a\n real\n file' ,
245+ '--- \n +++ \n @@ -1,9 +1,9 @@\n -file\n -with\n -multiple\n +readme\n +without\n +some\n lines\n to\n -emulate\n +simulate\n a\n real\n file' ,
246+ 'Readme.md' ,
247+ edit_type = EDIT_TYPE .MODIFIED ,
248+ )
249+ ]
250+
251+ actual = provider .get_diff_files ()
252+
253+ assert actual == expected
254+
255+ def test_get_diff_files_multi_merge_diverge_70 (self ):
256+ bitbucket_client = self .get_multi_merge_diverge_mock_client (70 )
257+
258+ provider = BitbucketServerProvider (
259+ "https://git.onpreminstance.com/projects/AAA/repos/my-repo/pull-requests/1" ,
260+ bitbucket_client = bitbucket_client
261+ )
262+
263+ expected = [
264+ FilePatchInfo (
265+ 'file\n with\n some\n lines\n to\n emulate\n a\n real\n file' ,
266+ 'readme\n without\n some\n lines\n to\n simulate\n a\n real\n file' ,
267+ '--- \n +++ \n @@ -1,9 +1,9 @@\n -file\n -with\n +readme\n +without\n some\n lines\n to\n -emulate\n +simulate\n a\n real\n file' ,
268+ 'Readme.md' ,
269+ edit_type = EDIT_TYPE .MODIFIED ,
270+ )
271+ ]
272+
273+ actual = provider .get_diff_files ()
274+
275+ assert actual == expected
276+
277+ def test_get_diff_files_multi_merge_diverge_816 (self ):
278+ bitbucket_client = self .get_multi_merge_diverge_mock_client (816 )
279+
280+ provider = BitbucketServerProvider (
281+ "https://git.onpreminstance.com/projects/AAA/repos/my-repo/pull-requests/1" ,
282+ bitbucket_client = bitbucket_client
283+ )
284+
285+ expected = [
286+ FilePatchInfo (
287+ 'file\n with\n some\n lines\n to\n emulate\n a\n real\n file' ,
288+ 'readme\n without\n some\n lines\n to\n simulate\n a\n real\n file' ,
289+ '--- \n +++ \n @@ -1,9 +1,9 @@\n -file\n -with\n +readme\n +without\n some\n lines\n to\n -emulate\n +simulate\n a\n real\n file' ,
290+ 'Readme.md' ,
291+ edit_type = EDIT_TYPE .MODIFIED ,
292+ )
293+ ]
294+
295+ actual = provider .get_diff_files ()
296+
297+ assert actual == expected
0 commit comments