.*?|
.*?
}m) { |match| extract_piece(match) }
+ # Extract links with probably parsable hrefs
+ text.gsub!(%r{#{code}
+
+ HTML
+ end
+
+ def link(link, title, content)
+ h.link_to_gfm(content, link, title: title)
+ end
+
+ def postprocess(full_document)
+ h.gfm(full_document)
+ end
+end
diff --git a/lib/tasks/add_branch.rake b/lib/tasks/add_branch.rake
index 47c0bf9ed..c8055d8c4 100644
--- a/lib/tasks/add_branch.rake
+++ b/lib/tasks/add_branch.rake
@@ -12,6 +12,21 @@ namespace :add_branch do
FileUtils.rm_rf tmp_path
end
+ desc "Add branch for group projects"
+ task :group => :environment do
+ src_branch = ENV['SRC_BRANCH']
+ dst_branch = ENV['DST_BRANCH']
+ group = ENV['GROUP']
+ say "START add branch #{dst_branch} from #{src_branch} in #{group} group"
+ Group.find_by_uname(group).projects.find_each do |p|
+ next if p.repo.branches.map(&:name).include?(dst_branch)
+ next if p.repo.branches.map(&:name).exclude?(src_branch)
+ say "===== Process #{p.name} project"
+ Rake::Task['add_branch:fork_branch'].execute(:path => p.path, :src_branch => src_branch, :dst_branch => dst_branch)
+ end
+ say 'DONE'
+ end
+
desc "Add branch for platform projects"
task :platform => :environment do
src_branch = ENV['SRC_BRANCH'] || 'import_mandriva2011'
diff --git a/lib/tasks/build.rake b/lib/tasks/build.rake
deleted file mode 100644
index c0f414df6..000000000
--- a/lib/tasks/build.rake
+++ /dev/null
@@ -1,25 +0,0 @@
-require 'highline/import'
-require 'open-uri'
-
-namespace :build do
- desc "Build projects from list"
- task :projects => :environment do
- source = ENV['SOURCE'] || 'http://dl.dropbox.com/u/984976/rebuild_list.txt'
- owner = User.find_by_uname!(ENV['OWNER'] || 'warpc')
- platform = Platform.find_by_name!(ENV['PLATFORM'] || 'rosa2012lts')
- arch = Arch.find_by_name!(ENV['ARCH'] || 'i586')
-
- say "START build projects from #{source} for platform=#{platform.name}, owner=#{owner.uname}, arch=#{arch.name}"
- open(source).readlines.each do |name|
- name.chomp!; name.strip! #; name.downcase!
- if p = Project.joins(:repositories).where('repositories.id IN (?)', platform.repositories).find_by_name(name)
- # Old code p.build_for(platform, owner, arch)
- say "== Build #{p.name} =="
- else
- say "== Not found #{name} =="
- end
- sleep 0.2
- end
- say 'DONE'
- end
-end
diff --git a/lib/tasks/import.rake b/lib/tasks/import.rake
index 309315e27..d63718df1 100644
--- a/lib/tasks/import.rake
+++ b/lib/tasks/import.rake
@@ -26,12 +26,13 @@ namespace :import do
say 'DONE'
end
- # bundle exec rake import:srpm RAILS_ENV=production BASE=/share/platforms/naulinux5x_personal/tmp/SRPMS LIST=https://dl.dropbox.com/u/984976/nauschool5x.srpms.txt OWNER=naulinux PLATFORM=naulinux REPO=main CLEAR=true > log/srpm_naulinux.log &
+ # bundle exec rake import:srpm RAILS_ENV=production BASE=/share/platforms/naulinux5x_personal/tmp/SRPMS LIST=https://dl.dropbox.com/u/984976/nauschool5x.srpms.txt OWNER=naulinux PLATFORM=naulinux REPO=main CLEAR=true HIDDEN=true > log/srpm_naulinux.log &
desc 'Import SRPMs as projects'
task :srpm => :environment do
base = ENV['BASE'] || '/share/alt_repos/rsync'
list = ENV['LIST'] #|| 'https://dl.dropbox.com/u/984976/alt_import.txt'
mask = ENV['MASK'] || '*.src.rpm'
+ hidden = ENV['HIDDEN'] == 'true' ? true : false
owner = User.find_by_uname(ENV['OWNER']) || Group.find_by_uname!(ENV['OWNER'] || 'altlinux')
platform = Platform.find_by_name!(ENV['PLATFORM'] || 'altlinux5')
repo = platform.repositories.find_by_name!(ENV['REPO'] || 'main')
@@ -44,14 +45,14 @@ namespace :import do
if name = `rpm -q --qf '[%{Name}]' -p #{srpm_file}` and $?.success? and name.present?
if clear # simply add
project = Project.find_or_create_by_name_and_owner_type_and_owner_id(name, owner.class.to_s, owner.id)
- repo.projects << project
+ repo.projects << project rescue nil
else # check if project already added
if project = repo.projects.find_by_name(name) || repo.projects.by_name(name).first # fallback to speedup
print "Found project '#{project.name_with_owner}' in '#{platform.name}/#{repo.name}'."
elsif scoped = Project.where(:owner_id => owner.id, :owner_type => owner.class) and
project = scoped.find_by_name(name) || scoped.by_name(name).first
begin
- repo.projects << project
+ repo.projects << project rescue nil
rescue Exception => e
print "Add project '#{project.name_with_owner}' to '#{platform.name}/#{repo.name}' FAILED: #{e.message}."
else
@@ -60,10 +61,11 @@ namespace :import do
else
description = `rpm -q --qf '[%{Description}]' -p #{srpm_file}`
project = Project.create!(:name => name, :description => description) {|p| p.owner = owner}
- repo.projects << project
+ repo.projects << project rescue nil
print "Create project #{project.name_with_owner} in #{platform.name}/#{repo.name} OK."
end
end
+ project.update_attributes(:visibility => 'hidden') if hidden
project.import_srpm(srpm_file, platform.name)
print " Code import complete!"
else
diff --git a/lib/tasks/new_core.rake b/lib/tasks/new_core.rake
index bdaf4bab0..a38753d2c 100644
--- a/lib/tasks/new_core.rake
+++ b/lib/tasks/new_core.rake
@@ -1,58 +1,4 @@
namespace :new_core do
- desc 'Sets bs_id field for all BuildList which use new_core'
- task :update_bs_id => :environment do
- say "[#{Time.zone.now}] Starting to update bs_id..."
-
- BuildList.select(:id).
- where(:new_core => true, :bs_id => nil).
- find_in_batches(:batch_size => 500) do | bls |
-
- puts "[#{Time.zone.now}] - where build_lists.id from #{bls.first.id} to #{bls.last.id}"
- BuildList.where(:id => bls.map(&:id), :bs_id => nil).
- update_all("bs_id = id")
- end
-
- say "[#{Time.zone.now}] done"
- end
-
- desc 'Publish mass-build 73'
- task :publish_mass_build_73 => :environment do
- say "[#{Time.zone.now}] Starting to publish mass-build 317..."
-
- bl = BuildList.where(:mass_build_id => 73).first
- platform_repository_folder = "#{bl.save_to_platform.path}/repository"
- BuildList.where(:mass_build_id => 73).
- where(:status => [
- BuildList::SUCCESS,
- BuildList::FAILED_PUBLISH
- ]).
- order(:id).
- find_in_batches(:batch_size => 1) do | bls |
-
- bl = bls.first
- puts "[#{Time.zone.now}] - where build_lists.id #{bl.id}"
-
- sha1 = bl.results.find{ |r| r['file_name'] =~ /.*\.tar\.gz$/ }['sha1']
-
- system "cd #{platform_repository_folder} && curl -L -O #{APP_CONFIG['file_store_url']}/api/v1/file_stores/#{sha1}"
- system "cd #{platform_repository_folder} && tar -xzf #{sha1}"
- system "rm -f #{platform_repository_folder}/#{sha1}"
-
- archive_folder = "#{platform_repository_folder}/archives"
- system "sudo chown root:root #{archive_folder}/SRC_RPM/*"
- system "sudo chmod 0666 #{archive_folder}/SRC_RPM/*"
- system "sudo chown root:root #{archive_folder}/RPM/*"
- system "sudo chmod 0666 #{archive_folder}/RPM/*"
-
- system "sudo mv #{archive_folder}/SRC_RPM/* #{platform_repository_folder}/SRPMS/main/release/"
- system "sudo mv #{archive_folder}/RPM/* #{platform_repository_folder}/#{bl.arch.name}/main/release/"
-
- system "sudo rm -rf #{archive_folder}"
- bl.update_column(:status, BuildList::BUILD_PUBLISH)
- end
-
- say "[#{Time.zone.now}] done"
- end
desc 'Extracts all rpms from BuildList container and updates BuildList::Package#sha1 field'
task :update_packages => :environment do
diff --git a/lib/tasks/projects.rake b/lib/tasks/projects.rake
index bfe2d982f..973123b73 100644
--- a/lib/tasks/projects.rake
+++ b/lib/tasks/projects.rake
@@ -26,3 +26,20 @@ namespace :project do
task :maintainer => 'maintainer:set_to_owner'
end
+
+namespace :projects do
+ desc 'Add projects from one platform repository to another'
+ task :copy_to_repo => :environment do
+ source_platform = Platform.find_by_name!(ENV['SRC_PLATFORM'])
+ dest_platform = Platform.find_by_name!(ENV['DST_PLATFORM'])
+ source_repo = source_platform.repositories.find_by_name!(ENV['SRC_REPO'])
+ dest_repo = dest_platform.repositories.find_by_name!(ENV['DST_REPO'])
+
+ say "Add from repo '#{source_platform.name}/#{source_repo.name}' to repo '#{dest_platform.name}/#{dest_repo.name}'."
+ source_repo.projects.each do |pr|
+ say "project #{pr.name}"
+ dest_repo.projects << pr rescue print ' Add to repo failed!'
+ end
+ say 'DONE'
+ end
+end
\ No newline at end of file
diff --git a/lib/tasks/remove_branch.rake b/lib/tasks/remove_branch.rake
new file mode 100644
index 000000000..89281d5a1
--- /dev/null
+++ b/lib/tasks/remove_branch.rake
@@ -0,0 +1,14 @@
+namespace :remove_branch do
+ desc "Remove branch for group projects"
+ task :group => :environment do
+ branch = ENV['BRANCH']
+ group = ENV['GROUP']
+ say "START remove branch #{branch} from #{group} group"
+ Group.find_by_uname(group).projects.find_each do |p|
+ next if p.repo.branches.map(&:name).exclude?(branch)
+ say "===== Process #{p.name} project"
+ p.repo.git.native(:branch, {}, '-D', branch)
+ end
+ say 'DONE'
+ end
+end
diff --git a/spec/controllers/activity_feeds_controller_spec.rb b/spec/controllers/activity_feeds_controller_spec.rb
deleted file mode 100644
index 54ce3026a..000000000
--- a/spec/controllers/activity_feeds_controller_spec.rb
+++ /dev/null
@@ -1,5 +0,0 @@
-require 'spec_helper'
-
-describe ActivityFeedsController do
-
-end
diff --git a/spec/controllers/advisories_controller_spec.rb b/spec/controllers/advisories_controller_spec.rb
new file mode 100644
index 000000000..f2006fd93
--- /dev/null
+++ b/spec/controllers/advisories_controller_spec.rb
@@ -0,0 +1,11 @@
+# -*- encoding : utf-8 -*-
+require 'spec_helper'
+
+describe AdvisoriesController do
+ context 'for all' do
+ it "should be able to perform search action" do
+ get :search
+ response.should_not redirect_to(forbidden_path)
+ end
+ end
+end
\ No newline at end of file
diff --git a/spec/controllers/api/v1/advisories_controller_spec.rb b/spec/controllers/api/v1/advisories_controller_spec.rb
index e4f9048bb..dcc24b12e 100644
--- a/spec/controllers/api/v1/advisories_controller_spec.rb
+++ b/spec/controllers/api/v1/advisories_controller_spec.rb
@@ -86,7 +86,7 @@ describe Api::V1::AdvisoriesController do
stub_symlink_methods
@advisory = FactoryGirl.create(:advisory)
- @build_list = FactoryGirl.create(:build_list_core)
+ @build_list = FactoryGirl.create(:build_list)
@build_list.save_to_platform.update_column(:released, true)
@build_list.save_to_repository.update_column(:publish_without_qa, false)
@build_list.update_column(:status, BuildList::BUILD_PUBLISHED)
diff --git a/spec/controllers/api/v1/build_lists_controller_spec.rb b/spec/controllers/api/v1/build_lists_controller_spec.rb
index 42a65f1e4..47e0dca86 100644
--- a/spec/controllers/api/v1/build_lists_controller_spec.rb
+++ b/spec/controllers/api/v1/build_lists_controller_spec.rb
@@ -100,7 +100,7 @@ describe Api::V1::BuildListsController do
Arch.destroy_all
User.destroy_all
- @build_list = FactoryGirl.create(:build_list_core)
+ @build_list = FactoryGirl.create(:build_list)
@params = @build_list.attributes.symbolize_keys
@project = @build_list.project
@platform = @build_list.save_to_platform
@@ -114,9 +114,8 @@ describe Api::V1::BuildListsController do
@build_list.save_to_platform.relations.create(:role => 'admin', :actor => @owner_user) # Why it's really need it??
# Create and show params:
- @create_params = {:build_list => @build_list.attributes.symbolize_keys.except(:bs_id)
- .merge(:qwerty=>'!')} # wrong parameter
- @create_params = @create_params.merge(:arches => [@params[:arch_id]], :build_for_platforms => [@params[:build_for_platform_id]], :format => :json)
+ @create_params = {:build_list => @build_list.attributes.symbolize_keys.merge(:qwerty=>'!')} # wrong parameter
+ @create_params = @create_params.merge(:arches => [@params[:arch_id]], :build_for_platform_id => @platform.id, :format => :json)
any_instance_of(Project, :versions => ['v1.0', 'v2.0'])
http_login(@user)
@@ -151,14 +150,14 @@ describe Api::V1::BuildListsController do
context "if it has another status" do
before do
- @build_list.update_column(:status, BuildList::PROJECT_VERSION_NOT_FOUND)
+ @build_list.update_column(:status, BuildList::SUCCESS)
do_cancel
end
it_should_behave_like 'validation error via build list api', I18n.t('layout.build_lists.cancel_fail')
it "should not change status of build list" do
- @build_list.reload.status.should == BuildList::PROJECT_VERSION_NOT_FOUND
+ @build_list.reload.status.should == BuildList::SUCCESS
end
end
end
@@ -238,6 +237,107 @@ describe Api::V1::BuildListsController do
end
end
+ context 'do publish_into_testing' do
+ def do_publish_into_testing
+ put :publish_into_testing, :id => @build_list, :format => :json
+ end
+
+ context 'if user is project && platform owner' do
+ before(:each) do
+ http_login(@owner_user)
+ end
+
+ context "if it has :failed_publish status" do
+ before do
+ @build_list.update_column(:status, BuildList::FAILED_PUBLISH)
+ do_publish_into_testing
+ end
+ it "should return correct json message" do
+ response.body.should == { :build_list => {:id => @build_list.id, :message => I18n.t('layout.build_lists.publish_success')} }.to_json
+ end
+
+ it 'should return 200 response code' do
+ response.should be_success
+ end
+
+ it "should change status of build list" do
+ @build_list.reload.status.should == BuildList::BUILD_PUBLISH_INTO_TESTING
+ end
+ end
+
+ context "if it has :build_published_into_testing status" do
+ before do
+ @build_list.update_column(:status, BuildList::BUILD_PUBLISHED_INTO_TESTING)
+ do_publish_into_testing
+ end
+
+ it "should return correct json message" do
+ response.body.should == { :build_list => {:id => @build_list.id, :message => I18n.t('layout.build_lists.publish_success')} }.to_json
+ end
+
+ it 'should return 200 response code' do
+ response.should be_success
+ end
+
+ it "should change status of build list" do
+ @build_list.reload.status.should == BuildList::BUILD_PUBLISH_INTO_TESTING
+ end
+ end
+
+ context "if it has another status" do
+ before(:each) do
+ @build_list.update_column(:status, BuildList::BUILD_CANCELED)
+ do_publish_into_testing
+ end
+
+ it "should return access violation message" do
+ response.body.should == {"message" => "Access violation to this page!"}.to_json
+ end
+
+ it "should not change status of build list" do
+ @build_list.reload.status.should == BuildList::BUILD_CANCELED
+ end
+ end
+
+ end
+
+ context 'if user is not project owner' do
+
+ context "if it has :build_published_into_testing status" do
+ before do
+ @build_list.update_column(:status, BuildList::BUILD_PUBLISHED_INTO_TESTING)
+ do_publish_into_testing
+ end
+
+ it 'should not be able to perform create action' do
+ response.body.should == {"message" => "Access violation to this page!"}.to_json
+ end
+
+ it 'should return 403 response code' do
+ response.status.should == 403
+ end
+
+ it "should not change status of build list" do
+ @build_list.reload.status.should == BuildList::BUILD_PUBLISHED_INTO_TESTING
+ end
+ end
+
+ context "if it has :failed_publish status" do
+ before do
+ @build_list.update_column(:status, BuildList::FAILED_PUBLISH_INTO_TESTING)
+ do_publish_into_testing
+ end
+ it "should return access violation message" do
+ response.body.should == {"message" => "Access violation to this page!"}.to_json
+ end
+
+ it "should not change status of build list" do
+ @build_list.reload.status.should == BuildList::FAILED_PUBLISH_INTO_TESTING
+ end
+ end
+ end
+ end
+
context "do publish" do
def do_publish
put :publish, :id => @build_list, :format => :json
@@ -287,7 +387,7 @@ describe Api::V1::BuildListsController do
context "if it has another status" do
before(:each) do
- @build_list.update_column(:status, BuildList::PROJECT_VERSION_NOT_FOUND)
+ @build_list.update_column(:status, BuildList::BUILD_CANCELED)
do_publish
end
@@ -296,7 +396,7 @@ describe Api::V1::BuildListsController do
end
it "should not change status of build list" do
- @build_list.reload.status.should == BuildList::PROJECT_VERSION_NOT_FOUND
+ @build_list.reload.status.should == BuildList::BUILD_CANCELED
end
end
@@ -387,14 +487,14 @@ describe Api::V1::BuildListsController do
context "if it has another status" do
before(:each) do
- @build_list.update_column(:status, BuildList::PROJECT_VERSION_NOT_FOUND)
+ @build_list.update_column(:status, BuildList::BUILD_CANCELED)
do_reject_publish
end
it_should_behave_like 'validation error via build list api', I18n.t('layout.build_lists.reject_publish_fail')
it "should not change status of build list" do
- @build_list.reload.status.should == BuildList::PROJECT_VERSION_NOT_FOUND
+ @build_list.reload.status.should == BuildList::BUILD_CANCELED
end
end
end
@@ -415,6 +515,49 @@ describe Api::V1::BuildListsController do
@build_list.reload.status.should == BuildList::SUCCESS
end
end
+
+ context 'if user is project reader' do
+ before(:each) do
+ @another_user = FactoryGirl.create(:user)
+ @build_list.update_column(:status, BuildList::SUCCESS)
+ @build_list.save_to_repository.update_column(:publish_without_qa, true)
+ @build_list.project.collaborators.create(:actor_type => 'User', :actor_id => @another_user.id, :role => 'reader')
+ http_login(@another_user)
+ do_reject_publish
+ end
+
+ it "should return access violation message" do
+ response.body.should == {"message" => "Access violation to this page!"}.to_json
+ end
+
+ it "should not change status of build list" do
+ do_reject_publish
+ @build_list.reload.status.should == BuildList::SUCCESS
+ end
+ end
+
+ context 'if user is project writer' do
+ before(:each) do
+ @another_user = FactoryGirl.create(:user)
+ @build_list.update_column(:status, BuildList::SUCCESS)
+ @build_list.save_to_repository.update_column(:publish_without_qa, true)
+ @build_list.project.relations.create!(:actor_type => 'User', :actor_id => @another_user.id, :role => 'writer')
+ http_login(@another_user)
+ do_reject_publish
+ end
+
+ it "should return correct json message" do
+ response.body.should == { :build_list => {:id => @build_list.id, :message => I18n.t('layout.build_lists.reject_publish_success')} }.to_json
+ end
+
+ it 'should return 200 response code' do
+ response.should be_success
+ end
+
+ it "should reject publish build list" do
+ @build_list.reload.status.should == BuildList::REJECTED_PUBLISH
+ end
+ end
end
context 'for open project' do
@@ -423,10 +566,25 @@ describe Api::V1::BuildListsController do
context 'if user is project owner' do
before(:each) {http_login(@owner_user)}
it_should_behave_like 'create build list via api'
+
+ context 'no ability to read build_for_platform' do
+ before do
+ repository = FactoryGirl.create(:repository)
+ repository.platform.change_visibility
+ Platform.where(:id => @platform.id).update_all(:platform_type => 'personal')
+ @create_params[:build_list].merge!({
+ :include_repos => [repository.id],
+ :build_for_platform_id => repository.platform_id
+ })
+ end
+ it_should_behave_like 'not create build list via api'
+ end
+
end
context 'if user is project read member' do
before(:each) {http_login(@member_user)}
+ it_should_behave_like 'not create build list via api'
end
end
@@ -455,7 +613,7 @@ describe Api::V1::BuildListsController do
Arch.destroy_all
User.destroy_all
- @build_list = FactoryGirl.create(:build_list_core)
+ @build_list = FactoryGirl.create(:build_list)
@params = @build_list.attributes.symbolize_keys
@project = @build_list.project
@platform = @build_list.save_to_platform
@@ -466,8 +624,8 @@ describe Api::V1::BuildListsController do
@member_user = FactoryGirl.create(:user)
# Create and show params:
- @create_params = {:build_list => @build_list.attributes.symbolize_keys.except(:bs_id)}
- @create_params = @create_params.merge(:arches => [@params[:arch_id]], :build_for_platforms => [@params[:build_for_platform_id]], :format => :json)
+ @create_params = {:build_list => @build_list.attributes.symbolize_keys}
+ @create_params = @create_params.merge(:arches => [@params[:arch_id]], :build_for_platform_id => @platform.id, :format => :json)
any_instance_of(Project, :versions => ['v1.0', 'v2.0'])
# Groups:
@@ -479,8 +637,11 @@ describe Api::V1::BuildListsController do
@user = FactoryGirl.create(:user)
@group.actors.create :role => 'reader', :actor_id => @user.id, :actor_type => 'User'
+ old_path = @project.path
@project.owner = @owner_group
@project.save
+ # Move GIT repo into new folder
+ system "mkdir -p #{@project.path} && mv -f #{old_path}/* #{@project.path}/"
@project.relations.create :role => 'reader', :actor_id => @member_group.id, :actor_type => 'Group'
@project.relations.create :role => 'admin', :actor_id => @owner_group.id, :actor_type => 'Group'
@@ -533,22 +694,22 @@ describe Api::V1::BuildListsController do
@user = FactoryGirl.create(:user)
# Build Lists:
- @build_list1 = FactoryGirl.create(:build_list_core)
+ @build_list1 = FactoryGirl.create(:build_list)
- @build_list2 = FactoryGirl.create(:build_list_core)
+ @build_list2 = FactoryGirl.create(:build_list)
@build_list2.project.update_column(:visibility, 'hidden')
project = FactoryGirl.create(:project_with_commit, :visibility => 'hidden', :owner => @user)
- @build_list3 = FactoryGirl.create(:build_list_core_with_attaching_project, :project => project)
+ @build_list3 = FactoryGirl.create(:build_list_with_attaching_project, :project => project)
- @build_list4 = FactoryGirl.create(:build_list_core)
+ @build_list4 = FactoryGirl.create(:build_list)
@build_list4.project.update_column(:visibility, 'hidden')
@build_list4.project.relations.create! :role => 'reader', :actor_id => @user.id, :actor_type => 'User'
- @filter_build_list1 = FactoryGirl.create(:build_list_core)
- @filter_build_list2 = FactoryGirl.create(:build_list_core)
- @filter_build_list3 = FactoryGirl.create(:build_list_core)
- @filter_build_list4 = FactoryGirl.create(:build_list_core, :updated_at => (Time.now - 1.day),
+ @filter_build_list1 = FactoryGirl.create(:build_list)
+ @filter_build_list2 = FactoryGirl.create(:build_list)
+ @filter_build_list3 = FactoryGirl.create(:build_list)
+ @filter_build_list4 = FactoryGirl.create(:build_list, :updated_at => (Time.now - 1.day),
:project => @build_list3.project, :save_to_platform => @build_list3.save_to_platform,
:arch => @build_list3.arch)
end
@@ -590,8 +751,8 @@ describe Api::V1::BuildListsController do
http_login FactoryGirl.create(:admin)
end
- it 'should filter by bs_id' do
- get :index, :filter => {:bs_id => @filter_build_list1.bs_id, :project_name => 'fdsfdf', :any_other_field => 'do not matter'}, :format => :json
+ it 'should filter by id' do
+ get :index, :filter => {:id => @filter_build_list1.id, :project_name => 'fdsfdf', :any_other_field => 'do not matter'}, :format => :json
assigns[:build_lists].should include(@filter_build_list1)
assigns[:build_lists].should_not include(@filter_build_list2)
assigns[:build_lists].should_not include(@filter_build_list3)
@@ -619,7 +780,7 @@ describe Api::V1::BuildListsController do
context "for user" do
before(:each) do
- @build_list = FactoryGirl.create(:build_list_core)
+ @build_list = FactoryGirl.create(:build_list)
@params = @build_list.attributes.symbolize_keys
@project = @build_list.project
@@ -675,7 +836,7 @@ describe Api::V1::BuildListsController do
context "for group" do
before(:each) do
@platform = FactoryGirl.create(:platform_with_repos)
- @build_list = FactoryGirl.create(:build_list_core, :save_to_platform => @platform)
+ @build_list = FactoryGirl.create(:build_list, :save_to_platform => @platform)
@project = @build_list.project
@params = @build_list.attributes.symbolize_keys
@@ -741,6 +902,5 @@ describe Api::V1::BuildListsController do
end
end
end
-
end
end
diff --git a/spec/controllers/api/v1/issues_controller_spec.rb b/spec/controllers/api/v1/issues_controller_spec.rb
new file mode 100644
index 000000000..f7342a774
--- /dev/null
+++ b/spec/controllers/api/v1/issues_controller_spec.rb
@@ -0,0 +1,222 @@
+# -*- encoding : utf-8 -*-
+require 'spec_helper'
+
+describe Api::V1::IssuesController do
+ before(:all) do
+ stub_symlink_methods
+ stub_redis
+ any_instance_of(Project, :versions => ['v1.0', 'v2.0'])
+
+ @project = FactoryGirl.create(:project_with_commit)
+ @issue = FactoryGirl.create(:issue, :project => @project)
+
+ @membered_issue = FactoryGirl.create(:issue)
+ @membered_project = @membered_issue.project
+ @membered_project.relations.create(:role => 'reader', :actor => @issue.user)
+
+ @open_issue = FactoryGirl.create(:issue)
+ @open_project = @open_issue.project
+
+ @own_hidden_project = FactoryGirl.create(:project, :owner => @issue.user)
+ @own_hidden_project.update_column :visibility, 'hidden'
+ @own_hidden_issue = FactoryGirl.create(:issue, :project => @own_hidden_project, :assignee => @issue.user)
+
+ @hidden_issue = FactoryGirl.create(:issue)
+ @hidden_project = @hidden_issue.project
+ @hidden_project.update_column :visibility, 'hidden'
+
+ @create_params = {:issue => {:title => 'title', :body => 'body'}, :project_id => @project.id, :format => :json}
+ @update_params = {:issue => {:title => 'new title'}, :project_id => @project.id, :id => @issue.serial_id, :format => :json}
+
+ @pull = @project.pull_requests.new :issue_attributes => {:title => 'test', :body => 'testing'}
+ @pull.issue.user, @pull.issue.project = @project.owner, @pull.to_project
+ @pull.to_ref = 'master'
+ @pull.from_project, @pull.from_ref = @project, 'non_conflicts'
+ @pull.save
+ end
+
+ context 'read and accessible abilities' do
+ context 'for user' do
+ before(:each) do
+ http_login(@issue.user)
+ end
+
+ it 'can show issue in own project' do
+ get :show, :project_id => @project.id, :id => @issue.serial_id, :format => :json
+ response.should be_success
+ end
+
+ it 'should render right template for show action' do
+ get :show, :project_id => @project.id, :id => @issue.serial_id, :format => :json
+ response.should render_template('api/v1/issues/show')
+ end
+
+ it 'can show issue in open project' do
+ get :show, :project_id => @open_project.id, :id => @open_issue.serial_id, :format => :json
+ response.should be_success
+ end
+
+ it 'can show issue in own hidden project' do
+ get :show, :project_id => @own_hidden_project.id, :id => @own_hidden_issue.serial_id, :format => :json
+ response.should be_success
+ end
+
+ it "can't show issue in hidden project" do
+ get :show, :project_id => @hidden_project.id, :id => @hidden_issue.serial_id, :format => :json
+ response.status.should == 403
+ end
+
+ it 'should return three issues' do
+ get :all_index, :filter => 'all', :format => :json
+ assigns[:issues].should include(@issue)
+ assigns[:issues].should include(@own_hidden_issue)
+ assigns[:issues].should include(@membered_issue)
+ end
+
+ it 'should render right template for all index action' do
+ get :all_index, :format => :json
+ response.should render_template('api/v1/issues/index')
+ end
+
+ it 'should return only assigned issue' do
+ get :user_index, :format => :json
+ assigns[:issues].should include(@own_hidden_issue)
+ assigns[:issues].should have(1).item
+ end
+
+ it 'should render right template for user index action' do
+ get :user_index, :format => :json
+ response.should render_template('api/v1/issues/index')
+ end
+
+ it 'should return 404' do
+ get :show, :project_id => @project.id, :id => 999999, :format => :json
+ response.status.should == 404
+ end
+
+ it 'should redirect to pull request page' do
+ get :show, :project_id => @project.id, :id => @pull.serial_id, :format => :json
+ response.should redirect_to(api_v1_project_pull_request_path(@project.id, @pull.serial_id))
+ end
+ end
+
+ context 'for anonymous user' do
+ it 'can show issue in open project', :anonymous_access => true do
+ get :show, :project_id => @project.id, :id => @issue.serial_id, :format => :json
+ response.should be_success
+ end
+
+ it "can't show issue in hidden project", :anonymous_access => true do
+ get :show, :project_id => @hidden_project.id, :id => @hidden_issue.serial_id, :format => :json
+ response.status.should == 403
+ end
+
+ it 'should not return any issues' do
+ get :all_index, :filter => 'all', :format => :json
+ response.status.should == 401
+ end
+ end
+ end
+
+ context 'create accessibility' do
+ context 'for user' do
+ before(:each) do
+ http_login(@issue.user)
+ end
+
+ it 'can create issue in own project' do
+ lambda { post :create, @create_params}.should change{ Issue.count }.by(1)
+ end
+
+ it 'can create issue in own hidden project' do
+ lambda { post :create, @create_params.merge(:project_id => @own_hidden_project.id)}.should change{ Issue.count }.by(1)
+ end
+
+ it 'can create issue in open project' do
+ lambda { post :create, @create_params.merge(:project_id => @open_project.id)}.should change{ Issue.count }.by(1)
+ end
+
+ it "can't create issue in hidden project" do
+ lambda { post :create, @create_params.merge(:project_id => @hidden_project.id)}.should change{ Issue.count }.by(0)
+ end
+
+ it 'can assignee issue in own project' do
+ post :create, @create_params.deep_merge(:project_id => @own_hidden_project, :issue => {:assignee_id => @issue.user.id})
+ @own_hidden_project.issues.reload.last.assignee.id.should == @issue.user.id
+ end
+
+ it "can't assignee issue in open project" do
+ post :create, @create_params.deep_merge(:project_id => @open_project.id, :issue => {:assignee_id => @issue.user.id})
+ @open_project.issues.reload.last.assignee.should be_nil
+ end
+ end
+
+ context 'for anonymous user' do
+ it "can't create issue in project", :anonymous_access => true do
+ lambda { post :create, @create_params}.should change{ Issue.count }.by(0)
+ end
+
+ it "can't create issue in hidden project", :anonymous_access => true do
+ lambda { post :create, @create_params.merge(:project_id => @hidden_project.id)}.should change{ Issue.count }.by(0)
+ end
+ end
+ end
+
+ context 'update accessibility' do
+ context 'for user' do
+ before(:each) do
+ http_login(@issue.user)
+ end
+
+ it 'can update issue in own project' do
+ put :update, @update_params
+ @issue.reload.title.should == 'new title'
+ end
+
+ it 'can update issue in own hidden project' do
+ put :update, @update_params.merge(:project_id => @own_hidden_project.id, :id => @own_hidden_issue.serial_id)
+ @own_hidden_issue.reload.title.should == 'new title'
+ end
+
+ it "can't update issue in open project" do
+ put :update, @update_params.merge(:project_id => @open_project.id, :id => @open_issue.serial_id)
+ @open_issue.reload.title.should_not == 'new title'
+ end
+
+ it "can't update issue in hidden project" do
+ put :update, @update_params.merge(:project_id => @hidden_project.id, :id => @hidden_issue.serial_id)
+ @hidden_issue.reload.title.should_not == 'title'
+ end
+
+ it "can't assignee issue in open project" do
+ post :create, @update_params.deep_merge(:project_id => @open_project.id, :issue => {:assignee_id => @issue.user.id})
+ @open_issue.reload.assignee.id.should_not == @issue.user.id
+ end
+
+ it 'can assignee issue in own project' do
+ post :create, @update_params.deep_merge(:issue => {:assignee_id => @issue.user.id})
+ @issue.reload.assignee.id.should_not == @issue.user.id
+ end
+ end
+
+ context 'for anonymous user' do
+ before(:each) do
+ @count = Issue.count
+ end
+ it "can't update issue in project", :anonymous_access => true do
+ put :update, @update_params
+ response.status.should == 401
+ end
+
+ it "can't update issue in hidden project", :anonymous_access => true do
+ put :update, @update_params.merge(:project_id => @hidden_project.id, :id => @hidden_issue.serial_id)
+ response.status.should == 401
+ end
+ end
+ end
+
+ after(:all) do
+ User.destroy_all
+ Platform.destroy_all
+ end
+end
diff --git a/spec/controllers/api/v1/maintainers_controller_spec.rb b/spec/controllers/api/v1/maintainers_controller_spec.rb
index 837539ec9..6d28e2aad 100644
--- a/spec/controllers/api/v1/maintainers_controller_spec.rb
+++ b/spec/controllers/api/v1/maintainers_controller_spec.rb
@@ -1,21 +1,42 @@
require 'spec_helper'
+shared_examples_for 'api maintainers user with reader rights' do
+ it 'should be able to perform index action' do
+ get :index, :platform_id => package.platform_id, :format => :json
+ should render_template(:index)
+ end
+
+ it 'loads all of the maintainers into @maintainers' do
+ get :index, :platform_id => package.platform_id, :format => :json
+ assigns(:maintainers).should have(2).items
+ assigns(:maintainers).should include(package, package2)
+ end
+
+ it 'loads all of the maintainers into @maintainers when search by name' do
+ get :index, :platform_id => package.platform_id, :package_name => 'package1', :format => :json
+ assigns(:maintainers).should have(1).item
+ assigns(:maintainers).should include(package)
+ end
+
+end
+
describe Api::V1::MaintainersController do
before do
stub_symlink_methods
+ FactoryGirl.create(:build_list_package, :platform => package.platform)
end
+ let(:package) { FactoryGirl.create(:build_list_package, :name => 'package1', :actual => true) }
+ let!(:package2) { FactoryGirl.create(:build_list_package, :platform => package.platform, :actual => true) }
- let(:package) { FactoryGirl.create(:build_list_package) }
context 'for guest' do
- it "should be able to perform index action", :anonymous_access => true do
- get :index, :platform_id => package.platform_id, :format => :json
- should render_template(:index)
- end
-
- it 'should be able to perform get_id action', :anonymous_access => false do
- get :index, :platform_id => package.platform_id, :format => :json
- response.status.should == 401
+ if APP_CONFIG['anonymous_access']
+ it_should_behave_like 'api maintainers user with reader rights'
+ else
+ it 'should not be able to perform index action', :anonymous_access => false do
+ get :index, :platform_id => package.platform_id, :format => :json
+ response.status.should == 401
+ end
end
end
@@ -24,9 +45,6 @@ describe Api::V1::MaintainersController do
http_login(FactoryGirl.create(:user))
end
- it "should be able to perform index action" do
- get :index, :platform_id => package.platform_id, :format => :json
- should render_template(:index)
- end
+ it_should_behave_like 'api maintainers user with reader rights'
end
end
diff --git a/spec/controllers/api/v1/platforms_controller_spec.rb b/spec/controllers/api/v1/platforms_controller_spec.rb
index 355c04869..18553c737 100644
--- a/spec/controllers/api/v1/platforms_controller_spec.rb
+++ b/spec/controllers/api/v1/platforms_controller_spec.rb
@@ -224,13 +224,17 @@ describe Api::V1::PlatformsController do
response.status.should == 401
end
- [:show, :platforms_for_build].each do |action|
- it "should not be able to perform #{ action } action", :anonymous_access => false do
- get action, :format => :json
- response.status.should == 401
- end
+ it "should not be able to perform platforms_for_build action", :anonymous_access => false do
+ get :platforms_for_build, :format => :json
+ response.status.should == 401
end
+ it "should not be able to perform show action", :anonymous_access => false do
+ get :show, :id => @platform, :format => :json
+ response.status.should == 401
+ end
+
+
it 'should be able to perform members action', :anonymous_access => true do
get :members, :id => @platform.id, :format => :json
response.should render_template(:members)
@@ -241,6 +245,91 @@ describe Api::V1::PlatformsController do
it_should_behave_like 'api platform user without member rights'
it_should_behave_like 'api platform user without owner rights'
it_should_behave_like 'api platform user without global admin rights'
+
+
+ context 'perform allowed action' do
+ it 'ensures that status 200 if platform empty' do
+ get :allowed
+ response.status.should == 200
+ end
+
+ it 'ensures that status 403 if platform does not exist' do
+ get :allowed, :path => "/rosa-server/repository/SRPMS/base/release/repodata/"
+ response.status.should == 403
+ end
+
+ it 'ensures that status 200 if platform open' do
+ get :allowed, :path => "/#{@platform.name}/repository/SRPMS/base/release/repodata/"
+ response.status.should == 200
+ end
+
+ context 'for hidden platform' do
+ before { @platform.change_visibility }
+
+ it 'ensures that status 403 if no token' do
+ get :allowed, :path => "/#{@platform.name}/repository/SRPMS/base/release/repodata/"
+ response.status.should == 403
+ end
+
+ it 'ensures that status 403 if no token and a lot of "/"' do
+ get :allowed, :path => "///#{@platform.name}///repository/SRPMS/base/release/repodata/"
+ response.status.should == 403
+ end
+
+ it 'ensures that status 200 if token correct and a lot of "/"' do
+ token = FactoryGirl.create(:platform_token, :subject => @platform)
+ http_login token.authentication_token, ''
+ get :allowed, :path => "///#{@platform.name}///repository/SRPMS/base/release/repodata/"
+ response.status.should == 200
+ end
+
+ it 'ensures that status 403 on access to root of platform if no token' do
+ get :allowed, :path => "///#{@platform.name}"
+ response.status.should == 403
+ end
+
+ it 'ensures that status 200 on access to root of platform if token correct' do
+ token = FactoryGirl.create(:platform_token, :subject => @platform)
+ http_login token.authentication_token, ''
+ get :allowed, :path => "///#{@platform.name}"
+ response.status.should == 200
+ end
+
+ it 'ensures that status 403 if wrong token' do
+ http_login 'KuKu', ''
+ get :allowed, :path => "/#{@platform.name}/repository/SRPMS/base/release/repodata/"
+ response.status.should == 403
+ end
+
+ it 'ensures that status 200 if token correct' do
+ token = FactoryGirl.create(:platform_token, :subject => @platform)
+ http_login token.authentication_token, ''
+ get :allowed, :path => "/#{@platform.name}/repository/SRPMS/base/release/repodata/"
+ response.status.should == 200
+ end
+
+ it 'ensures that status 403 if token correct but blocked' do
+ token = FactoryGirl.create(:platform_token, :subject => @platform)
+ token.block
+ http_login token.authentication_token, ''
+ get :allowed, :path => "/#{@platform.name}/repository/SRPMS/base/release/repodata/"
+ response.status.should == 403
+ end
+
+ it 'ensures that status 200 if user token correct and user has ability to read platform' do
+ http_login @platform.owner.authentication_token, ''
+ get :allowed, :path => "/#{@platform.name}/repository/SRPMS/base/release/repodata/"
+ response.status.should == 200
+ end
+
+ it 'ensures that status 403 if user token correct but user has no ability to read platform' do
+ user = FactoryGirl.create(:user)
+ http_login user.authentication_token, ''
+ get :allowed, :path => "/#{@platform.name}/repository/SRPMS/base/release/repodata/"
+ response.status.should == 403
+ end
+ end
+ end
end
context 'for global admin' do
@@ -311,6 +400,38 @@ describe Api::V1::PlatformsController do
it_should_behave_like 'api platform user without global admin rights'
end
+ context 'for member of repository' do
+ before do
+ http_login(@user)
+ repository = FactoryGirl.create(:repository, :platform => @platform)
+ repository.add_member(@user)
+ personal_repository = FactoryGirl.create(:repository, :platform => @personal_platform)
+ personal_repository.add_member(@user)
+ end
+
+ context 'perform index action with type param' do
+ render_views
+ %w(main personal).each do |type|
+ it "ensures that filter by type = #{type} returns true result" do
+ get :index, :format => :json, :type => "#{type}"
+ JSON.parse(response.body)['platforms'].map{ |p| p['platform_type'] }.
+ uniq.should == ["#{type}"]
+ end
+ end
+ end
+
+ it 'should not be able to perform members action for hidden platform' do
+ @platform.update_column(:visibility, 'hidden')
+ get :members, :id => @platform.id, :format => :json
+ response.status.should == 403
+ end
+ it_should_behave_like 'api platform user with reader rights'
+ it_should_behave_like 'api platform user with reader rights for hidden platform'
+ it_should_behave_like 'api platform user without member rights'
+ it_should_behave_like 'api platform user without owner rights'
+ it_should_behave_like 'api platform user without global admin rights'
+ end
+
context 'for simple user' do
before do
http_login(@user)
diff --git a/spec/controllers/api/v1/projects_controller_spec.rb b/spec/controllers/api/v1/projects_controller_spec.rb
index 65e5055e2..49526ed8f 100644
--- a/spec/controllers/api/v1/projects_controller_spec.rb
+++ b/spec/controllers/api/v1/projects_controller_spec.rb
@@ -61,6 +61,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
@@ -235,7 +246,6 @@ shared_examples_for 'api projects user without admin rights' do
@project.members.should include(member)
end
end
-
end
shared_examples_for 'api projects user with owner rights' do
@@ -313,6 +323,18 @@ describe Api::V1::ProjectsController do
it 'ensures that project has been created' do
lambda { post :create, params, :format => :json }.should change{ Project.count }.by(1)
end
+
+ it 'writer group should be able to create project for their group' do
+ group = FactoryGirl.create(:group)
+ group.actors.create(:actor_type => 'User', :actor_id => @user.id, :role => 'writer')
+ lambda { post :create, params.deep_merge({:project => {:owner_type => 'Group', :owner_id => group.id}})}.should change{ Project.count }.by(1)
+ end
+
+ it 'reader group should not be able to create project for their group' do
+ group = FactoryGirl.create(:group)
+ group.actors.create(:actor_type => 'User', :actor_id => @user.id, :role => 'reader')
+ lambda { post :create, params.deep_merge({:project => {:owner_type => 'Group', :owner_id => group.id}})}.should change{ Project.count }.by(0)
+ end
end
it_should_behave_like 'api projects user with reader rights'
@@ -321,6 +343,38 @@ describe Api::V1::ProjectsController do
it_should_behave_like 'api projects user without fork rights for hidden project'
it_should_behave_like 'api projects user without admin rights'
it_should_behave_like 'api projects user without owner rights'
+
+ 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
+
+ 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
diff --git a/spec/controllers/api/v1/pull_requests_controller.rb b/spec/controllers/api/v1/pull_requests_controller.rb
new file mode 100644
index 000000000..e3469a172
--- /dev/null
+++ b/spec/controllers/api/v1/pull_requests_controller.rb
@@ -0,0 +1,324 @@
+# -*- encoding : utf-8 -*-
+require 'spec_helper'
+
+def create_pull to_ref, from_ref, owner, project = @project
+ pull = project.pull_requests.new :issue_attributes => {:title => 'test', :body => 'testing'}
+ pull.issue.user, pull.issue.project = owner, pull.to_project
+ pull.to_ref, pull.from_ref, pull.from_project = to_ref, from_ref, project
+ pull.save; pull.check
+ pull
+end
+
+describe Api::V1::PullRequestsController do
+ before(:all) do
+ stub_symlink_methods
+ stub_redis
+ @project = FactoryGirl.create(:project_with_commit)
+ @pull = create_pull 'master', 'non_conflicts', @project.owner
+
+ @another_project = FactoryGirl.create(:project_with_commit)
+ @another_pull = create_pull 'master', 'non_conflicts', @another_project.owner, @another_project
+
+ @hidden_project = FactoryGirl.create(:project_with_commit)
+ @hidden_project.update_column :visibility, 'hidden'
+ @hidden_pull = create_pull 'master', 'non_conflicts', @hidden_project.owner, @hidden_project
+
+ @own_hidden_project = FactoryGirl.create(:project_with_commit, :owner => @project.owner)
+ @own_hidden_project.update_column :visibility, 'hidden'
+ @own_hidden_pull = create_pull 'master', 'non_conflicts', @own_hidden_project.owner, @own_hidden_project
+ @own_hidden_pull.issue.update_column :assignee_id, @project.owner.id
+
+ @membered_project = FactoryGirl.create(:project_with_commit)
+ @membered_pull = create_pull 'master', 'non_conflicts', @membered_project.owner, @membered_project
+ @membered_project.relations.create(:role => 'reader', :actor => @pull.user)
+
+ @create_params = {:pull_request => {:title => 'title', :body => 'body',
+ :from_ref => 'conflicts', :to_ref => 'master'},
+ :project_id => @project.id, :format => :json}
+
+ @update_params = {:pull_request => {:title => 'new title'},
+ :project_id => @project.id, :id => @pull.serial_id, :format => :json}
+
+ @issue = FactoryGirl.create(:issue, :project => @project)
+ end
+
+ context 'read and accessible abilities' do
+ context 'for user' do
+ before(:each) do
+ http_login(@project.owner)
+ end
+
+ it 'can show pull request in own project' do
+ get :show, :project_id => @project.id, :id => @pull.serial_id, :format => :json
+ response.should be_success
+ end
+
+ it 'should render right template for show action' do
+ get :show, :project_id => @project.id, :id => @pull.serial_id, :format => :json
+ response.should render_template('api/v1/pull_requests/show')
+ end
+
+ it 'can show pull request in open project' do
+ get :show, :project_id => @another_project.id, :id => @another_pull.serial_id, :format => :json
+ response.should be_success
+ end
+
+ it 'can show pull request in own hidden project' do
+ get :show, :project_id => @own_hidden_project.id, :id => @own_hidden_pull.serial_id, :format => :json
+ response.should be_success
+ end
+
+ it 'cant show pull request in hidden project' do
+ get :show, :project_id => @hidden_project.id, :id => @hidden_pull.serial_id, :format => :json
+ response.status.should == 403
+ end
+
+ it 'should return three pull requests' do
+ get :all_index, :filter => 'all', :format => :json
+ assigns[:pulls].should include(@pull)
+ assigns[:pulls].should include(@own_hidden_pull)
+ assigns[:pulls].should include(@membered_pull)
+ end
+
+ it 'should render right template for all index action' do
+ get :all_index, :format => :json
+ response.should render_template('api/v1/pull_requests/index')
+ end
+
+ it 'should return only assigned pull request' do
+ get :user_index, :format => :json
+ assigns[:pulls].should include(@own_hidden_pull)
+ assigns[:pulls].should have(1).item
+ end
+
+ it 'should render right template for user index action' do
+ get :user_index, :format => :json
+ response.should render_template('api/v1/pull_requests/index')
+ end
+
+ %w(commits files).each do |action|
+ it "can show pull request #{action} in own project" do
+ get action, :project_id => @project.id, :id => @pull.serial_id, :format => :json
+ response.should be_success
+ end
+
+ it "should render right template for commits action" do
+ get action, :project_id => @project.id, :id => @pull.serial_id, :format => :json
+ response.should render_template("api/v1/pull_requests/#{action}")
+ end
+
+ it "can't show pull request #{action} in hidden project" do
+ get action, :project_id => @hidden_project.id, :id => @hidden_pull.serial_id, :format => :json
+ response.should_not be_success
+ end
+ end
+
+ it 'should return 404' do
+ get :show, :project_id => @project.id, :id => 999999, :format => :json
+ response.status.should == 404
+ end
+
+ it 'should redirect to issue page' do
+ get :show, :project_id => @project.id, :id => @issue.serial_id, :format => :json
+ response.should redirect_to(api_v1_project_issue_path(@project.id, @issue.serial_id))
+ end
+ end
+
+ context 'for anonymous user' do
+ it 'can show pull request in open project', :anonymous_access => true do
+ get :show, :project_id => @project.id, :id => @pull.serial_id, :format => :json
+ response.should be_success
+ end
+
+ it 'cant show pull request in hidden project', :anonymous_access => true do
+ @project.update_column :visibility, 'hidden'
+ get :show, :project_id => @project.id, :id => @pull.serial_id, :format => :json
+ response.status.should == 403
+ end
+
+ it 'should not return any pull requests' do
+ get :all_index, :filter => 'all', :format => :json
+ response.status.should == 401
+ end
+
+ %w(commits files).each do |action|
+ it "can show pull request #{action} in project", :anonymous_access => true do
+ get action, :project_id => @project.id, :id => @pull.serial_id, :format => :json
+ response.should be_success
+ end
+
+ it "should render right template for commits action", :anonymous_access => true do
+ get action, :project_id => @project.id, :id => @pull.serial_id, :format => :json
+ response.should render_template("api/v1/pull_requests/#{action}")
+ end
+
+ it "can't show pull request #{action} in hidden project", :anonymous_access => true do
+ get action, :project_id => @hidden_project.id, :id => @hidden_pull.serial_id, :format => :json
+ response.should_not be_success
+ end
+ end
+ end
+ end
+
+ context 'create accessibility' do
+ context 'for user' do
+ before(:each) do
+ http_login(@pull.user)
+ end
+
+ it 'can create pull request in own project' do
+ lambda { post :create, @create_params }.should change{ PullRequest.count }.by(1)
+ end
+
+ it 'can create pull request in own hidden project' do
+ lambda { post :create, @create_params.merge(:project_id => @own_hidden_project.id) }.should
+ change{ PullRequest.count }.by(1)
+ end
+
+ it 'can create pull request in open project' do
+ lambda { post :create, @create_params.merge(:project_id => @another_project.id) }.should
+ change{ PullRequest.count }.by(1)
+ end
+
+ it 'cant create pull request in hidden project' do
+ lambda { post :create, @create_params.merge(:project_id => @hidden_project.id) }.should
+ change{ PullRequest.count }.by(0)
+ end
+ end
+
+ context 'for anonymous user' do
+ it 'cant create pull request in project', :anonymous_access => true do
+ lambda { post :create, @create_params }.should change{ PullRequest.count }.by(0)
+ end
+
+ it 'cant create pull request in hidden project', :anonymous_access => true do
+ lambda { post :create, @create_params.merge(:project_id => @hidden_project.id) }.should
+ change{ PullRequest.count }.by(0)
+ end
+ end
+ end
+
+ context 'update accessibility' do
+ context 'for user' do
+ before(:each) do
+ http_login(@project.owner)
+ end
+
+ it 'can update pull request in own project' do
+ put :update, @update_params
+ @pull.reload.title.should == 'new title'
+ end
+
+ it 'can update pull request in own hidden project' do
+ put :update, @update_params.merge(:project_id => @own_hidden_project.id, :id => @own_hidden_pull.serial_id)
+ @own_hidden_pull.reload.title.should == 'new title'
+ end
+
+ it 'cant update pull request in open project' do
+ put :update, @update_params.merge(:project_id => @another_project.id, :id => @another_pull.serial_id)
+ @another_pull.reload.title.should_not == 'new title'
+ end
+
+ it 'cant update pull request in hidden project' do
+ put :update, @update_params.merge(:project_id => @hidden_project.id, :id => @hidden_pull.serial_id)
+ @hidden_pull.reload.title.should_not == 'title'
+ end
+
+ it 'can merge pull request in own project' do
+ put :merge, :project_id => @project.id, :id => @pull.serial_id, :format => :json
+ @pull.reload.status.should == 'merged'
+ response.should be_success
+ end
+
+ it 'can merge pull request in own hidden project' do
+ put :merge, :project_id => @own_hidden_project.id, :id => @own_hidden_pull.serial_id, :format => :json
+ @own_hidden_pull.reload.status.should == 'merged'
+ response.should be_success
+ end
+
+ it 'cant merge pull request in open project' do
+ put :merge, :project_id => @another_project.id, :id => @another_pull.serial_id, :format => :json
+ @another_pull.reload.status.should == 'ready'
+ response.status.should == 403
+ end
+
+ it 'cant merge pull request in hidden project' do
+ put :merge, :project_id => @hidden_project.id, :id => @hidden_pull.serial_id, :format => :json
+ @hidden_pull.reload.status.should == 'ready'
+ response.status.should == 403
+ end
+ end
+
+ context 'for anonymous user' do
+ it 'cant update pull request in project', :anonymous_access => true do
+ put :update, @update_params
+ response.status.should == 401
+ end
+
+ it 'cant update pull request in hidden project', :anonymous_access => true do
+ put :update, @update_params.merge(:project_id => @hidden_project.id, :id => @hidden_pull.serial_id)
+ response.status.should == 401
+ end
+
+ it 'cant merge pull request in open project' do
+ put :merge, :project_id => @another_project.id, :id => @another_pull.serial_id, :format => :json
+ @another_pull.reload.status.should == 'ready'
+ response.status.should == 401
+ end
+
+ it 'cant merge pull request in hidden project' do
+ put :merge, :project_id => @hidden_project.id, :id => @hidden_pull.serial_id, :format => :json
+ @hidden_pull.reload.status.should == 'ready'
+ response.status.should == 401
+ end
+ end
+ end
+
+ context 'send email messages' do
+ before(:each) do
+ @project_reader = FactoryGirl.create :user
+ @project.relations.create!(:actor_type => 'User', :actor_id => @project_reader.id, :role => 'reader')
+ @project_admin = FactoryGirl.create :user
+ @project.relations.create!(:actor_type => 'User', :actor_id => @project_admin.id, :role => 'admin')
+ @project_writer = FactoryGirl.create :user
+ @project.relations.create!(:actor_type => 'User', :actor_id => @project_writer.id, :role => 'writer')
+
+ http_login(@project_writer)
+ ActionMailer::Base.deliveries = []
+ end
+
+ it 'should send two email messages to project admins' do
+ post :create, @create_params
+ @project.pull_requests.last.issue.send(:new_issue_notifications)
+ @project.pull_requests.last.issue.send(:send_assign_notifications)
+ ActionMailer::Base.deliveries.count.should == 2
+ end
+
+ it 'should send two email messages to admins and one to assignee' do
+ post :create, @create_params.deep_merge(:pull_request => {:assignee_id => @project_reader.id})
+ @project.pull_requests.last.issue.send(:new_issue_notifications)
+ @project.pull_requests.last.issue.send(:send_assign_notifications)
+ ActionMailer::Base.deliveries.count.should == 3
+ end
+
+ it 'should send email message to new assignee' do
+ http_login(@project_admin)
+ put :update, @update_params.deep_merge(:pull_request => {:assignee_id => @project_reader.id})
+ @project.pull_requests.last.issue.send(:send_assign_notifications)
+ ActionMailer::Base.deliveries.count.should == 1
+ end
+
+ it 'should not duplicate email message' do
+ post :create, @create_params.deep_merge(:pull_request => {:assignee_id => @project_admin.id})
+ @project.pull_requests.last.issue.send(:new_issue_notifications)
+ @project.pull_requests.last.issue.send(:send_assign_notifications)
+ ActionMailer::Base.deliveries.count.should == 2 # send only to admins
+ ActionMailer::Base.deliveries.first.to != ActionMailer::Base.deliveries.last.to
+ end
+ end
+
+ after(:all) do
+ User.destroy_all
+ Platform.destroy_all
+ end
+end
diff --git a/spec/controllers/api/v1/repositories_controller_spec.rb b/spec/controllers/api/v1/repositories_controller_spec.rb
index cb812db39..bdf88710b 100644
--- a/spec/controllers/api/v1/repositories_controller_spec.rb
+++ b/spec/controllers/api/v1/repositories_controller_spec.rb
@@ -61,6 +61,15 @@ shared_examples_for 'api repository user with writer rights' do
end
end
+ context 'api repository user with add/remove repo_lock_file rights' do
+ [:add_repo_lock_file, :remove_repo_lock_file].each do |action|
+ it "should be able to perform #{action} action" do
+ put action, :id => @repository.id, :format => :json
+ response.should be_success
+ end
+ end
+ end
+
context 'api repository user with add_member rights' do
let(:member) { FactoryGirl.create(:user) }
before do
@@ -98,15 +107,44 @@ 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
+ context 'api repository user with update signatures rights' do
+ before do
+ kp = FactoryGirl.build(:key_pair)
+ put :signatures, :id => @repository.id, :repository => {:public => kp.public, :secret => kp.secret}, :format => :json
+ end
+ it 'should be able to perform signatures action' do
+ response.should be_success
+ end
+ it 'ensures that signatures has been updated' do
+ @repository.key_pair.should_not be_nil
+ end
+ end
+
+end
+
+shared_examples_for 'api repository user with project manage rights' do
+
context 'api repository user with add_project rights' do
before { put :add_project, :id => @repository.id, :project_id => @project.id, :format => :json }
it 'should be able to perform add_project action' do
@@ -131,19 +169,6 @@ shared_examples_for 'api repository user with writer rights' do
end
end
- context 'api repository user with update signatures rights' do
- before do
- kp = FactoryGirl.build(:key_pair)
- put :signatures, :id => @repository.id, :repository => {:public => kp.public, :secret => kp.secret}, :format => :json
- end
- it 'should be able to perform signatures action' do
- response.should be_success
- end
- it 'ensures that signatures has been updated' do
- @repository.key_pair.should_not be_nil
- end
- end
-
end
shared_examples_for 'api repository user without writer rights' do
@@ -162,6 +187,15 @@ shared_examples_for 'api repository user without writer rights' do
end
end
+ context 'api repository user without add/remove repo_lock_file rights' do
+ [:add_repo_lock_file, :remove_repo_lock_file].each do |action|
+ it "should not be able to perform #{action} action" do
+ put action, :id => @repository.id, :format => :json
+ response.should_not be_success
+ end
+ end
+ end
+
context 'api repository user without add_member rights' do
let(:member) { FactoryGirl.create(:user) }
before do
@@ -208,6 +242,22 @@ shared_examples_for 'api repository user without writer rights' do
end
end
+ context 'api repository user without update signatures rights' do
+ before do
+ kp = FactoryGirl.build(:key_pair)
+ put :signatures, :id => @repository.id, :repository => {:public => kp.public, :secret => kp.secret}, :format => :json
+ end
+ it 'should not be able to perform signatures action' do
+ response.should_not be_success
+ end
+ it 'ensures that signatures has not been updated' do
+ @repository.key_pair.should be_nil
+ end
+ end
+
+end
+
+shared_examples_for 'api repository user without project manage rights' do
context 'api repository user without add_project rights' do
before { put :add_project, :id => @repository.id, :project_id => @project.id, :format => :json }
it 'should not be able to perform add_project action' do
@@ -231,20 +281,6 @@ shared_examples_for 'api repository user without writer rights' do
@repository.projects.should include(@project)
end
end
-
- context 'api repository user without update signatures rights' do
- before do
- kp = FactoryGirl.build(:key_pair)
- put :signatures, :id => @repository.id, :repository => {:public => kp.public, :secret => kp.secret}, :format => :json
- end
- it 'should not be able to perform signatures action' do
- response.should_not be_success
- end
- it 'ensures that signatures has not been updated' do
- @repository.key_pair.should be_nil
- end
- end
-
end
@@ -271,6 +307,7 @@ describe Api::V1::RepositoriesController do
it_should_behave_like 'api repository user with show rights'
end
it_should_behave_like 'api repository user without writer rights'
+ it_should_behave_like 'api repository user without project manage rights'
it_should_behave_like 'api repository user without key_pair rights'
it 'should not be able to perform projects action', :anonymous_access => false do
@@ -295,9 +332,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'
@@ -316,6 +355,22 @@ describe Api::V1::RepositoriesController do
it_should_behave_like 'api repository user without reader rights for hidden platform'
it_should_behave_like 'api repository user with show rights'
it_should_behave_like 'api repository user without writer rights'
+ it_should_behave_like 'api repository user without project manage rights'
+ it_should_behave_like 'api repository user without key_pair rights'
+ end
+
+ context 'for member of repository' do
+ before(:each) do
+ @user = FactoryGirl.create(:user)
+ @repository.add_member @user
+ http_login @user
+ end
+
+ it_should_behave_like 'api repository user with reader rights'
+ it_should_behave_like 'api repository user with reader rights for hidden platform'
+ it_should_behave_like 'api repository user with show rights'
+ it_should_behave_like 'api repository user with project manage rights'
+ it_should_behave_like 'api repository user without writer rights'
it_should_behave_like 'api repository user without key_pair rights'
end
diff --git a/spec/controllers/autocompletes_controller_spec.rb b/spec/controllers/autocompletes_controller_spec.rb
index ac1f61e19..a80d70991 100644
--- a/spec/controllers/autocompletes_controller_spec.rb
+++ b/spec/controllers/autocompletes_controller_spec.rb
@@ -4,8 +4,9 @@ describe AutocompletesController do
before {stub_symlink_methods}
context 'for user' do
+ let(:user) { FactoryGirl.create(:user) }
before do
- set_session_for(FactoryGirl.create(:user))
+ set_session_for user
end
it 'should be able to perform autocomplete_group_uname action' do
@@ -18,6 +19,44 @@ describe AutocompletesController do
response.should be_success
end
+ context 'autocomplete_extra_build_list' do
+ let(:build_list) { FactoryGirl.create(:build_list, :user => user) }
+ let(:params) { { :term => build_list.id,
+ :platform_id => build_list.save_to_platform_id } }
+
+ it 'no data when build_list without container' do
+ get :autocomplete_extra_build_list, params
+ response.body.should == '[]'
+ end
+
+ it 'shows data when build_list with container' do
+ build_list.update_column(:container_status, BuildList::BUILD_PUBLISHED)
+ get :autocomplete_extra_build_list, params
+ response.body.should_not == '[]'
+ end
+ end
+
+ context 'autocomplete_extra_repositories' do
+ let(:repository) { FactoryGirl.create(:repository) }
+ let(:params) { { :term => repository.platform.name,
+ :platform_id => repository.platform_id } }
+
+ before do
+ repository.platform.add_member(user)
+ end
+
+ it 'no data when repository of main platform' do
+ get :autocomplete_extra_repositories, params
+ response.body.should == '[]'
+ end
+
+ it 'shows data when repository of personal platform' do
+ Platform.update_all(:platform_type => 'personal')
+ get :autocomplete_extra_repositories, params
+ response.body.should_not == '[]'
+ end
+ end
+
end
context 'for guest' do
@@ -26,14 +65,16 @@ describe AutocompletesController do
set_session_for(User.new)
end
- it 'should not be able to perform autocomplete_group_uname action' do
- get :autocomplete_group_uname
- response.should redirect_to(new_user_session_path)
- end
-
- it 'should not be able to perform autocomplete_user_uname action' do
- get :autocomplete_user_uname
- response.should redirect_to(new_user_session_path)
+ [
+ :autocomplete_group_uname,
+ :autocomplete_user_uname,
+ :autocomplete_extra_build_list,
+ :autocomplete_extra_repositories
+ ].each do |action|
+ it "should not be able to perform #{action} action" do
+ get action
+ response.should redirect_to(new_user_session_path)
+ end
end
end
diff --git a/spec/controllers/groups/profile_controller_spec.rb b/spec/controllers/groups/profile_controller_spec.rb
index 93119ad35..567ae26e2 100644
--- a/spec/controllers/groups/profile_controller_spec.rb
+++ b/spec/controllers/groups/profile_controller_spec.rb
@@ -2,7 +2,7 @@ require 'spec_helper'
shared_examples_for 'group user with project show rights' do
it 'should be able to perform show action' do
- get :show, :id => @group
+ get :show, :uname => @group.uname
response.should render_template(:show)
end
end
diff --git a/spec/controllers/platforms/contents_controller_spec.rb b/spec/controllers/platforms/contents_controller_spec.rb
new file mode 100644
index 000000000..e5cca7814
--- /dev/null
+++ b/spec/controllers/platforms/contents_controller_spec.rb
@@ -0,0 +1,98 @@
+# -*- encoding : utf-8 -*-
+require 'spec_helper'
+
+shared_examples_for 'content platform user without show rights for hidden platform' do
+ it 'should not be able to perform index action' do
+ @platform.update_column(:visibility, 'hidden')
+ get :index, :platform_id => @platform
+ response.should_not be_success
+ end
+end
+
+shared_examples_for 'content platform user with show rights for hidden platform' do
+ it 'should be able to perform index action' do
+ @platform.update_column(:visibility, 'hidden')
+ get :index, :platform_id => @platform
+ response.should be_success
+ end
+end
+
+shared_examples_for 'content platform user with show rights' do
+ it 'should be able to perform index action for main platform' do
+ get :index, :platform_id => @platform
+ response.should be_success
+ end
+
+ it 'should be able to perform index action for personal platform' do
+ get :index, :platform_id => @personal_platform
+ response.should be_success
+ end
+end
+
+describe Platforms::ContentsController do
+ before do
+ stub_symlink_methods
+
+ @platform = FactoryGirl.create(:platform)
+ @personal_platform = FactoryGirl.create(:platform, :platform_type => 'personal')
+
+ @user = FactoryGirl.create(:user)
+ end
+
+ context 'for guest' do
+
+ it 'should not be able to perform index action for main platform', :anonymous_access => false do
+ get :index, :platform_id => @platform
+ response.should_not be_success
+ end
+
+ it 'should not be able to perform index action for personal platform', :anonymous_access => false do
+ get :index, :platform_id => @personal_platform
+ response.should_not be_success
+ end
+
+ it_should_behave_like 'content platform user with show rights' if APP_CONFIG['anonymous_access']
+ it_should_behave_like 'content platform user without show rights for hidden platform'
+ end
+
+ context 'for global admin' do
+ before do
+ http_login(FactoryGirl.create(:admin))
+ end
+
+ it_should_behave_like 'content platform user with show rights'
+ it_should_behave_like 'content platform user with show rights for hidden platform'
+ end
+
+ context 'for owner user' do
+ before do
+ http_login(@user)
+ @platform.owner = @user; @platform.save
+ @platform.relations.create!(:actor_type => 'User', :actor_id => @user.id, :role => 'admin')
+ end
+
+ it_should_behave_like 'content platform user with show rights'
+ it_should_behave_like 'content platform user with show rights for hidden platform'
+ end
+
+ context 'for member of platform' do
+ before do
+ http_login(@user)
+ @platform.add_member(@user)
+ @personal_platform.add_member(@user)
+ end
+
+ it_should_behave_like 'content platform user with show rights'
+ it_should_behave_like 'content platform user with show rights for hidden platform'
+ end
+
+ context 'for simple user' do
+ before do
+ http_login(@user)
+ end
+
+ it_should_behave_like 'content platform user with show rights'
+ it_should_behave_like 'content platform user without show rights for hidden platform'
+ end
+
+end
diff --git a/spec/controllers/platforms/key_pairs_controller_spec.rb b/spec/controllers/platforms/key_pairs_controller_spec.rb
index cef278b35..bb21c11ac 100644
--- a/spec/controllers/platforms/key_pairs_controller_spec.rb
+++ b/spec/controllers/platforms/key_pairs_controller_spec.rb
@@ -78,7 +78,7 @@ describe Platforms::KeyPairsController do
@create_params = {
:platform_id => @platform,
:key_pair => {
- :repository_id => @repository,
+ :repository_id => @repository.id,
:public => kp.public,
:secret => kp.secret
}
diff --git a/spec/controllers/platforms/mass_builds_controller_spec.rb b/spec/controllers/platforms/mass_builds_controller_spec.rb
index bc70d7054..d5fbc4b06 100644
--- a/spec/controllers/platforms/mass_builds_controller_spec.rb
+++ b/spec/controllers/platforms/mass_builds_controller_spec.rb
@@ -6,6 +6,11 @@ shared_examples_for 'mass_build platform owner' do
response.should render_template(:index)
end
+ it 'should be able to perform new action' do
+ get :new, :platform_id => @platform
+ response.should render_template(:new)
+ end
+
it 'should be able to perform create action' do
post :create, @create_params
response.should redirect_to(platform_mass_builds_path(@platform))
@@ -45,19 +50,19 @@ shared_examples_for 'mass_build platform owner' do
get :get_list, :platform_id => @platform, :id => @mass_build, :kind => 'failed_builds_list'
response.should be_success
end
+end
- context 'for personal platform' do
- before(:each) do
- Platform.update_all(:platform_type => 'personal')
- end
-
- [:cancel, :get_list, :create, :publish].each do |action|
- it "should not be able to perform #{ action } action" do
- get action, :platform_id => @platform, :id => @mass_build.id
- response.should redirect_to(forbidden_path)
- end
+shared_examples_for 'mass_build platform owner of personal platform' do
+ before(:each) do
+ Platform.update_all(:platform_type => 'personal')
+ repository = FactoryGirl.create(:repository)
+ @mass_build.build_lists.each do |bl|
+ bl.build_for_platform = repository.platform
+ bl.include_repos = [repository.id]
+ bl.save
end
end
+ it_should_behave_like 'mass_build platform owner'
end
shared_examples_for 'mass_build platform reader' do
@@ -71,6 +76,11 @@ shared_examples_for 'mass_build platform reader' do
response.should be_success
end
+ it "should not be able to perform new action" do
+ get :new, :platform_id => @platform
+ response.should redirect_to(forbidden_path)
+ end
+
it "should not be able to perform create action" do
get :create, :platform_id => @platform
response.should redirect_to(forbidden_path)
@@ -112,14 +122,17 @@ describe Platforms::MassBuildsController do
@repository.projects << project
@create_params = {
- :platform_id => @platform,
- :projects_list => @repository.projects.map(&:name).join("\n"),
- :arches => [Arch.first.id],
- :auto_publish => true
+ :mass_build => {
+ :projects_list => @repository.projects.map(&:name).join("\n"),
+ :auto_publish => true,
+ :build_for_platform_id => @platform
+ },
+ :platform_id => @platform,
+ :arches => [Arch.first.id],
}
- @mass_build = FactoryGirl.create(:mass_build, :platform => @platform, :user => @user, :projects_list => project.name)
- FactoryGirl.create(:build_list_core, :mass_build => @mass_build, :status => BuildList::SUCCESS)
+ @mass_build = FactoryGirl.create(:mass_build, :save_to_platform => @platform, :user => @user, :projects_list => project.name)
+ FactoryGirl.create(:build_list, :mass_build => @mass_build, :status => BuildList::SUCCESS)
end
context 'for guest' do
@@ -144,12 +157,12 @@ describe Platforms::MassBuildsController do
response.should redirect_to(new_user_session_path)
end
- it "should not be able to perform create action" do
- get :create, :platform_id => @platform
+ it "should not be able to perform new action" do
+ get :new, :platform_id => @platform
response.should redirect_to(new_user_session_path)
end
- [:cancel, :publish].each do |action|
+ [:cancel, :publish, :create].each do |action|
it "should not be able to perform #{action} action" do
post action, :platform_id => @platform, :id => @mass_build
response.should redirect_to(new_user_session_path)
@@ -180,6 +193,7 @@ describe Platforms::MassBuildsController do
end
it_should_behave_like 'mass_build platform owner'
+ it_should_behave_like 'mass_build platform owner of personal platform'
end
context 'for owner user' do
@@ -192,6 +206,7 @@ describe Platforms::MassBuildsController do
end
it_should_behave_like 'mass_build platform owner'
+ it_should_behave_like 'mass_build platform owner of personal platform'
end
context 'for admin user' do
@@ -202,6 +217,7 @@ describe Platforms::MassBuildsController do
end
it_should_behave_like 'mass_build platform owner'
+ it_should_behave_like 'mass_build platform owner of personal platform'
end
context 'for reader user' do
diff --git a/spec/controllers/platforms/platforms_controller_spec.rb b/spec/controllers/platforms/platforms_controller_spec.rb
index dee03b79c..e4498d871 100644
--- a/spec/controllers/platforms/platforms_controller_spec.rb
+++ b/spec/controllers/platforms/platforms_controller_spec.rb
@@ -28,6 +28,22 @@ shared_examples_for 'platform user with owner rights' do
end
end
+ context 'perform change_visibility action' do
+ before do
+ @visibility = @platform.visibility
+ post :change_visibility, :id => @platform.id
+ end
+
+ it 'should be able to perform action' do
+ response.should redirect_to(platform_path(@platform))
+ end
+
+ it 'ensures that visibility of platform has been changed' do
+ @platform.reload
+ @platform.visibility.should_not == @visibility
+ end
+ end
+
context 'platform user with destroy rights for main platforms only' do
it 'should be able to perform destroy action for main platform' do
delete :destroy, :id => @platform.id
@@ -61,6 +77,22 @@ shared_examples_for 'platform user without owner rights' do
end
end
+ context 'perform change_visibility action' do
+ before do
+ @visibility = @platform.visibility
+ post :change_visibility, :id => @platform.id
+ end
+
+ it 'should not be able to perform action' do
+ response.should_not be_success
+ end
+
+ it 'ensures that visibility of platform has not been changed' do
+ @platform.reload
+ @platform.visibility.should == @visibility
+ end
+ end
+
context 'platform user without destroy rights' do
it 'should not be able to perform destroy action for main platform' do
delete :destroy, :id => @platform.id
@@ -345,6 +377,22 @@ describe Platforms::PlatformsController do
it_should_behave_like 'platform user without global admin rights'
end
+ context 'for member of repository' do
+ before do
+ http_login(@user)
+ repository = FactoryGirl.create(:repository, :platform => @platform)
+ repository.add_member(@user)
+ personal_repository = FactoryGirl.create(:repository, :platform => @personal_platform)
+ personal_repository.add_member(@user)
+ end
+
+ it_should_behave_like 'platform user with reader rights'
+ it_should_behave_like 'platform user with reader rights for hidden platform'
+ it_should_behave_like 'platform user without member rights'
+ it_should_behave_like 'platform user without owner rights'
+ it_should_behave_like 'platform user without global admin rights'
+ end
+
context 'for simple user' do
before do
http_login(@user)
diff --git a/spec/controllers/platforms/products_controller_spec.rb b/spec/controllers/platforms/products_controller_spec.rb
index 5ade7f3ad..61560f955 100644
--- a/spec/controllers/platforms/products_controller_spec.rb
+++ b/spec/controllers/platforms/products_controller_spec.rb
@@ -4,7 +4,7 @@ shared_examples_for 'admin user' do
it 'should be able to create product' do
lambda { post :create, @create_params }.should change{ Product.count }.by(1)
- response.should redirect_to(platform_product_path( Product.last.platform.id, Product.last ))
+ response.should redirect_to(platform_product_path( Product.last.platform, Product.last ))
end
it 'should be able to update product' do
@@ -30,7 +30,7 @@ describe Platforms::ProductsController do
@product = FactoryGirl.create(:product, :platform => @platform)
@project = FactoryGirl.create(:project)
- params = {:platform_id => @platform.id, :src_project => @project.name_with_owner}
+ params = {:platform_id => @platform, :src_project => @project.name_with_owner}
@create_params = params.merge({:product => {:name => 'pro', :time_living => 150}})
@update_params = params.merge({:product => {:name => 'pro2'}})
diff --git a/spec/controllers/platforms/repositories_controller_spec.rb b/spec/controllers/platforms/repositories_controller_spec.rb
index a2f96d5df..68993464a 100644
--- a/spec/controllers/platforms/repositories_controller_spec.rb
+++ b/spec/controllers/platforms/repositories_controller_spec.rb
@@ -1,13 +1,5 @@
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
@@ -29,6 +21,20 @@ shared_examples_for 'user with change projects in repository rights' do
end
+shared_examples_for 'user with rights of add/remove sync_lock_file to repository' do
+ it 'should be able to perform sync_lock_file action' do
+ put :sync_lock_file, :id => @repository.id, :platform_id => @platform.id
+ response.should redirect_to(edit_platform_repository_path(@platform, @repository))
+ end
+end
+
+shared_examples_for 'user without rights of add/remove sync_lock_file to repository' do
+ it 'should not be able to perform #{action} action' do
+ put :sync_lock_file, :id => @repository.id, :platform_id => @platform.id
+ response.should redirect_to(redirect_path)
+ end
+end
+
shared_examples_for 'user without change projects in repository rights' do
it 'should not be able to add project to repository' do
get :add_project, :id => @repository.id, :platform_id => @platform.id, :project_id => @project.id
@@ -36,6 +42,12 @@ shared_examples_for 'user without change projects in repository rights' do
@repository.projects.should_not include(@project)
end
+ it 'should not be able to perform regenerate_metadata action' do
+ put :regenerate_metadata, :id => @repository.id, :platform_id => @platform.id
+ response.should redirect_to(redirect_path)
+ @repository.repository_statuses.should have(:no).items
+ end
+
it 'should not be able to remove project from repository' do
delete :remove_project, :id => @repository.id, :platform_id => @platform.id, :project_id => @project.id
response.should redirect_to(redirect_path)
@@ -49,6 +61,18 @@ shared_examples_for 'registered user or guest' do
response.should redirect_to(redirect_path)
end
+ it 'should not be able to perform regenerate_metadata action' do
+ put :regenerate_metadata, :id => @repository.id, :platform_id => @platform.id
+ response.should redirect_to(redirect_path)
+ @repository.repository_statuses.should have(:no).items
+ end
+
+ it 'should not be able to perform regenerate_metadata action of personal repository' do
+ put :regenerate_metadata, :id => @personal_repository.id, :platform_id => @personal_repository.platform.id
+ response.should redirect_to(redirect_path)
+ @personal_repository.repository_statuses.should have(:no).items
+ end
+
it 'should not be able to perform create action' do
post :create, @create_params
lambda { post :create, @create_params }.should change{ Repository.count }.by(0)
@@ -89,12 +113,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
@@ -118,19 +146,40 @@ end
shared_examples_for 'platform admin user' do
it_should_behave_like 'registered user'
+ it_should_behave_like 'user with rights of add/remove sync_lock_file to repository'
it 'should be able to perform new action' do
get :new, :platform_id => @platform.id
response.should render_template(:new)
end
+ it 'should be able to perform regenerate_metadata action' do
+ put :regenerate_metadata, :id => @repository.id, :platform_id => @platform.id
+ response.should redirect_to(platform_repository_path(@platform, @repository))
+ @repository.repository_statuses.find_by_platform_id(@platform.id).
+ waiting_for_regeneration?.should be_true
+ end
+
+ it 'should be able to perform regenerate_metadata action of personal repository' do
+ put :regenerate_metadata, :id => @personal_repository.id, :platform_id => @personal_repository.platform.id, :build_for_platform_id => @platform.id
+ response.should redirect_to(platform_repository_path(@personal_repository.platform, @personal_repository))
+ @personal_repository.repository_statuses.find_by_platform_id(@platform.id).
+ waiting_for_regeneration?.should be_true
+ end
+
+ it 'should not be able to perform regenerate_metadata action of personal repository when build_for_platform does not exist' do
+ put :regenerate_metadata, :id => @personal_repository.id, :platform_id => @personal_repository.platform.id
+ response.should render_template(:file => "#{Rails.root}/public/404.html")
+ @personal_repository.repository_statuses.should have(:no).items
+ end
+
it 'should be able to create repository' do
lambda { post :create, @create_params }.should change{ Repository.count }.by(1)
response.should redirect_to(platform_repository_path(@platform, Repository.last))
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
@@ -162,15 +211,27 @@ 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
before(:each) do
stub_symlink_methods
+ stub_redis
@platform = FactoryGirl.create(:platform)
@repository = FactoryGirl.create(:repository, :platform => @platform)
@@ -194,6 +255,7 @@ describe Platforms::RepositoriesController do
let(:redirect_path) { new_user_session_path }
it_should_behave_like 'registered user or guest'
it_should_behave_like 'user without change projects in repository rights'
+ it_should_behave_like 'user without rights of add/remove sync_lock_file to repository'
it "should not be able to perform show action", :anonymous_access => false do
get :show, :id => @repository
@@ -218,6 +280,7 @@ describe Platforms::RepositoriesController do
let(:redirect_path) { forbidden_path }
it_should_behave_like 'registered user or guest'
it_should_behave_like 'user without change projects in repository rights'
+ it_should_behave_like 'user without rights of add/remove sync_lock_file to repository'
end
context 'for admin' do
@@ -233,6 +296,10 @@ describe Platforms::RepositoriesController do
context 'for platform owner user' do
before(:each) do
@user = @repository.platform.owner
+ platform = @personal_repository.platform
+ platform.owner = @user
+ # Owner of personal platform can't be changed
+ platform.save(:validate => false)
set_session_for(@user)
end
@@ -241,7 +308,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'
@@ -249,7 +318,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.add_member @user
+ end
end
it_should_behave_like 'registered user'
@@ -257,6 +328,21 @@ describe Platforms::RepositoriesController do
let(:redirect_path) { forbidden_path }
it_should_behave_like 'registered user or guest'
it_should_behave_like 'user with change projects in repository rights'
+ it_should_behave_like 'user without rights of add/remove sync_lock_file to repository'
+
+ context 'for hidden platform' do
+ before do
+ @platform.update_column(:visibility, 'hidden')
+ @personal_repository.platform.update_column(:visibility, 'hidden')
+ end
+ it_should_behave_like 'registered user'
+
+ let(:redirect_path) { forbidden_path }
+ it_should_behave_like 'registered user or guest'
+ it_should_behave_like 'user with change projects in repository rights'
+ it_should_behave_like 'user without rights of add/remove sync_lock_file to repository'
+ end
+
end
end
diff --git a/spec/controllers/platforms/tokens_controller_spec.rb b/spec/controllers/platforms/tokens_controller_spec.rb
new file mode 100644
index 000000000..5e27049d9
--- /dev/null
+++ b/spec/controllers/platforms/tokens_controller_spec.rb
@@ -0,0 +1,127 @@
+require 'spec_helper'
+
+def create_key_pair(repository, user)
+ @key_pair = FactoryGirl.create(:key_pair, :repository => repository, :user => user)
+end
+
+shared_examples_for 'token of platform for owner' do
+ [:index, :new].each do |action|
+ it "should be able to perform #{action} action" do
+ get action, :platform_id => @platform
+ response.should render_template(action)
+ end
+ end
+
+ it 'should not be able to perform show action' do
+ get :show, :platform_id => @platform, :id => @platform_token
+ response.should render_template(:show)
+ end
+
+ it 'should be able to perform create action' do
+ post :create, @create_params
+ response.should redirect_to(platform_tokens_path(@platform))
+ end
+
+ it 'should create key pair into db on create action' do
+ lambda { post :create, @create_params }.should change{Token.count}.by(1)
+ end
+end
+
+shared_examples_for 'token of platform for simple user or guest' do
+ [:index, :new].each do |action|
+ it "should not be able to perform #{ action } action" do
+ get action, :platform_id => @platform
+ response.should redirect_to(redirected_url)
+ end
+ end
+
+ it 'should not be able to perform show action' do
+ get :show, :platform_id => @platform, :id => @platform_token
+ response.should redirect_to(redirected_url)
+ end
+
+ it 'should not be able to perform show action' do
+ post :create, @create_params
+ response.should redirect_to(redirected_url)
+ end
+
+ it 'should not change objects count on create success' do
+ lambda { post :create, @create_params }.should change{ Token.count }.by(0)
+ end
+end
+
+describe Platforms::TokensController do
+ before do
+ stub_symlink_methods
+
+ @platform = FactoryGirl.create(:platform)
+ @user = FactoryGirl.create(:user)
+ @platform_token = FactoryGirl.create(:platform_token, :subject => @platform)
+ @create_params = {
+ :platform_id => @platform,
+ :tokens => {
+ :description => 'description'
+ }
+ }
+ end
+
+ it_should_behave_like 'token of platform for simple user or guest' do
+ let(:redirected_url) { new_user_session_path }
+ end
+
+ context 'for global admin' do
+ before(:each) do
+ @admin = FactoryGirl.create(:admin)
+ @user = FactoryGirl.create(:user)
+ set_session_for(@admin)
+ end
+
+ it_should_behave_like 'token of platform for owner'
+ end
+
+ context 'for owner user' do
+ before(:each) do
+ @user = FactoryGirl.create(:user)
+ set_session_for(@user)
+
+ @platform.owner = @user
+ @platform.save
+ end
+
+ it_should_behave_like 'token of platform for owner'
+ end
+
+ context 'for admin user' do
+ before(:each) do
+ @user = FactoryGirl.create(:user)
+ set_session_for(@user)
+ @platform.relations.create!(:actor_type => 'User', :actor_id => @user.id, :role => 'admin')
+ end
+
+ it_should_behave_like 'token of platform for owner'
+ end
+
+ context 'for reader user' do
+ before do
+ @user = FactoryGirl.create(:user)
+ set_session_for(@user)
+ @platform.relations.create!(:actor_type => 'User', :actor_id => @user.id, :role => 'reader')
+ end
+
+ it_should_behave_like 'token of platform for simple user or guest' do
+ let(:redirected_url) { forbidden_url }
+ end
+ end
+
+ context 'for simple user' do
+ before do
+ @user = FactoryGirl.create(:user)
+ set_session_for(@user)
+ end
+
+ it_should_behave_like 'token of platform for simple user or guest' do
+ let(:redirected_url) { forbidden_url }
+ end
+ end
+
+end
diff --git a/spec/controllers/projects/build_lists_controller_spec.rb b/spec/controllers/projects/build_lists_controller_spec.rb
index 27af17e06..efc6ef466 100644
--- a/spec/controllers/projects/build_lists_controller_spec.rb
+++ b/spec/controllers/projects/build_lists_controller_spec.rb
@@ -14,34 +14,6 @@ describe Projects::BuildListsController do
end
end
- shared_examples_for 'show extra_repos_and_builds actions' do
- it 'shows data when perform autocomplete_to_extra_repos_and_builds action' do
- @build_list.update_column(:container_status, BuildList::BUILD_PUBLISHED)
- get :autocomplete_to_extra_repos_and_builds, {:term => @build_list.id, :platform_id => @build_list.save_to_platform_id}
- response.body.should_not == '[]'
- end
-
- it 'shows data when perform update_extra_repos_and_builds action' do
- @build_list.update_column(:container_status, BuildList::BUILD_PUBLISHED)
- get :update_extra_repos_and_builds, {:build_list => {:save_to_repository_id => @build_list.save_to_repository_id, :extra_build_lists => [@build_list.id]}, :extra_repo => ''}
- response.body.should_not == ' '
- end
- end
-
- shared_examples_for 'not show extra_repos_and_builds actions' do
- it 'no data when perform autocomplete_to_extra_repos_and_builds action' do
- @build_list.update_column(:container_status, BuildList::BUILD_PUBLISHED)
- get :autocomplete_to_extra_repos_and_builds, {:term => @build_list.id, :platform_id => @build_list.save_to_platform_id}
- response.body.should == '[]'
- end
-
- it 'no data when perform update_extra_repos_and_builds action' do
- @build_list.update_column(:container_status, BuildList::BUILD_PUBLISHED)
- get :update_extra_repos_and_builds, {:build_list => {:save_to_repository_id => @build_list.save_to_repository_id, :extra_build_lists => [@build_list.id]}, :extra_repo => ''}
- response.body.should == ' '
- end
- end
-
shared_examples_for 'not show build list' do
it 'should not be able to perform show action' do
get :show, @show_params
@@ -89,7 +61,7 @@ describe Projects::BuildListsController do
end
end
- shared_examples_for 'not create build list' do
+ shared_examples_for 'not create build list' do |skip_new = false|
before {
@project.update_attribute(:repositories, @platform.repositories)
}
@@ -97,13 +69,12 @@ describe Projects::BuildListsController do
it 'should not be able to perform new action' do
get :new, :owner_name => @project.owner.uname, :project_name => @project.name
response.should redirect_to(forbidden_url)
- end
+ end unless skip_new
it 'should not be able to perform create action' do
post :create, {:owner_name => @project.owner.uname, :project_name => @project.name}.merge(@create_params)
response.should redirect_to(forbidden_url)
end
-
end
before { stub_symlink_methods }
@@ -136,17 +107,12 @@ describe Projects::BuildListsController do
response.should redirect_to(new_user_session_path)
end
- [:autocomplete_to_extra_repos_and_builds, :update_extra_repos_and_builds].each do |action|
- it "should not be able to perform #{action} action" do
- get action
- response.should redirect_to(new_user_session_path)
- end
- end
end
context 'for user' do
before(:each) do
- @build_list = FactoryGirl.create(:build_list_core)
+ any_instance_of(BuildList, :current_duration => 100)
+ @build_list = FactoryGirl.create(:build_list)
@project = @build_list.project
@owner_user = @project.owner
@member_user = FactoryGirl.create(:user)
@@ -156,19 +122,115 @@ describe Projects::BuildListsController do
@user = FactoryGirl.create(:user)
set_session_for(@user)
@show_params = {:owner_name => @project.owner.uname, :project_name => @project.name, :id => @build_list.id}
+ @build_list.save_to_repository.update_column(:publish_without_qa, false)
+ @request.env['HTTP_REFERER'] = build_list_path(@build_list)
+ end
+
+ context "do reject_publish" do
+ before(:each) {@build_list.save_to_repository.update_column(:publish_without_qa, true)}
+
+ def do_reject_publish
+ put :reject_publish, :id => @build_list
+ end
+
+ context 'if user is project owner' do
+ before(:each) do
+ set_session_for(@owner_user)
+ @build_list.update_column(:status, BuildList::SUCCESS)
+ @build_list.save_to_platform.update_column(:released, true)
+ do_reject_publish
+ end
+
+ context "if it has :success status" do
+ it 'should return 302 response code' do
+ response.status.should == 302
+ end
+
+ it "should reject publish build list" do
+ @build_list.reload.status.should == BuildList::REJECTED_PUBLISH
+ end
+ end
+
+ context "if it has another status" do
+ before(:each) do
+ @build_list.update_column(:status, BuildList::BUILD_ERROR)
+ do_reject_publish
+ end
+
+ it "should not change status of build list" do
+ @build_list.reload.status.should == BuildList::BUILD_ERROR
+ end
+ end
+ end
+
+ context 'if user is not project owner' do
+ before(:each) do
+ @build_list.update_column(:status, BuildList::SUCCESS)
+ @build_list.save_to_platform.update_column(:released, true)
+ do_reject_publish
+ end
+
+ it "should redirect to forbidden page" do
+ response.should redirect_to(forbidden_url)
+ end
+
+ it "should not change status of build list" do
+ do_reject_publish
+ @build_list.reload.status.should == BuildList::SUCCESS
+ end
+ end
+
+ context 'if user is project reader' do
+ before(:each) do
+ @another_user = FactoryGirl.create(:user)
+ @build_list.update_column(:status, BuildList::SUCCESS)
+ @build_list.save_to_repository.update_column(:publish_without_qa, true)
+ @build_list.project.collaborators.create(:actor_type => 'User', :actor_id => @another_user.id, :role => 'reader')
+ set_session_for(@another_user)
+ do_reject_publish
+ end
+
+ it "should redirect to forbidden page" do
+ response.should redirect_to(forbidden_url)
+ end
+
+ it "should not change status of build list" do
+ do_reject_publish
+ @build_list.reload.status.should == BuildList::SUCCESS
+ end
+ end
+
+ context 'if user is project writer' do
+ before(:each) do
+ @writer_user = FactoryGirl.create(:user)
+ @build_list.update_column(:status, BuildList::SUCCESS)
+ @build_list.save_to_repository.update_column(:publish_without_qa, true)
+ @build_list.project.relations.create!(:actor_type => 'User', :actor_id => @writer_user.id, :role => 'writer')
+ set_session_for(@writer_user)
+ do_reject_publish
+ end
+
+ it 'should return 302 response code' do
+ response.status.should == 302
+ end
+
+ it "should reject publish build list" do
+ @build_list.reload.status.should == BuildList::REJECTED_PUBLISH
+ end
+ end
end
context 'for all build lists' do
before(:each) do
- @build_list1 = FactoryGirl.create(:build_list_core)
+ @build_list1 = FactoryGirl.create(:build_list)
- @build_list2 = FactoryGirl.create(:build_list_core)
+ @build_list2 = FactoryGirl.create(:build_list)
@build_list2.project.update_column(:visibility, 'hidden')
project = FactoryGirl.create(:project_with_commit, :visibility => 'hidden', :owner => @user)
- @build_list3 = FactoryGirl.create(:build_list_core_with_attaching_project, :project => project)
+ @build_list3 = FactoryGirl.create(:build_list_with_attaching_project, :project => project)
- @build_list4 = FactoryGirl.create(:build_list_core)
+ @build_list4 = FactoryGirl.create(:build_list)
@build_list4.project.update_column(:visibility, 'hidden')
@build_list4.project.relations.create! :role => 'reader', :actor_id => @user.id, :actor_type => 'User'
end
@@ -190,13 +252,23 @@ describe Projects::BuildListsController do
context 'for open project' do
it_should_behave_like 'show build list'
it_should_behave_like 'not create build list'
- it_should_behave_like 'show extra_repos_and_builds actions'
context 'if user is project owner' do
before(:each) {set_session_for(@owner_user)}
it_should_behave_like 'show build list'
it_should_behave_like 'create build list'
+ context 'no ability to read build_for_platform' do
+ before do
+ repository = FactoryGirl.create(:repository)
+ repository.platform.change_visibility
+ Platform.where(:id => @platform.id).update_all(:platform_type => 'personal')
+ @create_params[:build_list].merge!({:include_repos => [repository.id]})
+ @create_params[:build_for_platforms] = [repository.platform_id]
+ end
+ it_should_behave_like 'not create build list', true
+ end
+
end
context 'if user is project read member' do
@@ -214,21 +286,17 @@ describe Projects::BuildListsController do
it_should_behave_like 'not show build list'
it_should_behave_like 'not create build list'
- it_should_behave_like 'not show extra_repos_and_builds actions'
context 'if user is project owner' do
before(:each) {set_session_for(@owner_user)}
it_should_behave_like 'show build list'
it_should_behave_like 'create build list'
- it_should_behave_like 'show extra_repos_and_builds actions'
end
context 'if user is project read member' do
before(:each) {set_session_for(@member_user)}
it_should_behave_like 'show build list'
it_should_behave_like 'not create build list'
- it_should_behave_like 'show extra_repos_and_builds actions'
-
end
end
end
@@ -254,15 +322,15 @@ describe Projects::BuildListsController do
context 'for all build lists' do
before(:each) do
- @build_list1 = FactoryGirl.create(:build_list_core)
+ @build_list1 = FactoryGirl.create(:build_list)
- @build_list2 = FactoryGirl.create(:build_list_core)
+ @build_list2 = FactoryGirl.create(:build_list)
@build_list2.project.update_column(:visibility, 'hidden')
project = FactoryGirl.create(:project_with_commit, :visibility => 'hidden', :owner => @user)
- @build_list3 = FactoryGirl.create(:build_list_core_with_attaching_project, :project => project)
+ @build_list3 = FactoryGirl.create(:build_list_with_attaching_project, :project => project)
- @build_list4 = FactoryGirl.create(:build_list_core)
+ @build_list4 = FactoryGirl.create(:build_list)
@build_list4.project.update_column(:visibility, 'hidden')
@build_list4.project.relations.create! :role => 'reader', :actor_id => @user.id, :actor_type => 'User'
end
@@ -284,7 +352,6 @@ describe Projects::BuildListsController do
context 'for open project' do
it_should_behave_like 'show build list'
it_should_behave_like 'not create build list'
- it_should_behave_like 'show extra_repos_and_builds actions'
context 'if user is group owner' do
before(:each) {set_session_for(@owner_user)}
@@ -307,20 +374,17 @@ describe Projects::BuildListsController do
it_should_behave_like 'not show build list'
it_should_behave_like 'not create build list'
- it_should_behave_like 'not show extra_repos_and_builds actions'
context 'if user is group owner' do
before(:each) {set_session_for(@owner_user)}
it_should_behave_like 'show build list'
it_should_behave_like 'create build list'
- it_should_behave_like 'show extra_repos_and_builds actions'
end
context 'if user is group read member' do
before(:each) {set_session_for(@member_user)}
it_should_behave_like 'show build list'
it_should_behave_like 'not create build list'
- it_should_behave_like 'show extra_repos_and_builds actions'
end
end
@@ -332,16 +396,16 @@ describe Projects::BuildListsController do
before(:each) do
set_session_for FactoryGirl.create(:admin)
- @build_list1 = FactoryGirl.create(:build_list_core)
- @build_list2 = FactoryGirl.create(:build_list_core)
- @build_list3 = FactoryGirl.create(:build_list_core)
- @build_list4 = FactoryGirl.create(:build_list_core, :updated_at => (Time.now - 1.day),
+ @build_list1 = FactoryGirl.create(:build_list)
+ @build_list2 = FactoryGirl.create(:build_list)
+ @build_list3 = FactoryGirl.create(:build_list)
+ @build_list4 = FactoryGirl.create(:build_list, :updated_at => (Time.now - 1.day),
:project => @build_list3.project, :save_to_platform => @build_list3.save_to_platform,
:arch => @build_list3.arch)
end
- it 'should filter by bs_id' do
- get :index, :filter => {:bs_id => @build_list1.bs_id, :project_name => 'fdsfdf', :any_other_field => 'do not matter'}
+ it 'should filter by id' do
+ get :index, :filter => {:id => @build_list1.id, :project_name => 'fdsfdf', :any_other_field => 'do not matter'}, :format => :json
assigns[:build_lists].should include(@build_list1)
assigns[:build_lists].should_not include(@build_list2)
assigns[:build_lists].should_not include(@build_list3)
@@ -349,7 +413,7 @@ describe Projects::BuildListsController do
it 'should filter by project_name' do
# Project.where(:id => build_list2.project.id).update_all(:name => 'project_name')
- get :index, :filter => {:project_name => @build_list2.project.name, :ownership => 'everything'}
+ get :index, :filter => {:project_name => @build_list2.project.name, :ownership => 'everything'}, :format => :json
assigns[:build_lists].should_not include(@build_list1)
assigns[:build_lists].should include(@build_list2)
assigns[:build_lists].should_not include(@build_list3)
@@ -357,7 +421,7 @@ describe Projects::BuildListsController do
it 'should filter by project_name and update_date' do
get :index, :filter => {:project_name => @build_list3.project.name, :ownership => 'everything',
- "updated_at_start" => @build_list3.updated_at.strftime('%d/%m/%Y')}
+ "updated_at_start" => @build_list3.updated_at.strftime('%d/%m/%Y')}, :format => :json
assigns[:build_lists].should_not include(@build_list1)
assigns[:build_lists].should_not include(@build_list2)
assigns[:build_lists].should include(@build_list3)
diff --git a/spec/controllers/projects/git/git_trees_controller_spec.rb b/spec/controllers/projects/git/git_trees_controller_spec.rb
index 48684360d..ddf639f70 100644
--- a/spec/controllers/projects/git/git_trees_controller_spec.rb
+++ b/spec/controllers/projects/git/git_trees_controller_spec.rb
@@ -6,7 +6,6 @@ describe Projects::Git::TreesController do
stub_symlink_methods
@project = FactoryGirl.create(:project)
- @another_user = FactoryGirl.create(:user)
@params = { :owner_name => @project.owner.uname,
:project_name => @project.name,
:treeish => "#{@project.name}-master"}
@@ -36,6 +35,22 @@ describe Projects::Git::TreesController do
get :archive, @params.merge(:format => 'tar.gz')
response.code.should == '401'
end
+
+ it 'should not be able to perform destroy action' do
+ delete :destroy, @params.merge(:treeish => 'master')
+ response.should_not be_success
+ end
+
+ it 'should not be able to perform restore_branch action' do
+ put :restore_branch, @params.merge(:treeish => 'master')
+ response.should_not be_success
+ end
+
+ it 'should not be able to perform create action' do
+ post :create, @params.merge(:treeish => '', :from_ref => 'master', :new_ref => 'master-1')
+ response.should_not be_success
+ end
+
end
context 'for other user' do
@@ -59,6 +74,21 @@ describe Projects::Git::TreesController do
response.should be_success
end
+ it 'should not be able to perform destroy action' do
+ delete :destroy, @params.merge(:treeish => 'master')
+ response.should_not be_success
+ end
+
+ it 'should not be able to perform restore_branch action' do
+ put :restore_branch, @params.merge(:treeish => 'master')
+ response.should_not be_success
+ end
+
+ it 'should not be able to perform create action' do
+ post :create, @params.merge(:treeish => '', :from_ref => 'master', :new_ref => 'master-1')
+ response.should_not be_success
+ end
+
[:tags, :branches].each do |action|
it "should be able to perform #{action} action" do
get action, @params.merge(:treeish => 'master')
@@ -67,5 +97,33 @@ describe Projects::Git::TreesController do
end
end
+ context 'for writer user' do
+ before(:each) do
+ user = FactoryGirl.create(:user)
+ @project.relations.create!(:actor_type => 'User', :actor_id => user.id, :role => 'writer')
+ set_session_for user
+ end
+
+ it 'should be able to perform destroy action' do
+ delete :destroy, @params.merge(:treeish => 'conflicts')
+ response.should be_success
+ end
+
+ it 'should not be able to perform destroy action for master branch' do
+ delete :destroy, @params.merge(:treeish => 'master')
+ response.should_not be_success
+ end
+
+ it 'should be able to perform restore_branch action' do
+ put :restore_branch, @params.merge(:treeish => 'master-1', :sha => 'master')
+ response.should be_success
+ end
+
+ it 'should be able to perform create action' do
+ post :create, @params.merge(:treeish => '', :from_ref => 'master', :new_ref => 'master-1')
+ response.should be_success
+ end
+ end
+
after(:all) {clean_projects_dir}
end
diff --git a/spec/controllers/projects/hooks_controller_spec.rb b/spec/controllers/projects/hooks_controller_spec.rb
new file mode 100644
index 000000000..36e299ef5
--- /dev/null
+++ b/spec/controllers/projects/hooks_controller_spec.rb
@@ -0,0 +1,205 @@
+# -*- encoding : utf-8 -*-
+require 'spec_helper'
+
+shared_examples_for 'hooks user with project admin rights' do
+ it 'should be able to perform index action' do
+ get :index, {:owner_name => @project.owner.uname, :project_name => @project.name}
+ response.should be_success
+ end
+
+ it 'should be able to perform new action' do
+ get :new, {:owner_name => @project.owner.uname, :project_name => @project.name, :hook => {:name => 'web'}}
+ response.should be_success
+ end
+
+ it 'should be able to perform edit action' do
+ get :new, {:owner_name => @project.owner.uname, :project_name => @project.name, :id => @hook.id}
+ response.should be_success
+ end
+
+ it 'should be able to perform update action' do
+ put :update, {:owner_name => @project.owner.uname, :project_name => @project.name, :id => @hook.id}.merge(@update_params)
+ response.should redirect_to(project_hooks_path(@project, :name => 'web'))
+ end
+
+ it 'should be able to perform create action' do
+ post :create, {:owner_name => @project.owner.uname, :project_name => @project.name}.merge(@create_params)
+ response.should redirect_to(project_hooks_path(@project, :name => 'web'))
+ end
+end
+
+shared_examples_for 'hooks user without project admin rights' do
+ it 'should not be able to perform index action' do
+ get :index, {:owner_name => @project.owner.uname, :project_name => @project.name}
+ response.should redirect_to(forbidden_path)
+ end
+
+ it 'should not be able to perform new action' do
+ get :new, {:owner_name => @project.owner.uname, :project_name => @project.name, :hook => {:name => 'web'}}
+ response.should redirect_to(forbidden_path)
+ end
+
+ it 'should not be able to perform edit action' do
+ get :new, {:owner_name => @project.owner.uname, :project_name => @project.name, :id => @hook.id}
+ response.should redirect_to(forbidden_path)
+ end
+
+ it 'should not be able to perform update action' do
+ put :update, {:owner_name => @project.owner.uname, :project_name => @project.name, :id => @hook.id}.merge(@update_params)
+ response.should redirect_to(forbidden_path)
+ end
+
+ it 'should not be able to perform create action' do
+ post :create, {:owner_name => @project.owner.uname, :project_name => @project.name}.merge(@create_params)
+ response.should redirect_to(forbidden_path)
+ end
+end
+
+describe Projects::HooksController do
+
+ before(:each) do
+ stub_symlink_methods
+
+ @project = FactoryGirl.create(:project)
+ @hook = FactoryGirl.create(:hook, :project => @project)
+
+ @create_params = {:hook => {:name => 'web', :data => {:url => 'create'}}}
+ @update_params = {:hook => {:data => {:url => 'update'}}}
+
+ @user = FactoryGirl.create(:user)
+ set_session_for(@user)
+ end
+
+ context 'registered user' do
+ it_should_behave_like 'hooks user without project admin rights'
+ end # context 'registered user'
+
+ context 'for project members' do
+
+ context 'for global admin' do
+ before do
+ @user.role = "admin"
+ @user.save
+ end
+
+ it_should_behave_like 'hooks user with project admin rights'
+ end
+
+ context 'for owner user' do
+ before do
+ @user = @project.owner
+ set_session_for(@user) # owner should be user
+ end
+ it_should_behave_like 'hooks user with project admin rights'
+ end
+
+ context 'for reader user' do
+ before do
+ @project.relations.create!(:actor_type => 'User', :actor_id => @user.id, :role => 'reader')
+ end
+ it_should_behave_like 'hooks user without project admin rights'
+ end
+
+ context 'for writer user' do
+ before do
+ @project.relations.create!(:actor_type => 'User', :actor_id => @user.id, :role => 'writer')
+ end
+ it_should_behave_like 'hooks user without project admin rights'
+ end
+
+ end # context 'for project members'
+
+ context 'for group' do
+ before do
+ @group = FactoryGirl.create(:group)
+ end
+
+ context 'group is owner of the project' do
+ before do
+ @project = FactoryGirl.create(:project, :owner => @group)
+ @hook = FactoryGirl.create(:hook, :project => @project)
+ end
+
+ context 'group member user with reader role' do
+ before do
+ @group.actors.create(:actor_id => @user.id, :actor_type => 'User', :role => 'reader')
+ end
+
+ it_should_behave_like 'hooks user without project admin rights'
+
+ context 'user should has best role' do
+ before do
+ @project.relations.create :actor_id => @user.id, :actor_type => @user.class.to_s, :role => 'admin'
+ end
+ it_should_behave_like 'hooks user with project admin rights'
+ end
+ end
+
+ context 'group member user with admin role' do
+ before do
+ @group.actors.create(:actor_id => @user.id, :actor_type => 'User', :role => 'admin')
+ end
+
+ it_should_behave_like 'hooks user with project admin rights'
+ end
+ end
+
+ context 'group is member of the project' do
+ context 'with admin rights' do
+ before do
+ @project.relations.create :actor_id => @group.id, :actor_type => @group.class.to_s, :role => 'admin'
+ end
+
+ context 'group member user with reader role' do
+ before do
+ @group.actors.create(:actor_id => @user.id, :actor_type => 'User', :role => 'reader')
+ end
+
+ it_should_behave_like 'hooks user with project admin rights'
+
+ context 'user should has best role' do
+ before do
+ @project.relations.create :actor_id => @user.id, :actor_type => @user.class.to_s, :role => 'reader'
+ end
+ it_should_behave_like 'hooks user with project admin rights'
+ end
+ end
+
+ context 'group member user with admin role' do
+ before do
+ @group.actors.create(:actor_id => @user.id, :actor_type => 'User', :role => 'admin')
+ end
+
+ it_should_behave_like 'hooks user with project admin rights'
+ end
+ end
+
+ context 'with reader rights' do
+ before do
+ @project.relations.create :actor_id => @group.id, :actor_type => @group.class.to_s, :role => 'reader'
+ end
+
+ context 'group member user with reader role' do
+ before do
+ @group.actors.create(:actor_id => @user.id, :actor_type => 'User', :role => 'reader')
+ end
+ it_should_behave_like 'hooks user without project admin rights'
+
+ context 'user should has best role' do
+ before do
+ @project.relations.create :actor_id => @user.id, :actor_type => @user.class.to_s, :role => 'admin'
+ end
+ it_should_behave_like 'hooks user with project admin rights'
+ end
+ end
+
+ context 'group member user with admin role' do
+ before do
+ @group.actors.create(:actor_id => @user.id, :actor_type => 'User', :role => 'admin')
+ end
+ it_should_behave_like 'hooks user without project admin rights'
+ end
+ end
+ end
+ end
+end
diff --git a/spec/controllers/projects/issues_controller_spec.rb b/spec/controllers/projects/issues_controller_spec.rb
index 8785910f3..a541faecd 100644
--- a/spec/controllers/projects/issues_controller_spec.rb
+++ b/spec/controllers/projects/issues_controller_spec.rb
@@ -1,13 +1,14 @@
require 'spec_helper'
shared_context "issues controller" do
- before(:each) do
+ before do
stub_symlink_methods
- @project = FactoryGirl.create(:project)
+ @project = FactoryGirl.create(:project_with_commit)
@issue_user = FactoryGirl.create(:user)
@issue = FactoryGirl.create(:issue, :project_id => @project.id, :assignee_id => @issue_user.id)
+ @label = FactoryGirl.create(:label, :project_id => @project.id)
@project_with_turned_off_issues = FactoryGirl.create(:project, :has_issues => false)
@turned_of_issue = FactoryGirl.create(:issue, :project_id => @project_with_turned_off_issues.id, :assignee_id => @issue_user.id)
@@ -19,10 +20,10 @@ shared_context "issues controller" do
:owner_name => @project.owner.uname, :project_name => @project.name,
:issue => {
:title => "issue1",
- :body => "issue body"
- },
- :assignee_id => @issue_user.id,
- :assignee_uname => @issue_user.uname
+ :body => "issue body",
+ :labelings_attributes => { @label.id => {:label_id => @label.id}},
+ :assignee_id => @issue_user.id
+ }
}
@update_params = {
@@ -32,6 +33,11 @@ shared_context "issues controller" do
}
}
+ @pull = @project.pull_requests.new :issue_attributes => {:title => 'test', :body => 'testing'}
+ @pull.issue.user, @pull.issue.project = @project.owner, @pull.to_project
+ @pull.to_ref = 'master'
+ @pull.from_project, @pull.from_ref = @project, 'non_conflicts'
+ @pull.save
end
end
@@ -55,9 +61,7 @@ shared_examples_for 'issue user with project reader rights' do
get :index, :owner_name => @project.owner.uname, :project_name => @project.name
response.should render_template(:index)
end
-end
-shared_examples_for 'issue user with project writer rights' do
it 'should be able to perform create action' do
post :create, @create_params
response.should redirect_to(project_issues_path(@project))
@@ -68,6 +72,30 @@ shared_examples_for 'issue user with project writer rights' do
end
end
+shared_examples_for 'issue user with project writer rights' do
+ it 'should be able to perform index action on hidden project' do
+ @project.update_attributes(:visibility => 'hidden')
+ get :index, :owner_name => @project.owner.uname, :project_name => @project.name
+ response.should render_template(:index)
+ end
+
+ it 'should create issue object into db' do
+ lambda{ post :create, @create_params }.should change{ Issue.count }.by(1)
+ end
+
+ context 'perform create action' do
+ before { post :create, @create_params }
+
+ it 'user should be assigned to issue' do
+ @project.issues.last.assignee_id.should_not be_nil
+ end
+
+ it 'label should be attached to issue' do
+ @project.issues.last.labels.should have(1).item
+ end
+ end
+end
+
shared_examples_for 'user with issue update rights' do
it 'should be able to perform update action' do
put :update, {:id => @issue.serial_id}.merge(@update_params)
@@ -105,12 +133,12 @@ end
shared_examples_for 'project with issues turned off' do
it 'should not be able to perform index action' do
- get :index, :project_id => @project_with_turned_off_issues.id
+ get :index, :owner_name => @project_with_turned_off_issues.owner.uname, :project_name => @project_with_turned_off_issues.name
response.should redirect_to(forbidden_path)
end
it 'should not be able to perform show action' do
- get :show, :project_id => @project_with_turned_off_issues.id, :id => @turned_of_issue.serial_id
+ get :show, :owner_name => @project_with_turned_off_issues.owner.uname, :project_name => @project_with_turned_off_issues.name, :id => @turned_of_issue.serial_id
response.should redirect_to(forbidden_path)
end
end
@@ -166,11 +194,22 @@ describe Projects::IssuesController do
it_should_behave_like 'issue user with project guest rights'
it_should_behave_like 'issue user with project reader rights'
- it_should_behave_like 'issue user with project writer rights'
it_should_behave_like 'user without issue update rights'
it_should_behave_like 'project with issues turned off'
it_should_behave_like 'user without issue destroy rights'
+ context 'perform create action' do
+ before { post :create, @create_params }
+
+ it 'user should not be assigned to issue' do
+ @project.issues.last.assignee_id.should be_nil
+ end
+
+ it 'label should not be attached to issue' do
+ @project.issues.last.labels.should have(:no).items
+ end
+ end
+
# it 'should not be able to perform create action on project' do
# post :create, @create_params
# response.should redirect_to(forbidden_path)
@@ -179,6 +218,16 @@ describe Projects::IssuesController do
# it 'should not create issue object into db' do
# lambda{ post :create, @create_params }.should change{ Issue.count }.by(0)
# end
+
+ it 'should return 404' do
+ get :show, :owner_name => @project.owner.uname, :project_name => @project.name, :id => 999999
+ render_template(:file => "#{Rails.root}/public/404.html")
+ end
+
+ it 'should redirect to pull request page' do
+ get :show, :owner_name => @project.owner.uname, :project_name => @project.name, :id => @pull.serial_id
+ response.should redirect_to(project_pull_request_path(@project, @pull))
+ end
end
context 'for project writer user' do
diff --git a/spec/controllers/projects/projects_controller_spec.rb b/spec/controllers/projects/projects_controller_spec.rb
index 8fa430e6c..b1a5868e5 100644
--- a/spec/controllers/projects/projects_controller_spec.rb
+++ b/spec/controllers/projects/projects_controller_spec.rb
@@ -20,11 +20,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
@@ -60,6 +59,32 @@ shared_examples_for 'projects user without project admin rights' do
@project.reload.has_issues.should == has_issues
response.should redirect_to(forbidden_path)
end
+
+ it 'writer group 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, :owner_name => @project.owner.uname, :project_name => @project.name,
+ :group => group.id}.should change{ Project.count }.by(1)
+ end
+
+ it 'reader group 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, :owner_name => @project.owner.uname, :project_name => @project.name,
+ :group => group.id}.should change{ Project.count }.by(0)
+ end
+
+ it 'writer group should be able to create project to their group' do
+ group = FactoryGirl.create(:group)
+ group.actors.create(:actor_type => 'User', :actor_id => @user.id, :role => 'writer')
+ lambda {post :create, @create_params.merge(:who_owns => 'group', :owner_id => group.id)}.should change{ Project.count }.by(1)
+ end
+
+ it 'reader group should not be able to create project to their group' do
+ group = FactoryGirl.create(:group)
+ group.actors.create(:actor_type => 'User', :actor_id => @user.id, :role => 'reader')
+ lambda {post :create, @create_params.merge(:who_owns => 'group', :owner_id => group.id)}.should change{ Project.count }.by(0)
+ end
end
describe Projects::ProjectsController do
@@ -76,7 +101,7 @@ describe Projects::ProjectsController do
set_session_for(@user)
end
- context 'for system users' do
+ context 'for users' do
context 'guest' do
@@ -137,11 +162,10 @@ describe Projects::ProjectsController do
group = FactoryGirl.create(:group, :owner => @user)
lambda { post :create, @create_params.merge({:who_owns => 'group', :owner_id => group.id})}.should change{ Project.count }.by(1)
end
-
end
end # context 'registered user'
- end # context 'for system users'
+ end # context 'for users'
context 'for project members' do
diff --git a/spec/controllers/projects/pull_requests_controller_spec.rb b/spec/controllers/projects/pull_requests_controller_spec.rb
index dfe2cea7f..526a6c33f 100644
--- a/spec/controllers/projects/pull_requests_controller_spec.rb
+++ b/spec/controllers/projects/pull_requests_controller_spec.rb
@@ -30,6 +30,8 @@ shared_context "pull request controller" do
@user = FactoryGirl.create(:user)
set_session_for(@user)
+
+ @issue = FactoryGirl.create(:issue, :project => @project)
end
end
@@ -93,12 +95,13 @@ end
shared_examples_for 'user with pull request update rights' do
it 'should be able to perform update action' do
put :update, @update_params
- response.should redirect_to(project_pull_request_path(@pull.to_project, @pull))
+ response.should be_success
end
it 'should be able to perform merge action' do
+ @pull.check
put :merge, @update_params
- response.should redirect_to(project_pull_request_path(@pull.to_project, @pull))
+ response.should be_success
end
let(:pull) { @project.pull_requests.find(@pull) }
@@ -134,11 +137,6 @@ shared_examples_for 'user without pull request update rights' do
response.should redirect_to(controller.current_user ? forbidden_path : new_user_session_path)
end
- it 'should not be able to perform merge action' do
- put :merge, @update_params
- response.should redirect_to(controller.current_user ? forbidden_path : new_user_session_path)
- end
-
let(:pull) { @project.pull_requests.find(@pull) }
it 'should not update pull request status' do
put :update, @update_params
@@ -153,12 +151,19 @@ shared_examples_for 'user without pull request update rights' do
put :update, @wrong_update_params
pull.issue.body.should_not =='updating'
end
+
+ it 'should be able to perform merge action' do
+ @pull.check
+ put :merge, @update_params
+ response.should_not be_success
+ end
+
end
shared_examples_for 'pull request when project with issues turned off' do
before { @project.update_attributes(:has_issues => false) }
it 'should be able to perform index action' do
- get :index, :project_id => @project.id
+ get :index, :owner_name => @project.owner.uname, :project_name => @project.name
response.should render_template(:index)
end
@@ -216,6 +221,16 @@ describe Projects::PullRequestsController do
it_should_behave_like 'pull request user with project reader rights'
it_should_behave_like 'user without pull request update rights'
it_should_behave_like 'pull request when project with issues turned off'
+
+ it 'should return 404' do
+ get :show, :owner_name => @project.owner.uname, :project_name => @project.name, :id => 999999
+ render_template(:file => "#{Rails.root}/public/404.html")
+ end
+
+ it 'should redirect to issue page' do
+ get :show, :owner_name => @project.owner.uname, :project_name => @project.name, :id => @issue.serial_id
+ response.should redirect_to(project_issue_path(@project, @issue))
+ end
end
context 'for project writer user' do
@@ -281,4 +296,40 @@ describe Projects::PullRequestsController do
it_should_behave_like 'user without pull request update rights'
end
+
+ context 'send email messages' do
+ before(:each) do
+ @project_reader = FactoryGirl.create :user
+ @project.relations.create!(:actor_type => 'User', :actor_id => @project_reader.id, :role => 'reader')
+ @project_admin = FactoryGirl.create :user
+ @project.relations.create!(:actor_type => 'User', :actor_id => @project_admin.id, :role => 'admin')
+ @project_writer = FactoryGirl.create :user
+ @project.relations.create!(:actor_type => 'User', :actor_id => @project_writer.id, :role => 'writer')
+
+ set_session_for(@project_writer)
+ ActionMailer::Base.deliveries = []
+ end
+
+ it 'should send two email messages to project admins' do
+ post :create, @create_params
+ @project.pull_requests.last.issue.send(:new_issue_notifications)
+ @project.pull_requests.last.issue.send(:send_assign_notifications)
+ ActionMailer::Base.deliveries.count.should == 2
+ end
+
+ it 'should send two email messages to admins and one to assignee' do
+ post :create, @create_params.deep_merge(:issue => {:assignee_id => @project_reader.id})
+ @project.pull_requests.last.issue.send(:new_issue_notifications)
+ @project.pull_requests.last.issue.send(:send_assign_notifications)
+ ActionMailer::Base.deliveries.count.should == 3
+ end
+
+ it 'should not duplicate email message' do
+ post :create, @create_params.deep_merge(:issue => {:assignee_id => @project_admin.id})
+ @project.pull_requests.last.issue.send(:new_issue_notifications)
+ @project.pull_requests.last.issue.send(:send_assign_notifications)
+ ActionMailer::Base.deliveries.count.should == 2 # send only to admins
+ ActionMailer::Base.deliveries.first.to != ActionMailer::Base.deliveries.last.to
+ end
+ end
end
diff --git a/spec/factories/build_lists.rb b/spec/factories/build_lists.rb
index 9f706d461..7ff38250d 100644
--- a/spec/factories/build_lists.rb
+++ b/spec/factories/build_lists.rb
@@ -21,15 +21,7 @@ FactoryGirl.define do
before(:create) { |bl| attach_project_to_build_list bl }
end
- factory :build_list_core, :parent => :build_list do
- bs_id { FactoryGirl.generate(:integer) }
- end
-
- factory :build_list_core_with_attaching_project, :parent => :build_list_core do
- before(:create) { |bl| attach_project_to_build_list bl }
- end
-
- factory :build_list_by_group_project, :parent => :build_list_core do
+ factory :build_list_by_group_project, :parent => :build_list do
project { |bl|
pr = FactoryGirl.create(:group_project_with_commit)
bl.save_to_platform.repositories.first.projects << pr
diff --git a/spec/factories/comments.rb b/spec/factories/comments.rb
index 5de44fa25..ee85deacc 100644
--- a/spec/factories/comments.rb
+++ b/spec/factories/comments.rb
@@ -3,5 +3,7 @@ FactoryGirl.define do
body { FactoryGirl.generate(:string) }
association :user, :factory => :user
association :commentable, :factory => :issue
+ project { |c| c.commentable.project }
+ after(:create) { |c| c.send(:new_comment_notifications) }
end
end
diff --git a/spec/factories/hook.rb b/spec/factories/hook.rb
new file mode 100644
index 000000000..d7fa39637
--- /dev/null
+++ b/spec/factories/hook.rb
@@ -0,0 +1,8 @@
+# -*- encoding : utf-8 -*-
+FactoryGirl.define do
+ factory :hook do
+ name 'web'
+ association :project, :factory => :project
+ data { |hook| hook.data = {:url => 'url'} }
+ end
+end
diff --git a/spec/factories/issues.rb b/spec/factories/issues.rb
index a0b075b09..66340557c 100644
--- a/spec/factories/issues.rb
+++ b/spec/factories/issues.rb
@@ -6,5 +6,9 @@ FactoryGirl.define do
association :user, :factory => :user
association :assignee, :factory => :user
status "open"
+ # Hooks for #after_commit
+ after(:create) { |i| i.send(:new_issue_notifications) }
+ after(:create) { |i| i.send(:send_assign_notifications) }
+ after(:create) { |i| i.send(:send_hooks) }
end
end
diff --git a/spec/factories/label.rb b/spec/factories/label.rb
new file mode 100644
index 000000000..b985a2d98
--- /dev/null
+++ b/spec/factories/label.rb
@@ -0,0 +1,8 @@
+# -*- encoding : utf-8 -*-
+FactoryGirl.define do
+ factory :label do
+ name { FactoryGirl.generate(:string) }
+ color 'FFF'
+ association :project, :factory => :project
+ end
+end
\ No newline at end of file
diff --git a/spec/factories/labeling.rb b/spec/factories/labeling.rb
new file mode 100644
index 000000000..51d1f6d70
--- /dev/null
+++ b/spec/factories/labeling.rb
@@ -0,0 +1,7 @@
+# -*- encoding : utf-8 -*-
+FactoryGirl.define do
+ factory :labeling do
+ association :project, :factory => :project
+ association :label, :factory => :label
+ end
+end
\ No newline at end of file
diff --git a/spec/factories/mass_build.rb b/spec/factories/mass_build.rb
index b73409fe0..dc6a08972 100644
--- a/spec/factories/mass_build.rb
+++ b/spec/factories/mass_build.rb
@@ -1,10 +1,9 @@
FactoryGirl.define do
factory :mass_build do
- association :platform
- #name FactoryGirl.generate(:name)
+ association :save_to_platform, :factory => :platform
association :user
projects_list "first"
- arches { [ Arch.first.id ] }
+ arches { [ Arch.find_or_create_by_name('x86_64').id ] }
auto_publish true
stop_build false
end
diff --git a/spec/factories/project_statistic.rb b/spec/factories/project_statistic.rb
new file mode 100644
index 000000000..ec381ef09
--- /dev/null
+++ b/spec/factories/project_statistic.rb
@@ -0,0 +1,7 @@
+# -*- encoding : utf-8 -*-
+FactoryGirl.define do
+ factory :project_statistic do
+ association :project, :factory => :project
+ association :arch, :factory => :arch
+ end
+end
diff --git a/spec/factories/token.rb b/spec/factories/token.rb
new file mode 100644
index 000000000..cee8561b5
--- /dev/null
+++ b/spec/factories/token.rb
@@ -0,0 +1,10 @@
+# -*- encoding : utf-8 -*-
+FactoryGirl.define do
+ factory :token do
+ association :creator, :factory => :user
+ end
+
+ factory :platform_token, :parent => :token do
+ association :subject, :factory => :platform
+ end
+end
diff --git a/spec/factories/users.rb b/spec/factories/users.rb
index 2fe9899a1..4d06ab4f3 100644
--- a/spec/factories/users.rb
+++ b/spec/factories/users.rb
@@ -6,6 +6,7 @@ FactoryGirl.define do
password '123456'
password_confirmation {|u| u.password}
confirmed_at { Time.now.utc }
+ after(:create) { |u| u.send(:new_user_notification) }
end
factory :admin, :parent => :user do
diff --git a/spec/helpers/activity_feeds_helper_spec.rb b/spec/helpers/activity_feeds_helper_spec.rb
deleted file mode 100644
index 623c526ec..000000000
--- a/spec/helpers/activity_feeds_helper_spec.rb
+++ /dev/null
@@ -1,15 +0,0 @@
-require 'spec_helper'
-
-# Specs in this file have access to a helper object that includes
-# the ActivityFeedsHelper. For example:
-#
-# describe ActivityFeedsHelper do
-# describe "string concat" do
-# it "concats two strings with spaces" do
-# helper.concat_strings("this","that").should == "this that"
-# end
-# end
-# end
-describe ActivityFeedsHelper do
- pending "add some examples to (or delete) #{__FILE__}"
-end
diff --git a/spec/integration/api_defender_spec.rb b/spec/integration/api_defender_spec.rb
index c369942af..ecc8e71ae 100644
--- a/spec/integration/api_defender_spec.rb
+++ b/spec/integration/api_defender_spec.rb
@@ -119,4 +119,18 @@ describe ApiDefender do
response.status.should == 200
end
end
+
+ context 'for allowed addresses' do
+ let(:remote_addr) { APP_CONFIG['allowed_addresses'].first }
+ it 'should not return the limit usage for allowed address' do
+ get "/api/v1/users/#{@user.id}.json", {}, {'REMOTE_ADDR' => remote_addr }
+ response.headers['X-RateLimit-Limit'].should_not == @rate_limit.to_s
+ end
+
+ it 'should not forbidden allowed address' do
+ (@rate_limit+1).times { get "/api/v1/users/#{@user.id}.json", {}, {'REMOTE_ADDR' => remote_addr } }
+ response.status.should == 200
+ end
+ end
+
end
diff --git a/spec/lib/abf-worker/build_lists_publish_task_manager_spec.rb b/spec/lib/abf-worker/build_lists_publish_task_manager_spec.rb
index dc95cea49..4a64ea82c 100644
--- a/spec/lib/abf-worker/build_lists_publish_task_manager_spec.rb
+++ b/spec/lib/abf-worker/build_lists_publish_task_manager_spec.rb
@@ -7,193 +7,172 @@ describe AbfWorker::BuildListsPublishTaskManager do
end
before do
- init_test_root
+ stub_redis
stub_symlink_methods
- FactoryGirl.create(:build_list_core, :new_core => true)
+ FactoryGirl.create(:build_list)
end
subject { AbfWorker::BuildListsPublishTaskManager }
- let(:build_list) { FactoryGirl.create(:build_list_core, :new_core => true) }
+ let(:build_list) { FactoryGirl.create(:build_list) }
- describe 'when no items for publishing' do
- before do
- stub_redis
- subject.new.run
- end
+ context 'when no items for publishing' do
+ before { subject.new.run }
- %w(RESIGN_REPOSITORIES
- PROJECTS_FOR_CLEANUP
+ %w(PROJECTS_FOR_CLEANUP
LOCKED_PROJECTS_FOR_CLEANUP
- LOCKED_REPOSITORIES
- LOCKED_REP_AND_PLATFORMS
LOCKED_BUILD_LISTS).each do |kind|
- it "ensure that no '#{kind.downcase.gsub('_', ' ')}'" do
+ it "ensures that no '#{kind.downcase.gsub('_', ' ')}'" do
@redis_instance.lrange(subject.const_get(kind), 0, -1).should be_empty
end
end
%w(publish_worker_default publish_worker).each do |kind|
- it "ensure that no tasks in '#{kind}' queue" do
+ it "ensures that no tasks in '#{kind}' queue" do
@redis_instance.lrange(kind, 0, -1).should be_empty
end
end
end
- describe 'when one build_list for publishing' do
+ context 'when one build_list for publishing' do
before do
- stub_redis
build_list.update_column(:status, BuildList::BUILD_PUBLISH)
2.times{ subject.new.run }
end
- %w(RESIGN_REPOSITORIES
- PROJECTS_FOR_CLEANUP
- LOCKED_PROJECTS_FOR_CLEANUP
- LOCKED_REPOSITORIES).each do |kind|
-
+ %w(PROJECTS_FOR_CLEANUP LOCKED_PROJECTS_FOR_CLEANUP).each do |kind|
it "ensure that no '#{kind.downcase.gsub('_', ' ')}'" do
@redis_instance.lrange(subject.const_get(kind), 0, -1).should be_empty
end
end
- it "ensure that 'locked rep and platforms' has only one item" do
- queue = @redis_instance.lrange(subject::LOCKED_REP_AND_PLATFORMS, 0, -1)
- queue.should have(1).item
- queue.should include("#{build_list.save_to_repository_id}-#{build_list.build_for_platform_id}")
+ it "ensures that repository_status has status publish" do
+ build_list.save_to_repository.repository_statuses.
+ find_by_platform_id(build_list.build_for_platform_id).publish?.
+ should be_true
end
- it "ensure that 'locked build lists' has only one item" do
+ it "ensures that 'locked build lists' has only one item" do
queue = @redis_instance.lrange(subject::LOCKED_BUILD_LISTS, 0, -1)
queue.should have(1).item
queue.should include(build_list.id.to_s)
end
- it "ensure that new task for publishing has been created" do
+ it "ensures that new task for publishing has been created" do
@redis_instance.lrange('queue:publish_worker_default', 0, -1).should have(1).item
end
end
- describe 'grouping build lists for publishing into same repository' do
- let(:build_list2) { FactoryGirl.create(:build_list_core,
+ context 'grouping build lists for publishing into same repository' do
+ let(:build_list2) { FactoryGirl.create(:build_list,
:new_core => true,
:save_to_platform => build_list.save_to_platform,
:save_to_repository => build_list.save_to_repository,
:build_for_platform => build_list.build_for_platform
) }
before do
- stub_redis
build_list.update_column(:status, BuildList::BUILD_PUBLISH)
build_list2.update_column(:status, BuildList::BUILD_PUBLISH)
2.times{ subject.new.run }
end
- %w(RESIGN_REPOSITORIES
- PROJECTS_FOR_CLEANUP
- LOCKED_PROJECTS_FOR_CLEANUP
- LOCKED_REPOSITORIES).each do |kind|
-
- it "ensure that no '#{kind.downcase.gsub('_', ' ')}'" do
+ %w(PROJECTS_FOR_CLEANUP LOCKED_PROJECTS_FOR_CLEANUP).each do |kind|
+ it "ensures that no '#{kind.downcase.gsub('_', ' ')}'" do
@redis_instance.lrange(subject.const_get(kind), 0, -1).should be_empty
end
end
- it "ensure that 'locked rep and platforms' has only one item" do
- queue = @redis_instance.lrange(subject::LOCKED_REP_AND_PLATFORMS, 0, -1)
- queue.should have(1).item
- queue.should include("#{build_list.save_to_repository_id}-#{build_list.build_for_platform_id}")
+ it "ensures that only one repository_status has status publish" do
+ RepositoryStatus.where(:status => RepositoryStatus::PUBLISH).should have(1).item
end
- it "ensure that 'locked build lists' has 2 items" do
+ it "ensures that 'locked build lists' has 2 items" do
queue = @redis_instance.lrange(subject::LOCKED_BUILD_LISTS, 0, -1)
queue.should have(2).item
queue.should include(build_list.id.to_s, build_list2.id.to_s)
end
- it "ensure that new task for publishing has been created" do
+ it "ensures that new task for publishing has been created" do
@redis_instance.lrange('queue:publish_worker_default', 0, -1).should have(1).item
end
end
- describe 'creates not more than 4 tasks for publishing' do
+ context 'creates not more than 4 tasks for publishing' do
before do
- stub_redis
build_list.update_column(:status, BuildList::BUILD_PUBLISH)
4.times {
- bl = FactoryGirl.create(:build_list_core, :new_core => true)
+ bl = FactoryGirl.create(:build_list, :new_core => true)
bl.update_column(:status, BuildList::BUILD_PUBLISH)
}
2.times{ subject.new.run }
end
- it "ensure that 'locked rep and platforms' has 4 items" do
- @redis_instance.lrange(subject::LOCKED_REP_AND_PLATFORMS, 0, -1).should have(4).items
+ it "ensures that 4 repository_statuses have status publish" do
+ RepositoryStatus.where(:status => RepositoryStatus::PUBLISH).should have(4).items
end
- it "ensure that 'locked build lists' has 4 items" do
+ it "ensures that 'locked build lists' has 4 items" do
@redis_instance.lrange(subject::LOCKED_BUILD_LISTS, 0, -1).should have(4).items
end
- it "ensure that new tasks for publishing has been created" do
+ it "ensures that new tasks for publishing has been created" do
@redis_instance.lrange('queue:publish_worker_default', 0, -1).should have(4).items
end
end
- describe 'creates task for removing project from repository' do
+ context 'creates task for removing project from repository' do
before do
- stub_redis
build_list.update_column(:status, BuildList::BUILD_PUBLISHED)
FactoryGirl.create(:build_list_package, :build_list => build_list)
ProjectToRepository.where(:project_id => build_list.project_id, :repository_id => build_list.save_to_repository_id).destroy_all
2.times{ subject.new.run }
end
- %w(RESIGN_REPOSITORIES
- PROJECTS_FOR_CLEANUP
- LOCKED_REPOSITORIES
- LOCKED_BUILD_LISTS).each do |kind|
-
- it "ensure that no '#{kind.downcase.gsub('_', ' ')}'" do
+ %w(LOCKED_BUILD_LISTS).each do |kind|
+ it "ensures that no '#{kind.downcase.gsub('_', ' ')}'" do
@redis_instance.lrange(subject.const_get(kind), 0, -1).should be_empty
end
end
- it "ensure that 'locked rep and platforms' has only one item" do
- queue = @redis_instance.lrange(subject::LOCKED_REP_AND_PLATFORMS, 0, -1)
+ it "ensures that has only 'projects for cleanup' for testing subrepo" do
+ queue = @redis_instance.lrange(subject::PROJECTS_FOR_CLEANUP, 0, -1)
queue.should have(1).item
- queue.should include("#{build_list.save_to_repository_id}-#{build_list.build_for_platform_id}")
+ queue.should include("testing-#{build_list.project_id}-#{build_list.save_to_repository_id}-#{build_list.build_for_platform_id}")
end
- it "ensure that 'locked projects for cleanup' has only one item" do
+ it "ensures that only one repository_status has status publish" do
+ RepositoryStatus.where(:status => RepositoryStatus::PUBLISH).should have(1).item
+ end
+
+ it "ensures that 'locked projects for cleanup' has only one item" do
queue = @redis_instance.lrange(subject::LOCKED_PROJECTS_FOR_CLEANUP, 0, -1)
queue.should have(1).item
queue.should include("#{build_list.project_id}-#{build_list.save_to_repository_id}-#{build_list.build_for_platform_id}")
end
- it "ensure that new task for publishing has been created" do
+ it "ensures that new task for publishing has been created" do
@redis_instance.lrange('queue:publish_worker_default', 0, -1).should have(1).item
end
end
- describe 'grouping build lists for publishing and tasks for removing project from repository' do
- let(:build_list2) { FactoryGirl.create(:build_list_core,
+ context 'grouping build lists for publishing and tasks for removing project from repository' do
+ let(:build_list2) { FactoryGirl.create(:build_list,
:new_core => true,
:save_to_platform => build_list.save_to_platform,
:save_to_repository => build_list.save_to_repository,
:build_for_platform => build_list.build_for_platform
) }
- let(:build_list3) { FactoryGirl.create(:build_list_core,
+ let(:build_list3) { FactoryGirl.create(:build_list,
:new_core => true,
:save_to_platform => build_list.save_to_platform,
:save_to_repository => build_list.save_to_repository,
:build_for_platform => build_list.build_for_platform
) }
before do
- stub_redis
build_list.update_column(:status, BuildList::BUILD_PUBLISH)
build_list2.update_column(:status, BuildList::BUILD_PUBLISHED)
build_list3.update_column(:status, BuildList::BUILD_PUBLISHED)
@@ -201,61 +180,48 @@ describe AbfWorker::BuildListsPublishTaskManager do
2.times{ subject.new.run }
end
- %w(RESIGN_REPOSITORIES
- PROJECTS_FOR_CLEANUP
- LOCKED_REPOSITORIES).each do |kind|
-
- it "ensure that no '#{kind.downcase.gsub('_', ' ')}'" do
- @redis_instance.lrange(subject.const_get(kind), 0, -1).should be_empty
- end
- end
-
- it "ensure that 'locked rep and platforms' has only one item" do
- queue = @redis_instance.lrange(subject::LOCKED_REP_AND_PLATFORMS, 0, -1)
+ it "ensures that no 'projects for cleanup' for main repo" do
+ queue = @redis_instance.lrange(subject::PROJECTS_FOR_CLEANUP, 0, -1)
queue.should have(1).item
- queue.should include("#{build_list.save_to_repository_id}-#{build_list.build_for_platform_id}")
+ queue.should include("testing-#{build_list3.project_id}-#{build_list3.save_to_repository_id}-#{build_list3.build_for_platform_id}")
end
- it "ensure that 'locked projects for cleanup' has only one item" do
+ it "ensures that only one repository_status has status publish" do
+ RepositoryStatus.where(:status => RepositoryStatus::PUBLISH).should have(1).item
+ end
+
+ it "ensures that 'locked projects for cleanup' has only one item" do
queue = @redis_instance.lrange(subject::LOCKED_PROJECTS_FOR_CLEANUP, 0, -1)
queue.should have(1).item
queue.should include("#{build_list3.project_id}-#{build_list3.save_to_repository_id}-#{build_list3.build_for_platform_id}")
end
- it "ensure that new task for publishing has been created" do
+ it "ensures that new task for publishing has been created" do
@redis_instance.lrange('queue:publish_worker_default', 0, -1).should have(1).item
end
- it "ensure that 'locked build lists' has only one item" do
+ it "ensures that 'locked build lists' has only one item" do
queue = @redis_instance.lrange(subject::LOCKED_BUILD_LISTS, 0, -1)
queue.should have(1).item
queue.should include(build_list.id.to_s)
end
end
- describe 'resign packages in repository' do
+ context 'resign packages in repository' do
before do
- stub_redis
build_list.update_column(:status, BuildList::BUILD_PUBLISH)
FactoryGirl.create(:key_pair, :repository => build_list.save_to_repository)
2.times{ subject.new.run }
end
- %w(RESIGN_REPOSITORIES
- PROJECTS_FOR_CLEANUP
- LOCKED_PROJECTS_FOR_CLEANUP
- LOCKED_REP_AND_PLATFORMS
- LOCKED_BUILD_LISTS).each do |kind|
-
+ %w(PROJECTS_FOR_CLEANUP LOCKED_PROJECTS_FOR_CLEANUP LOCKED_BUILD_LISTS).each do |kind|
it "ensure that no '#{kind.downcase.gsub('_', ' ')}'" do
@redis_instance.lrange(subject.const_get(kind), 0, -1).should be_empty
end
end
- it "ensure that 'locked repositories' has only one item" do
- queue = @redis_instance.lrange(subject::LOCKED_REPOSITORIES, 0, -1)
- queue.should have(1).item
- queue.should include(build_list.save_to_repository_id.to_s)
+ it "ensures that only one repository_status has status resign" do
+ RepositoryStatus.where(:status => RepositoryStatus::RESIGN).should have(1).item
end
it "ensure that new task for resign has been created" do
@@ -264,6 +230,41 @@ describe AbfWorker::BuildListsPublishTaskManager do
end
+ context 'regenerate metadata' do
+ context 'for repository of main platform' do
+ let(:repository) { FactoryGirl.create(:repository) }
+ before do
+ repository.regenerate
+ subject.new.run
+ end
+
+ it "ensures that only one repository_status has status regenerating" do
+ RepositoryStatus.where(:status => RepositoryStatus::REGENERATING).should have(1).item
+ end
+
+ it 'ensures that new task has been created' do
+ @redis_instance.lrange('queue:publish_worker_default', 0, -1).should have(1).item
+ end
+ end
+
+ context 'for repository of personal platform' do
+ let(:main_platform) { FactoryGirl.create(:platform) }
+ let(:repository) { FactoryGirl.create(:personal_repository) }
+ before do
+ repository.regenerate main_platform.id
+ subject.new.run
+ end
+
+ it "ensures that only one repository_status has status regenerating" do
+ RepositoryStatus.where(:status => RepositoryStatus::REGENERATING).should have(1).item
+ end
+
+ it 'ensures that new task has been created' do
+ @redis_instance.lrange('queue:publish_worker_default', 0, -1).should have(1).item
+ end
+ end
+
+ end
after(:all) do
APP_CONFIG['abf_worker']['publish_workers_count'] = @publish_workers_count
diff --git a/spec/mailers/user_mailer_spec.rb b/spec/mailers/user_mailer_spec.rb
index 7183cced0..b0167e089 100644
--- a/spec/mailers/user_mailer_spec.rb
+++ b/spec/mailers/user_mailer_spec.rb
@@ -1,7 +1,6 @@
require "spec_helper"
describe UserMailer do
- pending "add some examples to (or delete) #{__FILE__}"
context 'On Issue create' do
before(:each) do
@@ -13,7 +12,7 @@ describe UserMailer do
any_instance_of(Project, :versions => ['v1.0', 'v2.0'])
@issue = FactoryGirl.create(:issue, :project_id => @project.id, :assignee_id => @issue_user.id, :user => @issue_user)
- @email = UserMailer.new_issue_notification(@issue, @issue_user).deliver
+ @email = UserMailer.new_issue_notification(@issue, @issue_user).deliver!
end
it 'should have correct subject' do
@@ -48,7 +47,7 @@ describe UserMailer do
any_instance_of(Project, :versions => ['v1.0', 'v2.0'])
@issue = FactoryGirl.create(:issue, :project_id => @project.id, :assignee_id => @issue_user.id, :user => @issue_user)
- @email = UserMailer.issue_assign_notification(@issue, @user).deliver
+ @email = UserMailer.issue_assign_notification(@issue, @user).deliver!
end
it 'should have correct subject' do
@@ -63,10 +62,6 @@ describe UserMailer do
@email.from.should == [APP_CONFIG['do-not-reply-email']]
end
- it 'should assign user name' do
- @email.body.encoded.should match(@user.name)
- end
-
it 'should assign issue title' do
@email.body.encoded.should match(@issue.title)
end
@@ -85,7 +80,7 @@ describe UserMailer do
@issue = FactoryGirl.create(:issue, :project_id => @project.id, :assignee_id => @issue_user.id, :user => @issue_user)
@comment = FactoryGirl.create(:comment, :commentable => @issue, :user_id => @user.id, :project => @project)
- @email = UserMailer.new_comment_notification(@comment, @issue_user).deliver
+ @email = UserMailer.new_comment_notification(@comment, @issue_user).deliver!
end
it 'should have correct subject' do
diff --git a/spec/models/advisory_spec.rb b/spec/models/advisory_spec.rb
index abbb38c8e..2f2e6f8ce 100644
--- a/spec/models/advisory_spec.rb
+++ b/spec/models/advisory_spec.rb
@@ -1,5 +1,47 @@
require 'spec_helper'
-describe Advisory do
- pending "add some examples to (or delete) #{__FILE__}"
+shared_examples_for 'attach advisory to build_list' do
+
+ it 'ensure that advisory has been attached to build_list' do
+ build_list.reload.advisory.should == advisory
+ end
+
+ it 'ensure that save_to_platform of build_list has been attached to advisory' do
+ build_list.save_to_platform.advisories.should include(advisory)
+ end
+
+ it 'ensure that projects of build_list has been attached to advisory' do
+ build_list.project.advisories.should include(advisory)
+ end
+
+end
+
+describe Advisory do
+ before { stub_symlink_methods }
+ context 'attach_build_list' do
+ let(:build_list) { FactoryGirl.create(:build_list) }
+
+ context 'attach new advisory to build_list' do
+ let(:advisory) { FactoryGirl.build(:advisory) }
+ before do
+ advisory.attach_build_list(build_list)
+ end
+
+ it_should_behave_like 'attach advisory to build_list'
+
+ it 'ensure that advisory has been created' do
+ Advisory.should have(1).item
+ end
+ end
+
+ context 'attach old advisory to build_list' do
+ let(:advisory) { FactoryGirl.create(:advisory) }
+ before do
+ advisory.attach_build_list(build_list)
+ end
+
+ it_should_behave_like 'attach advisory to build_list'
+ end
+
+ end
end
diff --git a/spec/models/build_list/package_spec.rb b/spec/models/build_list/package_spec.rb
new file mode 100644
index 000000000..3ed6e1c8c
--- /dev/null
+++ b/spec/models/build_list/package_spec.rb
@@ -0,0 +1,31 @@
+# -*- encoding : utf-8 -*-
+require 'spec_helper'
+
+describe BuildList::Package do
+ before { stub_symlink_methods }
+
+ it 'is valid' do
+ FactoryGirl.create(:build_list_package).should be_persisted
+ end
+
+ context '#set_epoch' do
+ let(:package) { FactoryGirl.build(:build_list_package) }
+
+ ['', '(none)'].each do |epoch|
+ it "ensures that epoch is set to nil when epoch is '#{epoch}'" do
+ package.epoch = epoch
+ package.save
+ package.epoch.should be_nil
+ end
+
+ end
+
+ it "ensures that valid epoch has been setted" do
+ package.epoch = '55'
+ package.save
+ package.epoch.should == 55
+ end
+
+ end
+
+end
diff --git a/spec/models/build_list_spec.rb b/spec/models/build_list_spec.rb
index 7dd4dfbdc..6817f481b 100644
--- a/spec/models/build_list_spec.rb
+++ b/spec/models/build_list_spec.rb
@@ -1,6 +1,7 @@
require 'spec_helper'
describe BuildList do
+ before { stub_symlink_methods }
context 'validates that repository contains project' do
it 'when repository contains project' do
@@ -15,9 +16,8 @@ describe BuildList do
end
context "#notify_users" do
- before { stub_symlink_methods }
let!(:user) { FactoryGirl.create(:user) }
- let!(:build_list) { FactoryGirl.create(:build_list_core,
+ let!(:build_list) { FactoryGirl.create(:build_list,
:user => user,
:auto_publish => false) }
let!(:build_list_package) { FactoryGirl.create(:build_list_package,
@@ -140,7 +140,7 @@ describe BuildList do
it "doesn't get 2 notification by email when user associated to project and created task" do
project = FactoryGirl.create(:project_with_commit, :owner => user)
- bl = FactoryGirl.create(:build_list_core_with_attaching_project,
+ bl = FactoryGirl.create(:build_list_with_attaching_project,
:user => user,
:auto_publish => true,
:project => project
@@ -154,4 +154,83 @@ describe BuildList do
end # notify_users
+ context '#has_new_packages?' do
+ let!(:build_list) { FactoryGirl.create( :build_list,
+ :status => BuildList::SUCCESS,
+ :auto_publish => true) }
+ let!(:build_list_package) { FactoryGirl.create( :build_list_package,
+ :build_list => build_list,
+ :version => '3.1.12',
+ :release => 6,
+ :platform => build_list.save_to_platform,
+ :project => build_list.project) }
+ let!(:published_build_list) { FactoryGirl.create( :build_list,
+ :project => build_list.project,
+ :status => BuildList::BUILD_PUBLISHED,
+ :save_to_platform => build_list.save_to_platform,
+ :arch => build_list.arch) }
+ let!(:published_build_list_package) { FactoryGirl.create( :build_list_package,
+ :build_list => published_build_list,
+ :platform => published_build_list.save_to_platform,
+ :actual => true,
+ :version => '3.1.12',
+ :release => 6,
+ :project => published_build_list.project) }
+
+ it 'ensures that return false if version of packages are same and platform is released' do
+ build_list.save_to_platform.update_attributes(:released => true)
+ build_list.has_new_packages?.should be_false
+ end
+
+ it 'ensures that return true if version of packages are same and platform is not released' do
+ build_list.has_new_packages?.should be_true
+ end
+
+ context 'ensures that return false if version of published package >' do
+
+ it 'published: 3.1.13, new: 3.1.12' do
+ published_build_list_package.update_attributes(:version => '3.1.13')
+ build_list.has_new_packages?.should be_false
+ end
+
+ it 'published: 3.1.12, new: 3.0.999' do
+ build_list_package.update_attributes(:version => '3.0.999')
+ build_list.has_new_packages?.should be_false
+ end
+
+ it 'published: 3.0.0, new: 3.0.rc1' do
+ published_build_list_package.update_attributes(:version => '3.0.0')
+ build_list_package.update_attributes(:version => '3.0.rc1')
+ build_list.has_new_packages?.should be_false
+ end
+
+ end
+
+ context 'ensures that return true if version of published package <' do
+
+ it 'published: 3.1.11, new: 3.1.12' do
+ published_build_list_package.update_attributes(:version => '3.1.11')
+ build_list.has_new_packages?.should be_true
+ end
+
+ it 'published: 3.0.999, new: 3.1.12' do
+ published_build_list_package.update_attributes(:version => '3.0.999')
+ build_list.has_new_packages?.should be_true
+ end
+
+ it 'published: 3.0.rc1, new: 3.0.0' do
+ published_build_list_package.update_attributes(:version => '3.0.rc1')
+ build_list_package.update_attributes(:version => '3.0.0')
+ build_list.has_new_packages?.should be_true
+ end
+
+ end
+
+ it 'ensures that return true if release of published package <' do
+ published_build_list_package.update_attributes(:release => 5)
+ build_list.has_new_packages?.should be_true
+ end
+
+ end
+
end
diff --git a/spec/models/cancan_spec.rb b/spec/models/cancan_spec.rb
index 8cdc804da..8474e9697 100644
--- a/spec/models/cancan_spec.rb
+++ b/spec/models/cancan_spec.rb
@@ -2,12 +2,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
@@ -16,47 +16,46 @@ 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
-
- 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 repositories' do
- @ability.should_not be_able_to(:destroy, personal_repository)
- end
- end
-
- context 'Site guest' do
- 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)
+ 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 not be able to read hidden platform' do
- @ability.should_not be_able_to(:read, hidden_platform)
+ 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 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
+ 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)
end
[:publish, :cancel, :reject_publish, :create_container].each do |action|
@@ -65,6 +64,12 @@ describe CanCan do
end
end
+ [:mass_import, :run_mass_import].each do |action|
+ it "should not be able to #{ action } project" do
+ @ability.should_not be_able_to(action, Project)
+ end
+ end
+
it 'should not be able to update register request' do
@ability.should_not be_able_to(:update, register_request)
end
@@ -77,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
@@ -88,11 +93,17 @@ describe CanCan do
end
[Platform, Repository].each do |model_name|
- it "should not be able to read #{model_name}" do
+ it "should be able to read #{model_name}" do
@ability.should be_able_to(:read, model_name)
end
end
+ [:mass_import, :run_mass_import].each do |action|
+ it "should not be able to #{ action } project" do
+ @ability.should_not be_able_to(action, Project)
+ end
+ end
+
it "shoud be able to show user profile" do
@ability.should be_able_to(:show, User)
end
@@ -228,6 +239,27 @@ describe CanCan do
end
end
+ context 'through group-member' do
+ before(:each) do
+ @group_member = FactoryGirl.create(:group)
+ @project.relations.create!(:actor_id => @group_member.id, :actor_type => 'Group', :role => 'reader')
+ @group_member_ability = Ability.new(@group_member.owner)
+ end
+
+ it 'should be able to read open project' do
+ @group_member_ability.should be_able_to(:read, @project)
+ end
+
+ it 'should be able to read closed project' do
+ @project.update_attribute :visibility, 'hidden'
+ @group_member_ability.should be_able_to(:read, @project)
+ end
+
+ it 'should include hidden project in list' do
+ @project.update_attribute :visibility, 'hidden'
+ Project.accessible_by(@group_member_ability, :show).where(:projects => {:id => @project.id}).count.should == 1
+ end
+ end
end
context 'platform relations' do
@@ -239,9 +271,16 @@ describe CanCan do
before(:each) do
@platform.owner = @user
@platform.save
+ @ability = Ability.new(@user)
end
- [:read, :update, :destroy].each do |action|
+ [:mass_import, :run_mass_import].each do |action|
+ it "should be able to #{ action } project" do
+ @ability.should be_able_to(action, Project)
+ end
+ end
+
+ [:read, :update, :destroy, :change_visibility].each do |action|
it "should be able to #{action} platform" do
@ability.should be_able_to(action, @platform)
end
@@ -251,6 +290,13 @@ describe CanCan do
context 'with read rights' do
before(:each) do
@platform.relations.create!(:actor_id => @user.id, :actor_type => 'User', :role => 'reader')
+ @ability = Ability.new(@user)
+ end
+
+ [:mass_import, :run_mass_import].each do |action|
+ it "should not be able to #{ action } project" do
+ @ability.should_not be_able_to(action, Project)
+ end
end
it "should be able to read platform" do
@@ -270,7 +316,7 @@ describe CanCan do
@repository.platform.save
end
- [:read, :create, :update, :destroy, :add_project, :remove_project, :change_visibility, :settings].each do |action|
+ [:read, :create, :update, :destroy, :add_project, :remove_project, :settings].each do |action|
it "should be able to #{action} repository" do
@ability.should be_able_to(action, @repository)
end
diff --git a/spec/models/comment_for_commit_spec.rb b/spec/models/comment_for_commit_spec.rb
index 417995b8f..9ebc36b1f 100644
--- a/spec/models/comment_for_commit_spec.rb
+++ b/spec/models/comment_for_commit_spec.rb
@@ -5,6 +5,10 @@ def create_comment user
FactoryGirl.create(:comment, :user => user, :commentable => @commit, :project => @project)
end
+def create_comment_in_commit commit, project, body
+ FactoryGirl.create(:comment, :user => @user, :commentable => commit, :project => project, :body => body)
+end
+
def set_comments_data_for_commit
@ability = Ability.new(@user)
@@ -262,5 +266,63 @@ describe Comment do
should_not_send_email(commentor: @user)
end
end
+
+ context 'automatic issue linking' do
+ before(:each) do
+ @same_name_project = FactoryGirl.create(:project, :name => @project.name)
+ @issue_in_same_name_project = FactoryGirl.create(:issue, :project => @same_name_project, :user => @same_name_project.owner)
+ @another_project = FactoryGirl.create(:project, :owner => @user)
+ @other_user_project = FactoryGirl.create(:project)
+ @issue = FactoryGirl.create(:issue, :project => @project, :user => @user)
+ @second_issue = FactoryGirl.create(:issue, :project => @project, :user => @user)
+ @issue_in_another_project = FactoryGirl.create(:issue, :project => @another_project, :user => @user)
+ @issue_in_other_user_project = FactoryGirl.create(:issue, :project => @other_user_project, :user => @other_user_project.owner)
+ end
+
+ it 'should create automatic comment' do
+ create_comment_in_commit(@commit, @project, "test link to ##{@issue.serial_id}; [##{@second_issue.serial_id}]")
+ Comment.where(:automatic => true, :commentable_type => 'Issue',
+ :commentable_id => @second_issue.id,
+ :created_from_commit_hash => @commit.id.hex).count.should == 1
+ end
+
+ it 'should create automatic comment in the another project issue' do
+ body = "[#{@another_project.name_with_owner}##{@issue_in_another_project.serial_id}]"
+ create_comment_in_commit(@commit, @project, body)
+ Comment.where(:automatic => true, :commentable_type => 'Issue',
+ :commentable_id => @issue_in_another_project.id,
+ :created_from_commit_hash => @commit.id.hex).count.should == 1
+ end
+
+ it 'should create automatic comment in the same name project issue' do
+ body = "[#{@same_name_project.owner.uname}##{@issue_in_same_name_project.serial_id}]"
+ create_comment_in_commit(@commit, @project, body)
+ Comment.where(:automatic => true, :commentable_type => 'Issue',
+ :commentable_id => @issue_in_same_name_project.id,
+ :created_from_commit_hash => @commit.id.hex).count.should == 1
+ end
+
+ it 'should not create duplicate automatic comment' do
+ create_comment_in_commit(@commit, @project, "test link to [##{@second_issue.serial_id}]")
+ create_comment_in_commit(@commit, @project, "test duplicate link to [##{@second_issue.serial_id}]")
+ Comment.where(:automatic => true, :commentable_type => 'Issue',
+ :commentable_id => @second_issue.id,
+ :created_from_commit_hash => @commit.id.hex).count.should == 1
+ end
+
+ it 'should not create duplicate automatic comment from one' do
+ create_comment_in_commit(@commit, @project, "test link to [##{@second_issue.serial_id}]; ##{@second_issue.serial_id}")
+ Comment.where(:automatic => true, :commentable_type => 'Issue',
+ :commentable_id => @second_issue.id,
+ :created_from_commit_hash => @commit.id.hex).count.should == 1
+ end
+ it 'should create two automatic comment' do
+ body = "test ##{@second_issue.serial_id}" +
+ " && [#{@another_project.name_with_owner}##{@issue_in_another_project.serial_id}]"
+ create_comment_in_commit(@commit, @project, body)
+ Comment.where(:automatic => true,
+ :created_from_commit_hash => @commit.id.hex).count.should == 2
+ end
+ end
end
end
diff --git a/spec/models/comment_spec.rb b/spec/models/comment_spec.rb
index 47e8db74e..713bb6497 100644
--- a/spec/models/comment_spec.rb
+++ b/spec/models/comment_spec.rb
@@ -13,6 +13,10 @@ def set_commentable_data
any_instance_of(Project, :versions => ['v1.0', 'v2.0'])
end
+def create_comment_in_issue issue, body
+ FactoryGirl.create(:comment, :user => issue.user, :commentable => issue, :project => issue.project, :body => body)
+end
+
describe Comment do
before { stub_symlink_methods }
context 'for global admin user' do
@@ -99,5 +103,95 @@ describe Comment do
@comment.should_not allow_mass_assignment_of :project_id
end
end
+
+ context 'automatic issue linking' do
+ before(:each) do
+ @same_name_project = FactoryGirl.create(:project, :name => @project.name)
+ @issue_in_same_name_project = FactoryGirl.create(:issue, :project => @same_name_project, :user => @same_name_project.owner)
+ @another_project = FactoryGirl.create(:project, :owner => @user)
+ @other_user_project = FactoryGirl.create(:project)
+ @issue = FactoryGirl.create(:issue, :project => @project, :user => @user)
+ @second_issue = FactoryGirl.create(:issue, :project => @project, :user => @user)
+ @issue_in_another_project = FactoryGirl.create(:issue, :project => @another_project, :user => @user)
+ @issue_in_other_user_project = FactoryGirl.create(:issue, :project => @other_user_project, :user => @other_user_project.owner)
+ end
+
+ it 'should create automatic comment' do
+ create_comment_in_issue(@issue, "test link to ##{@issue.serial_id}; [##{@second_issue.serial_id}]")
+ Comment.where(:automatic => true, :commentable_type => 'Issue',
+ :commentable_id => @second_issue.id,
+ :created_from_issue_id => @issue.id).count.should == 1
+ end
+
+ it 'should not create automatic comment to the same issue' do
+ create_comment_in_issue(@issue, "test link to ##{@issue.serial_id}; [##{@second_issue.serial_id}]")
+ Comment.where(:automatic => true,
+ :created_from_issue_id => @issue.id).count.should == 1
+ end
+
+ it 'should create automatic comment in the another project issue' do
+ body = "[#{@another_project.name_with_owner}##{@issue_in_another_project.serial_id}]"
+ create_comment_in_issue(@issue, body)
+ Comment.where(:automatic => true, :commentable_type => 'Issue',
+ :commentable_id => @issue_in_another_project.id,
+ :created_from_issue_id => @issue.id).count.should == 1
+ end
+
+ it 'should create automatic comment in the same name project issue' do
+ body = "[#{@same_name_project.owner.uname}##{@issue_in_same_name_project.serial_id}]"
+ create_comment_in_issue(@issue, body)
+ Comment.where(:automatic => true, :commentable_type => 'Issue',
+ :commentable_id => @issue_in_same_name_project.id,
+ :created_from_issue_id => @issue.id).count.should == 1
+ end
+
+ it 'should not create duplicate automatic comment' do
+ create_comment_in_issue(@issue, "test link to [##{@second_issue.serial_id}]")
+ create_comment_in_issue(@issue, "test duplicate link to [##{@second_issue.serial_id}]")
+ Comment.where(:automatic => true, :commentable_type => 'Issue',
+ :commentable_id => @second_issue.id,
+ :created_from_issue_id => @issue.id).count.should == 1
+ end
+
+ it 'should not create duplicate automatic comment from one' do
+ create_comment_in_issue(@issue, "test link to [##{@second_issue.serial_id}]; ##{@second_issue.serial_id}")
+ Comment.where(:automatic => true, :commentable_type => 'Issue',
+ :commentable_id => @second_issue.id,
+ :created_from_issue_id => @issue.id).count.should == 1
+ end
+
+ it 'should create two automatic comment' do
+ body = "test ##{@second_issue.serial_id}" +
+ " && [#{@another_project.name_with_owner}##{@issue_in_another_project.serial_id}]"
+ create_comment_in_issue(@issue, body)
+ Comment.where(:automatic => true,
+ :created_from_issue_id => @issue.id).count.should == 2
+ end
+
+ it 'should create automatic comment by issue title' do
+ issue = FactoryGirl.create(:issue, :project => @project, :user => @user,
+ :title => "link to ##{@issue.serial_id}")
+ Comment.where(:automatic => true,
+ :created_from_issue_id => issue.id).count.should == 1
+ end
+
+ it 'should create automatic comment from issue body' do
+ issue = FactoryGirl.create(:issue, :project => @project, :user => @user,
+ :body => "link to ##{@issue.serial_id}")
+ Comment.where(:automatic => true,
+ :created_from_issue_id => issue.id).count.should == 1
+ end
+
+ it 'should create only one automatic comment from issue title and body' do
+ issue = FactoryGirl.create(:issue, :project => @project, :user => @user,
+ :title => "link to ##{@issue.serial_id} in title",
+ :body => "link to ##{@issue.serial_id} in body")
+ Comment.where(:automatic => true,
+ :created_from_issue_id => issue.id).count.should == 1
+ end
+
+
+
+ end
end
end
diff --git a/spec/models/activity_feed_observer_spec.rb b/spec/models/hook_spec.rb
similarity index 71%
rename from spec/models/activity_feed_observer_spec.rb
rename to spec/models/hook_spec.rb
index 378ee2377..42515cea0 100644
--- a/spec/models/activity_feed_observer_spec.rb
+++ b/spec/models/hook_spec.rb
@@ -1,5 +1,5 @@
require 'spec_helper'
-describe ActivityFeedObserver do
+describe Hook do
pending "add some examples to (or delete) #{__FILE__}"
end
diff --git a/spec/models/issue_spec.rb b/spec/models/issue_spec.rb
index ba688a33d..2ea3e032c 100644
--- a/spec/models/issue_spec.rb
+++ b/spec/models/issue_spec.rb
@@ -32,6 +32,31 @@ describe Issue do
create_issue(@user)
ActionMailer::Base.deliveries.count.should == 0
end
+
+ it 'should create automatic comment from another issue' do
+ create_issue(@user)
+ another_issue = FactoryGirl.create(:issue, :project => @project, :title => "[##{@issue.serial_id}]")
+ Comment.where(:automatic => true, :commentable_type => 'Issue',
+ :created_from_issue_id => another_issue.id).count.should == 1
+ end
+
+ it 'should create automatic comment after updating another issue body' do
+ create_issue(@user)
+ another_issue = FactoryGirl.create(:issue, :project => @project)
+ another_issue.update_attribute(:title, "[##{@issue.serial_id}]")
+ another_issue.send(:send_assign_notifications)
+
+ Comment.where(:automatic => true, :commentable_type => 'Issue',
+ :created_from_issue_id => another_issue.id).count.should == 1
+ end
+
+ it 'should send email message to new assignee' do
+ create_issue(@user)
+ ActionMailer::Base.deliveries = []
+ @issue.update_attribute :assignee_id, @user.id
+ @issue.send(:send_assign_notifications, :update)
+ ActionMailer::Base.deliveries.count.should == 1
+ end
end
context 'for member-group' do
@@ -40,8 +65,8 @@ describe Issue do
@project = FactoryGirl.create(:project, :owner => @user)
@group = FactoryGirl.create(:group)
- reader = FactoryGirl.create :user
- @group.actors.create(:actor_type => 'User', :actor_id => reader.id, :role => 'reader')
+ @reader = FactoryGirl.create :user
+ @group.actors.create(:actor_type => 'User', :actor_id => @reader.id, :role => 'reader')
end
it 'should send an e-mail to all members of the admin group' do
@@ -64,6 +89,32 @@ describe Issue do
create_issue(@stranger)
ActionMailer::Base.deliveries.count.should == 1 # 1 project owner
end
+
+ it 'should reset issue assignee after remove him from group' do
+ @project.relations.create!(:actor_type => 'Group', :actor_id => @group.id, :role => 'reader')
+ create_issue(@group.owner)
+ @issue.update_column :assignee_id, @reader.id
+ @group.remove_member @reader
+ @issue.reload.assignee_id.should == nil
+ end
+
+ it 'should not reset issue assignee' do
+ @project.relations.create!(:actor_type => 'Group', :actor_id => @group.id, :role => 'reader')
+ @project.relations.create!(:actor_type => 'User', :actor_id => @reader.id, :role => 'reader')
+ create_issue(@group.owner)
+ @issue.update_column :assignee_id, @reader.id
+ @group.remove_member @reader
+ @issue.reload.assignee_id.should == @reader.id
+ end
+
+ it 'should reset issue assignee after remove him from project' do
+ @project.relations.create!(:actor_type => 'User', :actor_id => @reader.id, :role => 'reader')
+ create_issue(@reader)
+ @issue.update_column :assignee_id, @reader.id
+ @project.remove_member @reader # via api
+ @issue.reload.assignee_id.should == nil
+ end
+
end
context 'Group project' do
diff --git a/spec/models/mass_build_spec.rb b/spec/models/mass_build_spec.rb
index e7bb6c4d2..3e213af38 100644
--- a/spec/models/mass_build_spec.rb
+++ b/spec/models/mass_build_spec.rb
@@ -1,5 +1,41 @@
require 'spec_helper'
describe MassBuild do
- pending "add some examples to (or delete) #{__FILE__}"
+ before { stub_symlink_methods }
+
+ context 'ensures that validations and associations exist' do
+ before do
+ # Need for validate_uniqueness_of check
+ FactoryGirl.create(:mass_build)
+ end
+
+ it { should belong_to(:build_for_platform) }
+ it { should belong_to(:save_to_platform) }
+ it { should belong_to(:user) }
+ it { should have_many(:build_lists)}
+
+ it { should validate_presence_of(:save_to_platform_id)}
+ it { should validate_presence_of(:build_for_platform_id)}
+ it { should validate_presence_of(:user_id)}
+ it { should validate_presence_of(:arch_names)}
+ it { should validate_presence_of(:name)}
+
+ it { should validate_presence_of(:projects_list)}
+ it { should ensure_length_of(:projects_list).is_at_most(500_000) }
+
+
+ it { should_not allow_mass_assignment_of(:name) }
+ it { should_not allow_mass_assignment_of(:arch_names) }
+ end
+
+ it 'ensures that projects_list contains unique projects' do
+ projects_list = %(at
+ at
+ ab
+ )
+ mass_build = FactoryGirl.create(:mass_build, :projects_list => projects_list)
+ list = mass_build.projects_list.split(/[\r]*\n/)
+ list.should have(2).items
+ list.should include('at', 'ab')
+ end
end
diff --git a/spec/models/platform_content.rb b/spec/models/platform_content.rb
new file mode 100644
index 000000000..1edb31e8f
--- /dev/null
+++ b/spec/models/platform_content.rb
@@ -0,0 +1,71 @@
+# -*- encoding : utf-8 -*-
+require 'spec_helper'
+
+describe PlatformContent do
+ subject { PlatformContent }
+
+ before { stub_symlink_methods }
+ let!(:platform) { FactoryGirl.create(:platform) }
+
+ context '#find_by_platform' do
+ before do
+ File.open(File.join(platform.path, 'test001'), "w")
+ File.open(File.join(platform.path, 'test002'), "w")
+ end
+
+ it 'ensures that finds files' do
+ # + /repository folder
+ subject.find_by_platform(platform, '', '').should have(3).items
+ end
+
+ context 'ensures that finds files by name' do
+ it { subject.find_by_platform(platform, '', 'test').should have(2).items }
+ it { subject.find_by_platform(platform, '', 'test001').should have(1).item }
+ it { subject.find_by_platform(platform, 'repository', 'test').should have(:no).items }
+ end
+
+ end
+
+ context '#is_folder?' do
+ it 'ensures that returns true for folder' do
+ subject.find_by_platform(platform, '', 'repository').first.is_folder?
+ .should be_true
+ end
+
+ it 'ensures that returns false for file' do
+ File.open(File.join(platform.path, 'test001'), "w")
+ subject.find_by_platform(platform, '', 'test').first.is_folder?
+ .should be_false
+ end
+ end
+
+ context '#build_list' do
+ let!(:package) { FactoryGirl.create(:build_list_package, :actual => true) }
+ let(:platform) { package.build_list.save_to_platform }
+ let(:repository) { platform.repositories.first }
+
+ before do
+ File.open(File.join(platform.path, 'test001'), "w")
+
+ package.build_list.update_column(:status, BuildList::BUILD_PUBLISHED)
+ path = File.join platform.path, 'repository', 'SRPMS', repository.name, 'release'
+ FileUtils.mkdir_p path
+ File.open(File.join(path, package.fullname), "w")
+
+ path = File.join path, 'repodata'
+ FileUtils.mkdir_p path
+ File.open(File.join(path, package.fullname), "w")
+ end
+
+ context 'ensures that returns nil for simple file' do
+ it { subject.find_by_platform(platform, '', 'test').first.build_list.should be_nil }
+ it { subject.find_by_platform(platform, "repository/SRPMS/#{repository.name}/release/repodata", '').first.build_list.should be_nil }
+ end
+
+ it 'ensures that returns build_list for package' do
+ subject.find_by_platform(platform, "repository/SRPMS/#{repository.name}/release", package.fullname)
+ .first.build_list.should == package.build_list
+ end
+ end
+
+end
diff --git a/spec/models/platform_spec.rb b/spec/models/platform_spec.rb
index 6eabc8798..0a7b5eb3c 100644
--- a/spec/models/platform_spec.rb
+++ b/spec/models/platform_spec.rb
@@ -1,48 +1,70 @@
require 'spec_helper'
describe Platform do
- before(:all) do
- stub_symlink_methods
- Platform.delete_all
- User.delete_all
- init_test_root
- # Need for validate_uniqueness_of check
- FactoryGirl.create(:platform)
+ before { stub_symlink_methods }
+
+ context 'ensures that validations and associations exist' do
+ before do
+ # Need for validate_uniqueness_of check
+ FactoryGirl.create(:platform)
+ end
+
+ it { should belong_to(:owner) }
+ it { should have_many(:members)}
+ it { should have_many(:repositories)}
+ it { should have_many(:products)}
+
+ it { should validate_presence_of(:name)}
+ it { should validate_uniqueness_of(:name).case_insensitive }
+ it { should allow_value('Basic_platform-name-1234').for(:name) }
+ it { should_not allow_value('.!').for(:name) }
+ it { should validate_presence_of(:description) }
+ it { should validate_presence_of(:distrib_type) }
+ it { should validate_presence_of(:visibility) }
+
+ Platform::VISIBILITIES.each do |value|
+ it {should allow_value(value).for(:visibility)}
+ end
+ it {should_not allow_value('custom_status').for(:visibility)}
+
+ it { should have_readonly_attribute(:name) }
+ it { should have_readonly_attribute(:distrib_type) }
+ it { should have_readonly_attribute(:parent_platform_id) }
+ it { should have_readonly_attribute(:platform_type) }
+
+ it { should_not allow_mass_assignment_of(:repositories) }
+ it { should_not allow_mass_assignment_of(:products) }
+ it { should_not allow_mass_assignment_of(:members) }
+ it { should_not allow_mass_assignment_of(:parent) }
+
+ it {should_not allow_value("How do you do...\nmy_platform").for(:name)}
end
- it { should belong_to(:owner) }
- it { should have_many(:members)}
- it { should have_many(:repositories)}
- it { should have_many(:products)}
-
- it { should validate_presence_of(:name)}
- it { should validate_uniqueness_of(:name).case_insensitive }
- it { should validate_format_of(:name).with('Basic_platform-name-1234') }
- it { should validate_format_of(:name).not_with('.!') }
- it { should validate_presence_of(:description) }
- it { should validate_presence_of(:distrib_type) }
- it { should validate_presence_of(:visibility) }
-
- Platform::VISIBILITIES.each do |value|
- it {should allow_value(value).for(:visibility)}
+ it 'ensures that folder of platform will be removed after destroy' do
+ platform = FactoryGirl.create :platform
+ FileUtils.mkdir_p platform.path
+ platform.destroy
+ Dir.exists?(platform.path).should be_false
end
- it {should_not allow_value('custom_status').for(:visibility)}
- it { should have_readonly_attribute(:name) }
- it { should have_readonly_attribute(:distrib_type) }
- it { should have_readonly_attribute(:parent_platform_id) }
- it { should have_readonly_attribute(:platform_type) }
-
- it { should_not allow_mass_assignment_of(:repositories) }
- it { should_not allow_mass_assignment_of(:products) }
- it { should_not allow_mass_assignment_of(:members) }
- it { should_not allow_mass_assignment_of(:parent) }
-
- it {should_not allow_value("How do you do...\nmy_platform").for(:name)}
-
- after(:all) do
- Platform.delete_all
- User.delete_all
- clear_test_root
+ it 'ensures that owner of personal platform can not be changed' do
+ platform = FactoryGirl.create :personal_platform
+ owner = platform.owner
+ platform.owner = FactoryGirl.create :user
+ platform.save.should be_false
end
+
+ it 'ensures that owner of platform of group can not be changed' do
+ group = FactoryGirl.create :group
+ platform = FactoryGirl.create :personal_platform, :owner => group
+ platform.owner = FactoryGirl.create :user
+ platform.save.should be_false
+ end
+
+ it 'ensures that owner of main platform can be changed' do
+ platform = FactoryGirl.create :platform
+ platform.owner = FactoryGirl.create :user
+ platform.save.should be_true
+ end
+
end
diff --git a/spec/models/project_spec.rb b/spec/models/project_spec.rb
index 31bd3b874..8aec0a4e3 100644
--- a/spec/models/project_spec.rb
+++ b/spec/models/project_spec.rb
@@ -1,11 +1,16 @@
require 'spec_helper'
describe Project do
- before do
- stub_symlink_methods
- @root_project = FactoryGirl.create(:project)
- @child_project = @root_project.fork(FactoryGirl.create(:user))
- @child_child_project = @child_project.fork(FactoryGirl.create(:user))
+ before { stub_symlink_methods }
+
+ context 'creation' do
+ let(:root_project) { FactoryGirl.create(:project) }
+ let(:child_project) { root_project.fork(FactoryGirl.create(:user)) }
+ let(:child_child_project) { child_project.fork(FactoryGirl.create(:user)) }
+
+ it { root_project }
+ it { child_project }
+ it { child_child_project }
end
context 'for destroy' do
@@ -85,4 +90,95 @@ describe Project do
lambda {FactoryGirl.create(:project, :name => "...\nbeatiful_name\n for project")}.should raise_error(ActiveRecord::RecordInvalid)
end
end
+
+ it 'ensures that path to git repository has been changed after rename of project' do
+ project = FactoryGirl.create(:project_with_commit)
+ project.update_attributes(:name => "#{project.name}-new")
+ Dir.exists?(project.path).should be_true
+ end
+
+ context 'manage branches' do
+ let!(:project) { FactoryGirl.create(:project_with_commit) }
+ let(:branch) { project.repo.branches.detect{|b| b.name == 'conflicts'} }
+ let(:master) { project.repo.branches.detect{|b| b.name == 'master'} }
+ let(:user) { FactoryGirl.create(:user) }
+ before { stub_redis }
+
+ context '#delete_branch' do
+ it 'ensures that returns true on success' do
+ project.delete_branch(branch, user).should be_true
+ end
+
+ it 'ensures that branch has been deleted' do
+ lambda { project.delete_branch(branch, user) }.should change{ project.repo.branches.count }.by(-1)
+ end
+
+ it 'ensures that returns false on delete master' do
+ project.delete_branch(master, user).should be_false
+ end
+
+ it 'ensures that master has not been deleted' do
+ lambda { project.delete_branch(master, user) }.should change{ project.repo.branches.count }.by(0)
+ end
+
+ it 'ensures that returns false on delete wrong branch' do
+ project.delete_branch(branch, user)
+ project.delete_branch(branch, user).should be_false
+ end
+ end
+
+ context '#create_branch' do
+ before do
+ project.delete_branch(branch, user)
+ end
+
+ it 'ensures that returns true on success' do
+ project.create_branch(branch.name, branch.commit.id, user).should be_true
+ end
+
+ it 'ensures that branch has been created' do
+ lambda { project.create_branch(branch.name, branch.commit.id, user) }.should change{ project.repo.branches.count }.by(1)
+ end
+
+ it 'ensures that returns false on create wrong branch' do
+ project.create_branch(branch.name, GitHook::ZERO, user).should be_false
+ end
+ end
+
+ end
+
+ context '#replace_release_tag' do
+
+ [
+ ['Release: %mkrel 4mdk', 'Release: 5mdk'],
+ ['Release: 4', 'Release: 5'],
+ ['Release: 4.1', 'Release: 4.2'],
+ ['Release: 5.4.2', 'Release: 5.4.3'],
+ ['Release: 5.4.2mdk', 'Release: 5.4.3mdk'],
+ ['Release: %mkrel 5.4.31mdk', 'Release: 5.4.32mdk'],
+ ['%define release %mkrel 4mdk', '%define release 5mdk'],
+ ['%define release 4', '%define release 5'],
+ ['%define release 4.1', '%define release 4.2'],
+ ['%define release 5.4.2', '%define release 5.4.3'],
+ ['%define release 5.4.31mdk', '%define release 5.4.32mdk']
+ ].each do |items|
+ it "ensures that replace '#{items[0]}' => '#{items[1]}'" do
+ Project.replace_release_tag(items[0]).should == items[1]
+ end
+ end
+ end
+
+ it '#run_mass_import' do
+ owner = FactoryGirl.create(:user)
+ repository = FactoryGirl.create(:repository)
+ url = 'http://abf-downloads.rosalinux.ru/abf_personal/repository/test-mass-import'
+ visibility = 'open'
+
+ Project.run_mass_import(url, "abf-worker-service-1-3.src.rpm\nredir-2.2.1-7.res6.src.rpm\n", visibility, owner, repository.id)
+
+ Project.count.should == 2
+ repository.projects.should have(2).items
+ owner.projects.should have(2).items
+ end
+
end
diff --git a/spec/models/project_statistic_spec.rb b/spec/models/project_statistic_spec.rb
new file mode 100644
index 000000000..e13a0ec20
--- /dev/null
+++ b/spec/models/project_statistic_spec.rb
@@ -0,0 +1,24 @@
+require 'spec_helper'
+
+describe ProjectStatistic do
+
+ context 'ensures that validations and associations exist' do
+ it { should belong_to(:project) }
+ it { should belong_to(:arch) }
+
+ it { should validate_presence_of(:project_id) }
+ it { should validate_presence_of(:arch_id) }
+ it { should validate_presence_of(:average_build_time) }
+ it { should validate_presence_of(:build_count) }
+
+ it { should_not allow_mass_assignment_of(:project_id) }
+ it { should_not allow_mass_assignment_of(:arch_id) }
+
+ it 'uniqueness of project_id and arch_id' do
+ FactoryGirl.create(:project_statistic)
+ should validate_uniqueness_of(:project_id).scoped_to(:arch_id)
+ end
+
+ end
+
+end
diff --git a/spec/models/project_to_repository_spec.rb b/spec/models/project_to_repository_spec.rb
index fd595d3b1..437ca789e 100644
--- a/spec/models/project_to_repository_spec.rb
+++ b/spec/models/project_to_repository_spec.rb
@@ -20,7 +20,8 @@ describe ProjectToRepository do
stub_redis
@first_repo.project_to_repositories.destroy_all
queue = @redis_instance.lrange(AbfWorker::BuildListsPublishTaskManager::PROJECTS_FOR_CLEANUP, 0, -1)
- queue.should have(1).item
- queue.should include("#{@project.id}-#{@first_repo.id}-#{@platform.id}")
+ queue.should have(2).item
+ key = "#{@project.id}-#{@first_repo.id}-#{@platform.id}"
+ queue.should include(key, "testing-#{key}")
end
end
diff --git a/spec/models/pull_request_spec.rb b/spec/models/pull_request_spec.rb
index 40b234c7f..634b9531f 100644
--- a/spec/models/pull_request_spec.rb
+++ b/spec/models/pull_request_spec.rb
@@ -14,7 +14,6 @@ def set_data_for_pull
end
describe PullRequest do
-
context 'for owner user' do
before do
stub_symlink_methods
@@ -33,6 +32,13 @@ describe PullRequest do
@other_pull.save
end
+ it 'ensures that path to pull_request repository has been changed after rename of project' do
+ @pull.check
+ @project.update_attributes(:name => "#{@project.name}-new")
+ @pull.reload
+ Dir.exists?(@pull.path).should be_true
+ end
+
it 'master should merge with non_conflicts branch' do
@pull.check
@pull.status.should == 'ready'
diff --git a/spec/models/repository_spec.rb b/spec/models/repository_spec.rb
index 5de451ad8..006cbbb2c 100644
--- a/spec/models/repository_spec.rb
+++ b/spec/models/repository_spec.rb
@@ -1,10 +1,74 @@
require 'spec_helper'
describe Repository do
+ before { stub_symlink_methods }
+
+ context 'ensures that validations and associations exist' do
+ before do
+ # Need for validate_uniqueness_of check
+ FactoryGirl.create(:repository)
+ end
+
+ it { should belong_to(:platform) }
+ it { should have_many(:project_to_repositories).validate(true) }
+ it { should have_many(:projects).through(:project_to_repositories) }
+
+ it { should validate_presence_of(:name) }
+ it { should validate_uniqueness_of(:name).case_insensitive.scoped_to(:platform_id) }
+ it { should allow_value('basic_repository-name-1234').for(:name) }
+ it { should_not allow_value('.!').for(:name) }
+ it { should_not allow_value('Main').for(:name) }
+ it { should_not allow_value("!!\nbang_bang\n!!").for(:name) }
+ it { should validate_presence_of(:description) }
+
+ it { should have_readonly_attribute(:name) }
+ it { should have_readonly_attribute(:platform_id) }
+
+ it { should_not allow_mass_assignment_of(:platform) }
+ it { should_not allow_mass_assignment_of(:platform_id) }
+
+ end
+
+ context '#sync_lock_file_exists?, #add_sync_lock_file, #remove_sync_lock_file, #add_repo_lock_file, #remove_repo_lock_file' do
+ let(:repository) { FactoryGirl.create(:repository) }
+ let(:path) { "#{repository.platform.path}/repository/SRPMS/#{repository.name}" }
+ before { FileUtils.mkdir_p path }
+
+ it 'ensures that #sync_lock_file_exists? returns false if .sync.lock file does not exist' do
+ repository.sync_lock_file_exists?.should be_false
+ end
+
+ it 'ensures that #sync_lock_file_exists? returns true if .sync.lock file does exist' do
+ FileUtils.touch "#{path}/.sync.lock"
+ repository.sync_lock_file_exists?.should be_true
+ end
+
+ it 'ensures that #add_sync_lock_file creates .sync.lock file' do
+ repository.add_sync_lock_file
+ File.exist?("#{path}/.sync.lock").should be_true
+ end
+
+ it 'ensures that #remove_sync_lock_file removes .sync.lock file' do
+ FileUtils.touch "#{path}/.sync.lock"
+ repository.remove_sync_lock_file
+ File.exist?("#{path}/.sync.lock").should be_false
+ end
+
+ it 'ensures that #add_repo_lock_file creates .repo.lock file' do
+ repository.add_repo_lock_file
+ File.exist?("#{path}/.repo.lock").should be_true
+ end
+
+ it 'ensures that #remove_repo_lock_file removes .repo.lock file' do
+ FileUtils.touch "#{path}/.repo.lock"
+ repository.remove_repo_lock_file
+ File.exist?("#{path}/.repo.lock").should be_false
+ end
+
+ end
context 'when create with same owner that platform' do
- before (:each) do
- stub_symlink_methods
+ before do
@platform = FactoryGirl.create(:platform)
@params = {:name => 'tst_platform', :description => 'test platform'}
end
@@ -15,39 +79,57 @@ describe Repository do
end
end
- before(:all) do
- stub_symlink_methods
- Platform.delete_all
- User.delete_all
- Repository.delete_all
- init_test_root
- # Need for validate_uniqueness_of check
- FactoryGirl.create(:repository)
+ context 'ensures that folder of repository will be removed after destroy' do
+ let(:arch) { FactoryGirl.create(:arch) }
+ let(:types) { ['SRPM', arch.name] }
+
+ it "repository of main platform" do
+ FactoryGirl.create(:arch)
+ r = FactoryGirl.create(:repository)
+ paths = types.
+ map{ |type| "#{r.platform.path}/repository/#{type}/#{r.name}" }.
+ each{ |path| FileUtils.mkdir_p path }
+ r.destroy
+ paths.each{ |path| Dir.exists?(path).should be_false }
+ end
+
+ it "repository of personal platform" do
+ FactoryGirl.create(:arch)
+ main_platform = FactoryGirl.create(:platform)
+ r = FactoryGirl.create(:personal_repository)
+ paths = types.
+ map{ |type| "#{r.platform.path}/repository/#{main_platform.name}/#{type}/#{r.name}" }.
+ each{ |path| FileUtils.mkdir_p path }
+ r.destroy
+ paths.each{ |path| Dir.exists?(path).should be_false }
+ end
+
end
- it { should belong_to(:platform) }
- it { should have_many(:project_to_repositories).validate(true) }
- it { should have_many(:projects).through(:project_to_repositories) }
+ context '#add_projects' do
+ it 'user has ability to read of adding project' do
+ repository = FactoryGirl.create(:repository)
+ project = FactoryGirl.create(:project)
+ repository.add_projects("#{project.owner.uname}/#{project.name}", FactoryGirl.create(:user))
+ repository.projects.should have(1).item
+ end
- it { should validate_presence_of(:name) }
- it { should validate_uniqueness_of(:name).case_insensitive.scoped_to(:platform_id) }
- it { should validate_format_of(:name).with('basic_repository-name-1234') }
- it { should validate_format_of(:name).not_with('.!') }
- it { should validate_format_of(:name).not_with('Main') }
- it { should validate_format_of(:name).not_with("!!\nbang_bang\n!!") }
- it { should validate_presence_of(:description) }
+ it 'user has no ability to read of adding project' do
+ repository = FactoryGirl.create(:repository)
+ project = FactoryGirl.create(:project, :visibility => 'hidden')
+ repository.add_projects("#{project.owner.uname}/#{project.name}", FactoryGirl.create(:user))
+ repository.projects.should have(:no).items
+ end
+ end
- it { should have_readonly_attribute(:name) }
- it { should have_readonly_attribute(:platform_id) }
-
- it { should_not allow_mass_assignment_of(:platform) }
- it { should_not allow_mass_assignment_of(:platform_id) }
-
- after(:all) do
- Platform.delete_all
- User.delete_all
- Repository.delete_all
- clear_test_root
+ it '#remove_projects' do
+ stub_redis
+ repository = FactoryGirl.create(:repository)
+ project = FactoryGirl.create(:project)
+ repository.projects << project
+ repository.remove_projects(project.name)
+ repository.reload
+ repository.projects.should have(:no).items
end
end
diff --git a/spec/models/token_spec.rb b/spec/models/token_spec.rb
new file mode 100644
index 000000000..8c3092028
--- /dev/null
+++ b/spec/models/token_spec.rb
@@ -0,0 +1,32 @@
+# -*- encoding : utf-8 -*-
+require 'spec_helper'
+
+describe Token do
+ before { stub_symlink_methods }
+
+ describe 'platform token' do
+ let!(:platform_token) { FactoryGirl.create(:platform_token) }
+
+ context 'ensures that validations and associations exist' do
+ it { should belong_to(:subject) }
+ it { should belong_to(:creator) }
+
+ it { should validate_presence_of(:creator_id) }
+ it { should validate_presence_of(:subject_id) }
+ it { should validate_presence_of(:subject_type) }
+
+ it { should_not allow_mass_assignment_of(:authentication_token) }
+ it { should_not allow_mass_assignment_of(:creator_id) }
+ it { should_not allow_mass_assignment_of(:subject_id) }
+ it { should_not allow_mass_assignment_of(:subject_type) }
+
+ it 'ensures that authentication_token unique' do
+ token = FactoryGirl.create(:platform_token)
+ token.authentication_token = platform_token.authentication_token
+ token.valid?.should be_false
+ end
+ end
+ end
+
+
+end
diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb
index 333f6c315..3203da2d8 100644
--- a/spec/spec_helper.rb
+++ b/spec/spec_helper.rb
@@ -27,6 +27,8 @@ RSpec.configure do |config|
config.filter_run_excluding :anonymous_access => !(APP_CONFIG['anonymous_access'])
+ config.before(:all) { init_test_root }
+ config.after(:all) { clear_test_root }
end
def set_session_for(user=nil)
@@ -35,9 +37,10 @@ def set_session_for(user=nil)
sign_in current_user
end
-def http_login(user=nil)
+def http_login(user=nil, password = '123456')
# FIXME: password constant is a bad choice...
- request.env['HTTP_AUTHORIZATION'] = ActionController::HttpAuthentication::Basic.encode_credentials(user.email,'123456')
+ email = user.is_a?(String) ? user : user.try(:email)
+ request.env['HTTP_AUTHORIZATION'] = ActionController::HttpAuthentication::Basic.encode_credentials(email, password)
end
def stub_symlink_methods
@@ -46,8 +49,9 @@ def stub_symlink_methods
end
Resque.inline = true
-APP_CONFIG['root_path'] = "#{Rails.root}/tmp/test_root"
-APP_CONFIG['git_path'] = "#{Rails.root}/tmp/test_root"
+APP_CONFIG['root_path'] = "#{Rails.root}/tmp/test_root"
+APP_CONFIG['git_path'] = "#{Rails.root}/tmp/test_root"
+APP_CONFIG['tmpfs_path'] = "#{Rails.root}/tmp/test_root"
def init_test_root
clear_test_root
@@ -64,8 +68,6 @@ def stub_redis
stub(Resque).redis { @redis_instance }
end
-init_test_root
-
def fill_project project
%x(mkdir -p #{project.path} && cp -Rf #{Rails.root}/spec/tests.git/* #{project.path}) # maybe FIXME ?
end
diff --git a/travis.sh b/travis.sh
new file mode 100755
index 000000000..663004ebf
--- /dev/null
+++ b/travis.sh
@@ -0,0 +1,20 @@
+#!/bin/bash -e
+
+rspec="bundle exec rspec"
+
+if [ $SPEC_GROUP = 'controllers' ]
+then
+ $rspec spec/controllers/*_spec.rb spec/controllers/admin/ spec/controllers/groups/ spec/controllers/projects/ spec/controllers/users/
+elif [ $SPEC_GROUP = 'platform_controllers' ]
+then
+ $rspec spec/controllers/platforms/
+elif [ $SPEC_GROUP = 'api' ]
+then
+ $rspec spec/controllers/api/
+elif [ $SPEC_GROUP = 'models' ]
+then
+ $rspec spec/models/
+elif [ $SPEC_GROUP = 'others' ]
+then
+ $rspec spec/helpers/ spec/integration/ spec/lib/ spec/mailers/ spec/mailers/ spec/routing/
+fi
diff --git a/vendor/assets/audios/garbage_shattering.wav b/vendor/assets/audios/garbage_shattering.wav
new file mode 100644
index 000000000..9953752ad
Binary files /dev/null and b/vendor/assets/audios/garbage_shattering.wav differ
diff --git a/vendor/assets/javascripts/moment/ru.js b/vendor/assets/javascripts/moment/ru.js
new file mode 100644
index 000000000..ce93b6375
--- /dev/null
+++ b/vendor/assets/javascripts/moment/ru.js
@@ -0,0 +1,125 @@
+// moment.js language configuration
+// language : russian (ru)
+// author : Viktorminator : https://github.com/Viktorminator
+// Author : Menelion Elensúle : https://github.com/Oire
+
+function plural(word, num) {
+ var forms = word.split('_');
+ return num % 10 === 1 && num % 100 !== 11 ? forms[0] : (num % 10 >= 2 && num % 10 <= 4 && (num % 100 < 10 || num % 100 >= 20) ? forms[1] : forms[2]);
+}
+
+function relativeTimeWithPlural(number, withoutSuffix, key) {
+ var format = {
+ 'mm': 'минута_минуты_минут',
+ 'hh': 'час_часа_часов',
+ 'dd': 'день_дня_дней',
+ 'MM': 'месяц_месяца_месяцев',
+ 'yy': 'год_года_лет'
+ };
+ if (key === 'm') {
+ return withoutSuffix ? 'минута' : 'минуту';
+ }
+ else {
+ return number + ' ' + plural(format[key], +number);
+ }
+}
+
+function monthsCaseReplace(m, format) {
+ var months = {
+ 'nominative': 'январь_февраль_март_апрель_май_июнь_июль_август_сентябрь_октябрь_ноябрь_декабрь'.split('_'),
+ 'accusative': 'января_февраля_марта_апреля_мая_июня_июля_августа_сентября_октября_ноября_декабря'.split('_')
+ },
+
+ nounCase = (/D[oD]? *MMMM?/).test(format) ?
+ 'accusative' :
+ 'nominative';
+
+ return months[nounCase][m.month()];
+}
+
+function weekdaysCaseReplace(m, format) {
+ var weekdays = {
+ 'nominative': 'воскресенье_понедельник_вторник_среда_четверг_пятница_суббота'.split('_'),
+ 'accusative': 'воскресенье_понедельник_вторник_среду_четверг_пятницу_субботу'.split('_')
+ },
+
+ nounCase = (/\[ ?[Вв] ?(?:прошлую|следующую)? ?\] ?dddd/).test(format) ?
+ 'accusative' :
+ 'nominative';
+
+ return weekdays[nounCase][m.day()];
+}
+
+moment.lang('ru', {
+ months : monthsCaseReplace,
+ monthsShort : "янв_фев_мар_апр_май_июн_июл_авг_сен_окт_ноя_дек".split("_"),
+ weekdays : weekdaysCaseReplace,
+ weekdaysShort : "вск_пнд_втр_срд_чтв_птн_сбт".split("_"),
+ weekdaysMin : "вс_пн_вт_ср_чт_пт_сб".split("_"),
+ longDateFormat : {
+ LT : "HH:mm",
+ L : "DD.MM.YYYY",
+ LL : "D MMMM YYYY г.",
+ LLL : "D MMMM YYYY г., LT",
+ LLLL : "dddd, D MMMM YYYY г., LT"
+ },
+ calendar : {
+ sameDay: '[Сегодня в] LT',
+ nextDay: '[Завтра в] LT',
+ lastDay: '[Вчера в] LT',
+ nextWeek: function () {
+ return this.day() === 2 ? '[Во] dddd [в] LT' : '[В] dddd [в] LT';
+ },
+ lastWeek: function () {
+ switch (this.day()) {
+ case 0:
+ return '[В прошлое] dddd [в] LT';
+ case 1:
+ case 2:
+ case 4:
+ return '[В прошлый] dddd [в] LT';
+ case 3:
+ case 5:
+ case 6:
+ return '[В прошлую] dddd [в] LT';
+ }
+ },
+ sameElse: 'L'
+ },
+ relativeTime : {
+ future : "через %s",
+ past : "%s назад",
+ s : "несколько секунд",
+ m : relativeTimeWithPlural,
+ mm : relativeTimeWithPlural,
+ h : "час",
+ hh : relativeTimeWithPlural,
+ d : "день",
+ dd : relativeTimeWithPlural,
+ M : "месяц",
+ MM : relativeTimeWithPlural,
+ y : "год",
+ yy : relativeTimeWithPlural
+ },
+
+ ordinal: function (number, period) {
+ switch (period) {
+ case 'M':
+ case 'd':
+ case 'DDD':
+ return number + '-й';
+ case 'D':
+ return number + '-го';
+ case 'w':
+ case 'W':
+ return number + '-я';
+ default:
+ return number;
+ }
+ },
+
+ week : {
+ dow : 1, // Monday is the first day of the week.
+ doy : 7 // The week that contains Jan 1st is the first week of the year.
+ }
+});
diff --git a/vendor/assets/stylesheets/bootstrap.css b/vendor/assets/stylesheets/bootstrap.css
index 27a4aa4bf..2a171d492 100644
--- a/vendor/assets/stylesheets/bootstrap.css
+++ b/vendor/assets/stylesheets/bootstrap.css
@@ -840,4 +840,297 @@ a.badge:hover {
}
.icon-remove-circle {
background-position: -168px -96px;
-}
\ No newline at end of file
+}
+.hide-text {
+ font: 0/0 a;
+ color: transparent;
+ text-shadow: none;
+ background-color: transparent;
+ border: 0;
+}
+.input-block-level {
+ display: block;
+ width: 100%;
+ min-height: 30px;
+ -webkit-box-sizing: border-box;
+ -moz-box-sizing: border-box;
+ box-sizing: border-box;
+}
+.row {
+ margin-left: -20px;
+ *zoom: 1;
+}
+.row:before,
+.row:after {
+ display: table;
+ content: "";
+ line-height: 0;
+}
+.row:after {
+ clear: both;
+}
+[class*="span"] {
+ float: left;
+ min-height: 1px;
+ margin-left: 20px;
+}
+.container,
+.navbar-static-top .container,
+.navbar-fixed-top .container,
+.navbar-fixed-bottom .container {
+ width: 940px;
+}
+.span12 {
+ width: 940px;
+}
+.span11 {
+ width: 860px;
+}
+.span10 {
+ width: 780px;
+}
+.span9 {
+ width: 700px;
+}
+.span8 {
+ width: 620px;
+}
+.span7 {
+ width: 540px;
+}
+.span6 {
+ width: 460px;
+}
+.span5 {
+ width: 380px;
+}
+.span4 {
+ width: 300px;
+}
+.span3 {
+ width: 220px;
+}
+.span2 {
+ width: 140px;
+}
+.span1 {
+ width: 60px;
+}
+.offset12 {
+ margin-left: 980px;
+}
+.offset11 {
+ margin-left: 900px;
+}
+.offset10 {
+ margin-left: 820px;
+}
+.offset9 {
+ margin-left: 740px;
+}
+.offset8 {
+ margin-left: 660px;
+}
+.offset7 {
+ margin-left: 580px;
+}
+.offset6 {
+ margin-left: 500px;
+}
+.offset5 {
+ margin-left: 420px;
+}
+.offset4 {
+ margin-left: 340px;
+}
+.offset3 {
+ margin-left: 260px;
+}
+.offset2 {
+ margin-left: 180px;
+}
+.offset1 {
+ margin-left: 100px;
+}
+.row-fluid {
+ width: 100%;
+ *zoom: 1;
+}
+.row-fluid:before,
+.row-fluid:after {
+ display: table;
+ content: "";
+ line-height: 0;
+}
+.row-fluid:after {
+ clear: both;
+}
+.row-fluid [class*="span"] {
+ display: block;
+ width: 100%;
+ min-height: 30px;
+ -webkit-box-sizing: border-box;
+ -moz-box-sizing: border-box;
+ box-sizing: border-box;
+ float: left;
+ margin-left: 2.127659574468085%;
+ *margin-left: 2.074468085106383%;
+}
+.row-fluid [class*="span"]:first-child {
+ margin-left: 0;
+}
+.row-fluid .controls-row [class*="span"] + [class*="span"] {
+ margin-left: 2.127659574468085%;
+}
+.row-fluid .span12 {
+ width: 100%;
+ *width: 99.94680851063829%;
+}
+.row-fluid .span11 {
+ width: 91.48936170212765%;
+ *width: 91.43617021276594%;
+}
+.row-fluid .span10 {
+ width: 82.97872340425532%;
+ *width: 82.92553191489361%;
+}
+.row-fluid .span9 {
+ width: 74.46808510638297%;
+ *width: 74.41489361702126%;
+}
+.row-fluid .span8 {
+ width: 65.95744680851064%;
+ *width: 65.90425531914893%;
+}
+.row-fluid .span7 {
+ width: 57.44680851063829%;
+ *width: 57.39361702127659%;
+}
+.row-fluid .span6 {
+ width: 48.93617021276595%;
+ *width: 48.88297872340425%;
+}
+.row-fluid .span5 {
+ width: 40.42553191489362%;
+ *width: 40.37234042553192%;
+}
+.row-fluid .span4 {
+ width: 31.914893617021278%;
+ *width: 31.861702127659576%;
+}
+.row-fluid .span3 {
+ width: 23.404255319148934%;
+ *width: 23.351063829787233%;
+}
+.row-fluid .span2 {
+ width: 14.893617021276595%;
+ *width: 14.840425531914894%;
+}
+.row-fluid .span1 {
+ width: 6.382978723404255%;
+ *width: 6.329787234042553%;
+}
+.row-fluid .offset12 {
+ margin-left: 104.25531914893617%;
+ *margin-left: 104.14893617021275%;
+}
+.row-fluid .offset12:first-child {
+ margin-left: 102.12765957446808%;
+ *margin-left: 102.02127659574467%;
+}
+.row-fluid .offset11 {
+ margin-left: 95.74468085106382%;
+ *margin-left: 95.6382978723404%;
+}
+.row-fluid .offset11:first-child {
+ margin-left: 93.61702127659574%;
+ *margin-left: 93.51063829787232%;
+}
+.row-fluid .offset10 {
+ margin-left: 87.23404255319149%;
+ *margin-left: 87.12765957446807%;
+}
+.row-fluid .offset10:first-child {
+ margin-left: 85.1063829787234%;
+ *margin-left: 84.99999999999999%;
+}
+.row-fluid .offset9 {
+ margin-left: 78.72340425531914%;
+ *margin-left: 78.61702127659572%;
+}
+.row-fluid .offset9:first-child {
+ margin-left: 76.59574468085106%;
+ *margin-left: 76.48936170212764%;
+}
+.row-fluid .offset8 {
+ margin-left: 70.2127659574468%;
+ *margin-left: 70.10638297872339%;
+}
+.row-fluid .offset8:first-child {
+ margin-left: 68.08510638297872%;
+ *margin-left: 67.9787234042553%;
+}
+.row-fluid .offset7 {
+ margin-left: 61.70212765957446%;
+ *margin-left: 61.59574468085106%;
+}
+.row-fluid .offset7:first-child {
+ margin-left: 59.574468085106375%;
+ *margin-left: 59.46808510638297%;
+}
+.row-fluid .offset6 {
+ margin-left: 53.191489361702125%;
+ *margin-left: 53.085106382978715%;
+}
+.row-fluid .offset6:first-child {
+ margin-left: 51.063829787234035%;
+ *margin-left: 50.95744680851063%;
+}
+.row-fluid .offset5 {
+ margin-left: 44.68085106382979%;
+ *margin-left: 44.57446808510638%;
+}
+.row-fluid .offset5:first-child {
+ margin-left: 42.5531914893617%;
+ *margin-left: 42.4468085106383%;
+}
+.row-fluid .offset4 {
+ margin-left: 36.170212765957444%;
+ *margin-left: 36.06382978723405%;
+}
+.row-fluid .offset4:first-child {
+ margin-left: 34.04255319148936%;
+ *margin-left: 33.93617021276596%;
+}
+.row-fluid .offset3 {
+ margin-left: 27.659574468085104%;
+ *margin-left: 27.5531914893617%;
+}
+.row-fluid .offset3:first-child {
+ margin-left: 25.53191489361702%;
+ *margin-left: 25.425531914893618%;
+}
+.row-fluid .offset2 {
+ margin-left: 19.148936170212764%;
+ *margin-left: 19.04255319148936%;
+}
+.row-fluid .offset2:first-child {
+ margin-left: 17.02127659574468%;
+ *margin-left: 16.914893617021278%;
+}
+.row-fluid .offset1 {
+ margin-left: 10.638297872340425%;
+ *margin-left: 10.53191489361702%;
+}
+.row-fluid .offset1:first-child {
+ margin-left: 8.51063829787234%;
+ *margin-left: 8.404255319148938%;
+}
+[class*="span"].hide,
+.row-fluid [class*="span"].hide {
+ display: none;
+}
+[class*="span"].pull-right,
+.row-fluid [class*="span"].pull-right {
+ float: right;
+}