diff --git a/app/components/valuation/budgets/index_component.html.erb b/app/components/valuation/budgets/index_component.html.erb
new file mode 100644
index 000000000..81e82f745
--- /dev/null
+++ b/app/components/valuation/budgets/index_component.html.erb
@@ -0,0 +1,21 @@
+
<%= t("valuation.budgets.index.title") %>
+
+<% if budgets.any? %>
+
+
+
+ | <%= t("valuation.budgets.index.table_name") %> |
+ <%= t("valuation.budgets.index.table_phase") %> |
+ <%= t("valuation.budgets.index.table_assigned_investments_valuation_open") %> |
+ <%= t("valuation.budgets.index.table_actions") %> |
+
+
+
+ <%= render Valuation::Budgets::RowComponent.with_collection(budgets) %>
+
+
+<% else %>
+
+ <%= t("valuation.budgets.index.no_budgets") %>
+
+<% end %>
diff --git a/app/components/valuation/budgets/index_component.rb b/app/components/valuation/budgets/index_component.rb
new file mode 100644
index 000000000..e8afdfce6
--- /dev/null
+++ b/app/components/valuation/budgets/index_component.rb
@@ -0,0 +1,7 @@
+class Valuation::Budgets::IndexComponent < ApplicationComponent
+ attr_reader :budgets
+
+ def initialize(budgets)
+ @budgets = budgets
+ end
+end
diff --git a/app/components/valuation/budgets/row_component.html.erb b/app/components/valuation/budgets/row_component.html.erb
new file mode 100644
index 000000000..5ba9933f8
--- /dev/null
+++ b/app/components/valuation/budgets/row_component.html.erb
@@ -0,0 +1,18 @@
+
+ |
+ <%= budget.name %>
+ |
+
+ <%= budget.current_phase.name %>
+ |
+
+ <%= investments.count %>
+ |
+
+ <% if investments.any? %>
+ <%= link_to t("valuation.budgets.index.evaluate"),
+ valuation_budget_budget_investments_path(budget_id: budget.id),
+ class: "button hollow expanded" %>
+ <% end %>
+ |
+
diff --git a/app/components/valuation/budgets/row_component.rb b/app/components/valuation/budgets/row_component.rb
new file mode 100644
index 000000000..4b75b196e
--- /dev/null
+++ b/app/components/valuation/budgets/row_component.rb
@@ -0,0 +1,16 @@
+class Valuation::Budgets::RowComponent < ApplicationComponent
+ attr_reader :budget
+ with_collection_parameter :budget
+
+ delegate :current_user, to: :helpers
+
+ def initialize(budget:)
+ @budget = budget
+ end
+
+ def investments
+ return Budget::Investment.none unless budget.valuating?
+
+ budget.investments.visible_to_valuators.by_valuator(current_user.valuator).valuation_open
+ end
+end
diff --git a/app/controllers/valuation/budget_investments_controller.rb b/app/controllers/valuation/budget_investments_controller.rb
index 6fe23df54..f1ff5d834 100644
--- a/app/controllers/valuation/budget_investments_controller.rb
+++ b/app/controllers/valuation/budget_investments_controller.rb
@@ -4,9 +4,9 @@ class Valuation::BudgetInvestmentsController < Valuation::BaseController
feature_flag :budgets
+ before_action :load_budget
before_action :restrict_access_to_assigned_items, only: [:show, :edit, :valuate]
before_action :restrict_access, only: [:edit, :valuate]
- before_action :load_budget
before_action :load_investment, only: [:show, :edit, :valuate]
has_orders %w[oldest], only: [:show, :edit]
@@ -110,7 +110,7 @@ class Valuation::BudgetInvestmentsController < Valuation::BaseController
end
def restrict_access
- unless current_user.administrator? || current_budget.valuating?
+ unless current_user.administrator? || @budget.valuating?
raise CanCan::AccessDenied, I18n.t("valuation.budget_investments.not_in_valuating_phase")
end
end
diff --git a/app/controllers/valuation/budgets_controller.rb b/app/controllers/valuation/budgets_controller.rb
index 0165fb0e2..729c39112 100644
--- a/app/controllers/valuation/budgets_controller.rb
+++ b/app/controllers/valuation/budgets_controller.rb
@@ -5,9 +5,6 @@ class Valuation::BudgetsController < Valuation::BaseController
load_and_authorize_resource
def index
- @budget = current_budget
- if @budget.present?
- @investments = @budget.investments.by_valuator(current_user.valuator).valuation_open
- end
+ @budgets = @budgets.published.order(created_at: :desc)
end
end
diff --git a/app/views/valuation/budgets/index.html.erb b/app/views/valuation/budgets/index.html.erb
index fae10257b..e435d1276 100644
--- a/app/views/valuation/budgets/index.html.erb
+++ b/app/views/valuation/budgets/index.html.erb
@@ -1,36 +1 @@
-<%= t("valuation.budgets.index.title") %>
-
-<% if @budget.present? %>
-
-
-
- | <%= t("valuation.budgets.index.table_name") %> |
- <%= t("valuation.budgets.index.table_phase") %> |
- <%= t("valuation.budgets.index.table_assigned_investments_valuation_open") %> |
- <%= t("valuation.budgets.index.table_actions") %> |
-
-
-
-
- |
- <%= @budget.name %>
- |
-
- <%= @budget.current_phase.name %>
- |
-
- <%= @investments.count %>
- |
-
- <%= link_to t("valuation.budgets.index.evaluate"),
- valuation_budget_budget_investments_path(budget_id: @budget.id),
- class: "button hollow expanded" %>
- |
-
-
-
-<% else %>
-
- <%= t("valuation.budgets.index.no_budgets") %>
-
-<% end %>
+<%= render Valuation::Budgets::IndexComponent.new(@budgets) %>
diff --git a/spec/components/valuation/budgets/row_component_spec.rb b/spec/components/valuation/budgets/row_component_spec.rb
new file mode 100644
index 000000000..4d0f1a7af
--- /dev/null
+++ b/spec/components/valuation/budgets/row_component_spec.rb
@@ -0,0 +1,50 @@
+require "rails_helper"
+
+describe Valuation::Budgets::RowComponent do
+ let(:valuator) { create(:valuator) }
+
+ before { sign_in(valuator.user) }
+
+ it "Displays visible and assigned investments count when budget is in valuating phase" do
+ budget = create(:budget, :valuating, name: "Sports")
+ create(:budget_investment, :visible_to_valuators, budget: budget, valuators: [valuator])
+ create(:budget_investment, :invisible_to_valuators, budget: budget, valuators: [valuator])
+ create(:budget_investment, :visible_to_valuators, budget: budget)
+
+ render_inline Valuation::Budgets::RowComponent.new(budget: budget)
+
+ expect(page).to have_selector(".investments-count", text: "1")
+ end
+
+ it "Displays zero as investments count when budget is not in valuating phase" do
+ budget = create(:budget, %i[accepting finished].sample, name: "Sports")
+ create(:budget_investment, :visible_to_valuators, budget: budget, valuators: [valuator])
+
+ render_inline Valuation::Budgets::RowComponent.new(budget: budget)
+
+ expect(page).to have_selector(".investments-count", text: "0")
+ end
+
+ it "Displays the link to evaluate investments when valuator has visible investments assigned and budget is
+ in valuating phase" do
+ valuating = create(:budget, :valuating)
+ create(:budget_investment, :visible_to_valuators, budget: valuating, valuators: [valuator])
+ valuating_invisible = create(:budget, :valuating)
+ create(:budget_investment, :invisible_to_valuators, budget: valuating_invisible, valuators: [valuator])
+ valuating_unassigned = create(:budget, :valuating)
+ create(:budget_investment, :visible_to_valuators, budget: valuating_unassigned)
+ accepting = create(:budget, :accepting)
+ create(:budget_investment, :visible_to_valuators, budget: accepting, valuators: [valuator])
+ finished = create(:budget, :finished)
+ create(:budget_investment, :visible_to_valuators, budget: finished, valuators: [valuator])
+ budgets = [valuating, valuating_invisible, valuating_unassigned, accepting, finished]
+
+ render_inline Valuation::Budgets::RowComponent.with_collection(budgets)
+
+ expect(page.find("#budget_#{valuating.id}")).to have_link("Evaluate")
+ expect(page.find("#budget_#{valuating_invisible.id}")).not_to have_link("Evaluate")
+ expect(page.find("#budget_#{valuating_unassigned.id}")).not_to have_link("Evaluate")
+ expect(page.find("#budget_#{accepting.id}")).not_to have_link("Evaluate")
+ expect(page.find("#budget_#{finished.id}")).not_to have_link("Evaluate")
+ end
+end
diff --git a/spec/system/admin/budget_investments_spec.rb b/spec/system/admin/budget_investments_spec.rb
index c0de69ff7..affd87411 100644
--- a/spec/system/admin/budget_investments_spec.rb
+++ b/spec/system/admin/budget_investments_spec.rb
@@ -1567,6 +1567,7 @@ describe "Admin budget investments", :admin do
end
scenario "Shows the correct investments to valuators" do
+ budget.update!(phase: :valuating)
investment1.update!(visible_to_valuators: true)
investment2.update!(visible_to_valuators: false)
diff --git a/spec/system/valuation/budget_investments_spec.rb b/spec/system/valuation/budget_investments_spec.rb
index 69a5188d0..e02ea6b5d 100644
--- a/spec/system/valuation/budget_investments_spec.rb
+++ b/spec/system/valuation/budget_investments_spec.rb
@@ -501,6 +501,17 @@ describe "Valuation budget investments" do
expect(page).to have_content("Investments can only be valuated when Budget is in valuating phase")
end
+ scenario "restric access to the budget given by params when is not in valuating phase" do
+ budget.update!(phase: "publishing_prices")
+ create(:budget, :valuating)
+ investment = create(:budget_investment, budget: budget, valuators: [valuator])
+
+ login_as(valuator.user)
+ visit edit_valuation_budget_budget_investment_path(budget, investment)
+
+ expect(page).to have_content("Investments can only be valuated when Budget is in valuating phase")
+ end
+
scenario "visible to admins regardless of not being in valuating phase" do
budget.update!(phase: "publishing_prices")
diff --git a/spec/system/valuation/budgets_spec.rb b/spec/system/valuation/budgets_spec.rb
index c6683268d..4233cd9d1 100644
--- a/spec/system/valuation/budgets_spec.rb
+++ b/spec/system/valuation/budgets_spec.rb
@@ -1,29 +1,17 @@
require "rails_helper"
describe "Valuation budgets" do
- before do
- valuator = create(:valuator, user: create(:user, username: "Rachel", email: "rachel@valuators.org"))
- login_as(valuator.user)
- end
+ before { login_as(create(:valuator).user) }
context "Index" do
- scenario "Displaying budgets" do
- budget = create(:budget)
- visit valuation_budgets_path
-
- expect(page).to have_content(budget.name)
- end
-
- scenario "Filters by phase" do
- budget1 = create(:budget, :finished)
- budget2 = create(:budget, :finished)
- budget3 = create(:budget, :accepting)
+ scenario "Displays published budgets" do
+ create(:budget, name: "Sports")
+ create(:budget, name: "Draft", published: false)
visit valuation_budgets_path
- expect(page).not_to have_content(budget1.name)
- expect(page).not_to have_content(budget2.name)
- expect(page).to have_content(budget3.name)
+ expect(page).to have_content("Sports")
+ expect(page).not_to have_content("Draft")
end
scenario "With no budgets" do