diff --git a/.rubocop.yml b/.rubocop.yml index ae486cc1c..0c56b53fc 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -20,7 +20,7 @@ Rails: Enabled: true Metrics/LineLength: - Max: 140 + Max: 100 Layout/IndentationConsistency: EnforcedStyle: rails diff --git a/app/controllers/admin/budgets_controller.rb b/app/controllers/admin/budgets_controller.rb index 2d6fc7d8f..d2f8706c0 100644 --- a/app/controllers/admin/budgets_controller.rb +++ b/app/controllers/admin/budgets_controller.rb @@ -27,7 +27,7 @@ class Admin::BudgetsController < Admin::BaseController def update if @budget.update(budget_params) - redirect_to admin_budget_path(@budget), notice: t('admin.budgets.update.notice') + redirect_to admin_budgets_path, notice: t('admin.budgets.update.notice') else render :edit end diff --git a/app/controllers/budgets_controller.rb b/app/controllers/budgets_controller.rb index 2a53c410b..4f215c46f 100644 --- a/app/controllers/budgets_controller.rb +++ b/app/controllers/budgets_controller.rb @@ -1,5 +1,6 @@ class BudgetsController < ApplicationController include FeatureFlags + include BudgetsHelper feature_flag :budgets load_and_authorize_resource @@ -9,6 +10,7 @@ class BudgetsController < ApplicationController respond_to :html, :js def show + raise ActionController::RoutingError, 'Not Found' unless budget_published?(@budget) end def index diff --git a/app/helpers/budgets_helper.rb b/app/helpers/budgets_helper.rb index fefda85ab..3b4c81f7e 100644 --- a/app/helpers/budgets_helper.rb +++ b/app/helpers/budgets_helper.rb @@ -42,4 +42,9 @@ module BudgetsHelper def investment_tags_select_options Budget::Investment.tags_on(:valuation).order(:name).select(:name).distinct end + + def budget_published?(budget) + !budget.drafting? || current_user&.administrator? + end + end diff --git a/app/models/budget.rb b/app/models/budget.rb index 024602730..ce8bc4dfa 100644 --- a/app/models/budget.rb +++ b/app/models/budget.rb @@ -3,7 +3,8 @@ class Budget < ActiveRecord::Base include Measurable include Sluggable - PHASES = %w(accepting reviewing selecting valuating balloting reviewing_ballots finished).freeze + PHASES = %w(drafting accepting reviewing selecting valuating balloting + reviewing_ballots finished).freeze CURRENCY_SYMBOLS = %w(€ $ £ ¥).freeze validates :name, presence: true, uniqueness: true @@ -19,6 +20,7 @@ class Budget < ActiveRecord::Base before_validation :sanitize_descriptions scope :on_hold, -> { where(phase: %w(reviewing valuating reviewing_ballots")) } + scope :drafting, -> { where(phase: "drafting") } scope :accepting, -> { where(phase: "accepting") } scope :reviewing, -> { where(phase: "reviewing") } scope :selecting, -> { where(phase: "selecting") } @@ -41,6 +43,10 @@ class Budget < ActiveRecord::Base 80 end + def drafting? + phase == "drafting" + end + def accepting? phase == "accepting" end diff --git a/app/views/budgets/index.html.erb b/app/views/budgets/index.html.erb index 8cde29bc7..0ccc8bcef 100644 --- a/app/views/budgets/index.html.erb +++ b/app/views/budgets/index.html.erb @@ -16,14 +16,16 @@ <% @budgets.each do |budget| %> - - - <%= link_to budget.name, budget %> - - - <%= budget.translated_phase %> - - + <% if budget_published?(budget) %> + + + <%= link_to budget.name, budget %> + + + <%= budget.translated_phase %> + + + <% end %> <% end %> diff --git a/app/views/budgets/investments/_investment_show.html.erb b/app/views/budgets/investments/_investment_show.html.erb index fc42e1a3a..946952bd9 100644 --- a/app/views/budgets/investments/_investment_show.html.erb +++ b/app/views/budgets/investments/_investment_show.html.erb @@ -1,3 +1,12 @@ +<% provide :social_media_meta_tags do %> +<%= render "shared/social_media_meta_tags", + social_url: budget_investments_path(investment), + social_title: investment.title, + social_description: investment.description, + twitter_image_url: (investment.image.present? ? investment.image_url(:thumb) : nil), + og_image_url: (investment.image.present? ? investment.image_url(:thumb) : nil) %> +<% end %> +
diff --git a/app/views/proposals/show.html.erb b/app/views/proposals/show.html.erb index d028a3f7f..dbeb110ce 100644 --- a/app/views/proposals/show.html.erb +++ b/app/views/proposals/show.html.erb @@ -4,7 +4,9 @@ <%= render "shared/social_media_meta_tags", social_url: proposal_url(@proposal), social_title: @proposal.title, - social_description: @proposal.summary %> + social_description: @proposal.summary, + twitter_image_url: (@proposal.image.present? ? @proposal.image_url(:thumb) : nil), + og_image_url: (@proposal.image.present? ? @proposal.image_url(:thumb) : nil) %> <% end %> <% content_for :canonical do %> <%= render "shared/canonical", href: proposal_url(@proposal) %> diff --git a/config/locales/en/budgets.yml b/config/locales/en/budgets.yml index 3710daf8a..bffa6965d 100644 --- a/config/locales/en/budgets.yml +++ b/config/locales/en/budgets.yml @@ -29,6 +29,7 @@ en: unselected_title: Investments not selected for balloting phase unselected: See investments not selected for balloting phase phase: + drafting: Draft (Not visible to the public) accepting: Accepting projects reviewing: Reviewing projects selecting: Selecting projects diff --git a/config/locales/es/budgets.yml b/config/locales/es/budgets.yml index 367bcecdc..d746772eb 100644 --- a/config/locales/es/budgets.yml +++ b/config/locales/es/budgets.yml @@ -29,6 +29,7 @@ es: unselected_title: Propuestas no seleccionadas para la votación final unselected: Ver las propuestas no seleccionadas para la votación final phase: + drafting: Borrador (No visible para el público) accepting: Presentación de proyectos reviewing: Revisión interna de proyectos selecting: Fase de apoyos diff --git a/db/migrate/20180108182839_add_drafting_phase_to_budget.rb b/db/migrate/20180108182839_add_drafting_phase_to_budget.rb new file mode 100644 index 000000000..9a8febb97 --- /dev/null +++ b/db/migrate/20180108182839_add_drafting_phase_to_budget.rb @@ -0,0 +1,5 @@ +class AddDraftingPhaseToBudget < ActiveRecord::Migration + def change + add_column :budgets, :description_drafting, :text + end +end diff --git a/db/schema.rb b/db/schema.rb index ab6decc80..d599658c1 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -11,7 +11,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 20171220010000) do +ActiveRecord::Schema.define(version: 20180108182839) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -201,6 +201,7 @@ ActiveRecord::Schema.define(version: 20171220010000) do t.text "description_reviewing_ballots" t.text "description_finished" t.string "slug" + t.text "description_drafting" end create_table "campaigns", force: :cascade do |t| diff --git a/spec/customization_engine_spec.rb b/spec/customization_engine_spec.rb index e4259b49a..c36ee68a7 100644 --- a/spec/customization_engine_spec.rb +++ b/spec/customization_engine_spec.rb @@ -8,21 +8,33 @@ describe 'Customization Engine' do let(:test_key) { I18n.t('account.show.change_credentials_link') } let!(:default_path) { I18n.load_path } + before do + reset_load_path_and_reload(default_path) + end + + after do + reset_load_path_and_reload(default_path) + end + it "loads custom and override original locales" do - I18n.load_path += Dir[Rails.root.join('spec', 'support', 'locales', 'custom', '*.{rb,yml}')] - I18n.reload! + increase_load_path_and_reload(Dir[Rails.root.join('spec', 'support', + 'locales', 'custom', '*.{rb,yml}')]) expect(test_key).to eq 'Overriden string with custom locales' end it "does not override original locales" do - I18n.load_path.delete_if {|item| item =~ /spec\/support\/locales\/custom/ } - I18n.load_path += Dir[Rails.root.join('spec', 'support', 'locales', '**', '*.{rb,yml}')] - I18n.reload! + increase_load_path_and_reload(Dir[Rails.root.join('spec', 'support', + 'locales', '**', '*.{rb,yml}')]) expect(test_key).to eq 'Not overriden string with custom locales' end - after do - I18n.load_path = default_path + def reset_load_path_and_reload(path) + I18n.load_path = path + I18n.reload! + end + + def increase_load_path_and_reload(path) + I18n.load_path += path I18n.reload! end diff --git a/spec/factories.rb b/spec/factories.rb index fd67fc4fc..86988e5e9 100644 --- a/spec/factories.rb +++ b/spec/factories.rb @@ -223,6 +223,7 @@ FactoryBot.define do sequence(:name) { |n| "Budget #{n}" } currency_symbol "€" phase 'accepting' + description_drafting "This budget is drafting" description_accepting "This budget is accepting" description_reviewing "This budget is reviewing" description_selecting "This budget is selecting" @@ -231,6 +232,10 @@ FactoryBot.define do description_reviewing_ballots "This budget is reviewing ballots" description_finished "This budget is finished" + trait :drafting do + phase 'drafting' + end + trait :accepting do phase 'accepting' end diff --git a/spec/features/admin/budgets_spec.rb b/spec/features/admin/budgets_spec.rb index b827274ae..0507b45f2 100644 --- a/spec/features/admin/budgets_spec.rb +++ b/spec/features/admin/budgets_spec.rb @@ -34,32 +34,32 @@ feature 'Admin budgets' do end scenario 'Filters by phase' do - budget1 = create(:budget) - budget2 = create(:budget, :accepting) - budget3 = create(:budget, :selecting) - budget4 = create(:budget, :balloting) - budget5 = create(:budget, :finished) + drafting_budget = create(:budget, :drafting) + accepting_budget = create(:budget, :accepting) + selecting_budget = create(:budget, :selecting) + balloting_budget = create(:budget, :balloting) + finished_budget = create(:budget, :finished) visit admin_budgets_path - expect(page).to have_content(budget1.name) - expect(page).to have_content(budget2.name) - expect(page).to have_content(budget3.name) - expect(page).to have_content(budget4.name) - expect(page).not_to have_content(budget5.name) + expect(page).to have_content(drafting_budget.name) + expect(page).to have_content(accepting_budget.name) + expect(page).to have_content(selecting_budget.name) + expect(page).to have_content(balloting_budget.name) + expect(page).not_to have_content(finished_budget.name) click_link 'Finished' - expect(page).not_to have_content(budget1.name) - expect(page).not_to have_content(budget2.name) - expect(page).not_to have_content(budget3.name) - expect(page).not_to have_content(budget4.name) - expect(page).to have_content(budget5.name) + expect(page).not_to have_content(drafting_budget.name) + expect(page).not_to have_content(accepting_budget.name) + expect(page).not_to have_content(selecting_budget.name) + expect(page).not_to have_content(balloting_budget.name) + expect(page).to have_content(finished_budget.name) click_link 'Open' - expect(page).to have_content(budget1.name) - expect(page).to have_content(budget2.name) - expect(page).to have_content(budget3.name) - expect(page).to have_content(budget4.name) - expect(page).not_to have_content(budget5.name) + expect(page).to have_content(drafting_budget.name) + expect(page).to have_content(accepting_budget.name) + expect(page).to have_content(selecting_budget.name) + expect(page).to have_content(balloting_budget.name) + expect(page).not_to have_content(finished_budget.name) end scenario 'Open filter is properly highlighted' do @@ -133,6 +133,24 @@ feature 'Admin budgets' do expect(page).to have_content('You cannot destroy a Budget that has associated investments') expect(page).to have_content('There is 1 participatory budget') end + end + + context 'Update' do + + background do + create(:budget) + end + + scenario 'Update budget' do + visit admin_budgets_path + click_link 'Edit budget' + + fill_in 'budget_name', with: 'More trees on the streets' + click_button 'Update Participatory budget' + + expect(page).to have_content('More trees on the streets') + expect(page).to have_current_path(admin_budgets_path) + end end diff --git a/spec/features/budgets/budgets_spec.rb b/spec/features/budgets/budgets_spec.rb index f7d194524..ee537a854 100644 --- a/spec/features/budgets/budgets_spec.rb +++ b/spec/features/budgets/budgets_spec.rb @@ -2,6 +2,9 @@ require 'rails_helper' feature 'Budgets' do + let(:budget) { create(:budget) } + let(:level_two_user) { create(:user, :level_two) } + scenario 'Index' do budgets = create_list(:budget, 3) visit budgets_path @@ -11,7 +14,6 @@ feature 'Budgets' do context 'Show' do scenario "List all groups" do - budget = create(:budget) group1 = create(:budget_group, budget: budget) group2 = create(:budget_group, budget: budget) @@ -61,9 +63,59 @@ feature 'Budgets' do end - context 'Accepting' do + context "In Drafting phase" do - let(:budget) { create(:budget) } + let(:admin) { create(:administrator).user } + + background do + logout + budget.update(phase: 'drafting') + end + + context "Listed" do + scenario "Not listed to guest users at the public budgets list" do + visit budgets_path + + expect(page).not_to have_content(budget.name) + end + + scenario "Not listed to logged users at the public budgets list" do + login_as(level_two_user) + visit budgets_path + + expect(page).not_to have_content(budget.name) + end + + scenario "Is listed to admins at the public budgets list" do + login_as(admin) + visit budgets_path + + expect(page).to have_content(budget.name) + end + end + + context "Shown" do + scenario "Not accesible to guest users" do + expect { visit budget_path(budget) }.to raise_error(ActionController::RoutingError) + end + + scenario "Not accesible to logged users" do + login_as(level_two_user) + + expect { visit budget_path(budget) }.to raise_error(ActionController::RoutingError) + end + + scenario "Is accesible to admin users" do + login_as(admin) + visit budget_path(budget) + + expect(page.status_code).to eq(200) + end + end + + end + + context 'Accepting' do background do budget.update(phase: 'accepting') @@ -72,8 +124,7 @@ feature 'Budgets' do context "Permissions" do scenario "Verified user" do - user = create(:user, :level_two) - login_as(user) + login_as(level_two_user) visit budget_path(budget) @@ -97,4 +148,4 @@ feature 'Budgets' do end end -end \ No newline at end of file +end diff --git a/spec/features/budgets/results_spec.rb b/spec/features/budgets/results_spec.rb index 178f3007a..5e194a393 100644 --- a/spec/features/budgets/results_spec.rb +++ b/spec/features/budgets/results_spec.rb @@ -65,7 +65,7 @@ feature 'Results' do end scenario "If budget is in a phase different from finished results can't be accessed" do - budget.update phase: (Budget::PHASES - ["finished"]).sample + budget.update(phase: (Budget::PHASES - ['drafting', 'finished']).sample) visit budget_path(budget) expect(page).not_to have_link "See results" diff --git a/spec/features/tags/budget_investments_spec.rb b/spec/features/tags/budget_investments_spec.rb index 74523f81b..f244583a6 100644 --- a/spec/features/tags/budget_investments_spec.rb +++ b/spec/features/tags/budget_investments_spec.rb @@ -8,6 +8,7 @@ feature 'Tags' do let!(:heading) { create(:budget_heading, name: "More hospitals", group: group) } let!(:tag_medio_ambiente) { create(:tag, :category, name: 'Medio Ambiente') } let!(:tag_economia) { create(:tag, :category, name: 'Economía') } + let(:admin) { create(:administrator).user } scenario 'Index' do earth = create(:budget_investment, heading: heading, tag_list: tag_medio_ambiente.name) @@ -185,6 +186,7 @@ feature 'Tags' do Budget::PHASES.each do |phase| budget.update(phase: phase) + login_as(admin) if budget.drafting? visit budget_investments_path(budget, heading_id: heading.id) within "#tag-cloud" do @@ -204,6 +206,7 @@ feature 'Tags' do end end + login_as(admin) if budget.drafting? visit budget_path(budget) click_link group.name @@ -230,6 +233,7 @@ feature 'Tags' do Budget::PHASES.each do |phase| budget.update(phase: phase) + login_as(admin) if budget.drafting? visit budget_investments_path(budget, heading_id: heading.id) within "#categories" do @@ -249,6 +253,7 @@ feature 'Tags' do end end + login_as(admin) if budget.drafting? visit budget_path(budget) click_link group.name @@ -282,8 +287,7 @@ feature 'Tags' do investment.set_tag_list_on(:valuation, 'Education') investment.save - admin = create(:administrator) - login_as(admin.user) + login_as(admin) visit admin_budget_budget_investment_path(budget, investment) click_link 'Edit classification' diff --git a/spec/models/budget_spec.rb b/spec/models/budget_spec.rb index b7926eb7b..b86db7e6e 100644 --- a/spec/models/budget_spec.rb +++ b/spec/models/budget_spec.rb @@ -40,6 +40,9 @@ describe Budget do end it "produces auxiliary methods" do + budget.phase = "drafting" + expect(budget).to be_drafting + budget.phase = "accepting" expect(budget).to be_accepting @@ -63,6 +66,9 @@ describe Budget do end it "on_hold?" do + budget.phase = "drafting" + expect(budget).not_to be_on_hold + budget.phase = "accepting" expect(budget).not_to be_on_hold @@ -86,6 +92,9 @@ describe Budget do end it "balloting_or_later?" do + budget.phase = "drafting" + expect(budget).not_to be_balloting_or_later + budget.phase = "accepting" expect(budget).not_to be_balloting_or_later