Commit 7dd5656a authored by Mika Mäenpää's avatar Mika Mäenpää Committed by Hannes Rosenögger

Implement edit via API for projects

parent 1050f523
...@@ -181,6 +181,7 @@ v 7.4.0 ...@@ -181,6 +181,7 @@ v 7.4.0
- Fail harder in the backup script - Fail harder in the backup script
- Changes to Slack service structure, only webhook url needed - Changes to Slack service structure, only webhook url needed
- Zen mode for wiki and milestones (Robert Schilling) - Zen mode for wiki and milestones (Robert Schilling)
- API: Add support for editing an existing project (Mika Mäenpää)
- Move Emoji parsing to html-pipeline-gitlab (Robert Schilling) - Move Emoji parsing to html-pipeline-gitlab (Robert Schilling)
- Font Awesome 4.2 integration (Sullivan Senechal) - Font Awesome 4.2 integration (Sullivan Senechal)
- Add Pushover service integration (Sullivan Senechal) - Add Pushover service integration (Sullivan Senechal)
......
...@@ -287,6 +287,31 @@ Parameters: ...@@ -287,6 +287,31 @@ Parameters:
- `visibility_level` (optional) - `visibility_level` (optional)
- `import_url` (optional) - `import_url` (optional)
### Edit project
Updates an existing project
```
PUT /projects/:id
```
Parameters:
- `id` (required) - The ID of a project
- `name` (optional) - project name
- `path` (optional) - repository name for project
- `description` (optional) - short project description
- `default_branch` (optional)
- `issues_enabled` (optional)
- `merge_requests_enabled` (optional)
- `wiki_enabled` (optional)
- `snippets_enabled` (optional)
- `public` (optional) - if `true` same as setting visibility_level = 20
- `visibility_level` (optional)
On success, method returns 200 with the updated project. If parameters are
invalid, 400 is returned.
### Fork project ### Fork project
Forks a project into the user namespace of the authenticated user. Forks a project into the user namespace of the authenticated user.
......
...@@ -200,6 +200,49 @@ module API ...@@ -200,6 +200,49 @@ module API
end end
end end
# Update an existing project
#
# Parameters:
# id (required) - the id of a project
# name (optional) - name of a project
# path (optional) - path of a project
# description (optional) - short project description
# issues_enabled (optional)
# merge_requests_enabled (optional)
# wiki_enabled (optional)
# snippets_enabled (optional)
# public (optional) - if true same as setting visibility_level = 20
# visibility_level (optional) - visibility level of a project
# Example Request
# PUT /projects/:id
put ':id' do
attrs = attributes_for_keys [:name,
:path,
:description,
:default_branch,
:issues_enabled,
:merge_requests_enabled,
:wiki_enabled,
:snippets_enabled,
:public,
:visibility_level]
attrs = map_public_to_visibility_level(attrs)
authorize_admin_project
authorize! :rename_project, user_project if attrs[:name].present?
if attrs[:visibility_level].present?
authorize! :change_visibility_level, user_project
end
::Projects::UpdateService.new(user_project,
current_user, attrs).execute
if user_project.valid?
present user_project, with: Entities::Project
else
render_validation_error!(user_project)
end
end
# Remove project # Remove project
# #
# Parameters: # Parameters:
......
# -*- coding: utf-8 -*-
require 'spec_helper' require 'spec_helper'
describe API::API, api: true do describe API::API, api: true do
...@@ -12,6 +13,24 @@ describe API::API, api: true do ...@@ -12,6 +13,24 @@ describe API::API, api: true do
let(:snippet) { create(:project_snippet, author: user, project: project, title: 'example') } let(:snippet) { create(:project_snippet, author: user, project: project, title: 'example') }
let(:project_member) { create(:project_member, user: user, project: project, access_level: ProjectMember::MASTER) } let(:project_member) { create(:project_member, user: user, project: project, access_level: ProjectMember::MASTER) }
let(:project_member2) { create(:project_member, user: user3, project: project, access_level: ProjectMember::DEVELOPER) } let(:project_member2) { create(:project_member, user: user3, project: project, access_level: ProjectMember::DEVELOPER) }
let(:user4) { create(:user) }
let(:project3) { create(:project,
name: 'second_project',
path: 'second_project',
creator_id: user.id,
namespace: user.namespace,
merge_requests_enabled: false,
issues_enabled: false, wiki_enabled: false,
snippets_enabled: false, visibility_level: 0) }
let(:project_member3) { create(:project_member,
user: user4,
project: project3,
access_level: ProjectMember::MASTER) }
let(:project4) { create(:project,
name: 'third_project',
path: 'third_project',
creator_id: user4.id,
namespace: user4.namespace) }
describe "GET /projects" do describe "GET /projects" do
before { project } before { project }
...@@ -650,6 +669,118 @@ describe API::API, api: true do ...@@ -650,6 +669,118 @@ describe API::API, api: true do
end end
end end
describe 'PUT /projects/:id̈́' do
before { project }
before { user }
before { user3 }
before { user4 }
before { project3 }
before { project4 }
before { project_member3 }
before { project_member2 }
context 'when unauthenticated' do
it 'should return authentication error' do
project_param = { name: 'bar' }
put api("/projects/#{project.id}"), project_param
response.status.should == 401
end
end
context 'when authenticated as project owner' do
it 'should update name' do
project_param = { name: 'bar' }
put api("/projects/#{project.id}", user), project_param
response.status.should == 200
project_param.each_pair do |k, v|
json_response[k.to_s].should == v
end
end
it 'should update visibility_level' do
project_param = { visibility_level: 20 }
put api("/projects/#{project3.id}", user), project_param
response.status.should == 200
project_param.each_pair do |k, v|
json_response[k.to_s].should == v
end
end
it 'should not update name to existing name' do
project_param = { name: project3.name }
put api("/projects/#{project.id}", user), project_param
response.status.should == 400
json_response['message']['name'].should == ['has already been taken']
end
it 'should update path & name to existing path & name in different namespace' do
project_param = { path: project4.path, name: project4.name }
put api("/projects/#{project3.id}", user), project_param
response.status.should == 200
project_param.each_pair do |k, v|
json_response[k.to_s].should == v
end
end
end
context 'when authenticated as project master' do
it 'should update path' do
project_param = { path: 'bar' }
put api("/projects/#{project3.id}", user4), project_param
response.status.should == 200
project_param.each_pair do |k, v|
json_response[k.to_s].should == v
end
end
it 'should update other attributes' do
project_param = { issues_enabled: true,
wiki_enabled: true,
snippets_enabled: true,
merge_requests_enabled: true,
description: 'new description' }
put api("/projects/#{project3.id}", user4), project_param
response.status.should == 200
project_param.each_pair do |k, v|
json_response[k.to_s].should == v
end
end
it 'should not update path to existing path' do
project_param = { path: project.path }
put api("/projects/#{project3.id}", user4), project_param
response.status.should == 400
json_response['message']['path'].should == ['has already been taken']
end
it 'should not update name' do
project_param = { name: 'bar' }
put api("/projects/#{project3.id}", user4), project_param
response.status.should == 403
end
it 'should not update visibility_level' do
project_param = { visibility_level: 20 }
put api("/projects/#{project3.id}", user4), project_param
response.status.should == 403
end
end
context 'when authenticated as project developer' do
it 'should not update other attributes' do
project_param = { path: 'bar',
issues_enabled: true,
wiki_enabled: true,
snippets_enabled: true,
merge_requests_enabled: true,
description: 'new description' }
put api("/projects/#{project.id}", user3), project_param
response.status.should == 403
end
end
end
describe "DELETE /projects/:id" do describe "DELETE /projects/:id" do
context "when authenticated as user" do context "when authenticated as user" do
it "should remove project" do it "should remove project" do
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment