From 3a843bc7de2cd2340b8fc60b355816e06795c457 Mon Sep 17 00:00:00 2001 From: Jakub Kadlcik Date: Mon, 7 Oct 2024 11:15:02 +0200 Subject: [PATCH] frontend: move repo functions to a separate file To avoid circular dependencies when we introduce some database queries to them. --- frontend/coprs_frontend/coprs/helpers.py | 133 +--------------- .../coprs/logic/complex_logic.py | 16 +- frontend/coprs_frontend/coprs/repos.py | 146 ++++++++++++++++++ .../coprs/views/apiv3_ns/apiv3_rpmrepo.py | 6 +- .../coprs/views/coprs_ns/coprs_general.py | 15 +- frontend/coprs_frontend/tests/test_helpers.py | 100 +----------- frontend/coprs_frontend/tests/test_repos.py | 102 ++++++++++++ .../test_coprs_ns/test_coprs_general.py | 2 +- 8 files changed, 278 insertions(+), 242 deletions(-) create mode 100644 frontend/coprs_frontend/coprs/repos.py create mode 100644 frontend/coprs_frontend/tests/test_repos.py diff --git a/frontend/coprs_frontend/coprs/helpers.py b/frontend/coprs_frontend/coprs/helpers.py index b717c02a1..5426cd4e3 100644 --- a/frontend/coprs_frontend/coprs/helpers.py +++ b/frontend/coprs_frontend/coprs/helpers.py @@ -6,10 +6,9 @@ import random import string import json -import posixpath import re from os.path import normpath -from urllib.parse import urlparse, parse_qs, urlunparse, urlencode +from urllib.parse import urlparse, urlencode import html5_parser @@ -337,32 +336,6 @@ def parse_package_name(pkg): return pkg -def generate_repo_url(mock_chroot, url, arch=None): - """ Generates url with build results for .repo file. - No checks if copr or mock_chroot exists. - """ - os_version = mock_chroot.os_version - - if mock_chroot.os_release == "fedora": - os_version = "$releasever" - - if mock_chroot.os_release == "centos-stream": - os_version = "$releasever" - - if mock_chroot.os_release == "opensuse-leap": - os_version = "$releasever" - - if mock_chroot.os_release == "mageia": - if mock_chroot.os_version != "cauldron": - os_version = "$releasever" - - url = posixpath.join( - url, "{0}-{1}-{2}/".format(mock_chroot.os_release, - os_version, arch or '$basearch')) - - return url - - def fix_protocol_for_backend(url): """ Ensure that url either has http or https protocol according to the @@ -585,70 +558,6 @@ def stream_template(template_name, **context): return rv -def generate_repo_name(repo_url): - """ based on url, generate repo name """ - repo_url = re.sub("[^a-zA-Z0-9]", '_', repo_url) - repo_url = re.sub("(__*)", '_', repo_url) - repo_url = re.sub("(_*$)|^_*", '', repo_url) - return repo_url - - -def is_copr_repo(repo_url): - return copr_repo_fullname(repo_url) is not None - - -def copr_repo_fullname(repo_url): - parsed_url = urlparse(repo_url) - query = parse_qs(parsed_url.query) - if parsed_url.scheme != "copr": - return None - return parsed_url.netloc + parsed_url.path - - -def pre_process_repo_url(chroot, repo_url): - """ - Expands variables and sanitize repo url to be used for mock config - """ - parsed_url = urlparse(repo_url) - query = parse_qs(parsed_url.query) - - if parsed_url.scheme == "copr": - user = parsed_url.netloc - prj = parsed_url.path.split("/")[1] - repo_url = "/".join([ - flask.current_app.config["BACKEND_BASE_URL"], - "results", user, prj, chroot - ]) + "/" - - elif "priority" in query: - query.pop("priority") - query_string = urlencode(query, doseq=True) - parsed_url = parsed_url._replace(query=query_string) - repo_url = urlunparse(parsed_url) - - repo_url = repo_url.replace("$chroot", chroot) - repo_url = repo_url.replace("$distname", chroot.rsplit("-", 2)[0]) - return repo_url - - -def parse_repo_params(repo, supported_keys=None): - """ - :param repo: str repo from Copr/CoprChroot/Build/... - :param supported_keys list of supported optional parameters - :return: dict of optional parameters parsed from the repo URL - """ - supported_keys = supported_keys or ["priority"] - params = {} - qs = parse_qs(urlparse(repo).query) - for k, v in qs.items(): - if k in supported_keys: - # parse_qs returns values as lists, but we allow setting the param only once, - # so we can take just first value from it - value = int(v[0]) if v[0].isnumeric() else v[0] - params[k] = value - return params - - def trim_git_url(url): if not url: return None @@ -891,43 +800,3 @@ def being_server_admin(user, copr): return False return True - - -def generate_repo_id_and_name(copr, copr_dir_name, multilib=False, dep_idx=None, - dependent=None): - """ - Return (repo_id, repo_name) for a given copr. If multilib is True, the - rpeo_id has a specific suffix, if the repo is dependency of the dependend, - the repo_id has a specific prefix. - """ - repo_id = "{0}:{1}:{2}:{3}{4}".format( - "coprdep" if dep_idx else "copr", - app.config["PUBLIC_COPR_HOSTNAME"].split(":")[0], - copr.owner_name.replace("@", "group_"), - copr_dir_name, - ":ml" if multilib else "" - ) - - if dep_idx and dependent: - name = "Copr {0}/{1}/{2} runtime dependency #{3} - {4}/{5}".format( - app.config["PUBLIC_COPR_HOSTNAME"].split(":")[0], - dependent.owner_name, dependent.name, dep_idx, - copr.owner_name, copr_dir_name - ) - else: - name = "Copr repo for {0} owned by {1}".format(copr_dir_name, - copr.owner_name) - return repo_id, name - -def generate_repo_id_and_name_ext(dependent, url, dep_idx): - """ - Return (repo_id, repo_name) pair according to the repo URL and what - DEPENDENT repository we depend on. - """ - repo_id = "coprdep:{0}".format(generate_repo_name(url)) - name = "Copr {0}/{1}/{2} external runtime dependency #{3} - {4}".format( - app.config["PUBLIC_COPR_HOSTNAME"].split(":")[0], - dependent.owner_name, dependent.name, dep_idx, - generate_repo_name(url), - ) - return repo_id, name diff --git a/frontend/coprs_frontend/coprs/logic/complex_logic.py b/frontend/coprs_frontend/coprs/logic/complex_logic.py index acd230b35..992771597 100644 --- a/frontend/coprs_frontend/coprs/logic/complex_logic.py +++ b/frontend/coprs_frontend/coprs/logic/complex_logic.py @@ -17,6 +17,12 @@ from coprs import cache from coprs.constants import DEFAULT_COPR_REPO_PRIORITY from coprs.exceptions import ObjectNotFound +from coprs.repos import ( + copr_repo_fullname, + parse_repo_params, + generate_repo_name, + pre_process_repo_url, +) from coprs.logic.builds_logic import BuildsLogic from coprs.logic.batches_logic import BatchesLogic from coprs.logic.packages_logic import PackagesLogic @@ -247,7 +253,7 @@ def get_copr_by_repo(repo_url): ObjectNotFound to the API if no such Copr (group) result was found in database. """ - copr_repo = helpers.copr_repo_fullname(repo_url) + copr_repo = copr_repo_fullname(repo_url) if not copr_repo: return None try: @@ -667,11 +673,11 @@ def get_build_isolation(cls, build_config, build): def get_additional_repo_views(cls, repos_list, chroot_id): repos = [] for repo in repos_list: - params = helpers.parse_repo_params(repo) + params = parse_repo_params(repo) repo_view = { - "id": helpers.generate_repo_name(repo), - "baseurl": helpers.pre_process_repo_url(chroot_id, repo), - "name": "Additional repo " + helpers.generate_repo_name(repo), + "id": generate_repo_name(repo), + "baseurl": pre_process_repo_url(chroot_id, repo), + "name": "Additional repo " + generate_repo_name(repo), } # We ask get_copr_by_repo() here only to resolve the diff --git a/frontend/coprs_frontend/coprs/repos.py b/frontend/coprs_frontend/coprs/repos.py new file mode 100644 index 000000000..ec9c03477 --- /dev/null +++ b/frontend/coprs_frontend/coprs/repos.py @@ -0,0 +1,146 @@ +""" +External repositories helper functions +""" + + +import re +import posixpath +from urllib.parse import urlparse, parse_qs, urlunparse, urlencode +import flask +from coprs import app + + +def generate_repo_url(mock_chroot, url, arch=None): + """ Generates url with build results for .repo file. + No checks if copr or mock_chroot exists. + """ + os_version = mock_chroot.os_version + + if mock_chroot.os_release == "fedora": + os_version = "$releasever" + + if mock_chroot.os_release == "centos-stream": + os_version = "$releasever" + + if mock_chroot.os_release == "opensuse-leap": + os_version = "$releasever" + + if mock_chroot.os_release == "mageia": + if mock_chroot.os_version != "cauldron": + os_version = "$releasever" + + url = posixpath.join( + url, "{0}-{1}-{2}/".format(mock_chroot.os_release, + os_version, arch or '$basearch')) + + return url + + +def generate_repo_name(repo_url): + """ based on url, generate repo name """ + repo_url = re.sub("[^a-zA-Z0-9]", '_', repo_url) + repo_url = re.sub("(__*)", '_', repo_url) + repo_url = re.sub("(_*$)|^_*", '', repo_url) + return repo_url + + +def is_copr_repo(repo_url): + """ + Is the repository in the copr://foo/bar format? + """ + return copr_repo_fullname(repo_url) is not None + + +def copr_repo_fullname(repo_url): + """ + For a copr://foo/bar repository, return foo/bar + """ + parsed_url = urlparse(repo_url) + if parsed_url.scheme != "copr": + return None + return parsed_url.netloc + parsed_url.path + + +def pre_process_repo_url(chroot, repo_url): + """ + Expands variables and sanitize repo url to be used for mock config + """ + parsed_url = urlparse(repo_url) + query = parse_qs(parsed_url.query) + + if parsed_url.scheme == "copr": + user = parsed_url.netloc + prj = parsed_url.path.split("/")[1] + repo_url = "/".join([ + flask.current_app.config["BACKEND_BASE_URL"], + "results", user, prj, chroot + ]) + "/" + + elif "priority" in query: + query.pop("priority") + query_string = urlencode(query, doseq=True) + parsed_url = parsed_url._replace(query=query_string) + repo_url = urlunparse(parsed_url) + + repo_url = repo_url.replace("$chroot", chroot) + repo_url = repo_url.replace("$distname", chroot.rsplit("-", 2)[0]) + return repo_url + + +def parse_repo_params(repo, supported_keys=None): + """ + :param repo: str repo from Copr/CoprChroot/Build/... + :param supported_keys list of supported optional parameters + :return: dict of optional parameters parsed from the repo URL + """ + supported_keys = supported_keys or ["priority"] + params = {} + qs = parse_qs(urlparse(repo).query) + for k, v in qs.items(): + if k in supported_keys: + # parse_qs returns values as lists, but we allow setting the param only once, + # so we can take just first value from it + value = int(v[0]) if v[0].isnumeric() else v[0] + params[k] = value + return params + + +def generate_repo_id_and_name(copr, copr_dir_name, multilib=False, dep_idx=None, + dependent=None): + """ + Return (repo_id, repo_name) for a given copr. If multilib is True, the + rpeo_id has a specific suffix, if the repo is dependency of the dependend, + the repo_id has a specific prefix. + """ + repo_id = "{0}:{1}:{2}:{3}{4}".format( + "coprdep" if dep_idx else "copr", + app.config["PUBLIC_COPR_HOSTNAME"].split(":")[0], + copr.owner_name.replace("@", "group_"), + copr_dir_name, + ":ml" if multilib else "" + ) + + if dep_idx and dependent: + name = "Copr {0}/{1}/{2} runtime dependency #{3} - {4}/{5}".format( + app.config["PUBLIC_COPR_HOSTNAME"].split(":")[0], + dependent.owner_name, dependent.name, dep_idx, + copr.owner_name, copr_dir_name + ) + else: + name = "Copr repo for {0} owned by {1}".format(copr_dir_name, + copr.owner_name) + return repo_id, name + + +def generate_repo_id_and_name_ext(dependent, url, dep_idx): + """ + Return (repo_id, repo_name) pair according to the repo URL and what + DEPENDENT repository we depend on. + """ + repo_id = "coprdep:{0}".format(generate_repo_name(url)) + name = "Copr {0}/{1}/{2} external runtime dependency #{3} - {4}".format( + app.config["PUBLIC_COPR_HOSTNAME"].split(":")[0], + dependent.owner_name, dependent.name, dep_idx, + generate_repo_name(url), + ) + return repo_id, name diff --git a/frontend/coprs_frontend/coprs/views/apiv3_ns/apiv3_rpmrepo.py b/frontend/coprs_frontend/coprs/views/apiv3_ns/apiv3_rpmrepo.py index 868da2f80..c89a18cce 100644 --- a/frontend/coprs_frontend/coprs/views/apiv3_ns/apiv3_rpmrepo.py +++ b/frontend/coprs_frontend/coprs/views/apiv3_ns/apiv3_rpmrepo.py @@ -21,11 +21,13 @@ from coprs.logic.complex_logic import ReposLogic from coprs.logic.stat_logic import CounterStatLogic from coprs.helpers import ( - generate_repo_id_and_name, - generate_repo_id_and_name_ext, get_stat_name, CounterStatType, ) +from coprs.repos import ( + generate_repo_id_and_name, + generate_repo_id_and_name_ext, +) apiv3_rpmrepo_ns = Namespace("rpmrepo", description="RPM Repo") diff --git a/frontend/coprs_frontend/coprs/views/coprs_ns/coprs_general.py b/frontend/coprs_frontend/coprs/views/coprs_ns/coprs_general.py index 7e560e3ae..28b07767b 100644 --- a/frontend/coprs_frontend/coprs/views/coprs_ns/coprs_general.py +++ b/frontend/coprs_frontend/coprs/views/coprs_ns/coprs_general.py @@ -38,6 +38,12 @@ from coprs.logic.complex_logic import ComplexLogic, ReposLogic from coprs.logic.outdated_chroots_logic import OutdatedChrootsLogic +from coprs.repos import ( + pre_process_repo_url, + generate_repo_id_and_name, + generate_repo_id_and_name_ext, + generate_repo_url, +) from coprs.views.misc import ( login_required, @@ -49,8 +55,7 @@ from coprs.views.coprs_ns import coprs_ns from coprs.logic import builds_logic, coprs_logic, actions_logic, users_logic, packages_logic -from coprs.helpers import generate_repo_url, \ - url_for_copr_view, CounterStatType +from coprs.helpers import url_for_copr_view, CounterStatType def url_for_copr_details(copr): @@ -861,7 +866,7 @@ def generate_repo_file(copr_dir, name_release, repofile): def render_repo_template(copr_dir, mock_chroot, arch=None, cost=None, runtime_dep=None, dependent=None): - repo_id, name = helpers.generate_repo_id_and_name( + repo_id, name = generate_repo_id_and_name( copr_dir.copr, copr_dir.name, multilib=arch, dep_idx=runtime_dep, dependent=dependent) @@ -877,8 +882,8 @@ def render_repo_template(copr_dir, mock_chroot, arch=None, cost=None, runtime_de def _render_external_repo_template(dep, copr_dir, mock_chroot, dep_idx): - baseurl = helpers.pre_process_repo_url(mock_chroot.name, dep) - repo_id, repo_name = helpers.generate_repo_id_and_name_ext( + baseurl = pre_process_repo_url(mock_chroot.name, dep) + repo_id, repo_name = generate_repo_id_and_name_ext( copr_dir.copr, dep, dep_idx) return flask.render_template("coprs/external_dependency.repo", repo_id=repo_id, name=repo_name, diff --git a/frontend/coprs_frontend/tests/test_helpers.py b/frontend/coprs_frontend/tests/test_helpers.py index bf2df8694..906b5a85d 100644 --- a/frontend/coprs_frontend/tests/test_helpers.py +++ b/frontend/coprs_frontend/tests/test_helpers.py @@ -1,14 +1,10 @@ import os -from copy import deepcopy -from unittest import mock - -from flask import Flask import pytest from coprs import app -from coprs.helpers import parse_package_name, generate_repo_url, \ - fix_protocol_for_frontend, fix_protocol_for_backend, pre_process_repo_url, \ - parse_repo_params, pagure_html_diff_changed, SubdirMatch, \ +from coprs.helpers import parse_package_name, \ + fix_protocol_for_frontend, fix_protocol_for_backend, \ + pagure_html_diff_changed, SubdirMatch, \ raw_commit_changes, WorkList, pluralize, clone_sqlalchemy_instance, \ being_server_admin @@ -38,62 +34,6 @@ def test_guess_package_name(self): for pkg, expected in EXP.items(): assert parse_package_name(pkg) == expected - def test_generate_repo_url(self): - test_sets = [] - - http_url = "http://example.com/path" - https_url = "https://example.com/path" - - mock_chroot = mock.MagicMock() - mock_chroot.os_release = "fedora" - mock_chroot.os_version = "20" - - test_sets.extend([ - dict(args=(mock_chroot, http_url), - expected="http://example.com/path/fedora-$releasever-$basearch/"), - dict(args=(mock_chroot, https_url), - expected="https://example.com/path/fedora-$releasever-$basearch/")]) - - m2 = deepcopy(mock_chroot) - m2.os_version = "rawhide" - - test_sets.extend([ - dict(args=(m2, http_url), - expected="http://example.com/path/fedora-$releasever-$basearch/"), - dict(args=(m2, https_url), - expected="https://example.com/path/fedora-$releasever-$basearch/")]) - - m3 = deepcopy(mock_chroot) - m3.os_release = "rhel7" - m3.os_version = "7.1" - - test_sets.extend([ - dict(args=(m3, http_url), - expected="http://example.com/path/rhel7-7.1-$basearch/"), - dict(args=(m3, https_url), - expected="https://example.com/path/rhel7-7.1-$basearch/")]) - - test_sets.extend([ - dict(args=(m3, http_url, 'i386'), - expected="http://example.com/path/rhel7-7.1-i386/"), - dict(args=(m3, https_url, 'ppc64le'), - expected="https://example.com/path/rhel7-7.1-ppc64le/")]) - - m4 = deepcopy(mock_chroot) - m4.os_release = "centos-stream" - m4.os_version = "9" - - test_sets.extend([ - dict(args=(m4, http_url), - expected="http://example.com/path/centos-stream-$releasever-$basearch/"), - dict(args=(m4, https_url), - expected="https://example.com/path/centos-stream-$releasever-$basearch/")]) - - app.config["USE_HTTPS_FOR_RESULTS"] = True - for test_set in test_sets: - result = generate_repo_url(*test_set["args"]) - assert result == test_set["expected"] - def test_fix_protocol_for_backend(self): http_url = "http://example.com/repo" https_url = "https://example.com/repo" @@ -140,40 +80,6 @@ def test_fix_protocol_for_frontend(self): raise e app.config["ENFORCE_PROTOCOL_FOR_BACKEND_URL"] = orig - def test_pre_process_repo_url(self): - app = Flask(__name__) - app.config["BACKEND_BASE_URL"] = "http://backend" - - test_cases = [ - ("http://example1.com/foo/$chroot/", "http://example1.com/foo/fedora-rawhide-x86_64/"), - ("copr://someuser/someproject", "http://backend/results/someuser/someproject/fedora-rawhide-x86_64/"), - ("copr://someuser/someproject?foo=bar&baz=10", - "http://backend/results/someuser/someproject/fedora-rawhide-x86_64/"), - ("http://example1.com/foo/$chroot?priority=10", - "http://example1.com/foo/fedora-rawhide-x86_64"), - ("http://example1.com/foo/$chroot?priority=10&foo=bar", - "http://example1.com/foo/fedora-rawhide-x86_64?foo=bar"), - ] - with app.app_context(): - for url, exp in test_cases: - assert pre_process_repo_url("fedora-rawhide-x86_64", url) == exp - - def test_parse_repo_params(self): - test_cases = [ - ("copr://foo/bar", {}), - ("copr://foo/bar?priority=10", {"priority": 10}), - ("copr://foo/bar?priority=10&unexp1=baz&unexp2=qux", {"priority": 10}), - ("http://example1.com/foo?priority=10", {"priority": 10}), - ] - for repo, exp in test_cases: - assert parse_repo_params(repo) == exp - - def test_parse_repo_params_pass_keys(self): - url = "copr://foo/bar?param1=foo¶m2=bar¶m3=baz¶m4=qux" - supported = ["param1", "param2", "param4"] - expected = {"param1": "foo", "param2": "bar", "param4": "qux"} - assert parse_repo_params(url, supported_keys=supported) == expected - def test_subdir_match(self): assert SubdirMatch(None).match("a") == True assert SubdirMatch("").match("a") == True diff --git a/frontend/coprs_frontend/tests/test_repos.py b/frontend/coprs_frontend/tests/test_repos.py new file mode 100644 index 000000000..6d0bd48d0 --- /dev/null +++ b/frontend/coprs_frontend/tests/test_repos.py @@ -0,0 +1,102 @@ +from copy import deepcopy +from unittest import mock +from flask import Flask +from coprs import app +from coprs.repos import ( + generate_repo_url, + pre_process_repo_url, + parse_repo_params, +) +from tests.coprs_test_case import CoprsTestCase + + +class TestRepos(CoprsTestCase): + def test_generate_repo_url(self): + test_sets = [] + + http_url = "http://example.com/path" + https_url = "https://example.com/path" + + mock_chroot = mock.MagicMock() + mock_chroot.os_release = "fedora" + mock_chroot.os_version = "20" + + test_sets.extend([ + dict(args=(mock_chroot, http_url), + expected="http://example.com/path/fedora-$releasever-$basearch/"), + dict(args=(mock_chroot, https_url), + expected="https://example.com/path/fedora-$releasever-$basearch/")]) + + m2 = deepcopy(mock_chroot) + m2.os_version = "rawhide" + + test_sets.extend([ + dict(args=(m2, http_url), + expected="http://example.com/path/fedora-$releasever-$basearch/"), + dict(args=(m2, https_url), + expected="https://example.com/path/fedora-$releasever-$basearch/")]) + + m3 = deepcopy(mock_chroot) + m3.os_release = "rhel7" + m3.os_version = "7.1" + + test_sets.extend([ + dict(args=(m3, http_url), + expected="http://example.com/path/rhel7-7.1-$basearch/"), + dict(args=(m3, https_url), + expected="https://example.com/path/rhel7-7.1-$basearch/")]) + + test_sets.extend([ + dict(args=(m3, http_url, 'i386'), + expected="http://example.com/path/rhel7-7.1-i386/"), + dict(args=(m3, https_url, 'ppc64le'), + expected="https://example.com/path/rhel7-7.1-ppc64le/")]) + + m4 = deepcopy(mock_chroot) + m4.os_release = "centos-stream" + m4.os_version = "9" + + test_sets.extend([ + dict(args=(m4, http_url), + expected="http://example.com/path/centos-stream-$releasever-$basearch/"), + dict(args=(m4, https_url), + expected="https://example.com/path/centos-stream-$releasever-$basearch/")]) + + app.config["USE_HTTPS_FOR_RESULTS"] = True + for test_set in test_sets: + result = generate_repo_url(*test_set["args"]) + assert result == test_set["expected"] + + def test_pre_process_repo_url(self): + app = Flask(__name__) + app.config["BACKEND_BASE_URL"] = "http://backend" + + test_cases = [ + ("http://example1.com/foo/$chroot/", "http://example1.com/foo/fedora-rawhide-x86_64/"), + ("copr://someuser/someproject", "http://backend/results/someuser/someproject/fedora-rawhide-x86_64/"), + ("copr://someuser/someproject?foo=bar&baz=10", + "http://backend/results/someuser/someproject/fedora-rawhide-x86_64/"), + ("http://example1.com/foo/$chroot?priority=10", + "http://example1.com/foo/fedora-rawhide-x86_64"), + ("http://example1.com/foo/$chroot?priority=10&foo=bar", + "http://example1.com/foo/fedora-rawhide-x86_64?foo=bar"), + ] + with app.app_context(): + for url, exp in test_cases: + assert pre_process_repo_url("fedora-rawhide-x86_64", url) == exp + + def test_parse_repo_params(self): + test_cases = [ + ("copr://foo/bar", {}), + ("copr://foo/bar?priority=10", {"priority": 10}), + ("copr://foo/bar?priority=10&unexp1=baz&unexp2=qux", {"priority": 10}), + ("http://example1.com/foo?priority=10", {"priority": 10}), + ] + for repo, exp in test_cases: + assert parse_repo_params(repo) == exp + + def test_parse_repo_params_pass_keys(self): + url = "copr://foo/bar?param1=foo¶m2=bar¶m3=baz¶m4=qux" + supported = ["param1", "param2", "param4"] + expected = {"param1": "foo", "param2": "bar", "param4": "qux"} + assert parse_repo_params(url, supported_keys=supported) == expected diff --git a/frontend/coprs_frontend/tests/test_views/test_coprs_ns/test_coprs_general.py b/frontend/coprs_frontend/tests/test_views/test_coprs_ns/test_coprs_general.py index c2e64375d..ab8153551 100644 --- a/frontend/coprs_frontend/tests/test_views/test_coprs_ns/test_coprs_general.py +++ b/frontend/coprs_frontend/tests/test_views/test_coprs_ns/test_coprs_general.py @@ -13,7 +13,7 @@ from copr_common.enums import ActionTypeEnum, ActionPriorityEnum, StorageEnum from coprs import app, cache, models -from coprs.helpers import generate_repo_name +from coprs.repos import generate_repo_name from coprs.logic.coprs_logic import CoprsLogic, CoprDirsLogic from coprs.logic.actions_logic import ActionsLogic