integrations: rewrote usage of pylons components inside integrations.
- added better auth decorators as used in other parts of the app - fixed tests - refactored the code to match other parts better (repo_route/repo_group_route)
This commit is contained in:
parent
2c11516c9b
commit
17359c262c
10 changed files with 471 additions and 382 deletions
|
|
@ -21,6 +21,7 @@
|
|||
import logging
|
||||
|
||||
from rhodecode.apps._base import ADMIN_PREFIX, add_route_requirements
|
||||
from rhodecode.lib.utils2 import safe_int
|
||||
from rhodecode.model.db import Repository, Integration, RepoGroup
|
||||
from rhodecode.integrations import integration_type_registry
|
||||
|
||||
|
|
@ -30,7 +31,6 @@ log = logging.getLogger(__name__)
|
|||
def includeme(config):
|
||||
|
||||
# global integrations
|
||||
|
||||
config.add_route('global_integrations_new',
|
||||
ADMIN_PREFIX + '/integrations/new')
|
||||
config.add_view('rhodecode.integrations.views.GlobalIntegrationsView',
|
||||
|
|
@ -45,7 +45,7 @@ def includeme(config):
|
|||
ADMIN_PREFIX + '/integrations/{integration}')
|
||||
for route_name in ['global_integrations_home', 'global_integrations_list']:
|
||||
config.add_view('rhodecode.integrations.views.GlobalIntegrationsView',
|
||||
attr='index',
|
||||
attr='integration_list',
|
||||
renderer='rhodecode:templates/admin/integrations/list.mako',
|
||||
request_method='GET',
|
||||
route_name=route_name)
|
||||
|
|
@ -57,7 +57,6 @@ def includeme(config):
|
|||
ADMIN_PREFIX + '/integrations/{integration}/{integration_id}',
|
||||
custom_predicates=(valid_integration,))
|
||||
|
||||
|
||||
for route_name in ['global_integrations_create', 'global_integrations_edit']:
|
||||
config.add_view('rhodecode.integrations.views.GlobalIntegrationsView',
|
||||
attr='settings_get',
|
||||
|
|
@ -70,154 +69,159 @@ def includeme(config):
|
|||
request_method='POST',
|
||||
route_name=route_name)
|
||||
|
||||
|
||||
# repo group integrations
|
||||
config.add_route('repo_group_integrations_home',
|
||||
add_route_requirements(
|
||||
'{repo_group_name}/settings/integrations',
|
||||
),
|
||||
custom_predicates=(valid_repo_group,)
|
||||
)
|
||||
config.add_route('repo_group_integrations_list',
|
||||
add_route_requirements(
|
||||
'{repo_group_name}/settings/integrations/{integration}',
|
||||
),
|
||||
custom_predicates=(valid_repo_group, valid_integration))
|
||||
for route_name in ['repo_group_integrations_home', 'repo_group_integrations_list']:
|
||||
config.add_view('rhodecode.integrations.views.RepoGroupIntegrationsView',
|
||||
attr='index',
|
||||
renderer='rhodecode:templates/admin/integrations/list.mako',
|
||||
request_method='GET',
|
||||
route_name=route_name)
|
||||
add_route_requirements('/{repo_group_name}/settings/integrations'),
|
||||
repo_group_route=True)
|
||||
|
||||
config.add_view('rhodecode.integrations.views.RepoGroupIntegrationsView',
|
||||
attr='integration_list',
|
||||
renderer='rhodecode:templates/admin/integrations/list.mako',
|
||||
request_method='GET',
|
||||
route_name='repo_group_integrations_home')
|
||||
|
||||
config.add_route('repo_group_integrations_new',
|
||||
add_route_requirements(
|
||||
'{repo_group_name}/settings/integrations/new',
|
||||
),
|
||||
custom_predicates=(valid_repo_group,))
|
||||
add_route_requirements('/{repo_group_name}/settings/integrations/new'),
|
||||
repo_group_route=True)
|
||||
config.add_view('rhodecode.integrations.views.RepoGroupIntegrationsView',
|
||||
attr='new_integration',
|
||||
renderer='rhodecode:templates/admin/integrations/new.mako',
|
||||
request_method='GET',
|
||||
route_name='repo_group_integrations_new')
|
||||
|
||||
config.add_route('repo_group_integrations_create',
|
||||
add_route_requirements(
|
||||
'{repo_group_name}/settings/integrations/{integration}/new',
|
||||
),
|
||||
custom_predicates=(valid_repo_group, valid_integration))
|
||||
config.add_route('repo_group_integrations_edit',
|
||||
add_route_requirements(
|
||||
'{repo_group_name}/settings/integrations/{integration}/{integration_id}',
|
||||
),
|
||||
custom_predicates=(valid_repo_group, valid_integration))
|
||||
for route_name in ['repo_group_integrations_edit', 'repo_group_integrations_create']:
|
||||
config.add_view('rhodecode.integrations.views.RepoGroupIntegrationsView',
|
||||
attr='settings_get',
|
||||
renderer='rhodecode:templates/admin/integrations/form.mako',
|
||||
request_method='GET',
|
||||
route_name=route_name)
|
||||
config.add_view('rhodecode.integrations.views.RepoGroupIntegrationsView',
|
||||
attr='settings_post',
|
||||
renderer='rhodecode:templates/admin/integrations/form.mako',
|
||||
request_method='POST',
|
||||
route_name=route_name)
|
||||
config.add_route('repo_group_integrations_list',
|
||||
add_route_requirements('/{repo_group_name}/settings/integrations/{integration}'),
|
||||
repo_group_route=True,
|
||||
custom_predicates=(valid_integration,))
|
||||
config.add_view('rhodecode.integrations.views.RepoGroupIntegrationsView',
|
||||
attr='integration_list',
|
||||
renderer='rhodecode:templates/admin/integrations/list.mako',
|
||||
request_method='GET',
|
||||
route_name='repo_group_integrations_list')
|
||||
|
||||
config.add_route('repo_group_integrations_create',
|
||||
add_route_requirements('/{repo_group_name}/settings/integrations/{integration}/new'),
|
||||
repo_group_route=True,
|
||||
custom_predicates=(valid_integration,))
|
||||
config.add_view('rhodecode.integrations.views.RepoGroupIntegrationsView',
|
||||
attr='settings_get',
|
||||
renderer='rhodecode:templates/admin/integrations/form.mako',
|
||||
request_method='GET',
|
||||
route_name='repo_group_integrations_create')
|
||||
config.add_view('rhodecode.integrations.views.RepoGroupIntegrationsView',
|
||||
attr='settings_post',
|
||||
renderer='rhodecode:templates/admin/integrations/form.mako',
|
||||
request_method='POST',
|
||||
route_name='repo_group_integrations_create')
|
||||
|
||||
config.add_route('repo_group_integrations_edit',
|
||||
add_route_requirements('/{repo_group_name}/settings/integrations/{integration}/{integration_id}'),
|
||||
repo_group_route=True,
|
||||
custom_predicates=(valid_integration,))
|
||||
|
||||
config.add_view('rhodecode.integrations.views.RepoGroupIntegrationsView',
|
||||
attr='settings_get',
|
||||
renderer='rhodecode:templates/admin/integrations/form.mako',
|
||||
request_method='GET',
|
||||
route_name='repo_group_integrations_edit')
|
||||
config.add_view('rhodecode.integrations.views.RepoGroupIntegrationsView',
|
||||
attr='settings_post',
|
||||
renderer='rhodecode:templates/admin/integrations/form.mako',
|
||||
request_method='POST',
|
||||
route_name='repo_group_integrations_edit')
|
||||
|
||||
# repo integrations
|
||||
config.add_route('repo_integrations_home',
|
||||
add_route_requirements(
|
||||
'{repo_name}/settings/integrations',
|
||||
),
|
||||
custom_predicates=(valid_repo,))
|
||||
config.add_route('repo_integrations_list',
|
||||
add_route_requirements(
|
||||
'{repo_name}/settings/integrations/{integration}',
|
||||
),
|
||||
custom_predicates=(valid_repo, valid_integration))
|
||||
for route_name in ['repo_integrations_home', 'repo_integrations_list']:
|
||||
config.add_view('rhodecode.integrations.views.RepoIntegrationsView',
|
||||
attr='index',
|
||||
request_method='GET',
|
||||
renderer='rhodecode:templates/admin/integrations/list.mako',
|
||||
route_name=route_name)
|
||||
add_route_requirements('/{repo_name}/settings/integrations'),
|
||||
repo_route=True)
|
||||
config.add_view('rhodecode.integrations.views.RepoIntegrationsView',
|
||||
attr='integration_list',
|
||||
request_method='GET',
|
||||
renderer='rhodecode:templates/admin/integrations/list.mako',
|
||||
route_name='repo_integrations_home')
|
||||
|
||||
config.add_route('repo_integrations_new',
|
||||
add_route_requirements(
|
||||
'{repo_name}/settings/integrations/new',
|
||||
),
|
||||
custom_predicates=(valid_repo,))
|
||||
add_route_requirements('/{repo_name}/settings/integrations/new'),
|
||||
repo_route=True)
|
||||
config.add_view('rhodecode.integrations.views.RepoIntegrationsView',
|
||||
attr='new_integration',
|
||||
renderer='rhodecode:templates/admin/integrations/new.mako',
|
||||
request_method='GET',
|
||||
route_name='repo_integrations_new')
|
||||
|
||||
config.add_route('repo_integrations_list',
|
||||
add_route_requirements('/{repo_name}/settings/integrations/{integration}'),
|
||||
repo_route=True,
|
||||
custom_predicates=(valid_integration,))
|
||||
config.add_view('rhodecode.integrations.views.RepoIntegrationsView',
|
||||
attr='integration_list',
|
||||
request_method='GET',
|
||||
renderer='rhodecode:templates/admin/integrations/list.mako',
|
||||
route_name='repo_integrations_list')
|
||||
|
||||
config.add_route('repo_integrations_create',
|
||||
add_route_requirements(
|
||||
'{repo_name}/settings/integrations/{integration}/new',
|
||||
),
|
||||
custom_predicates=(valid_repo, valid_integration))
|
||||
add_route_requirements('/{repo_name}/settings/integrations/{integration}/new'),
|
||||
repo_route=True,
|
||||
custom_predicates=(valid_integration,))
|
||||
config.add_view('rhodecode.integrations.views.RepoIntegrationsView',
|
||||
attr='settings_get',
|
||||
renderer='rhodecode:templates/admin/integrations/form.mako',
|
||||
request_method='GET',
|
||||
route_name='repo_integrations_create')
|
||||
config.add_view('rhodecode.integrations.views.RepoIntegrationsView',
|
||||
attr='settings_post',
|
||||
renderer='rhodecode:templates/admin/integrations/form.mako',
|
||||
request_method='POST',
|
||||
route_name='repo_integrations_create')
|
||||
|
||||
config.add_route('repo_integrations_edit',
|
||||
add_route_requirements(
|
||||
'{repo_name}/settings/integrations/{integration}/{integration_id}',
|
||||
),
|
||||
custom_predicates=(valid_repo, valid_integration))
|
||||
for route_name in ['repo_integrations_edit', 'repo_integrations_create']:
|
||||
config.add_view('rhodecode.integrations.views.RepoIntegrationsView',
|
||||
attr='settings_get',
|
||||
renderer='rhodecode:templates/admin/integrations/form.mako',
|
||||
request_method='GET',
|
||||
route_name=route_name)
|
||||
config.add_view('rhodecode.integrations.views.RepoIntegrationsView',
|
||||
attr='settings_post',
|
||||
renderer='rhodecode:templates/admin/integrations/form.mako',
|
||||
request_method='POST',
|
||||
route_name=route_name)
|
||||
add_route_requirements('/{repo_name}/settings/integrations/{integration}/{integration_id}'),
|
||||
repo_route=True,
|
||||
custom_predicates=(valid_integration,))
|
||||
config.add_view('rhodecode.integrations.views.RepoIntegrationsView',
|
||||
attr='settings_get',
|
||||
renderer='rhodecode:templates/admin/integrations/form.mako',
|
||||
request_method='GET',
|
||||
route_name='repo_integrations_edit')
|
||||
config.add_view('rhodecode.integrations.views.RepoIntegrationsView',
|
||||
attr='settings_post',
|
||||
renderer='rhodecode:templates/admin/integrations/form.mako',
|
||||
request_method='POST',
|
||||
route_name='repo_integrations_edit')
|
||||
|
||||
|
||||
def valid_repo(info, request):
|
||||
repo = Repository.get_by_repo_name(info['match']['repo_name'])
|
||||
if repo:
|
||||
return True
|
||||
|
||||
|
||||
def valid_repo_group(info, request):
|
||||
repo_group = RepoGroup.get_by_group_name(info['match']['repo_group_name'])
|
||||
if repo_group:
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
def valid_integration(info, request):
|
||||
integration_type = info['match']['integration']
|
||||
integration_id = info['match'].get('integration_id')
|
||||
repo_name = info['match'].get('repo_name')
|
||||
repo_group_name = info['match'].get('repo_group_name')
|
||||
|
||||
if integration_type not in integration_type_registry:
|
||||
return False
|
||||
|
||||
repo, repo_group = None, None
|
||||
if repo_name:
|
||||
repo = Repository.get_by_repo_name(repo_name)
|
||||
if not repo:
|
||||
return False
|
||||
|
||||
if repo_group_name:
|
||||
repo_group = RepoGroup.get_by_group_name(repo_group_name)
|
||||
if not repo_group:
|
||||
return False
|
||||
|
||||
if repo_name and repo_group:
|
||||
raise Exception('Either repo or repo_group can be set, not both')
|
||||
|
||||
if integration_id:
|
||||
if not safe_int(integration_id):
|
||||
return False
|
||||
|
||||
integration = Integration.get(integration_id)
|
||||
if not integration:
|
||||
return False
|
||||
if integration.integration_type != integration_type:
|
||||
return False
|
||||
|
||||
# match types to repo or repo group
|
||||
repo_name = info['match'].get('repo_name')
|
||||
repo_group_name = info['match'].get('repo_group_name')
|
||||
repo, repo_group = None, None
|
||||
if repo_name:
|
||||
repo = Repository.get_by_repo_name(repo_name)
|
||||
if not repo:
|
||||
return False
|
||||
|
||||
if repo_group_name:
|
||||
repo_group = RepoGroup.get_by_group_name(repo_group_name)
|
||||
if not repo_group:
|
||||
return False
|
||||
|
||||
if repo and repo.repo_id != integration.repo_id:
|
||||
return False
|
||||
if repo_group and repo_group.group_id != integration.repo_group_id:
|
||||
|
|
|
|||
19
rhodecode/integrations/tests/__init__.py
Normal file
19
rhodecode/integrations/tests/__init__.py
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Copyright (C) 2016-2017 RhodeCode GmbH
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Affero General Public License, version 3
|
||||
# (only), as published by the Free Software Foundation.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
# This program is dual-licensed. If you wish to learn more about the
|
||||
# RhodeCode Enterprise Edition, including its added features, Support services,
|
||||
# and proprietary license terms, please see https://rhodecode.com/licenses/
|
||||
|
|
@ -20,10 +20,16 @@
|
|||
|
||||
import pytest
|
||||
|
||||
from rhodecode.apps._base import ADMIN_PREFIX
|
||||
from rhodecode.model.db import Integration
|
||||
from rhodecode.model.meta import Session
|
||||
from rhodecode.integrations import integration_type_registry
|
||||
from rhodecode.config.routing import ADMIN_PREFIX
|
||||
|
||||
|
||||
def route_path(name, **kwargs):
|
||||
return {
|
||||
'home': '/',
|
||||
}[name].format(**kwargs)
|
||||
|
||||
|
||||
@pytest.mark.usefixtures('app', 'autologin_user')
|
||||
|
|
@ -32,86 +38,141 @@ class TestIntegrationsView(object):
|
|||
|
||||
|
||||
class TestGlobalIntegrationsView(TestIntegrationsView):
|
||||
def test_index_no_integrations(self, app):
|
||||
def test_index_no_integrations(self):
|
||||
url = ADMIN_PREFIX + '/integrations'
|
||||
response = app.get(url)
|
||||
response = self.app.get(url)
|
||||
|
||||
assert response.status_code == 200
|
||||
assert 'exist yet' in response.body
|
||||
|
||||
def test_index_with_integrations(self, app, global_integration_stub):
|
||||
def test_index_with_integrations(self, global_integration_stub):
|
||||
url = ADMIN_PREFIX + '/integrations'
|
||||
response = app.get(url)
|
||||
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
|
||||
|
||||
def test_new_integration_page(self, app):
|
||||
@pytest.mark.parametrize(
|
||||
'IntegrationType', integration_type_registry.values())
|
||||
def test_new_integration_page(self, IntegrationType):
|
||||
url = ADMIN_PREFIX + '/integrations/new'
|
||||
|
||||
response = app.get(url)
|
||||
response = self.app.get(url, status=200)
|
||||
|
||||
assert response.status_code == 200
|
||||
|
||||
for integration_key in integration_type_registry:
|
||||
nurl = (ADMIN_PREFIX + '/integrations/{integration}/new').format(
|
||||
integration=integration_key)
|
||||
assert nurl in response.body
|
||||
url = (ADMIN_PREFIX + '/integrations/{integration}/new').format(
|
||||
integration=IntegrationType.key)
|
||||
assert url in response.body
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
'IntegrationType', integration_type_registry.values())
|
||||
def test_get_create_integration_page(self, app, IntegrationType):
|
||||
def test_get_create_integration_page(self, IntegrationType):
|
||||
url = ADMIN_PREFIX + '/integrations/{integration_key}/new'.format(
|
||||
integration_key=IntegrationType.key)
|
||||
|
||||
response = app.get(url)
|
||||
response = self.app.get(url, status=200)
|
||||
|
||||
assert response.status_code == 200
|
||||
assert IntegrationType.display_name in response.body
|
||||
|
||||
def test_post_integration_page(self, app, StubIntegrationType, csrf_token,
|
||||
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(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)
|
||||
|
||||
|
||||
class TestRepoGroupIntegrationsView(TestIntegrationsView):
|
||||
def test_index_no_integrations(self, app, test_repo_group):
|
||||
url = '/{repo_group_name}/settings/integrations'.format(
|
||||
repo_group_name=test_repo_group.group_name)
|
||||
response = app.get(url)
|
||||
class TestRepoIntegrationsView(TestIntegrationsView):
|
||||
def test_index_no_integrations(self, backend_random):
|
||||
url = '/{repo_name}/settings/integrations'.format(
|
||||
repo_name=backend_random.repo.repo_name)
|
||||
response = self.app.get(url)
|
||||
|
||||
assert response.status_code == 200
|
||||
assert 'exist yet' in response.body
|
||||
|
||||
def test_index_with_integrations(self, app, test_repo_group,
|
||||
repogroup_integration_stub):
|
||||
def test_index_with_integrations(self, repo_integration_stub):
|
||||
url = '/{repo_name}/settings/integrations'.format(
|
||||
repo_name=repo_integration_stub.repo.repo_name)
|
||||
stub_name = repo_integration_stub.name
|
||||
|
||||
response = self.app.get(url)
|
||||
|
||||
assert response.status_code == 200
|
||||
assert stub_name in response.body
|
||||
assert 'exist yet' not in response.body
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
'IntegrationType', integration_type_registry.values())
|
||||
def test_new_integration_page(self, backend_random, IntegrationType):
|
||||
repo_name = backend_random.repo.repo_name
|
||||
url = '/{repo_name}/settings/integrations/new'.format(
|
||||
repo_name=repo_name)
|
||||
|
||||
response = self.app.get(url, status=200)
|
||||
|
||||
url = '/{repo_name}/settings/integrations/{integration}/new'.format(
|
||||
repo_name=repo_name,
|
||||
integration=IntegrationType.key)
|
||||
|
||||
assert url in response.body
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
'IntegrationType', integration_type_registry.values())
|
||||
def test_get_create_integration_page(self, backend_random, IntegrationType):
|
||||
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
|
||||
|
||||
def test_post_integration_page(self, backend_random, test_repo_group,
|
||||
StubIntegrationType, csrf_token):
|
||||
repo_name = backend_random.repo.repo_name
|
||||
url = '/{repo_name}/settings/integrations/{integration_key}/new'.format(
|
||||
repo_name=repo_name, integration_key=StubIntegrationType.key)
|
||||
|
||||
_post_integration_test_helper(
|
||||
self.app, url, csrf_token, admin_view=False,
|
||||
repo=backend_random.repo, repo_group=test_repo_group)
|
||||
|
||||
|
||||
class TestRepoGroupIntegrationsView(TestIntegrationsView):
|
||||
def test_index_no_integrations(self, test_repo_group):
|
||||
url = '/{repo_group_name}/settings/integrations'.format(
|
||||
repo_group_name=test_repo_group.group_name)
|
||||
response = self.app.get(url)
|
||||
|
||||
assert response.status_code == 200
|
||||
assert 'exist yet' in response.body
|
||||
|
||||
def test_index_with_integrations(
|
||||
self, test_repo_group, repogroup_integration_stub):
|
||||
|
||||
url = '/{repo_group_name}/settings/integrations'.format(
|
||||
repo_group_name=test_repo_group.group_name)
|
||||
|
||||
stub_name = repogroup_integration_stub.name
|
||||
response = app.get(url)
|
||||
response = self.app.get(url)
|
||||
|
||||
assert response.status_code == 200
|
||||
assert 'exist yet' not in response.body
|
||||
assert stub_name in response.body
|
||||
|
||||
def test_new_integration_page(self, app, test_repo_group):
|
||||
def test_new_integration_page(self, test_repo_group):
|
||||
repo_group_name = test_repo_group.group_name
|
||||
url = '/{repo_group_name}/settings/integrations/new'.format(
|
||||
repo_group_name=test_repo_group.group_name)
|
||||
|
||||
response = app.get(url)
|
||||
response = self.app.get(url)
|
||||
|
||||
assert response.status_code == 200
|
||||
|
||||
for integration_key in integration_type_registry:
|
||||
nurl = ('/{repo_group_name}/settings/integrations'
|
||||
'/{integration}/new').format(
|
||||
nurl = ('/{repo_group_name}/settings/integrations/{integration}/new').format(
|
||||
repo_group_name=repo_group_name,
|
||||
integration=integration_key)
|
||||
|
||||
|
|
@ -119,86 +180,29 @@ class TestRepoGroupIntegrationsView(TestIntegrationsView):
|
|||
|
||||
@pytest.mark.parametrize(
|
||||
'IntegrationType', integration_type_registry.values())
|
||||
def test_get_create_integration_page(self, app, test_repo_group,
|
||||
IntegrationType):
|
||||
def test_get_create_integration_page(
|
||||
self, test_repo_group, IntegrationType):
|
||||
|
||||
repo_group_name = test_repo_group.group_name
|
||||
url = ('/{repo_group_name}/settings/integrations/{integration_key}/new'
|
||||
).format(repo_group_name=repo_group_name,
|
||||
integration_key=IntegrationType.key)
|
||||
|
||||
response = app.get(url)
|
||||
response = self.app.get(url)
|
||||
|
||||
assert response.status_code == 200
|
||||
assert IntegrationType.display_name in response.body
|
||||
|
||||
def test_post_integration_page(self, app, test_repo_group, backend_random,
|
||||
def test_post_integration_page(self, test_repo_group, backend_random,
|
||||
StubIntegrationType, csrf_token):
|
||||
|
||||
repo_group_name = test_repo_group.group_name
|
||||
url = ('/{repo_group_name}/settings/integrations/{integration_key}/new'
|
||||
).format(repo_group_name=repo_group_name,
|
||||
integration_key=StubIntegrationType.key)
|
||||
|
||||
_post_integration_test_helper(app, url, csrf_token, admin_view=False,
|
||||
repo=backend_random.repo, repo_group=test_repo_group)
|
||||
|
||||
|
||||
class TestRepoIntegrationsView(TestIntegrationsView):
|
||||
def test_index_no_integrations(self, app, backend_random):
|
||||
url = '/{repo_name}/settings/integrations'.format(
|
||||
repo_name=backend_random.repo.repo_name)
|
||||
response = app.get(url)
|
||||
|
||||
assert response.status_code == 200
|
||||
assert 'exist yet' in response.body
|
||||
|
||||
def test_index_with_integrations(self, app, repo_integration_stub):
|
||||
url = '/{repo_name}/settings/integrations'.format(
|
||||
repo_name=repo_integration_stub.repo.repo_name)
|
||||
stub_name = repo_integration_stub.name
|
||||
|
||||
response = app.get(url)
|
||||
|
||||
assert response.status_code == 200
|
||||
assert stub_name in response.body
|
||||
assert 'exist yet' not in response.body
|
||||
|
||||
def test_new_integration_page(self, app, backend_random):
|
||||
repo_name = backend_random.repo.repo_name
|
||||
url = '/{repo_name}/settings/integrations/new'.format(
|
||||
repo_name=repo_name)
|
||||
|
||||
response = app.get(url)
|
||||
|
||||
assert response.status_code == 200
|
||||
|
||||
for integration_key in integration_type_registry:
|
||||
nurl = ('/{repo_name}/settings/integrations'
|
||||
'/{integration}/new').format(
|
||||
repo_name=repo_name,
|
||||
integration=integration_key)
|
||||
|
||||
assert nurl in response.body
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
'IntegrationType', integration_type_registry.values())
|
||||
def test_get_create_integration_page(self, app, backend_random,
|
||||
IntegrationType):
|
||||
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 = app.get(url)
|
||||
|
||||
assert response.status_code == 200
|
||||
assert IntegrationType.display_name in response.body
|
||||
|
||||
def test_post_integration_page(self, app, backend_random, test_repo_group,
|
||||
StubIntegrationType, csrf_token):
|
||||
repo_name = backend_random.repo.repo_name
|
||||
url = '/{repo_name}/settings/integrations/{integration_key}/new'.format(
|
||||
repo_name=repo_name, integration_key=StubIntegrationType.key)
|
||||
|
||||
_post_integration_test_helper(app, url, csrf_token, admin_view=False,
|
||||
_post_integration_test_helper(
|
||||
self.app, url, csrf_token, admin_view=False,
|
||||
repo=backend_random.repo, repo_group=test_repo_group)
|
||||
|
||||
|
||||
|
|
@ -208,7 +212,8 @@ def _post_integration_test_helper(app, url, csrf_token, repo, repo_group,
|
|||
Posts form data to create integration at the url given then deletes it and
|
||||
checks if the redirect url is correct.
|
||||
"""
|
||||
|
||||
repo_name = repo.repo_name
|
||||
repo_group_name = repo_group.group_name
|
||||
app.post(url, params={}, status=403) # missing csrf check
|
||||
response = app.post(url, params={'csrf_token': csrf_token})
|
||||
assert response.status_code == 200
|
||||
|
|
@ -216,15 +221,15 @@ def _post_integration_test_helper(app, url, csrf_token, repo, repo_group,
|
|||
|
||||
scopes_destinations = [
|
||||
('global',
|
||||
ADMIN_PREFIX + '/integrations'),
|
||||
ADMIN_PREFIX + '/integrations'),
|
||||
('root-repos',
|
||||
ADMIN_PREFIX + '/integrations'),
|
||||
('repo:%s' % repo.repo_name,
|
||||
'/%s/settings/integrations' % repo.repo_name),
|
||||
('repogroup:%s' % repo_group.group_name,
|
||||
'/%s/settings/integrations' % repo_group.group_name),
|
||||
('repogroup-recursive:%s' % repo_group.group_name,
|
||||
'/%s/settings/integrations' % repo_group.group_name),
|
||||
('repo:%s' % repo_name,
|
||||
'/%s/settings/integrations' % repo_name),
|
||||
('repogroup:%s' % repo_group_name,
|
||||
'/%s/settings/integrations' % repo_group_name),
|
||||
('repogroup-recursive:%s' % repo_group_name,
|
||||
'/%s/settings/integrations' % repo_group_name),
|
||||
]
|
||||
|
||||
for scope, destination in scopes_destinations:
|
||||
|
|
@ -18,45 +18,40 @@
|
|||
# RhodeCode Enterprise Edition, including its added features, Support services,
|
||||
# and proprietary license terms, please see https://rhodecode.com/licenses/
|
||||
|
||||
import pylons
|
||||
import deform
|
||||
import logging
|
||||
import colander
|
||||
import peppercorn
|
||||
import webhelpers.paginate
|
||||
|
||||
from pyramid.httpexceptions import HTTPFound, HTTPForbidden, HTTPBadRequest
|
||||
from pyramid.renderers import render
|
||||
from pyramid.response import Response
|
||||
from pyramid.httpexceptions import HTTPFound, HTTPForbidden
|
||||
|
||||
from rhodecode.apps._base import BaseAppView
|
||||
from rhodecode.integrations import integration_type_registry
|
||||
from rhodecode.apps.admin.navigation import navigation_list
|
||||
from rhodecode.lib import auth
|
||||
from rhodecode.lib.auth import LoginRequired, HasPermissionAllDecorator
|
||||
from rhodecode.lib.auth import (
|
||||
LoginRequired, CSRFRequired, HasPermissionAnyDecorator,
|
||||
HasRepoPermissionAnyDecorator, HasRepoGroupPermissionAnyDecorator)
|
||||
from rhodecode.lib.utils2 import safe_int
|
||||
from rhodecode.lib.helpers import Page
|
||||
from rhodecode.model.db import Repository, RepoGroup, Session, Integration
|
||||
from rhodecode.model.scm import ScmModel
|
||||
from rhodecode.model.integration import IntegrationModel
|
||||
from rhodecode.translation import _
|
||||
from rhodecode.integrations import integration_type_registry
|
||||
from rhodecode.model.validation_schema.schemas.integration_schema import (
|
||||
make_integration_schema, IntegrationScopeType)
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class IntegrationSettingsViewBase(object):
|
||||
""" Base Integration settings view used by both repo / global settings """
|
||||
class IntegrationSettingsViewBase(BaseAppView):
|
||||
"""
|
||||
Base Integration settings view used by both repo / global settings
|
||||
"""
|
||||
|
||||
def __init__(self, context, request):
|
||||
self.context = context
|
||||
self.request = request
|
||||
self._load_general_context()
|
||||
super(IntegrationSettingsViewBase, self).__init__(context, request)
|
||||
self._load_view_context()
|
||||
|
||||
if not self.perm_check(request.user):
|
||||
raise HTTPForbidden()
|
||||
|
||||
def _load_general_context(self):
|
||||
def _load_view_context(self):
|
||||
"""
|
||||
This avoids boilerplate for repo/global+list/edit+views/templates
|
||||
by doing all possible contexts at the same time however it should
|
||||
|
|
@ -110,25 +105,12 @@ class IntegrationSettingsViewBase(object):
|
|||
|
||||
return False
|
||||
|
||||
def _template_c_context(self):
|
||||
# TODO: dan: this is a stopgap in order to inherit from current pylons
|
||||
# based admin/repo settings templates - this should be removed entirely
|
||||
# after port to pyramid
|
||||
def _get_local_tmpl_context(self, include_app_defaults=False):
|
||||
_ = self.request.translate
|
||||
c = super(IntegrationSettingsViewBase, self)._get_local_tmpl_context(
|
||||
include_app_defaults=include_app_defaults)
|
||||
|
||||
c = pylons.tmpl_context
|
||||
c.active = 'integrations'
|
||||
c.rhodecode_user = self.request.user
|
||||
c.repo = self.repo
|
||||
c.repo_group = self.repo_group
|
||||
c.repo_name = self.repo and self.repo.repo_name or None
|
||||
c.repo_group_name = self.repo_group and self.repo_group.group_name or None
|
||||
|
||||
if self.repo:
|
||||
c.repo_info = self.repo
|
||||
c.rhodecode_db_repo = self.repo
|
||||
c.repository_pull_requests = ScmModel().get_pull_requests(self.repo)
|
||||
else:
|
||||
c.navlist = navigation_list(self.request)
|
||||
|
||||
return c
|
||||
|
||||
|
|
@ -142,6 +124,7 @@ class IntegrationSettingsViewBase(object):
|
|||
no_scope=not self.admin_view)
|
||||
|
||||
def _form_defaults(self):
|
||||
_ = self.request.translate
|
||||
defaults = {}
|
||||
|
||||
if self.integration:
|
||||
|
|
@ -178,28 +161,79 @@ class IntegrationSettingsViewBase(object):
|
|||
return defaults
|
||||
|
||||
def _delete_integration(self, integration):
|
||||
Session().delete(self.integration)
|
||||
_ = self.request.translate
|
||||
Session().delete(integration)
|
||||
Session().commit()
|
||||
self.request.session.flash(
|
||||
_('Integration {integration_name} deleted successfully.').format(
|
||||
integration_name=self.integration.name),
|
||||
integration_name=integration.name),
|
||||
queue='success')
|
||||
|
||||
if self.repo:
|
||||
redirect_to = self.request.route_url(
|
||||
redirect_to = self.request.route_path(
|
||||
'repo_integrations_home', repo_name=self.repo.repo_name)
|
||||
elif self.repo_group:
|
||||
redirect_to = self.request.route_url(
|
||||
redirect_to = self.request.route_path(
|
||||
'repo_group_integrations_home',
|
||||
repo_group_name=self.repo_group.group_name)
|
||||
else:
|
||||
redirect_to = self.request.route_url('global_integrations_home')
|
||||
redirect_to = self.request.route_path('global_integrations_home')
|
||||
raise HTTPFound(redirect_to)
|
||||
|
||||
def settings_get(self, defaults=None, form=None):
|
||||
def _integration_list(self):
|
||||
""" List integrations """
|
||||
|
||||
c = self.load_default_context()
|
||||
if self.repo:
|
||||
scope = self.repo
|
||||
elif self.repo_group:
|
||||
scope = self.repo_group
|
||||
else:
|
||||
scope = 'all'
|
||||
|
||||
integrations = []
|
||||
|
||||
for IntType, integration in IntegrationModel().get_integrations(
|
||||
scope=scope, IntegrationType=self.IntegrationType):
|
||||
|
||||
# extra permissions check *just in case*
|
||||
if not self._has_perms_for_integration(integration):
|
||||
continue
|
||||
|
||||
integrations.append((IntType, integration))
|
||||
|
||||
sort_arg = self.request.GET.get('sort', 'name:asc')
|
||||
if ':' in sort_arg:
|
||||
sort_field, sort_dir = sort_arg.split(':')
|
||||
else:
|
||||
sort_field = sort_arg, 'asc'
|
||||
|
||||
assert sort_field in ('name', 'integration_type', 'enabled', 'scope')
|
||||
|
||||
integrations.sort(
|
||||
key=lambda x: getattr(x[1], sort_field),
|
||||
reverse=(sort_dir == 'desc'))
|
||||
|
||||
page_url = webhelpers.paginate.PageURL(
|
||||
self.request.path, self.request.GET)
|
||||
page = safe_int(self.request.GET.get('page', 1), 1)
|
||||
|
||||
integrations = Page(
|
||||
integrations, page=page, items_per_page=10, url=page_url)
|
||||
|
||||
c.rev_sort_dir = sort_dir != 'desc' and 'desc' or 'asc'
|
||||
|
||||
c.current_IntegrationType = self.IntegrationType
|
||||
c.integrations_list = integrations
|
||||
c.available_integrations = integration_type_registry
|
||||
|
||||
return self._get_template_context(c)
|
||||
|
||||
def _settings_get(self, defaults=None, form=None):
|
||||
"""
|
||||
View that displays the integration settings as a form.
|
||||
"""
|
||||
c = self.load_default_context()
|
||||
|
||||
defaults = defaults or self._form_defaults()
|
||||
schema = self._form_schema()
|
||||
|
|
@ -211,20 +245,18 @@ class IntegrationSettingsViewBase(object):
|
|||
|
||||
form = form or deform.Form(schema, appstruct=defaults, buttons=buttons)
|
||||
|
||||
template_context = {
|
||||
'form': form,
|
||||
'current_IntegrationType': self.IntegrationType,
|
||||
'integration': self.integration,
|
||||
'c': self._template_c_context(),
|
||||
}
|
||||
c.form = form
|
||||
c.current_IntegrationType = self.IntegrationType
|
||||
c.integration = self.integration
|
||||
|
||||
return template_context
|
||||
return self._get_template_context(c)
|
||||
|
||||
@auth.CSRFRequired()
|
||||
def settings_post(self):
|
||||
def _settings_post(self):
|
||||
"""
|
||||
View that validates and stores the integration settings.
|
||||
"""
|
||||
_ = self.request.translate
|
||||
|
||||
controls = self.request.POST.items()
|
||||
pstruct = peppercorn.parse(controls)
|
||||
|
||||
|
|
@ -264,7 +296,7 @@ class IntegrationSettingsViewBase(object):
|
|||
_('Errors exist when saving integration settings. '
|
||||
'Please check the form inputs.'),
|
||||
queue='error')
|
||||
return self.settings_get(form=e)
|
||||
return self._settings_get(form=e)
|
||||
|
||||
if not self.integration:
|
||||
self.integration = Integration()
|
||||
|
|
@ -314,77 +346,110 @@ class IntegrationSettingsViewBase(object):
|
|||
|
||||
return HTTPFound(redirect_to)
|
||||
|
||||
def index(self):
|
||||
""" List integrations """
|
||||
if self.repo:
|
||||
scope = self.repo
|
||||
elif self.repo_group:
|
||||
scope = self.repo_group
|
||||
else:
|
||||
scope = 'all'
|
||||
def _new_integration(self):
|
||||
c = self.load_default_context()
|
||||
c.available_integrations = integration_type_registry
|
||||
return self._get_template_context(c)
|
||||
|
||||
integrations = []
|
||||
|
||||
for IntType, integration in IntegrationModel().get_integrations(
|
||||
scope=scope, IntegrationType=self.IntegrationType):
|
||||
|
||||
# extra permissions check *just in case*
|
||||
if not self._has_perms_for_integration(integration):
|
||||
continue
|
||||
|
||||
integrations.append((IntType, integration))
|
||||
|
||||
sort_arg = self.request.GET.get('sort', 'name:asc')
|
||||
if ':' in sort_arg:
|
||||
sort_field, sort_dir = sort_arg.split(':')
|
||||
else:
|
||||
sort_field = sort_arg, 'asc'
|
||||
|
||||
assert sort_field in ('name', 'integration_type', 'enabled', 'scope')
|
||||
|
||||
integrations.sort(
|
||||
key=lambda x: getattr(x[1], sort_field),
|
||||
reverse=(sort_dir == 'desc'))
|
||||
|
||||
page_url = webhelpers.paginate.PageURL(
|
||||
self.request.path, self.request.GET)
|
||||
page = safe_int(self.request.GET.get('page', 1), 1)
|
||||
|
||||
integrations = Page(integrations, page=page, items_per_page=10,
|
||||
url=page_url)
|
||||
|
||||
template_context = {
|
||||
'sort_field': sort_field,
|
||||
'rev_sort_dir': sort_dir != 'desc' and 'desc' or 'asc',
|
||||
'current_IntegrationType': self.IntegrationType,
|
||||
'integrations_list': integrations,
|
||||
'available_integrations': integration_type_registry,
|
||||
'c': self._template_c_context(),
|
||||
'request': self.request,
|
||||
}
|
||||
return template_context
|
||||
|
||||
def new_integration(self):
|
||||
template_context = {
|
||||
'available_integrations': integration_type_registry,
|
||||
'c': self._template_c_context(),
|
||||
}
|
||||
return template_context
|
||||
def load_default_context(self):
|
||||
raise NotImplementedError()
|
||||
|
||||
|
||||
class GlobalIntegrationsView(IntegrationSettingsViewBase):
|
||||
def perm_check(self, user):
|
||||
return auth.HasPermissionAll('hg.admin').check_permissions(user=user)
|
||||
def load_default_context(self):
|
||||
c = self._get_local_tmpl_context()
|
||||
c.repo = self.repo
|
||||
c.repo_group = self.repo_group
|
||||
c.navlist = navigation_list(self.request)
|
||||
self._register_global_c(c)
|
||||
return c
|
||||
|
||||
@LoginRequired()
|
||||
@HasPermissionAnyDecorator('hg.admin')
|
||||
def integration_list(self):
|
||||
return self._integration_list()
|
||||
|
||||
@LoginRequired()
|
||||
@HasPermissionAnyDecorator('hg.admin')
|
||||
def settings_get(self):
|
||||
return self._settings_get()
|
||||
|
||||
@LoginRequired()
|
||||
@HasPermissionAnyDecorator('hg.admin')
|
||||
@CSRFRequired()
|
||||
def settings_post(self):
|
||||
return self._settings_post()
|
||||
|
||||
@LoginRequired()
|
||||
@HasPermissionAnyDecorator('hg.admin')
|
||||
def new_integration(self):
|
||||
return self._new_integration()
|
||||
|
||||
|
||||
class RepoIntegrationsView(IntegrationSettingsViewBase):
|
||||
def perm_check(self, user):
|
||||
return auth.HasRepoPermissionAll('repository.admin')(
|
||||
repo_name=self.repo.repo_name, user=user)
|
||||
def load_default_context(self):
|
||||
c = self._get_local_tmpl_context()
|
||||
|
||||
c.repo = self.repo
|
||||
c.repo_group = self.repo_group
|
||||
|
||||
# TODO(marcink): remove repo_info and use c.rhodecode_db_repo instead
|
||||
c.repo_info = self.db_repo = self.repo
|
||||
c.rhodecode_db_repo = self.repo
|
||||
c.repo_name = self.db_repo.repo_name
|
||||
c.repository_pull_requests = ScmModel().get_pull_requests(self.repo)
|
||||
|
||||
self._register_global_c(c)
|
||||
return c
|
||||
|
||||
@LoginRequired()
|
||||
@HasRepoPermissionAnyDecorator('repository.admin')
|
||||
def integration_list(self):
|
||||
return self._integration_list()
|
||||
|
||||
@LoginRequired()
|
||||
@HasRepoPermissionAnyDecorator('repository.admin')
|
||||
def settings_get(self):
|
||||
return self._settings_get()
|
||||
|
||||
@LoginRequired()
|
||||
@HasRepoPermissionAnyDecorator('repository.admin')
|
||||
@CSRFRequired()
|
||||
def settings_post(self):
|
||||
return self._settings_post()
|
||||
|
||||
@LoginRequired()
|
||||
@HasRepoPermissionAnyDecorator('repository.admin')
|
||||
def new_integration(self):
|
||||
return self._new_integration()
|
||||
|
||||
|
||||
class RepoGroupIntegrationsView(IntegrationSettingsViewBase):
|
||||
def perm_check(self, user):
|
||||
return auth.HasRepoGroupPermissionAll('group.admin')(
|
||||
group_name=self.repo_group.group_name, user=user)
|
||||
def load_default_context(self):
|
||||
c = self._get_local_tmpl_context()
|
||||
c.repo = self.repo
|
||||
c.repo_group = self.repo_group
|
||||
c.navlist = navigation_list(self.request)
|
||||
self._register_global_c(c)
|
||||
return c
|
||||
|
||||
@LoginRequired()
|
||||
@HasRepoGroupPermissionAnyDecorator('group.admin')
|
||||
def integration_list(self):
|
||||
return self._integration_list()
|
||||
|
||||
@LoginRequired()
|
||||
@HasRepoGroupPermissionAnyDecorator('group.admin')
|
||||
def settings_get(self):
|
||||
return self._settings_get()
|
||||
|
||||
@LoginRequired()
|
||||
@HasRepoGroupPermissionAnyDecorator('group.admin')
|
||||
@CSRFRequired()
|
||||
def settings_post(self):
|
||||
return self._settings_post()
|
||||
|
||||
@LoginRequired()
|
||||
@HasRepoGroupPermissionAnyDecorator('group.admin')
|
||||
def new_integration(self):
|
||||
return self._new_integration()
|
||||
|
|
|
|||
|
|
@ -23,13 +23,13 @@ function registerRCRoutes() {
|
|||
pyroutes.register('global_integrations_create', '/_admin/integrations/%(integration)s/new', ['integration']);
|
||||
pyroutes.register('global_integrations_edit', '/_admin/integrations/%(integration)s/%(integration_id)s', ['integration', 'integration_id']);
|
||||
pyroutes.register('repo_group_integrations_home', '/%(repo_group_name)s/settings/integrations', ['repo_group_name']);
|
||||
pyroutes.register('repo_group_integrations_list', '/%(repo_group_name)s/settings/integrations/%(integration)s', ['repo_group_name', 'integration']);
|
||||
pyroutes.register('repo_group_integrations_new', '/%(repo_group_name)s/settings/integrations/new', ['repo_group_name']);
|
||||
pyroutes.register('repo_group_integrations_list', '/%(repo_group_name)s/settings/integrations/%(integration)s', ['repo_group_name', 'integration']);
|
||||
pyroutes.register('repo_group_integrations_create', '/%(repo_group_name)s/settings/integrations/%(integration)s/new', ['repo_group_name', 'integration']);
|
||||
pyroutes.register('repo_group_integrations_edit', '/%(repo_group_name)s/settings/integrations/%(integration)s/%(integration_id)s', ['repo_group_name', 'integration', 'integration_id']);
|
||||
pyroutes.register('repo_integrations_home', '/%(repo_name)s/settings/integrations', ['repo_name']);
|
||||
pyroutes.register('repo_integrations_list', '/%(repo_name)s/settings/integrations/%(integration)s', ['repo_name', 'integration']);
|
||||
pyroutes.register('repo_integrations_new', '/%(repo_name)s/settings/integrations/new', ['repo_name']);
|
||||
pyroutes.register('repo_integrations_list', '/%(repo_name)s/settings/integrations/%(integration)s', ['repo_name', 'integration']);
|
||||
pyroutes.register('repo_integrations_create', '/%(repo_name)s/settings/integrations/%(integration)s/new', ['repo_name', 'integration']);
|
||||
pyroutes.register('repo_integrations_edit', '/%(repo_name)s/settings/integrations/%(integration)s/%(integration_id)s', ['repo_name', 'integration', 'integration_id']);
|
||||
pyroutes.register('ops_ping', '/_admin/ops/ping', []);
|
||||
|
|
|
|||
|
|
@ -7,10 +7,10 @@
|
|||
»
|
||||
${h.link_to(_('Integrations'),request.route_url(route_name='repo_integrations_home', repo_name=c.repo.repo_name))}
|
||||
»
|
||||
${h.link_to(current_IntegrationType.display_name,
|
||||
${h.link_to(c.current_IntegrationType.display_name,
|
||||
request.route_url(route_name='repo_integrations_list',
|
||||
repo_name=c.repo.repo_name,
|
||||
integration=current_IntegrationType.key))}
|
||||
integration=c.current_IntegrationType.key))}
|
||||
%elif c.repo_group:
|
||||
${h.link_to(_('Admin'),h.route_path('admin_home'))}
|
||||
»
|
||||
|
|
@ -20,10 +20,10 @@
|
|||
»
|
||||
${h.link_to(_('Integrations'),request.route_url(route_name='repo_group_integrations_home', repo_group_name=c.repo_group.group_name))}
|
||||
»
|
||||
${h.link_to(current_IntegrationType.display_name,
|
||||
${h.link_to(c.current_IntegrationType.display_name,
|
||||
request.route_url(route_name='repo_group_integrations_list',
|
||||
repo_group_name=c.repo_group.group_name,
|
||||
integration=current_IntegrationType.key))}
|
||||
integration=c.current_IntegrationType.key))}
|
||||
%else:
|
||||
${h.link_to(_('Admin'),h.route_path('admin_home'))}
|
||||
»
|
||||
|
|
@ -31,17 +31,17 @@
|
|||
»
|
||||
${h.link_to(_('Integrations'),request.route_url(route_name='global_integrations_home'))}
|
||||
»
|
||||
${h.link_to(current_IntegrationType.display_name,
|
||||
${h.link_to(c.current_IntegrationType.display_name,
|
||||
request.route_url(route_name='global_integrations_list',
|
||||
integration=current_IntegrationType.key))}
|
||||
integration=c.current_IntegrationType.key))}
|
||||
%endif
|
||||
|
||||
%if integration:
|
||||
%if c.integration:
|
||||
»
|
||||
${integration.name}
|
||||
%elif current_IntegrationType:
|
||||
${c.integration.name}
|
||||
%elif c.current_IntegrationType:
|
||||
»
|
||||
${current_IntegrationType.display_name}
|
||||
${c.current_IntegrationType.display_name}
|
||||
%endif
|
||||
</%def>
|
||||
|
||||
|
|
@ -54,16 +54,16 @@
|
|||
<div class="panel panel-default">
|
||||
<div class="panel-heading">
|
||||
<h2 class="panel-title">
|
||||
%if integration:
|
||||
${current_IntegrationType.display_name} - ${integration.name}
|
||||
%if c.integration:
|
||||
${c.current_IntegrationType.display_name} - ${c.integration.name}
|
||||
%else:
|
||||
${_('Create New %(integration_type)s Integration') % {
|
||||
'integration_type': current_IntegrationType.display_name
|
||||
'integration_type': c.current_IntegrationType.display_name
|
||||
}}
|
||||
%endif
|
||||
</h2>
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
${form.render() | n}
|
||||
${c.form.render() | n}
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -15,22 +15,22 @@
|
|||
»
|
||||
${h.link_to(_('Settings'),h.url('admin_settings'))}
|
||||
%endif
|
||||
%if current_IntegrationType:
|
||||
%if c.current_IntegrationType:
|
||||
»
|
||||
%if c.repo:
|
||||
${h.link_to(_('Integrations'),
|
||||
request.route_url(route_name='repo_integrations_home',
|
||||
repo_name=c.repo.repo_name))}
|
||||
request.route_path(route_name='repo_integrations_home',
|
||||
repo_name=c.repo.repo_name))}
|
||||
%elif c.repo_group:
|
||||
${h.link_to(_('Integrations'),
|
||||
request.route_url(route_name='repo_group_integrations_home',
|
||||
repo_group_name=c.repo_group.group_name))}
|
||||
request.route_path(route_name='repo_group_integrations_home',
|
||||
repo_group_name=c.repo_group.group_name))}
|
||||
%else:
|
||||
${h.link_to(_('Integrations'),
|
||||
request.route_url(route_name='global_integrations_home'))}
|
||||
request.route_path(route_name='global_integrations_home'))}
|
||||
%endif
|
||||
»
|
||||
${current_IntegrationType.display_name}
|
||||
${c.current_IntegrationType.display_name}
|
||||
%else:
|
||||
»
|
||||
${_('Integrations')}
|
||||
|
|
@ -61,9 +61,9 @@
|
|||
home_url = request.route_path('global_integrations_home')
|
||||
%>
|
||||
|
||||
<a href="${home_url}" class="btn ${not current_IntegrationType and 'btn-primary' or ''}">${_('All')}</a>
|
||||
<a href="${home_url}" class="btn ${not c.current_IntegrationType and 'btn-primary' or ''}">${_('All')}</a>
|
||||
|
||||
%for integration_key, IntegrationType in available_integrations.items():
|
||||
%for integration_key, IntegrationType in c.available_integrations.items():
|
||||
<%
|
||||
if c.repo:
|
||||
list_url = request.route_path('repo_integrations_list',
|
||||
|
|
@ -78,12 +78,14 @@
|
|||
integration=integration_key)
|
||||
%>
|
||||
<a href="${list_url}"
|
||||
class="btn ${current_IntegrationType and integration_key == current_IntegrationType.key and 'btn-primary' or ''}">
|
||||
class="btn ${c.current_IntegrationType and integration_key == c.current_IntegrationType.key and 'btn-primary' or ''}">
|
||||
${IntegrationType.display_name}
|
||||
</a>
|
||||
%endfor
|
||||
|
||||
<%
|
||||
integration_type = c.current_IntegrationType and c.current_IntegrationType.display_name or ''
|
||||
|
||||
if c.repo:
|
||||
create_url = h.route_path('repo_integrations_new', repo_name=c.repo.repo_name)
|
||||
elif c.repo_group:
|
||||
|
|
@ -98,19 +100,19 @@
|
|||
<table class="rctable integrations">
|
||||
<thead>
|
||||
<tr>
|
||||
<th><a href="?sort=enabled:${rev_sort_dir}">${_('Enabled')}</a></th>
|
||||
<th><a href="?sort=name:${rev_sort_dir}">${_('Name')}</a></th>
|
||||
<th colspan="2"><a href="?sort=integration_type:${rev_sort_dir}">${_('Type')}</a></th>
|
||||
<th><a href="?sort=scope:${rev_sort_dir}">${_('Scope')}</a></th>
|
||||
<th><a href="?sort=enabled:${c.rev_sort_dir}">${_('Enabled')}</a></th>
|
||||
<th><a href="?sort=name:${c.rev_sort_dir}">${_('Name')}</a></th>
|
||||
<th colspan="2"><a href="?sort=integration_type:${c.rev_sort_dir}">${_('Type')}</a></th>
|
||||
<th><a href="?sort=scope:${c.rev_sort_dir}">${_('Scope')}</a></th>
|
||||
<th>${_('Actions')}</th>
|
||||
<th></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
%if not integrations_list:
|
||||
%if not c.integrations_list:
|
||||
<tr>
|
||||
<td colspan="7">
|
||||
<% integration_type = current_IntegrationType and current_IntegrationType.display_name or '' %>
|
||||
|
||||
%if c.repo:
|
||||
${_('No {type} integrations for repo {repo} exist yet.').format(type=integration_type, repo=c.repo.repo_name)}
|
||||
%elif c.repo_group:
|
||||
|
|
@ -119,14 +121,14 @@
|
|||
${_('No {type} integrations exist yet.').format(type=integration_type)}
|
||||
%endif
|
||||
|
||||
%if current_IntegrationType:
|
||||
%if c.current_IntegrationType:
|
||||
<%
|
||||
if c.repo:
|
||||
create_url = h.route_path('repo_integrations_create', repo_name=c.repo.repo_name, integration=current_IntegrationType.key)
|
||||
create_url = h.route_path('repo_integrations_create', repo_name=c.repo.repo_name, integration=c.current_IntegrationType.key)
|
||||
elif c.repo_group:
|
||||
create_url = h.route_path('repo_group_integrations_create', repo_group_name=c.repo_group.group_name, integration=current_IntegrationType.key)
|
||||
create_url = h.route_path('repo_group_integrations_create', repo_group_name=c.repo_group.group_name, integration=c.current_IntegrationType.key)
|
||||
else:
|
||||
create_url = h.route_path('global_integrations_create', integration=current_IntegrationType.key)
|
||||
create_url = h.route_path('global_integrations_create', integration=c.current_IntegrationType.key)
|
||||
%>
|
||||
%endif
|
||||
|
||||
|
|
@ -134,7 +136,7 @@
|
|||
</td>
|
||||
</tr>
|
||||
%endif
|
||||
%for IntegrationType, integration in integrations_list:
|
||||
%for IntegrationType, integration in c.integrations_list:
|
||||
<tr id="integration_${integration.integration_id}">
|
||||
<td class="td-enabled">
|
||||
%if integration.enabled:
|
||||
|
|
@ -147,9 +149,9 @@
|
|||
${integration.name}
|
||||
</td>
|
||||
<td class="td-icon">
|
||||
%if integration.integration_type in available_integrations:
|
||||
%if integration.integration_type in c.available_integrations:
|
||||
<div class="integration-icon">
|
||||
${available_integrations[integration.integration_type].icon|n}
|
||||
${c.available_integrations[integration.integration_type].icon|n}
|
||||
</div>
|
||||
%else:
|
||||
?
|
||||
|
|
@ -220,7 +222,7 @@
|
|||
</table>
|
||||
<div class="integrations-paginator">
|
||||
<div class="pagination-wh pagination-left">
|
||||
${integrations_list.pager('$link_previous ~2~ $link_next')}
|
||||
${c.integrations_list.pager('$link_previous ~2~ $link_next')}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@
|
|||
%endif
|
||||
</%def>
|
||||
|
||||
%for integration, IntegrationType in available_integrations.items():
|
||||
%for integration, IntegrationType in c.available_integrations.items():
|
||||
<%
|
||||
if c.repo:
|
||||
create_url = request.route_path('repo_integrations_create',
|
||||
|
|
|
|||
|
|
@ -25,21 +25,21 @@ from rhodecode import events
|
|||
from rhodecode.tests.fixture import Fixture
|
||||
from rhodecode.model.db import Session, Integration
|
||||
from rhodecode.model.integration import IntegrationModel
|
||||
from rhodecode.integrations.types.base import IntegrationTypeBase
|
||||
|
||||
|
||||
class TestDeleteScopesDeletesIntegrations(object):
|
||||
def test_delete_repo_with_integration_deletes_integration(self,
|
||||
repo_integration_stub):
|
||||
def test_delete_repo_with_integration_deletes_integration(
|
||||
self, repo_integration_stub):
|
||||
|
||||
Session().delete(repo_integration_stub.repo)
|
||||
Session().commit()
|
||||
Session().expire_all()
|
||||
integration = Integration.get(repo_integration_stub.integration_id)
|
||||
assert integration is None
|
||||
|
||||
def test_delete_repo_group_with_integration_deletes_integration(
|
||||
self, repogroup_integration_stub):
|
||||
|
||||
def test_delete_repo_group_with_integration_deletes_integration(self,
|
||||
repogroup_integration_stub):
|
||||
Session().delete(repogroup_integration_stub.repo_group)
|
||||
Session().commit()
|
||||
Session().expire_all()
|
||||
|
|
@ -146,7 +146,6 @@ def test_enabled_integration_repo_scopes(integration_repos):
|
|||
integrations['root_repo'],
|
||||
]
|
||||
|
||||
|
||||
triggered_integrations = IntegrationModel().get_for_event(
|
||||
events.RepoEvent(repos['other_repo']))
|
||||
|
||||
|
|
@ -157,7 +156,6 @@ def test_enabled_integration_repo_scopes(integration_repos):
|
|||
integrations['other_group_recursive'],
|
||||
]
|
||||
|
||||
|
||||
triggered_integrations = IntegrationModel().get_for_event(
|
||||
events.RepoEvent(repos['parent_repo']))
|
||||
|
||||
|
|
@ -193,26 +191,22 @@ def test_disabled_integration_repo_scopes(integration_repos):
|
|||
|
||||
assert triggered_integrations == []
|
||||
|
||||
|
||||
triggered_integrations = IntegrationModel().get_for_event(
|
||||
events.RepoEvent(repos['parent_repo']))
|
||||
|
||||
assert triggered_integrations == []
|
||||
|
||||
|
||||
triggered_integrations = IntegrationModel().get_for_event(
|
||||
events.RepoEvent(repos['child_repo']))
|
||||
|
||||
assert triggered_integrations == []
|
||||
|
||||
|
||||
triggered_integrations = IntegrationModel().get_for_event(
|
||||
events.RepoEvent(repos['other_repo']))
|
||||
|
||||
assert triggered_integrations == []
|
||||
|
||||
|
||||
|
||||
def test_enabled_non_repo_integrations(integration_repos):
|
||||
integrations = integration_repos['integrations']
|
||||
|
||||
|
|
|
|||
|
|
@ -336,7 +336,7 @@ def test_repo_group(request):
|
|||
usage automatically
|
||||
"""
|
||||
fixture = Fixture()
|
||||
repogroupid = 'test_repo_group_%s' % int(time.time())
|
||||
repogroupid = 'test_repo_group_%s' % str(time.time()).replace('.', '')
|
||||
repo_group = fixture.create_repo_group(repogroupid)
|
||||
|
||||
def _cleanup():
|
||||
|
|
@ -353,7 +353,7 @@ def test_user_group(request):
|
|||
usage automatically
|
||||
"""
|
||||
fixture = Fixture()
|
||||
usergroupid = 'test_user_group_%s' % int(time.time())
|
||||
usergroupid = 'test_user_group_%s' % str(time.time()).replace('.', '')
|
||||
user_group = fixture.create_user_group(usergroupid)
|
||||
|
||||
def _cleanup():
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue