[#325] add abibity to create fork with different name
This commit is contained in:
parent
2899728a33
commit
188c3be355
|
@ -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
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
|
@ -279,3 +279,10 @@ table.blame td.message .message {
|
||||||
background: #ECECEC;
|
background: #ECECEC;
|
||||||
color: #000;
|
color: #000;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.fork_name {
|
||||||
|
height: 20px;
|
||||||
|
margin-left: 10px;
|
||||||
|
width: 450px;
|
||||||
|
padding: 0 5px;
|
||||||
|
}
|
||||||
|
|
|
@ -66,7 +66,7 @@ class Api::V1::ProjectsController < Api::V1::BaseController
|
||||||
def fork
|
def fork
|
||||||
owner = (Group.find params[:group_id] if params[:group_id].present?) || current_user
|
owner = (Group.find params[:group_id] if params[:group_id].present?) || current_user
|
||||||
authorize! :write, owner if owner.class == Group
|
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'
|
render_json_response forked, 'Project has been forked successfully'
|
||||||
else
|
else
|
||||||
render_validation_error forked, 'Project has not been forked'
|
render_validation_error forked, 'Project has not been forked'
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
class Projects::ProjectsController < Projects::BaseController
|
class Projects::ProjectsController < Projects::BaseController
|
||||||
include ProjectsHelper
|
include ProjectsHelper
|
||||||
before_filter :authenticate_user!
|
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
|
def index
|
||||||
@projects = Project.accessible_by(current_ability, :membered)
|
@projects = Project.accessible_by(current_ability, :membered)
|
||||||
|
@ -68,7 +68,7 @@ class Projects::ProjectsController < Projects::BaseController
|
||||||
def fork
|
def fork
|
||||||
owner = (Group.find params[:group] if params[:group].present?) || current_user
|
owner = (Group.find params[:group] if params[:group].present?) || current_user
|
||||||
authorize! :write, owner if owner.class == Group
|
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")
|
redirect_to forked, :notice => t("flash.project.forked")
|
||||||
else
|
else
|
||||||
flash[:warning] = t("flash.project.fork_error")
|
flash[:warning] = t("flash.project.fork_error")
|
||||||
|
@ -77,6 +77,11 @@ class Projects::ProjectsController < Projects::BaseController
|
||||||
end
|
end
|
||||||
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
|
def sections
|
||||||
if request.post?
|
if request.post?
|
||||||
if @project.update_attributes(params[:project])
|
if @project.update_attributes(params[:project])
|
||||||
|
|
|
@ -189,8 +189,10 @@ class Project < ActiveRecord::Base
|
||||||
build_list.save
|
build_list.save
|
||||||
end
|
end
|
||||||
|
|
||||||
def fork(new_owner)
|
def fork(new_owner, new_name)
|
||||||
|
new_name = new_name.presence || name
|
||||||
dup.tap do |c|
|
dup.tap do |c|
|
||||||
|
c.name = new_name
|
||||||
c.parent_id = id
|
c.parent_id = id
|
||||||
c.owner = new_owner
|
c.owner = new_owner
|
||||||
c.updated_at = nil; c.created_at = nil # :id = nil
|
c.updated_at = nil; c.created_at = nil # :id = nil
|
||||||
|
|
|
@ -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'})" : ''
|
- is_group = owner.class == Group ? "(#{t 'activerecord.models.group'})" : ''
|
||||||
%p.center
|
%p.center
|
||||||
=t 'layout.projects.already_exists'
|
=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
|
- else
|
||||||
= form_for @project, :url => fork_project_path(@project), :html => { :class => :form, :multipart => true, :method => :post } do |f|
|
= 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 :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'
|
=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
|
:javascript
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
= hidden_field_tag :possible_forks_path, possible_forks_project_path(@project)
|
||||||
|
|
||||||
- if can? :write, @project
|
- if can? :write, @project
|
||||||
.r{:style => "display: block"}
|
.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'
|
=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
|
.modal-header
|
||||||
%a.close{"data-dismiss" => "modal"} ×
|
%a.close{"data-dismiss" => "modal"} ×
|
||||||
%h3=t 'layout.projects.fork_modal_header'
|
%h3=t 'layout.projects.fork_modal_header'
|
||||||
.modal-body.modal-body-fork
|
= hidden_field_tag :possible_forks, possible_forks_project_path(@project)
|
||||||
=render 'choose_fork', :owner => current_user
|
%div
|
||||||
%hr.bootstrap
|
= Project.human_attribute_name :name
|
||||||
- Group.can_own_project(current_user).each do |group|
|
= text_field_tag 'fork_name', @project.name, :id => 'fork_name', :class => 'fork_name'
|
||||||
=render 'choose_fork', :owner => group
|
#forks_list.modal-body.modal-body-fork
|
||||||
%hr.bootstrap
|
= render 'forks', :owner => current_user, :name => @project.name
|
||||||
|
|
||||||
- if @project.is_package && can?(:create, @project.build_lists.new)
|
- 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'
|
.r{:style => "display: block"}= link_to t('layout.projects.new_build_list'), new_project_build_list_path(@project), :class => 'button'
|
||||||
|
|
|
@ -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
|
|
@ -344,6 +344,7 @@ Rosa::Application.routes.draw do
|
||||||
delete '/' => 'projects#destroy'
|
delete '/' => 'projects#destroy'
|
||||||
# Member
|
# Member
|
||||||
post '/fork' => 'projects#fork', :as => :fork_project
|
post '/fork' => 'projects#fork', :as => :fork_project
|
||||||
|
get '/possible_forks' => 'projects#possible_forks', :as => :possible_forks_project
|
||||||
get '/sections' => 'projects#sections', :as => :sections_project
|
get '/sections' => 'projects#sections', :as => :sections_project
|
||||||
post '/sections' => 'projects#sections'
|
post '/sections' => 'projects#sections'
|
||||||
delete '/remove_user' => 'projects#remove_user', :as => :remove_user_project
|
delete '/remove_user' => 'projects#remove_user', :as => :remove_user_project
|
||||||
|
|
|
@ -62,6 +62,17 @@ shared_examples_for 'api projects user with fork rights' do
|
||||||
it 'ensures that project has been forked' do
|
it 'ensures that project has been forked' do
|
||||||
lambda { post :fork, :id => @project.id, :format => :json }.should change{ Project.count }.by(1)
|
lambda { post :fork, :id => @project.id, :format => :json }.should change{ Project.count }.by(1)
|
||||||
end
|
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
|
end
|
||||||
|
|
||||||
shared_examples_for 'api projects user with fork rights for hidden project' do
|
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 admin rights'
|
||||||
it_should_behave_like 'api projects user without owner 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 = FactoryGirl.create(:group)
|
||||||
group.actors.create(:actor_type => 'User', :actor_id => @user.id, :role => 'writer')
|
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)
|
lambda {post :fork, :id => @project.id, :group_id => group.id}.should change{ Project.count }.by(1)
|
||||||
end
|
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 = FactoryGirl.create(:group)
|
||||||
group.actors.create(:actor_type => 'User', :actor_id => @user.id, :role => 'reader')
|
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)
|
lambda {post :fork, :id => @project.id, :group_id => group.id}.should change{ Project.count }.by(0)
|
||||||
end
|
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
|
end
|
||||||
|
|
||||||
context 'for admin' do
|
context 'for admin' do
|
||||||
|
|
|
@ -21,11 +21,10 @@ shared_examples_for 'projects user with reader rights' do
|
||||||
:group => group.id}.should change{ Project.count }.by(1)
|
:group => group.id}.should change{ Project.count }.by(1)
|
||||||
end
|
end
|
||||||
|
|
||||||
# it 'should be able to view project' do
|
it 'should be able to fork project with different name' do
|
||||||
# get :show, :owner_name => @project.owner.uname, :project_name => @project.name
|
post :fork, :owner_name => @project.owner.uname, :project_name => @project.name, :fork_name => 'another_name'
|
||||||
# assigns(:project).should eq @project
|
response.should redirect_to(project_path(Project.where(:name => 'another_name').last))
|
||||||
# end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
shared_examples_for 'projects user with project admin rights' do
|
shared_examples_for 'projects user with project admin rights' do
|
||||||
|
|
Loading…
Reference in New Issue