Merge pull request #87 from abf/rosa-build:82-extend-abilities-of-personal-platforms
[refs #82]: Extend abilities of personal platforms
This commit is contained in:
commit
079d7110e0
|
@ -72,7 +72,7 @@ class Projects::ProjectsController < Projects::BaseController
|
|||
redirect_to forked, :notice => t("flash.project.forked")
|
||||
else
|
||||
flash[:warning] = t("flash.project.fork_error")
|
||||
flash[:error] = forked.errors.full_messages
|
||||
flash[:error] = forked.errors.full_messages.join("\n")
|
||||
redirect_to @project
|
||||
end
|
||||
end
|
||||
|
|
|
@ -146,7 +146,8 @@ class Ability
|
|||
|
||||
# Shared cannot rights for all users (registered, admin)
|
||||
cannot :destroy, Platform, :platform_type => 'personal'
|
||||
cannot [:create, :destroy, :edit, :update, :add_project, :remove_project], Repository, :platform => {:platform_type => 'personal'}
|
||||
cannot [:create, :destroy], Repository, :platform => {:platform_type => 'personal'}, :name => 'main'
|
||||
cannot [:remove_members, :remove_member, :add_member], Repository, :platform => {:platform_type => 'personal'}
|
||||
cannot :clear, Platform, :platform_type => 'main'
|
||||
cannot :destroy, Issue
|
||||
|
||||
|
|
|
@ -33,6 +33,14 @@ class Project < ActiveRecord::Base
|
|||
validates :visibility, :presence => true, :inclusion => {:in => VISIBILITIES}
|
||||
validate { errors.add(:base, :can_have_less_or_equal, :count => MAX_OWN_PROJECTS) if owner.projects.size >= MAX_OWN_PROJECTS }
|
||||
validate :check_default_branch
|
||||
# throws validation error message from ProjectToRepository model into Project model
|
||||
validate do |project|
|
||||
project.project_to_repositories.each do |p_to_r|
|
||||
next if p_to_r.valid?
|
||||
p_to_r.errors.full_messages.each{ |msg| errors[:base] << msg }
|
||||
end
|
||||
errors.delete :project_to_repositories
|
||||
end
|
||||
|
||||
attr_accessible :name, :description, :visibility, :srpm, :is_package, :default_branch, :has_issues, :has_wiki, :maintainer_id, :publish_i686_into_x86_64
|
||||
attr_readonly :name, :owner_id, :owner_type
|
||||
|
@ -250,11 +258,11 @@ class Project < ActiveRecord::Base
|
|||
end
|
||||
|
||||
def attach_to_personal_repository
|
||||
owner_rep = self.owner.personal_repository
|
||||
owner_repos = self.owner.personal_platform.repositories
|
||||
if is_package
|
||||
repositories << owner_rep unless repositories.exists?(:id => owner_rep)
|
||||
repositories << self.owner.personal_repository unless repositories.exists?(:id => owner_repos.pluck(:id))
|
||||
else
|
||||
repositories.delete owner_rep
|
||||
repositories.delete owner_repos
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -7,12 +7,12 @@ class ProjectToRepository < ActiveRecord::Base
|
|||
|
||||
after_destroy lambda { project.destroy_project_from_repository(repository) }, :unless => lambda {Thread.current[:skip]}
|
||||
|
||||
validate :one_project_in_platform_repositories
|
||||
validate :one_project_in_platform_repositories, :on => :create
|
||||
|
||||
protected
|
||||
|
||||
def one_project_in_platform_repositories
|
||||
errors.add(:project, 'should be one in platform') if Project.joins(:repositories => :platform).
|
||||
where('platforms.id = ?', repository.platform_id).by_name(project.name).count > 0
|
||||
errors.add(:base, I18n.t('activerecord.errors.project_to_repository.project')) if Project.joins(:repositories => :platform).
|
||||
where('platforms.id = ?', repository.platform_id).by_name(project.name).exists?
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
= render 'platforms/base/sidebar'
|
||||
|
||||
%h3= t("layout.key_pairs.header")
|
||||
|
||||
= form_for :key_pair, :url => platform_key_pairs_path(@platform), :method => :post, :html => { :class => :form } do |f|
|
||||
|
|
|
@ -1,2 +1,6 @@
|
|||
- set_meta_tags :title => [title_object(@platform), t('layout.key_pairs.header')]
|
||||
= render 'platforms/base/submenu'
|
||||
= render 'platforms/base/sidebar'
|
||||
|
||||
= render 'new' if can? :edit, @platform
|
||||
= render 'list'
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
.rightside
|
||||
= link_to t('layout.repositories.regenerate_metadata').split.first, regenerate_metadata_platform_repository_path(@platform, @repository),
|
||||
:method => :put, :confirm => t('layout.confirm'), :class => :button
|
||||
.hr{:style => 'padding-bottom:20px;'}
|
||||
.hr{:style => 'padding-bottom:20px;'}
|
||||
.both
|
||||
|
||||
.button_block
|
||||
|
|
|
@ -8,9 +8,10 @@
|
|||
= render "form", :f => f
|
||||
%br
|
||||
|
||||
= render "shared/members_table",
|
||||
:remove_members_path => remove_members_platform_repository_path(@platform, @repository),
|
||||
:remove_member_path => remove_member_platform_repository_path(@platform, @repository),
|
||||
:add_member_path => add_member_platform_repository_path(@platform, @repository),
|
||||
:members => @members,
|
||||
:editable_object => @repository
|
||||
- if @platform.main?
|
||||
= render "shared/members_table",
|
||||
:remove_members_path => remove_members_platform_repository_path(@platform, @repository),
|
||||
:remove_member_path => remove_member_platform_repository_path(@platform, @repository),
|
||||
:add_member_path => add_member_platform_repository_path(@platform, @repository),
|
||||
:members => @members,
|
||||
:editable_object => @repository
|
||||
|
|
|
@ -14,5 +14,5 @@
|
|||
- Group.can_own_project(current_user).each do |group|
|
||||
=render 'choose_fork', :owner => group
|
||||
%hr.bootstrap
|
||||
- if 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'
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
en:
|
||||
activerecord:
|
||||
errors:
|
||||
project_to_repository:
|
||||
project: Project already exists in platform
|
|
@ -0,0 +1,5 @@
|
|||
ru:
|
||||
activerecord:
|
||||
errors:
|
||||
project_to_repository:
|
||||
project: Проект уже присутствует в платформе
|
|
@ -36,7 +36,7 @@ en:
|
|||
update_error: Unable to update repository
|
||||
destroyed: Repository deleted
|
||||
project_added: Project added to repository
|
||||
project_not_added: Project adding error. A project with such name already exists in this repository. Remove the old project first
|
||||
project_not_added: Project adding error. A project with such name already exists in one repository of platform. Remove the old project first
|
||||
project_removed: Project deleted
|
||||
project_not_removed: Unable to delete project from repository
|
||||
clear: Platform successfully cleared!
|
||||
|
|
|
@ -36,7 +36,7 @@ ru:
|
|||
update_error: Не удалось обновить репозиторий
|
||||
destroyed: Репозиторий успешно удален
|
||||
project_added: Проект добавлен к репозиторию
|
||||
project_not_added: Не удалось добавить проект. В этом репозитории уже есть проект с таким именем. Сначала нужно удалить старый проект
|
||||
project_not_added: Не удалось добавить проект. В одном из репозиториев платформы уже есть проект с таким именем. Сначала нужно удалить старый проект
|
||||
project_removed: Проект удален из репозитория
|
||||
project_not_removed: Не удалось удалить проект из репозитория
|
||||
clear: Платформа успешно очищена!
|
||||
|
|
|
@ -99,12 +99,24 @@ shared_examples_for 'api repository user with writer rights' do
|
|||
it 'ensures that repository of main platform has been destroyed' do
|
||||
lambda { delete :destroy, :id => @repository.id, :format => :json }.should change{ Repository.count }.by(-1)
|
||||
end
|
||||
it 'should not be able to perform destroy action for repository of personal platform' do
|
||||
delete :destroy, :id => @personal_repository.id, :format => :json
|
||||
response.should_not be_success
|
||||
|
||||
context 'repository with name "main" of personal platform' do
|
||||
# hook for "ActiveRecord::ActiveRecordError: name is marked as readonly"
|
||||
before { Repository.where(:id => @personal_repository.id).update_all("name = 'main'") }
|
||||
it 'should not be able to perform destroy action' do
|
||||
delete :destroy, :id => @personal_repository.id, :format => :json
|
||||
response.should_not be_success
|
||||
end
|
||||
it 'ensures that repository has not been destroyed' do
|
||||
lambda { delete :destroy, :id => @personal_repository.id, :format => :json }.should_not change{ Repository.count }
|
||||
end
|
||||
end
|
||||
it 'ensures that repository of personal platform has not been destroyed' do
|
||||
lambda { delete :destroy, :id => @personal_repository.id, :format => :json }.should_not change{ Repository.count }
|
||||
it 'should be able to perform destroy action for repository with name not "main" of personal platform' do
|
||||
delete :destroy, :id => @personal_repository.id, :format => :json
|
||||
response.should be_success
|
||||
end
|
||||
it 'ensures that repository with name not "main" of personal platform has been destroyed' do
|
||||
lambda { delete :destroy, :id => @personal_repository.id, :format => :json }.should change{ Repository.count }.by(-1)
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -296,9 +308,11 @@ describe Api::V1::RepositoriesController do
|
|||
before(:each) do
|
||||
@user = FactoryGirl.create(:user)
|
||||
http_login(@user)
|
||||
platform = @repository.platform
|
||||
platform.owner = @user; platform.save
|
||||
@repository.platform.relations.create!(:actor_type => 'User', :actor_id => @user.id, :role => 'admin')
|
||||
[@repository, @personal_repository].each do |repository|
|
||||
platform = repository.platform
|
||||
platform.owner = @user; platform.save
|
||||
repository.platform.relations.create!(:actor_type => 'User', :actor_id => @user.id, :role => 'admin')
|
||||
end
|
||||
end
|
||||
|
||||
it_should_behave_like 'api repository user with reader rights'
|
||||
|
|
|
@ -1,14 +1,6 @@
|
|||
# -*- encoding : utf-8 -*-
|
||||
require 'spec_helper'
|
||||
|
||||
shared_examples_for 'not destroy personal repository' do
|
||||
it 'should not be able to destroy personal repository' do
|
||||
lambda { delete :destroy, :id => @personal_repository.id, :platform_id =>
|
||||
@personal_repository.platform.id}.should change{ Repository.count }.by(0)
|
||||
response.should redirect_to(redirect_path)
|
||||
end
|
||||
end
|
||||
|
||||
shared_examples_for 'user with change projects in repository rights' do
|
||||
|
||||
it 'should be able to see add_project page' do
|
||||
|
@ -90,12 +82,16 @@ shared_examples_for 'registered user or guest' do
|
|||
end
|
||||
|
||||
it 'should not be able to destroy repository in main platform' do
|
||||
delete :destroy, :id => @repository.id
|
||||
delete :destroy, :id => @repository.id, :platform_id => @platform.id
|
||||
response.should redirect_to(redirect_path)
|
||||
lambda { delete :destroy, :id => @repository.id }.should_not change{ Repository.count }.by(-1)
|
||||
end
|
||||
|
||||
it_should_behave_like 'not destroy personal repository'
|
||||
it 'should not be able to destroy personal repository' do
|
||||
lambda { delete :destroy, :id => @personal_repository.id, :platform_id => @personal_repository.platform.id}.
|
||||
should change{ Repository.count }.by(0)
|
||||
response.should redirect_to(redirect_path)
|
||||
end
|
||||
end
|
||||
|
||||
shared_examples_for 'registered user' do
|
||||
|
@ -131,7 +127,7 @@ shared_examples_for 'platform admin user' do
|
|||
end
|
||||
|
||||
it 'should be able to destroy repository in main platform' do
|
||||
lambda { delete :destroy, :id => @repository.id }.should change{ Repository.count }.by(-1)
|
||||
lambda { delete :destroy, :id => @repository.id, :platform_id => @platform.id }.should change{ Repository.count }.by(-1)
|
||||
response.should redirect_to(platform_repositories_path(@repository.platform))
|
||||
end
|
||||
|
||||
|
@ -163,10 +159,21 @@ shared_examples_for 'platform admin user' do
|
|||
@repository.members.should_not include(@another_user, another_user2)
|
||||
end
|
||||
|
||||
it_should_behave_like 'user with change projects in repository rights'
|
||||
it_should_behave_like 'not destroy personal repository' do
|
||||
let(:redirect_path) { forbidden_path }
|
||||
it 'should not be able to destroy personal repository with name "main"' do
|
||||
# hook for "ActiveRecord::ActiveRecordError: name is marked as readonly"
|
||||
Repository.where(:id => @personal_repository.id).update_all("name = 'main'")
|
||||
lambda { delete :destroy, :id => @personal_repository.id, :platform_id => @personal_repository.platform.id}.
|
||||
should change{ Repository.count }.by(0)
|
||||
response.should redirect_to(forbidden_path)
|
||||
end
|
||||
|
||||
it 'should be able to destroy personal repository with name not "main"' do
|
||||
lambda { delete :destroy, :id => @personal_repository.id, :platform_id => @personal_repository.platform.id}.
|
||||
should change{ Repository.count }.by(-1)
|
||||
response.should redirect_to(platform_repositories_path(@personal_repository.platform))
|
||||
end
|
||||
|
||||
it_should_behave_like 'user with change projects in repository rights'
|
||||
end
|
||||
|
||||
describe Platforms::RepositoriesController do
|
||||
|
@ -234,6 +241,8 @@ describe Platforms::RepositoriesController do
|
|||
context 'for platform owner user' do
|
||||
before(:each) do
|
||||
@user = @repository.platform.owner
|
||||
platform = @personal_repository.platform
|
||||
platform.owner = @user; platform.save
|
||||
set_session_for(@user)
|
||||
end
|
||||
|
||||
|
@ -242,7 +251,9 @@ describe Platforms::RepositoriesController do
|
|||
|
||||
context 'for platform member user' do
|
||||
before(:each) do
|
||||
@platform.relations.create!(:actor_type => 'User', :actor_id => @user.id, :role => 'admin')
|
||||
[@repository, @personal_repository].each do |repo|
|
||||
repo.platform.relations.create!(:actor_type => 'User', :actor_id => @user.id, :role => 'admin')
|
||||
end
|
||||
end
|
||||
|
||||
it_should_behave_like 'platform admin user'
|
||||
|
@ -250,7 +261,9 @@ describe Platforms::RepositoriesController do
|
|||
|
||||
context 'for repository member user' do
|
||||
before(:each) do
|
||||
@repository.relations.create!(:actor_type => 'User', :actor_id => @user.id, :role => 'admin')
|
||||
[@repository, @personal_repository].each do |repo|
|
||||
repo.relations.create!(:actor_type => 'User', :actor_id => @user.id, :role => 'admin')
|
||||
end
|
||||
end
|
||||
|
||||
it_should_behave_like 'registered user'
|
||||
|
|
|
@ -3,12 +3,12 @@ require 'spec_helper'
|
|||
require "cancan/matchers"
|
||||
|
||||
def admin_create
|
||||
@admin = FactoryGirl.create(:admin)
|
||||
@admin = FactoryGirl.create(:admin)
|
||||
@ability = Ability.new(@admin)
|
||||
end
|
||||
|
||||
def user_create
|
||||
@user = FactoryGirl.create(:user)
|
||||
@user = FactoryGirl.create(:user)
|
||||
@ability = Ability.new(@user)
|
||||
end
|
||||
|
||||
|
@ -17,47 +17,51 @@ def guest_create
|
|||
end
|
||||
|
||||
describe CanCan do
|
||||
|
||||
let(:personal_platform) { FactoryGirl.create(:platform, :platform_type => 'personal') }
|
||||
let(:personal_repository) { FactoryGirl.create(:personal_repository) }
|
||||
let(:open_platform) { FactoryGirl.create(:platform, :visibility => 'open') }
|
||||
let(:hidden_platform) { FactoryGirl.create(:platform, :visibility => 'hidden') }
|
||||
let(:register_request) { FactoryGirl.create(:register_request) }
|
||||
let(:open_platform) { FactoryGirl.create(:platform, :visibility => 'open') }
|
||||
|
||||
before(:each) do
|
||||
stub_symlink_methods
|
||||
end
|
||||
|
||||
context 'Site admin' do
|
||||
before(:each) do
|
||||
admin_create
|
||||
end
|
||||
context 'Site admin' do
|
||||
let(:personal_platform) { FactoryGirl.create(:platform, :platform_type => 'personal') }
|
||||
let(:personal_repository_main) { FactoryGirl.create(:personal_repository, :name => 'main') }
|
||||
let(:personal_repository) { FactoryGirl.create(:personal_repository) }
|
||||
before(:each) do
|
||||
admin_create
|
||||
end
|
||||
|
||||
it 'should manage all' do
|
||||
#(@ability.can? :manage, :all).should be_true
|
||||
@ability.should be_able_to(:manage, :all)
|
||||
end
|
||||
it 'should manage all' do
|
||||
#(@ability.can? :manage, :all).should be_true
|
||||
@ability.should be_able_to(:manage, :all)
|
||||
end
|
||||
|
||||
it 'should not be able to destroy personal platforms' do
|
||||
@ability.should_not be_able_to(:destroy, personal_platform)
|
||||
end
|
||||
it 'should not be able to destroy personal platforms' do
|
||||
@ability.should_not be_able_to(:destroy, personal_platform)
|
||||
end
|
||||
|
||||
it 'should not be able to destroy personal repositories' do
|
||||
@ability.should_not be_able_to(:destroy, personal_repository)
|
||||
end
|
||||
end
|
||||
it 'should not be able to destroy personal repositories with name "main"' do
|
||||
@ability.should_not be_able_to(:destroy, personal_repository_main)
|
||||
end
|
||||
it 'should be able to destroy personal repositories with name not "main"' do
|
||||
@ability.should be_able_to(:destroy, personal_repository)
|
||||
end
|
||||
end
|
||||
|
||||
context 'Site guest' do
|
||||
before(:each) do
|
||||
guest_create
|
||||
end
|
||||
context 'Site guest' do
|
||||
let(:hidden_platform) { FactoryGirl.create(:platform, :visibility => 'hidden') }
|
||||
let(:register_request) { FactoryGirl.create(:register_request) }
|
||||
|
||||
before(:each) do
|
||||
guest_create
|
||||
end
|
||||
|
||||
it 'should not be able to read open platform' do
|
||||
@ability.should_not be_able_to(:read, open_platform)
|
||||
@ability.should_not be_able_to(:read, open_platform)
|
||||
end
|
||||
|
||||
it 'should not be able to read hidden platform' do
|
||||
@ability.should_not be_able_to(:read, hidden_platform)
|
||||
@ability.should_not be_able_to(:read, hidden_platform)
|
||||
end
|
||||
|
||||
[:publish, :cancel, :reject_publish, :create_container].each do |action|
|
||||
|
@ -78,10 +82,10 @@ describe CanCan do
|
|||
@ability.should_not be_able_to(:destroy, register_request)
|
||||
end
|
||||
|
||||
pending 'should be able to register new user' do # while self registration is closed
|
||||
@ability.should be_able_to(:create, User)
|
||||
end
|
||||
end
|
||||
pending 'should be able to register new user' do # while self registration is closed
|
||||
@ability.should be_able_to(:create, User)
|
||||
end
|
||||
end
|
||||
|
||||
context 'Site user' do
|
||||
before(:each) do
|
||||
|
|
Loading…
Reference in New Issue