diff options
| -rw-r--r-- | .readthedocs.yml | 13 | ||||
| -rw-r--r-- | .renovaterc.json | 9 | ||||
| -rw-r--r-- | docs/gl_objects/users.rst | 4 | ||||
| -rw-r--r-- | gitlab/tests/objects/test_resource_label_events.py | 105 | ||||
| -rw-r--r-- | gitlab/tests/objects/test_users.py | 17 | ||||
| -rw-r--r-- | gitlab/v4/objects/__init__.py | 16 | ||||
| -rwxr-xr-x | tools/build_test_env.sh | 2 | ||||
| -rw-r--r-- | tools/functional/api/test_users.py | 20 |
8 files changed, 185 insertions, 1 deletions
diff --git a/.readthedocs.yml b/.readthedocs.yml new file mode 100644 index 0000000..69f8c3a --- /dev/null +++ b/.readthedocs.yml @@ -0,0 +1,13 @@ +version: 2 + +sphinx: + configuration: docs/conf.py + +formats: + - pdf + - epub + +python: + version: 3.8 + install: + - requirements: rtd-requirements.txt diff --git a/.renovaterc.json b/.renovaterc.json index 2b6699f..be47e3a 100644 --- a/.renovaterc.json +++ b/.renovaterc.json @@ -1,4 +1,7 @@ { + "extends": [ + "config:base" + ], "regexManagers": [ { "fileMatch": ["^tools/build_test_env.sh$"], @@ -7,5 +10,11 @@ "datasourceTemplate": "docker", "versioningTemplate": "loose" } + ], + "packageRules": [ + { + "packagePatterns": ["^gitlab\/gitlab-.+$"], + "automerge": true + } ] } diff --git a/docs/gl_objects/users.rst b/docs/gl_objects/users.rst index 5b1cf3d..9f2d42c 100644 --- a/docs/gl_objects/users.rst +++ b/docs/gl_objects/users.rst @@ -80,6 +80,10 @@ Set an external identity for a user:: user.extern_uid = '3' user.save() +Delete an external identity by provider name:: + + user.identityproviders.delete('oauth2_generic') + User custom attributes ====================== diff --git a/gitlab/tests/objects/test_resource_label_events.py b/gitlab/tests/objects/test_resource_label_events.py new file mode 100644 index 0000000..07f891c --- /dev/null +++ b/gitlab/tests/objects/test_resource_label_events.py @@ -0,0 +1,105 @@ +""" +GitLab API: https://docs.gitlab.com/ee/api/resource_label_events.html +""" + +import pytest +import responses + +from gitlab.v4.objects import ( + ProjectIssueResourceLabelEvent, + ProjectMergeRequestResourceLabelEvent, + GroupEpicResourceLabelEvent, +) + + +@pytest.fixture() +def resp_group_epic_request_label_events(): + epic_content = {"id": 1} + events_content = {"id": 1, "resource_type": "Epic"} + with responses.RequestsMock() as rsps: + rsps.add( + method=responses.GET, + url="http://localhost/api/v4/groups/1/epics", + json=[epic_content], + content_type="application/json", + status=200, + ) + rsps.add( + method=responses.GET, + url="http://localhost/api/v4/groups/1/epics/1/resource_label_events", + json=[events_content], + content_type="application/json", + status=200, + ) + yield rsps + + +@pytest.fixture() +def resp_merge_request_label_events(): + mr_content = {"iid": 1} + events_content = {"id": 1, "resource_type": "MergeRequest"} + with responses.RequestsMock() as rsps: + rsps.add( + method=responses.GET, + url="http://localhost/api/v4/projects/1/merge_requests", + json=[mr_content], + content_type="application/json", + status=200, + ) + rsps.add( + method=responses.GET, + url="http://localhost/api/v4/projects/1/merge_requests/1/resource_label_events", + json=[events_content], + content_type="application/json", + status=200, + ) + yield rsps + + +@pytest.fixture() +def resp_project_issue_label_events(): + issue_content = {"iid": 1} + events_content = {"id": 1, "resource_type": "Issue"} + with responses.RequestsMock() as rsps: + rsps.add( + method=responses.GET, + url="http://localhost/api/v4/projects/1/issues", + json=[issue_content], + content_type="application/json", + status=200, + ) + rsps.add( + method=responses.GET, + url="http://localhost/api/v4/projects/1/issues/1/resource_label_events", + json=[events_content], + content_type="application/json", + status=200, + ) + yield rsps + + +def test_project_issue_label_events(project, resp_project_issue_label_events): + issue = project.issues.list()[0] + label_events = issue.resourcelabelevents.list() + assert isinstance(label_events, list) + label_event = label_events[0] + assert isinstance(label_event, ProjectIssueResourceLabelEvent) + assert label_event.resource_type == "Issue" + + +def test_merge_request_label_events(project, resp_merge_request_label_events): + mr = project.mergerequests.list()[0] + label_events = mr.resourcelabelevents.list() + assert isinstance(label_events, list) + label_event = label_events[0] + assert isinstance(label_event, ProjectMergeRequestResourceLabelEvent) + assert label_event.resource_type == "MergeRequest" + + +def test_group_epic_request_label_events(group, resp_group_epic_request_label_events): + epic = group.epics.list()[0] + label_events = epic.resourcelabelevents.list() + assert isinstance(label_events, list) + label_event = label_events[0] + assert isinstance(label_event, GroupEpicResourceLabelEvent) + assert label_event.resource_type == "Epic" diff --git a/gitlab/tests/objects/test_users.py b/gitlab/tests/objects/test_users.py index ec282cf..f84e877 100644 --- a/gitlab/tests/objects/test_users.py +++ b/gitlab/tests/objects/test_users.py @@ -95,6 +95,19 @@ def resp_get_user_status(): yield rsps +@pytest.fixture +def resp_delete_user_identity(no_content): + with responses.RequestsMock() as rsps: + rsps.add( + method=responses.DELETE, + url="http://localhost/api/v4/users/1/identities/test_provider", + json=no_content, + content_type="application/json", + status=204, + ) + yield rsps + + def test_get_user(gl, resp_get_user): user = gl.users.get(1) assert isinstance(user, User) @@ -118,3 +131,7 @@ def test_user_status(user, resp_get_user_status): def test_user_activate_deactivate(user, resp_activate): user.activate() user.deactivate() + + +def test_delete_user_identity(user, resp_delete_user_identity): + user.identityproviders.delete("test_provider") diff --git a/gitlab/v4/objects/__init__.py b/gitlab/v4/objects/__init__.py index f9a2c25..016caec 100644 --- a/gitlab/v4/objects/__init__.py +++ b/gitlab/v4/objects/__init__.py @@ -217,6 +217,17 @@ class UserStatusManager(GetWithoutIdMixin, RESTManager): _from_parent_attrs = {"user_id": "id"} +class UserIdentityProviderManager(DeleteMixin, RESTManager): + """Manager for user identities. + + This manager does not actually manage objects but enables + functionality for deletion of user identities by provider. + """ + + _path = "/users/%(user_id)s/identities" + _from_parent_attrs = {"user_id": "id"} + + class UserImpersonationToken(ObjectDeleteMixin, RESTObject): pass @@ -320,6 +331,7 @@ class User(SaveMixin, ObjectDeleteMixin, RESTObject): ("emails", "UserEmailManager"), ("events", "UserEventManager"), ("gpgkeys", "UserGPGKeyManager"), + ("identityproviders", "UserIdentityProviderManager"), ("impersonationtokens", "UserImpersonationTokenManager"), ("keys", "UserKeyManager"), ("memberships", "UserMembershipManager"), @@ -1210,6 +1222,7 @@ class GroupMergeRequestManager(ListMixin, RESTManager): "source_branch", "target_branch", "search", + "wip", ) _types = {"labels": types.ListAttribute} @@ -1732,6 +1745,7 @@ class MergeRequestManager(ListMixin, RESTManager): "source_branch", "target_branch", "search", + "wip", ) _types = {"labels": types.ListAttribute} @@ -3402,6 +3416,7 @@ class ProjectMergeRequestManager(CRUDMixin, RESTManager): "source_branch", "target_branch", "search", + "wip", ) _types = {"labels": types.ListAttribute} @@ -5475,6 +5490,7 @@ class RunnerManager(CRUDMixin, RESTManager): "locked", "run_untagged", "tag_list", + "access_level", "maximum_timeout", ), ) diff --git a/tools/build_test_env.sh b/tools/build_test_env.sh index 24c56f5..e3b6d12 100755 --- a/tools/build_test_env.sh +++ b/tools/build_test_env.sh @@ -29,7 +29,7 @@ REUSE_CONTAINER= NOVENV= API_VER=4 DEFAULT_GITLAB_IMAGE=gitlab/gitlab-ce -DEFAULT_GITLAB_TAG=13.3.4-ce.0 +DEFAULT_GITLAB_TAG=13.3.5-ce.0 GITLAB_IMAGE="${GITLAB_IMAGE:-$DEFAULT_GITLAB_IMAGE}" GITLAB_TAG="${GITLAB_TAG:-$DEFAULT_GITLAB_TAG}" VENV_CMD="python3 -m venv" diff --git a/tools/functional/api/test_users.py b/tools/functional/api/test_users.py new file mode 100644 index 0000000..f70da4a --- /dev/null +++ b/tools/functional/api/test_users.py @@ -0,0 +1,20 @@ +""" +GitLab API: +https://docs.gitlab.com/ee/api/users.html +https://docs.gitlab.com/ee/api/users.html#delete-authentication-identity-from-user +""" + + +def test_user_identities(gl, user): + provider = "test_provider" + + user.provider = provider + user.extern_uid = "1" + user.save() + + assert provider in [item["provider"] for item in user.identities] + + user.identityproviders.delete(provider) + user = gl.users.get(user.id) + + assert provider not in [item["provider"] for item in user.identities] |
