| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -39,6 +39,7 @@ def __init__( | |||
| 39 | 39 | self.action = action.lower() | |
| 40 | 40 | self.gl = gl | |
| 41 | 41 | self.args = args | |
| 42 | + self.parent_args: Dict[str, Any] = {} | ||
| 42 | 43 | self.mgr_cls: Union[ | |
| 43 | 44 | Type[gitlab.mixins.CreateMixin], | |
| 44 | 45 | Type[gitlab.mixins.DeleteMixin], | |
@@ -53,7 +54,10 @@ def __init__( | |||
| 53 | 54 | # the class _path attribute, and replace the value with the result. | |
| 54 | 55 | if TYPE_CHECKING: | |
| 55 | 56 | assert self.mgr_cls._path is not None | |
| 56 | - self.mgr_cls._path = self.mgr_cls._path.format(**self.args) | ||
| 57 | + | ||
| 58 | + self._process_from_parent_attrs() | ||
| 59 | + | ||
| 60 | + self.mgr_cls._path = self.mgr_cls._path.format(**self.parent_args) | ||
| 57 | 61 | self.mgr = self.mgr_cls(gl) | |
| 58 | 62 | ||
| 59 | 63 | if self.mgr_cls._types: | |
@@ -63,6 +67,18 @@ def __init__( | |||
| 63 | 67 | obj.set_from_cli(self.args[attr_name]) | |
| 64 | 68 | self.args[attr_name] = obj.get() | |
| 65 | 69 | ||
| 70 | + def _process_from_parent_attrs(self) -> None: | ||
| 71 | + """Items in the path need to be url-encoded. There is a 1:1 mapping from | ||
| 72 | + mgr_cls._from_parent_attrs <--> mgr_cls._path. Those values must be url-encoded | ||
| 73 | + as they may contain a slash '/'.""" | ||
| 74 | + for key in self.mgr_cls._from_parent_attrs: | ||
| 75 | + if key not in self.args: | ||
| 76 | + continue | ||
| 77 | + | ||
| 78 | + self.parent_args[key] = gitlab.utils.clean_str_id(self.args[key]) | ||
| 79 | + # If we don't delete it then it will be added to the URL as a query-string | ||
| 80 | + del self.args[key] | ||
| 81 | + | ||
| 66 | 82 | def __call__(self) -> Any: | |
| 67 | 83 | # Check for a method that matches object + action | |
| 68 | 84 | method = f"do_{self.what}_{self.action}" | |
@@ -85,7 +101,7 @@ def do_custom(self) -> Any: | |||
| 85 | 101 | data = {} | |
| 86 | 102 | if self.mgr._from_parent_attrs: | |
| 87 | 103 | for k in self.mgr._from_parent_attrs: | |
| 88 | - data[k] = self.args[k] | ||
| 104 | + data[k] = self.parent_args[k] | ||
| 89 | 105 | if not issubclass(self.cls, gitlab.mixins.GetWithoutIdMixin): | |
| 90 | 106 | if TYPE_CHECKING: | |
| 91 | 107 | assert isinstance(self.cls._id_attr, str) | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -1,4 +1,7 @@ | |||
| 1 | 1 | import pytest | |
| 2 | + import responses | ||
| 3 | + | ||
| 4 | + from gitlab.const import DEFAULT_URL | ||
| 2 | 5 | ||
| 3 | 6 | ||
| 4 | 7 | @pytest.fixture | |
@@ -19,3 +22,14 @@ def _gitlab_cli(subcommands): | |||
| 19 | 22 | return script_runner.run(*command) | |
| 20 | 23 | ||
| 21 | 24 | return _gitlab_cli | |
| 25 | + | ||
| 26 | + | ||
| 27 | + @pytest.fixture | ||
| 28 | + def resp_get_project(): | ||
| 29 | + return { | ||
| 30 | + "method": responses.GET, | ||
| 31 | + "url": f"{DEFAULT_URL}/api/v4/projects/1", | ||
| 32 | + "json": {"name": "name", "path": "test-path", "id": 1}, | ||
| 33 | + "content_type": "application/json", | ||
| 34 | + "status": 200, | ||
| 35 | + } | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -17,17 +17,6 @@ | |||
| 17 | 17 | CI_SERVER_URL = "https://gitlab.example.com" | |
| 18 | 18 | ||
| 19 | 19 | ||
| 20 | - @pytest.fixture | ||
| 21 | - def resp_get_project(): | ||
| 22 | - return { | ||
| 23 | - "method": responses.GET, | ||
| 24 | - "url": f"{DEFAULT_URL}/api/v4/projects/1", | ||
| 25 | - "json": {"name": "name", "path": "test-path", "id": 1}, | ||
| 26 | - "content_type": "application/json", | ||
| 27 | - "status": 200, | ||
| 28 | - } | ||
| 29 | - | ||
| 30 | - | ||
| 31 | 20 | def test_main_entrypoint(script_runner, gitlab_config): | |
| 32 | 21 | ret = script_runner.run("python", "-m", "gitlab", "--config-file", gitlab_config) | |
| 33 | 22 | assert ret.returncode == 2 | |
@@ -42,11 +31,8 @@ def test_version(script_runner): | |||
| 42 | 31 | @responses.activate | |
| 43 | 32 | def test_defaults_to_gitlab_com(script_runner, resp_get_project, monkeypatch): | |
| 44 | 33 | responses.add(**resp_get_project) | |
| 45 | - with monkeypatch.context() as m: | ||
| 46 | - # Ensure we don't pick up any config files that may already exist in the local | ||
| 47 | - # environment. | ||
| 48 | - m.setattr(config, "_DEFAULT_FILES", []) | ||
| 49 | - ret = script_runner.run("gitlab", "project", "get", "--id", "1") | ||
| 34 | + monkeypatch.setattr(config, "_DEFAULT_FILES", []) | ||
| 35 | + ret = script_runner.run("gitlab", "project", "get", "--id", "1") | ||
| 50 | 36 | assert ret.success | |
| 51 | 37 | assert "id: 1" in ret.stdout | |
| 52 | 38 | ||
@@ -55,6 +41,7 @@ def test_defaults_to_gitlab_com(script_runner, resp_get_project, monkeypatch): | |||
| 55 | 41 | @responses.activate | |
| 56 | 42 | def test_uses_ci_server_url(monkeypatch, script_runner, resp_get_project): | |
| 57 | 43 | monkeypatch.setenv("CI_SERVER_URL", CI_SERVER_URL) | |
| 44 | + monkeypatch.setattr(config, "_DEFAULT_FILES", []) | ||
| 58 | 45 | resp_get_project_in_ci = copy.deepcopy(resp_get_project) | |
| 59 | 46 | resp_get_project_in_ci.update(url=f"{CI_SERVER_URL}/api/v4/projects/1") | |
| 60 | 47 | ||
@@ -67,6 +54,7 @@ def test_uses_ci_server_url(monkeypatch, script_runner, resp_get_project): | |||
| 67 | 54 | @responses.activate | |
| 68 | 55 | def test_uses_ci_job_token(monkeypatch, script_runner, resp_get_project): | |
| 69 | 56 | monkeypatch.setenv("CI_JOB_TOKEN", CI_JOB_TOKEN) | |
| 57 | + monkeypatch.setattr(config, "_DEFAULT_FILES", []) | ||
| 70 | 58 | resp_get_project_in_ci = copy.deepcopy(resp_get_project) | |
| 71 | 59 | resp_get_project_in_ci.update( | |
| 72 | 60 | match=[responses.matchers.header_matcher({"JOB-TOKEN": CI_JOB_TOKEN})], | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -1,3 +1,12 @@ | |||
| 1 | + import copy | ||
| 2 | + | ||
| 3 | + import pytest | ||
| 4 | + import responses | ||
| 5 | + | ||
| 6 | + from gitlab import config | ||
| 7 | + from gitlab.const import DEFAULT_URL | ||
| 8 | + | ||
| 9 | + | ||
| 1 | 10 | def test_list_instance_variables(gitlab_cli, gl): | |
| 2 | 11 | cmd = ["variable", "list"] | |
| 3 | 12 | ret = gitlab_cli(cmd) | |
@@ -17,3 +26,29 @@ def test_list_project_variables(gitlab_cli, project): | |||
| 17 | 26 | ret = gitlab_cli(cmd) | |
| 18 | 27 | ||
| 19 | 28 | assert ret.success | |
| 29 | + | ||
| 30 | + | ||
| 31 | + def test_list_project_variables_with_path(gitlab_cli, project): | ||
| 32 | + cmd = ["project-variable", "list", "--project-id", project.path_with_namespace] | ||
| 33 | + ret = gitlab_cli(cmd) | ||
| 34 | + | ||
| 35 | + assert ret.success | ||
| 36 | + | ||
| 37 | + | ||
| 38 | + @pytest.mark.script_launch_mode("inprocess") | ||
| 39 | + @responses.activate | ||
| 40 | + def test_list_project_variables_with_path_url_check( | ||
| 41 | + monkeypatch, script_runner, resp_get_project | ||
| 42 | + ): | ||
| 43 | + monkeypatch.setattr(config, "_DEFAULT_FILES", []) | ||
| 44 | + resp_get_project_variables = copy.deepcopy(resp_get_project) | ||
| 45 | + resp_get_project_variables.update( | ||
| 46 | + url=f"{DEFAULT_URL}/api/v4/projects/project%2Fwith%2Fa%2Fnamespace/variables" | ||
| 47 | + ) | ||
| 48 | + resp_get_project_variables.update(json=[]) | ||
| 49 | + | ||
| 50 | + responses.add(**resp_get_project_variables) | ||
| 51 | + ret = script_runner.run( | ||
| 52 | + "gitlab", "project-variable", "list", "--project-id", "project/with/a/namespace" | ||
| 53 | + ) | ||
| 54 | + assert ret.success | ||
| Back | FazBrowse Home | New Git URL |
0 commit comments