Merge branch 'master' of https://dev.finn.de/git/redmine-cost-control
Conflicts: app/views/hooks/_view_projects_settings_members_table_row.rhtmlpull/6827/head
commit
6def2e627e
@ -1,45 +1,48 @@ |
|||||||
<%- |
<%- |
||||||
index ||= "INDEX" |
index ||= "INDEX" |
||||||
new_or_existing = material_budget_item.new_record? ? 'new' : 'existing' |
new_or_existing = material_budget_item.new_record? ? 'new' : 'existing' |
||||||
id_or_index = material_budget_item.new_record? ? index : material_budget_item.id |
id_or_index = material_budget_item.new_record? ? index : material_budget_item.id |
||||||
prefix = "cost_object[#{new_or_existing}_material_budget_item_attributes][]" |
prefix = "cost_object[#{new_or_existing}_material_budget_item_attributes][]" |
||||||
id_prefix = "cost_object_#{new_or_existing}_material_budget_item_attributes_#{id_or_index}" |
id_prefix = "cost_object_#{new_or_existing}_material_budget_item_attributes_#{id_or_index}" |
||||||
name_prefix = "cost_object[#{new_or_existing}_material_budget_item_attributes][#{id_or_index}]" |
name_prefix = "cost_object[#{new_or_existing}_material_budget_item_attributes][#{id_or_index}]" |
||||||
classes ||= "" |
classes ||= "" |
||||||
|
|
||||||
@material_budget_item = material_budget_item |
@material_budget_item = material_budget_item |
||||||
error_messages = error_messages_for 'material_budget_item' |
error_messages = error_messages_for 'material_budget_item' |
||||||
-%> |
-%> |
||||||
|
|
||||||
<% unless error_messages.blank? %><tr><td colspan="5"><%= error_messages %></td></tr><% end %> |
<% unless error_messages.blank? %><tr><td colspan="5"><%= error_messages %></td></tr><% end %> |
||||||
<% fields_for prefix, material_budget_item do |cost_form| %> |
<% fields_for prefix, material_budget_item do |cost_form| %> |
||||||
<tr class="cost_entry <%= classes %>" id="<%= id_prefix %>"> |
<tr class="cost_entry <%= classes %>" id="<%= id_prefix %>"> |
||||||
<td class="units"> |
<td class="units"> |
||||||
|
<label class="hidden-for-sighted" for="<%= id_prefix %>_units"><%= l(:field_units) %></label> |
||||||
<%= cost_form.text_field :units, :index => id_or_index, :size => 3 %> |
<%= cost_form.text_field :units, :index => id_or_index, :size => 3 %> |
||||||
<span id="<%= "#{id_prefix}_unit_name" %>"> |
<span id="<%= "#{id_prefix}_unit_name" %>"> |
||||||
<%=h material_budget_item.cost_type.unit_plural if material_budget_item.cost_type %> |
<%=h material_budget_item.cost_type.unit_plural if material_budget_item.cost_type %> |
||||||
</span> |
</span> |
||||||
</td> |
</td> |
||||||
<td class="cost_type"> |
<td class="cost_type"> |
||||||
|
<label class="hidden-for-sighted" for="<%= id_prefix %>_cost_type_id"><%= l(:field_cost_type) %></label> |
||||||
<%= cost_form.select :cost_type_id, cost_types_collection_for_select_options(material_budget_item.cost_type), {}, {:index => id_or_index} %> |
<%= cost_form.select :cost_type_id, cost_types_collection_for_select_options(material_budget_item.cost_type), {}, {:index => id_or_index} %> |
||||||
<%= observe_field( "#{id_prefix}_cost_type_id", :url => {:action => :update_material_budget_item, :project_id => @project.id}, :with => "'cost_type_id=' + encodeURIComponent(value) + '&units=' + encodeURIComponent(document.getElementById('#{id_prefix}_units').value) + '&fixed_date=' + encodeURIComponent(document.getElementById('cost_object_fixed_date').value) + '&element_id=#{id_prefix}'") %> |
<%= observe_field( "#{id_prefix}_cost_type_id", :url => {:action => :update_material_budget_item, :project_id => @project.id}, :with => "'cost_type_id=' + encodeURIComponent(value) + '&units=' + encodeURIComponent(document.getElementById('#{id_prefix}_units').value) + '&fixed_date=' + encodeURIComponent(document.getElementById('cost_object_fixed_date').value) + '&element_id=#{id_prefix}'") %> |
||||||
<%= observe_field( "#{id_prefix}_units", :frequency => 1, :url => {:action => :update_material_budget_item, :project_id => @project.id}, :with => "'cost_type_id=' + encodeURIComponent(document.getElementById('#{id_prefix}_cost_type_id').value) + '&units=' + encodeURIComponent(value) + '&fixed_date=' + encodeURIComponent(document.getElementById('cost_object_fixed_date').value) + '&element_id=#{id_prefix}'") %> |
<%= observe_field( "#{id_prefix}_units", :frequency => 1, :url => {:action => :update_material_budget_item, :project_id => @project.id}, :with => "'cost_type_id=' + encodeURIComponent(document.getElementById('#{id_prefix}_cost_type_id').value) + '&units=' + encodeURIComponent(value) + '&fixed_date=' + encodeURIComponent(document.getElementById('cost_object_fixed_date').value) + '&element_id=#{id_prefix}'") %> |
||||||
</td> |
</td> |
||||||
<td class="comment"> |
<td class="comment"> |
||||||
|
<label class="hidden-for-sighted" for="<%= id_prefix %>_comments"><%= l(:field_comments) %></label> |
||||||
<%= cost_form.text_field :comments, :index => id_or_index, :size => 40 %> |
<%= cost_form.text_field :comments, :index => id_or_index, :size => 40 %> |
||||||
</td> |
</td> |
||||||
<td class="currency"> |
<td class="currency"> |
||||||
<span id="<%= "#{id_prefix}_costs" %>" class="icon icon-edit" title="<%= l(:help_click_to_edit) %>"> |
<a href="javascript:;" id="<%= "#{id_prefix}_costs" %>" class="icon icon-edit" title="<%= l(:help_click_to_edit) %>"> |
||||||
<%= number_to_currency(material_budget_item.calculated_costs(@cost_object.fixed_date)) %> |
<%= number_to_currency(material_budget_item.calculated_costs(@cost_object.fixed_date)) %> |
||||||
</span> |
</a> |
||||||
<%= update_page_tag do |page| |
<%= update_page_tag do |page| |
||||||
page << "makeEditable('#{id_prefix}_costs', '#{name_prefix}[budget]');" |
page << "makeEditable('#{id_prefix}_costs', '#{name_prefix}[budget]');" |
||||||
page << "edit($('#{id_prefix}_costs'), '#{name_prefix}[budget]', '#{number_to_currency(material_budget_item.budget)}');" if material_budget_item.budget |
page << "edit($('#{id_prefix}_costs'), '#{name_prefix}[budget]', '#{number_to_currency(material_budget_item.budget)}');" if material_budget_item.budget |
||||||
end %> |
end %> |
||||||
</td> |
</td> |
||||||
<td class="delete"> |
<td class="delete"> |
||||||
<%= link_to_function image_tag('delete.png'), "deleteMaterialBudgetItem('#{id_prefix}')" %> |
<%= link_to_function image_tag('delete.png', :alt => l(:button_delete), :title => l(:button_delete)), "deleteMaterialBudgetItem('#{id_prefix}')" %> |
||||||
</td> |
</td> |
||||||
</tr> |
</tr> |
||||||
<% end %> |
<% end %> |
||||||
|
|
||||||
|
@ -1,4 +0,0 @@ |
|||||||
<h3><%= l(:label_cost_object_plural) %></h3> |
|
||||||
|
|
||||||
<%= link_to_if_authorized l(:label_cost_object_new), {:action => 'new', :project_id => @project } %><br /> |
|
||||||
<%= link_to l(:label_view_all_cost_objects), {:action => 'index'} %><br /> |
|
@ -1,10 +1,19 @@ |
|||||||
<div class="contextual"> |
<% content_for :header_tags do %> |
||||||
<%= link_to_if_authorized(l(:button_update), {:controller => 'issues', :action => 'edit', :id => @issue }, :onclick => 'showAndScrollTo("update", "notes"); return false;', :class => 'icon icon-edit', :accesskey => accesskey(:edit)) %> |
<%= stylesheet_link_tag 'costs', :plugin => 'redmine_costs' %> |
||||||
<%= link_to_if_authorized l(:button_log_time), {:controller => 'timelog', :action => 'new', :issue_id => @issue}, :class => 'icon icon-time-add' %> |
<% end %> |
||||||
<%= link_to_if_authorized l(:button_log_costs), {:controller => 'costlog', :action => 'edit', :issue_id => @issue}, :class => 'icon icon-pieces' %> |
|
||||||
<%= watcher_link(@issue, User.current, {:class => 'watcher_link', :replace => ['#watchers', '.watcher_link']}) %> |
<% content_for :action_menu_main do %> |
||||||
<%= link_to_if_authorized l(:button_duplicate), {:controller => 'issues', :action => 'new', :project_id => @project, :copy_from => @issue }, :class => 'icon icon-duplicate' %> |
<%= li_unless_nil(link_to_if_authorized(l(:button_update), {:controller => 'issues', :action => 'edit', :id => @issue }, :onclick => 'showAndScrollTo("update", "notes"); return false;', :class => 'icon icon-edit', :accesskey => accesskey(:edit))) %> |
||||||
<%= link_to_if_authorized l(:button_copy), {:controller => 'issue_moves', :action => 'new', :id => @issue, :copy_options => {:copy => 't'}}, :class => 'icon icon-copy' %> |
<%= li_unless_nil(watcher_link(@issue, |
||||||
<%= link_to_if_authorized l(:button_move), {:controller => 'issue_moves', :action => 'new', :id => @issue}, :class => 'icon icon-move' %> |
User.current, |
||||||
<%= link_to_if_authorized l(:button_delete), {:controller => 'issues', :action => 'destroy', :id => @issue}, :confirm => (@issue.leaf? ? l(:text_are_you_sure) : l(:text_are_you_sure_with_children)), :method => :post, :class => 'icon icon-del' %> |
{ :class => 'watcher_link', |
||||||
</div> |
:replace => User.current.allowed_to?(:view_issue_watchers, @project) ? ['#watchers', '.watcher_link'] : ['.watcher_link'] })) %> |
||||||
|
<% end %> |
||||||
|
<% content_for :action_menu_more do %> |
||||||
|
<%= li_unless_nil(link_to_if_authorized l(:button_log_time), {:controller => 'timelog', :action => 'new', :issue_id => @issue}, :class => 'icon icon-time-add') %> |
||||||
|
<%= li_unless_nil(link_to_if_authorized l(:button_log_costs), {:controller => 'costlog', :action => 'edit', :issue_id => @issue}, :class => 'icon icon-pieces') %> |
||||||
|
<%= li_unless_nil(link_to_if_authorized l(:button_duplicate), {:controller => 'issues', :action => 'new', :project_id => @project, :copy_from => @issue }, :class => 'icon icon-duplicate') %> |
||||||
|
<%= li_unless_nil(link_to_if_authorized l(:button_copy), {:controller => 'issue_moves', :action => 'new', :id => @issue, :copy_options => {:copy => 't'}}, :class => 'icon icon-copy') %> |
||||||
|
<%= li_unless_nil(link_to_if_authorized l(:button_move), {:controller => 'issue_moves', :action => 'new', :id => @issue}, :class => 'icon icon-move') %> |
||||||
|
<%= li_unless_nil(link_to_if_authorized l(:button_delete), {:controller => 'issues', :action => 'destroy', :id => @issue}, :confirm => (@issue.leaf? ? l(:text_are_you_sure) : l(:text_are_you_sure_with_children)), :method => :post, :class => 'icon icon-del') %> |
||||||
|
<% end %> |
||||||
|
@ -0,0 +1,34 @@ |
|||||||
|
class CreateInitialVariableCostObjectJournals < ActiveRecord::Migration |
||||||
|
def self.up |
||||||
|
[VariableCostObject].each do |p| |
||||||
|
say_with_time("Building initial journals for #{p.class_name}") do |
||||||
|
|
||||||
|
# avoid touching the journaled object on journal creation |
||||||
|
p.journal_class.class_exec { |
||||||
|
def touch_journaled_after_creation |
||||||
|
end |
||||||
|
} |
||||||
|
|
||||||
|
# Create initial journals |
||||||
|
p.find(:all).each do |o| |
||||||
|
# Using rescue and save! here because either the Journal or the |
||||||
|
# touched record could fail. This will catch either error and continue |
||||||
|
begin |
||||||
|
new_journal = o.recreate_initial_journal! |
||||||
|
rescue ActiveRecord::RecordInvalid => ex |
||||||
|
if new_journal.errors.count == 1 && new_journal.errors.first[0] == "version" |
||||||
|
# Skip, only error was from creating the initial journal for a record that already had one. |
||||||
|
else |
||||||
|
puts "ERROR: errors creating the initial journal for #{o.class.to_s}##{o.id.to_s}:" |
||||||
|
puts " #{ex.message}" |
||||||
|
end |
||||||
|
end |
||||||
|
end |
||||||
|
end |
||||||
|
end |
||||||
|
end |
||||||
|
|
||||||
|
def self.down |
||||||
|
VariableCostObjectJournal.destroy_all |
||||||
|
end |
||||||
|
end |
@ -0,0 +1,29 @@ |
|||||||
|
Feature: Cost Object activities |
||||||
|
|
||||||
|
Background: |
||||||
|
Given there is a standard cost control project named "project1" |
||||||
|
And I am admin |
||||||
|
|
||||||
|
Scenario: cost object is a selectable activity type |
||||||
|
When I go to the activity page of the project "project1" |
||||||
|
Then I should see "Budgets" within "#sidebar" |
||||||
|
|
||||||
|
Scenario: Generating a cost object creates an activity |
||||||
|
Given there is a variable cost object with the following: |
||||||
|
| project | project1 | |
||||||
|
| subject | Cost Object Subject | |
||||||
|
| created_on | Time.now - 1.day | |
||||||
|
When I go to the activity page of the project "project1" |
||||||
|
Then I should see "Cost Object Subject" |
||||||
|
|
||||||
|
Scenario: Updating a cost object creates an activity |
||||||
|
Given there is a variable cost object with the following: |
||||||
|
| project | project1 | |
||||||
|
| subject | cost_object1 | |
||||||
|
| created_on | Time.now - 40.days | |
||||||
|
And I update the variable cost object "cost_object1" with the following: |
||||||
|
| subject | cost_object1_new_title | |
||||||
|
When I go to the activity page of the project "project1" |
||||||
|
Then I should see "cost_object1_new_title" |
||||||
|
|
||||||
|
|
@ -0,0 +1,26 @@ |
|||||||
|
class Costs::PrincipalAllowanceEvaluator::Costs < ChiliProject::PrincipalAllowanceEvaluator::Base |
||||||
|
def granted_for_global? membership, action, options |
||||||
|
granted = super |
||||||
|
|
||||||
|
allowed_for_role = Proc.new do |role| |
||||||
|
@user.allowed_for_role(action, nil, role, [@user], options.merge({:for => @user, :global => true})) |
||||||
|
end |
||||||
|
|
||||||
|
granted ||= if membership.is_a?(Member) |
||||||
|
membership.roles.any?(&allowed_for_role) |
||||||
|
elsif membership.is_a?(Role) |
||||||
|
allowed_for_role.call(membership) |
||||||
|
end |
||||||
|
end |
||||||
|
|
||||||
|
def granted_for_project? role, action, project, options |
||||||
|
(project.is_public? || role.member?) && |
||||||
|
@user.allowed_for_role(action, project, role, [@user], options.merge({:for => @user})) |
||||||
|
end |
||||||
|
|
||||||
|
def denied_for_project? role, action, project, options |
||||||
|
action.is_a?(Symbol) && |
||||||
|
options[:for] && options[:for] != @user && |
||||||
|
Redmine::AccessControl.permission(action).granular_for |
||||||
|
end |
||||||
|
end |
@ -0,0 +1,6 @@ |
|||||||
|
Factory.define :variable_cost_object do |m| |
||||||
|
m.association :project, :factory => :project |
||||||
|
m.sequence(:subject) { |n| "Cost Object No. #{n}" } |
||||||
|
m.sequence(:description) { |n| "I am a Cost Object No. #{n}" } |
||||||
|
m.fixed_date Time.now |
||||||
|
end |
@ -0,0 +1,112 @@ |
|||||||
|
require File.dirname(__FILE__) + '/../../../spec_helper' |
||||||
|
|
||||||
|
describe Costs::PrincipalAllowanceEvaluator::Costs do |
||||||
|
let(:klass) { Costs::PrincipalAllowanceEvaluator::Costs } |
||||||
|
let(:user) { Factory.build :user } |
||||||
|
let(:filter) { klass.new user } |
||||||
|
let(:member) { Factory.build :member } |
||||||
|
let(:project) { Factory.build :project } |
||||||
|
let(:role) { Factory.build :role } |
||||||
|
let(:role2) { Factory.build :role } |
||||||
|
let(:permission) { Redmine::AccessControl::Permission.new(:action, {}, {}) } |
||||||
|
let(:permission2) { Redmine::AccessControl::Permission.new(:action2, {}, {}) } |
||||||
|
|
||||||
|
before do |
||||||
|
Redmine::AccessControl.permissions.clear |
||||||
|
Redmine::AccessControl.permissions << permission |
||||||
|
Redmine::AccessControl.permissions << permission2 |
||||||
|
end |
||||||
|
|
||||||
|
describe :granted_for_project? do |
||||||
|
describe "WHEN the role is allowing the action" do |
||||||
|
|
||||||
|
before do |
||||||
|
role.permissions << permission.name |
||||||
|
end |
||||||
|
|
||||||
|
it { filter.granted_for_project?(role, permission.name, project, {}).should be_true } |
||||||
|
end |
||||||
|
|
||||||
|
describe "WHEN the role is not allowing the action" do |
||||||
|
|
||||||
|
it { filter.granted_for_project?(role, permission.name, project, {}).should be_false } |
||||||
|
end |
||||||
|
|
||||||
|
end |
||||||
|
|
||||||
|
describe :granted_for_global? do |
||||||
|
describe "WHEN the membership has a role allowing the action" do |
||||||
|
|
||||||
|
before do |
||||||
|
member.roles = [role] |
||||||
|
|
||||||
|
role.permissions << permission.name |
||||||
|
end |
||||||
|
|
||||||
|
it { filter.granted_for_global?(member, permission.name, {}).should be_true } |
||||||
|
end |
||||||
|
|
||||||
|
describe "WHEN the membership has two roles |
||||||
|
WHEN the first role is not allowing the action |
||||||
|
WHEN the second role is not allowing the action |
||||||
|
WHEN the action is a granular_for an action the second role allows" do |
||||||
|
|
||||||
|
before do |
||||||
|
permission2.instance_variable_set("@granular_for", permission.name) |
||||||
|
|
||||||
|
member.user = user |
||||||
|
member.project = project |
||||||
|
member.roles = [role, role2] |
||||||
|
member.save! |
||||||
|
|
||||||
|
role2.permissions << permission2.name |
||||||
|
role2.save! |
||||||
|
end |
||||||
|
|
||||||
|
it { filter.granted_for_global?(member, permission.name, :for => user).should be_true } |
||||||
|
end |
||||||
|
|
||||||
|
describe "WHEN the membership has two roles |
||||||
|
WHEN the first role is not allowing the action |
||||||
|
WHEN the second role is not allowing the action |
||||||
|
WHEN the action is a granular_for an action the second role does not allow" do |
||||||
|
|
||||||
|
before do |
||||||
|
member.user = user |
||||||
|
member.project = project |
||||||
|
member.roles = [role, role2] |
||||||
|
member.save! |
||||||
|
|
||||||
|
role2.permissions << :action_non |
||||||
|
role2.save! |
||||||
|
end |
||||||
|
|
||||||
|
it { filter.granted_for_global?(member, permission.name, :for => user).should be_false } |
||||||
|
end |
||||||
|
|
||||||
|
describe "WHEN the membership has one role |
||||||
|
WHEN the role is allowing the action |
||||||
|
WHEN the action is a granular_for another action" do |
||||||
|
|
||||||
|
before do |
||||||
|
permission.instance_variable_set("@granular_for", :action_lorem) |
||||||
|
|
||||||
|
member.user = user |
||||||
|
member.project = project |
||||||
|
member.roles = [role] |
||||||
|
member.save! |
||||||
|
|
||||||
|
role.permissions << :action |
||||||
|
role.save! |
||||||
|
end |
||||||
|
|
||||||
|
it { filter.granted_for_global?(member, permission.name, {}).should be_true } |
||||||
|
end |
||||||
|
|
||||||
|
describe "WHEN inserting something other than a Member" do |
||||||
|
it { filter.granted_for_global?(1, :action, {}).should be_false } |
||||||
|
end |
||||||
|
end |
||||||
|
end |
||||||
|
|
||||||
|
|
@ -0,0 +1,386 @@ |
|||||||
|
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper') |
||||||
|
|
||||||
|
|
||||||
|
describe User, "#allowed_to?" do |
||||||
|
let(:controller_member_role) { Factory.build(:member_role, :membership_type => :controller) } |
||||||
|
let(:member) { Factory.build(:member) } |
||||||
|
let(:member2) { Factory.build(:member) } |
||||||
|
let(:group_member) { Factory.build(:member) } |
||||||
|
|
||||||
|
let(:role) { Factory.build(:role) } |
||||||
|
let(:role2) { Factory.build(:role) } |
||||||
|
let(:user) { Factory.build(:user) } |
||||||
|
|
||||||
|
let(:non_member) { Factory.build(:non_member) } |
||||||
|
let(:anonymous_role) { Factory.build(:anonymous_role) } |
||||||
|
|
||||||
|
let(:permission) { Redmine::AccessControl::Permission.new(:action, {}, {}) } |
||||||
|
let(:permission2) { Redmine::AccessControl::Permission.new(:action2, {}, {}) } |
||||||
|
let(:project) { Factory.build(:project) } |
||||||
|
let(:project2) { Factory.build(:project) } |
||||||
|
let(:group) { Group.new :lastname => "group" } |
||||||
|
|
||||||
|
def create_member_with_roles roles |
||||||
|
member.user = user |
||||||
|
member.project = project |
||||||
|
member.roles = roles |
||||||
|
member.save! |
||||||
|
member |
||||||
|
end |
||||||
|
|
||||||
|
|
||||||
|
before do |
||||||
|
project.save! |
||||||
|
Redmine::AccessControl.permissions.clear |
||||||
|
Redmine::AccessControl.permissions << permission |
||||||
|
Redmine::AccessControl.permissions << permission2 |
||||||
|
|
||||||
|
non_member.save! |
||||||
|
anonymous_role.save! |
||||||
|
User.anonymous |
||||||
|
user.save! |
||||||
|
role.save! |
||||||
|
end |
||||||
|
|
||||||
|
after do |
||||||
|
User.destroy_all |
||||||
|
end |
||||||
|
|
||||||
|
describe "WHEN requesting a project permission |
||||||
|
WHEN the user has a membership in the project |
||||||
|
WHEN the membership has a role allowing the action" do |
||||||
|
before do |
||||||
|
create_member_with_roles [role] |
||||||
|
|
||||||
|
role.permissions << permission.name |
||||||
|
role.save |
||||||
|
end |
||||||
|
|
||||||
|
it { user.allowed_to?(permission.name, project, {}).should be_true } |
||||||
|
end |
||||||
|
|
||||||
|
describe "WHEN requesting a project permission |
||||||
|
WHEN the user has a membership in the project |
||||||
|
WHEN the membership has a role not allowing the action" do |
||||||
|
before do |
||||||
|
create_member_with_roles [role] |
||||||
|
|
||||||
|
role.permissions << :action_non |
||||||
|
role.save |
||||||
|
end |
||||||
|
|
||||||
|
it { user.allowed_to?(permission.name, project, {}).should be_false } |
||||||
|
end |
||||||
|
|
||||||
|
describe "WHEN requesting a project permission |
||||||
|
WHEN the user has a membership in the project |
||||||
|
WHEN the membership has a role not allowing the action |
||||||
|
WHEN the membership has a second role allowing the action" do |
||||||
|
before do |
||||||
|
create_member_with_roles [role, role2] |
||||||
|
|
||||||
|
role.permissions << :action_non |
||||||
|
role.save! |
||||||
|
role2.permissions << permission.name |
||||||
|
role2.save! |
||||||
|
end |
||||||
|
|
||||||
|
it { user.allowed_to?(permission.name, project, {}).should be_true } |
||||||
|
end |
||||||
|
|
||||||
|
describe "WHEN requesting a project permission |
||||||
|
WHEN the user has a membership in the project |
||||||
|
WHEN the membership has two roles |
||||||
|
WHEN the first role is not allowing the action |
||||||
|
WHEN the second role is not allowing the action |
||||||
|
WHEN the action is a granular_for an action the second role allows" do |
||||||
|
|
||||||
|
before do |
||||||
|
permission2.instance_variable_set("@granular_for_obj", permission) |
||||||
|
|
||||||
|
create_member_with_roles [role, role2] |
||||||
|
|
||||||
|
role2.permissions << permission2.name |
||||||
|
role2.save! |
||||||
|
end |
||||||
|
|
||||||
|
it { user.allowed_to?(permission.name, project).should be_true } |
||||||
|
end |
||||||
|
|
||||||
|
describe "WHEN requesting a project permission |
||||||
|
WHEN the user has a membership in the project |
||||||
|
WHEN the membership has two roles |
||||||
|
WHEN the first role is not allowing the action |
||||||
|
WHEN the second role is not allowing the action |
||||||
|
WHEN the action is a granular_for an action the second role does not allow" do |
||||||
|
|
||||||
|
before do |
||||||
|
permission2.instance_variable_set("@granular_for_obj", permission) |
||||||
|
|
||||||
|
create_member_with_roles [role, role2] |
||||||
|
|
||||||
|
role2.permissions << :non |
||||||
|
role2.save! |
||||||
|
end |
||||||
|
|
||||||
|
it { user.allowed_to?(permission.name, project).should be_false } |
||||||
|
end |
||||||
|
|
||||||
|
describe "WHEN requesting a project permission |
||||||
|
WHEN the user has a membership in the project |
||||||
|
WHEN the membership has one role |
||||||
|
WHEN the first role is allowing the action |
||||||
|
WHEN the action is a granular_for another action |
||||||
|
WHEN the request is issued for the user" do |
||||||
|
|
||||||
|
before do |
||||||
|
permission.instance_variable_set("@granular_for_obj", permission2) |
||||||
|
|
||||||
|
create_member_with_roles [role] |
||||||
|
|
||||||
|
role.permissions << :action |
||||||
|
role.save! |
||||||
|
end |
||||||
|
|
||||||
|
it { user.allowed_to?(permission.name, project, :for => user).should be_true } |
||||||
|
end |
||||||
|
|
||||||
|
describe "WHEN requesting a project permission |
||||||
|
WHEN the user has a membership in the project |
||||||
|
WHEN the membership has one role |
||||||
|
WHEN the first role is allowing the action |
||||||
|
WHEN the action is a granular_for another action |
||||||
|
WHEN the request is issued for somebody else" do |
||||||
|
|
||||||
|
before do |
||||||
|
permission.instance_variable_set("@granular_for_obj", permission2) |
||||||
|
|
||||||
|
create_member_with_roles [role] |
||||||
|
|
||||||
|
role.permissions << :action |
||||||
|
role.save! |
||||||
|
end |
||||||
|
|
||||||
|
it { user.allowed_to?(permission.name, project, :for => Factory.build(:user)).should be_false } |
||||||
|
end |
||||||
|
|
||||||
|
|
||||||
|
describe "WHEN requesting a project permission |
||||||
|
WHEN the user has no membership in this project" do |
||||||
|
before do |
||||||
|
member.user = user |
||||||
|
member.project = Factory.build(:project) |
||||||
|
member.roles = [role] |
||||||
|
member.save! |
||||||
|
|
||||||
|
role.permissions << permission.name |
||||||
|
role.save! |
||||||
|
end |
||||||
|
|
||||||
|
it { user.allowed_to?(permission.name, project, {}).should be_false } |
||||||
|
end |
||||||
|
|
||||||
|
describe "WHEN requesting a project permission |
||||||
|
WHEN the user is admin" do |
||||||
|
before do |
||||||
|
user.admin = true |
||||||
|
end |
||||||
|
|
||||||
|
it { user.allowed_to?(permission.name, project, {}).should be_true } |
||||||
|
end |
||||||
|
|
||||||
|
describe "WHEN requesting a project permission |
||||||
|
WHEN the project is public |
||||||
|
WHEN the action is allowed for non members" do |
||||||
|
before do |
||||||
|
project.is_public = true |
||||||
|
|
||||||
|
non_member.permissions << permission.name |
||||||
|
non_member.save! |
||||||
|
end |
||||||
|
|
||||||
|
it { user.allowed_to?(permission.name, project, {}).should be_true } |
||||||
|
end |
||||||
|
|
||||||
|
describe "WHEN requesting a project permission |
||||||
|
WHEN the project is public |
||||||
|
WHEN the action is not allowed for non members" do |
||||||
|
before do |
||||||
|
project.is_public = true |
||||||
|
end |
||||||
|
|
||||||
|
it { user.allowed_to?(permission.name, project, {}).should be_false } |
||||||
|
end |
||||||
|
|
||||||
|
describe "WHEN requesting a project permission as anonymous |
||||||
|
WHEN the project is public |
||||||
|
WHEN the action is allowed for anonymous" do |
||||||
|
before do |
||||||
|
project.is_public = true |
||||||
|
|
||||||
|
anonymous_role.permissions << permission.name |
||||||
|
anonymous_role.save! |
||||||
|
end |
||||||
|
|
||||||
|
it { User.anonymous.allowed_to?(permission.name, project, {}).should be_true } |
||||||
|
end |
||||||
|
|
||||||
|
describe "WHEN requesting a project permission as anonymous |
||||||
|
WHEN the project is public |
||||||
|
WHEN the action is not allowed for anonymous" do |
||||||
|
before do |
||||||
|
project.is_public = true |
||||||
|
end |
||||||
|
|
||||||
|
it { User.anonymous.allowed_to?(permission.name, project, {}).should be_false } |
||||||
|
end |
||||||
|
|
||||||
|
|
||||||
|
describe "WHEN requesting a project permission |
||||||
|
WHEN the project is inactive" do |
||||||
|
before do |
||||||
|
create_member_with_roles [role] |
||||||
|
|
||||||
|
role.permissions << permission.name |
||||||
|
|
||||||
|
project.archive |
||||||
|
end |
||||||
|
|
||||||
|
it { user.allowed_to?(permission.name, project, {}).should be_false } |
||||||
|
end |
||||||
|
|
||||||
|
describe "WHEN requesting a project permission |
||||||
|
WHEN the project is not allowing the action" do |
||||||
|
before do |
||||||
|
create_member_with_roles [role] |
||||||
|
|
||||||
|
project.instance_variable_set("@allowed_permissions", []) |
||||||
|
|
||||||
|
role.permissions << permission.name |
||||||
|
|
||||||
|
role.save! |
||||||
|
end |
||||||
|
|
||||||
|
it { user.allowed_to?(permission.name, project, {}).should be_false } |
||||||
|
end |
||||||
|
|
||||||
|
describe "WHEN requesting a permission on two projects |
||||||
|
WHEN the permission is granted on both projects" do |
||||||
|
before do |
||||||
|
project2.save! |
||||||
|
|
||||||
|
create_member_with_roles [role] |
||||||
|
|
||||||
|
member2.project = project2 |
||||||
|
member2.user = user |
||||||
|
member2.roles = [role2] |
||||||
|
member2.save! |
||||||
|
|
||||||
|
role2.permissions << permission.name |
||||||
|
role2.save! |
||||||
|
role.permissions << permission.name |
||||||
|
role.save! |
||||||
|
end |
||||||
|
|
||||||
|
it { user.allowed_to?(permission.name, [project, project2], {}).should be_true } |
||||||
|
|
||||||
|
end |
||||||
|
|
||||||
|
describe "WHEN requesting a permission on two projects |
||||||
|
WHEN the permission is granted on one project" do |
||||||
|
before do |
||||||
|
project2.save! |
||||||
|
|
||||||
|
create_member_with_roles [role] |
||||||
|
|
||||||
|
role.permissions << permission.name |
||||||
|
role.save! |
||||||
|
end |
||||||
|
|
||||||
|
it { user.allowed_to?(permission.name, [project, project2], {}).should be_false } |
||||||
|
end |
||||||
|
|
||||||
|
describe "WHEN requesting a permission on two projects |
||||||
|
WHEN the permission is granted on none of the project" do |
||||||
|
|
||||||
|
it { user.allowed_to?(permission.name, [project, project2], {}).should be_false } |
||||||
|
end |
||||||
|
|
||||||
|
describe "WHEN requesting a permission on no project" do |
||||||
|
|
||||||
|
it { user.allowed_to?(permission.name, [], {}).should be_false } |
||||||
|
end |
||||||
|
|
||||||
|
describe "WHEN requesting a global permission |
||||||
|
WHEN the user is admin" do |
||||||
|
before do |
||||||
|
user.admin = true |
||||||
|
end |
||||||
|
|
||||||
|
it { user.allowed_to?(permission.name, nil, :global => true).should be_true } |
||||||
|
end |
||||||
|
|
||||||
|
describe "WHEN requesting a global permission as anonymous |
||||||
|
WHEN anonymous is allowed the action" do |
||||||
|
|
||||||
|
before do |
||||||
|
anonymous_role.permissions << :action |
||||||
|
anonymous_role.save! |
||||||
|
end |
||||||
|
|
||||||
|
it { User.anonymous.allowed_to?(:action, nil, :global => true, :for => user).should be_true } |
||||||
|
end |
||||||
|
|
||||||
|
describe "WHEN requesting a global permission as anonymous |
||||||
|
WHEN anonymous is not allowed the action" do |
||||||
|
|
||||||
|
it { User.anonymous.allowed_to?(:action, nil, :global => true, :for => user).should be_false } |
||||||
|
end |
||||||
|
|
||||||
|
describe "WHEN requesting a global permission as anonymous |
||||||
|
WHEN anonymous is not allowed the action |
||||||
|
WHEN anonymous has a permission for an action that is a granular_for the requested action" do |
||||||
|
|
||||||
|
before do |
||||||
|
permission2.instance_variable_set("@granular_for_obj", permission) |
||||||
|
|
||||||
|
anonymous_role.permissions << :action2 |
||||||
|
anonymous_role.save! |
||||||
|
end |
||||||
|
|
||||||
|
it { User.anonymous.allowed_to?(:action, nil, :global => true).should be_true } |
||||||
|
end |
||||||
|
|
||||||
|
|
||||||
|
describe "WHEN requesting a global permission |
||||||
|
WHEN non_members are allowed the action" do |
||||||
|
|
||||||
|
before do |
||||||
|
non_member.permissions << :action |
||||||
|
non_member.save! |
||||||
|
end |
||||||
|
|
||||||
|
it { user.allowed_to?(:action, nil, :global => true, :for => user).should be_true } |
||||||
|
end |
||||||
|
|
||||||
|
describe "WHEN requesting a global permission |
||||||
|
WHEN non_members are not allowed the action" do |
||||||
|
|
||||||
|
it { user.allowed_to?(:action, nil, :global => true, :for => user).should be_false } |
||||||
|
end |
||||||
|
|
||||||
|
describe "WHEN requesting a global permission |
||||||
|
WHEN non_members are not allowed the action |
||||||
|
WHEN non_member has a permission for an action that is a granular_for the requested action" do |
||||||
|
|
||||||
|
before do |
||||||
|
permission2.instance_variable_set("@granular_for_obj", permission) |
||||||
|
|
||||||
|
non_member.permissions << :action2 |
||||||
|
non_member.save! |
||||||
|
end |
||||||
|
|
||||||
|
it { user.allowed_to?(:action, nil, :global => true).should be_true } |
||||||
|
end |
||||||
|
end |
||||||
|
|
@ -0,0 +1,9 @@ |
|||||||
|
require File.dirname(__FILE__) + '/../spec_helper' |
||||||
|
|
||||||
|
describe User do |
||||||
|
let(:klass) { User } |
||||||
|
|
||||||
|
describe :registered_allowance_evaluators do |
||||||
|
it { klass.registered_allowance_evaluators.include?(Costs::PrincipalAllowanceEvaluator::Costs).should be_true } |
||||||
|
end |
||||||
|
end |
@ -0,0 +1,20 @@ |
|||||||
|
require File.dirname(__FILE__) + '/../spec_helper' |
||||||
|
|
||||||
|
describe VariableCostObject do |
||||||
|
before(:each) do |
||||||
|
@tracker ||= Factory.create(:tracker_feature) |
||||||
|
@project ||= Factory.create(:project_with_trackers) |
||||||
|
@current = Factory.create(:user, :login => "user1", :mail => "user1@users.com") |
||||||
|
|
||||||
|
User.stub!(:current).and_return(@current) |
||||||
|
end |
||||||
|
|
||||||
|
it 'should work with recreate initial journal' do |
||||||
|
@variable_cost_object ||= Factory.create(:variable_cost_object , :project => @project, :author => @current) |
||||||
|
|
||||||
|
initial_journal = @variable_cost_object.journals.first |
||||||
|
recreated_journal = @variable_cost_object.recreate_initial_journal! |
||||||
|
|
||||||
|
initial_journal.should be_identical(recreated_journal) |
||||||
|
end |
||||||
|
end |
@ -1,26 +1,7 @@ |
|||||||
RAILS_ENV = "test" unless defined? RAILS_ENV |
RAILS_ENV = "test" unless defined? RAILS_ENV |
||||||
|
|
||||||
# prevent case where we are using rubygems and test-unit 2.x is installed |
require 'spec/spec_helper' |
||||||
begin |
require 'redmine_factory_girl' |
||||||
require 'rubygems' |
require 'identical_ext' |
||||||
gem "test-unit", "~> 1.2.3" |
|
||||||
rescue LoadError |
|
||||||
end |
|
||||||
|
|
||||||
begin |
|
||||||
#require "config/environment" unless defined? RAILS_ROOT |
|
||||||
require 'spec/spec_helper' |
|
||||||
rescue LoadError => error |
|
||||||
puts <<-EOS |
|
||||||
|
|
||||||
You need to install rspec in your Redmine project. |
|
||||||
Please execute the following code: |
|
||||||
|
|
||||||
gem install rspec-rails |
|
||||||
script/generate rspec |
|
||||||
|
|
||||||
EOS |
|
||||||
raise error |
|
||||||
end |
|
||||||
|
|
||||||
Fixtures.create_fixtures File.join(File.dirname(__FILE__), "fixtures"), ActiveRecord::Base.connection.tables |
Fixtures.create_fixtures File.join(File.dirname(__FILE__), "fixtures"), ActiveRecord::Base.connection.tables |
||||||
|
Loading…
Reference in new issue