Merge pull request #326 from abf/rosa-build:325-fork_project_with_another_name

#325 fork project with another name
This commit is contained in:
avokhmin 2013-11-20 14:58:00 +04:00
commit ccdf15bcad
11 changed files with 101 additions and 27 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

@ -2111,3 +2111,11 @@ table tbody {
cursor: default;
}
}
.fork_name {
height: 20px;
margin: 0 0 5px 10px;
width: 400px;
padding: 0 5px;
margin:auto;
}

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
before_filter :who_owns, :only => [:new, :create, :mass_import, :run_mass_import]
def index
@ -88,7 +88,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")
@ -97,6 +97,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

@ -200,8 +200,10 @@ class Project < ActiveRecord::Base
build_list.save
end
def fork(new_owner)
def fork(new_owner, new_name = 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,12 +1,15 @@
- if owner.own_projects.exists? :name => @project.name
- is_group = owner.class == Group ? "(#{t 'activerecord.models.group'})" : ''
- is_group = owner.class == Group ? "(#{t 'activerecord.models.group'})" : ''
- full_name = "#{owner.uname}/#{name} #{is_group}"
- if owner.own_projects.exists? :name => name
%p.center
=t 'layout.projects.already_exists'
=link_to "#{owner.uname}/#{@project.name} #{is_group}", project_path(owner, @project.name)
=link_to full_name, 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
=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'
= hidden_field_tag :fork_name, name, :name => 'fork_name'
=f.submit t('layout.projects.fork_to', :to => full_name), :class => 'btn btn-primary disabled', 'data-loading-text' => t('layout.processing'), :id => 'create_fork'
:javascript
$('#create_fork').click(function () {

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,10 @@
.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{:align => 'center'}= 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

@ -350,6 +350,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,16 +345,36 @@ 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
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)
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 '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
it 'group reader 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)
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

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