integrations: expose EE integrations as dummy objects to show
what EE edition have.
This commit is contained in:
parent
d35f866e04
commit
4718f3cec9
8 changed files with 93 additions and 60 deletions
|
|
@ -21,8 +21,7 @@
|
|||
import logging
|
||||
|
||||
from rhodecode.integrations.registry import IntegrationTypeRegistry
|
||||
from rhodecode.integrations.types import webhook, slack, hipchat, email
|
||||
|
||||
from rhodecode.integrations.types import webhook, slack, hipchat, email, base
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
||||
|
|
@ -41,6 +40,13 @@ integration_type_registry.register_integration_type(
|
|||
email.EmailIntegrationType)
|
||||
|
||||
|
||||
# dummy EE integration to show users what we have in EE edition
|
||||
integration_type_registry.register_integration_type(
|
||||
base.EEIntegration('Jira Issues integration', 'jira'))
|
||||
integration_type_registry.register_integration_type(
|
||||
base.EEIntegration('Redmine Tracker integration', 'redmine'))
|
||||
|
||||
|
||||
def integrations_event_handler(event):
|
||||
"""
|
||||
Takes an event and passes it to all enabled integrations
|
||||
|
|
|
|||
|
|
@ -18,11 +18,12 @@
|
|||
# and proprietary license terms, please see https://rhodecode.com/licenses/
|
||||
|
||||
import logging
|
||||
import collections
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class IntegrationTypeRegistry(dict):
|
||||
class IntegrationTypeRegistry(collections.OrderedDict):
|
||||
"""
|
||||
Registry Class to hold IntegrationTypes
|
||||
"""
|
||||
|
|
|
|||
|
|
@ -43,15 +43,15 @@ class TestGlobalIntegrationsView(TestIntegrationsView):
|
|||
response = self.app.get(url)
|
||||
|
||||
assert response.status_code == 200
|
||||
assert 'exist yet' in response.body
|
||||
response.mustcontain('exist yet')
|
||||
|
||||
def test_index_with_integrations(self, global_integration_stub):
|
||||
url = ADMIN_PREFIX + '/integrations'
|
||||
response = self.app.get(url)
|
||||
|
||||
assert response.status_code == 200
|
||||
assert 'exist yet' not in response.body
|
||||
assert global_integration_stub.name in response.body
|
||||
response.mustcontain(no=['exist yet'])
|
||||
response.mustcontain(global_integration_stub.name)
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
'IntegrationType', integration_type_registry.values())
|
||||
|
|
@ -59,27 +59,29 @@ class TestGlobalIntegrationsView(TestIntegrationsView):
|
|||
url = ADMIN_PREFIX + '/integrations/new'
|
||||
|
||||
response = self.app.get(url, status=200)
|
||||
|
||||
url = (ADMIN_PREFIX + '/integrations/{integration}/new').format(
|
||||
integration=IntegrationType.key)
|
||||
assert url in response.body
|
||||
if not IntegrationType.is_dummy:
|
||||
url = (ADMIN_PREFIX + '/integrations/{integration}/new').format(
|
||||
integration=IntegrationType.key)
|
||||
response.mustcontain(url)
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
'IntegrationType', integration_type_registry.values())
|
||||
def test_get_create_integration_page(self, IntegrationType):
|
||||
url = ADMIN_PREFIX + '/integrations/{integration_key}/new'.format(
|
||||
integration_key=IntegrationType.key)
|
||||
|
||||
response = self.app.get(url, status=200)
|
||||
|
||||
assert IntegrationType.display_name in response.body
|
||||
if IntegrationType.is_dummy:
|
||||
self.app.get(url, status=404)
|
||||
else:
|
||||
response = self.app.get(url, status=200)
|
||||
response.mustcontain(IntegrationType.display_name)
|
||||
|
||||
def test_post_integration_page(self, StubIntegrationType, csrf_token,
|
||||
test_repo_group, backend_random):
|
||||
url = ADMIN_PREFIX + '/integrations/{integration_key}/new'.format(
|
||||
integration_key=StubIntegrationType.key)
|
||||
|
||||
_post_integration_test_helper(self.app, url, csrf_token, admin_view=True,
|
||||
_post_integration_test_helper(
|
||||
self.app, url, csrf_token, admin_view=True,
|
||||
repo=backend_random.repo, repo_group=test_repo_group)
|
||||
|
||||
|
||||
|
|
@ -90,7 +92,7 @@ class TestRepoIntegrationsView(TestIntegrationsView):
|
|||
response = self.app.get(url)
|
||||
|
||||
assert response.status_code == 200
|
||||
assert 'exist yet' in response.body
|
||||
response.mustcontain('exist yet')
|
||||
|
||||
def test_index_with_integrations(self, repo_integration_stub):
|
||||
url = '/{repo_name}/settings/integrations'.format(
|
||||
|
|
@ -100,8 +102,8 @@ class TestRepoIntegrationsView(TestIntegrationsView):
|
|||
response = self.app.get(url)
|
||||
|
||||
assert response.status_code == 200
|
||||
assert stub_name in response.body
|
||||
assert 'exist yet' not in response.body
|
||||
response.mustcontain(stub_name)
|
||||
response.mustcontain(no=['exist yet'])
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
'IntegrationType', integration_type_registry.values())
|
||||
|
|
@ -115,8 +117,8 @@ class TestRepoIntegrationsView(TestIntegrationsView):
|
|||
url = '/{repo_name}/settings/integrations/{integration}/new'.format(
|
||||
repo_name=repo_name,
|
||||
integration=IntegrationType.key)
|
||||
|
||||
assert url in response.body
|
||||
if not IntegrationType.is_dummy:
|
||||
response.mustcontain(url)
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
'IntegrationType', integration_type_registry.values())
|
||||
|
|
@ -124,10 +126,11 @@ class TestRepoIntegrationsView(TestIntegrationsView):
|
|||
repo_name = backend_random.repo.repo_name
|
||||
url = '/{repo_name}/settings/integrations/{integration_key}/new'.format(
|
||||
repo_name=repo_name, integration_key=IntegrationType.key)
|
||||
|
||||
response = self.app.get(url, status=200)
|
||||
|
||||
assert IntegrationType.display_name in response.body
|
||||
if IntegrationType.is_dummy:
|
||||
self.app.get(url, status=404)
|
||||
else:
|
||||
response = self.app.get(url, status=200)
|
||||
response.mustcontain(IntegrationType.display_name)
|
||||
|
||||
def test_post_integration_page(self, backend_random, test_repo_group,
|
||||
StubIntegrationType, csrf_token):
|
||||
|
|
@ -147,7 +150,7 @@ class TestRepoGroupIntegrationsView(TestIntegrationsView):
|
|||
response = self.app.get(url)
|
||||
|
||||
assert response.status_code == 200
|
||||
assert 'exist yet' in response.body
|
||||
response.mustcontain('exist yet')
|
||||
|
||||
def test_index_with_integrations(
|
||||
self, test_repo_group, repogroup_integration_stub):
|
||||
|
|
@ -159,8 +162,8 @@ class TestRepoGroupIntegrationsView(TestIntegrationsView):
|
|||
response = self.app.get(url)
|
||||
|
||||
assert response.status_code == 200
|
||||
assert 'exist yet' not in response.body
|
||||
assert stub_name in response.body
|
||||
response.mustcontain(no=['exist yet'])
|
||||
response.mustcontain(stub_name)
|
||||
|
||||
def test_new_integration_page(self, test_repo_group):
|
||||
repo_group_name = test_repo_group.group_name
|
||||
|
|
@ -171,12 +174,13 @@ class TestRepoGroupIntegrationsView(TestIntegrationsView):
|
|||
|
||||
assert response.status_code == 200
|
||||
|
||||
for integration_key in integration_type_registry:
|
||||
nurl = ('/{repo_group_name}/settings/integrations/{integration}/new').format(
|
||||
for integration_key, integration_obj in integration_type_registry.items():
|
||||
if not integration_obj.is_dummy:
|
||||
nurl = (
|
||||
'/{repo_group_name}/settings/integrations/{integration}/new').format(
|
||||
repo_group_name=repo_group_name,
|
||||
integration=integration_key)
|
||||
|
||||
assert nurl in response.body
|
||||
response.mustcontain(nurl)
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
'IntegrationType', integration_type_registry.values())
|
||||
|
|
@ -188,10 +192,11 @@ class TestRepoGroupIntegrationsView(TestIntegrationsView):
|
|||
).format(repo_group_name=repo_group_name,
|
||||
integration_key=IntegrationType.key)
|
||||
|
||||
response = self.app.get(url)
|
||||
|
||||
assert response.status_code == 200
|
||||
assert IntegrationType.display_name in response.body
|
||||
if not IntegrationType.is_dummy:
|
||||
response = self.app.get(url, status=200)
|
||||
response.mustcontain(IntegrationType.display_name)
|
||||
else:
|
||||
self.app.get(url, status=404)
|
||||
|
||||
def test_post_integration_page(self, test_repo_group, backend_random,
|
||||
StubIntegrationType, csrf_token):
|
||||
|
|
@ -217,7 +222,7 @@ def _post_integration_test_helper(app, url, csrf_token, repo, repo_group,
|
|||
app.post(url, params={}, status=403) # missing csrf check
|
||||
response = app.post(url, params={'csrf_token': csrf_token})
|
||||
assert response.status_code == 200
|
||||
assert 'Errors exist' in response.body
|
||||
response.mustcontain('Errors exist')
|
||||
|
||||
scopes_destinations = [
|
||||
('global',
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ from rhodecode.translation import _
|
|||
|
||||
class IntegrationTypeBase(object):
|
||||
""" Base class for IntegrationType plugins """
|
||||
|
||||
is_dummy = False
|
||||
description = ''
|
||||
icon = '''
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
|
|
@ -99,3 +99,12 @@ class IntegrationTypeBase(object):
|
|||
A colander schema of settings for the integration type
|
||||
"""
|
||||
return colander.Schema()
|
||||
|
||||
|
||||
class EEIntegration(IntegrationTypeBase):
|
||||
description = 'Integration available in RhodeCode EE edition.'
|
||||
is_dummy = True
|
||||
|
||||
def __init__(self, name, key, settings=None):
|
||||
self.display_name = name
|
||||
self.key = key
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ import logging
|
|||
import peppercorn
|
||||
import webhelpers.paginate
|
||||
|
||||
from pyramid.httpexceptions import HTTPFound, HTTPForbidden
|
||||
from pyramid.httpexceptions import HTTPFound, HTTPForbidden, HTTPNotFound
|
||||
|
||||
from rhodecode.apps._base import BaseAppView
|
||||
from rhodecode.integrations import integration_type_registry
|
||||
|
|
@ -76,7 +76,12 @@ class IntegrationSettingsViewBase(BaseAppView):
|
|||
|
||||
if 'integration' in request.matchdict: # integration type context
|
||||
integration_type = request.matchdict['integration']
|
||||
if integration_type not in integration_type_registry:
|
||||
raise HTTPNotFound()
|
||||
|
||||
self.IntegrationType = integration_type_registry[integration_type]
|
||||
if self.IntegrationType.is_dummy:
|
||||
raise HTTPNotFound()
|
||||
|
||||
if 'integration_id' in request.matchdict: # single integration context
|
||||
integration_id = request.matchdict['integration_id']
|
||||
|
|
|
|||
|
|
@ -1195,6 +1195,9 @@ table.integrations {
|
|||
min-width: 140px;
|
||||
}
|
||||
}
|
||||
a.integration-box.dummy-integration {
|
||||
color: @grey4
|
||||
}
|
||||
}
|
||||
|
||||
//Permissions Settings
|
||||
|
|
|
|||
|
|
@ -64,23 +64,25 @@
|
|||
<a href="${home_url}" class="btn ${not c.current_IntegrationType and 'btn-primary' or ''}">${_('All')}</a>
|
||||
|
||||
%for integration_key, IntegrationType in c.available_integrations.items():
|
||||
<%
|
||||
if c.repo:
|
||||
list_url = request.route_path('repo_integrations_list',
|
||||
repo_name=c.repo.repo_name,
|
||||
integration=integration_key)
|
||||
elif c.repo_group:
|
||||
list_url = request.route_path('repo_group_integrations_list',
|
||||
repo_group_name=c.repo_group.group_name,
|
||||
integration=integration_key)
|
||||
else:
|
||||
list_url = request.route_path('global_integrations_list',
|
||||
integration=integration_key)
|
||||
%>
|
||||
<a href="${list_url}"
|
||||
class="btn ${c.current_IntegrationType and integration_key == c.current_IntegrationType.key and 'btn-primary' or ''}">
|
||||
${IntegrationType.display_name}
|
||||
</a>
|
||||
% if not IntegrationType.is_dummy:
|
||||
<%
|
||||
if c.repo:
|
||||
list_url = request.route_path('repo_integrations_list',
|
||||
repo_name=c.repo.repo_name,
|
||||
integration=integration_key)
|
||||
elif c.repo_group:
|
||||
list_url = request.route_path('repo_group_integrations_list',
|
||||
repo_group_name=c.repo_group.group_name,
|
||||
integration=integration_key)
|
||||
else:
|
||||
list_url = request.route_path('global_integrations_list',
|
||||
integration=integration_key)
|
||||
%>
|
||||
<a href="${list_url}"
|
||||
class="btn ${c.current_IntegrationType and integration_key == c.current_IntegrationType.key and 'btn-primary' or ''}">
|
||||
${IntegrationType.display_name}
|
||||
</a>
|
||||
% endif
|
||||
%endfor
|
||||
|
||||
<%
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@
|
|||
%endif
|
||||
</%def>
|
||||
|
||||
%for integration, IntegrationType in c.available_integrations.items():
|
||||
%for integration, IntegrationObject in c.available_integrations.items():
|
||||
<%
|
||||
if c.repo:
|
||||
create_url = request.route_path('repo_integrations_create',
|
||||
|
|
@ -49,16 +49,18 @@
|
|||
else:
|
||||
create_url = request.route_path('global_integrations_create',
|
||||
integration=integration)
|
||||
if IntegrationObject.is_dummy:
|
||||
create_url = request.current_route_path()
|
||||
%>
|
||||
<a href="${create_url}" class="integration-box">
|
||||
<a href="${create_url}" class="integration-box ${'dummy-integration' if IntegrationObject.is_dummy else ''}">
|
||||
<%widgets:panel>
|
||||
<h2>
|
||||
<div class="integration-icon">
|
||||
${IntegrationType.icon|n}
|
||||
${IntegrationObject.icon|n}
|
||||
</div>
|
||||
${IntegrationType.display_name}
|
||||
${IntegrationObject.display_name}
|
||||
</h2>
|
||||
${IntegrationType.description or _('No description available')}
|
||||
${IntegrationObject.description or _('No description available')}
|
||||
</%widgets:panel>
|
||||
</a>
|
||||
%endfor
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue