Skip to content

Commit

Permalink
Merge pull request #664 from shoshoi/master
Browse files Browse the repository at this point in the history
Add project export API
  • Loading branch information
NARKOZ authored Jun 13, 2024
2 parents 19517d5 + 20dcfdf commit 0c154ae
Show file tree
Hide file tree
Showing 6 changed files with 125 additions and 1 deletion.
54 changes: 54 additions & 0 deletions lib/gitlab/client/project_exports.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
# frozen_string_literal: true

class Gitlab::Client
# Defines methods related to project exports.
# @see https://docs.gitlab.com/ce/api/project_import_export.html
module ProjectExports
# Start a new export
#
# @example
# Gitlab.export_project(2)
#
# @param [Integer, String] id The ID or path of a project.
# @param [Hash] options A customizable set of options.
# @option options [String] description(optional) Overrides the project description
# @option options [hash] upload(optional) Hash that contains the information to upload the exported project to a web server
# @option options [String] upload[url] TThe URL to upload the project
# @option options [String] upload[http_method](optional) The HTTP method to upload the exported project. Only PUT and POST methods allowed. Default is PUT
# @return [Gitlab::ObjectifiedHash]
def export_project(id, options = {})
post("/projects/#{url_encode id}/export", body: options)
end

# Get the status of export
#
# @example
# Gitlab.export_project_status(2)
#
# @param [Integer, String] id The ID or path of a project.
# @return [Gitlab::ObjectifiedHash]
def export_project_status(id)
get("/projects/#{url_encode id}/export")
end

# Download the finished export
#
# @example
# Gitlab.exported_project_download(2)
#
# @param [Integer, String] id The ID or path of a project.
# @return [Gitlab::FileResponse]
def exported_project_download(id)
get("/projects/#{url_encode id}/export/download",
format: nil,
headers: { Accept: 'application/octet-stream' },
parser: proc { |body, _|
if body.encoding == Encoding::ASCII_8BIT # binary response
::Gitlab::FileResponse.new StringIO.new(body, 'rb+')
else # error with json response
::Gitlab::Request.parse(body)
end
})
end
end
end
Binary file added spec/fixtures/exported_project_download.tar.gz
Binary file not shown.
1 change: 1 addition & 0 deletions spec/fixtures/project_export.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"message": "202 Accepted"}
1 change: 1 addition & 0 deletions spec/fixtures/project_export_status.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"export_status": "none"}
68 changes: 68 additions & 0 deletions spec/gitlab/client/projects_export_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe Gitlab::Client do
describe '.export_project' do
before do
stub_post('/projects/1/export', 'project_export')
@export_project = Gitlab.export_project(1, { description: 'test_description-path', upload: { url: 'https://example.com/', http_method: 'POST' } })
end

it 'gets the correct resource' do
expect(a_post('/projects/1/export')
.with(body: { description: 'test_description-path', upload: { url: 'https://example.com/', http_method: 'POST' } })).to have_been_made
end

it 'returns information about the project export request' do
expect(@export_project.message).to eq('202 Accepted')
end
end

describe '.project_export_status' do
before do
stub_get('/projects/1/export', 'project_export_status')
@export_project = Gitlab.export_project_status(1)
end

it 'gets the correct resource' do
expect(a_get('/projects/1/export')).to have_been_made
end

it 'returns information about the project export status' do
expect(@export_project.export_status).to eq('none')
end
end

describe '.exported_project_download' do
context 'when successful request' do
before do
fixture = load_fixture('exported_project_download.tar.gz')
fixture.set_encoding(Encoding::ASCII_8BIT)
stub_request(:get, "#{Gitlab.endpoint}/projects/1/export/download")
.with(headers: { 'PRIVATE-TOKEN' => Gitlab.private_token })
.to_return(body: fixture.read, headers: { 'Content-Disposition' => 'attachment; filename=exported_project_download.tar.gz' })
@exported_project = Gitlab.exported_project_download(1)
end

it 'gets the correct resource' do
expect(a_get('/projects/1/export/download')).to have_been_made
end

it 'returns a FileResponse' do
expect(@exported_project).to be_a Gitlab::FileResponse
end

it 'returns a file with filename' do
expect(@exported_project.filename).to eq 'exported_project_download.tar.gz'
end
end

context 'when bad request' do
it 'throws an exception' do
stub_get('/projects/1/export/download', 'error_project_not_found', 404)
expect { Gitlab.exported_project_download(1) }.to raise_error(Gitlab::Error::NotFound, "Server responded with code 404, message: 404 Project Not Found. Request URI: #{Gitlab.endpoint}/projects/1/export/download")
end
end
end
end
2 changes: 1 addition & 1 deletion spec/spec_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
require File.expand_path('../lib/gitlab/cli', __dir__)

def load_fixture(name)
name, extension = name.split('.')
name, extension = name.split('.', 2)
File.new(File.dirname(__FILE__) + "/fixtures/#{name}.#{extension || 'json'}")
end

Expand Down

0 comments on commit 0c154ae

Please sign in to comment.