diff --git a/app/controllers/taggings_controller.rb b/app/controllers/taggings_controller.rb index 60b4523b2c..653c5b08e4 100644 --- a/app/controllers/taggings_controller.rb +++ b/app/controllers/taggings_controller.rb @@ -26,7 +26,7 @@ def index category_names_all: @category_names_all, pages: pages, number_of_items_per_page: number_of_items_per_page - ) + ).select { |type, _items| allowed_to?(:index?, Tag::TAGGABLE_META.fetch(type)[:klass]) } @sectors = authorized_scope(Sector.all, as: :taggable).order(:name) @categories = authorized_scope(Category.all, as: :taggable) diff --git a/spec/policies/organization_policy_spec.rb b/spec/policies/organization_policy_spec.rb index a66e8d94aa..0bcaa20858 100644 --- a/spec/policies/organization_policy_spec.rb +++ b/spec/policies/organization_policy_spec.rb @@ -81,6 +81,27 @@ def policy_for(record: nil, user:) scope = policy.apply_scope(Organization.all, type: :active_record_relation) expect(scope.to_sql).to eq(Organization.published.to_sql) end + + it "includes organizations with an active affiliation and excludes those without one" do + regular = create(:user) + with_active_affiliation = create(:organization) + create(:affiliation, organization: with_active_affiliation, inactive: false, end_date: nil) + + # An expired affiliation isn't active, and the factory status is never + # "Active", so this org matches neither branch of `published`/`active`. + without_active_affiliation = create(:organization) + create(:affiliation, organization: without_active_affiliation, end_date: 1.day.ago) + + # The scope is broader than "has an active affiliation": an org flagged + # "Active" by status alone still qualifies, even with no affiliations. + active_by_status = create(:organization, organization_status: create(:organization_status, name: "Active")) + + policy = described_class.new(Organization, user: regular) + scope = policy.apply_scope(Organization.all, type: :active_record_relation) + + expect(scope).to include(with_active_affiliation, active_by_status) + expect(scope).not_to include(without_active_affiliation) + end end end end diff --git a/spec/requests/taggings_spec.rb b/spec/requests/taggings_spec.rb index 36af448060..711dfd0b2a 100644 --- a/spec/requests/taggings_spec.rb +++ b/spec/requests/taggings_spec.rb @@ -113,4 +113,53 @@ expect(response.body).to include("Art for Healing") end end + + describe "People and Organizations sections gated by index permission" do + let!(:active_status) { create(:organization_status, name: "Active") } + let!(:organization) do + create(:organization, name: "Healing Org", organization_status: active_status) + end + let!(:person) { create(:person, profile_is_searchable: true) } + + before do + # An active affiliation makes the org active (published) and the person + # visible via with_active_affiliations. + create(:affiliation, person: person, organization: organization) + create(:sectorable_item, sector: sector_1, sectorable: organization) + create(:sectorable_item, sector: sector_1, sectorable: person) + end + + context "as a regular signed-in user (cannot index people or organizations)" do + it "hides the People and Organizations sections but keeps allowed sections" do + get taggings_path(sector_names_all: sector_1.name) + + expect(response.body).not_to include("View all People results") + expect(response.body).not_to include("View all Organizations results") + expect(response.body).to include("Art for Healing") + end + end + + context "as a guest (cannot index people or organizations)" do + it "hides the People and Organizations sections" do + sign_out user + get taggings_path(sector_names_all: sector_1.name) + + expect(response.body).not_to include("View all People results") + expect(response.body).not_to include("View all Organizations results") + end + end + + context "as an admin (can index people and organizations)" do + let!(:admin) { create(:user, :admin) } + + before { sign_in admin } + + it "shows the People and Organizations sections" do + get taggings_path(sector_names_all: sector_1.name) + + expect(response.body).to include("View all People results") + expect(response.body).to include("View all Organizations results") + end + end + end end