diff --git a/rhodecode/apps/_base/__init__.py b/rhodecode/apps/_base/__init__.py --- a/rhodecode/apps/_base/__init__.py +++ b/rhodecode/apps/_base/__init__.py @@ -250,12 +250,21 @@ class BaseReferencesView(RepoAppView): # TODO: johbo: Unify generation of reference links use_commit_id = '/' in ref_name or is_svn - files_url = h.url( - 'files_home', - repo_name=self.db_repo_name, - f_path=ref_name if is_svn else '', - revision=commit_id if use_commit_id else ref_name, - at=ref_name) + + if use_commit_id: + files_url = h.route_path( + 'repo_files', + repo_name=self.db_repo_name, + f_path=ref_name if is_svn else '', + commit_id=commit_id) + + else: + files_url = h.route_path( + 'repo_files', + repo_name=self.db_repo_name, + f_path=ref_name if is_svn else '', + commit_id=ref_name, + _query=dict(at=ref_name)) data.append({ "name": _render('name', ref_name, files_url, closed), diff --git a/rhodecode/apps/repository/__init__.py b/rhodecode/apps/repository/__init__.py --- a/rhodecode/apps/repository/__init__.py +++ b/rhodecode/apps/repository/__init__.py @@ -37,6 +37,95 @@ def includeme(config): name='repo_commit', pattern='/{repo_name:.*?[^/]}/changeset/{commit_id}', repo_route=True) + # repo files + config.add_route( + name='repo_archivefile', + pattern='/{repo_name:.*?[^/]}/archive/{fname}', repo_route=True) + + config.add_route( + name='repo_files_diff', + pattern='/{repo_name:.*?[^/]}/diff/{f_path:.*}', repo_route=True) + config.add_route( # legacy route to make old links work + name='repo_files_diff_2way_redirect', + pattern='/{repo_name:.*?[^/]}/diff-2way/{f_path:.*}', repo_route=True) + + config.add_route( + name='repo_files', + pattern='/{repo_name:.*?[^/]}/files/{commit_id}/{f_path:.*}', repo_route=True) + config.add_route( + name='repo_files:default_path', + pattern='/{repo_name:.*?[^/]}/files/{commit_id}/', repo_route=True) + config.add_route( + name='repo_files:default_commit', + pattern='/{repo_name:.*?[^/]}/files', repo_route=True) + + config.add_route( + name='repo_files:rendered', + pattern='/{repo_name:.*?[^/]}/render/{commit_id}/{f_path:.*}', repo_route=True) + + config.add_route( + name='repo_files:annotated', + pattern='/{repo_name:.*?[^/]}/annotate/{commit_id}/{f_path:.*}', repo_route=True) + config.add_route( + name='repo_files:annotated_previous', + pattern='/{repo_name:.*?[^/]}/annotate-previous/{commit_id}/{f_path:.*}', repo_route=True) + + config.add_route( + name='repo_nodetree_full', + pattern='/{repo_name:.*?[^/]}/nodetree_full/{commit_id}/{f_path:.*}', repo_route=True) + config.add_route( + name='repo_nodetree_full:default_path', + pattern='/{repo_name:.*?[^/]}/nodetree_full/{commit_id}/', repo_route=True) + + config.add_route( + name='repo_files_nodelist', + pattern='/{repo_name:.*?[^/]}/nodelist/{commit_id}/{f_path:.*}', repo_route=True) + + config.add_route( + name='repo_file_raw', + pattern='/{repo_name:.*?[^/]}/raw/{commit_id}/{f_path:.*}', repo_route=True) + + config.add_route( + name='repo_file_download', + pattern='/{repo_name:.*?[^/]}/download/{commit_id}/{f_path:.*}', repo_route=True) + config.add_route( # backward compat to keep old links working + name='repo_file_download:legacy', + pattern='/{repo_name:.*?[^/]}/rawfile/{commit_id}/{f_path:.*}', + repo_route=True) + + config.add_route( + name='repo_file_history', + pattern='/{repo_name:.*?[^/]}/history/{commit_id}/{f_path:.*}', repo_route=True) + + config.add_route( + name='repo_file_authors', + pattern='/{repo_name:.*?[^/]}/authors/{commit_id}/{f_path:.*}', repo_route=True) + + config.add_route( + name='repo_files_remove_file', + pattern='/{repo_name:.*?[^/]}/remove_file/{commit_id}/{f_path:.*}', + repo_route=True) + config.add_route( + name='repo_files_delete_file', + pattern='/{repo_name:.*?[^/]}/delete_file/{commit_id}/{f_path:.*}', + repo_route=True) + config.add_route( + name='repo_files_edit_file', + pattern='/{repo_name:.*?[^/]}/edit_file/{commit_id}/{f_path:.*}', + repo_route=True) + config.add_route( + name='repo_files_update_file', + pattern='/{repo_name:.*?[^/]}/update_file/{commit_id}/{f_path:.*}', + repo_route=True) + config.add_route( + name='repo_files_add_file', + pattern='/{repo_name:.*?[^/]}/add_file/{commit_id}/{f_path:.*}', + repo_route=True) + config.add_route( + name='repo_files_create_file', + pattern='/{repo_name:.*?[^/]}/create_file/{commit_id}/{f_path:.*}', + repo_route=True) + # refs data config.add_route( name='repo_refs_data', diff --git a/rhodecode/tests/functional/test_files.py b/rhodecode/apps/repository/tests/test_repo_files.py rename from rhodecode/tests/functional/test_files.py rename to rhodecode/apps/repository/tests/test_repo_files.py --- a/rhodecode/tests/functional/test_files.py +++ b/rhodecode/apps/repository/tests/test_repo_files.py @@ -23,15 +23,14 @@ import os import mock import pytest -from rhodecode.controllers.files import FilesController +from rhodecode.apps.repository.views.repo_files import RepoFilesView from rhodecode.lib import helpers as h from rhodecode.lib.compat import OrderedDict from rhodecode.lib.ext_json import json from rhodecode.lib.vcs import nodes from rhodecode.lib.vcs.conf import settings -from rhodecode.tests import ( - url, assert_session_flash, assert_not_in_session_flash) +from rhodecode.tests import assert_session_flash from rhodecode.tests.fixture import Fixture fixture = Fixture() @@ -43,14 +42,71 @@ NODE_HISTORY = { } +def route_path(name, params=None, **kwargs): + import urllib + + base_url = { + 'repo_archivefile': '/{repo_name}/archive/{fname}', + 'repo_files_diff': '/{repo_name}/diff/{f_path}', + 'repo_files_diff_2way_redirect': '/{repo_name}/diff-2way/{f_path}', + 'repo_files': '/{repo_name}/files/{commit_id}/{f_path}', + 'repo_files:default_path': '/{repo_name}/files/{commit_id}/', + 'repo_files:default_commit': '/{repo_name}/files', + 'repo_files:rendered': '/{repo_name}/render/{commit_id}/{f_path}', + 'repo_files:annotated': '/{repo_name}/annotate/{commit_id}/{f_path}', + 'repo_files:annotated_previous': '/{repo_name}/annotate-previous/{commit_id}/{f_path}', + 'repo_files_nodelist': '/{repo_name}/nodelist/{commit_id}/{f_path}', + 'repo_file_raw': '/{repo_name}/raw/{commit_id}/{f_path}', + 'repo_file_download': '/{repo_name}/download/{commit_id}/{f_path}', + 'repo_file_history': '/{repo_name}/history/{commit_id}/{f_path}', + 'repo_file_authors': '/{repo_name}/authors/{commit_id}/{f_path}', + 'repo_files_remove_file': '/{repo_name}/remove_file/{commit_id}/{f_path}', + 'repo_files_delete_file': '/{repo_name}/delete_file/{commit_id}/{f_path}', + 'repo_files_edit_file': '/{repo_name}/edit_file/{commit_id}/{f_path}', + 'repo_files_update_file': '/{repo_name}/update_file/{commit_id}/{f_path}', + 'repo_files_add_file': '/{repo_name}/add_file/{commit_id}/{f_path}', + 'repo_files_create_file': '/{repo_name}/create_file/{commit_id}/{f_path}', + 'repo_nodetree_full': '/{repo_name}/nodetree_full/{commit_id}/{f_path}', + 'repo_nodetree_full:default_path': '/{repo_name}/nodetree_full/{commit_id}/', + }[name].format(**kwargs) + + if params: + base_url = '{}?{}'.format(base_url, urllib.urlencode(params)) + return base_url + + +def assert_files_in_response(response, files, params): + template = ( + 'href="/%(repo_name)s/files/%(commit_id)s/%(name)s"') + _assert_items_in_response(response, files, template, params) + + +def assert_dirs_in_response(response, dirs, params): + template = ( + 'href="/%(repo_name)s/files/%(commit_id)s/%(name)s"') + _assert_items_in_response(response, dirs, template, params) + + +def _assert_items_in_response(response, items, template, params): + for item in items: + item_params = {'name': item} + item_params.update(params) + response.mustcontain(template % item_params) + + +def assert_timeago_in_response(response, items, params): + for item in items: + response.mustcontain(h.age_component(params['date'])) + @pytest.mark.usefixtures("app") -class TestFilesController: +class TestFilesViews(object): - def test_index(self, backend): - response = self.app.get(url( - controller='files', action='index', - repo_name=backend.repo_name, revision='tip', f_path='/')) + def test_show_files(self, backend): + response = self.app.get( + route_path('repo_files', + repo_name=backend.repo_name, + commit_id='tip', f_path='/')) commit = backend.repo.get_commit() params = { @@ -77,21 +133,23 @@ class TestFilesController: assert_files_in_response(response, files, params) assert_timeago_in_response(response, files, params) - def test_index_links_submodules_with_absolute_url(self, backend_hg): + def test_show_files_links_submodules_with_absolute_url(self, backend_hg): repo = backend_hg['subrepos'] - response = self.app.get(url( - controller='files', action='index', - repo_name=repo.repo_name, revision='tip', f_path='/')) + response = self.app.get( + route_path('repo_files', + repo_name=repo.repo_name, + commit_id='tip', f_path='/')) assert_response = response.assert_response() assert_response.contains_one_link( 'absolute-path @ 000000000000', 'http://example.com/absolute-path') - def test_index_links_submodules_with_absolute_url_subpaths( + def test_show_files_links_submodules_with_absolute_url_subpaths( self, backend_hg): repo = backend_hg['subrepos'] - response = self.app.get(url( - controller='files', action='index', - repo_name=repo.repo_name, revision='tip', f_path='/')) + response = self.app.get( + route_path('repo_files', + repo_name=repo.repo_name, + commit_id='tip', f_path='/')) assert_response = response.assert_response() assert_response.contains_one_link( 'subpaths-path @ 000000000000', @@ -108,29 +166,29 @@ class TestFilesController: backend.repo.landing_rev = "branch:%s" % new_branch - # get response based on tip and not new revision - response = self.app.get(url( - controller='files', action='index', - repo_name=backend.repo_name, revision='tip', f_path='/'), - status=200) + # get response based on tip and not new commit + response = self.app.get( + route_path('repo_files', + repo_name=backend.repo_name, + commit_id='tip', f_path='/')) - # make sure Files menu url is not tip but new revision + # make sure Files menu url is not tip but new commit landing_rev = backend.repo.landing_rev[1] - files_url = url('files_home', repo_name=backend.repo_name, - revision=landing_rev) + files_url = route_path('repo_files:default_path', + repo_name=backend.repo_name, + commit_id=landing_rev) assert landing_rev != 'tip' - response.mustcontain('