From 67942f0d46b7d445f28f80d3f57aa91eeea97a24 Mon Sep 17 00:00:00 2001 From: Antoine Auger Date: Tue, 14 Jun 2022 17:05:44 +0200 Subject: [PATCH 1/3] test(projects): add unit tests for projects --- tests/unit/conftest.py | 5 + .../objects/test_project_import_export.py | 45 +- tests/unit/objects/test_projects.py | 587 +++++++++++++++--- 3 files changed, 537 insertions(+), 100 deletions(-) diff --git a/tests/unit/conftest.py b/tests/unit/conftest.py index 929be1a65..5d3bfd5c9 100644 --- a/tests/unit/conftest.py +++ b/tests/unit/conftest.py @@ -69,6 +69,11 @@ def project(gl): return gl.projects.get(1, lazy=True) +@pytest.fixture +def another_project(gl): + return gl.projects.get(2, lazy=True) + + @pytest.fixture def project_issue(project): return project.issues.get(1, lazy=True) diff --git a/tests/unit/objects/test_project_import_export.py b/tests/unit/objects/test_project_import_export.py index 78e51b1fe..450acc0ad 100644 --- a/tests/unit/objects/test_project_import_export.py +++ b/tests/unit/objects/test_project_import_export.py @@ -73,8 +73,36 @@ def resp_import_github(): yield rsps +@pytest.fixture +def resp_import_bitbucket_server(): + content = { + "id": 1, + "name": "project", + "import_status": "scheduled", + } + + with responses.RequestsMock() as rsps: + rsps.add( + method=responses.POST, + url="http://localhost/api/v4/import/bitbucket_server", + json=content, + content_type="application/json", + status=201, + ) + yield rsps + + def test_import_project(gl, resp_import_project): - project_import = gl.projects.import_project("file", "api-project") + project_import = gl.projects.import_project( + "file", "api-project", "api-project", "root" + ) + assert project_import["import_status"] == "scheduled" + + +def test_import_project_with_override_params(gl, resp_import_project): + project_import = gl.projects.import_project( + "file", "api-project", override_params={"visibility": "private"} + ) assert project_import["import_status"] == "scheduled" @@ -94,6 +122,21 @@ def test_import_github(gl, resp_import_github): assert ret["full_name"].endswith(name) +def test_import_bitbucket_server(gl, resp_import_bitbucket_server): + res = gl.projects.import_bitbucket_server( + bitbucket_server_project="project", + bitbucket_server_repo="repo", + bitbucket_server_url="url", + bitbucket_server_username="username", + personal_access_token="token", + new_name="new_name", + target_namespace="namespace", + ) + assert res["id"] == 1 + assert res["name"] == "project" + assert res["import_status"] == "scheduled" + + def test_create_project_export(project, resp_export): export = project.exports.create() assert export.message == "202 Accepted" diff --git a/tests/unit/objects/test_projects.py b/tests/unit/objects/test_projects.py index f964d114c..914aa8d65 100644 --- a/tests/unit/objects/test_projects.py +++ b/tests/unit/objects/test_projects.py @@ -2,9 +2,13 @@ GitLab API: https://docs.gitlab.com/ce/api/projects.html """ +from unittest.mock import mock_open, patch + import pytest import responses +from gitlab import exceptions +from gitlab.const import DEVELOPER_ACCESS, SEARCH_SCOPE_ISSUES from gitlab.v4.objects import ( Project, ProjectFork, @@ -15,6 +19,11 @@ from gitlab.v4.objects.projects import ProjectStorage project_content = {"name": "name", "id": 1} +project_with_owner_content = { + "name": "name", + "id": 1, + "owner": {"id": 1, "username": "owner_username", "name": "owner_name"}, +} languages_content = { "python": 80.00, "ruby": 99.99, @@ -30,10 +39,49 @@ "id": 1, }, ] -import_content = { +project_forked_from_content = { + "name": "name", + "id": 2, + "forks_count": 0, + "forked_from_project": {"id": 1, "name": "name", "forks_count": 1}, +} +project_starrers_content = { + "starred_since": "2019-01-28T14:47:30.642Z", + "user": { + "id": 1, + "name": "name", + }, +} +delete_project_content = {"message": "202 Accepted"} +upload_file_content = { + "alt": "filename", + "url": "/uploads/66dbcd21ec5d24ed6ea225176098d52b/filename.png", + "full_path": "/namespace/project/uploads/66dbcd21ec5d24ed6ea225176098d52b/filename.png", + "markdown": "![dk](/uploads/66dbcd21ec5d24ed6ea225176098d52b/filename.png)", +} +share_project_content = { + "id": 1, + "project_id": 1, + "group_id": 1, + "group_access": 30, + "expires_at": None, +} +push_rules_content = {"id": 1, "deny_delete_tag": True} +search_issues_content = [ + { + "id": 1, + "iid": 1, + "project_id": 1, + "title": "Issue", + } +] +pipeline_trigger_content = { "id": 1, - "name": "project", - "import_status": "scheduled", + "iid": 1, + "project_id": 1, + "ref": "main", + "status": "created", + "source": "trigger", } @@ -50,6 +98,58 @@ def resp_get_project(): yield rsps +@pytest.fixture +def resp_post_project(): + with responses.RequestsMock() as rsps: + rsps.add( + method=responses.POST, + url="http://localhost/api/v4/projects", + json=project_content, + content_type="application/json", + status=201, + ) + yield rsps + + +@pytest.fixture +def resp_post_project_user(): + with responses.RequestsMock() as rsps: + rsps.add( + method=responses.POST, + url="http://localhost/api/v4/projects/user/1", + json=project_with_owner_content, + content_type="application/json", + status=201, + ) + yield rsps + + +@pytest.fixture +def resp_post_fork_project(): + with responses.RequestsMock() as rsps: + rsps.add( + method=responses.POST, + url="http://localhost/api/v4/projects/1/fork", + json=project_forked_from_content, + content_type="application/json", + status=201, + ) + yield rsps + + +@pytest.fixture +def resp_put_project(): + with responses.RequestsMock() as rsps: + rsps.add( + method=responses.PUT, + url="http://localhost/api/v4/projects/1", + json=project_content, + content_type="application/json", + status=201, + ) + yield rsps + + @pytest.fixture def resp_get_project_storage(): with responses.RequestsMock() as rsps: @@ -76,6 +176,45 @@ def resp_user_projects(): yield rsps +@pytest.fixture +def resp_star_project(): + with responses.RequestsMock() as rsps: + rsps.add( + method=responses.POST, + url="http://localhost/api/v4/projects/1/star", + json=project_content, + content_type="application/json", + status=201, + ) + yield rsps + + +@pytest.fixture +def resp_unstar_project(): + with responses.RequestsMock() as rsps: + rsps.add( + method=responses.POST, + url="http://localhost/api/v4/projects/1/unstar", + json=project_content, + content_type="application/json", + status=201, + ) + yield rsps + + +@pytest.fixture +def resp_project_starrers(): + with responses.RequestsMock() as rsps: + rsps.add( + method=responses.GET, + url="http://localhost/api/v4/projects/1/starrers", + json=[project_starrers_content], + content_type="application/json", + status=200, + ) + yield rsps + + @pytest.fixture def resp_starred_projects(): with responses.RequestsMock() as rsps: @@ -142,12 +281,41 @@ def resp_list_projects(): @pytest.fixture -def resp_import_bitbucket_server(): +def resp_transfer_project(): + with responses.RequestsMock() as rsps: + rsps.add( + method=responses.PUT, + url="http://localhost/api/v4/projects/1/transfer", + json=project_content, + content_type="application/json", + status=200, + match=[ + responses.matchers.json_params_matcher({"namespace": "test-namespace"}) + ], + ) + yield rsps + + +@pytest.fixture +def resp_archive_project(): + with responses.RequestsMock() as rsps: + rsps.add( + method=responses.POST, + url="http://localhost/api/v4/projects/1/archive", + json=project_content, + content_type="application/json", + status=201, + ) + yield rsps + + +@pytest.fixture +def resp_unarchive_project(): with responses.RequestsMock() as rsps: rsps.add( method=responses.POST, - url="http://localhost/api/v4/import/bitbucket_server", - json=import_content, + url="http://localhost/api/v4/projects/1/unarchive", + json=project_content, content_type="application/json", status=201, ) @@ -155,17 +323,221 @@ def resp_import_bitbucket_server(): @pytest.fixture -def resp_transfer_project(): +def resp_delete_project(): with responses.RequestsMock() as rsps: rsps.add( - method=responses.PUT, - url="http://localhost/api/v4/projects/1/transfer", + method=responses.DELETE, + url="http://localhost/api/v4/projects/1", + json=delete_project_content, + content_type="application/json", + status=202, + ) + yield rsps + + +@pytest.fixture +def resp_upload_file_project(): + with responses.RequestsMock() as rsps: + rsps.add( + method=responses.POST, + url="http://localhost/api/v4/projects/1/uploads", + json=upload_file_content, + content_type="application/json", + status=201, + ) + yield rsps + + +@pytest.fixture +def resp_share_project(): + with responses.RequestsMock() as rsps: + rsps.add( + method=responses.POST, + url="http://localhost/api/v4/projects/1/share", + json=share_project_content, + content_type="application/json", + status=201, + ) + yield rsps + + +@pytest.fixture +def resp_unshare_project(): + with responses.RequestsMock() as rsps: + rsps.add( + method=responses.DELETE, + url="http://localhost/api/v4/projects/1/share/1", + json=None, + content_type="application/json", + status=204, + ) + yield rsps + + +@pytest.fixture +def resp_create_fork_relation(): + with responses.RequestsMock() as rsps: + rsps.add( + method=responses.POST, + url="http://localhost/api/v4/projects/2/fork/1", json=project_content, content_type="application/json", + status=201, + ) + yield rsps + + +@pytest.fixture +def resp_delete_fork_relation(): + with responses.RequestsMock() as rsps: + rsps.add( + method=responses.DELETE, + url="http://localhost/api/v4/projects/2/fork", + json=None, + content_type="application/json", + status=204, + ) + yield rsps + + +@pytest.fixture +def resp_trigger_pipeline(): + with responses.RequestsMock() as rsps: + rsps.add( + method=responses.POST, + url="http://localhost/api/v4/projects/1/trigger/pipeline", + json=pipeline_trigger_content, + content_type="application/json", + status=201, + ) + yield rsps + + +@pytest.fixture +def resp_search_project_resources_by_name(): + with responses.RequestsMock() as rsps: + rsps.add( + method=responses.GET, + url="http://localhost/api/v4/projects/1/search?scope=issues&search=Issue", + json=search_issues_content, + content_type="application/json", + status=200, + ) + yield rsps + + +@pytest.fixture +def resp_start_housekeeping(): + with responses.RequestsMock() as rsps: + rsps.add( + method=responses.POST, + url="http://localhost/api/v4/projects/1/housekeeping", + json="0ee4c430667fb7be8461f310", + content_type="application/json", + status=201, + ) + yield rsps + + +@pytest.fixture +def resp_get_push_rules_project(): + with responses.RequestsMock() as rsps: + rsps.add( + method=responses.GET, + url="http://localhost/api/v4/projects/1/push_rule", + json=push_rules_content, + content_type="application/json", + status=200, + ) + yield rsps + + +@pytest.fixture +def resp_post_push_rules_project(): + with responses.RequestsMock() as rsps: + rsps.add( + method=responses.POST, + url="http://localhost/api/v4/projects/1/push_rule", + json=push_rules_content, + content_type="application/json", + status=201, + ) + yield rsps + + +@pytest.fixture +def resp_update_push_rules_project(): + with responses.RequestsMock() as rsps: + rsps.add( + method=responses.GET, + url="http://localhost/api/v4/projects/1/push_rule", + json=push_rules_content, + content_type="application/json", + status=200, + ) + rsps.add( + method=responses.PUT, + url="http://localhost/api/v4/projects/1/push_rule", + json=push_rules_content, + content_type="application/json", + status=201, + ) + yield rsps + + +@pytest.fixture +def resp_delete_push_rules_project(): + with responses.RequestsMock() as rsps: + rsps.add( + method=responses.GET, + url="http://localhost/api/v4/projects/1/push_rule", + json=push_rules_content, + content_type="application/json", + status=200, + ) + rsps.add( + method=responses.DELETE, + url="http://localhost/api/v4/projects/1/push_rule", + json=None, + content_type="application/json", + status=204, + ) + yield rsps + + +@pytest.fixture +def resp_start_pull_mirroring_project(): + with responses.RequestsMock() as rsps: + rsps.add( + method=responses.POST, + url="http://localhost/api/v4/projects/1/mirror/pull", + json={}, + content_type="application/json", + status=201, + ) + yield rsps + + +@pytest.fixture +def resp_snapshot_project(): + with responses.RequestsMock() as rsps: + rsps.add( + method=responses.GET, + url="http://localhost/api/v4/projects/1/snapshot", + content_type="application/x-tar", + status=200, + ) + yield rsps + + +@pytest.fixture +def resp_artifact(): + with responses.RequestsMock() as rsps: + rsps.add( + method=responses.GET, + url="http://localhost/api/v4/projects/1/jobs/artifacts/ref_name/raw/artifact_path?job=job", + content_type="application/x-tar", status=200, - match=[ - responses.matchers.json_params_matcher({"namespace": "test-namespace"}) - ], ) yield rsps @@ -183,21 +555,6 @@ def test_list_projects(gl, resp_list_projects): assert projects[0].name == "name" -def test_import_bitbucket_server(gl, resp_import_bitbucket_server): - res = gl.projects.import_bitbucket_server( - bitbucket_server_project="project", - bitbucket_server_repo="repo", - bitbucket_server_url="url", - bitbucket_server_username="username", - personal_access_token="token", - new_name="new_name", - target_namespace="namespace", - ) - assert res["id"] == 1 - assert res["name"] == "project" - assert res["import_status"] == "scheduled" - - def test_list_user_projects(user, resp_user_projects): user_project = user.projects.list()[0] assert isinstance(user_project, UserProject) @@ -220,24 +577,36 @@ def test_list_project_users(project, resp_list_users): assert user.state == "active" -@pytest.mark.skip(reason="missing test") -def test_create_project(gl): - pass +def test_create_project(gl, resp_post_project): + project = gl.projects.create({"name": "name"}) + assert project.id == 1 + assert project.name == "name" -@pytest.mark.skip(reason="missing test") -def test_create_user_project(gl): - pass +def test_create_user_project(user, resp_post_project_user): + user_project = user.projects.create({"name": "name"}) + assert user_project.id == 1 + assert user_project.name == "name" + assert user_project.owner + assert user_project.owner.get("id") == user.id + assert user_project.owner.get("name") == "owner_name" + assert user_project.owner.get("username") == "owner_username" -@pytest.mark.skip(reason="missing test") -def test_update_project(gl): - pass +def test_update_project(project, resp_put_project): + project.snippets_enabled = 1 + project.save() -@pytest.mark.skip(reason="missing test") -def test_fork_project(gl): - pass +def test_fork_project(project, resp_post_fork_project): + fork = project.forks.create({}) + assert fork.id == 2 + assert fork.name == "name" + assert fork.forks_count == 0 + assert fork.forked_from_project + assert fork.forked_from_project.get("id") == project.id + assert fork.forked_from_project.get("name") == "name" + assert fork.forked_from_project.get("forks_count") == 1 def test_list_project_forks(project, resp_list_forks): @@ -246,18 +615,16 @@ def test_list_project_forks(project, resp_list_forks): assert fork.id == 1 -@pytest.mark.skip(reason="missing test") -def test_star_project(gl): - pass +def test_star_project(project, resp_star_project): + project.star() -@pytest.mark.skip(reason="missing test") -def test_unstar_project(gl): - pass +def test_unstar_project(project, resp_unstar_project): + project.unstar() @pytest.mark.skip(reason="missing test") -def test_list_project_starrers(gl): +def test_list_project_starrers(project, resp_project_starrers): pass @@ -276,19 +643,16 @@ def test_get_project_storage(project, resp_get_project_storage): assert storage.disk_path == "/disk/path" -@pytest.mark.skip(reason="missing test") -def test_archive_project(gl): - pass +def test_archive_project(project, resp_archive_project): + project.archive() -@pytest.mark.skip(reason="missing test") -def test_unarchive_project(gl): - pass +def test_unarchive_project(project, resp_unarchive_project): + project.unarchive() -@pytest.mark.skip(reason="missing test") -def test_remove_project(gl): - pass +def test_delete_project(project, resp_delete_project): + project.delete() @pytest.mark.skip(reason="missing test") @@ -296,80 +660,105 @@ def test_restore_project(gl): pass -@pytest.mark.skip(reason="missing test") -def test_upload_file(gl): - pass +def test_upload_file(project, resp_upload_file_project): + project.upload("filename.png", "raw\nfile\ndata") -@pytest.mark.skip(reason="missing test") -def test_share_project(gl): - pass +def test_upload_file_with_filepath(project, resp_upload_file_project): + with patch("builtins.open", mock_open(read_data="raw\nfile\ndata")): + project.upload("filename.png", None, "/filepath") -@pytest.mark.skip(reason="missing test") -def test_delete_shared_project_link(gl): - pass +def test_upload_file_without_filepath_nor_filedata(project): + with pytest.raises( + exceptions.GitlabUploadError, match="No file contents or path specified" + ): + project.upload("filename.png") -@pytest.mark.skip(reason="missing test") -def test_create_forked_from_relationship(gl): - pass +def test_upload_file_with_filepath_and_filedata(project): + with pytest.raises( + exceptions.GitlabUploadError, match="File contents and file path specified" + ): + project.upload("filename.png", "filedata", "/filepath") -@pytest.mark.skip(reason="missing test") -def test_delete_forked_from_relationship(gl): - pass +def test_share_project(project, group, resp_share_project): + project.share(group.id, DEVELOPER_ACCESS) -@pytest.mark.skip(reason="missing test") -def test_search_projects_by_name(gl): - pass +def test_delete_shared_project_link(project, group, resp_unshare_project): + project.unshare(group.id) -@pytest.mark.skip(reason="missing test") -def test_project_housekeeping(gl): - pass +def test_trigger_pipeline_project(project, resp_trigger_pipeline): + project.trigger_pipeline("MOCK_PIPELINE_TRIGGER_TOKEN", "main") -@pytest.mark.skip(reason="missing test") -def test_get_project_push_rules(gl): - pass +def test_create_forked_from_relationship( + project, another_project, resp_create_fork_relation +): + another_project.create_fork_relation(project.id) -@pytest.mark.skip(reason="missing test") -def test_create_project_push_rule(gl): - pass +def test_delete_forked_from_relationship(another_project, resp_delete_fork_relation): + another_project.delete_fork_relation() -@pytest.mark.skip(reason="missing test") -def test_update_project_push_rule(gl): - pass +def test_search_project_resources_by_name( + project, resp_search_project_resources_by_name +): + issue = project.search(SEARCH_SCOPE_ISSUES, "Issue")[0] + assert issue + assert issue.get("title") == "Issue" -@pytest.mark.skip(reason="missing test") -def test_delete_project_push_rule(gl): - pass +def test_project_housekeeping(project, resp_start_housekeeping): + project.housekeeping() + + +def test_get_project_push_rules(project, resp_get_push_rules_project): + pr = project.pushrules.get() + assert pr + assert pr.deny_delete_tag + + +def test_create_project_push_rule(project, resp_post_push_rules_project): + project.pushrules.create({"deny_delete_tag": True}) + + +def test_update_project_push_rule( + project, + resp_update_push_rules_project, +): + pr = project.pushrules.get() + pr.deny_delete_tag = False + pr.save() + + +def test_delete_project_push_rule(project, resp_delete_push_rules_project): + pr = project.pushrules.get() + pr.delete() def test_transfer_project(project, resp_transfer_project): project.transfer("test-namespace") -def test_transfer_project_deprecated_warns(project, resp_transfer_project): +def test_artifact_project(project, resp_artifact): with pytest.warns(DeprecationWarning): - project.transfer_project("test-namespace") + project.artifact("ref_name", "artifact_path", "job") -@pytest.mark.skip(reason="missing test") -def test_project_pull_mirror(gl): - pass +def test_transfer_project_deprecated_warns(project, resp_transfer_project): + with pytest.warns(DeprecationWarning): + project.transfer_project("test-namespace") -@pytest.mark.skip(reason="missing test") -def test_project_snapshot(gl): - pass +def test_project_pull_mirror(project, resp_start_pull_mirroring_project): + project.mirror_pull() -@pytest.mark.skip(reason="missing test") -def test_import_github(gl): - pass +def test_project_snapshot(project, resp_snapshot_project): + tar_file = project.snapshot() + assert isinstance(tar_file, bytes) From 9be0875c3793324b4c4dde29519ee62b39a8cc18 Mon Sep 17 00:00:00 2001 From: Antoine Auger Date: Thu, 16 Jun 2022 11:07:42 +0200 Subject: [PATCH 2/3] refactor(test-projects): remove test_restore_project --- tests/unit/objects/test_projects.py | 5 ----- 1 file changed, 5 deletions(-) diff --git a/tests/unit/objects/test_projects.py b/tests/unit/objects/test_projects.py index 914aa8d65..7033a12d1 100644 --- a/tests/unit/objects/test_projects.py +++ b/tests/unit/objects/test_projects.py @@ -655,11 +655,6 @@ def test_delete_project(project, resp_delete_project): project.delete() -@pytest.mark.skip(reason="missing test") -def test_restore_project(gl): - pass - - def test_upload_file(project, resp_upload_file_project): project.upload("filename.png", "raw\nfile\ndata") From a51f848db4204b2f37ae96fd235ae33cb7c2fe98 Mon Sep 17 00:00:00 2001 From: Antoine Auger Date: Wed, 29 Jun 2022 10:57:37 +0200 Subject: [PATCH 3/3] refactor(test-projects): apply suggestions and use fixtures --- tests/unit/objects/test_projects.py | 53 ++++++++++++++--------------- 1 file changed, 26 insertions(+), 27 deletions(-) diff --git a/tests/unit/objects/test_projects.py b/tests/unit/objects/test_projects.py index 7033a12d1..85bae8600 100644 --- a/tests/unit/objects/test_projects.py +++ b/tests/unit/objects/test_projects.py @@ -52,7 +52,6 @@ "name": "name", }, } -delete_project_content = {"message": "202 Accepted"} upload_file_content = { "alt": "filename", "url": "/uploads/66dbcd21ec5d24ed6ea225176098d52b/filename.png", @@ -99,7 +98,7 @@ def resp_get_project(): @pytest.fixture -def resp_post_project(): +def resp_create_project(): with responses.RequestsMock() as rsps: rsps.add( method=responses.POST, @@ -112,7 +111,7 @@ def resp_post_project(): @pytest.fixture -def resp_post_project_user(): +def resp_create_user_project(): with responses.RequestsMock() as rsps: rsps.add( method=responses.POST, @@ -125,7 +124,7 @@ def resp_post_project_user(): @pytest.fixture -def resp_post_fork_project(): +def resp_fork_project(): with responses.RequestsMock() as rsps: rsps.add( method=responses.POST, @@ -138,7 +137,7 @@ def resp_post_fork_project(): @pytest.fixture -def resp_put_project(): +def resp_update_project(): with responses.RequestsMock() as rsps: rsps.add( method=responses.PUT, @@ -164,7 +163,7 @@ def resp_get_project_storage(): @pytest.fixture -def resp_user_projects(): +def resp_list_user_projects(): with responses.RequestsMock() as rsps: rsps.add( method=responses.GET, @@ -203,7 +202,7 @@ def resp_unstar_project(): @pytest.fixture -def resp_project_starrers(): +def resp_list_project_starrers(): with responses.RequestsMock() as rsps: rsps.add( method=responses.GET, @@ -216,7 +215,7 @@ def resp_project_starrers(): @pytest.fixture -def resp_starred_projects(): +def resp_list_starred_projects(): with responses.RequestsMock() as rsps: rsps.add( method=responses.GET, @@ -323,12 +322,12 @@ def resp_unarchive_project(): @pytest.fixture -def resp_delete_project(): +def resp_delete_project(accepted_content): with responses.RequestsMock() as rsps: rsps.add( method=responses.DELETE, url="http://localhost/api/v4/projects/1", - json=delete_project_content, + json=accepted_content, content_type="application/json", status=202, ) @@ -362,12 +361,12 @@ def resp_share_project(): @pytest.fixture -def resp_unshare_project(): +def resp_unshare_project(no_content): with responses.RequestsMock() as rsps: rsps.add( method=responses.DELETE, url="http://localhost/api/v4/projects/1/share/1", - json=None, + json=no_content, content_type="application/json", status=204, ) @@ -388,12 +387,12 @@ def resp_create_fork_relation(): @pytest.fixture -def resp_delete_fork_relation(): +def resp_delete_fork_relation(no_content): with responses.RequestsMock() as rsps: rsps.add( method=responses.DELETE, url="http://localhost/api/v4/projects/2/fork", - json=None, + json=no_content, content_type="application/json", status=204, ) @@ -440,7 +439,7 @@ def resp_start_housekeeping(): @pytest.fixture -def resp_get_push_rules_project(): +def resp_list_push_rules_project(): with responses.RequestsMock() as rsps: rsps.add( method=responses.GET, @@ -453,7 +452,7 @@ def resp_get_push_rules_project(): @pytest.fixture -def resp_post_push_rules_project(): +def resp_create_push_rules_project(): with responses.RequestsMock() as rsps: rsps.add( method=responses.POST, @@ -486,7 +485,7 @@ def resp_update_push_rules_project(): @pytest.fixture -def resp_delete_push_rules_project(): +def resp_delete_push_rules_project(no_content): with responses.RequestsMock() as rsps: rsps.add( method=responses.GET, @@ -498,7 +497,7 @@ def resp_delete_push_rules_project(): rsps.add( method=responses.DELETE, url="http://localhost/api/v4/projects/1/push_rule", - json=None, + json=no_content, content_type="application/json", status=204, ) @@ -555,14 +554,14 @@ def test_list_projects(gl, resp_list_projects): assert projects[0].name == "name" -def test_list_user_projects(user, resp_user_projects): +def test_list_user_projects(user, resp_list_user_projects): user_project = user.projects.list()[0] assert isinstance(user_project, UserProject) assert user_project.name == "name" assert user_project.id == 1 -def test_list_user_starred_projects(user, resp_starred_projects): +def test_list_user_starred_projects(user, resp_list_starred_projects): starred_projects = user.starred_projects.list()[0] assert isinstance(starred_projects, StarredProject) assert starred_projects.name == "name" @@ -577,13 +576,13 @@ def test_list_project_users(project, resp_list_users): assert user.state == "active" -def test_create_project(gl, resp_post_project): +def test_create_project(gl, resp_create_project): project = gl.projects.create({"name": "name"}) assert project.id == 1 assert project.name == "name" -def test_create_user_project(user, resp_post_project_user): +def test_create_user_project(user, resp_create_user_project): user_project = user.projects.create({"name": "name"}) assert user_project.id == 1 assert user_project.name == "name" @@ -593,12 +592,12 @@ def test_create_user_project(user, resp_post_project_user): assert user_project.owner.get("username") == "owner_username" -def test_update_project(project, resp_put_project): +def test_update_project(project, resp_update_project): project.snippets_enabled = 1 project.save() -def test_fork_project(project, resp_post_fork_project): +def test_fork_project(project, resp_fork_project): fork = project.forks.create({}) assert fork.id == 2 assert fork.name == "name" @@ -624,7 +623,7 @@ def test_unstar_project(project, resp_unstar_project): @pytest.mark.skip(reason="missing test") -def test_list_project_starrers(project, resp_project_starrers): +def test_list_project_starrers(project, resp_list_project_starrers): pass @@ -712,13 +711,13 @@ def test_project_housekeeping(project, resp_start_housekeeping): project.housekeeping() -def test_get_project_push_rules(project, resp_get_push_rules_project): +def test_list_project_push_rules(project, resp_list_push_rules_project): pr = project.pushrules.get() assert pr assert pr.deny_delete_tag -def test_create_project_push_rule(project, resp_post_push_rules_project): +def test_create_project_push_rule(project, resp_create_push_rules_project): project.pushrules.create({"deny_delete_tag": True})