diff --git a/plugins/sub_organizations/controllers/sub_organizations_plugin_myprofile_controller.rb b/plugins/sub_organizations/controllers/sub_organizations_plugin_myprofile_controller.rb new file mode 100644 index 0000000..75d1a9a --- /dev/null +++ b/plugins/sub_organizations/controllers/sub_organizations_plugin_myprofile_controller.rb @@ -0,0 +1,53 @@ +class SubOrganizationsPluginMyprofileController < MyProfileController + append_view_path File.join(File.dirname(__FILE__) + '/../views') + + before_filter :organizations_only + + def index + @children = SubOrganizationsPlugin::Relation.children(profile) + @tokenized_children = prepare_to_token_input(@children) + @pending_children = SubOrganizationsPlugin::ApprovePaternityRelation.pending_children(profile) + if request.post? + begin + original = SubOrganizationsPlugin::Relation.children(profile) + requested = Organization.find(params[:q].split(',')) + added = requested - original + removed = original - requested + added.each do |organization| + if current_person.has_permission?('perform_task',organization) + SubOrganizationsPlugin::Relation.add_children(profile, organization) + else + SubOrganizationsPlugin::ApprovePaternity.create!(:requestor => user, :temp_parent_type => profile.class.name, :temp_parent_id => profile.id, :target => organization) + end + end + SubOrganizationsPlugin::Relation.remove_children(profile,removed) + session[:notice] = _('Sub-organizations updated') + rescue Exception => exception + logger.error(exception.to_s) + session[:notice] = _('Sub-organizations could not be updated') + end + redirect_to :action => :index + end + end + + def search_organization + render :text => prepare_to_token_input(environment.organizations.find(:all, :conditions => + ["(LOWER(name) LIKE ? OR LOWER(identifier) LIKE ?) + AND (identifier NOT LIKE ?) AND (id != ?)", + "%#{params[:q]}%", "%#{params[:q]}%", "%_template", profile.id]). + select { |organization| + SubOrganizationsPlugin::Relation.children(organization).blank? && + !SubOrganizationsPlugin::ApprovePaternityRelation.pending_children(profile).include?(organization) + }).to_json + end + + private + + def organizations_only + render_not_found if !profile.organization? + end + + def prepare_to_token_input(array) + array.map { |object| {:id => object.id, :name => object.name} } + end +end diff --git a/plugins/sub_organizations/db/migrate/20120530173629_create_relation.rb b/plugins/sub_organizations/db/migrate/20120530173629_create_relation.rb new file mode 100644 index 0000000..04df40c --- /dev/null +++ b/plugins/sub_organizations/db/migrate/20120530173629_create_relation.rb @@ -0,0 +1,12 @@ +class CreateRelation < ActiveRecord::Migration + def self.up + create_table :sub_organizations_plugin_relations do |t| + t.references :parent, :polymorphic => true + t.references :child, :polymorphic => true + end + end + + def self.down + drop_table :sub_organizations_plugin_relations + end +end diff --git a/plugins/sub_organizations/db/migrate/20120615202224_approve_paternity_relation.rb b/plugins/sub_organizations/db/migrate/20120615202224_approve_paternity_relation.rb new file mode 100644 index 0000000..5536a32 --- /dev/null +++ b/plugins/sub_organizations/db/migrate/20120615202224_approve_paternity_relation.rb @@ -0,0 +1,13 @@ +class ApprovePaternityRelation < ActiveRecord::Migration + def self.up + create_table :sub_organizations_plugin_approve_paternity_relations do |t| + t.references :task + t.references :parent, :polymorphic => true + t.references :child, :polymorphic => true + end + end + + def self.down + drop_table :sub_organizations_plugin_approve_paternity_relations + end +end diff --git a/plugins/sub_organizations/lib/sub_organizations_plugin.rb b/plugins/sub_organizations/lib/sub_organizations_plugin.rb new file mode 100644 index 0000000..817e2e1 --- /dev/null +++ b/plugins/sub_organizations/lib/sub_organizations_plugin.rb @@ -0,0 +1,46 @@ +require_dependency 'sub_organizations_plugin/ext/organization' +require_dependency 'sub_organizations_plugin/ext/create_enterprise' + +class SubOrganizationsPlugin < Noosfero::Plugin + + def self.plugin_name + _("Sub-groups") + end + + def self.plugin_description + _("Adds the ability for groups to have sub-groups.") + end + + def control_panel_buttons + if context.profile.organization? && SubOrganizationsPlugin::Relation.parents(context.profile).blank? + { :title => _('Manage sub-groups'), :icon => 'groups', :url => {:controller => 'sub_organizations_plugin_myprofile'} } + end + end + + def stylesheet? + true + end + + def organization_members(organization) + children = SubOrganizationsPlugin::Relation.children(organization) + Person.members_of(children) if children.present? + end + + def has_permission?(person, permission, target) + if !target.kind_of?(Environment) && target.organization? + SubOrganizationsPlugin::Relation.parents(target).map do |parent| + person.has_permission_without_plugins?(permission, parent) + end.include?(true) + end + end + + def new_community_hidden_fields + parent_to_be = context.params[:sub_organizations_plugin_parent_to_be] + {'sub_organizations_plugin_parent_to_be' => parent_to_be} if parent_to_be.present? + end + + def enterprise_registration_hidden_fields + parent_to_be = context.params[:sub_organizations_plugin_parent_to_be] + {'sub_organizations_plugin_parent_to_be' => parent_to_be} if parent_to_be.present? + end +end diff --git a/plugins/sub_organizations/lib/sub_organizations_plugin/approve_paternity.rb b/plugins/sub_organizations/lib/sub_organizations_plugin/approve_paternity.rb new file mode 100644 index 0000000..743dcc6 --- /dev/null +++ b/plugins/sub_organizations/lib/sub_organizations_plugin/approve_paternity.rb @@ -0,0 +1,57 @@ +class SubOrganizationsPlugin::ApprovePaternity < Task + validates_presence_of :requestor, :target + + settings_items :temp_parent_id + settings_items :temp_parent_type + + after_create do |task| + r = SubOrganizationsPlugin::ApprovePaternityRelation.create!(:task => task, :parent => task.temp_parent, :child => task.target) + end + + def temp_parent + temp_parent_type.constantize.find(temp_parent_id) + end + + def parent + SubOrganizationsPlugin::ApprovePaternityRelation.parent(self) + end + + def title + _("Paternity request") + end + + def linked_subject + {:text => parent.name, :url => parent.url} + end + + def information + {:message => _('%{requestor} wants to add this organization as a sub-organization of %{linked_subject}.')} + end + + def reject_details + true + end + + def icon + {:type => :profile_image, :profile => parent, :url => parent.url} + end + + def task_created_message + ('%{requestor} wants to add your organization %{target} as a sub-organization of %{parent}.') % {:requestor => requestor.name, :target => target.name, :parent => temp_parent.name} + end + + def task_finished_message + ('%{target} accepted your request to add it as a sub-organization of %{parent}.') % {:target => target.name, :parent => parent.name} + end + + def task_cancelled_message + ('%{target} refused your request to add it as a sub-organization of %{parent}.') % {:target => target.name, :parent => parent.name} + end + + protected + + def perform + SubOrganizationsPlugin::Relation.add_children(parent, target) + end + +end diff --git a/plugins/sub_organizations/lib/sub_organizations_plugin/approve_paternity_relation.rb b/plugins/sub_organizations/lib/sub_organizations_plugin/approve_paternity_relation.rb new file mode 100644 index 0000000..a1adb7d --- /dev/null +++ b/plugins/sub_organizations/lib/sub_organizations_plugin/approve_paternity_relation.rb @@ -0,0 +1,23 @@ +class SubOrganizationsPlugin::ApprovePaternityRelation < Noosfero::Plugin::ActiveRecord + belongs_to :task + belongs_to :parent, :polymorphic => true + belongs_to :child, :polymorphic => true + + validates_presence_of :task, :parent, :child + + class << self + def parent(task) + find_by_task_id(task.id).parent + end + + def pending_children(parent) + options = { + :select => "distinct profiles.*", + :joins => "inner join sub_organizations_plugin_approve_paternity_relations as relations on profiles.id=relations.child_id inner join tasks on relations.task_id=tasks.id", + :conditions => ["relations.parent_id = ? AND tasks.status = 1", parent.id] + } + ActiveRecord::NamedScope::Scope.new(Organization, options) + end + end + +end diff --git a/plugins/sub_organizations/lib/sub_organizations_plugin/ext/create_enterprise.rb b/plugins/sub_organizations/lib/sub_organizations_plugin/ext/create_enterprise.rb new file mode 100644 index 0000000..e4e19ea --- /dev/null +++ b/plugins/sub_organizations/lib/sub_organizations_plugin/ext/create_enterprise.rb @@ -0,0 +1,5 @@ +require_dependency 'create_enterprise' + +class CreateEnterprise + settings_items :sub_organizations_plugin_parent_to_be +end diff --git a/plugins/sub_organizations/lib/sub_organizations_plugin/ext/organization.rb b/plugins/sub_organizations/lib/sub_organizations_plugin/ext/organization.rb new file mode 100644 index 0000000..5626fa1 --- /dev/null +++ b/plugins/sub_organizations/lib/sub_organizations_plugin/ext/organization.rb @@ -0,0 +1,13 @@ +require_dependency 'organization' +class Organization + settings_items :sub_organizations_plugin_parent_to_be + + after_create do |organization| + if organization.sub_organizations_plugin_parent_to_be.present? + parent = Organization.find(organization.sub_organizations_plugin_parent_to_be) + SubOrganizationsPlugin::Relation.add_children(parent,organization) + end + end + + FIELDS << 'sub_organizations_plugin_parent_to_be' +end diff --git a/plugins/sub_organizations/lib/sub_organizations_plugin/relation.rb b/plugins/sub_organizations/lib/sub_organizations_plugin/relation.rb new file mode 100644 index 0000000..b173108 --- /dev/null +++ b/plugins/sub_organizations/lib/sub_organizations_plugin/relation.rb @@ -0,0 +1,54 @@ +class SubOrganizationsPlugin::Relation < Noosfero::Plugin::ActiveRecord + belongs_to :parent, :polymorphic => true + belongs_to :child, :polymorphic => true + + validates_presence_of :parent, :child + validate :no_self_reference + validate :no_cyclical_reference, :if => 'parent.present? && child.present?' + validate :no_multi_level, :if => 'parent.present? && child.present?' + + def no_self_reference + errors.add(:child, _('self-reference is not allowed.')) if parent == child + end + + def no_cyclical_reference + if self.class.children(child).include?(parent) + errors.add(:child, _('cyclical reference is not allowed.')) + end + end + + def no_multi_level + if self.class.parents(parent).present? || self.class.children(child).present? + errors.add(:child, _('multi-level paternity is not allowed.')) + end + end + + class << self + def children(parent) + options = { + :select => "profiles.*", + :joins => "inner join sub_organizations_plugin_relations as relations on profiles.id=relations.child_id", + :conditions => ["relations.parent_id = ?", parent.id] + } + ActiveRecord::NamedScope::Scope.new(Organization, options) + end + + def parents(child) + options = { + :select => "profiles.*", + :joins => "inner join sub_organizations_plugin_relations as relations on profiles.id=relations.parent_id", + :conditions => ["relations.child_id = ?", child.id] + } + ActiveRecord::NamedScope::Scope.new(Organization, options) + end + + def add_children(parent, *children) + children.each {|child| create!(:parent => parent, :child => child)} + end + + def remove_children(parent, *children) + children.flatten.each {|child| find_by_parent_id_and_child_id(parent.id, child.id).destroy} + end + end + +end diff --git a/plugins/sub_organizations/public/style.css b/plugins/sub_organizations/public/style.css new file mode 100644 index 0000000..2a2444d --- /dev/null +++ b/plugins/sub_organizations/public/style.css @@ -0,0 +1,3 @@ +#content .token-input-list { + margin-bottom: 30px; +} diff --git a/plugins/sub_organizations/test/functional/sub_organizations_plugin_myprofile_controller_test.rb b/plugins/sub_organizations/test/functional/sub_organizations_plugin_myprofile_controller_test.rb new file mode 100644 index 0000000..0b7bfdd --- /dev/null +++ b/plugins/sub_organizations/test/functional/sub_organizations_plugin_myprofile_controller_test.rb @@ -0,0 +1,89 @@ +require File.dirname(__FILE__) + '/../../../../test/test_helper' +require File.dirname(__FILE__) + '/../../controllers/sub_organizations_plugin_myprofile_controller' + +# Re-raise errors caught by the controller. +class SubOrganizationsPluginMyprofileController; def rescue_action(e) raise e end; end + +class SubOrganizationsPluginMyprofileControllerTest < ActionController::TestCase + def setup + @controller = SubOrganizationsPluginMyprofileController.new + @request = ActionController::TestRequest.new + @response = ActionController::TestResponse.new + @organization = Organization.create!(:name => 'My Organization', :identifier => 'my-organization') + @person = create_user('person').person + @organization.add_admin(@person) + login_as(@person.user.login) + e = Environment.default + e.enable_plugin('SubOrganizationsPlugin') + e.save! + end + + attr_accessor :person, :organization + + should 'search organizations' do + # Should list if match name + o1 = fast_create(Organization, :name => 'sample organization 1') + # Should be case insensitive + o2 = fast_create(Organization, :name => 'SaMpLe OrGaNiZaTiOn 2') + # Should not list if don't match name + o3 = fast_create(Organization, :name => 'blo') + # Should not list if is has children + child = fast_create(Organization) + o4 = fast_create(Organization, :name => 'sample organization 4') + SubOrganizationsPlugin::Relation.add_children(o4, child) + # Should not list if is there is a task to add it + o5 = fast_create(Organization, :name => 'sample enterprise 5') + SubOrganizationsPlugin::ApprovePaternity.create!(:requestor => person, :target => o5, :temp_parent_id => organization.id, :temp_parent_type => organization.class.name) + # Should search by identifier + o6 = fast_create(Organization, :name => 'Bla', :identifier => 'sample-enterprise-6') + # Should not list itself + organization.name = 'Sample Organization' + organization.save! + + get :search_organization, :profile => organization.identifier, :q => 'sampl' + + assert_match /#{o1.name}/, @response.body + assert_match /#{o2.name}/, @response.body + assert_no_match /#{o3.name}/, @response.body + assert_no_match /#{o4.name}/, @response.body + assert_no_match /#{o5.name}/, @response.body + assert_match /#{o6.name}/, @response.body + assert_no_match /#{organization.name}/, @response.body + end + + should 'update sub-organizations list' do + org1 = fast_create(Organization) + org2 = fast_create(Organization) + org3 = fast_create(Organization) + org4 = fast_create(Organization) + SubOrganizationsPlugin::Relation.add_children(organization, org1, org2) + + post :index, :profile => organization.identifier, :q => [org2,org3,org4].map(&:id).join(',') + + children = SubOrganizationsPlugin::Relation.children(organization) + assert_not_includes children, org1 + assert_includes children, org2 + assert_not_includes children, org3 + assert_not_includes children, org4 + + SubOrganizationsPlugin::ApprovePaternity.all.map(&:finish) + + children = SubOrganizationsPlugin::Relation.children(organization) + assert_not_includes children, org1 + assert_includes children, org2 + assert_includes children, org3 + assert_includes children, org4 + end + + should 'establish relation right away if the user can perform tasks on the sub-organization' do + org1 = fast_create(Organization) + org2 = fast_create(Organization) + org2.add_admin(person) + + assert_difference SubOrganizationsPlugin::ApprovePaternity, :count, 1 do + post :index, :profile => organization.identifier, :q => [org1,org2].map(&:id).join(',') + end + assert_includes SubOrganizationsPlugin::Relation.children(organization), org2 + end + +end diff --git a/plugins/sub_organizations/test/unit/sub_organizations_plugin/approve_paternity_relation_test.rb b/plugins/sub_organizations/test/unit/sub_organizations_plugin/approve_paternity_relation_test.rb new file mode 100644 index 0000000..2d5c78a --- /dev/null +++ b/plugins/sub_organizations/test/unit/sub_organizations_plugin/approve_paternity_relation_test.rb @@ -0,0 +1,32 @@ +require File.dirname(__FILE__) + '/../../../../../test/test_helper' + +class SubOrganizationsPlugin::ApprovePaternityRelationTest < ActiveSupport::TestCase + + def setup + @requestor = create_user('some-user').person + end + + attr_reader :requestor + + should 'return parent' do + org1 = fast_create(Organization) + org2 = fast_create(Organization) + task = SubOrganizationsPlugin::ApprovePaternity.create!(:requestor => requestor, :target => org2, :temp_parent_id => org1.id, :temp_parent_type => org1.class.name) + + assert_equal SubOrganizationsPlugin::ApprovePaternityRelation.parent(task), org1 + end + + should 'list pending children' do + organization = fast_create(Organization) + org1 = fast_create(Organization) + org2 = fast_create(Organization) + org3 = fast_create(Organization) + + SubOrganizationsPlugin::ApprovePaternity.create!(:requestor => requestor, :target => org1, :temp_parent_id => organization.id, :temp_parent_type => organization.class.name) + SubOrganizationsPlugin::ApprovePaternity.create!(:requestor => requestor, :target => org2, :temp_parent_id => organization.id, :temp_parent_type => organization.class.name) + + assert_includes SubOrganizationsPlugin::ApprovePaternityRelation.pending_children(organization), org1 + assert_includes SubOrganizationsPlugin::ApprovePaternityRelation.pending_children(organization), org2 + assert_not_includes SubOrganizationsPlugin::ApprovePaternityRelation.pending_children(organization), org3 + end +end diff --git a/plugins/sub_organizations/test/unit/sub_organizations_plugin/approve_paternity_test.rb b/plugins/sub_organizations/test/unit/sub_organizations_plugin/approve_paternity_test.rb new file mode 100644 index 0000000..e58062f --- /dev/null +++ b/plugins/sub_organizations/test/unit/sub_organizations_plugin/approve_paternity_test.rb @@ -0,0 +1,29 @@ +require File.dirname(__FILE__) + '/../../../../../test/test_helper' + +class SubOrganizationsPlugin::ApprovePaternityTest < ActiveSupport::TestCase + + def setup + @requestor = create_user('some-user').person + end + + attr_reader :requestor + + should 'create relation after creation' do + org1 = fast_create(Organization) + org2 = fast_create(Organization) + assert_difference SubOrganizationsPlugin::ApprovePaternityRelation, :count, 1 do + SubOrganizationsPlugin::ApprovePaternity.create!(:requestor => requestor, :temp_parent_id => org1.id, :temp_parent_type => org1.class.name, :target => org2) + end + end + + should 'add children to parent after approving' do + org1 = fast_create(Organization) + org2 = fast_create(Organization) + + task = SubOrganizationsPlugin::ApprovePaternity.create!(:requestor => requestor, :temp_parent_id => org1.id, :temp_parent_type => org1.class.name, :target => org2) + assert_not_includes SubOrganizationsPlugin::Relation.children(org1), org2 + + task.finish + assert_includes SubOrganizationsPlugin::Relation.children(org1), org2 + end +end diff --git a/plugins/sub_organizations/test/unit/sub_organizations_plugin/ext/create_enterprise_test.rb b/plugins/sub_organizations/test/unit/sub_organizations_plugin/ext/create_enterprise_test.rb new file mode 100644 index 0000000..692b174 --- /dev/null +++ b/plugins/sub_organizations/test/unit/sub_organizations_plugin/ext/create_enterprise_test.rb @@ -0,0 +1,11 @@ +require File.dirname(__FILE__) + '/../../../../../../test/test_helper' + +class CreateEnterpriseTest < ActiveSupport::TestCase + + should 'inlude the parent field in create enterprise' do + create_enterprise = CreateEnterprise.new + assert_nothing_raised { create_enterprise.sub_organizations_plugin_parent_to_be = '999' } + end + +end + diff --git a/plugins/sub_organizations/test/unit/sub_organizations_plugin/ext/organization.rb b/plugins/sub_organizations/test/unit/sub_organizations_plugin/ext/organization.rb new file mode 100644 index 0000000..b9a70c2 --- /dev/null +++ b/plugins/sub_organizations/test/unit/sub_organizations_plugin/ext/organization.rb @@ -0,0 +1,23 @@ +require File.dirname(__FILE__) + '/../../../../../../test/test_helper' + +class OrganizationTest < ActiveSupport::TestCase + + should 'inlude the parent field in organization' do + organization = Organization.new + assert_nothing_raised { organization.sub_organizations_plugin_parent_to_be = '999' } + end + + should 'include the parent field in the FIELDS constant' do + assert_includes Organization::FIELDS, 'sub_organizations_plugin_parent_to_be' + end + + should 'relate organization with parent if the attribute is set' do + parent = fast_create(Organization) + organization = Organization.new(:identifier => 'some-org',:name => 'Some Org', :sub_organizations_plugin_parent_to_be => parent.id) + assert_not_includes SubOrganizationsPlugin::Relation.children(parent), organization + + organization.save! + assert_includes SubOrganizationsPlugin::Relation.children(parent), organization + end + +end diff --git a/plugins/sub_organizations/test/unit/sub_organizations_plugin/relation_test.rb b/plugins/sub_organizations/test/unit/sub_organizations_plugin/relation_test.rb new file mode 100644 index 0000000..a30a7e3 --- /dev/null +++ b/plugins/sub_organizations/test/unit/sub_organizations_plugin/relation_test.rb @@ -0,0 +1,110 @@ +require File.dirname(__FILE__) + '/../../../../../test/test_helper' + +class SubOrganizationsPlugin::RelationTest < ActiveSupport::TestCase + + should 'validates presence of child and parent' do + org = fast_create(Organization) + relation = SubOrganizationsPlugin::Relation.new + + relation.parent = org + relation.valid? + assert relation.errors.invalid?(:child) + + relation.parent = nil + relation.child = org + relation.valid? + assert relation.errors.invalid?(:parent) + end + + should 'relate two organizations' do + org1 = fast_create(Organization) + org2 = fast_create(Organization) + relation = SubOrganizationsPlugin::Relation.create!(:parent => org1, :child => org2) + + assert_equal org1, relation.parent + assert_equal org2, relation.child + end + + should 'not allow self relation' do + org = fast_create(Organization) + relation = SubOrganizationsPlugin::Relation.new(:parent_id => org, :child_id => org) + assert !relation.valid? + assert relation.errors.invalid?(:child) + end + + should 'be able to retrieve parents of an organization' do + child = fast_create(Organization) + parent1 = fast_create(Organization) + parent2 = fast_create(Organization) + SubOrganizationsPlugin::Relation.create!(:parent => parent1, :child => child) + SubOrganizationsPlugin::Relation.create!(:parent => parent2, :child => child) + + assert_includes SubOrganizationsPlugin::Relation.parents(child), parent1 + assert_includes SubOrganizationsPlugin::Relation.parents(child), parent2 + end + + should 'be able to retrieve children of an organization' do + parent = fast_create(Organization) + child1 = fast_create(Organization) + child2 = fast_create(Organization) + SubOrganizationsPlugin::Relation.create!(:parent => parent, :child => child1) + SubOrganizationsPlugin::Relation.create!(:parent => parent, :child => child2) + + assert_includes SubOrganizationsPlugin::Relation.children(parent), child1 + assert_includes SubOrganizationsPlugin::Relation.children(parent), child2 + end + + should 'not allow cyclical reference' do + org1 = fast_create(Organization) + org2 = fast_create(Organization) + SubOrganizationsPlugin::Relation.create!(:parent => org1, :child => org2) + relation = SubOrganizationsPlugin::Relation.new(:parent => org2, :child => org1) + + assert !relation.valid? + assert relation.errors.invalid?(:child) + end + + should 'not allow multi-level paternity' do + org1 = fast_create(Organization) + org2 = fast_create(Organization) + org3 = fast_create(Organization) + SubOrganizationsPlugin::Relation.create!(:parent => org1, :child => org2) + r1 = SubOrganizationsPlugin::Relation.new(:parent => org2, :child => org3) + r2 = SubOrganizationsPlugin::Relation.new(:parent => org3, :child => org1) + + assert !r1.valid? + assert r1.errors.invalid?(:child) + + assert !r2.valid? + assert r2.errors.invalid?(:child) + end + + should 'add children' do + org1 = fast_create(Organization) + org2 = fast_create(Organization) + org3 = fast_create(Organization) + org4 = fast_create(Organization) + + SubOrganizationsPlugin::Relation.add_children(org1,org2) + assert_includes SubOrganizationsPlugin::Relation.children(org1), org2 + + SubOrganizationsPlugin::Relation.add_children(org1,org3,org4) + assert_includes SubOrganizationsPlugin::Relation.children(org1), org3 + assert_includes SubOrganizationsPlugin::Relation.children(org1), org4 + end + + should 'remove children' do + org1 = fast_create(Organization) + org2 = fast_create(Organization) + org3 = fast_create(Organization) + org4 = fast_create(Organization) + SubOrganizationsPlugin::Relation.add_children(org1,org2,org3,org4) + + SubOrganizationsPlugin::Relation.remove_children(org1,org2) + assert_not_includes SubOrganizationsPlugin::Relation.children(org1), org2 + + SubOrganizationsPlugin::Relation.remove_children(org1,org3,org4) + assert_not_includes SubOrganizationsPlugin::Relation.children(org1), org3 + assert_not_includes SubOrganizationsPlugin::Relation.children(org1), org4 + end +end diff --git a/plugins/sub_organizations/test/unit/sub_organizations_plugin_test.rb b/plugins/sub_organizations/test/unit/sub_organizations_plugin_test.rb new file mode 100644 index 0000000..2d3b3c5 --- /dev/null +++ b/plugins/sub_organizations/test/unit/sub_organizations_plugin_test.rb @@ -0,0 +1,83 @@ +require File.dirname(__FILE__) + '/../../../../test/test_helper' + +class SubOrganizationsTest < ActiveSupport::TestCase + + def setup + @plugin = SubOrganizationsPlugin.new + end + + attr_reader :plugin + + should 'include sub-organizations members in the parent organization' do + org1 = fast_create(Organization) + org2 = fast_create(Organization) + org3 = fast_create(Organization) + member1 = fast_create(Person) + member2 = fast_create(Person) + member3 = fast_create(Person) + member4 = fast_create(Person) + member5 = fast_create(Person) + member6 = fast_create(Person) + member7 = fast_create(Person) + org1.add_member(member1) + org2.add_member(member2) + org2.add_member(member3) + org3.add_member(member4) + org3.add_member(member5) + SubOrganizationsPlugin::Relation.create!(:parent => org1, :child => org2) + SubOrganizationsPlugin::Relation.create!(:parent => org1, :child => org3) + + org1_members = plugin.organization_members(org1) + + assert_equal ActiveRecord::NamedScope::Scope, org1_members.class + assert_not_includes org1_members, member1 + assert_includes org1_members, member2 + assert_includes org1_members, member3 + assert_includes org1_members, member4 + assert_includes org1_members, member5 + assert_not_includes org1_members, member6 + assert_not_includes org1_members, member7 + + org2_members = plugin.organization_members(org2) + org3_members = plugin.organization_members(org3) + + assert org2_members.blank? + assert org3_members.blank? + end + + should 'grant permission that user has on parent organizations over children orgnaizations' do + person = create_user('admin-user').person + org1 = fast_create(Organization) + org2 = fast_create(Organization) + SubOrganizationsPlugin::Relation.add_children(org1,org2) + person.stubs('has_permission_without_plugins?').with(:make_ice_cream, org1).returns(true) + person.stubs('has_permission_without_plugins?').with(:make_ice_cream, org2).returns(false) + + assert plugin.has_permission?(person, :make_ice_cream, org2) + end + + should 'not crash if receives an environment as target of has permission' do + assert_nothing_raised do + plugin.has_permission?(fast_create(Person), :make_ice_cream, fast_create(Environment)) + end + end + + should 'display control panel button only to organizations with no parent' do + org1 = fast_create(Organization) + org2 = fast_create(Organization) + profile = fast_create(Profile) + SubOrganizationsPlugin::Relation.add_children(org1,org2) + context = mock() + SubOrganizationsPlugin.any_instance.stubs(:context).returns(context) + + context.stubs(:profile).returns(org1) + assert_not_nil plugin.control_panel_buttons + + context.stubs(:profile).returns(org2) + assert_nil plugin.control_panel_buttons + + context.stubs(:profile).returns(profile) + assert_nil plugin.control_panel_buttons + end +end + diff --git a/plugins/sub_organizations/views/sub_organizations_plugin_myprofile/index.html.erb b/plugins/sub_organizations/views/sub_organizations_plugin_myprofile/index.html.erb new file mode 100644 index 0000000..999c9db --- /dev/null +++ b/plugins/sub_organizations/views/sub_organizations_plugin_myprofile/index.html.erb @@ -0,0 +1,31 @@ +