#34: merge master into branch

This commit is contained in:
Vokhmin Alexey V 2013-04-25 15:36:00 +04:00
commit 4c96629a28
45 changed files with 726 additions and 490 deletions

View File

@ -2,8 +2,6 @@ ROSA ABF is Copyright 2010-2013 ROSA CJSC.
ROSA CJSC ("ROSA") distributes the ABF source code under the GNU General Public License (GPL), version 2.0 or later.
The image and icon files in ABF are copyright ROSA CJSC ("ROSA"), but unlike the source code they are not licensed under the GPL version 2.0 or later. ROSA grants you the right to use them for testing and development purposes only, but not to use them in production (commercially or non-commercially).
Third-party copyright in this distribution is noted where applicable.
All rights not expressly granted are reserved.

256
README
View File

@ -1,256 +0,0 @@
== Welcome to Rails
Rails is a web-application framework that includes everything needed to create
database-backed web applications according to the Model-View-Control pattern.
This pattern splits the view (also called the presentation) into "dumb"
templates that are primarily responsible for inserting pre-built data in between
HTML tags. The model contains the "smart" domain objects (such as Account,
Product, Person, Post) that holds all the business logic and knows how to
persist themselves to a database. The controller handles the incoming requests
(such as Save New Account, Update Product, Show Post) by manipulating the model
and directing data to the view.
In Rails, the model is handled by what's called an object-relational mapping
layer entitled Active Record. This layer allows you to present the data from
database rows as objects and embellish these data objects with business logic
methods. You can read more about Active Record in
link:files/vendor/rails/activerecord/README.html.
The controller and view are handled by the Action Pack, which handles both
layers by its two parts: Action View and Action Controller. These two layers
are bundled in a single package due to their heavy interdependence. This is
unlike the relationship between the Active Record and Action Pack that is much
more separate. Each of these packages can be used independently outside of
Rails. You can read more about Action Pack in
link:files/vendor/rails/actionpack/README.html.
== Getting Started
1. At the command prompt, create a new Rails application:
<tt>rails new myapp</tt> (where <tt>myapp</tt> is the application name)
2. Change directory to <tt>myapp</tt> and start the web server:
<tt>cd myapp; rails server</tt> (run with --help for options)
3. Go to http://localhost:3000/ and you'll see:
"Welcome aboard: You're riding Ruby on Rails!"
4. Follow the guidelines to start developing your application. You can find
the following resources handy:
* The Getting Started Guide: http://guides.rubyonrails.org/getting_started.html
* Ruby on Rails Tutorial Book: http://www.railstutorial.org/
== Debugging Rails
Sometimes your application goes wrong. Fortunately there are a lot of tools that
will help you debug it and get it back on the rails.
First area to check is the application log files. Have "tail -f" commands
running on the server.log and development.log. Rails will automatically display
debugging and runtime information to these files. Debugging info will also be
shown in the browser on requests from 127.0.0.1.
You can also log your own messages directly into the log file from your code
using the Ruby logger class from inside your controllers. Example:
class WeblogController < ActionController::Base
def destroy
@weblog = Weblog.find(params[:id])
@weblog.destroy
logger.info("#{Time.now} Destroyed Weblog ID ##{@weblog.id}!")
end
end
The result will be a message in your log file along the lines of:
Mon Oct 08 14:22:29 +1000 2007 Destroyed Weblog ID #1!
More information on how to use the logger is at http://www.ruby-doc.org/core/
Also, Ruby documentation can be found at http://www.ruby-lang.org/. There are
several books available online as well:
* Programming Ruby: http://www.ruby-doc.org/docs/ProgrammingRuby/ (Pickaxe)
* Learn to Program: http://pine.fm/LearnToProgram/ (a beginners guide)
These two books will bring you up to speed on the Ruby language and also on
programming in general.
== Debugger
Debugger support is available through the debugger command when you start your
Mongrel or WEBrick server with --debugger. This means that you can break out of
execution at any point in the code, investigate and change the model, and then,
resume execution! You need to install ruby-debug to run the server in debugging
mode. With gems, use <tt>sudo gem install ruby-debug</tt>. Example:
class WeblogController < ActionController::Base
def index
@posts = Post.find(:all)
debugger
end
end
So the controller will accept the action, run the first line, then present you
with a IRB prompt in the server window. Here you can do things like:
>> @posts.inspect
=> "[#<Post:0x14a6be8
@attributes={"title"=>nil, "body"=>nil, "id"=>"1"}>,
#<Post:0x14a6620
@attributes={"title"=>"Rails", "body"=>"Only ten..", "id"=>"2"}>]"
>> @posts.first.title = "hello from a debugger"
=> "hello from a debugger"
...and even better, you can examine how your runtime objects actually work:
>> f = @posts.first
=> #<Post:0x13630c4 @attributes={"title"=>nil, "body"=>nil, "id"=>"1"}>
>> f.
Display all 152 possibilities? (y or n)
Finally, when you're ready to resume execution, you can enter "cont".
== Console
The console is a Ruby shell, which allows you to interact with your
application's domain model. Here you'll have all parts of the application
configured, just like it is when the application is running. You can inspect
domain models, change values, and save to the database. Starting the script
without arguments will launch it in the development environment.
To start the console, run <tt>rails console</tt> from the application
directory.
Options:
* Passing the <tt>-s, --sandbox</tt> argument will rollback any modifications
made to the database.
* Passing an environment name as an argument will load the corresponding
environment. Example: <tt>rails console production</tt>.
To reload your controllers and models after launching the console run
<tt>reload!</tt>
More information about irb can be found at:
link:http://www.rubycentral.com/pickaxe/irb.html
== dbconsole
You can go to the command line of your database directly through <tt>rails
dbconsole</tt>. You would be connected to the database with the credentials
defined in database.yml. Starting the script without arguments will connect you
to the development database. Passing an argument will connect you to a different
database, like <tt>rails dbconsole production</tt>. Currently works for MySQL,
PostgreSQL and SQLite 3.
== Description of Contents
The default directory structure of a generated Ruby on Rails application:
|-- app
| |-- controllers
| |-- helpers
| |-- mailers
| |-- models
| `-- views
| `-- layouts
|-- config
| |-- environments
| |-- initializers
| `-- locales
|-- db
|-- doc
|-- lib
| `-- tasks
|-- log
|-- public
| |-- images
| |-- javascripts
| `-- stylesheets
|-- script
|-- test
| |-- fixtures
| |-- functional
| |-- integration
| |-- performance
| `-- unit
|-- tmp
| |-- cache
| |-- pids
| |-- sessions
| `-- sockets
`-- vendor
`-- plugins
app
Holds all the code that's specific to this particular application.
app/controllers
Holds controllers that should be named like weblogs_controller.rb for
automated URL mapping. All controllers should descend from
ApplicationController which itself descends from ActionController::Base.
app/models
Holds models that should be named like post.rb. Models descend from
ActiveRecord::Base by default.
app/views
Holds the template files for the view that should be named like
weblogs/index.html.erb for the WeblogsController#index action. All views use
eRuby syntax by default.
app/views/layouts
Holds the template files for layouts to be used with views. This models the
common header/footer method of wrapping views. In your views, define a layout
using the <tt>layout :default</tt> and create a file named default.html.erb.
Inside default.html.erb, call <% yield %> to render the view using this
layout.
app/helpers
Holds view helpers that should be named like weblogs_helper.rb. These are
generated for you automatically when using generators for controllers.
Helpers can be used to wrap functionality for your views into methods.
config
Configuration files for the Rails environment, the routing map, the database,
and other dependencies.
db
Contains the database schema in schema.rb. db/migrate contains all the
sequence of Migrations for your schema.
doc
This directory is where your application documentation will be stored when
generated using <tt>rake doc:app</tt>
lib
Application specific libraries. Basically, any kind of custom code that
doesn't belong under controllers, models, or helpers. This directory is in
the load path.
public
The directory available for the web server. Contains subdirectories for
images, stylesheets, and javascripts. Also contains the dispatchers and the
default HTML files. This should be set as the DOCUMENT_ROOT of your web
server.
script
Helper scripts for automation and generation.
test
Unit and functional tests along with fixtures. When using the rails generate
command, template test files will be generated for you and placed in this
directory.
vendor
External libraries that the application depends on. Also includes the plugins
subdirectory. If the app has frozen rails, those gems also go here, under
vendor/rails/. This directory is in the load path.

13
README.md Normal file
View File

@ -0,0 +1,13 @@
RosaLab ABF
===========
A distributed environment to build distributions, supporting all steps from managing source code to creating ISO images. If you have any problems or requests please contact
[support](https://abf.rosalinux.ru/contact).
**Note: This Documentation is in a beta state. Breaking changes may occur.**
* [API](http://abf-doc.rosalinux.ru/abf/api/)
* [Integration with FileStore (.abf.yml)](http://abf-doc.rosalinux.ru/abf/file_store_integration/)
* [ISO build environment](http://abf-doc.rosalinux.ru/abf/iso_build/)
* [Package build environment](http://abf-doc.rosalinux.ru/abf/scripts/)
* [Deployment](http://abf-doc.rosalinux.ru/abf/deployment/)

View File

@ -0,0 +1,108 @@
# -*- encoding : utf-8 -*-
class Api::V1::IssuesController < Api::V1::BaseController
respond_to :json
before_filter :authenticate_user!
skip_before_filter :authenticate_user!, :only => [:show] if APP_CONFIG['anonymous_access']
load_and_authorize_resource :group, :only => :group_index
load_resource :project
load_and_authorize_resource :issue, :through => :project, :find_by => :serial_id, :only => [:show, :update, :destroy, :create, :index]
def index
@issues = @project.issues
render_issues_list
end
def all_index
project_ids = get_all_project_ids Project.accessible_by(current_ability, :membered).uniq.pluck(:id)
@issues = Issue.where('issues.project_id IN (?)', project_ids)
render_issues_list
end
def user_index
project_ids = get_all_project_ids current_user.projects.select('distinct projects.id').pluck(:id)
@issues = Issue.where('issues.project_id IN (?)', project_ids)
render_issues_list
end
def group_index
project_ids = @group.projects.select('distinct projects.id').pluck(:id)
@issues = Issue.where(:project_id => project_ids)
render_issues_list
end
def show
respond_with @issue
end
def create
@issue.user = current_user
create_subject @issue
end
def update
update_subject @issue
end
def destroy
destroy_subject @issue
end
private
def render_issues_list
@issues = @issues.includes(:user, :assignee, :labels).without_pull_requests
if params[:status] == 'closed'
@issues = @issues.closed
else
@issues = @issues.opened
end
if action_name == 'index' && params[:assignee].present?
case params[:assignee]
when 'none'
@issues = @issues.where(:assigned_id => nil)
when '*'
@issues = @issues.where('assigned_id IS NOT NULL')
else
@issues = @issues.where('assignees_issues.uname = ?', params[:assignee])
end
end
if %w[all_index user_index group_index].include?(action_name)
case params[:filter]
when 'created'
@issues = @issues.where(:user_id => current_user)
when 'all'
else
@issues = @issues.where(:assignee_id => current_user)
end
else
@issues.where('users.uname = ?', params[:creator]) if params[:creator].present?
end
if params[:labels].present?
labels = params[:labels].split(',').map {|e| e.strip}.select {|e| e.present?}
@issues = @issues.where('labels.name IN (?)', labels)
end
sort = params[:sort] == 'updated' ? 'issues.updated_at' : 'issues.created_at'
direction = params[:direction] == 'asc' ? 'ASC' : 'DESC'
@issues = @issues.order("#{sort} #{direction}")
@issues = @issues.where('created_at >= to_timestamp(?)', params[:since]) if params[:since] =~ /\A\d+\z/
@issues.paginate(paginate_params)
respond_with @issues
end
def get_all_project_ids default_project_ids
project_ids = []
if ['created', 'all'].include? params[:filter]
# add own issues
project_ids = Project.accessible_by(current_ability, :show).joins(:issues).
where(:issues => {:user_id => current_user.id}).uniq.pluck('projects.id')
end
project_ids |= default_project_ids
end
end

View File

@ -72,7 +72,7 @@ class Projects::ProjectsController < Projects::BaseController
redirect_to forked, :notice => t("flash.project.forked")
else
flash[:warning] = t("flash.project.fork_error")
flash[:error] = forked.errors.full_messages
flash[:error] = forked.errors.full_messages.join("\n")
redirect_to @project
end
end

View File

@ -115,9 +115,12 @@ class Projects::PullRequestsController < Projects::BaseController
end
def autocomplete_to_project
items = Project.accessible_by(current_ability, :membered) | @project.ancestors
term = Regexp.new(Regexp.escape params[:term].downcase)
items.select! {|e| term.match(e.name_with_owner.downcase) && e.repo.branches.count > 0}
items = []
term = params[:term].to_s.strip.downcase
[Project.accessible_by(current_ability, :membered), @project.ancestors].each do |p|
items.concat p.by_owner_and_name(term)
end
items = items.uniq{|i| i.id}.select{|e| e.repo.branches.count > 0}
render :json => json_for_autocomplete_base(items)
end
@ -129,7 +132,7 @@ class Projects::PullRequestsController < Projects::BaseController
def json_for_autocomplete_base items
items.collect do |project|
hash = {"id" => project.id.to_s, "label" => project.name_with_owner, "value" => project.name_with_owner}
hash = {:id => project.id.to_s, :label => project.name_with_owner, :value => project.name_with_owner}
hash[:get_refs_url] = project_refs_list_path(project)
hash
end

View File

@ -148,7 +148,8 @@ class Ability
# Shared cannot rights for all users (registered, admin)
cannot :destroy, Platform, :platform_type => 'personal'
cannot [:create, :destroy, :edit, :update, :add_project, :remove_project], Repository, :platform => {:platform_type => 'personal'}
cannot [:create, :destroy], Repository, :platform => {:platform_type => 'personal'}, :name => 'main'
cannot [:remove_members, :remove_member, :add_member], Repository, :platform => {:platform_type => 'personal'}
cannot :clear, Platform, :platform_type => 'main'
cannot :destroy, Issue

View File

@ -110,6 +110,7 @@ class Collaborator
def destroy
relation.try(:destroy)
@actor.check_assigned_issues @project
end
def attributes

View File

@ -142,6 +142,7 @@ class Comment < ActiveRecord::Base
case
when item.is_a?(GitHook)
elements = commits
opts = {}
when item.is_a?(Issue)
elements = [[item, item.title], [item, item.body]]
opts = {:created_from_issue_id => item.id}

View File

@ -21,9 +21,7 @@ class KeyPair < ActiveRecord::Base
protected
def check_keys
tmp = "#{APP_CONFIG['root_path']}/tmp"
system "sudo chown `whoami` #{tmp} && chmod 1777 #{tmp}"
dir = Dir.mktmpdir('keys-', tmp)
dir = Dir.mktmpdir('keys-', '/tmp')
begin
%w(pubring secring).each do |kind|
filename = "#{dir}/#{kind}"

View File

@ -19,7 +19,6 @@ class Platform < ActiveRecord::Base
has_many :mass_builds
validates :description, :presence => true
validates :owner, :presence => true
validates :visibility, :presence => true, :inclusion => {:in => VISIBILITIES}
validates :name, :uniqueness => {:case_sensitive => false}, :presence => true, :format => { :with => /\A[a-zA-Z0-9_\-\.]+\z/ }
validates :distrib_type, :presence => true, :inclusion => {:in => APP_CONFIG['distr_types']}

View File

@ -29,11 +29,18 @@ class Project < ActiveRecord::Base
validates :name, :uniqueness => {:scope => [:owner_id, :owner_type], :case_sensitive => false},
:presence => true,
:format => {:with => /\A#{NAME_REGEXP}\z/, :message => I18n.t("activerecord.errors.project.uname")}
validates :owner, :presence => true
validates :maintainer_id, :presence => true, :unless => :new_record?
validates :visibility, :presence => true, :inclusion => {:in => VISIBILITIES}
validate { errors.add(:base, :can_have_less_or_equal, :count => MAX_OWN_PROJECTS) if owner.projects.size >= MAX_OWN_PROJECTS }
validate :check_default_branch
# throws validation error message from ProjectToRepository model into Project model
validate do |project|
project.project_to_repositories.each do |p_to_r|
next if p_to_r.valid?
p_to_r.errors.full_messages.each{ |msg| errors[:base] << msg }
end
errors.delete :project_to_repositories
end
attr_accessible :name, :description, :visibility, :srpm, :is_package, :default_branch, :has_issues, :has_wiki, :maintainer_id, :publish_i686_into_x86_64
attr_readonly :name, :owner_id, :owner_type
@ -42,6 +49,10 @@ class Project < ActiveRecord::Base
scope :search_order, order("CHAR_LENGTH(#{table_name}.name) ASC")
scope :search, lambda {|q| by_name("%#{q.to_s.strip}%")}
scope :by_name, lambda {|name| where("#{table_name}.name ILIKE ?", name) if name.present?}
scope :by_owner_and_name, lambda { |*params|
term = params.map(&:strip).join('/').downcase
where("lower(concat(owner_uname, '/', name)) ILIKE ?", "%#{term}%") if term.present?
}
scope :by_visibilities, lambda {|v| where(:visibility => v)}
scope :opened, where(:visibility => 'open')
scope :package, where(:is_package => true)
@ -59,6 +70,7 @@ class Project < ActiveRecord::Base
}
before_validation :truncate_name, :on => :create
before_save lambda { self.owner_uname = owner.uname if owner_uname.blank? || owner_id_changed? || owner_type_changed? }
before_create :set_maintainer
after_save :attach_to_personal_repository
after_update :set_new_git_head
@ -71,10 +83,8 @@ class Project < ActiveRecord::Base
class << self
def find_by_owner_and_name(owner_name, project_name)
owner = User.find_by_uname(owner_name) || Group.find_by_uname(owner_name) || User.by_uname(owner_name).first || Group.by_uname(owner_name).first and
scoped = where(:owner_id => owner.id, :owner_type => owner.class) and
scoped.find_by_name(project_name) || scoped.by_name(project_name).first
# owner.projects.find_by_name(project_name) || owner.projects.by_name(project_name).first # TODO force this work?
where(:owner_uname => owner_name, :name => project_name).first ||
by_owner_and_name(owner_name, project_name).first
end
def find_by_owner_and_name!(owner_name, project_name)
@ -82,6 +92,10 @@ class Project < ActiveRecord::Base
end
end
def name_with_owner
"#{owner_uname || owner.uname}/#{name}"
end
def to_param
name
end
@ -255,11 +269,11 @@ class Project < ActiveRecord::Base
end
def attach_to_personal_repository
owner_rep = self.owner.personal_repository
owner_repos = self.owner.personal_platform.repositories
if is_package
repositories << owner_rep unless repositories.exists?(:id => owner_rep)
repositories << self.owner.personal_repository unless repositories.exists?(:id => owner_repos.pluck(:id))
else
repositories.delete owner_rep
repositories.delete owner_repos
end
end

View File

@ -7,12 +7,12 @@ class ProjectToRepository < ActiveRecord::Base
after_destroy lambda { project.destroy_project_from_repository(repository) }, :unless => lambda {Thread.current[:skip]}
validate :one_project_in_platform_repositories
validate :one_project_in_platform_repositories, :on => :create
protected
def one_project_in_platform_repositories
errors.add(:project, 'should be one in platform') if Project.joins(:repositories => :platform).
where('platforms.id = ?', repository.platform_id).by_name(project.name).count > 0
errors.add(:base, I18n.t('activerecord.errors.project_to_repository.project')) if Project.joins(:repositories => :platform).
where('platforms.id = ?', repository.platform_id).by_name(project.name).exists?
end
end

View File

@ -34,7 +34,11 @@ class Relation < ActiveRecord::Base
def self.remove_member(member, target)
return false if target.respond_to?(:owner) && target.owner == member
Relation.by_actor(member).by_target(target).each{|r| r.destroy}
res = Relation.by_actor(member).by_target(target).each{|r| r.destroy}
if member.is_a?(User) && ['Project', 'Group'].include?(target.class.name)
member.check_assigned_issues target
end
res
end
protected

View File

@ -17,7 +17,7 @@ class Repository < ActiveRecord::Base
scope :recent, order("#{table_name}.name ASC")
before_destroy :detele_directory, :unless => lambda {Thread.current[:skip]}
before_destroy :detele_directory
attr_accessible :name, :description, :publish_without_qa
attr_readonly :name, :platform_id

View File

@ -22,7 +22,7 @@ class SshKey < ActiveRecord::Base
def set_fingerprint
return false unless key
file = Tempfile.new('key_file', "#{APP_CONFIG['root_path']}/tmp")
file = Tempfile.new('key_file', '/tmp')
filename = file.path
begin
file.puts key

View File

@ -28,6 +28,7 @@ class User < Avatar
has_many :own_projects, :as => :owner, :class_name => 'Project', :dependent => :destroy
has_many :own_groups, :foreign_key => :owner_id, :class_name => 'Group', :dependent => :destroy
has_many :own_platforms, :as => :owner, :class_name => 'Platform', :dependent => :destroy
has_many :assigned_issues, :foreign_key => :assignee_id, :class_name => 'Issue', :dependent => :nullify
has_many :key_pairs
has_many :ssh_keys, :dependent => :destroy
@ -141,6 +142,19 @@ class User < Avatar
raise "unknown user #{self.uname} roles #{roles}"
end
def check_assigned_issues target
if target.is_a? Project
assigned_issues.where(:project_id => target.id).update_all(:assignee_id => nil)
else
ability = Ability.new self
project_ids = Project.accessible_by(ability, :membered).uniq.pluck(:id)
issues = assigned_issues
issues = issues.where('project_id not in (?)', project_ids) if project_ids.present?
issues.update_all(:assignee_id => nil)
end
end
protected
def target_roles target

View File

@ -0,0 +1,11 @@
json.number issue.serial_id
json.(issue, :title, :status)
json.labels issue.labels do |json_labels, label|
json.partial! 'label', :label => label, :json => json_labels
end
json.assignee do |json_assignee|
json.partial! 'api/v1/shared/member', :member => issue.assignee, :tag => json_assignee
end if issue.assignee
json.url api_v1_project_issue_path(issue.project.id, issue.serial_id, :format => :json)

View File

@ -0,0 +1 @@
json.(label, :name, :color)

View File

@ -0,0 +1,11 @@
json.issues @issues do |json, issue|
json.partial! 'issue', :issue => issue, :json => json
json.issue issue.body
json.partial! 'api/v1/shared/owner', :owner => issue.user
json.closed_at issue.closed_at.to_i
json.closed_by do |json_user|
json.partial! 'api/v1/shared/member', :member => issue.closer, :tag => json_user
end if issue.closer
json.created_at issue.created_at.to_i
json.updated_at issue.updated_at.to_i
end

View File

@ -0,0 +1,11 @@
json.issue do |json|
json.partial! 'issue', :issue => @issue, :json => json
json.issue @issue.body
json.partial! 'api/v1/shared/owner', :owner => @issue.user
json.closed_at @issue.closed_at.to_i
json.closed_by do |json_user|
json.partial! 'api/v1/shared/member', :member => @issue.closer, :tag => json_user
end if @issue.closer
json.created_at @issue.created_at.to_i
json.updated_at @issue.updated_at.to_i
end

View File

@ -1,5 +1,3 @@
= render 'platforms/base/sidebar'
%h3= t("layout.key_pairs.header")
= form_for :key_pair, :url => platform_key_pairs_path(@platform), :method => :post, :html => { :class => :form } do |f|

View File

@ -1,2 +1,6 @@
- set_meta_tags :title => [title_object(@platform), t('layout.key_pairs.header')]
= render 'platforms/base/submenu'
= render 'platforms/base/sidebar'
= render 'new' if can? :edit, @platform
= render 'list'

View File

@ -15,7 +15,7 @@
.rightside
= link_to t('layout.repositories.regenerate_metadata').split.first, regenerate_metadata_platform_repository_path(@platform, @repository),
:method => :put, :confirm => t('layout.confirm'), :class => :button
.hr{:style => 'padding-bottom:20px;'}
.hr{:style => 'padding-bottom:20px;'}
.both
.button_block

View File

@ -8,9 +8,10 @@
= render "form", :f => f
%br
= render "shared/members_table",
:remove_members_path => remove_members_platform_repository_path(@platform, @repository),
:remove_member_path => remove_member_platform_repository_path(@platform, @repository),
:add_member_path => add_member_platform_repository_path(@platform, @repository),
:members => @members,
:editable_object => @repository
- if @platform.main?
= render "shared/members_table",
:remove_members_path => remove_members_platform_repository_path(@platform, @repository),
:remove_member_path => remove_member_platform_repository_path(@platform, @repository),
:add_member_path => add_member_platform_repository_path(@platform, @repository),
:members => @members,
:editable_object => @repository

View File

@ -14,5 +14,5 @@
- Group.can_own_project(current_user).each do |group|
=render 'choose_fork', :owner => group
%hr.bootstrap
- if can? :create, @project.build_lists.new
- if @project.is_package && can?(:create, @project.build_lists.new)
.r{:style => "display: block"}= link_to t('layout.projects.new_build_list'), new_project_build_list_path(@project), :class => 'button'

View File

@ -0,0 +1,5 @@
en:
activerecord:
errors:
project_to_repository:
project: Project already exists in platform

View File

@ -0,0 +1,5 @@
ru:
activerecord:
errors:
project_to_repository:
project: Проект уже присутствует в платформе

View File

@ -36,7 +36,7 @@ en:
update_error: Unable to update repository
destroyed: Repository deleted
project_added: Project added to repository
project_not_added: Project adding error. A project with such name already exists in this repository. Remove the old project first
project_not_added: Project adding error. A project with such name already exists in one repository of platform. Remove the old project first
project_removed: Project deleted
project_not_removed: Unable to delete project from repository
clear: Platform successfully cleared!

View File

@ -36,7 +36,7 @@ ru:
update_error: Не удалось обновить репозиторий
destroyed: Репозиторий успешно удален
project_added: Проект добавлен к репозиторию
project_not_added: Не удалось добавить проект. В этом репозитории уже есть проект с таким именем. Сначала нужно удалить старый проект
project_not_added: Не удалось добавить проект. В одном из репозиториев платформы уже есть проект с таким именем. Сначала нужно удалить старый проект
project_removed: Проект удален из репозитория
project_not_removed: Не удалось удалить проект из репозитория
clear: Платформа успешно очищена!

View File

@ -58,6 +58,7 @@ Rosa::Application.routes.draw do
put :update_member
}
resources :build_lists, :only => :index
resources :issues, :only => [:index, :create, :show, :update]
end
resources :users, :only => [:show]
get 'user' => 'users#show_current_user'
@ -65,6 +66,7 @@ Rosa::Application.routes.draw do
member {
get :notifiers
put :notifiers
get '/issues' => 'issues#user_index'
}
end
resources :groups, :only => [:index, :show, :update, :create, :destroy] do
@ -73,6 +75,7 @@ Rosa::Application.routes.draw do
put :add_member
delete :remove_member
put :update_member
get '/issues' => 'issues#group_index'
}
end
resources :products, :only => [:show, :update, :create, :destroy] do
@ -82,6 +85,7 @@ Rosa::Application.routes.draw do
put :cancel, :on => :member
end
#resources :ssh_keys, :only => [:index, :create, :destroy]
get 'issues' => 'issues#all_index'
end
end

View File

@ -0,0 +1,22 @@
class AddNameWithOwnerToProject < ActiveRecord::Migration
def up
add_column :projects, :owner_uname, :string
execute <<-SQL
UPDATE projects SET owner_uname = owners.uname
FROM users as owners
WHERE projects.owner_type = 'User' AND projects.owner_id = owners.id
SQL
execute <<-SQL
UPDATE projects SET owner_uname = owners.uname
FROM groups as owners
WHERE projects.owner_type = 'Group' AND projects.owner_id = owners.id
SQL
change_column :projects, :owner_uname, :string, :null => false
end
def down
remove_column :projects, :owner_uname
end
end

View File

@ -0,0 +1,5 @@
class AddUserIndexToIssue < ActiveRecord::Migration
def change
add_index :issues, :user_id
end
end

View File

@ -11,14 +11,14 @@
#
# It's strongly recommended to check this file into your version control system.
ActiveRecord::Schema.define(:version => 20130412124536) do
ActiveRecord::Schema.define(:version => 20130417162427) do
create_table "activity_feeds", :force => true do |t|
t.integer "user_id", :null => false
t.string "kind"
t.text "data"
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
t.datetime "created_at"
t.datetime "updated_at"
end
create_table "advisories", :force => true do |t|
@ -53,8 +53,8 @@ ActiveRecord::Schema.define(:version => 20130412124536) do
create_table "arches", :force => true do |t|
t.string "name", :null => false
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
t.datetime "created_at"
t.datetime "updated_at"
end
add_index "arches", ["name"], :name => "index_arches_on_name", :unique => true
@ -63,8 +63,8 @@ ActiveRecord::Schema.define(:version => 20130412124536) do
t.integer "user_id"
t.string "provider"
t.string "uid"
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
t.datetime "created_at"
t.datetime "updated_at"
end
add_index "authentications", ["provider", "uid"], :name => "index_authentications_on_provider_and_uid", :unique => true
@ -75,8 +75,8 @@ ActiveRecord::Schema.define(:version => 20130412124536) do
t.integer "level"
t.integer "status"
t.integer "build_list_id"
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
t.datetime "created_at"
t.datetime "updated_at"
t.string "version"
end
@ -110,8 +110,8 @@ ActiveRecord::Schema.define(:version => 20130412124536) do
t.integer "project_id"
t.integer "arch_id"
t.datetime "notified_at"
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
t.datetime "created_at"
t.datetime "updated_at"
t.boolean "is_circle", :default => false
t.text "additional_repos"
t.string "name"
@ -150,8 +150,8 @@ ActiveRecord::Schema.define(:version => 20130412124536) do
t.string "commentable_type"
t.integer "user_id"
t.text "body"
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
t.datetime "created_at"
t.datetime "updated_at"
t.decimal "commentable_id", :precision => 50, :scale => 0
t.integer "project_id"
t.text "data"
@ -178,8 +178,8 @@ ActiveRecord::Schema.define(:version => 20130412124536) do
t.string "controller"
t.string "action"
t.text "message"
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
t.datetime "created_at"
t.datetime "updated_at"
end
create_table "flash_notifies", :force => true do |t|
@ -193,8 +193,8 @@ ActiveRecord::Schema.define(:version => 20130412124536) do
create_table "groups", :force => true do |t|
t.integer "owner_id"
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
t.datetime "created_at"
t.datetime "updated_at"
t.string "uname"
t.integer "own_projects_count", :default => 0, :null => false
t.text "description"
@ -219,14 +219,15 @@ ActiveRecord::Schema.define(:version => 20130412124536) do
t.string "title"
t.text "body"
t.string "status", :default => "open"
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
t.datetime "created_at"
t.datetime "updated_at"
t.integer "user_id"
t.datetime "closed_at"
t.integer "closed_by"
end
add_index "issues", ["project_id", "serial_id"], :name => "index_issues_on_project_id_and_serial_id", :unique => true
add_index "issues", ["user_id"], :name => "index_issues_on_user_id"
create_table "key_pairs", :force => true do |t|
t.text "public", :null => false
@ -297,14 +298,14 @@ ActiveRecord::Schema.define(:version => 20130412124536) do
t.string "description"
t.string "name", :null => false
t.integer "parent_platform_id"
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
t.datetime "created_at"
t.datetime "updated_at"
t.boolean "released", :default => false, :null => false
t.integer "owner_id"
t.string "owner_type"
t.string "visibility", :default => "open", :null => false
t.string "platform_type", :default => "main", :null => false
t.string "distrib_type"
t.string "distrib_type", :null => false
end
add_index "platforms", ["name"], :name => "index_platforms_on_name", :unique => true, :case_sensitive => false
@ -313,16 +314,16 @@ ActiveRecord::Schema.define(:version => 20130412124536) do
t.integer "platform_id"
t.string "login"
t.string "password"
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
t.datetime "created_at"
t.datetime "updated_at"
t.integer "user_id"
end
create_table "product_build_lists", :force => true do |t|
t.integer "product_id"
t.integer "status", :default => 3, :null => false
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
t.integer "status", :default => 2, :null => false
t.datetime "created_at"
t.datetime "updated_at"
t.integer "project_id"
t.string "project_version"
t.string "commit_hash"
@ -341,8 +342,8 @@ ActiveRecord::Schema.define(:version => 20130412124536) do
create_table "products", :force => true do |t|
t.string "name", :null => false
t.integer "platform_id", :null => false
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
t.datetime "created_at"
t.datetime "updated_at"
t.text "description"
t.integer "project_id"
t.string "params"
@ -357,8 +358,8 @@ ActiveRecord::Schema.define(:version => 20130412124536) do
t.string "name"
t.string "version"
t.datetime "file_mtime"
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
t.datetime "created_at"
t.datetime "updated_at"
t.integer "platform_id"
end
@ -377,33 +378,34 @@ ActiveRecord::Schema.define(:version => 20130412124536) do
create_table "project_to_repositories", :force => true do |t|
t.integer "project_id"
t.integer "repository_id"
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
t.datetime "created_at"
t.datetime "updated_at"
end
add_index "project_to_repositories", ["repository_id", "project_id"], :name => "index_project_to_repositories_on_repository_id_and_project_id", :unique => true
create_table "projects", :force => true do |t|
t.string "name"
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
t.datetime "created_at"
t.datetime "updated_at"
t.integer "owner_id"
t.string "owner_type"
t.string "visibility", :default => "open"
t.text "description"
t.string "ancestry"
t.boolean "has_issues", :default => true
t.boolean "has_wiki", :default => false
t.string "srpm_file_name"
t.string "srpm_content_type"
t.integer "srpm_file_size"
t.datetime "srpm_updated_at"
t.string "srpm_content_type"
t.boolean "has_wiki", :default => false
t.string "default_branch", :default => "master"
t.boolean "is_package", :default => true, :null => false
t.integer "average_build_time", :default => 0, :null => false
t.integer "build_count", :default => 0, :null => false
t.integer "maintainer_id"
t.boolean "publish_i686_into_x86_64", :default => false
t.string "owner_uname", :null => false
end
add_index "projects", ["owner_id", "name", "owner_type"], :name => "index_projects_on_name_and_owner_id_and_owner_type", :unique => true, :case_sensitive => false
@ -428,8 +430,8 @@ ActiveRecord::Schema.define(:version => 20130412124536) do
t.string "token"
t.boolean "approved", :default => false
t.boolean "rejected", :default => false
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
t.datetime "created_at"
t.datetime "updated_at"
t.string "interest"
t.text "more"
t.string "language"
@ -443,16 +445,16 @@ ActiveRecord::Schema.define(:version => 20130412124536) do
t.string "actor_type"
t.integer "target_id"
t.string "target_type"
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
t.datetime "created_at"
t.datetime "updated_at"
t.string "role"
end
create_table "repositories", :force => true do |t|
t.string "description", :null => false
t.integer "platform_id", :null => false
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
t.datetime "created_at"
t.datetime "updated_at"
t.string "name", :null => false
t.boolean "publish_without_qa", :default => true
end
@ -466,8 +468,8 @@ ActiveRecord::Schema.define(:version => 20130412124536) do
t.boolean "new_comment_reply", :default => true
t.boolean "new_issue", :default => true
t.boolean "issue_assign", :default => true
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
t.datetime "created_at"
t.datetime "updated_at"
t.boolean "new_comment_commit_owner", :default => true
t.boolean "new_comment_commit_repo_owner", :default => true
t.boolean "new_comment_commit_commentor", :default => true
@ -490,8 +492,8 @@ ActiveRecord::Schema.define(:version => 20130412124536) do
create_table "subscribes", :force => true do |t|
t.string "subscribeable_type"
t.integer "user_id"
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
t.datetime "created_at"
t.datetime "updated_at"
t.boolean "status", :default => true
t.integer "project_id"
t.decimal "subscribeable_id", :precision => 50, :scale => 0
@ -499,21 +501,18 @@ ActiveRecord::Schema.define(:version => 20130412124536) do
create_table "users", :force => true do |t|
t.string "name"
t.string "email", :default => "", :null => false
t.string "encrypted_password", :default => "", :null => false
t.string "email", :default => "", :null => false
t.string "encrypted_password", :limit => 128, :default => "", :null => false
t.string "reset_password_token"
t.datetime "reset_password_sent_at"
t.datetime "remember_created_at"
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
t.datetime "created_at"
t.datetime "updated_at"
t.text "ssh_key"
t.string "uname"
t.string "role"
t.string "language", :default => "en"
t.integer "own_projects_count", :default => 0, :null => false
t.string "confirmation_token"
t.datetime "confirmed_at"
t.datetime "confirmation_sent_at"
t.string "language", :default => "en"
t.integer "own_projects_count", :default => 0, :null => false
t.text "professional_experience"
t.string "site"
t.string "company"
@ -522,11 +521,14 @@ ActiveRecord::Schema.define(:version => 20130412124536) do
t.string "avatar_content_type"
t.integer "avatar_file_size"
t.datetime "avatar_updated_at"
t.integer "failed_attempts", :default => 0
t.integer "failed_attempts", :default => 0
t.string "unlock_token"
t.datetime "locked_at"
t.string "confirmation_token"
t.datetime "confirmed_at"
t.datetime "confirmation_sent_at"
t.string "authentication_token"
t.integer "build_priority", :default => 50
t.integer "build_priority", :default => 50
end
add_index "users", ["authentication_token"], :name => "index_users_on_authentication_token"

View File

@ -246,7 +246,7 @@ module AbfWorker
order(:updated_at)
locked_ids = @redis.lrange(LOCKED_BUILD_LISTS, 0, -1)
build_lists = build_lists.where('build_lists.id NOT IN (?)', locked_ids) unless locked_ids.empty?
build_lists = build_lists.limit(50)
build_lists = build_lists.limit(150)
old_packages = {:sources => [], :binaries => {:x86_64 => [], :i586 => []}}

View File

@ -5,12 +5,10 @@ module Modules
extend ActiveSupport::Concern
included do
validates :owner, :presence => true
after_create lambda { relations.create :actor_id => owner.id, :actor_type => owner.class.to_s, :role => 'admin' }
end
def name_with_owner
"#{owner.respond_to?(:uname) ? owner.uname : owner.name}/#{self.name}"
end
end
end
end

View File

@ -480,8 +480,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'

View File

@ -0,0 +1,181 @@
# -*- 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'])
@issue = FactoryGirl.create(:issue)
@project = @issue.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}
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 '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 'cant 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 return only assigned issue' do
http_login(@issue.user)
get :user_index, :format => :json
assigns[:issues].should include(@own_hidden_issue)
assigns[:issues].count.should == 1
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 'cant 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)
@count = Issue.count
end
it 'can create issue in own project' do
post :create, @create_params
Issue.count.should == @count+1
end
it 'can create issue in own hidden project' do
post :create, @create_params.merge(:project_id => @own_hidden_project.id)
Issue.count.should == @count+1
end
it 'can create issue in open project' do
post :create, @create_params.merge(:project_id => @open_project.id)
Issue.count.should == @count+1
end
it 'cant create issue in hidden project' do
post :create, @create_params.merge(:project_id => @hidden_project.id)
Issue.count.should == @count
end
end
context 'for anonymous user' do
before(:each) do
@count = Issue.count
end
it 'cant create issue in project', :anonymous_access => true do
post :create, @create_params
Issue.count.should == @count
end
it 'cant create issue in hidden project', :anonymous_access => true do
post :create, @create_params.merge(:project_id => @hidden_project.id)
Issue.count.should == @count
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 'cant 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 'cant 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
end
context 'for anonymous user' do
before(:each) do
@count = Issue.count
end
it 'cant update issue in project', :anonymous_access => true do
put :update, @update_params
response.status.should == 401
end
it 'cant 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

View File

@ -99,12 +99,24 @@ shared_examples_for 'api repository user with writer rights' do
it 'ensures that repository of main platform has been destroyed' do
lambda { delete :destroy, :id => @repository.id, :format => :json }.should change{ Repository.count }.by(-1)
end
it 'should not be able to perform destroy action for repository of personal platform' do
delete :destroy, :id => @personal_repository.id, :format => :json
response.should_not be_success
context 'repository with name "main" of personal platform' do
# hook for "ActiveRecord::ActiveRecordError: name is marked as readonly"
before { Repository.where(:id => @personal_repository.id).update_all("name = 'main'") }
it 'should not be able to perform destroy action' do
delete :destroy, :id => @personal_repository.id, :format => :json
response.should_not be_success
end
it 'ensures that repository has not been destroyed' do
lambda { delete :destroy, :id => @personal_repository.id, :format => :json }.should_not change{ Repository.count }
end
end
it 'ensures that repository of personal platform has not been destroyed' do
lambda { delete :destroy, :id => @personal_repository.id, :format => :json }.should_not change{ Repository.count }
it 'should be able to perform destroy action for repository with name not "main" of personal platform' do
delete :destroy, :id => @personal_repository.id, :format => :json
response.should be_success
end
it 'ensures that repository with name not "main" of personal platform has been destroyed' do
lambda { delete :destroy, :id => @personal_repository.id, :format => :json }.should change{ Repository.count }.by(-1)
end
end
@ -296,9 +308,11 @@ describe Api::V1::RepositoriesController do
before(:each) do
@user = FactoryGirl.create(:user)
http_login(@user)
platform = @repository.platform
platform.owner = @user; platform.save
@repository.platform.relations.create!(:actor_type => 'User', :actor_id => @user.id, :role => 'admin')
[@repository, @personal_repository].each do |repository|
platform = repository.platform
platform.owner = @user; platform.save
repository.platform.relations.create!(:actor_type => 'User', :actor_id => @user.id, :role => 'admin')
end
end
it_should_behave_like 'api repository user with reader rights'

View File

@ -1,14 +1,6 @@
# -*- encoding : utf-8 -*-
require 'spec_helper'
shared_examples_for 'not destroy personal repository' do
it 'should not be able to destroy personal repository' do
lambda { delete :destroy, :id => @personal_repository.id, :platform_id =>
@personal_repository.platform.id}.should change{ Repository.count }.by(0)
response.should redirect_to(redirect_path)
end
end
shared_examples_for 'user with change projects in repository rights' do
it 'should be able to see add_project page' do
@ -90,12 +82,16 @@ shared_examples_for 'registered user or guest' do
end
it 'should not be able to destroy repository in main platform' do
delete :destroy, :id => @repository.id
delete :destroy, :id => @repository.id, :platform_id => @platform.id
response.should redirect_to(redirect_path)
lambda { delete :destroy, :id => @repository.id }.should_not change{ Repository.count }.by(-1)
end
it_should_behave_like 'not destroy personal repository'
it 'should not be able to destroy personal repository' do
lambda { delete :destroy, :id => @personal_repository.id, :platform_id => @personal_repository.platform.id}.
should change{ Repository.count }.by(0)
response.should redirect_to(redirect_path)
end
end
shared_examples_for 'registered user' do
@ -131,7 +127,7 @@ shared_examples_for 'platform admin user' do
end
it 'should be able to destroy repository in main platform' do
lambda { delete :destroy, :id => @repository.id }.should change{ Repository.count }.by(-1)
lambda { delete :destroy, :id => @repository.id, :platform_id => @platform.id }.should change{ Repository.count }.by(-1)
response.should redirect_to(platform_repositories_path(@repository.platform))
end
@ -163,10 +159,21 @@ shared_examples_for 'platform admin user' do
@repository.members.should_not include(@another_user, another_user2)
end
it_should_behave_like 'user with change projects in repository rights'
it_should_behave_like 'not destroy personal repository' do
let(:redirect_path) { forbidden_path }
it 'should not be able to destroy personal repository with name "main"' do
# hook for "ActiveRecord::ActiveRecordError: name is marked as readonly"
Repository.where(:id => @personal_repository.id).update_all("name = 'main'")
lambda { delete :destroy, :id => @personal_repository.id, :platform_id => @personal_repository.platform.id}.
should change{ Repository.count }.by(0)
response.should redirect_to(forbidden_path)
end
it 'should be able to destroy personal repository with name not "main"' do
lambda { delete :destroy, :id => @personal_repository.id, :platform_id => @personal_repository.platform.id}.
should change{ Repository.count }.by(-1)
response.should redirect_to(platform_repositories_path(@personal_repository.platform))
end
it_should_behave_like 'user with change projects in repository rights'
end
describe Platforms::RepositoriesController do
@ -234,6 +241,8 @@ describe Platforms::RepositoriesController do
context 'for platform owner user' do
before(:each) do
@user = @repository.platform.owner
platform = @personal_repository.platform
platform.owner = @user; platform.save
set_session_for(@user)
end
@ -242,7 +251,9 @@ describe Platforms::RepositoriesController do
context 'for platform member user' do
before(:each) do
@platform.relations.create!(:actor_type => 'User', :actor_id => @user.id, :role => 'admin')
[@repository, @personal_repository].each do |repo|
repo.platform.relations.create!(:actor_type => 'User', :actor_id => @user.id, :role => 'admin')
end
end
it_should_behave_like 'platform admin user'
@ -250,7 +261,9 @@ describe Platforms::RepositoriesController do
context 'for repository member user' do
before(:each) do
@repository.relations.create!(:actor_type => 'User', :actor_id => @user.id, :role => 'admin')
[@repository, @personal_repository].each do |repo|
repo.relations.create!(:actor_type => 'User', :actor_id => @user.id, :role => 'admin')
end
end
it_should_behave_like 'registered user'

View File

@ -3,12 +3,12 @@ require 'spec_helper'
require "cancan/matchers"
def admin_create
@admin = FactoryGirl.create(:admin)
@admin = FactoryGirl.create(:admin)
@ability = Ability.new(@admin)
end
def user_create
@user = FactoryGirl.create(:user)
@user = FactoryGirl.create(:user)
@ability = Ability.new(@user)
end
@ -17,47 +17,51 @@ def guest_create
end
describe CanCan do
let(:personal_platform) { FactoryGirl.create(:platform, :platform_type => 'personal') }
let(:personal_repository) { FactoryGirl.create(:personal_repository) }
let(:open_platform) { FactoryGirl.create(:platform, :visibility => 'open') }
let(:hidden_platform) { FactoryGirl.create(:platform, :visibility => 'hidden') }
let(:register_request) { FactoryGirl.create(:register_request) }
let(:open_platform) { FactoryGirl.create(:platform, :visibility => 'open') }
before(:each) do
stub_symlink_methods
end
context 'Site admin' do
before(:each) do
admin_create
end
context 'Site admin' do
let(:personal_platform) { FactoryGirl.create(:platform, :platform_type => 'personal') }
let(:personal_repository_main) { FactoryGirl.create(:personal_repository, :name => 'main') }
let(:personal_repository) { FactoryGirl.create(:personal_repository) }
before(:each) do
admin_create
end
it 'should manage all' do
#(@ability.can? :manage, :all).should be_true
@ability.should be_able_to(:manage, :all)
end
it 'should manage all' do
#(@ability.can? :manage, :all).should be_true
@ability.should be_able_to(:manage, :all)
end
it 'should not be able to destroy personal platforms' do
@ability.should_not be_able_to(:destroy, personal_platform)
end
it 'should not be able to destroy personal platforms' do
@ability.should_not be_able_to(:destroy, personal_platform)
end
it 'should not be able to destroy personal repositories' do
@ability.should_not be_able_to(:destroy, personal_repository)
end
end
it 'should not be able to destroy personal repositories with name "main"' do
@ability.should_not be_able_to(:destroy, personal_repository_main)
end
it 'should be able to destroy personal repositories with name not "main"' do
@ability.should be_able_to(:destroy, personal_repository)
end
end
context 'Site guest' do
before(:each) do
guest_create
end
context 'Site guest' do
let(:hidden_platform) { FactoryGirl.create(:platform, :visibility => 'hidden') }
let(:register_request) { FactoryGirl.create(:register_request) }
before(:each) do
guest_create
end
it 'should not be able to read open platform' do
@ability.should_not be_able_to(:read, open_platform)
@ability.should_not be_able_to(:read, open_platform)
end
it 'should not be able to read hidden platform' do
@ability.should_not be_able_to(:read, hidden_platform)
@ability.should_not be_able_to(:read, hidden_platform)
end
[:publish, :cancel, :reject_publish, :create_container].each do |action|
@ -78,10 +82,10 @@ describe CanCan do
@ability.should_not be_able_to(:destroy, register_request)
end
pending 'should be able to register new user' do # while self registration is closed
@ability.should be_able_to(:create, User)
end
end
pending 'should be able to register new user' do # while self registration is closed
@ability.should be_able_to(:create, User)
end
end
context 'Site user' do
before(:each) do

View File

@ -41,8 +41,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
@ -65,6 +65,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

View File

@ -2,48 +2,49 @@
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)}
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 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
end

View File

@ -2,10 +2,36 @@
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 '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
@ -16,39 +42,31 @@ 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)
end
context 'ensures that folder of repository will be removed after destroy' do
let(:arch) { FactoryGirl.create(:arch) }
let(:types) { ['SRPM', arch.name] }
it { should belong_to(:platform) }
it { should have_many(:project_to_repositories).validate(true) }
it { should have_many(:projects).through(:project_to_repositories) }
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 { 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 "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
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
end
end

View File

@ -28,6 +28,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)
@ -65,8 +67,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