Commit fd9a3c230f85b124d85f12ae8d4d7e57df7785e3
1 parent
4e225ec6
Exists in
master
and in
28 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 @@ |
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 @@ |
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 @@ |
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 @@ |
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 @@ |
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 @@ |
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 @@ |
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 @@ |
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 @@ |
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 @@ |
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 @@ |
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 @@ |
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 @@ |
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 @@ |
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 @@ |
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 @@ |
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} %> | ... | ... |