import json import warnings import pytest from gitlab import types, utils class TestEncodedId: def test_init_str(self): obj = utils.EncodedId("Hello") assert "Hello" == obj assert "Hello" == str(obj) assert "Hello" == f"{obj}" assert isinstance(obj, utils.EncodedId) obj = utils.EncodedId("this/is a/path") assert "this%2Fis%20a%2Fpath" == str(obj) assert "this%2Fis%20a%2Fpath" == f"{obj}" assert isinstance(obj, utils.EncodedId) def test_init_int(self): obj = utils.EncodedId(23) assert "23" == obj assert "23" == f"{obj}" assert isinstance(obj, utils.EncodedId) def test_init_invalid_type_raises(self): with pytest.raises(TypeError): utils.EncodedId(None) def test_init_encodeid_str(self): value = "Goodbye" obj_init = utils.EncodedId(value) obj = utils.EncodedId(obj_init) assert value == str(obj) assert value == f"{obj}" value = "we got/a/path" expected = "we%20got%2Fa%2Fpath" obj_init = utils.EncodedId(value) assert expected == str(obj_init) assert expected == f"{obj_init}" # Show that no matter how many times we recursively call it we still only # URL-encode it once. obj = utils.EncodedId( utils.EncodedId(utils.EncodedId(utils.EncodedId(utils.EncodedId(obj_init)))) ) assert expected == str(obj) assert expected == f"{obj}" # Show assignments still only encode once obj2 = obj assert expected == str(obj2) assert expected == f"{obj2}" def test_init_encodeid_int(self): value = 23 expected = f"{value}" obj_init = utils.EncodedId(value) obj = utils.EncodedId(obj_init) assert expected == str(obj) assert expected == f"{obj}" def test_json_serializable(self): obj = utils.EncodedId("someone") assert '"someone"' == json.dumps(obj) obj = utils.EncodedId("we got/a/path") assert '"we%20got%2Fa%2Fpath"' == json.dumps(obj) class TestWarningsWrapper: def test_warn(self): warn_message = "short and stout" warn_source = "teapot" with warnings.catch_warnings(record=True) as caught_warnings: utils.warn(message=warn_message, category=UserWarning, source=warn_source) assert len(caught_warnings) == 1 warning = caught_warnings[0] # File name is this file as it is the first file outside of the `gitlab/` path. assert __file__ == warning.filename assert warning.category == UserWarning assert isinstance(warning.message, UserWarning) assert warn_message in str(warning.message) assert __file__ in str(warning.message) assert warn_source == warning.source @pytest.mark.parametrize( "source,expected", [ ({"a": "", "b": "spam", "c": None}, {"a": "", "b": "spam", "c": None}), ({"a": "", "b": {"c": "spam"}}, {"a": "", "b[c]": "spam"}), ], ) def test_copy_dict(source, expected): dest = {} utils.copy_dict(src=source, dest=dest) assert dest == expected @pytest.mark.parametrize( "dictionary,expected", [ ({"a": None, "b": "spam"}, {"b": "spam"}), ({"a": "", "b": "spam"}, {"a": "", "b": "spam"}), ({"a": None, "b": None}, {}), ], ) def test_remove_none_from_dict(dictionary, expected): result = utils.remove_none_from_dict(dictionary) assert result == expected def test_transform_types_copies_data_with_empty_files(): data = {"attr": "spam"} new_data, files = utils._transform_types(data, {}, transform_data=True) assert new_data is not data assert new_data == data assert files == {} def test_transform_types_with_transform_files_populates_files(): custom_types = {"attr": types.FileAttribute} data = {"attr": "spam"} new_data, files = utils._transform_types(data, custom_types, transform_data=True) assert new_data == {} assert files["attr"] == ("attr", "spam") def test_transform_types_without_transform_files_populates_data_with_empty_files(): custom_types = {"attr": types.FileAttribute} data = {"attr": "spam"} new_data, files = utils._transform_types( data, custom_types, transform_files=False, transform_data=True ) assert new_data == {"attr": "spam"} assert files == {} def test_transform_types_params_array(): data = {"attr": [1, 2, 3]} custom_types = {"attr": types.ArrayAttribute} new_data, files = utils._transform_types(data, custom_types, transform_data=True) assert new_data is not data assert new_data == {"attr[]": [1, 2, 3]} assert files == {} def test_transform_types_not_params_array(): data = {"attr": [1, 2, 3]} custom_types = {"attr": types.ArrayAttribute} new_data, files = utils._transform_types(data, custom_types, transform_data=False) assert new_data is not data assert new_data == data assert files == {}