Merge pull request #2864 from consul/backport_1543-budget_execution_list
Budget execution list
This commit is contained in:
BIN
app/assets/images/budget_execution_no_image.jpg
Normal file
BIN
app/assets/images/budget_execution_no_image.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 119 KiB |
@@ -1680,6 +1680,59 @@
|
||||
}
|
||||
}
|
||||
|
||||
.budget-execution {
|
||||
border: 1px solid $border;
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
|
||||
a {
|
||||
color: $text;
|
||||
display: block;
|
||||
|
||||
img {
|
||||
height: $line-height * 9;
|
||||
transition-duration: 0.3s;
|
||||
transition-property: transform;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
text-decoration: none;
|
||||
|
||||
img {
|
||||
transform: scale(1.05);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
h5 {
|
||||
font-size: $base-font-size;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.budget-execution-info {
|
||||
padding: $line-height / 2;
|
||||
}
|
||||
|
||||
.author {
|
||||
color: $text-medium;
|
||||
font-size: $small-font-size;
|
||||
}
|
||||
|
||||
.budget-execution-content {
|
||||
min-height: $line-height * 3;
|
||||
}
|
||||
|
||||
.price {
|
||||
color: $budget;
|
||||
font-size: rem-calc(24);
|
||||
}
|
||||
|
||||
&:hover {
|
||||
box-shadow: 0 0 12px 0 rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
}
|
||||
|
||||
// 07. Proposals successful
|
||||
// -------------------------
|
||||
|
||||
|
||||
46
app/controllers/budgets/executions_controller.rb
Normal file
46
app/controllers/budgets/executions_controller.rb
Normal file
@@ -0,0 +1,46 @@
|
||||
module Budgets
|
||||
class ExecutionsController < ApplicationController
|
||||
before_action :load_budget
|
||||
|
||||
load_and_authorize_resource :budget
|
||||
|
||||
def show
|
||||
authorize! :read_executions, @budget
|
||||
@statuses = ::Budget::Investment::Status.all
|
||||
|
||||
if params[:status].present?
|
||||
@investments_by_heading = @budget.investments.winners
|
||||
.joins(:milestones).includes(:milestones)
|
||||
.select { |i| i.milestones.published.with_status
|
||||
.order_by_publication_date.last
|
||||
.status_id == params[:status].to_i }
|
||||
.uniq
|
||||
.group_by(&:heading)
|
||||
else
|
||||
@investments_by_heading = @budget.investments.winners
|
||||
.joins(:milestones).includes(:milestones)
|
||||
.distinct.group_by(&:heading)
|
||||
end
|
||||
|
||||
@investments_by_heading = reorder_alphabetically_with_city_heading_first.to_h
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def load_budget
|
||||
@budget = Budget.find_by(slug: params[:id]) || Budget.find_by(id: params[:id])
|
||||
end
|
||||
|
||||
def reorder_alphabetically_with_city_heading_first
|
||||
@investments_by_heading.sort do |a, b|
|
||||
if a[0].name == 'Toda la ciudad'
|
||||
-1
|
||||
elsif b[0].name == 'Toda la ciudad'
|
||||
1
|
||||
else
|
||||
a[0].name <=> b[0].name
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
9
app/helpers/budget_executions_helper.rb
Normal file
9
app/helpers/budget_executions_helper.rb
Normal file
@@ -0,0 +1,9 @@
|
||||
module BudgetExecutionsHelper
|
||||
|
||||
def filters_select_counts(status)
|
||||
@budget.investments.winners.with_milestones.select { |i| i.milestones
|
||||
.published.with_status.order_by_publication_date
|
||||
.last.status_id == status rescue false }.count
|
||||
end
|
||||
|
||||
end
|
||||
@@ -22,7 +22,7 @@ module Abilities
|
||||
can [:read], Budget
|
||||
can [:read], Budget::Group
|
||||
can [:read, :print, :json_data], Budget::Investment
|
||||
can :read_results, Budget, phase: "finished"
|
||||
can [:read_results, :read_executions], Budget, phase: "finished"
|
||||
can :new, DirectMessage
|
||||
can [:read, :debate, :draft_publication, :allegations, :result_publication, :proposals], Legislation::Process, published: true
|
||||
can [:read, :changes, :go_to_version], Legislation::DraftVersion
|
||||
|
||||
@@ -84,6 +84,7 @@ class Budget
|
||||
scope :last_week, -> { where("created_at >= ?", 7.days.ago)}
|
||||
scope :sort_by_flags, -> { order(flags_count: :desc, updated_at: :desc) }
|
||||
scope :sort_by_created_at, -> { reorder(created_at: :desc) }
|
||||
scope :with_milestones, -> { joins(:milestones).distinct }
|
||||
|
||||
scope :by_budget, ->(budget) { where(budget: budget) }
|
||||
scope :by_group, ->(group_id) { where(group_id: group_id) }
|
||||
|
||||
@@ -18,6 +18,8 @@ class Budget
|
||||
validate :description_or_status_present?
|
||||
|
||||
scope :order_by_publication_date, -> { order(publication_date: :asc) }
|
||||
scope :published, -> { where("publication_date <= ?", Date.current) }
|
||||
scope :with_status, -> { where("status_id IS NOT NULL") }
|
||||
|
||||
def self.title_max_length
|
||||
80
|
||||
|
||||
@@ -4,7 +4,8 @@ class SiteCustomization::Image < ActiveRecord::Base
|
||||
"logo_header" => [260, 80],
|
||||
"social_media_icon" => [470, 246],
|
||||
"social_media_icon_twitter" => [246, 246],
|
||||
"apple-touch-icon-200" => [200, 200]
|
||||
"apple-touch-icon-200" => [200, 200],
|
||||
"budget_execution_no_image" => [800, 600]
|
||||
}
|
||||
|
||||
has_attached_file :image
|
||||
|
||||
33
app/views/budgets/executions/_investments.html.erb
Normal file
33
app/views/budgets/executions/_investments.html.erb
Normal file
@@ -0,0 +1,33 @@
|
||||
<% @investments_by_heading.each do |heading, investments| %>
|
||||
<h4 id="<%= heading.name.parameterize %>">
|
||||
<%= heading.name %> (<%= investments.count %>)
|
||||
</h4>
|
||||
<div class="row" data-equalizer-on="medium" data-equalizer>
|
||||
<% investments.each do |investment| %>
|
||||
<div class="small-12 medium-6 large-4 column end margin-bottom">
|
||||
<div class="budget-execution">
|
||||
<%= link_to budget_investment_path(@budget, investment, anchor: "tab-milestones"), data: { 'equalizer-watch': true } do %>
|
||||
<% investment.milestones.order(publication_date: :desc).limit(1).each do |milestone| %>
|
||||
<% if milestone.image.present? %>
|
||||
<%= image_tag milestone.image_url(:large), alt: milestone.image.title %>
|
||||
<% elsif investment.image.present? %>
|
||||
<%= image_tag investment.image_url(:thumb), alt: investment.image.title %>
|
||||
<% else %>
|
||||
<%= image_tag "budget_execution_no_image.jpg", alt: investment.title %>
|
||||
<% end %>
|
||||
<% end %>
|
||||
<div class="budget-execution-info">
|
||||
<div class="budget-execution-content">
|
||||
<h5><%= investment.title %></h5>
|
||||
<span class="author"><%= investment.author.name %></span>
|
||||
</div>
|
||||
<p class="price margin-top text-center">
|
||||
<strong><%= investment.formatted_price %></strong>
|
||||
</p>
|
||||
</div>
|
||||
<% end %>
|
||||
</div>
|
||||
</div>
|
||||
<% end %>
|
||||
</div>
|
||||
<% end %>
|
||||
77
app/views/budgets/executions/show.html.erb
Normal file
77
app/views/budgets/executions/show.html.erb
Normal file
@@ -0,0 +1,77 @@
|
||||
<% provide :title, t("budgets.executions.page_title", budget: @budget.name) %>
|
||||
<% content_for :meta_description do %><%= @budget.description_for_phase('finished') %><% end %>
|
||||
<% provide :social_media_meta_tags do %>
|
||||
<%= render 'shared/social_media_meta_tags',
|
||||
social_url: budget_executions_url(@budget),
|
||||
social_title: @budget.name,
|
||||
social_description: @budget.description_for_phase('finished') %>
|
||||
<% end %>
|
||||
|
||||
<% content_for :canonical do %>
|
||||
<%= render 'shared/canonical', href: budget_executions_url(@budget) %>
|
||||
<% end %>
|
||||
|
||||
<div class="budgets-stats">
|
||||
<div class="expanded no-margin-top padding header">
|
||||
<div class="row">
|
||||
<div class="small-12 column">
|
||||
<%= back_link_to budgets_path %>
|
||||
<h2 class="margin-top">
|
||||
<%= t("budgets.executions.heading") %><br>
|
||||
<span><%= @budget.name %></span>
|
||||
</h2>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row margin-top">
|
||||
<div class="small-12 column">
|
||||
<ul class="tabs">
|
||||
<li class="tabs-title">
|
||||
<%= link_to t("budgets.results.link"), budget_results_path(@budget) %>
|
||||
</li>
|
||||
<li class="tabs-title is-active">
|
||||
<%= link_to t("budgets.executions.link"), budget_executions_path(@budget), class: 'is-active' %>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="small-12 medium-3 large-2 column">
|
||||
<h3 class="margin-bottom">
|
||||
<%= t("budgets.executions.heading_selection_title") %>
|
||||
</h3>
|
||||
<ul class="menu vertical no-margin-top no-padding-top">
|
||||
<% @investments_by_heading.each_pair do |heading, investments| %>
|
||||
<li>
|
||||
<%= link_to heading.name, "#" + heading.name.parameterize %>
|
||||
</li>
|
||||
<% end %>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="small-12 medium-9 large-10 column">
|
||||
<%= form_tag(budget_executions_path(@budget), method: :get) do %>
|
||||
<div class="small-12 medium-3 column">
|
||||
<%= label_tag t("budgets.executions.filters.label") %>
|
||||
<%= select_tag :status,
|
||||
options_from_collection_for_select(@statuses,
|
||||
:id, lambda { |s| "#{s.name} (#{filters_select_counts(s.id)})" },
|
||||
params[:status]),
|
||||
class: "js-submit-on-change",
|
||||
prompt: t("budgets.executions.filters.all",
|
||||
count: @budget.investments.winners.with_milestones.count) %>
|
||||
</div>
|
||||
<% end %>
|
||||
|
||||
<% if @investments_by_heading.any? %>
|
||||
<%= render 'budgets/executions/investments' %>
|
||||
<% else %>
|
||||
<div class="callout primary clear">
|
||||
<%= t("budgets.executions.no_winner_investments") %>
|
||||
</div>
|
||||
<% end %>
|
||||
</div>
|
||||
</div>
|
||||
@@ -33,7 +33,7 @@
|
||||
<% if current_user %>
|
||||
<% if current_user.level_two_or_three_verified? %>
|
||||
<%= link_to t("budgets.investments.index.sidebar.create"),
|
||||
new_budget_investment_path(@budget),
|
||||
new_budget_investment_path(current_budget),
|
||||
class: "button margin-top expanded" %>
|
||||
<% else %>
|
||||
<div class="callout warning margin-top">
|
||||
|
||||
@@ -29,10 +29,10 @@
|
||||
<ul class="tabs">
|
||||
<li class="tabs-title is-active">
|
||||
<span class="show-for-sr"><%= t("shared.you_are_in") %></span>
|
||||
<%= link_to t("budgets.results.link"), budget_results_path(@budget), class: "is-active" %>
|
||||
<%= link_to t("budgets.results.link"), budget_results_path(@budget), class: "is-active" %>
|
||||
</li>
|
||||
<li class="tabs-title">
|
||||
<%# link_to t("budgets.stats.link"), budget_stats_path(@budget)%>
|
||||
<%= link_to t("budgets.executions.link"), budget_executions_path(@budget) %>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
@@ -174,6 +174,15 @@ en:
|
||||
investment_proyects: List of all investment projects
|
||||
unfeasible_investment_proyects: List of all unfeasible investment projects
|
||||
not_selected_investment_proyects: List of all investment projects not selected for balloting
|
||||
executions:
|
||||
link: "Milestones"
|
||||
page_title: "%{budget} - Milestones"
|
||||
heading: "Participatory budget Milestones"
|
||||
heading_selection_title: "By district"
|
||||
no_winner_investments: "No winner investments in this state"
|
||||
filters:
|
||||
label: "Project's current state"
|
||||
all: "All (%{count})"
|
||||
phases:
|
||||
errors:
|
||||
dates_range_invalid: "Start date can't be equal or later than End date"
|
||||
|
||||
@@ -174,6 +174,15 @@ es:
|
||||
investment_proyects: Ver lista completa de proyectos de gasto
|
||||
unfeasible_investment_proyects: Ver lista de proyectos de gasto inviables
|
||||
not_selected_investment_proyects: Ver lista de proyectos de gasto no seleccionados para la votación final
|
||||
executions:
|
||||
link: "Seguimiento"
|
||||
page_title: "%{budget} - Seguimiento de proyectos"
|
||||
heading: "Seguimiento de proyectos"
|
||||
heading_selection_title: "Ámbito de actuación"
|
||||
no_winner_investments: "No hay proyectos de gasto ganadores en este estado"
|
||||
filters:
|
||||
label: "Estado actual del proyecto"
|
||||
all: "Todos (%{count})"
|
||||
phases:
|
||||
errors:
|
||||
dates_range_invalid: "La fecha de comienzo no puede ser igual o superior a la de finalización"
|
||||
|
||||
@@ -15,6 +15,7 @@ resources :budgets, only: [:show, :index] do
|
||||
end
|
||||
|
||||
resource :results, only: :show, controller: "budgets/results"
|
||||
resource :executions, only: :show, controller: 'budgets/executions'
|
||||
end
|
||||
|
||||
scope '/participatory_budget' do
|
||||
|
||||
@@ -139,6 +139,13 @@ section "Creating Valuation Assignments" do
|
||||
end
|
||||
end
|
||||
|
||||
section "Creating default Investment Milestone Statuses" do
|
||||
Budget::Investment::Status.create(name: I18n.t('seeds.budgets.statuses.studying_project'))
|
||||
Budget::Investment::Status.create(name: I18n.t('seeds.budgets.statuses.bidding'))
|
||||
Budget::Investment::Status.create(name: I18n.t('seeds.budgets.statuses.executing_project'))
|
||||
Budget::Investment::Status.create(name: I18n.t('seeds.budgets.statuses.executed'))
|
||||
end
|
||||
|
||||
section "Creating investment milestones" do
|
||||
Budget::Investment.find_each do |investment|
|
||||
milestone = Budget::Investment::Milestone.new(investment_id: investment.id, publication_date: Date.tomorrow)
|
||||
@@ -151,10 +158,3 @@ section "Creating investment milestones" do
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
section "Creating default Investment Milestone Statuses" do
|
||||
Budget::Investment::Status.create(name: I18n.t('seeds.budgets.statuses.studying_project'))
|
||||
Budget::Investment::Status.create(name: I18n.t('seeds.budgets.statuses.bidding'))
|
||||
Budget::Investment::Status.create(name: I18n.t('seeds.budgets.statuses.executing_project'))
|
||||
Budget::Investment::Status.create(name: I18n.t('seeds.budgets.statuses.executed'))
|
||||
end
|
||||
|
||||
@@ -124,6 +124,15 @@ feature 'Budgets' do
|
||||
|
||||
expect(page).to have_content "There are no budgets"
|
||||
end
|
||||
|
||||
scenario "Accepting" do
|
||||
budget.update(phase: "accepting")
|
||||
login_as(create(:user, :level_two))
|
||||
|
||||
visit budgets_path
|
||||
|
||||
expect(page).to have_link "Create a budget investment"
|
||||
end
|
||||
end
|
||||
|
||||
scenario 'Index shows only published phases' do
|
||||
|
||||
252
spec/features/budgets/executions_spec.rb
Normal file
252
spec/features/budgets/executions_spec.rb
Normal file
@@ -0,0 +1,252 @@
|
||||
require 'rails_helper'
|
||||
|
||||
feature 'Executions' do
|
||||
|
||||
let(:budget) { create(:budget, phase: 'finished') }
|
||||
let(:group) { create(:budget_group, budget: budget) }
|
||||
let(:heading) { create(:budget_heading, group: group) }
|
||||
|
||||
let!(:investment1) { create(:budget_investment, :winner, heading: heading) }
|
||||
let!(:investment2) { create(:budget_investment, :winner, heading: heading) }
|
||||
let!(:investment4) { create(:budget_investment, :winner, heading: heading) }
|
||||
let!(:investment3) { create(:budget_investment, :incompatible, heading: heading) }
|
||||
|
||||
scenario 'only displays investments with milestones' do
|
||||
create(:budget_investment_milestone, investment: investment1)
|
||||
|
||||
visit budget_path(budget)
|
||||
click_link 'See results'
|
||||
|
||||
expect(page).to have_link('Milestones')
|
||||
|
||||
click_link 'Milestones'
|
||||
|
||||
expect(page).to have_content(investment1.title)
|
||||
expect(page).not_to have_content(investment2.title)
|
||||
expect(page).not_to have_content(investment3.title)
|
||||
expect(page).not_to have_content(investment4.title)
|
||||
end
|
||||
|
||||
scenario "Do not display headings with no winning investments for selected status" do
|
||||
create(:budget_investment_milestone, investment: investment1)
|
||||
|
||||
empty_group = create(:budget_group, budget: budget)
|
||||
empty_heading = create(:budget_heading, group: empty_group, price: 1000)
|
||||
|
||||
visit budget_path(budget)
|
||||
click_link 'See results'
|
||||
|
||||
expect(page).to have_content(heading.name)
|
||||
expect(page).to have_content(empty_heading.name)
|
||||
|
||||
click_link 'Milestones'
|
||||
|
||||
expect(page).to have_content(heading.name)
|
||||
expect(page).not_to have_content(empty_heading.name)
|
||||
end
|
||||
|
||||
scenario "Show message when there are no winning investments with the selected status", :js do
|
||||
create(:budget_investment_status, name: I18n.t('seeds.budgets.statuses.executed'))
|
||||
|
||||
visit budget_path(budget)
|
||||
|
||||
click_link 'See results'
|
||||
click_link 'Milestones'
|
||||
|
||||
expect(page).not_to have_content('No winner investments in this state')
|
||||
|
||||
select 'Executed (0)', from: 'status'
|
||||
|
||||
expect(page).to have_content('No winner investments in this state')
|
||||
end
|
||||
|
||||
context 'Images' do
|
||||
scenario 'renders milestone image if available' do
|
||||
milestone1 = create(:budget_investment_milestone, investment: investment1)
|
||||
create(:image, imageable: milestone1)
|
||||
|
||||
visit budget_path(budget)
|
||||
|
||||
click_link 'See results'
|
||||
click_link 'Milestones'
|
||||
|
||||
expect(page).to have_content(investment1.title)
|
||||
expect(page).to have_css("img[alt='#{milestone1.image.title}']")
|
||||
end
|
||||
|
||||
scenario 'renders investment image if no milestone image is available' do
|
||||
create(:budget_investment_milestone, investment: investment2)
|
||||
create(:image, imageable: investment2)
|
||||
|
||||
visit budget_path(budget)
|
||||
|
||||
click_link 'See results'
|
||||
click_link 'Milestones'
|
||||
|
||||
expect(page).to have_content(investment2.title)
|
||||
expect(page).to have_css("img[alt='#{investment2.image.title}']")
|
||||
end
|
||||
|
||||
scenario 'renders default image if no milestone nor investment images are available' do
|
||||
create(:budget_investment_milestone, investment: investment4)
|
||||
|
||||
visit budget_path(budget)
|
||||
|
||||
click_link 'See results'
|
||||
click_link 'Milestones'
|
||||
|
||||
expect(page).to have_content(investment4.title)
|
||||
expect(page).to have_css("img[alt='#{investment4.title}']")
|
||||
end
|
||||
|
||||
scenario "renders last milestone's image if investment has multiple milestones with images associated" do
|
||||
milestone1 = create(:budget_investment_milestone, investment: investment1,
|
||||
publication_date: 2.weeks.ago)
|
||||
|
||||
milestone2 = create(:budget_investment_milestone, investment: investment1,
|
||||
publication_date: Date.yesterday)
|
||||
|
||||
create(:image, imageable: milestone1, title: 'First milestone image')
|
||||
create(:image, imageable: milestone2, title: 'Second milestone image')
|
||||
|
||||
visit budget_path(budget)
|
||||
|
||||
click_link 'See results'
|
||||
click_link 'Milestones'
|
||||
|
||||
expect(page).to have_content(investment1.title)
|
||||
expect(page).to have_css("img[alt='#{milestone2.image.title}']")
|
||||
expect(page).not_to have_css("img[alt='#{milestone1.image.title}']")
|
||||
end
|
||||
end
|
||||
|
||||
context 'Filters' do
|
||||
|
||||
let!(:status1) { create(:budget_investment_status, name: I18n.t('seeds.budgets.statuses.studying_project')) }
|
||||
let!(:status2) { create(:budget_investment_status, name: I18n.t('seeds.budgets.statuses.bidding')) }
|
||||
|
||||
scenario 'Filters select with counter are shown' do
|
||||
create(:budget_investment_milestone, investment: investment1,
|
||||
publication_date: Date.yesterday,
|
||||
status: status1)
|
||||
|
||||
create(:budget_investment_milestone, investment: investment2,
|
||||
publication_date: Date.yesterday,
|
||||
status: status2)
|
||||
|
||||
visit budget_path(budget)
|
||||
|
||||
click_link 'See results'
|
||||
click_link 'Milestones'
|
||||
|
||||
expect(page).to have_content("All (2)")
|
||||
expect(page).to have_content("#{status1.name} (1)")
|
||||
expect(page).to have_content("#{status2.name} (1)")
|
||||
end
|
||||
|
||||
scenario 'by milestone status', :js do
|
||||
create(:budget_investment_milestone, investment: investment1, status: status1)
|
||||
create(:budget_investment_milestone, investment: investment2, status: status2)
|
||||
create(:budget_investment_status, name: I18n.t('seeds.budgets.statuses.executing_project'))
|
||||
|
||||
visit budget_path(budget)
|
||||
|
||||
click_link 'See results'
|
||||
click_link 'Milestones'
|
||||
|
||||
expect(page).to have_content(investment1.title)
|
||||
expect(page).to have_content(investment2.title)
|
||||
|
||||
select 'Studying the project (1)', from: 'status'
|
||||
|
||||
expect(page).to have_content(investment1.title)
|
||||
expect(page).not_to have_content(investment2.title)
|
||||
|
||||
select 'Bidding (1)', from: 'status'
|
||||
|
||||
expect(page).to have_content(investment2.title)
|
||||
expect(page).not_to have_content(investment1.title)
|
||||
|
||||
select 'Executing the project (0)', from: 'status'
|
||||
|
||||
expect(page).not_to have_content(investment1.title)
|
||||
expect(page).not_to have_content(investment2.title)
|
||||
end
|
||||
|
||||
scenario 'are based on latest milestone status', :js do
|
||||
create(:budget_investment_milestone, investment: investment1,
|
||||
publication_date: 1.month.ago,
|
||||
status: status1)
|
||||
|
||||
create(:budget_investment_milestone, investment: investment1,
|
||||
publication_date: Date.yesterday,
|
||||
status: status2)
|
||||
|
||||
visit budget_path(budget)
|
||||
click_link 'See results'
|
||||
click_link 'Milestones'
|
||||
|
||||
select 'Studying the project (0)', from: 'status'
|
||||
expect(page).not_to have_content(investment1.title)
|
||||
|
||||
select 'Bidding (1)', from: 'status'
|
||||
expect(page).to have_content(investment1.title)
|
||||
end
|
||||
|
||||
scenario 'milestones with future dates are not shown', :js do
|
||||
create(:budget_investment_milestone, investment: investment1,
|
||||
publication_date: Date.yesterday,
|
||||
status: status1)
|
||||
|
||||
create(:budget_investment_milestone, investment: investment1,
|
||||
publication_date: Date.tomorrow,
|
||||
status: status2)
|
||||
|
||||
visit budget_path(budget)
|
||||
click_link 'See results'
|
||||
click_link 'Milestones'
|
||||
|
||||
select 'Studying the project (1)', from: 'status'
|
||||
expect(page).to have_content(investment1.title)
|
||||
|
||||
select 'Bidding (0)', from: 'status'
|
||||
expect(page).not_to have_content(investment1.title)
|
||||
end
|
||||
end
|
||||
|
||||
context 'Heading Order' do
|
||||
|
||||
def create_heading_with_investment_with_milestone(group:, name:)
|
||||
heading = create(:budget_heading, group: group, name: name)
|
||||
investment = create(:budget_investment, :winner, heading: heading)
|
||||
milestone = create(:budget_investment_milestone, investment: investment)
|
||||
heading
|
||||
end
|
||||
|
||||
scenario 'City heading is displayed first' do
|
||||
heading.destroy!
|
||||
other_heading1 = create_heading_with_investment_with_milestone(group: group, name: 'Other 1')
|
||||
city_heading = create_heading_with_investment_with_milestone(group: group, name: 'Toda la ciudad')
|
||||
other_heading2 = create_heading_with_investment_with_milestone(group: group, name: 'Other 2')
|
||||
|
||||
visit budget_executions_path(budget)
|
||||
|
||||
expect(page).to have_css('.budget-execution', count: 3)
|
||||
expect(city_heading.name).to appear_before(other_heading1.name)
|
||||
expect(city_heading.name).to appear_before(other_heading2.name)
|
||||
end
|
||||
|
||||
scenario 'Non-city headings are displayed in alphabetical order' do
|
||||
heading.destroy!
|
||||
z_heading = create_heading_with_investment_with_milestone(group: group, name: 'Zzz')
|
||||
a_heading = create_heading_with_investment_with_milestone(group: group, name: 'Aaa')
|
||||
m_heading = create_heading_with_investment_with_milestone(group: group, name: 'Mmm')
|
||||
|
||||
visit budget_executions_path(budget)
|
||||
|
||||
expect(page).to have_css('.budget-execution', count: 3)
|
||||
expect(a_heading.name).to appear_before(m_heading.name)
|
||||
expect(m_heading.name).to appear_before(z_heading.name)
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -69,4 +69,16 @@ describe Budget::Investment::Milestone do
|
||||
end
|
||||
end
|
||||
|
||||
describe ".published" do
|
||||
it "uses the application's time zone date", :with_different_time_zone do
|
||||
published_in_local_time_zone = create(:budget_investment_milestone,
|
||||
publication_date: Date.today)
|
||||
|
||||
published_in_application_time_zone = create(:budget_investment_milestone,
|
||||
publication_date: Date.current)
|
||||
|
||||
expect(Budget::Investment::Milestone.published).to include(published_in_application_time_zone)
|
||||
expect(Budget::Investment::Milestone.published).not_to include(published_in_local_time_zone)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -90,6 +90,17 @@ RSpec.configure do |config|
|
||||
travel_back
|
||||
end
|
||||
|
||||
config.before(:each, :with_different_time_zone) do
|
||||
system_zone = ActiveSupport::TimeZone.new("UTC")
|
||||
local_zone = ActiveSupport::TimeZone.new("Madrid")
|
||||
|
||||
# Make sure the date defined by `config.time_zone` and
|
||||
# the local date are different.
|
||||
allow(Time).to receive(:zone).and_return(system_zone)
|
||||
allow(Time).to receive(:now).and_return(Date.current.at_end_of_day.in_time_zone(local_zone))
|
||||
allow(Date).to receive(:today).and_return(Time.now.to_date)
|
||||
end
|
||||
|
||||
# Allows RSpec to persist some state between runs in order to support
|
||||
# the `--only-failures` and `--next-failure` CLI options.
|
||||
config.example_status_persistence_file_path = "spec/examples.txt"
|
||||
|
||||
Reference in New Issue
Block a user