diff --git a/app/components/admin/budgets/links_component.html.erb b/app/components/admin/budgets/links_component.html.erb
index bc6799b80..db6b436bd 100644
--- a/app/components/admin/budgets/links_component.html.erb
+++ b/app/components/admin/budgets/links_component.html.erb
@@ -1,8 +1,6 @@
- <% if budget.has_winning_investments? %>
- <%= action(:results,
- text: t("budgets.show.see_results"),
- path: budget_results_path(budget)) %>
+ <% if can?(:read_results, budget) %>
+ <%= action(:results, text: results_text, path: budget_results_path(budget)) %>
<% end %>
<%= action(:preview, text: t("admin.budgets.actions.preview"), path: budget_path(budget), target: "_blank") %>
diff --git a/app/components/admin/budgets/links_component.rb b/app/components/admin/budgets/links_component.rb
index ffec46c93..909a4002b 100644
--- a/app/components/admin/budgets/links_component.rb
+++ b/app/components/admin/budgets/links_component.rb
@@ -1,5 +1,6 @@
class Admin::Budgets::LinksComponent < ApplicationComponent
attr_reader :budget
+ delegate :can?, to: :helpers
def initialize(budget)
@budget = budget
@@ -10,4 +11,12 @@ class Admin::Budgets::LinksComponent < ApplicationComponent
def action(action_name, **options)
render Admin::ActionComponent.new(action_name, budget, **options)
end
+
+ def results_text
+ if Abilities::Everyone.new(User.new).can?(:read_results, budget)
+ t("budgets.show.see_results")
+ else
+ t("admin.budgets.actions.preview_results")
+ end
+ end
end
diff --git a/app/models/abilities/administrator.rb b/app/models/abilities/administrator.rb
index 287611c02..e04545147 100644
--- a/app/models/abilities/administrator.rb
+++ b/app/models/abilities/administrator.rb
@@ -64,6 +64,9 @@ module Abilities
can [:index, :read, :new, :create, :update, :destroy], Budget
can :publish, Budget, id: Budget.drafting.ids
can :calculate_winners, Budget, &:reviewing_ballots?
+ can :read_results, Budget do |budget|
+ budget.balloting_finished? && budget.has_winning_investments?
+ end
can [:read, :create, :update, :destroy], Budget::Group
can [:read, :create, :update, :destroy], Budget::Heading
diff --git a/app/models/budget.rb b/app/models/budget.rb
index 64433042e..9ea47bed7 100644
--- a/app/models/budget.rb
+++ b/app/models/budget.rb
@@ -158,6 +158,10 @@ class Budget < ApplicationRecord
current_phase&.balloting_or_later?
end
+ def balloting_finished?
+ balloting_or_later? && !balloting?
+ end
+
def single_group?
groups.one?
end
diff --git a/app/views/admin/budget_investments/index.html.erb b/app/views/admin/budget_investments/index.html.erb
index 1a5c6686f..4878421cd 100644
--- a/app/views/admin/budget_investments/index.html.erb
+++ b/app/views/admin/budget_investments/index.html.erb
@@ -1,4 +1,4 @@
-<% if @budget.has_winning_investments? %>
+<% if can?(:read_results, @budget) %>
<%= link_to t("admin.budget_investments.index.see_results"),
budget_results_path(@budget, heading_id: @budget.headings.first),
diff --git a/config/locales/en/admin.yml b/config/locales/en/admin.yml
index 27720a9c1..5a1a5e52d 100644
--- a/config/locales/en/admin.yml
+++ b/config/locales/en/admin.yml
@@ -71,6 +71,7 @@ en:
actions:
edit: "Edit budget"
preview: "Preview"
+ preview_results: "Preview results"
index:
title: Participatory budgets
new_link: Create new budget
diff --git a/config/locales/es/admin.yml b/config/locales/es/admin.yml
index 1b8ac73ad..f4af55f64 100644
--- a/config/locales/es/admin.yml
+++ b/config/locales/es/admin.yml
@@ -71,6 +71,7 @@ es:
actions:
edit: "Editar presupuesto"
preview: "Previsualizar"
+ preview_results: "Previsualizar resultados"
index:
title: Presupuestos participativos
new_link: Crear nuevo presupuesto
diff --git a/spec/components/admin/budgets/links_component_spec.rb b/spec/components/admin/budgets/links_component_spec.rb
new file mode 100644
index 000000000..18968f515
--- /dev/null
+++ b/spec/components/admin/budgets/links_component_spec.rb
@@ -0,0 +1,59 @@
+require "rails_helper"
+
+describe Admin::Budgets::LinksComponent, controller: Admin::BaseController do
+ before { sign_in(create(:administrator).user) }
+
+ describe "see results link" do
+ let(:budget) { create(:budget, :finished) }
+ let(:component) { Admin::Budgets::LinksComponent.new(budget) }
+
+ it "is shown for budgets with results enabled" do
+ budget.update!(results_enabled: true)
+
+ render_inline component
+
+ expect(page).to have_link "See results"
+ expect(page).not_to have_link "Preview results"
+ end
+
+ it "is not shown for budgets with results disabled" do
+ budget.update!(results_enabled: false)
+
+ render_inline component
+
+ expect(page).not_to have_link "See results"
+ expect(page).not_to have_link "Preview results"
+ end
+
+ context "after calculating winners" do
+ let(:budget) { create(:budget, :with_winner) }
+
+ it "is shown as a preview link after finishing the process" do
+ budget.update!(phase: "finished", results_enabled: false)
+
+ render_inline component
+
+ expect(page).to have_link "Preview results"
+ expect(page).not_to have_link "See results"
+ end
+
+ it "is shown as a preview link after balloting has finished" do
+ budget.update!(phase: "reviewing_ballots", results_enabled: false)
+
+ render_inline component
+
+ expect(page).to have_link "Preview results"
+ expect(page).not_to have_link "See results"
+ end
+
+ it "is not shown while balloting" do
+ budget.update!(phase: "balloting", results_enabled: true)
+
+ render_inline component
+
+ expect(page).not_to have_link "Preview results"
+ expect(page).not_to have_link "See results"
+ end
+ end
+ end
+end
diff --git a/spec/factories/budgets.rb b/spec/factories/budgets.rb
index ed78d2a32..81f2089ec 100644
--- a/spec/factories/budgets.rb
+++ b/spec/factories/budgets.rb
@@ -64,6 +64,10 @@ FactoryBot.define do
trait :approval do
voting_style { "approval" }
end
+
+ trait :with_winner do
+ after(:create) { |budget| create(:budget_investment, :winner, budget: budget) }
+ end
end
factory :budget_group, class: "Budget::Group" do
diff --git a/spec/models/abilities/administrator_spec.rb b/spec/models/abilities/administrator_spec.rb
index 425400388..7a82b4482 100644
--- a/spec/models/abilities/administrator_spec.rb
+++ b/spec/models/abilities/administrator_spec.rb
@@ -77,7 +77,14 @@ describe Abilities::Administrator do
it { should be_able_to(:create, Budget) }
it { should be_able_to(:update, Budget) }
- it { should be_able_to(:read_results, Budget) }
+
+ it { should be_able_to(:read_results, create(:budget, :reviewing_ballots, :with_winner)) }
+ it { should be_able_to(:read_results, create(:budget, :finished, :with_winner)) }
+ it { should be_able_to(:read_results, create(:budget, :finished, results_enabled: true)) }
+ it { should_not be_able_to(:read_results, create(:budget, :balloting, :with_winner, results_enabled: true)) }
+ it { should_not be_able_to(:read_results, create(:budget, :reviewing_ballots, results_enabled: true)) }
+ it { should_not be_able_to(:read_results, create(:budget, :finished, results_enabled: false)) }
+
it { should be_able_to(:calculate_winners, create(:budget, :reviewing_ballots)) }
it { should_not be_able_to(:calculate_winners, create(:budget, :balloting)) }
it { should_not be_able_to(:calculate_winners, create(:budget, :finished)) }
diff --git a/spec/system/admin/budgets_spec.rb b/spec/system/admin/budgets_spec.rb
index cc024981b..cb0620543 100644
--- a/spec/system/admin/budgets_spec.rb
+++ b/spec/system/admin/budgets_spec.rb
@@ -351,6 +351,14 @@ describe "Admin budgets", :admin do
visit admin_budget_path(budget)
+ expect(page).not_to have_link "See results"
+
+ click_link "Edit budget"
+ select "Finished budget", from: "Active phase"
+ check "Show results"
+ click_button "Update Budget"
+
+ expect(page).to have_content "Participatory budget updated successfully"
expect(page).to have_link "See results"
end