1import json
2from mock import patch
3
4import jenkins
5from tests.base import JenkinsTestBase
6
7
8class JenkinsViewsTestBase(JenkinsTestBase):
9    config_xml = """
10        <listView>
11            <description>Foo</description>
12            <jobNames />
13        </listView>"""
14
15
16class JenkinsGetViewNameTest(JenkinsViewsTestBase):
17
18    @patch.object(jenkins.Jenkins, 'jenkins_open')
19    def test_simple(self, jenkins_mock):
20        view_name_to_return = {u'name': 'Test View'}
21        jenkins_mock.return_value = json.dumps(view_name_to_return)
22
23        view_name = self.j.get_view_name(u'Test View')
24
25        self.assertEqual(view_name, 'Test View')
26        self.assertEqual(
27            jenkins_mock.call_args[0][0].url,
28            self.make_url('view/Test%20View/api/json?tree=name'))
29        self._check_requests(jenkins_mock.call_args_list)
30
31    @patch.object(jenkins.Jenkins, 'jenkins_open')
32    def test_dir_simple(self, jenkins_mock):
33        # VIEW_NAME will always return just name of view instead
34        # of dir/view_name and this is specific of jenkins
35        view_name_to_return = {u'name': 'Test View'}
36        jenkins_mock.return_value = json.dumps(view_name_to_return)
37
38        view_name = self.j.get_view_name(u'Test Dir/Test View')
39
40        self.assertEqual(view_name, 'Test Dir/Test View')
41        self.assertEqual(
42            jenkins_mock.call_args[0][0].url,
43            self.make_url('job/Test%20Dir/view/Test%20View/api/json?tree=name'))
44        self._check_requests(jenkins_mock.call_args_list)
45
46    @patch.object(jenkins.Jenkins, 'jenkins_open')
47    def test_dir_extended(self, jenkins_mock):
48        # VIEW_NAME will always return just name of view instead
49        # of dir/view_name and this is specific of jenkins
50        view_name_to_return = {u'name': 'Test View'}
51        jenkins_mock.return_value = json.dumps(view_name_to_return)
52
53        view_name = self.j.get_view_name(u'Test Extended/Test Dir/Test View')
54
55        self.assertEqual(view_name, 'Test Extended/Test Dir/Test View')
56        self.assertEqual(
57            jenkins_mock.call_args[0][0].url,
58            self.make_url('job/Test%20Extended/job/Test%20Dir/view/Test%20View/api/json?tree=name'))
59        self._check_requests(jenkins_mock.call_args_list)
60
61    @patch.object(jenkins.Jenkins, 'jenkins_open')
62    def test_return_none(self, jenkins_mock):
63        jenkins_mock.side_effect = jenkins.NotFoundException()
64
65        view_name = self.j.get_view_name(u'TestView')
66
67        self.assertEqual(view_name, None)
68        self.assertEqual(
69            jenkins_mock.call_args[0][0].url,
70            self.make_url('view/TestView/api/json?tree=name'))
71        self._check_requests(jenkins_mock.call_args_list)
72
73    @patch.object(jenkins.Jenkins, 'jenkins_open')
74    def test_dir_return_none(self, jenkins_mock):
75        jenkins_mock.side_effect = jenkins.NotFoundException()
76
77        view_name = self.j.get_view_name(u'TestDir/TestView')
78
79        self.assertEqual(view_name, None)
80        self.assertEqual(
81            jenkins_mock.call_args[0][0].url,
82            self.make_url('job/TestDir/view/TestView/api/json?tree=name'))
83        self._check_requests(jenkins_mock.call_args_list)
84
85    @patch.object(jenkins.Jenkins, 'jenkins_open')
86    def test_extended_dir_return_none(self, jenkins_mock):
87        jenkins_mock.side_effect = jenkins.NotFoundException()
88
89        view_name = self.j.get_view_name(u'TestExtended/TestDir/TestView')
90
91        self.assertEqual(view_name, None)
92        self.assertEqual(
93            jenkins_mock.call_args[0][0].url,
94            self.make_url('job/TestExtended/job/TestDir/view/TestView/api/json?tree=name'))
95        self._check_requests(jenkins_mock.call_args_list)
96
97    @patch.object(jenkins.Jenkins, 'jenkins_open')
98    def test_unexpected_view_name(self, jenkins_mock):
99        view_name_to_return = {u'name': 'not the right name'}
100        jenkins_mock.return_value = json.dumps(view_name_to_return)
101
102        with self.assertRaises(jenkins.JenkinsException) as context_manager:
103            self.j.get_view_name(u'TestView')
104        self.assertEqual(
105            jenkins_mock.call_args_list[0][0][0].url,
106            self.make_url('view/TestView/api/json?tree=name'))
107        self.assertEqual(
108            str(context_manager.exception),
109            'Jenkins returned an unexpected view name {0} '
110            '(expected: {1})'.format(view_name_to_return['name'], 'TestView'))
111        self._check_requests(jenkins_mock.call_args_list)
112
113    @patch.object(jenkins.Jenkins, 'jenkins_open')
114    def test_unexpected_dir_view_name(self, jenkins_mock):
115        view_name_to_return = {u'name': 'not the right name'}
116        jenkins_mock.return_value = json.dumps(view_name_to_return)
117
118        with self.assertRaises(jenkins.JenkinsException) as context_manager:
119            self.j.get_view_name(u'TestDir/TestView')
120        self.assertEqual(
121            jenkins_mock.call_args_list[0][0][0].url,
122            self.make_url('job/TestDir/view/TestView/api/json?tree=name'))
123        self.assertEqual(
124            str(context_manager.exception),
125            'Jenkins returned an unexpected view name {0} '
126            '(expected: {1})'.format(view_name_to_return['name'], 'TestView'))
127        self._check_requests(jenkins_mock.call_args_list)
128
129    @patch.object(jenkins.Jenkins, 'jenkins_open')
130    def test_unexpected_extended_dir_view_name(self, jenkins_mock):
131        view_name_to_return = {u'name': 'not the right name'}
132        jenkins_mock.return_value = json.dumps(view_name_to_return)
133
134        with self.assertRaises(jenkins.JenkinsException) as context_manager:
135            self.j.get_view_name(u'TestExtended/TestDir/TestView')
136        self.assertEqual(
137            jenkins_mock.call_args_list[0][0][0].url,
138            self.make_url('job/TestExtended/job/TestDir/view/TestView/api/json?tree=name'))
139        self.assertEqual(
140            str(context_manager.exception),
141            'Jenkins returned an unexpected view name {0} '
142            '(expected: {1})'.format(view_name_to_return['name'], 'TestView'))
143        self._check_requests(jenkins_mock.call_args_list)
144
145
146class JenkinsAssertViewTest(JenkinsViewsTestBase):
147
148    @patch.object(jenkins.Jenkins, 'jenkins_open')
149    def test_view_missing(self, jenkins_mock):
150        jenkins_mock.side_effect = jenkins.NotFoundException()
151
152        with self.assertRaises(jenkins.JenkinsException) as context_manager:
153            self.j.assert_view_exists('NonExistent')
154        self.assertEqual(
155            str(context_manager.exception),
156            'view[NonExistent] does not exist')
157        self._check_requests(jenkins_mock.call_args_list)
158
159    @patch.object(jenkins.Jenkins, 'jenkins_open')
160    def test_view_exists(self, jenkins_mock):
161        jenkins_mock.side_effect = [
162            json.dumps({'name': 'ExistingView'}),
163        ]
164        self.j.assert_view_exists('ExistingView')
165        self._check_requests(jenkins_mock.call_args_list)
166
167    @patch.object(jenkins.Jenkins, 'jenkins_open')
168    def test_dir_view_exists(self, jenkins_mock):
169        jenkins_mock.side_effect = [
170            json.dumps({'name': 'ExistingView'}),
171        ]
172        self.j.assert_view_exists('Dir/ExistingView')
173        self._check_requests(jenkins_mock.call_args_list)
174
175    @patch.object(jenkins.Jenkins, 'jenkins_open')
176    def test_extended_dir_view_exists(self, jenkins_mock):
177        jenkins_mock.side_effect = [
178            json.dumps({'name': 'ExistingView'}),
179        ]
180        self.j.assert_view_exists('Extended/Dir/ExistingView')
181        self._check_requests(jenkins_mock.call_args_list)
182
183
184class JenkinsGetViewsTest(JenkinsViewsTestBase):
185
186    @patch.object(jenkins.Jenkins, 'jenkins_open')
187    def test_simple(self, jenkins_mock):
188        views = {
189            u'url': u'http://your_url_here/view/my_view/',
190            u'name': u'my_view',
191        }
192        view_info_to_return = {u'views': views}
193        jenkins_mock.return_value = json.dumps(view_info_to_return)
194
195        view_info = self.j.get_views()
196
197        self.assertEqual(view_info, views)
198        self.assertEqual(
199            jenkins_mock.call_args[0][0].url,
200            self.make_url('api/json'))
201        self._check_requests(jenkins_mock.call_args_list)
202
203
204class JenkinsDeleteViewTest(JenkinsViewsTestBase):
205
206    @patch.object(jenkins.Jenkins, 'jenkins_open')
207    def test_simple(self, jenkins_mock):
208        jenkins_mock.side_effect = [
209            None,
210            jenkins.NotFoundException(),
211        ]
212
213        self.j.delete_view(u'Test View')
214
215        self.assertEqual(
216            jenkins_mock.call_args_list[0][0][0].url,
217            self.make_url('view/Test%20View/doDelete'))
218        self._check_requests(jenkins_mock.call_args_list)
219
220    @patch.object(jenkins.Jenkins, 'jenkins_open')
221    def test_dir_simple(self, jenkins_mock):
222        jenkins_mock.side_effect = [
223            None,
224            jenkins.NotFoundException(),
225        ]
226
227        self.j.delete_view(u'Test Dir/Test View')
228
229        self.assertEqual(
230            jenkins_mock.call_args_list[0][0][0].url,
231            self.make_url('job/Test%20Dir/view/Test%20View/doDelete'))
232        self._check_requests(jenkins_mock.call_args_list)
233
234    @patch.object(jenkins.Jenkins, 'jenkins_open')
235    def test_extended_dir_simple(self, jenkins_mock):
236        jenkins_mock.side_effect = [
237            None,
238            jenkins.NotFoundException(),
239        ]
240
241        self.j.delete_view(u'Test Extended/Test Dir/Test View')
242
243        self.assertEqual(
244            jenkins_mock.call_args_list[0][0][0].url,
245            self.make_url('job/Test%20Extended/job/Test%20Dir/view/Test%20View/doDelete'))
246        self._check_requests(jenkins_mock.call_args_list)
247
248    @patch.object(jenkins.Jenkins, 'jenkins_open')
249    def test_failed(self, jenkins_mock):
250        jenkins_mock.side_effect = [
251            json.dumps({'name': 'TestView'}),
252            json.dumps({'name': 'TestView'}),
253            json.dumps({'name': 'TestView'}),
254        ]
255
256        with self.assertRaises(jenkins.JenkinsException) as context_manager:
257            self.j.delete_view(u'TestView')
258        self.assertEqual(
259            jenkins_mock.call_args_list[0][0][0].url,
260            self.make_url('view/TestView/doDelete'))
261        self.assertEqual(
262            str(context_manager.exception),
263            'delete[TestView] failed')
264        self._check_requests(jenkins_mock.call_args_list)
265
266    @patch.object(jenkins.Jenkins, 'jenkins_open')
267    def test_dir_failed(self, jenkins_mock):
268        jenkins_mock.side_effect = [
269            json.dumps({'name': 'TestView'}),
270            json.dumps({'name': 'TestView'}),
271            json.dumps({'name': 'TestView'}),
272        ]
273
274        with self.assertRaises(jenkins.JenkinsException) as context_manager:
275            self.j.delete_view(u'TestDir/TestView')
276        self.assertEqual(
277            jenkins_mock.call_args_list[0][0][0].url,
278            self.make_url('job/TestDir/view/TestView/doDelete'))
279        self.assertEqual(
280            str(context_manager.exception),
281            'delete[TestDir/TestView] failed')
282        self._check_requests(jenkins_mock.call_args_list)
283
284    @patch.object(jenkins.Jenkins, 'jenkins_open')
285    def test_extended_dir_failed(self, jenkins_mock):
286        jenkins_mock.side_effect = [
287            json.dumps({'name': 'TestView'}),
288            json.dumps({'name': 'TestView'}),
289            json.dumps({'name': 'TestView'}),
290        ]
291
292        with self.assertRaises(jenkins.JenkinsException) as context_manager:
293            self.j.delete_view(u'TestExtended/TestDir/TestView')
294        self.assertEqual(
295            jenkins_mock.call_args_list[0][0][0].url,
296            self.make_url('job/TestExtended/job/TestDir/view/TestView/doDelete'))
297        self.assertEqual(
298            str(context_manager.exception),
299            'delete[TestExtended/TestDir/TestView] failed')
300        self._check_requests(jenkins_mock.call_args_list)
301
302
303class JenkinsCreateViewTest(JenkinsViewsTestBase):
304
305    @patch.object(jenkins.Jenkins, 'jenkins_open')
306    def test_simple(self, jenkins_mock):
307        jenkins_mock.side_effect = [
308            jenkins.NotFoundException(),
309            None,
310            json.dumps({'name': 'Test View'}),
311        ]
312
313        self.j.create_view(u'Test View', self.config_xml)
314
315        self.assertEqual(
316            jenkins_mock.call_args_list[1][0][0].url,
317            self.make_url('createView?name=Test%20View'))
318        self._check_requests(jenkins_mock.call_args_list)
319
320    @patch.object(jenkins.Jenkins, 'jenkins_open')
321    def test_dir_simple(self, jenkins_mock):
322        jenkins_mock.side_effect = [
323            jenkins.NotFoundException(),
324            None,
325            json.dumps({'name': 'Test View'}),
326        ]
327
328        self.j.create_view(u'Test Dir/Test View', self.config_xml)
329
330        self.assertEqual(
331            jenkins_mock.call_args_list[1][0][0].url,
332            self.make_url('job/Test%20Dir/createView?name=Test%20View'))
333        self._check_requests(jenkins_mock.call_args_list)
334
335    @patch.object(jenkins.Jenkins, 'jenkins_open')
336    def test_extended_dir_simple(self, jenkins_mock):
337        jenkins_mock.side_effect = [
338            jenkins.NotFoundException(),
339            None,
340            json.dumps({'name': 'Test View'}),
341        ]
342
343        self.j.create_view(u'Test Extended/Test Dir/Test View', self.config_xml)
344
345        self.assertEqual(
346            jenkins_mock.call_args_list[1][0][0].url,
347            self.make_url('job/Test%20Extended/job/Test%20Dir/createView?name=Test%20View'))
348        self._check_requests(jenkins_mock.call_args_list)
349
350    @patch.object(jenkins.Jenkins, 'jenkins_open')
351    def test_already_exists(self, jenkins_mock):
352        jenkins_mock.side_effect = [
353            json.dumps({'name': 'TestView'}),
354            None,
355        ]
356
357        with self.assertRaises(jenkins.JenkinsException) as context_manager:
358            self.j.create_view(u'TestView', self.config_xml)
359        self.assertEqual(
360            jenkins_mock.call_args_list[0][0][0].url,
361            self.make_url('view/TestView/api/json?tree=name'))
362        self.assertEqual(
363            str(context_manager.exception),
364            'view[TestView] already exists')
365        self._check_requests(jenkins_mock.call_args_list)
366
367    @patch.object(jenkins.Jenkins, 'jenkins_open')
368    def test_dir_already_exists(self, jenkins_mock):
369        jenkins_mock.side_effect = [
370            json.dumps({'name': 'TestView'}),
371            None,
372        ]
373
374        with self.assertRaises(jenkins.JenkinsException) as context_manager:
375            self.j.create_view(u'TestDir/TestView', self.config_xml)
376        self.assertEqual(
377            jenkins_mock.call_args_list[0][0][0].url,
378            self.make_url('job/TestDir/view/TestView/api/json?tree=name'))
379        self.assertEqual(
380            str(context_manager.exception),
381            'view[TestDir/TestView] already exists')
382        self._check_requests(jenkins_mock.call_args_list)
383
384    @patch.object(jenkins.Jenkins, 'jenkins_open')
385    def test_extended_dir_already_exists(self, jenkins_mock):
386        jenkins_mock.side_effect = [
387            json.dumps({'name': 'TestView'}),
388            None,
389        ]
390
391        with self.assertRaises(jenkins.JenkinsException) as context_manager:
392            self.j.create_view(u'TestExtended/TestDir/TestView', self.config_xml)
393        self.assertEqual(
394            jenkins_mock.call_args_list[0][0][0].url,
395            self.make_url('job/TestExtended/job/TestDir/view/TestView/api/json?tree=name'))
396        self.assertEqual(
397            str(context_manager.exception),
398            'view[TestExtended/TestDir/TestView] already exists')
399        self._check_requests(jenkins_mock.call_args_list)
400
401    @patch.object(jenkins.Jenkins, 'jenkins_open')
402    def test_failed(self, jenkins_mock):
403        jenkins_mock.side_effect = [
404            jenkins.NotFoundException(),
405            None,
406            jenkins.NotFoundException(),
407        ]
408
409        with self.assertRaises(jenkins.JenkinsException) as context_manager:
410            self.j.create_view(u'TestView', self.config_xml)
411        self.assertEqual(
412            jenkins_mock.call_args_list[0][0][0].url,
413            self.make_url('view/TestView/api/json?tree=name'))
414        self.assertEqual(
415            jenkins_mock.call_args_list[1][0][0].url,
416            self.make_url('createView?name=TestView'))
417        self.assertEqual(
418            str(context_manager.exception),
419            'create[TestView] failed')
420        self._check_requests(jenkins_mock.call_args_list)
421
422    @patch.object(jenkins.Jenkins, 'jenkins_open')
423    def test_dir_failed(self, jenkins_mock):
424        jenkins_mock.side_effect = [
425            jenkins.NotFoundException(),
426            None,
427            jenkins.NotFoundException(),
428        ]
429
430        with self.assertRaises(jenkins.JenkinsException) as context_manager:
431            self.j.create_view(u'TestDir/TestView', self.config_xml)
432        self.assertEqual(
433            jenkins_mock.call_args_list[0][0][0].url,
434            self.make_url('job/TestDir/view/TestView/api/json?tree=name'))
435        self.assertEqual(
436            jenkins_mock.call_args_list[1][0][0].url,
437            self.make_url('job/TestDir/createView?name=TestView'))
438        self.assertEqual(
439            str(context_manager.exception),
440            'create[TestDir/TestView] failed')
441        self._check_requests(jenkins_mock.call_args_list)
442
443    @patch.object(jenkins.Jenkins, 'jenkins_open')
444    def test_extended_dir_failed(self, jenkins_mock):
445        jenkins_mock.side_effect = [
446            jenkins.NotFoundException(),
447            None,
448            jenkins.NotFoundException(),
449        ]
450
451        with self.assertRaises(jenkins.JenkinsException) as context_manager:
452            self.j.create_view(u'TestExtended/TestDir/TestView', self.config_xml)
453        self.assertEqual(
454            jenkins_mock.call_args_list[0][0][0].url,
455            self.make_url('job/TestExtended/job/TestDir/view/TestView/api/json?tree=name'))
456        self.assertEqual(
457            jenkins_mock.call_args_list[1][0][0].url,
458            self.make_url('job/TestExtended/job/TestDir/createView?name=TestView'))
459        self.assertEqual(
460            str(context_manager.exception),
461            'create[TestExtended/TestDir/TestView] failed')
462        self._check_requests(jenkins_mock.call_args_list)
463
464
465class JenkinsReconfigViewTest(JenkinsViewsTestBase):
466
467    @patch.object(jenkins.Jenkins, 'jenkins_open')
468    def test_simple(self, jenkins_mock):
469        jenkins_mock.side_effect = [
470            json.dumps({'name': 'Test View'}),
471            None,
472        ]
473
474        self.j.reconfig_view(u'Test View', self.config_xml)
475
476        self.assertEqual(jenkins_mock.call_args[0][0].url,
477                         self.make_url('view/Test%20View/config.xml'))
478        self._check_requests(jenkins_mock.call_args_list)
479
480    @patch.object(jenkins.Jenkins, 'jenkins_open')
481    def test_dir_simple(self, jenkins_mock):
482        jenkins_mock.side_effect = [
483            json.dumps({'name': 'Test View'}),
484            None,
485        ]
486
487        self.j.reconfig_view(u'Test Dir/Test View', self.config_xml)
488
489        self.assertEqual(jenkins_mock.call_args[0][0].url,
490                         self.make_url('job/Test%20Dir/view/Test%20View/config.xml'))
491        self._check_requests(jenkins_mock.call_args_list)
492
493    @patch.object(jenkins.Jenkins, 'jenkins_open')
494    def test_extended_dir_simple(self, jenkins_mock):
495        jenkins_mock.side_effect = [
496            json.dumps({'name': 'Test View'}),
497            None,
498        ]
499
500        self.j.reconfig_view(u'Test Extended/Test Dir/Test View', self.config_xml)
501
502        self.assertEqual(jenkins_mock.call_args[0][0].url,
503                         self.make_url('job/Test%20Extended/job/Test%20Dir/view/Test%20View/config.xml'))
504        self._check_requests(jenkins_mock.call_args_list)
505
506
507class JenkinsGetViewConfigTest(JenkinsViewsTestBase):
508
509    @patch.object(jenkins.Jenkins, 'jenkins_open')
510    def test_encodes_view_name(self, jenkins_mock):
511        self.j.get_view_config(u'Test View')
512
513        self.assertEqual(
514            jenkins_mock.call_args[0][0].url,
515            self.make_url('view/Test%20View/config.xml'))
516        self._check_requests(jenkins_mock.call_args_list)
517
518    @patch.object(jenkins.Jenkins, 'jenkins_open')
519    def test_encodes_dir_view_name(self, jenkins_mock):
520        self.j.get_view_config(u'Test Dir/Test View')
521
522        self.assertEqual(
523            jenkins_mock.call_args[0][0].url,
524            self.make_url('job/Test%20Dir/view/Test%20View/config.xml'))
525        self._check_requests(jenkins_mock.call_args_list)
526
527    @patch.object(jenkins.Jenkins, 'jenkins_open')
528    def test_encodes_extended_dir_view_name(self, jenkins_mock):
529        self.j.get_view_config(u'Test Extended/Test Dir/Test View')
530
531        self.assertEqual(
532            jenkins_mock.call_args[0][0].url,
533            self.make_url('job/Test%20Extended/job/Test%20Dir/view/Test%20View/config.xml'))
534        self._check_requests(jenkins_mock.call_args_list)
535