diff options
author | Dmitriy Zaporozhets <dmitriy.zaporozhets@gmail.com> | 2014-10-01 10:20:57 +0000 |
---|---|---|
committer | Dmitriy Zaporozhets <dmitriy.zaporozhets@gmail.com> | 2014-10-01 10:20:57 +0000 |
commit | ca1c35aa51f8350c09f7a0a42bbf0008941bf1b3 (patch) | |
tree | 0652e3a26d46e23289c102c3923326fff8968e20 /spec | |
parent | 8b1da505e0f46f720d5097c4850ee83f10cc8d51 (diff) | |
parent | f030ee846ed39c5e0a326e8ba117ec79f40e230d (diff) | |
download | gitlab-ce-ca1c35aa51f8350c09f7a0a42bbf0008941bf1b3.tar.gz |
Merge branch 'fork-via-API' into 'master'
API: Add support for forking a project via the API
This adds an API call to create a fork of a project.
Such API "fork button" has been requested by feature requests summing up with 37 votes.
The GitLab user has flagged one of them as accepting merge/pull requests for this feature.
Motivation:
The ability to create a fork is missing in the API.
(The API currently only supports adding and removing the "forked" relationship between two existing projects)
This feature (create fork thru the API) feature has been requested via two feature requests:
15 votes, 13 comments: to be able to fork a project through the API
http://feedback.gitlab.com/forums/176466-general/suggestions/4125380-to-be-able-to-fork-a-project-through-the-api (it was marked as completed in error by referring to the much more special change which allows to add&delete fork information)
22 votes, 3 comments: add a "fork project" API call that acts like the "fork button"
http://feedback.gitlab.com/forums/176466-general/suggestions/5820264-add-a-fork-project-api-call-that-acts-like-the
The implementation is described in the text of the commit message (click on the "..." field to open it).
A comprehensive test suite is added as well: It covers all 5 success / failure modes:
1. Success case
2. Failure if authenticated user has no access the the project to be forked
3. Failure if the forked project already exists in the authenticated user's namespace
4. Failure if the forked project does not exist
5. Failure if not authenticated
Documentation for the new API call is added to the project help page: doc/api/projects.md
I have 2 additional merge requests in progress, one is based on this feature and extend it, the other is related to querying forks.
The merge request that would be directly related is based on a request written comment of one of the feature requests (that was independently also requested in a but entry):
The ability to fork a project (thru the API) to a given namespace, eg. a group, in one case, for trainings.
As this request does not change code, but only adds a new request API for creating forks, it does not have
the capability to break existing code, and as the test spec demonstrates, it works.
It allocates the API request POST /projects/fork/:id, the only other API path I'd have thought of would have been POST /projects/:id/fork but that path is already taken by the API for creating a new fork relationship between projects, so POST /projects/fork/:id is the remaining possibility that I could see.
See merge request !191
Diffstat (limited to 'spec')
-rw-r--r-- | spec/requests/api/fork_spec.rb | 73 |
1 files changed, 73 insertions, 0 deletions
diff --git a/spec/requests/api/fork_spec.rb b/spec/requests/api/fork_spec.rb new file mode 100644 index 00000000000..cbbd1e7de5a --- /dev/null +++ b/spec/requests/api/fork_spec.rb @@ -0,0 +1,73 @@ +require 'spec_helper' + +describe API::API, api: true do + include ApiHelpers + let(:user) { create(:user) } + let(:user2) { create(:user) } + let(:user3) { create(:user) } + let(:admin) { create(:admin) } + let(:project) { + create(:project, creator_id: user.id, + namespace: user.namespace) + } + let(:project_user2) { + create(:project_member, user: user2, + project: project, + access_level: ProjectMember::GUEST) + } + + describe 'POST /projects/fork/:id' do + before { project_user2 } + before { user3 } + + context 'when authenticated' do + it 'should fork if user has sufficient access to project' do + post api("/projects/fork/#{project.id}", user2) + response.status.should == 201 + json_response['name'].should == project.name + json_response['path'].should == project.path + json_response['owner']['id'].should == user2.id + json_response['namespace']['id'].should == user2.namespace.id + json_response['forked_from_project']['id'].should == project.id + end + + it 'should fork if user is admin' do + post api("/projects/fork/#{project.id}", admin) + response.status.should == 201 + json_response['name'].should == project.name + json_response['path'].should == project.path + json_response['owner']['id'].should == admin.id + json_response['namespace']['id'].should == admin.namespace.id + json_response['forked_from_project']['id'].should == project.id + end + + it 'should fail on missing project access for the project to fork' do + post api("/projects/fork/#{project.id}", user3) + response.status.should == 404 + json_response['message'].should == '404 Not Found' + end + + it 'should fail if forked project exists in the user namespace' do + post api("/projects/fork/#{project.id}", user) + response.status.should == 409 + json_response['message']['base'].should == ['Invalid fork destination'] + json_response['message']['name'].should == ['has already been taken'] + json_response['message']['path'].should == ['has already been taken'] + end + + it 'should fail if project to fork from does not exist' do + post api('/projects/fork/424242', user) + response.status.should == 404 + json_response['message'].should == '404 Not Found' + end + end + + context 'when unauthenticated' do + it 'should return authentication error' do + post api("/projects/fork/#{project.id}") + response.status.should == 401 + json_response['message'].should == '401 Unauthorized' + end + end + end +end |