1#!/usr/bin/env python
2# -*- coding: utf-8 -*-
3#
4# Copyright (C) 2016-2017 Gauvain Pocentek <gauvain@pocentek.net>
5#
6# This program is free software: you can redistribute it and/or modify
7# it under the terms of the GNU Lesser General Public License as published by
8# the Free Software Foundation, either version 3 of the License, or
9# (at your option) any later version.
10#
11# This program is distributed in the hope that it will be useful,
12# but WITHOUT ANY WARRANTY; without even the implied warranty of
13# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14# GNU Lesser General Public License for more details.
15#
16# You should have received a copy of the GNU Lesser General Public License
17# along with this program.  If not, see <http://www.gnu.org/licenses/>.
18
19import argparse
20import io
21import os
22import tempfile
23from contextlib import redirect_stderr  # noqa: H302
24
25import pytest
26
27from gitlab import cli
28
29
30@pytest.mark.parametrize(
31    "what,expected_class",
32    [
33        ("class", "Class"),
34        ("test-class", "TestClass"),
35        ("test-longer-class", "TestLongerClass"),
36        ("current-user-gpg-key", "CurrentUserGPGKey"),
37        ("user-gpg-key", "UserGPGKey"),
38        ("ldap-group", "LDAPGroup"),
39    ],
40)
41def test_what_to_cls(what, expected_class):
42    def _namespace():
43        pass
44
45    ExpectedClass = type(expected_class, (), {})
46    _namespace.__dict__[expected_class] = ExpectedClass
47
48    assert cli.what_to_cls(what, _namespace) == ExpectedClass
49
50
51@pytest.mark.parametrize(
52    "class_name,expected_what",
53    [
54        ("Class", "class"),
55        ("TestClass", "test-class"),
56        ("TestUPPERCASEClass", "test-uppercase-class"),
57        ("UPPERCASETestClass", "uppercase-test-class"),
58        ("CurrentUserGPGKey", "current-user-gpg-key"),
59        ("UserGPGKey", "user-gpg-key"),
60        ("LDAPGroup", "ldap-group"),
61    ],
62)
63def test_cls_to_what(class_name, expected_what):
64    TestClass = type(class_name, (), {})
65
66    assert cli.cls_to_what(TestClass) == expected_what
67
68
69def test_die():
70    fl = io.StringIO()
71    with redirect_stderr(fl):
72        with pytest.raises(SystemExit) as test:
73            cli.die("foobar")
74    assert fl.getvalue() == "foobar\n"
75    assert test.value.code == 1
76
77
78def test_parse_value():
79    ret = cli._parse_value("foobar")
80    assert ret == "foobar"
81
82    ret = cli._parse_value(True)
83    assert ret is True
84
85    ret = cli._parse_value(1)
86    assert ret == 1
87
88    ret = cli._parse_value(None)
89    assert ret is None
90
91    fd, temp_path = tempfile.mkstemp()
92    os.write(fd, b"content")
93    os.close(fd)
94    ret = cli._parse_value("@%s" % temp_path)
95    assert ret == "content"
96    os.unlink(temp_path)
97
98    fl = io.StringIO()
99    with redirect_stderr(fl):
100        with pytest.raises(SystemExit) as exc:
101            cli._parse_value("@/thisfileprobablydoesntexist")
102        assert (
103            fl.getvalue() == "[Errno 2] No such file or directory:"
104            " '/thisfileprobablydoesntexist'\n"
105        )
106        assert exc.value.code == 1
107
108
109def test_base_parser():
110    parser = cli._get_base_parser()
111    args = parser.parse_args(["-v", "-g", "gl_id", "-c", "foo.cfg", "-c", "bar.cfg"])
112    assert args.verbose
113    assert args.gitlab == "gl_id"
114    assert args.config_file == ["foo.cfg", "bar.cfg"]
115
116
117def test_v4_parse_args():
118    parser = cli._get_parser()
119    args = parser.parse_args(["project", "list"])
120    assert args.what == "project"
121    assert args.whaction == "list"
122
123
124def test_v4_parser():
125    parser = cli._get_parser()
126    subparsers = next(
127        action
128        for action in parser._actions
129        if isinstance(action, argparse._SubParsersAction)
130    )
131    assert subparsers is not None
132    assert "project" in subparsers.choices
133
134    user_subparsers = next(
135        action
136        for action in subparsers.choices["project"]._actions
137        if isinstance(action, argparse._SubParsersAction)
138    )
139    assert user_subparsers is not None
140    assert "list" in user_subparsers.choices
141    assert "get" in user_subparsers.choices
142    assert "delete" in user_subparsers.choices
143    assert "update" in user_subparsers.choices
144    assert "create" in user_subparsers.choices
145    assert "archive" in user_subparsers.choices
146    assert "unarchive" in user_subparsers.choices
147
148    actions = user_subparsers.choices["create"]._option_string_actions
149    assert not actions["--description"].required
150
151    user_subparsers = next(
152        action
153        for action in subparsers.choices["group"]._actions
154        if isinstance(action, argparse._SubParsersAction)
155    )
156    actions = user_subparsers.choices["create"]._option_string_actions
157    assert actions["--name"].required
158