diff --git a/gitlab/cli.py b/gitlab/cli.py index a0134ecd4..c1a13345a 100644 --- a/gitlab/cli.py +++ b/gitlab/cli.py @@ -178,7 +178,7 @@ def _parse_value(v: Any) -> Any: return v -def docs() -> argparse.ArgumentParser: +def docs() -> argparse.ArgumentParser: # pragma: no cover """ Provide a statically generated parser for sphinx only, so we don't need to provide dummy gitlab config for readthedocs. @@ -208,7 +208,7 @@ def main() -> None: sys.exit(0) sys.exit(e) # We only support v4 API at this time - if config.api_version not in ("4",): + if config.api_version not in ("4",): # dead code # pragma: no cover raise ModuleNotFoundError(name=f"gitlab.v{config.api_version}.cli") # Now we build the entire set of subcommands and do the complete parsing @@ -216,7 +216,7 @@ def main() -> None: try: import argcomplete # type: ignore - argcomplete.autocomplete(parser) + argcomplete.autocomplete(parser) # pragma: no cover except Exception: pass args = parser.parse_args() diff --git a/pyproject.toml b/pyproject.toml index a19b28e58..3e8116904 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -12,6 +12,7 @@ files = "." module = [ "docs.*", "docs.ext.*", + "tests.*", "tests.functional.*", "tests.functional.api.*", "tests.unit.*", diff --git a/requirements-docker.txt b/requirements-docker.txt index 4ff5657fd..c7f6406b3 100644 --- a/requirements-docker.txt +++ b/requirements-docker.txt @@ -1,5 +1,4 @@ -r requirements.txt -r requirements-test.txt docker-compose==1.29.2 # prevent inconsistent .env behavior from system install -pytest-console-scripts pytest-docker diff --git a/requirements-test.txt b/requirements-test.txt index 8d61ad154..9f9df6153 100644 --- a/requirements-test.txt +++ b/requirements-test.txt @@ -1,6 +1,6 @@ coverage httmock -mock pytest +pytest-console-scripts==1.2.1 pytest-cov responses diff --git a/tests/conftest.py b/tests/conftest.py new file mode 100644 index 000000000..12b573f60 --- /dev/null +++ b/tests/conftest.py @@ -0,0 +1,6 @@ +import pytest + + +@pytest.fixture(scope="session") +def test_dir(pytestconfig): + return pytestconfig.rootdir / "tests" diff --git a/tests/functional/api/test_users.py b/tests/functional/api/test_users.py index 1ef237c89..edbbca1ba 100644 --- a/tests/functional/api/test_users.py +++ b/tests/functional/api/test_users.py @@ -3,23 +3,17 @@ https://docs.gitlab.com/ee/api/users.html https://docs.gitlab.com/ee/api/users.html#delete-authentication-identity-from-user """ -import pytest import requests -@pytest.fixture(scope="session") -def avatar_path(test_dir): - return test_dir / "fixtures" / "avatar.png" - - -def test_create_user(gl, avatar_path): +def test_create_user(gl, fixture_dir): user = gl.users.create( { "email": "foo@bar.com", "username": "foo", "name": "foo", "password": "foo_password", - "avatar": open(avatar_path, "rb"), + "avatar": open(fixture_dir / "avatar.png", "rb"), } ) @@ -29,7 +23,7 @@ def test_create_user(gl, avatar_path): avatar_url = user.avatar_url.replace("gitlab.test", "localhost:8080") uploaded_avatar = requests.get(avatar_url).content - assert uploaded_avatar == open(avatar_path, "rb").read() + assert uploaded_avatar == open(fixture_dir / "avatar.png", "rb").read() def test_block_user(gl, user): diff --git a/tests/functional/cli/test_cli.py b/tests/functional/cli/test_cli.py new file mode 100644 index 000000000..c4e76a70b --- /dev/null +++ b/tests/functional/cli/test_cli.py @@ -0,0 +1,49 @@ +import json + +from gitlab import __version__ + + +def test_main_entrypoint(script_runner, gitlab_config): + ret = script_runner.run("python", "-m", "gitlab", "--config-file", gitlab_config) + assert ret.returncode == 2 + + +def test_version(script_runner): + ret = script_runner.run("gitlab", "--version") + assert ret.stdout.strip() == __version__ + + +def test_invalid_config(script_runner): + ret = script_runner.run("gitlab", "--gitlab", "invalid") + assert not ret.success + assert not ret.stdout + + +def test_invalid_config_prints_help(script_runner): + ret = script_runner.run("gitlab", "--gitlab", "invalid", "--help") + assert ret.success + assert ret.stdout + + +def test_invalid_api_version(script_runner, monkeypatch, fixture_dir): + monkeypatch.setenv("PYTHON_GITLAB_CFG", str(fixture_dir / "invalid_version.cfg")) + ret = script_runner.run("gitlab", "--gitlab", "test", "project", "list") + assert not ret.success + assert ret.stderr.startswith("Unsupported API version:") + + +def test_invalid_auth_config(script_runner, monkeypatch, fixture_dir): + monkeypatch.setenv("PYTHON_GITLAB_CFG", str(fixture_dir / "invalid_auth.cfg")) + ret = script_runner.run("gitlab", "--gitlab", "test", "project", "list") + assert not ret.success + assert "401" in ret.stderr + + +def test_fields(gitlab_cli, project_file): + cmd = "-o", "json", "--fields", "default_branch", "project", "list" + + ret = gitlab_cli(cmd) + assert ret.success + + content = json.loads(ret.stdout.strip()) + assert ["default_branch" in item for item in content] diff --git a/tests/functional/conftest.py b/tests/functional/conftest.py index b6fb9edbe..625cff986 100644 --- a/tests/functional/conftest.py +++ b/tests/functional/conftest.py @@ -9,6 +9,11 @@ import gitlab +@pytest.fixture(scope="session") +def fixture_dir(test_dir): + return test_dir / "functional" / "fixtures" + + def reset_gitlab(gl): # previously tools/reset_gitlab.py for project in gl.projects.list(): @@ -26,8 +31,8 @@ def reset_gitlab(gl): user.delete(hard_delete=True) -def set_token(container, rootdir): - set_token_rb = rootdir / "fixtures" / "set_token.rb" +def set_token(container, fixture_dir): + set_token_rb = fixture_dir / "set_token.rb" with open(set_token_rb, "r") as f: set_token_command = f.read().strip() @@ -68,13 +73,8 @@ def temp_dir(): @pytest.fixture(scope="session") -def test_dir(pytestconfig): - return pytestconfig.rootdir / "tests" / "functional" - - -@pytest.fixture(scope="session") -def docker_compose_file(test_dir): - return test_dir / "fixtures" / "docker-compose.yml" +def docker_compose_file(fixture_dir): + return fixture_dir / "docker-compose.yml" @pytest.fixture(scope="session") @@ -129,7 +129,7 @@ def _wait(timeout=30, step=0.5): @pytest.fixture(scope="session") -def gitlab_config(check_is_alive, docker_ip, docker_services, temp_dir, test_dir): +def gitlab_config(check_is_alive, docker_ip, docker_services, temp_dir, fixture_dir): config_file = temp_dir / "python-gitlab.cfg" port = docker_services.port_for("gitlab", 80) @@ -137,7 +137,7 @@ def gitlab_config(check_is_alive, docker_ip, docker_services, temp_dir, test_dir timeout=200, pause=5, check=lambda: check_is_alive("gitlab-test") ) - token = set_token("gitlab-test", rootdir=test_dir) + token = set_token("gitlab-test", fixture_dir=fixture_dir) config = f"""[global] default = local diff --git a/tests/functional/fixtures/invalid_auth.cfg b/tests/functional/fixtures/invalid_auth.cfg new file mode 100644 index 000000000..3d61d67e5 --- /dev/null +++ b/tests/functional/fixtures/invalid_auth.cfg @@ -0,0 +1,3 @@ +[test] +url = https://gitlab.com +private_token = abc123 diff --git a/tests/functional/fixtures/invalid_version.cfg b/tests/functional/fixtures/invalid_version.cfg new file mode 100644 index 000000000..31059a277 --- /dev/null +++ b/tests/functional/fixtures/invalid_version.cfg @@ -0,0 +1,3 @@ +[test] +api_version = 3 +url = https://gitlab.example.com diff --git a/tests/unit/conftest.py b/tests/unit/conftest.py index f58c77a75..929be1a65 100644 --- a/tests/unit/conftest.py +++ b/tests/unit/conftest.py @@ -3,6 +3,11 @@ import gitlab +@pytest.fixture(scope="session") +def fixture_dir(test_dir): + return test_dir / "unit" / "fixtures" + + @pytest.fixture def gl(): return gitlab.Gitlab( diff --git a/tests/unit/data/todo.json b/tests/unit/fixtures/todo.json similarity index 100% rename from tests/unit/data/todo.json rename to tests/unit/fixtures/todo.json diff --git a/tests/unit/objects/test_todos.py b/tests/unit/objects/test_todos.py index 9d6b6b40b..ded6cf99a 100644 --- a/tests/unit/objects/test_todos.py +++ b/tests/unit/objects/test_todos.py @@ -3,20 +3,22 @@ """ import json -import os import pytest import responses from gitlab.v4.objects import Todo -with open(f"{os.path.dirname(__file__)}/../data/todo.json", "r") as json_file: - todo_content = json_file.read() - json_content = json.loads(todo_content) + +@pytest.fixture() +def json_content(fixture_dir): + with open(fixture_dir / "todo.json", "r") as json_file: + todo_content = json_file.read() + return json.loads(todo_content) @pytest.fixture -def resp_todo(): +def resp_todo(json_content): with responses.RequestsMock(assert_all_requests_are_fired=False) as rsps: rsps.add( method=responses.GET, diff --git a/tests/unit/test_cli.py b/tests/unit/test_cli.py index d5afe699b..2ada1c37f 100644 --- a/tests/unit/test_cli.py +++ b/tests/unit/test_cli.py @@ -25,6 +25,7 @@ import pytest from gitlab import cli +from gitlab.exceptions import GitlabError @pytest.mark.parametrize( @@ -66,12 +67,19 @@ def test_cls_to_what(class_name, expected_what): assert cli.cls_to_what(TestClass) == expected_what -def test_die(): +@pytest.mark.parametrize( + "message,error,expected", + [ + ("foobar", None, "foobar\n"), + ("foo", GitlabError("bar"), "foo (bar)\n"), + ], +) +def test_die(message, error, expected): fl = io.StringIO() with redirect_stderr(fl): with pytest.raises(SystemExit) as test: - cli.die("foobar") - assert fl.getvalue() == "foobar\n" + cli.die(message, error) + assert fl.getvalue() == expected assert test.value.code == 1 diff --git a/tests/unit/test_config.py b/tests/unit/test_config.py index f7fffb285..82b97143f 100644 --- a/tests/unit/test_config.py +++ b/tests/unit/test_config.py @@ -18,8 +18,8 @@ import io import os from textwrap import dedent +from unittest import mock -import mock import pytest from gitlab import config, USER_AGENT
Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.
Alternative Proxies: