summaryrefslogtreecommitdiff
path: root/tests/functional/cli/test_cli.py
blob: a8890661fae1cfda6298c2a0cba62a3739550909 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
"""
Some test cases are run in-process to intercept requests to gitlab.com
and example servers.
"""

import copy
import json

import pytest
import responses

from gitlab import __version__, config
from gitlab.const import DEFAULT_URL

PRIVATE_TOKEN = "glpat-abc123"
CI_JOB_TOKEN = "ci-job-token"
CI_SERVER_URL = "https://gitlab.example.com"


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__


@pytest.mark.script_launch_mode("inprocess")
@responses.activate
def test_defaults_to_gitlab_com(script_runner, resp_get_project, monkeypatch):
    responses.add(**resp_get_project)
    monkeypatch.setattr(config, "_DEFAULT_FILES", [])
    ret = script_runner.run("gitlab", "project", "get", "--id", "1")
    assert ret.success
    assert "id: 1" in ret.stdout


@pytest.mark.script_launch_mode("inprocess")
@responses.activate
def test_uses_ci_server_url(monkeypatch, script_runner, resp_get_project):
    monkeypatch.setenv("CI_SERVER_URL", CI_SERVER_URL)
    monkeypatch.setattr(config, "_DEFAULT_FILES", [])
    resp_get_project_in_ci = copy.deepcopy(resp_get_project)
    resp_get_project_in_ci.update(url=f"{CI_SERVER_URL}/api/v4/projects/1")

    responses.add(**resp_get_project_in_ci)
    ret = script_runner.run("gitlab", "project", "get", "--id", "1")
    assert ret.success


@pytest.mark.script_launch_mode("inprocess")
@responses.activate
def test_uses_ci_job_token(monkeypatch, script_runner, resp_get_project):
    monkeypatch.setenv("CI_JOB_TOKEN", CI_JOB_TOKEN)
    monkeypatch.setattr(config, "_DEFAULT_FILES", [])
    resp_get_project_in_ci = copy.deepcopy(resp_get_project)
    resp_get_project_in_ci.update(
        match=[responses.matchers.header_matcher({"JOB-TOKEN": CI_JOB_TOKEN})],
    )

    responses.add(**resp_get_project_in_ci)
    ret = script_runner.run("gitlab", "project", "get", "--id", "1")
    assert ret.success


@pytest.mark.script_launch_mode("inprocess")
@responses.activate
def test_private_token_overrides_job_token(
    monkeypatch, script_runner, resp_get_project
):
    monkeypatch.setenv("GITLAB_PRIVATE_TOKEN", PRIVATE_TOKEN)
    monkeypatch.setenv("CI_JOB_TOKEN", CI_JOB_TOKEN)

    resp_get_project_with_token = copy.deepcopy(resp_get_project)
    resp_get_project_with_token.update(
        match=[responses.matchers.header_matcher({"PRIVATE-TOKEN": PRIVATE_TOKEN})],
    )

    # CLI first calls .auth() when private token is present
    resp_auth_with_token = copy.deepcopy(resp_get_project_with_token)
    resp_auth_with_token.update(url=f"{DEFAULT_URL}/api/v4/user")

    responses.add(**resp_get_project_with_token)
    responses.add(**resp_auth_with_token)
    ret = script_runner.run("gitlab", "project", "get", "--id", "1")
    assert ret.success


def test_env_config_missing_file_raises(script_runner, monkeypatch):
    monkeypatch.setenv("PYTHON_GITLAB_CFG", "non-existent")
    ret = script_runner.run("gitlab", "project", "list")
    assert not ret.success
    assert ret.stderr.startswith("Cannot read config from PYTHON_GITLAB_CFG")


def test_arg_config_missing_file_raises(script_runner):
    ret = script_runner.run(
        "gitlab", "--config-file", "non-existent", "project", "list"
    )
    assert not ret.success
    assert ret.stderr.startswith("Cannot read config from file")


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]