From 91a731620ef9ef1e6ea06b1490530daa19d44033 Mon Sep 17 00:00:00 2001 From: ievgenii vdovenko Date: Fri, 1 Aug 2025 13:20:41 +0200 Subject: [PATCH] tests: fixes existing tests; adds tests for forks detach\delete --- rhodecode/api/tests/test_delete_repo.py | 45 +++++++++++++++++++ rhodecode/api/tests/utils.py | 2 +- rhodecode/api/views/repo_api.py | 17 ++++--- .../tests/test_repo_settings_advanced.py | 10 +++-- .../views/repo_settings_advanced.py | 2 +- 5 files changed, 64 insertions(+), 12 deletions(-) diff --git a/rhodecode/api/tests/test_delete_repo.py b/rhodecode/api/tests/test_delete_repo.py index 8893d136..f73593c4 100644 --- a/rhodecode/api/tests/test_delete_repo.py +++ b/rhodecode/api/tests/test_delete_repo.py @@ -19,6 +19,8 @@ import mock import pytest +from rhodecode.model.db import Repository +from rhodecode.model.meta import Session from rhodecode.model.repo import RepoModel from rhodecode.api.tests.utils import build_data, api_call, assert_error, assert_ok, crash @@ -27,6 +29,9 @@ from rhodecode.api.tests.utils import build_data, api_call, assert_error, assert class TestApiDeleteRepo(object): def test_api_delete_repo(self, backend): repo = backend.create_repo() + repo.private = True + Session().commit() + repo_name = repo.repo_name id_, params = build_data( self.apikey, @@ -38,6 +43,46 @@ class TestApiDeleteRepo(object): expected = {"msg": "Deleted repository `%s`" % (repo_name,), "success": True} assert_ok(id_, expected, given=response.body) + @pytest.mark.parametrize( + "fork_action, expected_fork_msg", + [ + ("detach", "Detached 1 forks"), + ("delete", "Deleted 1 forks"), + ], + ) + def test_api_delete_repo_with_forks(self, backend, fork_action, expected_fork_msg): + repo = backend.create_repo() + repo.private = True + fork = backend.create_fork() + fork_name = fork.repo_name + Session().commit() + + assert fork.parent is not None + + repo_name = repo.repo_name + id_, params = build_data( + self.apikey, + "delete_repo", + repoid=repo.repo_name, + forks=fork_action, + ) + response = api_call(self.app, params) + + expected = { + "msg": "Deleted repository `%s` %s; NOTE: 'forks' option will be deprecated." + % (repo_name, expected_fork_msg), + "success": True, + } + assert_ok(id_, expected, given=response.body) + self._validate_fork_db_state(fork_action, fork_name) + + def _validate_fork_db_state(self, fork_action, fork_name): + fork = Repository.get_by_repo_name(repo_name=fork_name) + if fork_action == "detach": + assert fork.parent is None + elif fork_action == "delete": + assert fork is None + def test_api_delete_repo_by_non_admin(self, backend, user_regular): repo = backend.create_repo(cur_user=user_regular.username) repo_name = repo.repo_name diff --git a/rhodecode/api/tests/utils.py b/rhodecode/api/tests/utils.py index 930f898d..138df62a 100644 --- a/rhodecode/api/tests/utils.py +++ b/rhodecode/api/tests/utils.py @@ -48,7 +48,7 @@ def assert_ok(id_, expected, given): expected = jsonify({"id": id_, "error": None, "result": expected}) - assert expected == given + assert expected == given, "Expected: %s, Given: %s" % (expected, given) def assert_error(id_, expected, given): diff --git a/rhodecode/api/views/repo_api.py b/rhodecode/api/views/repo_api.py index 4da17e7b..cee7e38b 100644 --- a/rhodecode/api/views/repo_api.py +++ b/rhodecode/api/views/repo_api.py @@ -1359,21 +1359,19 @@ def delete_repo(request, apiuser, repoid, forks=Optional("")): _perms = ("repository.admin",) validate_repo_permissions(apiuser, repoid, repo, _perms) - deprecation_warning = "NOTE: 'forks' option will be deprecated." - try: - handle_forks = Optional.extract(forks) + str_fork_action = Optional.extract(forks) _forks_msg = "" _forks = [f for f in repo.forks] - if handle_forks == "detach": + if str_fork_action == "detach": _forks_msg = " " + f"Detached {len(_forks)} forks" - elif handle_forks == "delete": + elif str_fork_action == "delete": _forks_msg = " " + f"Deleted {len(_forks)} forks" elif _forks: raise JSONRPCError(f"Cannot delete `{repo.repo_name}` it still contains attached forks") old_data = repo.get_api_data() - RepoModel().delete(repo, forks_action=ForksAction(handle_forks)) + RepoModel().delete(repo, forks_action=ForksAction(str_fork_action)) repo = audit_logger.RepoWrap(repo_id=None, repo_name=repo.repo_name) @@ -1381,7 +1379,12 @@ def delete_repo(request, apiuser, repoid, forks=Optional("")): ScmModel().mark_for_invalidation(repo_name, delete=True) Session().commit() - return {"msg": f"Deleted repository `{repo_name}`{_forks_msg}; {deprecation_warning}", "success": True} + res_message = {"msg": f"Deleted repository `{repo_name}`{_forks_msg}", "success": True} + if str_fork_action: + deprecation_warning = "; NOTE: 'forks' option will be deprecated." + res_message["msg"] += deprecation_warning + + return res_message except Exception: log.exception("Exception occurred while trying to delete repo") raise JSONRPCError(f"failed to delete repository `{repo_name}`") diff --git a/rhodecode/apps/repository/tests/test_repo_settings_advanced.py b/rhodecode/apps/repository/tests/test_repo_settings_advanced.py index b32a9cad..9d1d3124 100644 --- a/rhodecode/apps/repository/tests/test_repo_settings_advanced.py +++ b/rhodecode/apps/repository/tests/test_repo_settings_advanced.py @@ -21,7 +21,8 @@ from unittest.mock import patch, MagicMock from rhodecode.apps.repository.views.repo_settings_advanced import RepoSettingsAdvancedView from rhodecode.lib.str_utils import safe_str from rhodecode.model.db import Repository -from rhodecode.model.repo import RepoModel +from rhodecode.model.meta import Session +from rhodecode.model.repo import RepoModel, ForksAction from rhodecode.tests import HG_REPO, GIT_REPO, assert_session_flash, no_newline_id_generator from rhodecode.tests.fixtures.rc_fixture import Fixture from rhodecode.tests.utils import repo_on_filesystem @@ -61,7 +62,7 @@ class TestAdminRepoSettingsAdvanced(object): response.mustcontain(opt) - fixture.destroy_repo(target_repo, forks="detach") + fixture.destroy_repo(target_repo, forks_action=ForksAction.DETACH) @pytest.mark.backends("hg", "git") def test_set_fork_of_other_type_repo(self, autologin_user, backend, csrf_token): @@ -97,7 +98,10 @@ class TestAdminRepoSettingsAdvanced(object): @pytest.mark.parametrize("suffix", ["", "ąęł", "123"], ids=no_newline_id_generator) def test_advanced_repo_delete(self, autologin_user, backend, suffix, csrf_token): - repo = backend.create_repo(name_suffix=suffix) + repo = backend.create_repo(name_suffix=suffix, private_repo=True) + repo.private = True + Session().commit() + repo_name = repo.repo_name repo_name_str = safe_str(repo.repo_name) diff --git a/rhodecode/apps/repository/views/repo_settings_advanced.py b/rhodecode/apps/repository/views/repo_settings_advanced.py index f47934ea..82b45f0b 100644 --- a/rhodecode/apps/repository/views/repo_settings_advanced.py +++ b/rhodecode/apps/repository/views/repo_settings_advanced.py @@ -148,7 +148,7 @@ class RepoSettingsAdvancedView(RepoAppView): fork_action = delete_res.fork_action_result.action fork_cnt = delete_res.fork_action_result.fork_count - if fork_action is not None: + if fork_cnt > 0 and fork_action is not None: if fork_action is ForksAction.DETACH: h.flash(_("Detached %s forks") % fork_cnt, category="success") elif fork_action is ForksAction.DELETE: