##// END OF EJS Templates
integrations: rewrote usage of pylons components inside integrations....
marcink -
r1990:32399c6a default
parent child Browse files
Show More
@@ -0,0 +1,19 b''
1 # -*- coding: utf-8 -*-
2
3 # Copyright (C) 2016-2017 RhodeCode GmbH
4 #
5 # This program is free software: you can redistribute it and/or modify
6 # it under the terms of the GNU Affero General Public License, version 3
7 # (only), as published by the Free Software Foundation.
8 #
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
13 #
14 # You should have received a copy of the GNU Affero General Public License
15 # along with this program. If not, see <http://www.gnu.org/licenses/>.
16 #
17 # This program is dual-licensed. If you wish to learn more about the
18 # RhodeCode Enterprise Edition, including its added features, Support services,
19 # and proprietary license terms, please see https://rhodecode.com/licenses/
@@ -21,6 +21,7 b''
21 21 import logging
22 22
23 23 from rhodecode.apps._base import ADMIN_PREFIX, add_route_requirements
24 from rhodecode.lib.utils2 import safe_int
24 25 from rhodecode.model.db import Repository, Integration, RepoGroup
25 26 from rhodecode.integrations import integration_type_registry
26 27
@@ -30,7 +31,6 b' log = logging.getLogger(__name__)'
30 31 def includeme(config):
31 32
32 33 # global integrations
33
34 34 config.add_route('global_integrations_new',
35 35 ADMIN_PREFIX + '/integrations/new')
36 36 config.add_view('rhodecode.integrations.views.GlobalIntegrationsView',
@@ -45,7 +45,7 b' def includeme(config):'
45 45 ADMIN_PREFIX + '/integrations/{integration}')
46 46 for route_name in ['global_integrations_home', 'global_integrations_list']:
47 47 config.add_view('rhodecode.integrations.views.GlobalIntegrationsView',
48 attr='index',
48 attr='integration_list',
49 49 renderer='rhodecode:templates/admin/integrations/list.mako',
50 50 request_method='GET',
51 51 route_name=route_name)
@@ -57,7 +57,6 b' def includeme(config):'
57 57 ADMIN_PREFIX + '/integrations/{integration}/{integration_id}',
58 58 custom_predicates=(valid_integration,))
59 59
60
61 60 for route_name in ['global_integrations_create', 'global_integrations_edit']:
62 61 config.add_view('rhodecode.integrations.views.GlobalIntegrationsView',
63 62 attr='settings_get',
@@ -70,154 +69,159 b' def includeme(config):'
70 69 request_method='POST',
71 70 route_name=route_name)
72 71
73
74 72 # repo group integrations
75 73 config.add_route('repo_group_integrations_home',
76 add_route_requirements(
77 '{repo_group_name}/settings/integrations',
78 ),
79 custom_predicates=(valid_repo_group,)
80 )
81 config.add_route('repo_group_integrations_list',
82 add_route_requirements(
83 '{repo_group_name}/settings/integrations/{integration}',
84 ),
85 custom_predicates=(valid_repo_group, valid_integration))
86 for route_name in ['repo_group_integrations_home', 'repo_group_integrations_list']:
87 config.add_view('rhodecode.integrations.views.RepoGroupIntegrationsView',
88 attr='index',
89 renderer='rhodecode:templates/admin/integrations/list.mako',
90 request_method='GET',
91 route_name=route_name)
74 add_route_requirements('/{repo_group_name}/settings/integrations'),
75 repo_group_route=True)
76
77 config.add_view('rhodecode.integrations.views.RepoGroupIntegrationsView',
78 attr='integration_list',
79 renderer='rhodecode:templates/admin/integrations/list.mako',
80 request_method='GET',
81 route_name='repo_group_integrations_home')
92 82
93 83 config.add_route('repo_group_integrations_new',
94 add_route_requirements(
95 '{repo_group_name}/settings/integrations/new',
96 ),
97 custom_predicates=(valid_repo_group,))
84 add_route_requirements('/{repo_group_name}/settings/integrations/new'),
85 repo_group_route=True)
98 86 config.add_view('rhodecode.integrations.views.RepoGroupIntegrationsView',
99 87 attr='new_integration',
100 88 renderer='rhodecode:templates/admin/integrations/new.mako',
101 89 request_method='GET',
102 90 route_name='repo_group_integrations_new')
103 91
92 config.add_route('repo_group_integrations_list',
93 add_route_requirements('/{repo_group_name}/settings/integrations/{integration}'),
94 repo_group_route=True,
95 custom_predicates=(valid_integration,))
96 config.add_view('rhodecode.integrations.views.RepoGroupIntegrationsView',
97 attr='integration_list',
98 renderer='rhodecode:templates/admin/integrations/list.mako',
99 request_method='GET',
100 route_name='repo_group_integrations_list')
101
104 102 config.add_route('repo_group_integrations_create',
105 add_route_requirements(
106 '{repo_group_name}/settings/integrations/{integration}/new',
107 ),
108 custom_predicates=(valid_repo_group, valid_integration))
103 add_route_requirements('/{repo_group_name}/settings/integrations/{integration}/new'),
104 repo_group_route=True,
105 custom_predicates=(valid_integration,))
106 config.add_view('rhodecode.integrations.views.RepoGroupIntegrationsView',
107 attr='settings_get',
108 renderer='rhodecode:templates/admin/integrations/form.mako',
109 request_method='GET',
110 route_name='repo_group_integrations_create')
111 config.add_view('rhodecode.integrations.views.RepoGroupIntegrationsView',
112 attr='settings_post',
113 renderer='rhodecode:templates/admin/integrations/form.mako',
114 request_method='POST',
115 route_name='repo_group_integrations_create')
116
109 117 config.add_route('repo_group_integrations_edit',
110 add_route_requirements(
111 '{repo_group_name}/settings/integrations/{integration}/{integration_id}',
112 ),
113 custom_predicates=(valid_repo_group, valid_integration))
114 for route_name in ['repo_group_integrations_edit', 'repo_group_integrations_create']:
115 config.add_view('rhodecode.integrations.views.RepoGroupIntegrationsView',
116 attr='settings_get',
117 renderer='rhodecode:templates/admin/integrations/form.mako',
118 request_method='GET',
119 route_name=route_name)
120 config.add_view('rhodecode.integrations.views.RepoGroupIntegrationsView',
121 attr='settings_post',
122 renderer='rhodecode:templates/admin/integrations/form.mako',
123 request_method='POST',
124 route_name=route_name)
118 add_route_requirements('/{repo_group_name}/settings/integrations/{integration}/{integration_id}'),
119 repo_group_route=True,
120 custom_predicates=(valid_integration,))
125 121
122 config.add_view('rhodecode.integrations.views.RepoGroupIntegrationsView',
123 attr='settings_get',
124 renderer='rhodecode:templates/admin/integrations/form.mako',
125 request_method='GET',
126 route_name='repo_group_integrations_edit')
127 config.add_view('rhodecode.integrations.views.RepoGroupIntegrationsView',
128 attr='settings_post',
129 renderer='rhodecode:templates/admin/integrations/form.mako',
130 request_method='POST',
131 route_name='repo_group_integrations_edit')
126 132
127 133 # repo integrations
128 134 config.add_route('repo_integrations_home',
129 add_route_requirements(
130 '{repo_name}/settings/integrations',
131 ),
132 custom_predicates=(valid_repo,))
133 config.add_route('repo_integrations_list',
134 add_route_requirements(
135 '{repo_name}/settings/integrations/{integration}',
136 ),
137 custom_predicates=(valid_repo, valid_integration))
138 for route_name in ['repo_integrations_home', 'repo_integrations_list']:
139 config.add_view('rhodecode.integrations.views.RepoIntegrationsView',
140 attr='index',
141 request_method='GET',
142 renderer='rhodecode:templates/admin/integrations/list.mako',
143 route_name=route_name)
135 add_route_requirements('/{repo_name}/settings/integrations'),
136 repo_route=True)
137 config.add_view('rhodecode.integrations.views.RepoIntegrationsView',
138 attr='integration_list',
139 request_method='GET',
140 renderer='rhodecode:templates/admin/integrations/list.mako',
141 route_name='repo_integrations_home')
144 142
145 143 config.add_route('repo_integrations_new',
146 add_route_requirements(
147 '{repo_name}/settings/integrations/new',
148 ),
149 custom_predicates=(valid_repo,))
144 add_route_requirements('/{repo_name}/settings/integrations/new'),
145 repo_route=True)
150 146 config.add_view('rhodecode.integrations.views.RepoIntegrationsView',
151 147 attr='new_integration',
152 148 renderer='rhodecode:templates/admin/integrations/new.mako',
153 149 request_method='GET',
154 150 route_name='repo_integrations_new')
155 151
152 config.add_route('repo_integrations_list',
153 add_route_requirements('/{repo_name}/settings/integrations/{integration}'),
154 repo_route=True,
155 custom_predicates=(valid_integration,))
156 config.add_view('rhodecode.integrations.views.RepoIntegrationsView',
157 attr='integration_list',
158 request_method='GET',
159 renderer='rhodecode:templates/admin/integrations/list.mako',
160 route_name='repo_integrations_list')
161
156 162 config.add_route('repo_integrations_create',
157 add_route_requirements(
158 '{repo_name}/settings/integrations/{integration}/new',
159 ),
160 custom_predicates=(valid_repo, valid_integration))
163 add_route_requirements('/{repo_name}/settings/integrations/{integration}/new'),
164 repo_route=True,
165 custom_predicates=(valid_integration,))
166 config.add_view('rhodecode.integrations.views.RepoIntegrationsView',
167 attr='settings_get',
168 renderer='rhodecode:templates/admin/integrations/form.mako',
169 request_method='GET',
170 route_name='repo_integrations_create')
171 config.add_view('rhodecode.integrations.views.RepoIntegrationsView',
172 attr='settings_post',
173 renderer='rhodecode:templates/admin/integrations/form.mako',
174 request_method='POST',
175 route_name='repo_integrations_create')
176
161 177 config.add_route('repo_integrations_edit',
162 add_route_requirements(
163 '{repo_name}/settings/integrations/{integration}/{integration_id}',
164 ),
165 custom_predicates=(valid_repo, valid_integration))
166 for route_name in ['repo_integrations_edit', 'repo_integrations_create']:
167 config.add_view('rhodecode.integrations.views.RepoIntegrationsView',
168 attr='settings_get',
169 renderer='rhodecode:templates/admin/integrations/form.mako',
170 request_method='GET',
171 route_name=route_name)
172 config.add_view('rhodecode.integrations.views.RepoIntegrationsView',
173 attr='settings_post',
174 renderer='rhodecode:templates/admin/integrations/form.mako',
175 request_method='POST',
176 route_name=route_name)
178 add_route_requirements('/{repo_name}/settings/integrations/{integration}/{integration_id}'),
179 repo_route=True,
180 custom_predicates=(valid_integration,))
181 config.add_view('rhodecode.integrations.views.RepoIntegrationsView',
182 attr='settings_get',
183 renderer='rhodecode:templates/admin/integrations/form.mako',
184 request_method='GET',
185 route_name='repo_integrations_edit')
186 config.add_view('rhodecode.integrations.views.RepoIntegrationsView',
187 attr='settings_post',
188 renderer='rhodecode:templates/admin/integrations/form.mako',
189 request_method='POST',
190 route_name='repo_integrations_edit')
177 191
178 192
179 def valid_repo(info, request):
180 repo = Repository.get_by_repo_name(info['match']['repo_name'])
181 if repo:
182 return True
183
184
185 def valid_repo_group(info, request):
186 repo_group = RepoGroup.get_by_group_name(info['match']['repo_group_name'])
187 if repo_group:
188 return True
189 return False
190
191 193
192 194 def valid_integration(info, request):
193 195 integration_type = info['match']['integration']
194 196 integration_id = info['match'].get('integration_id')
195 repo_name = info['match'].get('repo_name')
196 repo_group_name = info['match'].get('repo_group_name')
197 197
198 198 if integration_type not in integration_type_registry:
199 199 return False
200 200
201 repo, repo_group = None, None
202 if repo_name:
203 repo = Repository.get_by_repo_name(repo_name)
204 if not repo:
201 if integration_id:
202 if not safe_int(integration_id):
205 203 return False
206 204
207 if repo_group_name:
208 repo_group = RepoGroup.get_by_group_name(repo_group_name)
209 if not repo_group:
210 return False
211
212 if repo_name and repo_group:
213 raise Exception('Either repo or repo_group can be set, not both')
214
215 if integration_id:
216 205 integration = Integration.get(integration_id)
217 206 if not integration:
218 207 return False
219 208 if integration.integration_type != integration_type:
220 209 return False
210
211 # match types to repo or repo group
212 repo_name = info['match'].get('repo_name')
213 repo_group_name = info['match'].get('repo_group_name')
214 repo, repo_group = None, None
215 if repo_name:
216 repo = Repository.get_by_repo_name(repo_name)
217 if not repo:
218 return False
219
220 if repo_group_name:
221 repo_group = RepoGroup.get_by_group_name(repo_group_name)
222 if not repo_group:
223 return False
224
221 225 if repo and repo.repo_id != integration.repo_id:
222 226 return False
223 227 if repo_group and repo_group.group_id != integration.repo_group_id:
@@ -20,10 +20,16 b''
20 20
21 21 import pytest
22 22
23 from rhodecode.apps._base import ADMIN_PREFIX
23 24 from rhodecode.model.db import Integration
24 25 from rhodecode.model.meta import Session
25 26 from rhodecode.integrations import integration_type_registry
26 from rhodecode.config.routing import ADMIN_PREFIX
27
28
29 def route_path(name, **kwargs):
30 return {
31 'home': '/',
32 }[name].format(**kwargs)
27 33
28 34
29 35 @pytest.mark.usefixtures('app', 'autologin_user')
@@ -32,86 +38,141 b' class TestIntegrationsView(object):'
32 38
33 39
34 40 class TestGlobalIntegrationsView(TestIntegrationsView):
35 def test_index_no_integrations(self, app):
41 def test_index_no_integrations(self):
36 42 url = ADMIN_PREFIX + '/integrations'
37 response = app.get(url)
43 response = self.app.get(url)
38 44
39 45 assert response.status_code == 200
40 46 assert 'exist yet' in response.body
41 47
42 def test_index_with_integrations(self, app, global_integration_stub):
48 def test_index_with_integrations(self, global_integration_stub):
43 49 url = ADMIN_PREFIX + '/integrations'
44 response = app.get(url)
50 response = self.app.get(url)
45 51
46 52 assert response.status_code == 200
47 53 assert 'exist yet' not in response.body
48 54 assert global_integration_stub.name in response.body
49 55
50 def test_new_integration_page(self, app):
56 @pytest.mark.parametrize(
57 'IntegrationType', integration_type_registry.values())
58 def test_new_integration_page(self, IntegrationType):
51 59 url = ADMIN_PREFIX + '/integrations/new'
52 60
53 response = app.get(url)
54
55 assert response.status_code == 200
61 response = self.app.get(url, status=200)
56 62
57 for integration_key in integration_type_registry:
58 nurl = (ADMIN_PREFIX + '/integrations/{integration}/new').format(
59 integration=integration_key)
60 assert nurl in response.body
63 url = (ADMIN_PREFIX + '/integrations/{integration}/new').format(
64 integration=IntegrationType.key)
65 assert url in response.body
61 66
62 67 @pytest.mark.parametrize(
63 68 'IntegrationType', integration_type_registry.values())
64 def test_get_create_integration_page(self, app, IntegrationType):
69 def test_get_create_integration_page(self, IntegrationType):
65 70 url = ADMIN_PREFIX + '/integrations/{integration_key}/new'.format(
66 71 integration_key=IntegrationType.key)
67 72
68 response = app.get(url)
73 response = self.app.get(url, status=200)
69 74
70 assert response.status_code == 200
71 75 assert IntegrationType.display_name in response.body
72 76
73 def test_post_integration_page(self, app, StubIntegrationType, csrf_token,
77 def test_post_integration_page(self, StubIntegrationType, csrf_token,
74 78 test_repo_group, backend_random):
75 79 url = ADMIN_PREFIX + '/integrations/{integration_key}/new'.format(
76 80 integration_key=StubIntegrationType.key)
77 81
78 _post_integration_test_helper(app, url, csrf_token, admin_view=True,
82 _post_integration_test_helper(self.app, url, csrf_token, admin_view=True,
83 repo=backend_random.repo, repo_group=test_repo_group)
84
85
86 class TestRepoIntegrationsView(TestIntegrationsView):
87 def test_index_no_integrations(self, backend_random):
88 url = '/{repo_name}/settings/integrations'.format(
89 repo_name=backend_random.repo.repo_name)
90 response = self.app.get(url)
91
92 assert response.status_code == 200
93 assert 'exist yet' in response.body
94
95 def test_index_with_integrations(self, repo_integration_stub):
96 url = '/{repo_name}/settings/integrations'.format(
97 repo_name=repo_integration_stub.repo.repo_name)
98 stub_name = repo_integration_stub.name
99
100 response = self.app.get(url)
101
102 assert response.status_code == 200
103 assert stub_name in response.body
104 assert 'exist yet' not in response.body
105
106 @pytest.mark.parametrize(
107 'IntegrationType', integration_type_registry.values())
108 def test_new_integration_page(self, backend_random, IntegrationType):
109 repo_name = backend_random.repo.repo_name
110 url = '/{repo_name}/settings/integrations/new'.format(
111 repo_name=repo_name)
112
113 response = self.app.get(url, status=200)
114
115 url = '/{repo_name}/settings/integrations/{integration}/new'.format(
116 repo_name=repo_name,
117 integration=IntegrationType.key)
118
119 assert url in response.body
120
121 @pytest.mark.parametrize(
122 'IntegrationType', integration_type_registry.values())
123 def test_get_create_integration_page(self, backend_random, IntegrationType):
124 repo_name = backend_random.repo.repo_name
125 url = '/{repo_name}/settings/integrations/{integration_key}/new'.format(
126 repo_name=repo_name, integration_key=IntegrationType.key)
127
128 response = self.app.get(url, status=200)
129
130 assert IntegrationType.display_name in response.body
131
132 def test_post_integration_page(self, backend_random, test_repo_group,
133 StubIntegrationType, csrf_token):
134 repo_name = backend_random.repo.repo_name
135 url = '/{repo_name}/settings/integrations/{integration_key}/new'.format(
136 repo_name=repo_name, integration_key=StubIntegrationType.key)
137
138 _post_integration_test_helper(
139 self.app, url, csrf_token, admin_view=False,
79 140 repo=backend_random.repo, repo_group=test_repo_group)
80 141
81 142
82 143 class TestRepoGroupIntegrationsView(TestIntegrationsView):
83 def test_index_no_integrations(self, app, test_repo_group):
144 def test_index_no_integrations(self, test_repo_group):
84 145 url = '/{repo_group_name}/settings/integrations'.format(
85 146 repo_group_name=test_repo_group.group_name)
86 response = app.get(url)
147 response = self.app.get(url)
87 148
88 149 assert response.status_code == 200
89 150 assert 'exist yet' in response.body
90 151
91 def test_index_with_integrations(self, app, test_repo_group,
92 repogroup_integration_stub):
152 def test_index_with_integrations(
153 self, test_repo_group, repogroup_integration_stub):
154
93 155 url = '/{repo_group_name}/settings/integrations'.format(
94 156 repo_group_name=test_repo_group.group_name)
95 157
96 158 stub_name = repogroup_integration_stub.name
97 response = app.get(url)
159 response = self.app.get(url)
98 160
99 161 assert response.status_code == 200
100 162 assert 'exist yet' not in response.body
101 163 assert stub_name in response.body
102 164
103 def test_new_integration_page(self, app, test_repo_group):
165 def test_new_integration_page(self, test_repo_group):
104 166 repo_group_name = test_repo_group.group_name
105 167 url = '/{repo_group_name}/settings/integrations/new'.format(
106 168 repo_group_name=test_repo_group.group_name)
107 169
108 response = app.get(url)
170 response = self.app.get(url)
109 171
110 172 assert response.status_code == 200
111 173
112 174 for integration_key in integration_type_registry:
113 nurl = ('/{repo_group_name}/settings/integrations'
114 '/{integration}/new').format(
175 nurl = ('/{repo_group_name}/settings/integrations/{integration}/new').format(
115 176 repo_group_name=repo_group_name,
116 177 integration=integration_key)
117 178
@@ -119,86 +180,29 b' class TestRepoGroupIntegrationsView(Test'
119 180
120 181 @pytest.mark.parametrize(
121 182 'IntegrationType', integration_type_registry.values())
122 def test_get_create_integration_page(self, app, test_repo_group,
123 IntegrationType):
183 def test_get_create_integration_page(
184 self, test_repo_group, IntegrationType):
185
124 186 repo_group_name = test_repo_group.group_name
125 187 url = ('/{repo_group_name}/settings/integrations/{integration_key}/new'
126 188 ).format(repo_group_name=repo_group_name,
127 189 integration_key=IntegrationType.key)
128 190
129 response = app.get(url)
191 response = self.app.get(url)
130 192
131 193 assert response.status_code == 200
132 194 assert IntegrationType.display_name in response.body
133 195
134 def test_post_integration_page(self, app, test_repo_group, backend_random,
196 def test_post_integration_page(self, test_repo_group, backend_random,
135 197 StubIntegrationType, csrf_token):
198
136 199 repo_group_name = test_repo_group.group_name
137 200 url = ('/{repo_group_name}/settings/integrations/{integration_key}/new'
138 201 ).format(repo_group_name=repo_group_name,
139 202 integration_key=StubIntegrationType.key)
140 203
141 _post_integration_test_helper(app, url, csrf_token, admin_view=False,
142 repo=backend_random.repo, repo_group=test_repo_group)
143
144
145 class TestRepoIntegrationsView(TestIntegrationsView):
146 def test_index_no_integrations(self, app, backend_random):
147 url = '/{repo_name}/settings/integrations'.format(
148 repo_name=backend_random.repo.repo_name)
149 response = app.get(url)
150
151 assert response.status_code == 200
152 assert 'exist yet' in response.body
153
154 def test_index_with_integrations(self, app, repo_integration_stub):
155 url = '/{repo_name}/settings/integrations'.format(
156 repo_name=repo_integration_stub.repo.repo_name)
157 stub_name = repo_integration_stub.name
158
159 response = app.get(url)
160
161 assert response.status_code == 200
162 assert stub_name in response.body
163 assert 'exist yet' not in response.body
164
165 def test_new_integration_page(self, app, backend_random):
166 repo_name = backend_random.repo.repo_name
167 url = '/{repo_name}/settings/integrations/new'.format(
168 repo_name=repo_name)
169
170 response = app.get(url)
171
172 assert response.status_code == 200
173
174 for integration_key in integration_type_registry:
175 nurl = ('/{repo_name}/settings/integrations'
176 '/{integration}/new').format(
177 repo_name=repo_name,
178 integration=integration_key)
179
180 assert nurl in response.body
181
182 @pytest.mark.parametrize(
183 'IntegrationType', integration_type_registry.values())
184 def test_get_create_integration_page(self, app, backend_random,
185 IntegrationType):
186 repo_name = backend_random.repo.repo_name
187 url = '/{repo_name}/settings/integrations/{integration_key}/new'.format(
188 repo_name=repo_name, integration_key=IntegrationType.key)
189
190 response = app.get(url)
191
192 assert response.status_code == 200
193 assert IntegrationType.display_name in response.body
194
195 def test_post_integration_page(self, app, backend_random, test_repo_group,
196 StubIntegrationType, csrf_token):
197 repo_name = backend_random.repo.repo_name
198 url = '/{repo_name}/settings/integrations/{integration_key}/new'.format(
199 repo_name=repo_name, integration_key=StubIntegrationType.key)
200
201 _post_integration_test_helper(app, url, csrf_token, admin_view=False,
204 _post_integration_test_helper(
205 self.app, url, csrf_token, admin_view=False,
202 206 repo=backend_random.repo, repo_group=test_repo_group)
203 207
204 208
@@ -208,7 +212,8 b' def _post_integration_test_helper(app, u'
208 212 Posts form data to create integration at the url given then deletes it and
209 213 checks if the redirect url is correct.
210 214 """
211
215 repo_name = repo.repo_name
216 repo_group_name = repo_group.group_name
212 217 app.post(url, params={}, status=403) # missing csrf check
213 218 response = app.post(url, params={'csrf_token': csrf_token})
214 219 assert response.status_code == 200
@@ -216,15 +221,15 b' def _post_integration_test_helper(app, u'
216 221
217 222 scopes_destinations = [
218 223 ('global',
219 ADMIN_PREFIX + '/integrations'),
224 ADMIN_PREFIX + '/integrations'),
220 225 ('root-repos',
221 226 ADMIN_PREFIX + '/integrations'),
222 ('repo:%s' % repo.repo_name,
223 '/%s/settings/integrations' % repo.repo_name),
224 ('repogroup:%s' % repo_group.group_name,
225 '/%s/settings/integrations' % repo_group.group_name),
226 ('repogroup-recursive:%s' % repo_group.group_name,
227 '/%s/settings/integrations' % repo_group.group_name),
227 ('repo:%s' % repo_name,
228 '/%s/settings/integrations' % repo_name),
229 ('repogroup:%s' % repo_group_name,
230 '/%s/settings/integrations' % repo_group_name),
231 ('repogroup-recursive:%s' % repo_group_name,
232 '/%s/settings/integrations' % repo_group_name),
228 233 ]
229 234
230 235 for scope, destination in scopes_destinations:
@@ -18,45 +18,40 b''
18 18 # RhodeCode Enterprise Edition, including its added features, Support services,
19 19 # and proprietary license terms, please see https://rhodecode.com/licenses/
20 20
21 import pylons
22 21 import deform
23 22 import logging
24 import colander
25 23 import peppercorn
26 24 import webhelpers.paginate
27 25
28 from pyramid.httpexceptions import HTTPFound, HTTPForbidden, HTTPBadRequest
29 from pyramid.renderers import render
30 from pyramid.response import Response
26 from pyramid.httpexceptions import HTTPFound, HTTPForbidden
31 27
28 from rhodecode.apps._base import BaseAppView
29 from rhodecode.integrations import integration_type_registry
32 30 from rhodecode.apps.admin.navigation import navigation_list
33 from rhodecode.lib import auth
34 from rhodecode.lib.auth import LoginRequired, HasPermissionAllDecorator
31 from rhodecode.lib.auth import (
32 LoginRequired, CSRFRequired, HasPermissionAnyDecorator,
33 HasRepoPermissionAnyDecorator, HasRepoGroupPermissionAnyDecorator)
35 34 from rhodecode.lib.utils2 import safe_int
36 35 from rhodecode.lib.helpers import Page
37 36 from rhodecode.model.db import Repository, RepoGroup, Session, Integration
38 37 from rhodecode.model.scm import ScmModel
39 38 from rhodecode.model.integration import IntegrationModel
40 from rhodecode.translation import _
41 from rhodecode.integrations import integration_type_registry
42 39 from rhodecode.model.validation_schema.schemas.integration_schema import (
43 40 make_integration_schema, IntegrationScopeType)
44 41
45 42 log = logging.getLogger(__name__)
46 43
47 44
48 class IntegrationSettingsViewBase(object):
49 """ Base Integration settings view used by both repo / global settings """
45 class IntegrationSettingsViewBase(BaseAppView):
46 """
47 Base Integration settings view used by both repo / global settings
48 """
50 49
51 50 def __init__(self, context, request):
52 self.context = context
53 self.request = request
54 self._load_general_context()
51 super(IntegrationSettingsViewBase, self).__init__(context, request)
52 self._load_view_context()
55 53
56 if not self.perm_check(request.user):
57 raise HTTPForbidden()
58
59 def _load_general_context(self):
54 def _load_view_context(self):
60 55 """
61 56 This avoids boilerplate for repo/global+list/edit+views/templates
62 57 by doing all possible contexts at the same time however it should
@@ -110,25 +105,12 b' class IntegrationSettingsViewBase(object'
110 105
111 106 return False
112 107
113 def _template_c_context(self):
114 # TODO: dan: this is a stopgap in order to inherit from current pylons
115 # based admin/repo settings templates - this should be removed entirely
116 # after port to pyramid
108 def _get_local_tmpl_context(self, include_app_defaults=False):
109 _ = self.request.translate
110 c = super(IntegrationSettingsViewBase, self)._get_local_tmpl_context(
111 include_app_defaults=include_app_defaults)
117 112
118 c = pylons.tmpl_context
119 113 c.active = 'integrations'
120 c.rhodecode_user = self.request.user
121 c.repo = self.repo
122 c.repo_group = self.repo_group
123 c.repo_name = self.repo and self.repo.repo_name or None
124 c.repo_group_name = self.repo_group and self.repo_group.group_name or None
125
126 if self.repo:
127 c.repo_info = self.repo
128 c.rhodecode_db_repo = self.repo
129 c.repository_pull_requests = ScmModel().get_pull_requests(self.repo)
130 else:
131 c.navlist = navigation_list(self.request)
132 114
133 115 return c
134 116
@@ -142,6 +124,7 b' class IntegrationSettingsViewBase(object'
142 124 no_scope=not self.admin_view)
143 125
144 126 def _form_defaults(self):
127 _ = self.request.translate
145 128 defaults = {}
146 129
147 130 if self.integration:
@@ -178,28 +161,79 b' class IntegrationSettingsViewBase(object'
178 161 return defaults
179 162
180 163 def _delete_integration(self, integration):
181 Session().delete(self.integration)
164 _ = self.request.translate
165 Session().delete(integration)
182 166 Session().commit()
183 167 self.request.session.flash(
184 168 _('Integration {integration_name} deleted successfully.').format(
185 integration_name=self.integration.name),
169 integration_name=integration.name),
186 170 queue='success')
187 171
188 172 if self.repo:
189 redirect_to = self.request.route_url(
173 redirect_to = self.request.route_path(
190 174 'repo_integrations_home', repo_name=self.repo.repo_name)
191 175 elif self.repo_group:
192 redirect_to = self.request.route_url(
176 redirect_to = self.request.route_path(
193 177 'repo_group_integrations_home',
194 178 repo_group_name=self.repo_group.group_name)
195 179 else:
196 redirect_to = self.request.route_url('global_integrations_home')
180 redirect_to = self.request.route_path('global_integrations_home')
197 181 raise HTTPFound(redirect_to)
198 182
199 def settings_get(self, defaults=None, form=None):
183 def _integration_list(self):
184 """ List integrations """
185
186 c = self.load_default_context()
187 if self.repo:
188 scope = self.repo
189 elif self.repo_group:
190 scope = self.repo_group
191 else:
192 scope = 'all'
193
194 integrations = []
195
196 for IntType, integration in IntegrationModel().get_integrations(
197 scope=scope, IntegrationType=self.IntegrationType):
198
199 # extra permissions check *just in case*
200 if not self._has_perms_for_integration(integration):
201 continue
202
203 integrations.append((IntType, integration))
204
205 sort_arg = self.request.GET.get('sort', 'name:asc')
206 if ':' in sort_arg:
207 sort_field, sort_dir = sort_arg.split(':')
208 else:
209 sort_field = sort_arg, 'asc'
210
211 assert sort_field in ('name', 'integration_type', 'enabled', 'scope')
212
213 integrations.sort(
214 key=lambda x: getattr(x[1], sort_field),
215 reverse=(sort_dir == 'desc'))
216
217 page_url = webhelpers.paginate.PageURL(
218 self.request.path, self.request.GET)
219 page = safe_int(self.request.GET.get('page', 1), 1)
220
221 integrations = Page(
222 integrations, page=page, items_per_page=10, url=page_url)
223
224 c.rev_sort_dir = sort_dir != 'desc' and 'desc' or 'asc'
225
226 c.current_IntegrationType = self.IntegrationType
227 c.integrations_list = integrations
228 c.available_integrations = integration_type_registry
229
230 return self._get_template_context(c)
231
232 def _settings_get(self, defaults=None, form=None):
200 233 """
201 234 View that displays the integration settings as a form.
202 235 """
236 c = self.load_default_context()
203 237
204 238 defaults = defaults or self._form_defaults()
205 239 schema = self._form_schema()
@@ -211,20 +245,18 b' class IntegrationSettingsViewBase(object'
211 245
212 246 form = form or deform.Form(schema, appstruct=defaults, buttons=buttons)
213 247
214 template_context = {
215 'form': form,
216 'current_IntegrationType': self.IntegrationType,
217 'integration': self.integration,
218 'c': self._template_c_context(),
219 }
248 c.form = form
249 c.current_IntegrationType = self.IntegrationType
250 c.integration = self.integration
220 251
221 return template_context
252 return self._get_template_context(c)
222 253
223 @auth.CSRFRequired()
224 def settings_post(self):
254 def _settings_post(self):
225 255 """
226 256 View that validates and stores the integration settings.
227 257 """
258 _ = self.request.translate
259
228 260 controls = self.request.POST.items()
229 261 pstruct = peppercorn.parse(controls)
230 262
@@ -264,7 +296,7 b' class IntegrationSettingsViewBase(object'
264 296 _('Errors exist when saving integration settings. '
265 297 'Please check the form inputs.'),
266 298 queue='error')
267 return self.settings_get(form=e)
299 return self._settings_get(form=e)
268 300
269 301 if not self.integration:
270 302 self.integration = Integration()
@@ -314,77 +346,110 b' class IntegrationSettingsViewBase(object'
314 346
315 347 return HTTPFound(redirect_to)
316 348
317 def index(self):
318 """ List integrations """
319 if self.repo:
320 scope = self.repo
321 elif self.repo_group:
322 scope = self.repo_group
323 else:
324 scope = 'all'
325
326 integrations = []
327
328 for IntType, integration in IntegrationModel().get_integrations(
329 scope=scope, IntegrationType=self.IntegrationType):
330
331 # extra permissions check *just in case*
332 if not self._has_perms_for_integration(integration):
333 continue
334
335 integrations.append((IntType, integration))
336
337 sort_arg = self.request.GET.get('sort', 'name:asc')
338 if ':' in sort_arg:
339 sort_field, sort_dir = sort_arg.split(':')
340 else:
341 sort_field = sort_arg, 'asc'
342
343 assert sort_field in ('name', 'integration_type', 'enabled', 'scope')
349 def _new_integration(self):
350 c = self.load_default_context()
351 c.available_integrations = integration_type_registry
352 return self._get_template_context(c)
344 353
345 integrations.sort(
346 key=lambda x: getattr(x[1], sort_field),
347 reverse=(sort_dir == 'desc'))
348
349 page_url = webhelpers.paginate.PageURL(
350 self.request.path, self.request.GET)
351 page = safe_int(self.request.GET.get('page', 1), 1)
352
353 integrations = Page(integrations, page=page, items_per_page=10,
354 url=page_url)
355
356 template_context = {
357 'sort_field': sort_field,
358 'rev_sort_dir': sort_dir != 'desc' and 'desc' or 'asc',
359 'current_IntegrationType': self.IntegrationType,
360 'integrations_list': integrations,
361 'available_integrations': integration_type_registry,
362 'c': self._template_c_context(),
363 'request': self.request,
364 }
365 return template_context
366
367 def new_integration(self):
368 template_context = {
369 'available_integrations': integration_type_registry,
370 'c': self._template_c_context(),
371 }
372 return template_context
354 def load_default_context(self):
355 raise NotImplementedError()
373 356
374 357
375 358 class GlobalIntegrationsView(IntegrationSettingsViewBase):
376 def perm_check(self, user):
377 return auth.HasPermissionAll('hg.admin').check_permissions(user=user)
359 def load_default_context(self):
360 c = self._get_local_tmpl_context()
361 c.repo = self.repo
362 c.repo_group = self.repo_group
363 c.navlist = navigation_list(self.request)
364 self._register_global_c(c)
365 return c
366
367 @LoginRequired()
368 @HasPermissionAnyDecorator('hg.admin')
369 def integration_list(self):
370 return self._integration_list()
371
372 @LoginRequired()
373 @HasPermissionAnyDecorator('hg.admin')
374 def settings_get(self):
375 return self._settings_get()
376
377 @LoginRequired()
378 @HasPermissionAnyDecorator('hg.admin')
379 @CSRFRequired()
380 def settings_post(self):
381 return self._settings_post()
382
383 @LoginRequired()
384 @HasPermissionAnyDecorator('hg.admin')
385 def new_integration(self):
386 return self._new_integration()
378 387
379 388
380 389 class RepoIntegrationsView(IntegrationSettingsViewBase):
381 def perm_check(self, user):
382 return auth.HasRepoPermissionAll('repository.admin')(
383 repo_name=self.repo.repo_name, user=user)
390 def load_default_context(self):
391 c = self._get_local_tmpl_context()
392
393 c.repo = self.repo
394 c.repo_group = self.repo_group
395
396 # TODO(marcink): remove repo_info and use c.rhodecode_db_repo instead
397 c.repo_info = self.db_repo = self.repo
398 c.rhodecode_db_repo = self.repo
399 c.repo_name = self.db_repo.repo_name
400 c.repository_pull_requests = ScmModel().get_pull_requests(self.repo)
401
402 self._register_global_c(c)
403 return c
404
405 @LoginRequired()
406 @HasRepoPermissionAnyDecorator('repository.admin')
407 def integration_list(self):
408 return self._integration_list()
409
410 @LoginRequired()
411 @HasRepoPermissionAnyDecorator('repository.admin')
412 def settings_get(self):
413 return self._settings_get()
414
415 @LoginRequired()
416 @HasRepoPermissionAnyDecorator('repository.admin')
417 @CSRFRequired()
418 def settings_post(self):
419 return self._settings_post()
420
421 @LoginRequired()
422 @HasRepoPermissionAnyDecorator('repository.admin')
423 def new_integration(self):
424 return self._new_integration()
384 425
385 426
386 427 class RepoGroupIntegrationsView(IntegrationSettingsViewBase):
387 def perm_check(self, user):
388 return auth.HasRepoGroupPermissionAll('group.admin')(
389 group_name=self.repo_group.group_name, user=user)
428 def load_default_context(self):
429 c = self._get_local_tmpl_context()
430 c.repo = self.repo
431 c.repo_group = self.repo_group
432 c.navlist = navigation_list(self.request)
433 self._register_global_c(c)
434 return c
435
436 @LoginRequired()
437 @HasRepoGroupPermissionAnyDecorator('group.admin')
438 def integration_list(self):
439 return self._integration_list()
390 440
441 @LoginRequired()
442 @HasRepoGroupPermissionAnyDecorator('group.admin')
443 def settings_get(self):
444 return self._settings_get()
445
446 @LoginRequired()
447 @HasRepoGroupPermissionAnyDecorator('group.admin')
448 @CSRFRequired()
449 def settings_post(self):
450 return self._settings_post()
451
452 @LoginRequired()
453 @HasRepoGroupPermissionAnyDecorator('group.admin')
454 def new_integration(self):
455 return self._new_integration()
@@ -23,13 +23,13 b' function registerRCRoutes() {'
23 23 pyroutes.register('global_integrations_create', '/_admin/integrations/%(integration)s/new', ['integration']);
24 24 pyroutes.register('global_integrations_edit', '/_admin/integrations/%(integration)s/%(integration_id)s', ['integration', 'integration_id']);
25 25 pyroutes.register('repo_group_integrations_home', '/%(repo_group_name)s/settings/integrations', ['repo_group_name']);
26 pyroutes.register('repo_group_integrations_new', '/%(repo_group_name)s/settings/integrations/new', ['repo_group_name']);
26 27 pyroutes.register('repo_group_integrations_list', '/%(repo_group_name)s/settings/integrations/%(integration)s', ['repo_group_name', 'integration']);
27 pyroutes.register('repo_group_integrations_new', '/%(repo_group_name)s/settings/integrations/new', ['repo_group_name']);
28 28 pyroutes.register('repo_group_integrations_create', '/%(repo_group_name)s/settings/integrations/%(integration)s/new', ['repo_group_name', 'integration']);
29 29 pyroutes.register('repo_group_integrations_edit', '/%(repo_group_name)s/settings/integrations/%(integration)s/%(integration_id)s', ['repo_group_name', 'integration', 'integration_id']);
30 30 pyroutes.register('repo_integrations_home', '/%(repo_name)s/settings/integrations', ['repo_name']);
31 pyroutes.register('repo_integrations_new', '/%(repo_name)s/settings/integrations/new', ['repo_name']);
31 32 pyroutes.register('repo_integrations_list', '/%(repo_name)s/settings/integrations/%(integration)s', ['repo_name', 'integration']);
32 pyroutes.register('repo_integrations_new', '/%(repo_name)s/settings/integrations/new', ['repo_name']);
33 33 pyroutes.register('repo_integrations_create', '/%(repo_name)s/settings/integrations/%(integration)s/new', ['repo_name', 'integration']);
34 34 pyroutes.register('repo_integrations_edit', '/%(repo_name)s/settings/integrations/%(integration)s/%(integration_id)s', ['repo_name', 'integration', 'integration_id']);
35 35 pyroutes.register('ops_ping', '/_admin/ops/ping', []);
@@ -7,10 +7,10 b''
7 7 &raquo;
8 8 ${h.link_to(_('Integrations'),request.route_url(route_name='repo_integrations_home', repo_name=c.repo.repo_name))}
9 9 &raquo;
10 ${h.link_to(current_IntegrationType.display_name,
10 ${h.link_to(c.current_IntegrationType.display_name,
11 11 request.route_url(route_name='repo_integrations_list',
12 12 repo_name=c.repo.repo_name,
13 integration=current_IntegrationType.key))}
13 integration=c.current_IntegrationType.key))}
14 14 %elif c.repo_group:
15 15 ${h.link_to(_('Admin'),h.route_path('admin_home'))}
16 16 &raquo;
@@ -20,10 +20,10 b''
20 20 &raquo;
21 21 ${h.link_to(_('Integrations'),request.route_url(route_name='repo_group_integrations_home', repo_group_name=c.repo_group.group_name))}
22 22 &raquo;
23 ${h.link_to(current_IntegrationType.display_name,
23 ${h.link_to(c.current_IntegrationType.display_name,
24 24 request.route_url(route_name='repo_group_integrations_list',
25 25 repo_group_name=c.repo_group.group_name,
26 integration=current_IntegrationType.key))}
26 integration=c.current_IntegrationType.key))}
27 27 %else:
28 28 ${h.link_to(_('Admin'),h.route_path('admin_home'))}
29 29 &raquo;
@@ -31,17 +31,17 b''
31 31 &raquo;
32 32 ${h.link_to(_('Integrations'),request.route_url(route_name='global_integrations_home'))}
33 33 &raquo;
34 ${h.link_to(current_IntegrationType.display_name,
34 ${h.link_to(c.current_IntegrationType.display_name,
35 35 request.route_url(route_name='global_integrations_list',
36 integration=current_IntegrationType.key))}
36 integration=c.current_IntegrationType.key))}
37 37 %endif
38 38
39 %if integration:
39 %if c.integration:
40 40 &raquo;
41 ${integration.name}
42 %elif current_IntegrationType:
41 ${c.integration.name}
42 %elif c.current_IntegrationType:
43 43 &raquo;
44 ${current_IntegrationType.display_name}
44 ${c.current_IntegrationType.display_name}
45 45 %endif
46 46 </%def>
47 47
@@ -54,16 +54,16 b''
54 54 <div class="panel panel-default">
55 55 <div class="panel-heading">
56 56 <h2 class="panel-title">
57 %if integration:
58 ${current_IntegrationType.display_name} - ${integration.name}
57 %if c.integration:
58 ${c.current_IntegrationType.display_name} - ${c.integration.name}
59 59 %else:
60 60 ${_('Create New %(integration_type)s Integration') % {
61 'integration_type': current_IntegrationType.display_name
61 'integration_type': c.current_IntegrationType.display_name
62 62 }}
63 63 %endif
64 64 </h2>
65 65 </div>
66 66 <div class="panel-body">
67 ${form.render() | n}
67 ${c.form.render() | n}
68 68 </div>
69 69 </div>
@@ -15,22 +15,22 b''
15 15 &raquo;
16 16 ${h.link_to(_('Settings'),h.url('admin_settings'))}
17 17 %endif
18 %if current_IntegrationType:
18 %if c.current_IntegrationType:
19 19 &raquo;
20 20 %if c.repo:
21 21 ${h.link_to(_('Integrations'),
22 request.route_url(route_name='repo_integrations_home',
23 repo_name=c.repo.repo_name))}
22 request.route_path(route_name='repo_integrations_home',
23 repo_name=c.repo.repo_name))}
24 24 %elif c.repo_group:
25 25 ${h.link_to(_('Integrations'),
26 request.route_url(route_name='repo_group_integrations_home',
27 repo_group_name=c.repo_group.group_name))}
26 request.route_path(route_name='repo_group_integrations_home',
27 repo_group_name=c.repo_group.group_name))}
28 28 %else:
29 29 ${h.link_to(_('Integrations'),
30 request.route_url(route_name='global_integrations_home'))}
30 request.route_path(route_name='global_integrations_home'))}
31 31 %endif
32 32 &raquo;
33 ${current_IntegrationType.display_name}
33 ${c.current_IntegrationType.display_name}
34 34 %else:
35 35 &raquo;
36 36 ${_('Integrations')}
@@ -61,9 +61,9 b''
61 61 home_url = request.route_path('global_integrations_home')
62 62 %>
63 63
64 <a href="${home_url}" class="btn ${not current_IntegrationType and 'btn-primary' or ''}">${_('All')}</a>
64 <a href="${home_url}" class="btn ${not c.current_IntegrationType and 'btn-primary' or ''}">${_('All')}</a>
65 65
66 %for integration_key, IntegrationType in available_integrations.items():
66 %for integration_key, IntegrationType in c.available_integrations.items():
67 67 <%
68 68 if c.repo:
69 69 list_url = request.route_path('repo_integrations_list',
@@ -78,12 +78,14 b''
78 78 integration=integration_key)
79 79 %>
80 80 <a href="${list_url}"
81 class="btn ${current_IntegrationType and integration_key == current_IntegrationType.key and 'btn-primary' or ''}">
81 class="btn ${c.current_IntegrationType and integration_key == c.current_IntegrationType.key and 'btn-primary' or ''}">
82 82 ${IntegrationType.display_name}
83 83 </a>
84 84 %endfor
85 85
86 86 <%
87 integration_type = c.current_IntegrationType and c.current_IntegrationType.display_name or ''
88
87 89 if c.repo:
88 90 create_url = h.route_path('repo_integrations_new', repo_name=c.repo.repo_name)
89 91 elif c.repo_group:
@@ -98,19 +100,19 b''
98 100 <table class="rctable integrations">
99 101 <thead>
100 102 <tr>
101 <th><a href="?sort=enabled:${rev_sort_dir}">${_('Enabled')}</a></th>
102 <th><a href="?sort=name:${rev_sort_dir}">${_('Name')}</a></th>
103 <th colspan="2"><a href="?sort=integration_type:${rev_sort_dir}">${_('Type')}</a></th>
104 <th><a href="?sort=scope:${rev_sort_dir}">${_('Scope')}</a></th>
103 <th><a href="?sort=enabled:${c.rev_sort_dir}">${_('Enabled')}</a></th>
104 <th><a href="?sort=name:${c.rev_sort_dir}">${_('Name')}</a></th>
105 <th colspan="2"><a href="?sort=integration_type:${c.rev_sort_dir}">${_('Type')}</a></th>
106 <th><a href="?sort=scope:${c.rev_sort_dir}">${_('Scope')}</a></th>
105 107 <th>${_('Actions')}</th>
106 108 <th></th>
107 109 </tr>
108 110 </thead>
109 111 <tbody>
110 %if not integrations_list:
112 %if not c.integrations_list:
111 113 <tr>
112 114 <td colspan="7">
113 <% integration_type = current_IntegrationType and current_IntegrationType.display_name or '' %>
115
114 116 %if c.repo:
115 117 ${_('No {type} integrations for repo {repo} exist yet.').format(type=integration_type, repo=c.repo.repo_name)}
116 118 %elif c.repo_group:
@@ -119,14 +121,14 b''
119 121 ${_('No {type} integrations exist yet.').format(type=integration_type)}
120 122 %endif
121 123
122 %if current_IntegrationType:
124 %if c.current_IntegrationType:
123 125 <%
124 126 if c.repo:
125 create_url = h.route_path('repo_integrations_create', repo_name=c.repo.repo_name, integration=current_IntegrationType.key)
127 create_url = h.route_path('repo_integrations_create', repo_name=c.repo.repo_name, integration=c.current_IntegrationType.key)
126 128 elif c.repo_group:
127 create_url = h.route_path('repo_group_integrations_create', repo_group_name=c.repo_group.group_name, integration=current_IntegrationType.key)
129 create_url = h.route_path('repo_group_integrations_create', repo_group_name=c.repo_group.group_name, integration=c.current_IntegrationType.key)
128 130 else:
129 create_url = h.route_path('global_integrations_create', integration=current_IntegrationType.key)
131 create_url = h.route_path('global_integrations_create', integration=c.current_IntegrationType.key)
130 132 %>
131 133 %endif
132 134
@@ -134,7 +136,7 b''
134 136 </td>
135 137 </tr>
136 138 %endif
137 %for IntegrationType, integration in integrations_list:
139 %for IntegrationType, integration in c.integrations_list:
138 140 <tr id="integration_${integration.integration_id}">
139 141 <td class="td-enabled">
140 142 %if integration.enabled:
@@ -147,9 +149,9 b''
147 149 ${integration.name}
148 150 </td>
149 151 <td class="td-icon">
150 %if integration.integration_type in available_integrations:
152 %if integration.integration_type in c.available_integrations:
151 153 <div class="integration-icon">
152 ${available_integrations[integration.integration_type].icon|n}
154 ${c.available_integrations[integration.integration_type].icon|n}
153 155 </div>
154 156 %else:
155 157 ?
@@ -220,7 +222,7 b''
220 222 </table>
221 223 <div class="integrations-paginator">
222 224 <div class="pagination-wh pagination-left">
223 ${integrations_list.pager('$link_previous ~2~ $link_next')}
225 ${c.integrations_list.pager('$link_previous ~2~ $link_next')}
224 226 </div>
225 227 </div>
226 228 </div>
@@ -36,7 +36,7 b''
36 36 %endif
37 37 </%def>
38 38
39 %for integration, IntegrationType in available_integrations.items():
39 %for integration, IntegrationType in c.available_integrations.items():
40 40 <%
41 41 if c.repo:
42 42 create_url = request.route_path('repo_integrations_create',
@@ -25,21 +25,21 b' from rhodecode import events'
25 25 from rhodecode.tests.fixture import Fixture
26 26 from rhodecode.model.db import Session, Integration
27 27 from rhodecode.model.integration import IntegrationModel
28 from rhodecode.integrations.types.base import IntegrationTypeBase
29 28
30 29
31 30 class TestDeleteScopesDeletesIntegrations(object):
32 def test_delete_repo_with_integration_deletes_integration(self,
33 repo_integration_stub):
31 def test_delete_repo_with_integration_deletes_integration(
32 self, repo_integration_stub):
33
34 34 Session().delete(repo_integration_stub.repo)
35 35 Session().commit()
36 36 Session().expire_all()
37 37 integration = Integration.get(repo_integration_stub.integration_id)
38 38 assert integration is None
39 39
40 def test_delete_repo_group_with_integration_deletes_integration(
41 self, repogroup_integration_stub):
40 42
41 def test_delete_repo_group_with_integration_deletes_integration(self,
42 repogroup_integration_stub):
43 43 Session().delete(repogroup_integration_stub.repo_group)
44 44 Session().commit()
45 45 Session().expire_all()
@@ -146,7 +146,6 b' def test_enabled_integration_repo_scopes'
146 146 integrations['root_repo'],
147 147 ]
148 148
149
150 149 triggered_integrations = IntegrationModel().get_for_event(
151 150 events.RepoEvent(repos['other_repo']))
152 151
@@ -157,7 +156,6 b' def test_enabled_integration_repo_scopes'
157 156 integrations['other_group_recursive'],
158 157 ]
159 158
160
161 159 triggered_integrations = IntegrationModel().get_for_event(
162 160 events.RepoEvent(repos['parent_repo']))
163 161
@@ -193,26 +191,22 b' def test_disabled_integration_repo_scope'
193 191
194 192 assert triggered_integrations == []
195 193
196
197 194 triggered_integrations = IntegrationModel().get_for_event(
198 195 events.RepoEvent(repos['parent_repo']))
199 196
200 197 assert triggered_integrations == []
201 198
202
203 199 triggered_integrations = IntegrationModel().get_for_event(
204 200 events.RepoEvent(repos['child_repo']))
205 201
206 202 assert triggered_integrations == []
207 203
208
209 204 triggered_integrations = IntegrationModel().get_for_event(
210 205 events.RepoEvent(repos['other_repo']))
211 206
212 207 assert triggered_integrations == []
213 208
214 209
215
216 210 def test_enabled_non_repo_integrations(integration_repos):
217 211 integrations = integration_repos['integrations']
218 212
@@ -336,7 +336,7 b' def test_repo_group(request):'
336 336 usage automatically
337 337 """
338 338 fixture = Fixture()
339 repogroupid = 'test_repo_group_%s' % int(time.time())
339 repogroupid = 'test_repo_group_%s' % str(time.time()).replace('.', '')
340 340 repo_group = fixture.create_repo_group(repogroupid)
341 341
342 342 def _cleanup():
@@ -353,7 +353,7 b' def test_user_group(request):'
353 353 usage automatically
354 354 """
355 355 fixture = Fixture()
356 usergroupid = 'test_user_group_%s' % int(time.time())
356 usergroupid = 'test_user_group_%s' % str(time.time()).replace('.', '')
357 357 user_group = fixture.create_user_group(usergroupid)
358 358
359 359 def _cleanup():
General Comments 0
You need to be logged in to leave comments. Login now