##// END OF EJS Templates
integrations: expose EE integrations as dummy objects to show...
marcink -
r2138:cfe7604e default
parent child Browse files
Show More
@@ -21,8 +21,7 b''
21 21 import logging
22 22
23 23 from rhodecode.integrations.registry import IntegrationTypeRegistry
24 from rhodecode.integrations.types import webhook, slack, hipchat, email
25
24 from rhodecode.integrations.types import webhook, slack, hipchat, email, base
26 25 log = logging.getLogger(__name__)
27 26
28 27
@@ -41,6 +40,13 b' integration_type_registry.register_integ'
41 40 email.EmailIntegrationType)
42 41
43 42
43 # dummy EE integration to show users what we have in EE edition
44 integration_type_registry.register_integration_type(
45 base.EEIntegration('Jira Issues integration', 'jira'))
46 integration_type_registry.register_integration_type(
47 base.EEIntegration('Redmine Tracker integration', 'redmine'))
48
49
44 50 def integrations_event_handler(event):
45 51 """
46 52 Takes an event and passes it to all enabled integrations
@@ -18,11 +18,12 b''
18 18 # and proprietary license terms, please see https://rhodecode.com/licenses/
19 19
20 20 import logging
21 import collections
21 22
22 23 log = logging.getLogger(__name__)
23 24
24 25
25 class IntegrationTypeRegistry(dict):
26 class IntegrationTypeRegistry(collections.OrderedDict):
26 27 """
27 28 Registry Class to hold IntegrationTypes
28 29 """
@@ -43,15 +43,15 b' class TestGlobalIntegrationsView(TestInt'
43 43 response = self.app.get(url)
44 44
45 45 assert response.status_code == 200
46 assert 'exist yet' in response.body
46 response.mustcontain('exist yet')
47 47
48 48 def test_index_with_integrations(self, global_integration_stub):
49 49 url = ADMIN_PREFIX + '/integrations'
50 50 response = self.app.get(url)
51 51
52 52 assert response.status_code == 200
53 assert 'exist yet' not in response.body
54 assert global_integration_stub.name in response.body
53 response.mustcontain(no=['exist yet'])
54 response.mustcontain(global_integration_stub.name)
55 55
56 56 @pytest.mark.parametrize(
57 57 'IntegrationType', integration_type_registry.values())
@@ -59,27 +59,29 b' class TestGlobalIntegrationsView(TestInt'
59 59 url = ADMIN_PREFIX + '/integrations/new'
60 60
61 61 response = self.app.get(url, status=200)
62
63 url = (ADMIN_PREFIX + '/integrations/{integration}/new').format(
64 integration=IntegrationType.key)
65 assert url in response.body
62 if not IntegrationType.is_dummy:
63 url = (ADMIN_PREFIX + '/integrations/{integration}/new').format(
64 integration=IntegrationType.key)
65 response.mustcontain(url)
66 66
67 67 @pytest.mark.parametrize(
68 68 'IntegrationType', integration_type_registry.values())
69 69 def test_get_create_integration_page(self, IntegrationType):
70 70 url = ADMIN_PREFIX + '/integrations/{integration_key}/new'.format(
71 71 integration_key=IntegrationType.key)
72
73 response = self.app.get(url, status=200)
74
75 assert IntegrationType.display_name in response.body
72 if IntegrationType.is_dummy:
73 self.app.get(url, status=404)
74 else:
75 response = self.app.get(url, status=200)
76 response.mustcontain(IntegrationType.display_name)
76 77
77 78 def test_post_integration_page(self, StubIntegrationType, csrf_token,
78 79 test_repo_group, backend_random):
79 80 url = ADMIN_PREFIX + '/integrations/{integration_key}/new'.format(
80 81 integration_key=StubIntegrationType.key)
81 82
82 _post_integration_test_helper(self.app, url, csrf_token, admin_view=True,
83 _post_integration_test_helper(
84 self.app, url, csrf_token, admin_view=True,
83 85 repo=backend_random.repo, repo_group=test_repo_group)
84 86
85 87
@@ -90,7 +92,7 b' class TestRepoIntegrationsView(TestInteg'
90 92 response = self.app.get(url)
91 93
92 94 assert response.status_code == 200
93 assert 'exist yet' in response.body
95 response.mustcontain('exist yet')
94 96
95 97 def test_index_with_integrations(self, repo_integration_stub):
96 98 url = '/{repo_name}/settings/integrations'.format(
@@ -100,8 +102,8 b' class TestRepoIntegrationsView(TestInteg'
100 102 response = self.app.get(url)
101 103
102 104 assert response.status_code == 200
103 assert stub_name in response.body
104 assert 'exist yet' not in response.body
105 response.mustcontain(stub_name)
106 response.mustcontain(no=['exist yet'])
105 107
106 108 @pytest.mark.parametrize(
107 109 'IntegrationType', integration_type_registry.values())
@@ -115,8 +117,8 b' class TestRepoIntegrationsView(TestInteg'
115 117 url = '/{repo_name}/settings/integrations/{integration}/new'.format(
116 118 repo_name=repo_name,
117 119 integration=IntegrationType.key)
118
119 assert url in response.body
120 if not IntegrationType.is_dummy:
121 response.mustcontain(url)
120 122
121 123 @pytest.mark.parametrize(
122 124 'IntegrationType', integration_type_registry.values())
@@ -124,10 +126,11 b' class TestRepoIntegrationsView(TestInteg'
124 126 repo_name = backend_random.repo.repo_name
125 127 url = '/{repo_name}/settings/integrations/{integration_key}/new'.format(
126 128 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
129 if IntegrationType.is_dummy:
130 self.app.get(url, status=404)
131 else:
132 response = self.app.get(url, status=200)
133 response.mustcontain(IntegrationType.display_name)
131 134
132 135 def test_post_integration_page(self, backend_random, test_repo_group,
133 136 StubIntegrationType, csrf_token):
@@ -147,7 +150,7 b' class TestRepoGroupIntegrationsView(Test'
147 150 response = self.app.get(url)
148 151
149 152 assert response.status_code == 200
150 assert 'exist yet' in response.body
153 response.mustcontain('exist yet')
151 154
152 155 def test_index_with_integrations(
153 156 self, test_repo_group, repogroup_integration_stub):
@@ -159,8 +162,8 b' class TestRepoGroupIntegrationsView(Test'
159 162 response = self.app.get(url)
160 163
161 164 assert response.status_code == 200
162 assert 'exist yet' not in response.body
163 assert stub_name in response.body
165 response.mustcontain(no=['exist yet'])
166 response.mustcontain(stub_name)
164 167
165 168 def test_new_integration_page(self, test_repo_group):
166 169 repo_group_name = test_repo_group.group_name
@@ -171,12 +174,13 b' class TestRepoGroupIntegrationsView(Test'
171 174
172 175 assert response.status_code == 200
173 176
174 for integration_key in integration_type_registry:
175 nurl = ('/{repo_group_name}/settings/integrations/{integration}/new').format(
177 for integration_key, integration_obj in integration_type_registry.items():
178 if not integration_obj.is_dummy:
179 nurl = (
180 '/{repo_group_name}/settings/integrations/{integration}/new').format(
176 181 repo_group_name=repo_group_name,
177 182 integration=integration_key)
178
179 assert nurl in response.body
183 response.mustcontain(nurl)
180 184
181 185 @pytest.mark.parametrize(
182 186 'IntegrationType', integration_type_registry.values())
@@ -188,10 +192,11 b' class TestRepoGroupIntegrationsView(Test'
188 192 ).format(repo_group_name=repo_group_name,
189 193 integration_key=IntegrationType.key)
190 194
191 response = self.app.get(url)
192
193 assert response.status_code == 200
194 assert IntegrationType.display_name in response.body
195 if not IntegrationType.is_dummy:
196 response = self.app.get(url, status=200)
197 response.mustcontain(IntegrationType.display_name)
198 else:
199 self.app.get(url, status=404)
195 200
196 201 def test_post_integration_page(self, test_repo_group, backend_random,
197 202 StubIntegrationType, csrf_token):
@@ -217,7 +222,7 b' def _post_integration_test_helper(app, u'
217 222 app.post(url, params={}, status=403) # missing csrf check
218 223 response = app.post(url, params={'csrf_token': csrf_token})
219 224 assert response.status_code == 200
220 assert 'Errors exist' in response.body
225 response.mustcontain('Errors exist')
221 226
222 227 scopes_destinations = [
223 228 ('global',
@@ -24,7 +24,7 b' from rhodecode.translation import _'
24 24
25 25 class IntegrationTypeBase(object):
26 26 """ Base class for IntegrationType plugins """
27
27 is_dummy = False
28 28 description = ''
29 29 icon = '''
30 30 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
@@ -99,3 +99,12 b' class IntegrationTypeBase(object):'
99 99 A colander schema of settings for the integration type
100 100 """
101 101 return colander.Schema()
102
103
104 class EEIntegration(IntegrationTypeBase):
105 description = 'Integration available in RhodeCode EE edition.'
106 is_dummy = True
107
108 def __init__(self, name, key, settings=None):
109 self.display_name = name
110 self.key = key
@@ -23,7 +23,7 b' import logging'
23 23 import peppercorn
24 24 import webhelpers.paginate
25 25
26 from pyramid.httpexceptions import HTTPFound, HTTPForbidden
26 from pyramid.httpexceptions import HTTPFound, HTTPForbidden, HTTPNotFound
27 27
28 28 from rhodecode.apps._base import BaseAppView
29 29 from rhodecode.integrations import integration_type_registry
@@ -76,7 +76,12 b' class IntegrationSettingsViewBase(BaseAp'
76 76
77 77 if 'integration' in request.matchdict: # integration type context
78 78 integration_type = request.matchdict['integration']
79 if integration_type not in integration_type_registry:
80 raise HTTPNotFound()
81
79 82 self.IntegrationType = integration_type_registry[integration_type]
83 if self.IntegrationType.is_dummy:
84 raise HTTPNotFound()
80 85
81 86 if 'integration_id' in request.matchdict: # single integration context
82 87 integration_id = request.matchdict['integration_id']
@@ -1195,6 +1195,9 b' table.integrations {'
1195 1195 min-width: 140px;
1196 1196 }
1197 1197 }
1198 a.integration-box.dummy-integration {
1199 color: @grey4
1200 }
1198 1201 }
1199 1202
1200 1203 //Permissions Settings
@@ -64,23 +64,25 b''
64 64 <a href="${home_url}" class="btn ${not c.current_IntegrationType and 'btn-primary' or ''}">${_('All')}</a>
65 65
66 66 %for integration_key, IntegrationType in c.available_integrations.items():
67 <%
68 if c.repo:
69 list_url = request.route_path('repo_integrations_list',
70 repo_name=c.repo.repo_name,
71 integration=integration_key)
72 elif c.repo_group:
73 list_url = request.route_path('repo_group_integrations_list',
74 repo_group_name=c.repo_group.group_name,
75 integration=integration_key)
76 else:
77 list_url = request.route_path('global_integrations_list',
78 integration=integration_key)
79 %>
80 <a href="${list_url}"
81 class="btn ${c.current_IntegrationType and integration_key == c.current_IntegrationType.key and 'btn-primary' or ''}">
82 ${IntegrationType.display_name}
83 </a>
67 % if not IntegrationType.is_dummy:
68 <%
69 if c.repo:
70 list_url = request.route_path('repo_integrations_list',
71 repo_name=c.repo.repo_name,
72 integration=integration_key)
73 elif c.repo_group:
74 list_url = request.route_path('repo_group_integrations_list',
75 repo_group_name=c.repo_group.group_name,
76 integration=integration_key)
77 else:
78 list_url = request.route_path('global_integrations_list',
79 integration=integration_key)
80 %>
81 <a href="${list_url}"
82 class="btn ${c.current_IntegrationType and integration_key == c.current_IntegrationType.key and 'btn-primary' or ''}">
83 ${IntegrationType.display_name}
84 </a>
85 % endif
84 86 %endfor
85 87
86 88 <%
@@ -36,7 +36,7 b''
36 36 %endif
37 37 </%def>
38 38
39 %for integration, IntegrationType in c.available_integrations.items():
39 %for integration, IntegrationObject in c.available_integrations.items():
40 40 <%
41 41 if c.repo:
42 42 create_url = request.route_path('repo_integrations_create',
@@ -49,16 +49,18 b''
49 49 else:
50 50 create_url = request.route_path('global_integrations_create',
51 51 integration=integration)
52 if IntegrationObject.is_dummy:
53 create_url = request.current_route_path()
52 54 %>
53 <a href="${create_url}" class="integration-box">
55 <a href="${create_url}" class="integration-box ${'dummy-integration' if IntegrationObject.is_dummy else ''}">
54 56 <%widgets:panel>
55 57 <h2>
56 58 <div class="integration-icon">
57 ${IntegrationType.icon|n}
59 ${IntegrationObject.icon|n}
58 60 </div>
59 ${IntegrationType.display_name}
61 ${IntegrationObject.display_name}
60 62 </h2>
61 ${IntegrationType.description or _('No description available')}
63 ${IntegrationObject.description or _('No description available')}
62 64 </%widgets:panel>
63 65 </a>
64 66 %endfor
General Comments 0
You need to be logged in to leave comments. Login now