[#325] add abibity to create fork with different name

This commit is contained in:
Alexander Machehin 2013-11-19 17:02:05 +06:00
parent 2899728a33
commit 188c3be355
11 changed files with 98 additions and 25 deletions

View File

@ -0,0 +1,19 @@
$(document).ready(function() {
var fork_name = $('#fork_name');
var forks_path = $('#possible_forks_path');
fork_name.keyup(function(){
$.ajax({
type: 'GET',
url: forks_path.val(),
data: 'name=' + fork_name.val(),
success: function(data){
$('#forks_list').html(data);
},
error: function(data){
alert('error'); // TODO remove
}
});
});
});

View File

@ -279,3 +279,10 @@ table.blame td.message .message {
background: #ECECEC;
color: #000;
}
.fork_name {
height: 20px;
margin-left: 10px;
width: 450px;
padding: 0 5px;
}

View File

@ -66,7 +66,7 @@ class Api::V1::ProjectsController < Api::V1::BaseController
def fork
owner = (Group.find params[:group_id] if params[:group_id].present?) || current_user
authorize! :write, owner if owner.class == Group
if forked = @project.fork(owner) and forked.valid?
if forked = @project.fork(owner, params[:fork_name]) and forked.valid?
render_json_response forked, 'Project has been forked successfully'
else
render_validation_error forked, 'Project has not been forked'

View File

@ -2,7 +2,7 @@
class Projects::ProjectsController < Projects::BaseController
include ProjectsHelper
before_filter :authenticate_user!
load_and_authorize_resource :id_param => :project_name # to force member actions load
load_and_authorize_resource :id_param => :project_name, :collection => :possible_forks # to force member actions load
def index
@projects = Project.accessible_by(current_ability, :membered)
@ -68,7 +68,7 @@ class Projects::ProjectsController < Projects::BaseController
def fork
owner = (Group.find params[:group] if params[:group].present?) || current_user
authorize! :write, owner if owner.class == Group
if forked = @project.fork(owner) and forked.valid?
if forked = @project.fork(owner, params[:fork_name]) and forked.valid?
redirect_to forked, :notice => t("flash.project.forked")
else
flash[:warning] = t("flash.project.fork_error")
@ -77,6 +77,11 @@ class Projects::ProjectsController < Projects::BaseController
end
end
def possible_forks
render :partial => 'projects/git/base/forks', :layout => false,
:locals => { :owner => current_user, :name => (params[:name].presence || @project.name) }
end
def sections
if request.post?
if @project.update_attributes(params[:project])

View File

@ -189,8 +189,10 @@ class Project < ActiveRecord::Base
build_list.save
end
def fork(new_owner)
def fork(new_owner, new_name)
new_name = new_name.presence || name
dup.tap do |c|
c.name = new_name
c.parent_id = id
c.owner = new_owner
c.updated_at = nil; c.created_at = nil # :id = nil

View File

@ -1,11 +1,12 @@
- if owner.own_projects.exists? :name => @project.name
- if owner.own_projects.exists? :name => name
- is_group = owner.class == Group ? "(#{t 'activerecord.models.group'})" : ''
%p.center
=t 'layout.projects.already_exists'
=link_to "#{owner.uname}/#{@project.name} #{is_group}", project_path(owner, @project.name)
=link_to "#{owner.uname}/#{name} #{is_group}", project_path(owner, name)
- else
= form_for @project, :url => fork_project_path(@project), :html => { :class => :form, :multipart => true, :method => :post } do |f|
= hidden_field_tag :group, owner.id if owner.class == Group
= hidden_field_tag :fork_name, name, :name => 'fork_name'
=f.submit t('layout.projects.fork_to', :to => "#{owner.uname} #{is_group}"), :class => 'btn btn-primary disabled', 'data-loading-text' => t('layout.processing'), :id => 'create_fork'
:javascript

View File

@ -1,3 +1,5 @@
= hidden_field_tag :possible_forks_path, possible_forks_project_path(@project)
- if can? :write, @project
.r{:style => "display: block"}
=link_to t("projects.pull_requests.show.pull"), new_project_pull_request_path(@project, :treeish => @treeish), :id => 'send_pull_request', :class => 'button'
@ -8,11 +10,12 @@
.modal-header
%a.close{"data-dismiss" => "modal"} ×
%h3=t 'layout.projects.fork_modal_header'
.modal-body.modal-body-fork
=render 'choose_fork', :owner => current_user
%hr.bootstrap
- Group.can_own_project(current_user).each do |group|
=render 'choose_fork', :owner => group
%hr.bootstrap
= hidden_field_tag :possible_forks, possible_forks_project_path(@project)
%div
= Project.human_attribute_name :name
= text_field_tag 'fork_name', @project.name, :id => 'fork_name', :class => 'fork_name'
#forks_list.modal-body.modal-body-fork
= render 'forks', :owner => current_user, :name => @project.name
- if @project.is_package && can?(:create, @project.build_lists.new)
.r{:style => "display: block"}= link_to t('layout.projects.new_build_list'), new_project_build_list_path(@project), :class => 'button'

View File

@ -0,0 +1,5 @@
=render 'projects/git/base/choose_fork', :owner => current_user, :name => name
%hr.bootstrap
- Group.can_own_project(current_user).each do |group|
=render 'projects/git/base/choose_fork', :owner => group, :name => name
%hr.bootstrap

View File

@ -344,6 +344,7 @@ Rosa::Application.routes.draw do
delete '/' => 'projects#destroy'
# Member
post '/fork' => 'projects#fork', :as => :fork_project
get '/possible_forks' => 'projects#possible_forks', :as => :possible_forks_project
get '/sections' => 'projects#sections', :as => :sections_project
post '/sections' => 'projects#sections'
delete '/remove_user' => 'projects#remove_user', :as => :remove_user_project

View File

@ -62,6 +62,17 @@ shared_examples_for 'api projects user with fork rights' do
it 'ensures that project has been forked' do
lambda { post :fork, :id => @project.id, :format => :json }.should change{ Project.count }.by(1)
end
it 'should be able to perform fork action with different name' do
post :fork, :id => @project.id, :fork_name => (@project.name + '_forked'), :format => :json
response.should be_success
end
it 'ensures that project has been forked' do
new_name = @project.name + '_forked'
lambda { post :fork, :id => @project.id, :fork_name => new_name, :format => :json }.should
change{ Project.where(:name => new_name).count }.by(1)
end
end
shared_examples_for 'api projects user with fork rights for hidden project' do
@ -334,17 +345,37 @@ describe Api::V1::ProjectsController do
it_should_behave_like 'api projects user without admin rights'
it_should_behave_like 'api projects user without owner rights'
it 'group writer should be able to fork project to their group' do
context 'group writer' do
it 'should be able to fork project to their group' do
group = FactoryGirl.create(:group)
group.actors.create(:actor_type => 'User', :actor_id => @user.id, :role => 'writer')
lambda {post :fork, :id => @project.id, :group_id => group.id}.should change{ Project.count }.by(1)
end
it 'group reader should not be able to fork project to their group' do
it 'should be able to fork project with different name to their group' do
group = FactoryGirl.create(:group)
group.actors.create(:actor_type => 'User', :actor_id => @user.id, :role => 'writer')
new_name = @project.name + '_forked'
lambda { post :fork, :id => @project.id, :group_id => group.id, :fork_name => new_name }.should
change { Project.where(:name => new_name).count }.by(1)
end
end
context 'group reader' do
it 'should not be able to fork project to their group' do
group = FactoryGirl.create(:group)
group.actors.create(:actor_type => 'User', :actor_id => @user.id, :role => 'reader')
lambda {post :fork, :id => @project.id, :group_id => group.id}.should change{ Project.count }.by(0)
end
it 'should not be able to fork project with different name to their group' do
group = FactoryGirl.create(:group)
new_name = @project.name + '_forked'
group.actors.create(:actor_type => 'User', :actor_id => @user.id, :role => 'reader')
lambda { post :fork, :id => @project.id, :group_id => group.id, :fork_name => new_name }.should
change{ Project.where(:name => new_name.count) }.by(0)
end
end
end
context 'for admin' do

View File

@ -21,11 +21,10 @@ shared_examples_for 'projects user with reader rights' do
:group => group.id}.should change{ Project.count }.by(1)
end
# it 'should be able to view project' do
# get :show, :owner_name => @project.owner.uname, :project_name => @project.name
# assigns(:project).should eq @project
# end
it 'should be able to fork project with different name' do
post :fork, :owner_name => @project.owner.uname, :project_name => @project.name, :fork_name => 'another_name'
response.should redirect_to(project_path(Project.where(:name => 'another_name').last))
end
end
shared_examples_for 'projects user with project admin rights' do