diff --git a/gitlab/tests/objects/test_projects.py b/gitlab/tests/objects/test_projects.py index 237a9bee7..d87f75930 100644 --- a/gitlab/tests/objects/test_projects.py +++ b/gitlab/tests/objects/test_projects.py @@ -8,13 +8,118 @@ import requests from gitlab import * # noqa from gitlab.v4.objects import * # noqa -from httmock import HTTMock, urlmatch, response # noqa +from httmock import HTTMock, urlmatch, response, with_httmock # noqa headers = {"content-type": "application/json"} +binary_content = b"binary content" -class TestProjectSnippets(unittest.TestCase): +@urlmatch( + scheme="http", netloc="localhost", path="/api/v4/projects/1/export", method="post", +) +def resp_create_export(url, request): + """Common mock for Project Export tests.""" + content = """{ + "message": "202 Accepted" + }""" + content = content.encode("utf-8") + return response(202, content, headers, None, 25, request) + + +@urlmatch( + scheme="http", netloc="localhost", path="/api/v4/projects/1/export", method="get", +) +def resp_export_status(url, request): + """Mock for Project Export GET response.""" + content = """{ + "id": 1, + "description": "Itaque perspiciatis minima aspernatur", + "name": "Gitlab Test", + "name_with_namespace": "Gitlab Org / Gitlab Test", + "path": "gitlab-test", + "path_with_namespace": "gitlab-org/gitlab-test", + "created_at": "2017-08-29T04:36:44.383Z", + "export_status": "finished", + "_links": { + "api_url": "https://gitlab.test/api/v4/projects/1/export/download", + "web_url": "https://gitlab.test/gitlab-test/download_export" + } + } + """ + content = content.encode("utf-8") + return response(200, content, headers, None, 25, request) + + +@urlmatch( + scheme="http", + netloc="localhost", + path="/api/v4/projects/1/export/download", + method="get", +) +def resp_download_export(url, request): + """Mock for Project Export Download GET response.""" + headers = {"content-type": "application/octet-stream"} + content = binary_content + return response(200, content, headers, None, 25, request) + + +@urlmatch( + scheme="http", netloc="localhost", path="/api/v4/projects/import", method="post", +) +def resp_import_project(url, request): + """Mock for Project Import POST response.""" + content = """{ + "id": 1, + "description": null, + "name": "api-project", + "name_with_namespace": "Administrator / api-project", + "path": "api-project", + "path_with_namespace": "root/api-project", + "created_at": "2018-02-13T09:05:58.023Z", + "import_status": "scheduled" + }""" + content = content.encode("utf-8") + return response(200, content, headers, None, 25, request) + + +@urlmatch( + scheme="http", netloc="localhost", path="/api/v4/projects/1/import", method="get", +) +def resp_import_status(url, request): + """Mock for Project Import GET response.""" + content = """{ + "id": 1, + "description": "Itaque perspiciatis minima aspernatur corporis consequatur.", + "name": "Gitlab Test", + "name_with_namespace": "Gitlab Org / Gitlab Test", + "path": "gitlab-test", + "path_with_namespace": "gitlab-org/gitlab-test", + "created_at": "2017-08-29T04:36:44.383Z", + "import_status": "finished" + }""" + content = content.encode("utf-8") + return response(200, content, headers, None, 25, request) + + +@urlmatch( + scheme="http", netloc="localhost", path="/api/v4/import/github", method="post", +) +def resp_import_github(url, request): + """Mock for GitHub Project Import POST response.""" + content = """{ + "id": 27, + "name": "my-repo", + "full_path": "/root/my-repo", + "full_name": "Administrator / my-repo" + }""" + content = content.encode("utf-8") + return response(200, content, headers, None, 25, request) + + +class TestProject(unittest.TestCase): + """Base class for GitLab Project tests.""" + def setUp(self): self.gl = Gitlab( "http://localhost", @@ -22,7 +127,10 @@ def setUp(self): ssl_verify=True, api_version=4, ) + self.project = self.gl.projects.get(1, lazy=True) + +class TestProjectSnippets(TestProject): def test_list_project_snippets(self): title = "Example Snippet Title" visibility = "private" @@ -47,7 +155,7 @@ def resp_list_snippet(url, request): return response(200, content, headers, None, 25, request) with HTTMock(resp_list_snippet): - snippets = self.gl.projects.get(1, lazy=True).snippets.list() + snippets = self.project.snippets.list() self.assertEqual(len(snippets), 1) self.assertEqual(snippets[0].title, title) self.assertEqual(snippets[0].visibility, visibility) @@ -76,7 +184,7 @@ def resp_get_snippet(url, request): return response(200, content, headers, None, 25, request) with HTTMock(resp_get_snippet): - snippet = self.gl.projects.get(1, lazy=True).snippets.get(1) + snippet = self.project.snippets.get(1) self.assertEqual(snippet.title, title) self.assertEqual(snippet.visibility, visibility) @@ -123,7 +231,7 @@ def resp_create_snippet(url, request): return response(200, content, headers, None, 25, request) with HTTMock(resp_create_snippet, resp_update_snippet): - snippet = self.gl.projects.get(1, lazy=True).snippets.create( + snippet = self.project.snippets.create( { "title": title, "file_name": title, @@ -138,3 +246,46 @@ def resp_create_snippet(url, request): snippet.save() self.assertEqual(snippet.title, title) self.assertEqual(snippet.visibility, visibility) + + +class TestProjectExport(TestProject): + @with_httmock(resp_create_export) + def test_create_project_export(self): + export = self.project.exports.create() + self.assertEqual(export.message, "202 Accepted") + + @with_httmock(resp_create_export, resp_export_status) + def test_refresh_project_export_status(self): + export = self.project.exports.create() + export.refresh() + self.assertEqual(export.export_status, "finished") + + @with_httmock(resp_create_export, resp_download_export) + def test_download_project_export(self): + export = self.project.exports.create() + download = export.download() + self.assertIsInstance(download, bytes) + self.assertEqual(download, binary_content) + + +class TestProjectImport(TestProject): + @with_httmock(resp_import_project) + def test_import_project(self): + project_import = self.gl.projects.import_project("file", "api-project") + self.assertEqual(project_import["import_status"], "scheduled") + + @with_httmock(resp_import_status) + def test_refresh_project_import_status(self): + project_import = self.project.imports.get() + project_import.refresh() + self.assertEqual(project_import.import_status, "finished") + + @with_httmock(resp_import_github) + def test_import_github(self): + base_path = "/root" + name = "my-repo" + ret = self.gl.projects.import_github("githubkey", 1234, base_path, name) + self.assertIsInstance(ret, dict) + self.assertEqual(ret["name"], name) + self.assertEqual(ret["full_path"], "/".join((base_path, name))) + self.assertTrue(ret["full_name"].endswith(name)) diff --git a/gitlab/tests/test_gitlab.py b/gitlab/tests/test_gitlab.py index 249d0c50d..591f166ec 100644 --- a/gitlab/tests/test_gitlab.py +++ b/gitlab/tests/test_gitlab.py @@ -937,33 +937,6 @@ def resp_update_submodule(url, request): self.assertEqual(ret["message"], "Message") self.assertEqual(ret["id"], "ed899a2f4b50b4370feeea94676502b42383c746") - def test_import_github(self): - @urlmatch( - scheme="http", - netloc="localhost", - path="/api/v4/import/github", - method="post", - ) - def resp_import_github(url, request): - headers = {"content-type": "application/json"} - content = """{ - "id": 27, - "name": "my-repo", - "full_path": "/root/my-repo", - "full_name": "Administrator / my-repo" - }""" - content = content.encode("utf-8") - return response(200, content, headers, None, 25, request) - - with HTTMock(resp_import_github): - base_path = "/root" - name = "my-repo" - ret = self.gl.projects.import_github("githubkey", 1234, base_path, name) - self.assertIsInstance(ret, dict) - self.assertEqual(ret["name"], name) - self.assertEqual(ret["full_path"], "/".join((base_path, name))) - self.assertTrue(ret["full_name"].endswith(name)) - def test_applications(self): content = '{"name": "test_app", "redirect_uri": "http://localhost:8080", "scopes": ["api", "email"]}' json_content = json.loads(content) diff --git a/gitlab/v4/objects.py b/gitlab/v4/objects.py index f832b7112..9da9adf2c 100644 --- a/gitlab/v4/objects.py +++ b/gitlab/v4/objects.py @@ -4839,6 +4839,7 @@ def import_project( self, file, path, + name=None, namespace=None, overwrite=False, override_params=None, @@ -4868,6 +4869,8 @@ def import_project( if override_params: for k, v in override_params.items(): data["override_params[%s]" % k] = v + if name is not None: + data["name"] = name if namespace: data["namespace"] = namespace return self.gitlab.http_post( diff --git a/tools/python_test_v4.py b/tools/python_test_v4.py index 90aa7f162..fad8c69eb 100644 --- a/tools/python_test_v4.py +++ b/tools/python_test_v4.py @@ -962,9 +962,13 @@ ex.download(streamed=True, action=f.write) output = gl.projects.import_project( - open("/tmp/gitlab-export.tgz", "rb"), "imported_project" + open("/tmp/gitlab-export.tgz", "rb"), "imported_project", name="Imported Project" ) project_import = gl.projects.get(output["id"], lazy=True).imports.get() + +assert project_import.path == "imported_project" +assert project_import.name == "Imported Project" + count = 0 while project_import.import_status != "finished": time.sleep(1)