# -*- coding: utf-8 -*- # # Copyright (C) 2014 Mika Mäenpää , # Tampere University of Technology # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU Lesser General Public License as published by # the Free Software Foundation, either version 3 of the License, or` # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU Lesser General Public License for more details. # # You should have received a copy of the GNU Lesser General Public License # along with this program. If not, see . import pickle import warnings from copy import deepcopy import pytest import responses import gitlab localhost = "http://localhost" token = "abc123" @pytest.fixture def resp_get_user(): return { "method": responses.GET, "url": "http://localhost/api/v4/user", "json": {"id": 1, "username": "username"}, "content_type": "application/json", "status": 200, } @pytest.fixture def resp_page_1(): headers = { "X-Page": "1", "X-Next-Page": "2", "X-Per-Page": "1", "X-Total-Pages": "2", "X-Total": "2", "Link": (";" ' rel="next"'), } return { "method": responses.GET, "url": "http://localhost/api/v4/tests", "json": [{"a": "b"}], "headers": headers, "content_type": "application/json", "status": 200, "match_querystring": True, } @pytest.fixture def resp_page_2(): headers = { "X-Page": "2", "X-Next-Page": "2", "X-Per-Page": "1", "X-Total-Pages": "2", "X-Total": "2", } params = {"per_page": "1", "page": "2"} return { "method": responses.GET, "url": "http://localhost/api/v4/tests", "json": [{"c": "d"}], "headers": headers, "content_type": "application/json", "status": 200, "match": [responses.matchers.query_param_matcher(params)], "match_querystring": False, } @responses.activate def test_gitlab_build_list(gl, resp_page_1, resp_page_2): responses.add(**resp_page_1) obj = gl.http_list("/tests", as_list=False) assert len(obj) == 2 assert obj._next_url == "http://localhost/api/v4/tests?per_page=1&page=2" assert obj.current_page == 1 assert obj.prev_page is None assert obj.next_page == 2 assert obj.per_page == 1 assert obj.total_pages == 2 assert obj.total == 2 responses.add(**resp_page_2) test_list = list(obj) assert len(test_list) == 2 assert test_list[0]["a"] == "b" assert test_list[1]["c"] == "d" def _strip_pagination_headers(response): """ https://docs.gitlab.com/ee/user/gitlab_com/index.html#pagination-response-headers """ stripped = deepcopy(response) del stripped["headers"]["X-Total-Pages"] del stripped["headers"]["X-Total"] return stripped @pytest.mark.xfail(reason="See #1686") @responses.activate def test_gitlab_build_list_missing_headers(gl, resp_page_1, resp_page_2): stripped_page_1 = _strip_pagination_headers(resp_page_1) stripped_page_2 = _strip_pagination_headers(resp_page_2) responses.add(**stripped_page_1) obj = gl.http_list("/tests", as_list=False) assert len(obj) == 0 # Lazy generator has no knowledge of total items assert obj.total_pages is None assert obj.total is None responses.add(**stripped_page_2) test_list = list(obj) assert len(test_list) == 2 # List has total items after making the API calls @responses.activate def test_gitlab_all_omitted_when_as_list(gl, resp_page_1, resp_page_2): responses.add(**resp_page_1) responses.add(**resp_page_2) result = gl.http_list("/tests", as_list=False, all=True) assert isinstance(result, gitlab.GitlabList) def test_gitlab_strip_base_url(gl_trailing): assert gl_trailing.url == "http://localhost" def test_gitlab_strip_api_url(gl_trailing): assert gl_trailing.api_url == "http://localhost/api/v4" def test_gitlab_build_url(gl_trailing): r = gl_trailing._build_url("/projects") assert r == "http://localhost/api/v4/projects" def test_gitlab_pickability(gl): original_gl_objects = gl._objects pickled = pickle.dumps(gl) unpickled = pickle.loads(pickled) assert isinstance(unpickled, gitlab.Gitlab) assert hasattr(unpickled, "_objects") assert unpickled._objects == original_gl_objects @responses.activate def test_gitlab_token_auth(gl, resp_get_user): responses.add(**resp_get_user) gl.auth() assert gl.user.username == "username" assert gl.user.id == 1 assert isinstance(gl.user, gitlab.v4.objects.CurrentUser) def test_gitlab_default_url(): gl = gitlab.Gitlab() assert gl.url == gitlab.const.DEFAULT_URL @pytest.mark.parametrize( "args, kwargs, expected_url, expected_private_token, expected_oauth_token", [ ([], {}, gitlab.const.DEFAULT_URL, None, None), ([None, token], {}, gitlab.const.DEFAULT_URL, token, None), ([localhost], {}, localhost, None, None), ([localhost, token], {}, localhost, token, None), ([localhost, None, token], {}, localhost, None, token), ([], {"private_token": token}, gitlab.const.DEFAULT_URL, token, None), ([], {"oauth_token": token}, gitlab.const.DEFAULT_URL, None, token), ([], {"url": localhost}, localhost, None, None), ([], {"url": localhost, "private_token": token}, localhost, token, None), ([], {"url": localhost, "oauth_token": token}, localhost, None, token), ], ids=[ "no_args", "args_private_token", "args_url", "args_url_private_token", "args_url_oauth_token", "kwargs_private_token", "kwargs_oauth_token", "kwargs_url", "kwargs_url_private_token", "kwargs_url_oauth_token", ], ) def test_gitlab_args_kwargs( args, kwargs, expected_url, expected_private_token, expected_oauth_token ): gl = gitlab.Gitlab(*args, **kwargs) assert gl.url == expected_url assert gl.private_token == expected_private_token assert gl.oauth_token == expected_oauth_token def test_gitlab_from_config(default_config): config_path = default_config gitlab.Gitlab.from_config("one", [config_path]) def test_gitlab_subclass_from_config(default_config): class MyGitlab(gitlab.Gitlab): pass config_path = default_config gl = MyGitlab.from_config("one", [config_path]) assert isinstance(gl, MyGitlab) @pytest.mark.parametrize( "kwargs,expected_agent", [ ({}, gitlab.const.USER_AGENT), ({"user_agent": "my-package/1.0.0"}, "my-package/1.0.0"), ], ) def test_gitlab_user_agent(kwargs, expected_agent): gl = gitlab.Gitlab("http://localhost", **kwargs) assert gl.headers["User-Agent"] == expected_agent def test_gitlab_deprecated_const(): with warnings.catch_warnings(record=True) as caught_warnings: gitlab.NO_ACCESS assert len(caught_warnings) == 1 warning = caught_warnings[0] assert isinstance(warning.message, DeprecationWarning) message = str(caught_warnings[0].message) assert "deprecated" in message assert "gitlab.const.NO_ACCESS" in message with warnings.catch_warnings(record=True) as caught_warnings: gitlab.const.NO_ACCESS assert len(caught_warnings) == 0