Commit fd9a3c230f85b124d85f12ae8d4d7e57df7785e3
1 parent
4e225ec6
Exists in
master
and in
29 other branches
Sub-organizations plugin
Showing
18 changed files
with
687 additions
and
0 deletions
Show diff stats
plugins/sub_organizations/controllers/sub_organizations_plugin_myprofile_controller.rb
0 → 100644
| @@ -0,0 +1,53 @@ | @@ -0,0 +1,53 @@ | ||
| 1 | +class SubOrganizationsPluginMyprofileController < MyProfileController | ||
| 2 | + append_view_path File.join(File.dirname(__FILE__) + '/../views') | ||
| 3 | + | ||
| 4 | + before_filter :organizations_only | ||
| 5 | + | ||
| 6 | + def index | ||
| 7 | + @children = SubOrganizationsPlugin::Relation.children(profile) | ||
| 8 | + @tokenized_children = prepare_to_token_input(@children) | ||
| 9 | + @pending_children = SubOrganizationsPlugin::ApprovePaternityRelation.pending_children(profile) | ||
| 10 | + if request.post? | ||
| 11 | + begin | ||
| 12 | + original = SubOrganizationsPlugin::Relation.children(profile) | ||
| 13 | + requested = Organization.find(params[:q].split(',')) | ||
| 14 | + added = requested - original | ||
| 15 | + removed = original - requested | ||
| 16 | + added.each do |organization| | ||
| 17 | + if current_person.has_permission?('perform_task',organization) | ||
| 18 | + SubOrganizationsPlugin::Relation.add_children(profile, organization) | ||
| 19 | + else | ||
| 20 | + SubOrganizationsPlugin::ApprovePaternity.create!(:requestor => user, :temp_parent_type => profile.class.name, :temp_parent_id => profile.id, :target => organization) | ||
| 21 | + end | ||
| 22 | + end | ||
| 23 | + SubOrganizationsPlugin::Relation.remove_children(profile,removed) | ||
| 24 | + session[:notice] = _('Sub-organizations updated') | ||
| 25 | + rescue Exception => exception | ||
| 26 | + logger.error(exception.to_s) | ||
| 27 | + session[:notice] = _('Sub-organizations could not be updated') | ||
| 28 | + end | ||
| 29 | + redirect_to :action => :index | ||
| 30 | + end | ||
| 31 | + end | ||
| 32 | + | ||
| 33 | + def search_organization | ||
| 34 | + render :text => prepare_to_token_input(environment.organizations.find(:all, :conditions => | ||
| 35 | + ["(LOWER(name) LIKE ? OR LOWER(identifier) LIKE ?) | ||
| 36 | + AND (identifier NOT LIKE ?) AND (id != ?)", | ||
| 37 | + "%#{params[:q]}%", "%#{params[:q]}%", "%_template", profile.id]). | ||
| 38 | + select { |organization| | ||
| 39 | + SubOrganizationsPlugin::Relation.children(organization).blank? && | ||
| 40 | + !SubOrganizationsPlugin::ApprovePaternityRelation.pending_children(profile).include?(organization) | ||
| 41 | + }).to_json | ||
| 42 | + end | ||
| 43 | + | ||
| 44 | + private | ||
| 45 | + | ||
| 46 | + def organizations_only | ||
| 47 | + render_not_found if !profile.organization? | ||
| 48 | + end | ||
| 49 | + | ||
| 50 | + def prepare_to_token_input(array) | ||
| 51 | + array.map { |object| {:id => object.id, :name => object.name} } | ||
| 52 | + end | ||
| 53 | +end |
plugins/sub_organizations/db/migrate/20120530173629_create_relation.rb
0 → 100644
| @@ -0,0 +1,12 @@ | @@ -0,0 +1,12 @@ | ||
| 1 | +class CreateRelation < ActiveRecord::Migration | ||
| 2 | + def self.up | ||
| 3 | + create_table :sub_organizations_plugin_relations do |t| | ||
| 4 | + t.references :parent, :polymorphic => true | ||
| 5 | + t.references :child, :polymorphic => true | ||
| 6 | + end | ||
| 7 | + end | ||
| 8 | + | ||
| 9 | + def self.down | ||
| 10 | + drop_table :sub_organizations_plugin_relations | ||
| 11 | + end | ||
| 12 | +end |
plugins/sub_organizations/db/migrate/20120615202224_approve_paternity_relation.rb
0 → 100644
| @@ -0,0 +1,13 @@ | @@ -0,0 +1,13 @@ | ||
| 1 | +class ApprovePaternityRelation < ActiveRecord::Migration | ||
| 2 | + def self.up | ||
| 3 | + create_table :sub_organizations_plugin_approve_paternity_relations do |t| | ||
| 4 | + t.references :task | ||
| 5 | + t.references :parent, :polymorphic => true | ||
| 6 | + t.references :child, :polymorphic => true | ||
| 7 | + end | ||
| 8 | + end | ||
| 9 | + | ||
| 10 | + def self.down | ||
| 11 | + drop_table :sub_organizations_plugin_approve_paternity_relations | ||
| 12 | + end | ||
| 13 | +end |
plugins/sub_organizations/lib/sub_organizations_plugin.rb
0 → 100644
| @@ -0,0 +1,46 @@ | @@ -0,0 +1,46 @@ | ||
| 1 | +require_dependency 'sub_organizations_plugin/ext/organization' | ||
| 2 | +require_dependency 'sub_organizations_plugin/ext/create_enterprise' | ||
| 3 | + | ||
| 4 | +class SubOrganizationsPlugin < Noosfero::Plugin | ||
| 5 | + | ||
| 6 | + def self.plugin_name | ||
| 7 | + _("Sub-groups") | ||
| 8 | + end | ||
| 9 | + | ||
| 10 | + def self.plugin_description | ||
| 11 | + _("Adds the ability for groups to have sub-groups.") | ||
| 12 | + end | ||
| 13 | + | ||
| 14 | + def control_panel_buttons | ||
| 15 | + if context.profile.organization? && SubOrganizationsPlugin::Relation.parents(context.profile).blank? | ||
| 16 | + { :title => _('Manage sub-groups'), :icon => 'groups', :url => {:controller => 'sub_organizations_plugin_myprofile'} } | ||
| 17 | + end | ||
| 18 | + end | ||
| 19 | + | ||
| 20 | + def stylesheet? | ||
| 21 | + true | ||
| 22 | + end | ||
| 23 | + | ||
| 24 | + def organization_members(organization) | ||
| 25 | + children = SubOrganizationsPlugin::Relation.children(organization) | ||
| 26 | + Person.members_of(children) if children.present? | ||
| 27 | + end | ||
| 28 | + | ||
| 29 | + def has_permission?(person, permission, target) | ||
| 30 | + if !target.kind_of?(Environment) && target.organization? | ||
| 31 | + SubOrganizationsPlugin::Relation.parents(target).map do |parent| | ||
| 32 | + person.has_permission_without_plugins?(permission, parent) | ||
| 33 | + end.include?(true) | ||
| 34 | + end | ||
| 35 | + end | ||
| 36 | + | ||
| 37 | + def new_community_hidden_fields | ||
| 38 | + parent_to_be = context.params[:sub_organizations_plugin_parent_to_be] | ||
| 39 | + {'sub_organizations_plugin_parent_to_be' => parent_to_be} if parent_to_be.present? | ||
| 40 | + end | ||
| 41 | + | ||
| 42 | + def enterprise_registration_hidden_fields | ||
| 43 | + parent_to_be = context.params[:sub_organizations_plugin_parent_to_be] | ||
| 44 | + {'sub_organizations_plugin_parent_to_be' => parent_to_be} if parent_to_be.present? | ||
| 45 | + end | ||
| 46 | +end |
plugins/sub_organizations/lib/sub_organizations_plugin/approve_paternity.rb
0 → 100644
| @@ -0,0 +1,57 @@ | @@ -0,0 +1,57 @@ | ||
| 1 | +class SubOrganizationsPlugin::ApprovePaternity < Task | ||
| 2 | + validates_presence_of :requestor, :target | ||
| 3 | + | ||
| 4 | + settings_items :temp_parent_id | ||
| 5 | + settings_items :temp_parent_type | ||
| 6 | + | ||
| 7 | + after_create do |task| | ||
| 8 | + r = SubOrganizationsPlugin::ApprovePaternityRelation.create!(:task => task, :parent => task.temp_parent, :child => task.target) | ||
| 9 | + end | ||
| 10 | + | ||
| 11 | + def temp_parent | ||
| 12 | + temp_parent_type.constantize.find(temp_parent_id) | ||
| 13 | + end | ||
| 14 | + | ||
| 15 | + def parent | ||
| 16 | + SubOrganizationsPlugin::ApprovePaternityRelation.parent(self) | ||
| 17 | + end | ||
| 18 | + | ||
| 19 | + def title | ||
| 20 | + _("Paternity request") | ||
| 21 | + end | ||
| 22 | + | ||
| 23 | + def linked_subject | ||
| 24 | + {:text => parent.name, :url => parent.url} | ||
| 25 | + end | ||
| 26 | + | ||
| 27 | + def information | ||
| 28 | + {:message => _('%{requestor} wants to add this organization as a sub-organization of %{linked_subject}.')} | ||
| 29 | + end | ||
| 30 | + | ||
| 31 | + def reject_details | ||
| 32 | + true | ||
| 33 | + end | ||
| 34 | + | ||
| 35 | + def icon | ||
| 36 | + {:type => :profile_image, :profile => parent, :url => parent.url} | ||
| 37 | + end | ||
| 38 | + | ||
| 39 | + def task_created_message | ||
| 40 | + ('%{requestor} wants to add your organization %{target} as a sub-organization of %{parent}.') % {:requestor => requestor.name, :target => target.name, :parent => temp_parent.name} | ||
| 41 | + end | ||
| 42 | + | ||
| 43 | + def task_finished_message | ||
| 44 | + ('%{target} accepted your request to add it as a sub-organization of %{parent}.') % {:target => target.name, :parent => parent.name} | ||
| 45 | + end | ||
| 46 | + | ||
| 47 | + def task_cancelled_message | ||
| 48 | + ('%{target} refused your request to add it as a sub-organization of %{parent}.') % {:target => target.name, :parent => parent.name} | ||
| 49 | + end | ||
| 50 | + | ||
| 51 | + protected | ||
| 52 | + | ||
| 53 | + def perform | ||
| 54 | + SubOrganizationsPlugin::Relation.add_children(parent, target) | ||
| 55 | + end | ||
| 56 | + | ||
| 57 | +end |
plugins/sub_organizations/lib/sub_organizations_plugin/approve_paternity_relation.rb
0 → 100644
| @@ -0,0 +1,23 @@ | @@ -0,0 +1,23 @@ | ||
| 1 | +class SubOrganizationsPlugin::ApprovePaternityRelation < Noosfero::Plugin::ActiveRecord | ||
| 2 | + belongs_to :task | ||
| 3 | + belongs_to :parent, :polymorphic => true | ||
| 4 | + belongs_to :child, :polymorphic => true | ||
| 5 | + | ||
| 6 | + validates_presence_of :task, :parent, :child | ||
| 7 | + | ||
| 8 | + class << self | ||
| 9 | + def parent(task) | ||
| 10 | + find_by_task_id(task.id).parent | ||
| 11 | + end | ||
| 12 | + | ||
| 13 | + def pending_children(parent) | ||
| 14 | + options = { | ||
| 15 | + :select => "distinct profiles.*", | ||
| 16 | + :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", | ||
| 17 | + :conditions => ["relations.parent_id = ? AND tasks.status = 1", parent.id] | ||
| 18 | + } | ||
| 19 | + ActiveRecord::NamedScope::Scope.new(Organization, options) | ||
| 20 | + end | ||
| 21 | + end | ||
| 22 | + | ||
| 23 | +end |
plugins/sub_organizations/lib/sub_organizations_plugin/ext/create_enterprise.rb
0 → 100644
plugins/sub_organizations/lib/sub_organizations_plugin/ext/organization.rb
0 → 100644
| @@ -0,0 +1,13 @@ | @@ -0,0 +1,13 @@ | ||
| 1 | +require_dependency 'organization' | ||
| 2 | +class Organization | ||
| 3 | + settings_items :sub_organizations_plugin_parent_to_be | ||
| 4 | + | ||
| 5 | + after_create do |organization| | ||
| 6 | + if organization.sub_organizations_plugin_parent_to_be.present? | ||
| 7 | + parent = Organization.find(organization.sub_organizations_plugin_parent_to_be) | ||
| 8 | + SubOrganizationsPlugin::Relation.add_children(parent,organization) | ||
| 9 | + end | ||
| 10 | + end | ||
| 11 | + | ||
| 12 | + FIELDS << 'sub_organizations_plugin_parent_to_be' | ||
| 13 | +end |
plugins/sub_organizations/lib/sub_organizations_plugin/relation.rb
0 → 100644
| @@ -0,0 +1,54 @@ | @@ -0,0 +1,54 @@ | ||
| 1 | +class SubOrganizationsPlugin::Relation < Noosfero::Plugin::ActiveRecord | ||
| 2 | + belongs_to :parent, :polymorphic => true | ||
| 3 | + belongs_to :child, :polymorphic => true | ||
| 4 | + | ||
| 5 | + validates_presence_of :parent, :child | ||
| 6 | + validate :no_self_reference | ||
| 7 | + validate :no_cyclical_reference, :if => 'parent.present? && child.present?' | ||
| 8 | + validate :no_multi_level, :if => 'parent.present? && child.present?' | ||
| 9 | + | ||
| 10 | + def no_self_reference | ||
| 11 | + errors.add(:child, _('self-reference is not allowed.')) if parent == child | ||
| 12 | + end | ||
| 13 | + | ||
| 14 | + def no_cyclical_reference | ||
| 15 | + if self.class.children(child).include?(parent) | ||
| 16 | + errors.add(:child, _('cyclical reference is not allowed.')) | ||
| 17 | + end | ||
| 18 | + end | ||
| 19 | + | ||
| 20 | + def no_multi_level | ||
| 21 | + if self.class.parents(parent).present? || self.class.children(child).present? | ||
| 22 | + errors.add(:child, _('multi-level paternity is not allowed.')) | ||
| 23 | + end | ||
| 24 | + end | ||
| 25 | + | ||
| 26 | + class << self | ||
| 27 | + def children(parent) | ||
| 28 | + options = { | ||
| 29 | + :select => "profiles.*", | ||
| 30 | + :joins => "inner join sub_organizations_plugin_relations as relations on profiles.id=relations.child_id", | ||
| 31 | + :conditions => ["relations.parent_id = ?", parent.id] | ||
| 32 | + } | ||
| 33 | + ActiveRecord::NamedScope::Scope.new(Organization, options) | ||
| 34 | + end | ||
| 35 | + | ||
| 36 | + def parents(child) | ||
| 37 | + options = { | ||
| 38 | + :select => "profiles.*", | ||
| 39 | + :joins => "inner join sub_organizations_plugin_relations as relations on profiles.id=relations.parent_id", | ||
| 40 | + :conditions => ["relations.child_id = ?", child.id] | ||
| 41 | + } | ||
| 42 | + ActiveRecord::NamedScope::Scope.new(Organization, options) | ||
| 43 | + end | ||
| 44 | + | ||
| 45 | + def add_children(parent, *children) | ||
| 46 | + children.each {|child| create!(:parent => parent, :child => child)} | ||
| 47 | + end | ||
| 48 | + | ||
| 49 | + def remove_children(parent, *children) | ||
| 50 | + children.flatten.each {|child| find_by_parent_id_and_child_id(parent.id, child.id).destroy} | ||
| 51 | + end | ||
| 52 | + end | ||
| 53 | + | ||
| 54 | +end |
plugins/sub_organizations/test/functional/sub_organizations_plugin_myprofile_controller_test.rb
0 → 100644
| @@ -0,0 +1,89 @@ | @@ -0,0 +1,89 @@ | ||
| 1 | +require File.dirname(__FILE__) + '/../../../../test/test_helper' | ||
| 2 | +require File.dirname(__FILE__) + '/../../controllers/sub_organizations_plugin_myprofile_controller' | ||
| 3 | + | ||
| 4 | +# Re-raise errors caught by the controller. | ||
| 5 | +class SubOrganizationsPluginMyprofileController; def rescue_action(e) raise e end; end | ||
| 6 | + | ||
| 7 | +class SubOrganizationsPluginMyprofileControllerTest < ActionController::TestCase | ||
| 8 | + def setup | ||
| 9 | + @controller = SubOrganizationsPluginMyprofileController.new | ||
| 10 | + @request = ActionController::TestRequest.new | ||
| 11 | + @response = ActionController::TestResponse.new | ||
| 12 | + @organization = Organization.create!(:name => 'My Organization', :identifier => 'my-organization') | ||
| 13 | + @person = create_user('person').person | ||
| 14 | + @organization.add_admin(@person) | ||
| 15 | + login_as(@person.user.login) | ||
| 16 | + e = Environment.default | ||
| 17 | + e.enable_plugin('SubOrganizationsPlugin') | ||
| 18 | + e.save! | ||
| 19 | + end | ||
| 20 | + | ||
| 21 | + attr_accessor :person, :organization | ||
| 22 | + | ||
| 23 | + should 'search organizations' do | ||
| 24 | + # Should list if match name | ||
| 25 | + o1 = fast_create(Organization, :name => 'sample organization 1') | ||
| 26 | + # Should be case insensitive | ||
| 27 | + o2 = fast_create(Organization, :name => 'SaMpLe OrGaNiZaTiOn 2') | ||
| 28 | + # Should not list if don't match name | ||
| 29 | + o3 = fast_create(Organization, :name => 'blo') | ||
| 30 | + # Should not list if is has children | ||
| 31 | + child = fast_create(Organization) | ||
| 32 | + o4 = fast_create(Organization, :name => 'sample organization 4') | ||
| 33 | + SubOrganizationsPlugin::Relation.add_children(o4, child) | ||
| 34 | + # Should not list if is there is a task to add it | ||
| 35 | + o5 = fast_create(Organization, :name => 'sample enterprise 5') | ||
| 36 | + SubOrganizationsPlugin::ApprovePaternity.create!(:requestor => person, :target => o5, :temp_parent_id => organization.id, :temp_parent_type => organization.class.name) | ||
| 37 | + # Should search by identifier | ||
| 38 | + o6 = fast_create(Organization, :name => 'Bla', :identifier => 'sample-enterprise-6') | ||
| 39 | + # Should not list itself | ||
| 40 | + organization.name = 'Sample Organization' | ||
| 41 | + organization.save! | ||
| 42 | + | ||
| 43 | + get :search_organization, :profile => organization.identifier, :q => 'sampl' | ||
| 44 | + | ||
| 45 | + assert_match /#{o1.name}/, @response.body | ||
| 46 | + assert_match /#{o2.name}/, @response.body | ||
| 47 | + assert_no_match /#{o3.name}/, @response.body | ||
| 48 | + assert_no_match /#{o4.name}/, @response.body | ||
| 49 | + assert_no_match /#{o5.name}/, @response.body | ||
| 50 | + assert_match /#{o6.name}/, @response.body | ||
| 51 | + assert_no_match /#{organization.name}/, @response.body | ||
| 52 | + end | ||
| 53 | + | ||
| 54 | + should 'update sub-organizations list' do | ||
| 55 | + org1 = fast_create(Organization) | ||
| 56 | + org2 = fast_create(Organization) | ||
| 57 | + org3 = fast_create(Organization) | ||
| 58 | + org4 = fast_create(Organization) | ||
| 59 | + SubOrganizationsPlugin::Relation.add_children(organization, org1, org2) | ||
| 60 | + | ||
| 61 | + post :index, :profile => organization.identifier, :q => [org2,org3,org4].map(&:id).join(',') | ||
| 62 | + | ||
| 63 | + children = SubOrganizationsPlugin::Relation.children(organization) | ||
| 64 | + assert_not_includes children, org1 | ||
| 65 | + assert_includes children, org2 | ||
| 66 | + assert_not_includes children, org3 | ||
| 67 | + assert_not_includes children, org4 | ||
| 68 | + | ||
| 69 | + SubOrganizationsPlugin::ApprovePaternity.all.map(&:finish) | ||
| 70 | + | ||
| 71 | + children = SubOrganizationsPlugin::Relation.children(organization) | ||
| 72 | + assert_not_includes children, org1 | ||
| 73 | + assert_includes children, org2 | ||
| 74 | + assert_includes children, org3 | ||
| 75 | + assert_includes children, org4 | ||
| 76 | + end | ||
| 77 | + | ||
| 78 | + should 'establish relation right away if the user can perform tasks on the sub-organization' do | ||
| 79 | + org1 = fast_create(Organization) | ||
| 80 | + org2 = fast_create(Organization) | ||
| 81 | + org2.add_admin(person) | ||
| 82 | + | ||
| 83 | + assert_difference SubOrganizationsPlugin::ApprovePaternity, :count, 1 do | ||
| 84 | + post :index, :profile => organization.identifier, :q => [org1,org2].map(&:id).join(',') | ||
| 85 | + end | ||
| 86 | + assert_includes SubOrganizationsPlugin::Relation.children(organization), org2 | ||
| 87 | + end | ||
| 88 | + | ||
| 89 | +end |
plugins/sub_organizations/test/unit/sub_organizations_plugin/approve_paternity_relation_test.rb
0 → 100644
| @@ -0,0 +1,32 @@ | @@ -0,0 +1,32 @@ | ||
| 1 | +require File.dirname(__FILE__) + '/../../../../../test/test_helper' | ||
| 2 | + | ||
| 3 | +class SubOrganizationsPlugin::ApprovePaternityRelationTest < ActiveSupport::TestCase | ||
| 4 | + | ||
| 5 | + def setup | ||
| 6 | + @requestor = create_user('some-user').person | ||
| 7 | + end | ||
| 8 | + | ||
| 9 | + attr_reader :requestor | ||
| 10 | + | ||
| 11 | + should 'return parent' do | ||
| 12 | + org1 = fast_create(Organization) | ||
| 13 | + org2 = fast_create(Organization) | ||
| 14 | + task = SubOrganizationsPlugin::ApprovePaternity.create!(:requestor => requestor, :target => org2, :temp_parent_id => org1.id, :temp_parent_type => org1.class.name) | ||
| 15 | + | ||
| 16 | + assert_equal SubOrganizationsPlugin::ApprovePaternityRelation.parent(task), org1 | ||
| 17 | + end | ||
| 18 | + | ||
| 19 | + should 'list pending children' do | ||
| 20 | + organization = fast_create(Organization) | ||
| 21 | + org1 = fast_create(Organization) | ||
| 22 | + org2 = fast_create(Organization) | ||
| 23 | + org3 = fast_create(Organization) | ||
| 24 | + | ||
| 25 | + SubOrganizationsPlugin::ApprovePaternity.create!(:requestor => requestor, :target => org1, :temp_parent_id => organization.id, :temp_parent_type => organization.class.name) | ||
| 26 | + SubOrganizationsPlugin::ApprovePaternity.create!(:requestor => requestor, :target => org2, :temp_parent_id => organization.id, :temp_parent_type => organization.class.name) | ||
| 27 | + | ||
| 28 | + assert_includes SubOrganizationsPlugin::ApprovePaternityRelation.pending_children(organization), org1 | ||
| 29 | + assert_includes SubOrganizationsPlugin::ApprovePaternityRelation.pending_children(organization), org2 | ||
| 30 | + assert_not_includes SubOrganizationsPlugin::ApprovePaternityRelation.pending_children(organization), org3 | ||
| 31 | + end | ||
| 32 | +end |
plugins/sub_organizations/test/unit/sub_organizations_plugin/approve_paternity_test.rb
0 → 100644
| @@ -0,0 +1,29 @@ | @@ -0,0 +1,29 @@ | ||
| 1 | +require File.dirname(__FILE__) + '/../../../../../test/test_helper' | ||
| 2 | + | ||
| 3 | +class SubOrganizationsPlugin::ApprovePaternityTest < ActiveSupport::TestCase | ||
| 4 | + | ||
| 5 | + def setup | ||
| 6 | + @requestor = create_user('some-user').person | ||
| 7 | + end | ||
| 8 | + | ||
| 9 | + attr_reader :requestor | ||
| 10 | + | ||
| 11 | + should 'create relation after creation' do | ||
| 12 | + org1 = fast_create(Organization) | ||
| 13 | + org2 = fast_create(Organization) | ||
| 14 | + assert_difference SubOrganizationsPlugin::ApprovePaternityRelation, :count, 1 do | ||
| 15 | + SubOrganizationsPlugin::ApprovePaternity.create!(:requestor => requestor, :temp_parent_id => org1.id, :temp_parent_type => org1.class.name, :target => org2) | ||
| 16 | + end | ||
| 17 | + end | ||
| 18 | + | ||
| 19 | + should 'add children to parent after approving' do | ||
| 20 | + org1 = fast_create(Organization) | ||
| 21 | + org2 = fast_create(Organization) | ||
| 22 | + | ||
| 23 | + task = SubOrganizationsPlugin::ApprovePaternity.create!(:requestor => requestor, :temp_parent_id => org1.id, :temp_parent_type => org1.class.name, :target => org2) | ||
| 24 | + assert_not_includes SubOrganizationsPlugin::Relation.children(org1), org2 | ||
| 25 | + | ||
| 26 | + task.finish | ||
| 27 | + assert_includes SubOrganizationsPlugin::Relation.children(org1), org2 | ||
| 28 | + end | ||
| 29 | +end |
plugins/sub_organizations/test/unit/sub_organizations_plugin/ext/create_enterprise_test.rb
0 → 100644
| @@ -0,0 +1,11 @@ | @@ -0,0 +1,11 @@ | ||
| 1 | +require File.dirname(__FILE__) + '/../../../../../../test/test_helper' | ||
| 2 | + | ||
| 3 | +class CreateEnterpriseTest < ActiveSupport::TestCase | ||
| 4 | + | ||
| 5 | + should 'inlude the parent field in create enterprise' do | ||
| 6 | + create_enterprise = CreateEnterprise.new | ||
| 7 | + assert_nothing_raised { create_enterprise.sub_organizations_plugin_parent_to_be = '999' } | ||
| 8 | + end | ||
| 9 | + | ||
| 10 | +end | ||
| 11 | + |
plugins/sub_organizations/test/unit/sub_organizations_plugin/ext/organization.rb
0 → 100644
| @@ -0,0 +1,23 @@ | @@ -0,0 +1,23 @@ | ||
| 1 | +require File.dirname(__FILE__) + '/../../../../../../test/test_helper' | ||
| 2 | + | ||
| 3 | +class OrganizationTest < ActiveSupport::TestCase | ||
| 4 | + | ||
| 5 | + should 'inlude the parent field in organization' do | ||
| 6 | + organization = Organization.new | ||
| 7 | + assert_nothing_raised { organization.sub_organizations_plugin_parent_to_be = '999' } | ||
| 8 | + end | ||
| 9 | + | ||
| 10 | + should 'include the parent field in the FIELDS constant' do | ||
| 11 | + assert_includes Organization::FIELDS, 'sub_organizations_plugin_parent_to_be' | ||
| 12 | + end | ||
| 13 | + | ||
| 14 | + should 'relate organization with parent if the attribute is set' do | ||
| 15 | + parent = fast_create(Organization) | ||
| 16 | + organization = Organization.new(:identifier => 'some-org',:name => 'Some Org', :sub_organizations_plugin_parent_to_be => parent.id) | ||
| 17 | + assert_not_includes SubOrganizationsPlugin::Relation.children(parent), organization | ||
| 18 | + | ||
| 19 | + organization.save! | ||
| 20 | + assert_includes SubOrganizationsPlugin::Relation.children(parent), organization | ||
| 21 | + end | ||
| 22 | + | ||
| 23 | +end |
plugins/sub_organizations/test/unit/sub_organizations_plugin/relation_test.rb
0 → 100644
| @@ -0,0 +1,110 @@ | @@ -0,0 +1,110 @@ | ||
| 1 | +require File.dirname(__FILE__) + '/../../../../../test/test_helper' | ||
| 2 | + | ||
| 3 | +class SubOrganizationsPlugin::RelationTest < ActiveSupport::TestCase | ||
| 4 | + | ||
| 5 | + should 'validates presence of child and parent' do | ||
| 6 | + org = fast_create(Organization) | ||
| 7 | + relation = SubOrganizationsPlugin::Relation.new | ||
| 8 | + | ||
| 9 | + relation.parent = org | ||
| 10 | + relation.valid? | ||
| 11 | + assert relation.errors.invalid?(:child) | ||
| 12 | + | ||
| 13 | + relation.parent = nil | ||
| 14 | + relation.child = org | ||
| 15 | + relation.valid? | ||
| 16 | + assert relation.errors.invalid?(:parent) | ||
| 17 | + end | ||
| 18 | + | ||
| 19 | + should 'relate two organizations' do | ||
| 20 | + org1 = fast_create(Organization) | ||
| 21 | + org2 = fast_create(Organization) | ||
| 22 | + relation = SubOrganizationsPlugin::Relation.create!(:parent => org1, :child => org2) | ||
| 23 | + | ||
| 24 | + assert_equal org1, relation.parent | ||
| 25 | + assert_equal org2, relation.child | ||
| 26 | + end | ||
| 27 | + | ||
| 28 | + should 'not allow self relation' do | ||
| 29 | + org = fast_create(Organization) | ||
| 30 | + relation = SubOrganizationsPlugin::Relation.new(:parent_id => org, :child_id => org) | ||
| 31 | + assert !relation.valid? | ||
| 32 | + assert relation.errors.invalid?(:child) | ||
| 33 | + end | ||
| 34 | + | ||
| 35 | + should 'be able to retrieve parents of an organization' do | ||
| 36 | + child = fast_create(Organization) | ||
| 37 | + parent1 = fast_create(Organization) | ||
| 38 | + parent2 = fast_create(Organization) | ||
| 39 | + SubOrganizationsPlugin::Relation.create!(:parent => parent1, :child => child) | ||
| 40 | + SubOrganizationsPlugin::Relation.create!(:parent => parent2, :child => child) | ||
| 41 | + | ||
| 42 | + assert_includes SubOrganizationsPlugin::Relation.parents(child), parent1 | ||
| 43 | + assert_includes SubOrganizationsPlugin::Relation.parents(child), parent2 | ||
| 44 | + end | ||
| 45 | + | ||
| 46 | + should 'be able to retrieve children of an organization' do | ||
| 47 | + parent = fast_create(Organization) | ||
| 48 | + child1 = fast_create(Organization) | ||
| 49 | + child2 = fast_create(Organization) | ||
| 50 | + SubOrganizationsPlugin::Relation.create!(:parent => parent, :child => child1) | ||
| 51 | + SubOrganizationsPlugin::Relation.create!(:parent => parent, :child => child2) | ||
| 52 | + | ||
| 53 | + assert_includes SubOrganizationsPlugin::Relation.children(parent), child1 | ||
| 54 | + assert_includes SubOrganizationsPlugin::Relation.children(parent), child2 | ||
| 55 | + end | ||
| 56 | + | ||
| 57 | + should 'not allow cyclical reference' do | ||
| 58 | + org1 = fast_create(Organization) | ||
| 59 | + org2 = fast_create(Organization) | ||
| 60 | + SubOrganizationsPlugin::Relation.create!(:parent => org1, :child => org2) | ||
| 61 | + relation = SubOrganizationsPlugin::Relation.new(:parent => org2, :child => org1) | ||
| 62 | + | ||
| 63 | + assert !relation.valid? | ||
| 64 | + assert relation.errors.invalid?(:child) | ||
| 65 | + end | ||
| 66 | + | ||
| 67 | + should 'not allow multi-level paternity' do | ||
| 68 | + org1 = fast_create(Organization) | ||
| 69 | + org2 = fast_create(Organization) | ||
| 70 | + org3 = fast_create(Organization) | ||
| 71 | + SubOrganizationsPlugin::Relation.create!(:parent => org1, :child => org2) | ||
| 72 | + r1 = SubOrganizationsPlugin::Relation.new(:parent => org2, :child => org3) | ||
| 73 | + r2 = SubOrganizationsPlugin::Relation.new(:parent => org3, :child => org1) | ||
| 74 | + | ||
| 75 | + assert !r1.valid? | ||
| 76 | + assert r1.errors.invalid?(:child) | ||
| 77 | + | ||
| 78 | + assert !r2.valid? | ||
| 79 | + assert r2.errors.invalid?(:child) | ||
| 80 | + end | ||
| 81 | + | ||
| 82 | + should 'add children' do | ||
| 83 | + org1 = fast_create(Organization) | ||
| 84 | + org2 = fast_create(Organization) | ||
| 85 | + org3 = fast_create(Organization) | ||
| 86 | + org4 = fast_create(Organization) | ||
| 87 | + | ||
| 88 | + SubOrganizationsPlugin::Relation.add_children(org1,org2) | ||
| 89 | + assert_includes SubOrganizationsPlugin::Relation.children(org1), org2 | ||
| 90 | + | ||
| 91 | + SubOrganizationsPlugin::Relation.add_children(org1,org3,org4) | ||
| 92 | + assert_includes SubOrganizationsPlugin::Relation.children(org1), org3 | ||
| 93 | + assert_includes SubOrganizationsPlugin::Relation.children(org1), org4 | ||
| 94 | + end | ||
| 95 | + | ||
| 96 | + should 'remove children' do | ||
| 97 | + org1 = fast_create(Organization) | ||
| 98 | + org2 = fast_create(Organization) | ||
| 99 | + org3 = fast_create(Organization) | ||
| 100 | + org4 = fast_create(Organization) | ||
| 101 | + SubOrganizationsPlugin::Relation.add_children(org1,org2,org3,org4) | ||
| 102 | + | ||
| 103 | + SubOrganizationsPlugin::Relation.remove_children(org1,org2) | ||
| 104 | + assert_not_includes SubOrganizationsPlugin::Relation.children(org1), org2 | ||
| 105 | + | ||
| 106 | + SubOrganizationsPlugin::Relation.remove_children(org1,org3,org4) | ||
| 107 | + assert_not_includes SubOrganizationsPlugin::Relation.children(org1), org3 | ||
| 108 | + assert_not_includes SubOrganizationsPlugin::Relation.children(org1), org4 | ||
| 109 | + end | ||
| 110 | +end |
plugins/sub_organizations/test/unit/sub_organizations_plugin_test.rb
0 → 100644
| @@ -0,0 +1,83 @@ | @@ -0,0 +1,83 @@ | ||
| 1 | +require File.dirname(__FILE__) + '/../../../../test/test_helper' | ||
| 2 | + | ||
| 3 | +class SubOrganizationsTest < ActiveSupport::TestCase | ||
| 4 | + | ||
| 5 | + def setup | ||
| 6 | + @plugin = SubOrganizationsPlugin.new | ||
| 7 | + end | ||
| 8 | + | ||
| 9 | + attr_reader :plugin | ||
| 10 | + | ||
| 11 | + should 'include sub-organizations members in the parent organization' do | ||
| 12 | + org1 = fast_create(Organization) | ||
| 13 | + org2 = fast_create(Organization) | ||
| 14 | + org3 = fast_create(Organization) | ||
| 15 | + member1 = fast_create(Person) | ||
| 16 | + member2 = fast_create(Person) | ||
| 17 | + member3 = fast_create(Person) | ||
| 18 | + member4 = fast_create(Person) | ||
| 19 | + member5 = fast_create(Person) | ||
| 20 | + member6 = fast_create(Person) | ||
| 21 | + member7 = fast_create(Person) | ||
| 22 | + org1.add_member(member1) | ||
| 23 | + org2.add_member(member2) | ||
| 24 | + org2.add_member(member3) | ||
| 25 | + org3.add_member(member4) | ||
| 26 | + org3.add_member(member5) | ||
| 27 | + SubOrganizationsPlugin::Relation.create!(:parent => org1, :child => org2) | ||
| 28 | + SubOrganizationsPlugin::Relation.create!(:parent => org1, :child => org3) | ||
| 29 | + | ||
| 30 | + org1_members = plugin.organization_members(org1) | ||
| 31 | + | ||
| 32 | + assert_equal ActiveRecord::NamedScope::Scope, org1_members.class | ||
| 33 | + assert_not_includes org1_members, member1 | ||
| 34 | + assert_includes org1_members, member2 | ||
| 35 | + assert_includes org1_members, member3 | ||
| 36 | + assert_includes org1_members, member4 | ||
| 37 | + assert_includes org1_members, member5 | ||
| 38 | + assert_not_includes org1_members, member6 | ||
| 39 | + assert_not_includes org1_members, member7 | ||
| 40 | + | ||
| 41 | + org2_members = plugin.organization_members(org2) | ||
| 42 | + org3_members = plugin.organization_members(org3) | ||
| 43 | + | ||
| 44 | + assert org2_members.blank? | ||
| 45 | + assert org3_members.blank? | ||
| 46 | + end | ||
| 47 | + | ||
| 48 | + should 'grant permission that user has on parent organizations over children orgnaizations' do | ||
| 49 | + person = create_user('admin-user').person | ||
| 50 | + org1 = fast_create(Organization) | ||
| 51 | + org2 = fast_create(Organization) | ||
| 52 | + SubOrganizationsPlugin::Relation.add_children(org1,org2) | ||
| 53 | + person.stubs('has_permission_without_plugins?').with(:make_ice_cream, org1).returns(true) | ||
| 54 | + person.stubs('has_permission_without_plugins?').with(:make_ice_cream, org2).returns(false) | ||
| 55 | + | ||
| 56 | + assert plugin.has_permission?(person, :make_ice_cream, org2) | ||
| 57 | + end | ||
| 58 | + | ||
| 59 | + should 'not crash if receives an environment as target of has permission' do | ||
| 60 | + assert_nothing_raised do | ||
| 61 | + plugin.has_permission?(fast_create(Person), :make_ice_cream, fast_create(Environment)) | ||
| 62 | + end | ||
| 63 | + end | ||
| 64 | + | ||
| 65 | + should 'display control panel button only to organizations with no parent' do | ||
| 66 | + org1 = fast_create(Organization) | ||
| 67 | + org2 = fast_create(Organization) | ||
| 68 | + profile = fast_create(Profile) | ||
| 69 | + SubOrganizationsPlugin::Relation.add_children(org1,org2) | ||
| 70 | + context = mock() | ||
| 71 | + SubOrganizationsPlugin.any_instance.stubs(:context).returns(context) | ||
| 72 | + | ||
| 73 | + context.stubs(:profile).returns(org1) | ||
| 74 | + assert_not_nil plugin.control_panel_buttons | ||
| 75 | + | ||
| 76 | + context.stubs(:profile).returns(org2) | ||
| 77 | + assert_nil plugin.control_panel_buttons | ||
| 78 | + | ||
| 79 | + context.stubs(:profile).returns(profile) | ||
| 80 | + assert_nil plugin.control_panel_buttons | ||
| 81 | + end | ||
| 82 | +end | ||
| 83 | + |
plugins/sub_organizations/views/sub_organizations_plugin_myprofile/index.html.erb
0 → 100644
| @@ -0,0 +1,31 @@ | @@ -0,0 +1,31 @@ | ||
| 1 | +<h1><%= _('Manage sub-groups') %></h1> | ||
| 2 | + | ||
| 3 | +<% if !@pending_children.blank? %> | ||
| 4 | + <%= _('Sub-groups awaiting approval:') %> | ||
| 5 | + <ul> | ||
| 6 | + <% @pending_children.each do |child| %> | ||
| 7 | + <li><%= link_to(child.name, child.url) %></li> | ||
| 8 | + <% end %> | ||
| 9 | + </ul> | ||
| 10 | +<% end %> | ||
| 11 | + | ||
| 12 | +<% form_tag do %> | ||
| 13 | + <% button_bar do %> | ||
| 14 | + <%= button(:add, __('Create a new sub-community'), :controller => 'memberships', :action => 'new_community', :profile => user.identifier, :sub_organizations_plugin_parent_to_be => profile.id) %> | ||
| 15 | + <%= button :add, __('Register a new sub-enterprise'), :controller => 'enterprise_registration', :sub_organizations_plugin_parent_to_be => profile.id if environment.enabled?('enterprise_registration') %> | ||
| 16 | + <% end %> | ||
| 17 | + | ||
| 18 | + <%= token_input_field_tag(:q, 'search-organization', {:action => 'search_organization'}, | ||
| 19 | + { :focus => true, | ||
| 20 | + :hint_text => _('Type in a search term for a group'), | ||
| 21 | + :pre_populate => @tokenized_children}) %> | ||
| 22 | + | ||
| 23 | + <% button_bar do %> | ||
| 24 | + <%= submit_button('save', _('Save'))%> | ||
| 25 | + <%= button('cancel', _('Cancel'), {:controller => 'profile_editor'})%> | ||
| 26 | + <% end %> | ||
| 27 | +<% end %> | ||
| 28 | + | ||
| 29 | +<br style='clear: both'/> | ||
| 30 | + | ||
| 31 | +<%= render :partial => 'shared/list_groups', :locals => {:profile => user, :groups => @children} %> |