From 323b05f4de37cbdcf6a118baeb9904180e503798 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pedro=20R=C3=ADos=20Flores?= Date: Fri, 29 Sep 2017 12:30:02 +0200 Subject: [PATCH 01/69] Issue #1901: Budget related entries in Management shouldn't appear if budgets are globally disabled. --- app/views/management/_menu.html.erb | 48 ++++++++++++++++------------- 1 file changed, 27 insertions(+), 21 deletions(-) diff --git a/app/views/management/_menu.html.erb b/app/views/management/_menu.html.erb index 050e5eb7f..e70ec9ee5 100644 --- a/app/views/management/_menu.html.erb +++ b/app/views/management/_menu.html.erb @@ -44,21 +44,25 @@ <% end %> -
  • > - <%= link_to create_investments_management_budgets_path do %> - - <%= t("management.menu.create_budget_investment") %> - <% end %> -
  • + <% if Setting['feature.budgets'] %> +
  • > + <%= link_to create_investments_management_budgets_path do %> + + <%= t("management.menu.create_budget_investment") %> + <% end %> +
  • + <% end %> -
  • > - <%= link_to support_investments_management_budgets_path do %> - - <%= t("management.menu.support_budget_investments") %> - <% end %> -
  • + <% if Setting['feature.budgets'] %> +
  • > + <%= link_to support_investments_management_budgets_path do %> + + <%= t("management.menu.support_budget_investments") %> + <% end %> +
  • + <% end %>
  • > <%= link_to print_management_proposals_path do %> @@ -74,13 +78,15 @@ <% end %>
  • -
  • > - <%= link_to print_investments_management_budgets_path do %> - - <%= t("management.menu.print_budget_investments") %> - <% end %> -
  • + <% if Setting['feature.budgets'] %> +
  • > + <%= link_to print_investments_management_budgets_path do %> + + <%= t("management.menu.print_budget_investments") %> + <% end %> +
  • + <% end %>
  • From 693030ff1791d93824e938907fc512399286d033 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pedro=20R=C3=ADos=20Flores?= Date: Mon, 9 Oct 2017 12:26:34 +0200 Subject: [PATCH 02/69] Wrapped two links under the same if clause. --- app/views/management/_menu.html.erb | 2 -- 1 file changed, 2 deletions(-) diff --git a/app/views/management/_menu.html.erb b/app/views/management/_menu.html.erb index e70ec9ee5..51df9518a 100644 --- a/app/views/management/_menu.html.erb +++ b/app/views/management/_menu.html.erb @@ -52,9 +52,7 @@ <%= t("management.menu.create_budget_investment") %> <% end %>
  • - <% end %> - <% if Setting['feature.budgets'] %>
  • > <%= link_to support_investments_management_budgets_path do %> From 87d4fa92b41bc87ccd2b5649cb694e174af00acf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pedro=20R=C3=ADos=20Flores?= Date: Mon, 9 Oct 2017 13:09:09 +0200 Subject: [PATCH 03/69] Wrapped the last link under the same if clause. --- app/views/management/_menu.html.erb | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/app/views/management/_menu.html.erb b/app/views/management/_menu.html.erb index 51df9518a..b01bbaf0c 100644 --- a/app/views/management/_menu.html.erb +++ b/app/views/management/_menu.html.erb @@ -60,6 +60,14 @@ <%= t("management.menu.support_budget_investments") %> <% end %>
  • + +
  • > + <%= link_to print_investments_management_budgets_path do %> + + <%= t("management.menu.print_budget_investments") %> + <% end %> +
  • <% end %>
  • > @@ -76,17 +84,6 @@ <% end %>
  • - <% if Setting['feature.budgets'] %> -
  • > - <%= link_to print_investments_management_budgets_path do %> - - <%= t("management.menu.print_budget_investments") %> - <% end %> -
  • - <% end %> - -
  • <%= link_to new_management_user_invite_path do %> From 10d7a1d89bf3a930c3f979d0d311bac94171dbf0 Mon Sep 17 00:00:00 2001 From: Manuel Ortega Date: Tue, 17 Oct 2017 14:37:27 +0200 Subject: [PATCH 04/69] Added investment's user generated tags to admin show and sort to the valuation tags --- .../admin/budget_investments/_written_by_author.html.erb | 5 +++++ app/views/admin/budget_investments/show.html.erb | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/app/views/admin/budget_investments/_written_by_author.html.erb b/app/views/admin/budget_investments/_written_by_author.html.erb index a913aff00..467d81481 100644 --- a/app/views/admin/budget_investments/_written_by_author.html.erb +++ b/app/views/admin/budget_investments/_written_by_author.html.erb @@ -56,3 +56,8 @@ <% end %> <%= safe_html_with_links @investment.description %> + +

    + <%= t("admin.budget_investments.show.tags") %> del usuario: + <%= @investment.tag_list.sort.join(', ') %> +

    diff --git a/app/views/admin/budget_investments/show.html.erb b/app/views/admin/budget_investments/show.html.erb index f220c0955..5fa35a1fa 100644 --- a/app/views/admin/budget_investments/show.html.erb +++ b/app/views/admin/budget_investments/show.html.erb @@ -19,7 +19,7 @@

    <%= t("admin.budget_investments.show.tags") %>: - <%= @investment.tags_on(:valuation).pluck(:name).join(', ') %> + <%= @investment.tags_on(:valuation).pluck(:name).sort.join(', ') %>

    From 12ac758e8ef58742408a2eb9787334e5c19e7f96 Mon Sep 17 00:00:00 2001 From: Manuel Ortega Date: Tue, 17 Oct 2017 18:11:29 +0200 Subject: [PATCH 05/69] Added investment's user generated tags to admin interface form --- .../admin/budget_investments_controller.rb | 2 +- .../admin/budget_investments/edit.html.erb | 9 ++++++- config/locales/en/admin.yml | 1 + config/locales/es/admin.yml | 1 + .../features/admin/budget_investments_spec.rb | 27 +++++++++++++++---- 5 files changed, 33 insertions(+), 7 deletions(-) diff --git a/app/controllers/admin/budget_investments_controller.rb b/app/controllers/admin/budget_investments_controller.rb index dd10930fb..4b6bd6b3a 100644 --- a/app/controllers/admin/budget_investments_controller.rb +++ b/app/controllers/admin/budget_investments_controller.rb @@ -51,7 +51,7 @@ class Admin::BudgetInvestmentsController < Admin::BaseController def budget_investment_params params.require(:budget_investment) - .permit(:title, :description, :external_url, :heading_id, :administrator_id, :valuation_tag_list, :incompatible, + .permit(:title, :description, :external_url, :heading_id, :administrator_id, :tag_list, :valuation_tag_list, :incompatible, :selected, valuator_ids: []) end diff --git a/app/views/admin/budget_investments/edit.html.erb b/app/views/admin/budget_investments/edit.html.erb index c33039021..ab843cf24 100644 --- a/app/views/admin/budget_investments/edit.html.erb +++ b/app/views/admin/budget_investments/edit.html.erb @@ -18,6 +18,13 @@ <%= f.cktext_area :description, maxlength: Budget::Investment.description_max_length, ckeditor: { language: I18n.locale } %> +

    + <%= f.label :tag_list, t("admin.budget_investments.edit.user_tags") %> + <%= f.text_field :tag_list, + value: @investment.tag_list.sort.join(','), + label: false %> +
    +
    <%= f.text_field :external_url %>
    @@ -39,7 +46,7 @@
    - <%= f.label :tag_list, t("admin.budget_investments.edit.tags") %> + <%= f.label :valuation_tag_list, t("admin.budget_investments.edit.tags") %>
    <% @tags.each do |tag| %> <%= tag.name %> diff --git a/config/locales/en/admin.yml b/config/locales/en/admin.yml index 87bbb6685..398ce6421 100644 --- a/config/locales/en/admin.yml +++ b/config/locales/en/admin.yml @@ -181,6 +181,7 @@ en: assigned_valuators: Valuators select_heading: Select heading submit_button: Update + user_tags: User assigned tags tags: Tags tags_placeholder: "Write the tags you want separated by commas (,)" undefined: Undefined diff --git a/config/locales/es/admin.yml b/config/locales/es/admin.yml index d1a24b314..e3a52977d 100644 --- a/config/locales/es/admin.yml +++ b/config/locales/es/admin.yml @@ -181,6 +181,7 @@ es: assigned_valuators: Evaluadores select_heading: Seleccionar partida submit_button: Actualizar + user_tags: Etiquetas asignadas por el usuario tags: Etiquetas tags_placeholder: "Escribe las etiquetas que desees separadas por comas (,)" undefined: Sin definir diff --git a/spec/features/admin/budget_investments_spec.rb b/spec/features/admin/budget_investments_spec.rb index 7252e2660..1ad89e6aa 100644 --- a/spec/features/admin/budget_investments_spec.rb +++ b/spec/features/admin/budget_investments_spec.rb @@ -421,20 +421,37 @@ feature 'Admin budget investments' do end end - scenario "Only displays valuation tags" do + scenario "Changes valuation and user generated tags" do budget_investment = create(:budget_investment, tag_list: 'Park') budget_investment.set_tag_list_on(:valuation, 'Education') budget_investment.save visit admin_budget_budget_investment_path(budget_investment.budget, budget_investment) - expect(page).to have_content "Education" - expect(page).to_not have_content "Park" + within("#user-tags") do + expect(page).to_not have_content "Education" + expect(page).to have_content "Park" + end click_link 'Edit classification' - expect(page).to have_content "Education" - expect(page).to_not have_content "Park" + fill_in 'budget_investment_tag_list', with: 'Park, Trees' + fill_in 'budget_investment_valuation_tag_list', with: 'Education, Environment' + click_button 'Update' + + visit admin_budget_budget_investment_path(budget_investment.budget, budget_investment) + + within("#user-tags") do + expect(page).to_not have_content "Education" + expect(page).to_not have_content "Environment" + expect(page).to have_content "Park, Trees" + end + + within("#tags") do + expect(page).to have_content "Education, Environment" + expect(page).to_not have_content "Park" + expect(page).to_not have_content "Trees" + end end scenario "Maintains user tags" do From 928186045a9623878c3ed3a73871dd07bc4a7a9d Mon Sep 17 00:00:00 2001 From: Manuel Ortega Date: Sun, 22 Oct 2017 14:25:15 +0200 Subject: [PATCH 06/69] Moved 'del usuario' text form view to locale files --- app/views/admin/budget_investments/_written_by_author.html.erb | 2 +- config/locales/en/admin.yml | 1 + config/locales/es/admin.yml | 3 ++- 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/app/views/admin/budget_investments/_written_by_author.html.erb b/app/views/admin/budget_investments/_written_by_author.html.erb index 467d81481..8cf2eca57 100644 --- a/app/views/admin/budget_investments/_written_by_author.html.erb +++ b/app/views/admin/budget_investments/_written_by_author.html.erb @@ -58,6 +58,6 @@ <%= safe_html_with_links @investment.description %>

    - <%= t("admin.budget_investments.show.tags") %> del usuario: + <%= t("admin.budget_investments.show.user_tags") %>: <%= @investment.tag_list.sort.join(', ') %>

    diff --git a/config/locales/en/admin.yml b/config/locales/en/admin.yml index 398ce6421..38365f777 100644 --- a/config/locales/en/admin.yml +++ b/config/locales/en/admin.yml @@ -157,6 +157,7 @@ en: dossier: Dossier edit_dossier: Edit dossier tags: Tags + user_tags: User tags undefined: Undefined milestone: Milestone new_milestone: Create new milestone diff --git a/config/locales/es/admin.yml b/config/locales/es/admin.yml index e3a52977d..19563a880 100644 --- a/config/locales/es/admin.yml +++ b/config/locales/es/admin.yml @@ -157,6 +157,7 @@ es: dossier: Informe edit_dossier: Editar informe tags: Etiquetas + user_tags: Etiquetas del usuario undefined: Sin definir milestone: Seguimiento new_milestone: Crear nuevo hito @@ -181,7 +182,7 @@ es: assigned_valuators: Evaluadores select_heading: Seleccionar partida submit_button: Actualizar - user_tags: Etiquetas asignadas por el usuario + user_tags: Etiquetas asignadas por el usuario tags: Etiquetas tags_placeholder: "Escribe las etiquetas que desees separadas por comas (,)" undefined: Sin definir From 5a3e701e8de2379c229c9944347b455f493688ca Mon Sep 17 00:00:00 2001 From: iagirre Date: Mon, 23 Oct 2017 13:19:22 +0200 Subject: [PATCH 07/69] Polls' stats migrated from Madrid's fork and sortable functions added for tables --- app/assets/javascripts/application.js | 2 + .../javascripts/table_sortable.js.coffee | 23 +++++ app/controllers/admin/stats_controller.rb | 7 +- app/views/admin/stats/polls.html.erb | 87 +++++++++++++++++++ app/views/admin/stats/show.html.erb | 2 + config/routes.rb | 1 + 6 files changed, 121 insertions(+), 1 deletion(-) create mode 100644 app/assets/javascripts/table_sortable.js.coffee create mode 100644 app/views/admin/stats/polls.html.erb diff --git a/app/assets/javascripts/application.js b/app/assets/javascripts/application.js index 51de9c678..611ecc546 100644 --- a/app/assets/javascripts/application.js +++ b/app/assets/javascripts/application.js @@ -73,6 +73,7 @@ //= require map //= require polls //= require sortable +//= require table_sortable var initialize_modules = function() { App.Comments.initialize(); @@ -113,6 +114,7 @@ var initialize_modules = function() { App.Map.initialize(); App.Polls.initialize(); App.Sortable.initialize(); + App.TableSortable.initialize(); }; $(function(){ diff --git a/app/assets/javascripts/table_sortable.js.coffee b/app/assets/javascripts/table_sortable.js.coffee new file mode 100644 index 000000000..331f794a4 --- /dev/null +++ b/app/assets/javascripts/table_sortable.js.coffee @@ -0,0 +1,23 @@ +App.TableSortable = + getCellValue: (row, index) -> + $(row).children('td').eq(index).text() + + comparer: (index) -> + (a, b) -> + valA = App.TableSortable.getCellValue(a, index) + valB = App.TableSortable.getCellValue(b, index) + return if $.isNumeric(valA) and $.isNumeric(valB) then valA - valB else valA.localeCompare(valB) + + initialize: -> + $('table.sortable th').click -> + table = $(this).parents('table').eq(0) + rows = table.find('tr:gt(0)').not('tfoot tr').toArray().sort(App.TableSortable.comparer($(this).index())) + @asc = !@asc + if !@asc + rows = rows.reverse() + i = 0 + while i < rows.length + table.append rows[i] + i++ + return + \ No newline at end of file diff --git a/app/controllers/admin/stats_controller.rb b/app/controllers/admin/stats_controller.rb index 5a50d03b4..91e266b77 100644 --- a/app/controllers/admin/stats_controller.rb +++ b/app/controllers/admin/stats_controller.rb @@ -36,4 +36,9 @@ class Admin::StatsController < Admin::BaseController @users_who_have_sent_message = DirectMessage.select(:sender_id).distinct.count end -end \ No newline at end of file + def polls + @polls = ::Poll.current + @participants = ::Poll::Voter.where(poll: @polls) + end + +end diff --git a/app/views/admin/stats/polls.html.erb b/app/views/admin/stats/polls.html.erb new file mode 100644 index 000000000..c2b0b8481 --- /dev/null +++ b/app/views/admin/stats/polls.html.erb @@ -0,0 +1,87 @@ +<%= back_link_to %> + +

    <%= t("admin.stats.polls.title")%>

    + +
    +
    +
    + +
    + +
    + +
    +
    +
    + +

    <%= t("admin.stats.polls.all") %>

    + + + + + + + + + <% @polls.each do |poll| %> + + + + + + <% end %> +
    <%= t("admin.stats.polls.table.poll_name") %><%= t("admin.stats.polls.total_participants") %><%= t("admin.stats.polls.table.origin_web") %>
    + <%= poll.name %> + + <%= poll.voters.select(:user_id).distinct.count %> + + <%= poll.voters.web.select(:user_id).distinct.count %> +
    + +<% @polls.each do |poll| %> +

    + <%= t("admin.stats.polls.poll_questions", poll: poll.name) %> +

    + + + + + + + + <% poll.questions.each do |question| %> + + + + + <% end %> + + + + + + +
    <%= t("admin.stats.polls.table.question_name") %> + <%= t("admin.stats.polls.table.origin_web") %> +
    + <%= question.title %> + + <%= ::Poll::Answer.by_question(question).count %> +
    + + <%= t("admin.stats.polls.table.origin_total") %>: + <%= ::Poll::Answer.where(question: poll.questions) + .select(:author_id).distinct.count %> + +
    +<% end %> \ No newline at end of file diff --git a/app/views/admin/stats/show.html.erb b/app/views/admin/stats/show.html.erb index 5df7b5df2..330a69b01 100644 --- a/app/views/admin/stats/show.html.erb +++ b/app/views/admin/stats/show.html.erb @@ -7,6 +7,8 @@

    <%= t "admin.stats.show.stats_title" %>

    + <%= link_to t("admin.stats.show.polls"), + polls_admin_stats_path, class: "button hollow" %> <%= link_to t("admin.stats.show.direct_messages"), direct_messages_admin_stats_path, class: "button hollow" %> <%= link_to t("admin.stats.show.proposal_notifications"), diff --git a/config/routes.rb b/config/routes.rb index 6f94594a3..2b7f41c60 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -323,6 +323,7 @@ Rails.application.routes.draw do resource :stats, only: :show do get :proposal_notifications, on: :collection get :direct_messages, on: :collection + get :polls, on: :collection end namespace :legislation do From a7d474910c91e97aedfbf326e453a1d133d917ed Mon Sep 17 00:00:00 2001 From: iagirre Date: Mon, 23 Oct 2017 16:17:25 +0200 Subject: [PATCH 08/69] Added missing i18n keys and css to make the cursor change when hover th in head --- app/assets/stylesheets/custom.scss | 5 +++++ config/locales/en/admin.yml | 12 ++++++++++++ config/locales/es/admin.yml | 12 ++++++++++++ 3 files changed, 29 insertions(+) diff --git a/app/assets/stylesheets/custom.scss b/app/assets/stylesheets/custom.scss index 090eb0342..06b4d91ce 100644 --- a/app/assets/stylesheets/custom.scss +++ b/app/assets/stylesheets/custom.scss @@ -3,3 +3,8 @@ // * English: https://github.com/consul/consul/blob/master/CUSTOMIZE_EN.md#css // * Spanish: https://github.com/consul/consul/blob/master/CUSTOMIZE_ES.md#css // + +table.sortable thead th:hover { + text-decoration: underline; + cursor: pointer; +} \ No newline at end of file diff --git a/config/locales/en/admin.yml b/config/locales/en/admin.yml index aa0fc0f8a..341ab8616 100644 --- a/config/locales/en/admin.yml +++ b/config/locales/en/admin.yml @@ -917,6 +917,7 @@ en: direct_messages: Direct messages proposal_notifications: Proposal notifications incomplete_verifications: Incomplete verifications + polls: Votaciones direct_messages: title: Direct messages total: Total @@ -925,6 +926,17 @@ en: title: Proposal notifications total: Total proposals_with_notifications: Proposals with notifications + polls: + title: Poll Stats + all: Polls + web_participants: Web participants + total_participants: Total Participants + poll_questions: "Questions from poll: %{poll}" + table: + poll_name: Poll + question_name: Question + origin_web: Web participants + origin_total: Total participants tags: create: Create topic destroy: Destroy topic diff --git a/config/locales/es/admin.yml b/config/locales/es/admin.yml index 2ff4449ec..ed2c36825 100644 --- a/config/locales/es/admin.yml +++ b/config/locales/es/admin.yml @@ -919,6 +919,7 @@ es: direct_messages: Mensajes directos proposal_notifications: Notificaciones de propuestas incomplete_verifications: Verificaciones incompletas + polls: Votaciones direct_messages: title: Mensajes directos total: Total @@ -927,6 +928,17 @@ es: title: Notificaciones de propuestas total: Total proposals_with_notifications: Propuestas con notificaciones + polls: + title: Estadísticas de votaciones + all: Votaciones + web_participants: Participantes en Web + total_participants: Participantes totales + poll_questions: "Preguntas de votación: %{poll}" + table: + poll_name: Votación + question_name: Pregunta + origin_web: Participantes Web + origin_total: Participantes Totales tags: create: Crear tema destroy: Eliminar tema From 7c02e2914bab96b188076d97414269cebb944ed8 Mon Sep 17 00:00:00 2001 From: iagirre Date: Mon, 23 Oct 2017 16:22:27 +0200 Subject: [PATCH 09/69] Fixed a translation in english (it was in spanish) --- config/locales/en/admin.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/locales/en/admin.yml b/config/locales/en/admin.yml index 341ab8616..a60600916 100644 --- a/config/locales/en/admin.yml +++ b/config/locales/en/admin.yml @@ -917,7 +917,7 @@ en: direct_messages: Direct messages proposal_notifications: Proposal notifications incomplete_verifications: Incomplete verifications - polls: Votaciones + polls: Polls direct_messages: title: Direct messages total: Total From 3815e2050670d0c47be43154381578c941a25bec Mon Sep 17 00:00:00 2001 From: iagirre Date: Mon, 23 Oct 2017 16:48:50 +0200 Subject: [PATCH 10/69] Specs for admins polls stats added --- spec/features/admin/stats_spec.rb | 95 +++++++++++++++++++++++++++++++ 1 file changed, 95 insertions(+) diff --git a/spec/features/admin/stats_spec.rb b/spec/features/admin/stats_spec.rb index c0aefe4e5..60dae016b 100644 --- a/spec/features/admin/stats_spec.rb +++ b/spec/features/admin/stats_spec.rb @@ -162,4 +162,99 @@ feature 'Stats' do end + context "Polls" do + + scenario "Total participants by origin" do + oa = create(:poll_officer_assignment) + 3.times { create(:poll_voter, origin: "web") } + + visit admin_stats_path + + within(".stats") do + click_link "Polls" + end + + within("#web_participants") do + expect(page).to have_content "3" + end + end + + scenario "Total participants" do + user = create(:user, :level_two) + 3.times { create(:poll_voter, user: user) } + create(:poll_voter) + + visit admin_stats_path + + within(".stats") do + click_link "Polls" + end + + within("#participants") do + expect(page).to have_content "2" + end + end + + scenario "Participants by poll" do + oa = create(:poll_officer_assignment) + + poll1 = create(:poll) + poll2 = create(:poll) + + 1.times { create(:poll_voter, poll: poll1, origin: "web") } + 2.times { create(:poll_voter, poll: poll2, origin: "web") } + + visit admin_stats_path + + within(".stats") do + click_link "Polls" + end + + within("#polls") do + + within("#poll_#{poll1.id}") do + expect(page).to have_content "1" + end + + within("#poll_#{poll2.id}") do + expect(page).to have_content "2" + end + + end + end + + scenario "Participants by poll question" do + user1 = create(:user, :level_two) + user2 = create(:user, :level_two) + + poll = create(:poll) + + question1 = create(:poll_question, :with_answers, poll: poll) + question2 = create(:poll_question, :with_answers, poll: poll) + + create(:poll_answer, question: question1, author: user1) + create(:poll_answer, question: question2, author: user1) + create(:poll_answer, question: question2, author: user2) + + visit admin_stats_path + + within(".stats") do + click_link "Polls" + end + + within("#poll_question_#{question1.id}") do + expect(page).to have_content "1" + end + + within("#poll_question_#{question2.id}") do + expect(page).to have_content "2" + end + + within("#poll_#{poll.id}_questions_total") do + expect(page).to have_content "2" + end + end + + end + end From b854d992484e196e724db33b3547616ea8682a69 Mon Sep 17 00:00:00 2001 From: iagirre Date: Fri, 27 Oct 2017 13:10:10 +0200 Subject: [PATCH 11/69] Assign/Unassign button for expired polls is disabled --- .../admin/poll/booth_assignments/_booth_assignment.html.erb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/views/admin/poll/booth_assignments/_booth_assignment.html.erb b/app/views/admin/poll/booth_assignments/_booth_assignment.html.erb index d78f7be8b..8fb944e9c 100644 --- a/app/views/admin/poll/booth_assignments/_booth_assignment.html.erb +++ b/app/views/admin/poll/booth_assignments/_booth_assignment.html.erb @@ -14,7 +14,7 @@ method: :delete, remote: true, title: t("admin.booth_assignments.manage.actions.unassign"), - class: "button hollow alert" %> + class: "button hollow alert #{@poll.expired? ? 'disabled' : ''}" %> <% else %> @@ -26,6 +26,6 @@ method: :post, remote: true, title: t("admin.booth_assignments.manage.actions.assign"), - class: "button" %> + class: "button #{@poll.expired? ? 'disabled' : ''}" %> <% end %> From 89425f50efdd3312afb76916b209832a25302ffd Mon Sep 17 00:00:00 2001 From: iagirre Date: Fri, 27 Oct 2017 14:57:32 +0200 Subject: [PATCH 12/69] First steps to destroy shifts when booth_assignments are destroyed --- app/models/poll.rb | 4 ++++ app/models/poll/booth_assignment.rb | 13 +++++++++++++ .../booth_assignments/_booth_assignment.html.erb | 3 ++- 3 files changed, 19 insertions(+), 1 deletion(-) diff --git a/app/models/poll.rb b/app/models/poll.rb index 27125d8a1..f08f9bdcd 100644 --- a/app/models/poll.rb +++ b/app/models/poll.rb @@ -90,4 +90,8 @@ class Poll < ActiveRecord::Base end end + def shifts_in_booth(booth_id) + officer_assignments.where(booth_assignment_id: booth_assignments.where(booth_id: booth_id).pluck(:id)).pluck(:officer_id).uniq + end + end diff --git a/app/models/poll/booth_assignment.rb b/app/models/poll/booth_assignment.rb index 8489c3cf0..a1d0c0d39 100644 --- a/app/models/poll/booth_assignment.rb +++ b/app/models/poll/booth_assignment.rb @@ -8,5 +8,18 @@ class Poll has_many :voters has_many :partial_results has_many :recounts + + before_destroy :destroy_poll_shifts + + def has_shifts? + + end + + private + + def destroy_poll_shifts +# officers = poll.officers_in_booth(booth.id) +# Poll::Shift.where(officer_id: officers, booth_id: booth.id) + end end end diff --git a/app/views/admin/poll/booth_assignments/_booth_assignment.html.erb b/app/views/admin/poll/booth_assignments/_booth_assignment.html.erb index 8fb944e9c..b1ab3885e 100644 --- a/app/views/admin/poll/booth_assignments/_booth_assignment.html.erb +++ b/app/views/admin/poll/booth_assignments/_booth_assignment.html.erb @@ -14,7 +14,8 @@ method: :delete, remote: true, title: t("admin.booth_assignments.manage.actions.unassign"), - class: "button hollow alert #{@poll.expired? ? 'disabled' : ''}" %> + class: "button hollow alert #{@poll.expired? ? 'disabled' : ''}", + data: (booth_assignment.has_shifts? ? {confirm: "Are you sure?"} : nil) %> <% else %> From 1077e25b2ba9fcff63cefe64537fcc5c711f6551 Mon Sep 17 00:00:00 2001 From: iagirre Date: Mon, 30 Oct 2017 12:36:07 +0100 Subject: [PATCH 13/69] Shifts are destroyed when a booths is unassigned. An alert appears if there are shifts, but it doesn't if there aren't. --- app/models/poll.rb | 4 ---- app/models/poll/booth_assignment.rb | 15 +++++++++------ .../booth_assignments/_booth_assignment.html.erb | 2 +- config/locales/en/admin.yml | 2 ++ config/locales/es/admin.yml | 2 ++ 5 files changed, 14 insertions(+), 11 deletions(-) diff --git a/app/models/poll.rb b/app/models/poll.rb index f08f9bdcd..27125d8a1 100644 --- a/app/models/poll.rb +++ b/app/models/poll.rb @@ -90,8 +90,4 @@ class Poll < ActiveRecord::Base end end - def shifts_in_booth(booth_id) - officer_assignments.where(booth_assignment_id: booth_assignments.where(booth_id: booth_id).pluck(:id)).pluck(:officer_id).uniq - end - end diff --git a/app/models/poll/booth_assignment.rb b/app/models/poll/booth_assignment.rb index a1d0c0d39..81759ee0f 100644 --- a/app/models/poll/booth_assignment.rb +++ b/app/models/poll/booth_assignment.rb @@ -3,23 +3,26 @@ class Poll belongs_to :booth belongs_to :poll + before_destroy :destroy_poll_shifts, only: :destroy + has_many :officer_assignments, class_name: "Poll::OfficerAssignment", dependent: :destroy has_many :officers, through: :officer_assignments has_many :voters has_many :partial_results has_many :recounts - before_destroy :destroy_poll_shifts - - def has_shifts? - + def shifts? + shifts.empty? ? false : true end private + def shifts + Poll::Shift.where(booth_id: booth_id, officer_id: officer_assignments.pluck(:officer_id), date: officer_assignments.pluck(:date)) + end + def destroy_poll_shifts -# officers = poll.officers_in_booth(booth.id) -# Poll::Shift.where(officer_id: officers, booth_id: booth.id) + shifts.destroy_all end end end diff --git a/app/views/admin/poll/booth_assignments/_booth_assignment.html.erb b/app/views/admin/poll/booth_assignments/_booth_assignment.html.erb index b1ab3885e..b3b711f9f 100644 --- a/app/views/admin/poll/booth_assignments/_booth_assignment.html.erb +++ b/app/views/admin/poll/booth_assignments/_booth_assignment.html.erb @@ -15,7 +15,7 @@ remote: true, title: t("admin.booth_assignments.manage.actions.unassign"), class: "button hollow alert #{@poll.expired? ? 'disabled' : ''}", - data: (booth_assignment.has_shifts? ? {confirm: "Are you sure?"} : nil) %> + data: (booth_assignment.shifts? ? {confirm: "#{t("admin.poll_booth_assignments.alert.shifts")}"} : nil) %> <% else %> diff --git a/config/locales/en/admin.yml b/config/locales/en/admin.yml index a2062f8ce..c36ba0b94 100644 --- a/config/locales/en/admin.yml +++ b/config/locales/en/admin.yml @@ -544,6 +544,8 @@ en: assign: Assign booth unassign: Unassign booth poll_booth_assignments: + alert: + shifts: "There are shifts associated to this booth. If you remove the booth assignment, the shifts will be also deleted. Continue?" flash: destroy: "Booth not assigned anymore" create: "Booth assigned" diff --git a/config/locales/es/admin.yml b/config/locales/es/admin.yml index 1c7d0fa74..cc3683bf4 100644 --- a/config/locales/es/admin.yml +++ b/config/locales/es/admin.yml @@ -544,6 +544,8 @@ es: assign: Assign booth unassign: Unassign booth poll_booth_assignments: + alert: + shifts: "Hay turnos asignados para esta urna. Si la desasignas, esos turnos se eliminarán. ¿Deseas continuar?" flash: destroy: "Urna desasignada" create: "Urna asignada" From 4b8a471d3842e409250e678d599c42a7e3da8d24 Mon Sep 17 00:00:00 2001 From: iagirre Date: Mon, 30 Oct 2017 16:50:25 +0100 Subject: [PATCH 14/69] Specs added to test the functionality and some UI modified to make test pass --- .../_booth_assignment.html.erb | 6 +-- .../admin/poll/booth_assigments_spec.rb | 37 ++++++++++++++++++- spec/models/poll/booth_assignment_spec.rb | 29 +++++++++++++++ 3 files changed, 68 insertions(+), 4 deletions(-) create mode 100644 spec/models/poll/booth_assignment_spec.rb diff --git a/app/views/admin/poll/booth_assignments/_booth_assignment.html.erb b/app/views/admin/poll/booth_assignments/_booth_assignment.html.erb index b3b711f9f..d7896446f 100644 --- a/app/views/admin/poll/booth_assignments/_booth_assignment.html.erb +++ b/app/views/admin/poll/booth_assignments/_booth_assignment.html.erb @@ -14,8 +14,8 @@ method: :delete, remote: true, title: t("admin.booth_assignments.manage.actions.unassign"), - class: "button hollow alert #{@poll.expired? ? 'disabled' : ''}", - data: (booth_assignment.shifts? ? {confirm: "#{t("admin.poll_booth_assignments.alert.shifts")}"} : nil) %> + class: "button hollow alert", + data: (booth_assignment.shifts? ? {confirm: "#{t("admin.poll_booth_assignments.alert.shifts")}"} : nil) if !@poll.expired? %> <% else %> @@ -27,6 +27,6 @@ method: :post, remote: true, title: t("admin.booth_assignments.manage.actions.assign"), - class: "button #{@poll.expired? ? 'disabled' : ''}" %> + class: "button" if !@poll.expired? %> <% end %> diff --git a/spec/features/admin/poll/booth_assigments_spec.rb b/spec/features/admin/poll/booth_assigments_spec.rb index cceec1a3e..52f5d89fa 100644 --- a/spec/features/admin/poll/booth_assigments_spec.rb +++ b/spec/features/admin/poll/booth_assigments_spec.rb @@ -106,9 +106,44 @@ feature 'Admin booths assignments' do expect(page).to have_content 'There are no booths assigned to this poll.' expect(page).not_to have_content booth.name end + + scenario 'Unassing booth whith associated shifts', :js do + assignment = create(:poll_booth_assignment, poll: poll, booth: booth) + officer = create(:poll_officer) + create(:poll_officer_assignment, officer: officer, booth_assignment: assignment) + create(:poll_shift, booth: booth, officer: officer) + + visit manage_admin_poll_booth_assignments_path(poll) + + within("#poll_booth_#{booth.id}") do + expect(page).to have_content(booth.name) + expect(page).to have_content "Assigned" + + click_link 'Unassign booth' + + expect(page).to have_content "Unassigned" + expect(page).not_to have_content "Assigned" + expect(page).to have_link "Assign booth" + end + end + + scenario "Cannot unassing booth if poll is expired" do + poll_expired = create(:poll, :expired) + create(:poll_booth_assignment, poll: poll_expired, booth: booth) + + visit manage_admin_poll_booth_assignments_path(poll_expired) + + within("#poll_booth_#{booth.id}") do + expect(page).to have_content(booth.name) + expect(page).to have_content "Assigned" + + expect(page).not_to have_link 'Unassign booth' + end + + end end - feature 'Show' do + xfeature 'Show' do scenario 'Lists all assigned poll officers' do poll = create(:poll) booth = create(:poll_booth) diff --git a/spec/models/poll/booth_assignment_spec.rb b/spec/models/poll/booth_assignment_spec.rb new file mode 100644 index 000000000..8663e3872 --- /dev/null +++ b/spec/models/poll/booth_assignment_spec.rb @@ -0,0 +1,29 @@ +require 'rails_helper' + +describe :booth_assignment do + let(:poll){create(:poll)} + let(:booth){create(:poll_booth)} + let(:booth1){create(:poll_booth)} + + it "should check if there are shifts" do + assignment_with_shifts = create(:poll_booth_assignment, poll: poll, booth: booth) + assignment_without_shifts = create(:poll_booth_assignment, poll: poll, booth: booth1) + officer = create(:poll_officer) + create(:poll_officer_assignment, officer: officer, booth_assignment: assignment_with_shifts) + create(:poll_shift, booth: booth, officer: officer) + + expect(assignment_with_shifts.shifts?).to eq(true) + expect(assignment_without_shifts.shifts?).to eq(false) + end + + it "should delete shifts associated to booth assignments" do + assignment = create(:poll_booth_assignment, poll: poll, booth: booth) + officer = create(:poll_officer) + create(:poll_officer_assignment, officer: officer, booth_assignment: assignment) + create(:poll_shift, booth: booth, officer: officer) + + assignment.destroy + + expect(Poll::Shift.all.count).to eq(0) + end +end \ No newline at end of file From 4819d1b74e770ad367c5c79060a64d808b09609e Mon Sep 17 00:00:00 2001 From: iagirre Date: Mon, 30 Oct 2017 16:55:13 +0100 Subject: [PATCH 15/69] Enabled one test disabled to run in local --- spec/features/admin/poll/booth_assigments_spec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/features/admin/poll/booth_assigments_spec.rb b/spec/features/admin/poll/booth_assigments_spec.rb index 52f5d89fa..29e1eccde 100644 --- a/spec/features/admin/poll/booth_assigments_spec.rb +++ b/spec/features/admin/poll/booth_assigments_spec.rb @@ -143,7 +143,7 @@ feature 'Admin booths assignments' do end end - xfeature 'Show' do + feature 'Show' do scenario 'Lists all assigned poll officers' do poll = create(:poll) booth = create(:poll_booth) From bfcbb6c0ad6a646fb44ece0512557535e14c13ac Mon Sep 17 00:00:00 2001 From: iagirre Date: Tue, 31 Oct 2017 13:04:30 +0100 Subject: [PATCH 16/69] Validation in model and in form added. When users makes the on focus on population field an explanation appears. Some specs added to test the model validations --- app/models/budget/heading.rb | 1 + app/views/admin/budgets/_group.html.erb | 11 +++++++++-- config/locales/en/admin.yml | 1 + config/locales/es/admin.yml | 1 + spec/models/budget/heading_spec.rb | 14 ++++++++++++++ 5 files changed, 26 insertions(+), 2 deletions(-) diff --git a/app/models/budget/heading.rb b/app/models/budget/heading.rb index 1a232c75e..d740db502 100644 --- a/app/models/budget/heading.rb +++ b/app/models/budget/heading.rb @@ -10,6 +10,7 @@ class Budget validates :name, presence: true, uniqueness: { if: :name_exists_in_budget_headings } validates :price, presence: true validates :slug, presence: true, format: /\A[a-z0-9\-_]+\z/ + validates :population, numericality: { greater_than: 0 }, allow_nil: true delegate :budget, :budget_id, to: :group, allow_nil: true diff --git a/app/views/admin/budgets/_group.html.erb b/app/views/admin/budgets/_group.html.erb index 8537fa477..3d65730cc 100644 --- a/app/views/admin/budgets/_group.html.erb +++ b/app/views/admin/budgets/_group.html.erb @@ -49,10 +49,17 @@
    - <%= f.text_field :population, + <%= f.number_field :population, label: false, maxlength: 8, - placeholder: t("admin.budgets.form.population") %> + min: 1, + placeholder: t("admin.budgets.form.population"), + data: {toggle_focus: "population-info"} %> +
    +
    +
    diff --git a/config/locales/en/admin.yml b/config/locales/en/admin.yml index 483777d6f..e3ccb4446 100644 --- a/config/locales/en/admin.yml +++ b/config/locales/en/admin.yml @@ -105,6 +105,7 @@ en: table_heading: Heading table_amount: Amount table_population: Population + population_info: "Budget Heading population field is used for Statistic purposes at the end of the Budget to show for each Heading that represents an area with population what percentage voted. The field is optional so you can leave it empty if it doesn't apply." winners: calculate: Calculate Winner Investments calculated: Winners being calculated, it may take a minute. diff --git a/config/locales/es/admin.yml b/config/locales/es/admin.yml index 648fdb8a6..109078002 100644 --- a/config/locales/es/admin.yml +++ b/config/locales/es/admin.yml @@ -105,6 +105,7 @@ es: table_heading: Partida table_amount: Cantidad table_population: Población + population_info: "El campo población de las partidas presupuestarias se usa con fines estadísticos únicamente, con el objetivo de mostrar el porcentaje de votos habidos en cada partida que represente un área con población. Es un campo opcional, así que puedes dejarlo en blanco si no aplica." winners: calculate: Calcular propuestas ganadoras calculated: Calculando ganadoras, puede tardar un minuto. diff --git a/spec/models/budget/heading_spec.rb b/spec/models/budget/heading_spec.rb index ee2e4c142..73e3bb994 100644 --- a/spec/models/budget/heading_spec.rb +++ b/spec/models/budget/heading_spec.rb @@ -25,4 +25,18 @@ describe Budget::Heading do end end + describe "Save population" do + it "Allows nil for population" do + expect(create(:budget_heading, group: group, name: 'Population is nil')).to be_valid + end + + it "Doesn't allow 0 for population" do + expect(create(:budget_heading, group: group, name: 'Population is 0', population: 0)).not_to be_valid + end + + it "Allows value > 0 for population" do + expect(create(:budget_heading, group: group, name: 'Population is 10', population: 10)).to be_valid + end + end + end From aed0013e799312de5d1a2dc62e4e63938ed8aea6 Mon Sep 17 00:00:00 2001 From: iagirre Date: Tue, 31 Oct 2017 15:54:17 +0100 Subject: [PATCH 17/69] Spec fixed --- spec/models/budget/heading_spec.rb | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/spec/models/budget/heading_spec.rb b/spec/models/budget/heading_spec.rb index 73e3bb994..76df1fa5c 100644 --- a/spec/models/budget/heading_spec.rb +++ b/spec/models/budget/heading_spec.rb @@ -26,17 +26,22 @@ describe Budget::Heading do end describe "Save population" do - it "Allows nil for population" do - expect(create(:budget_heading, group: group, name: 'Population is nil')).to be_valid + it "Allows population == nil" do + expect(create(:budget_heading, group: group, name: 'Population is nil', population: nil)).to be_valid end - it "Doesn't allow 0 for population" do - expect(create(:budget_heading, group: group, name: 'Population is 0', population: 0)).not_to be_valid - end - - it "Allows value > 0 for population" do - expect(create(:budget_heading, group: group, name: 'Population is 10', population: 10)).to be_valid - end + it "Doesn't allow population <= 0" do + heading = create(:budget_heading, group: group, name: 'Population is > 0') + + heading.population = 0 + expect(heading).not_to be_valid + + heading.population = -10 + expect(heading).not_to be_valid + + heading.population = 10 + expect(heading).to be_valid + end end end From 7f0e447e0f6be5dfb46d4c6deb3be835107b9f2b Mon Sep 17 00:00:00 2001 From: iagirre Date: Wed, 15 Nov 2017 08:56:31 +0100 Subject: [PATCH 18/69] One aproach to make the randomness work with kaminari --- .../budgets/investments_controller.rb | 19 ++++++++++++++----- app/models/budget/investment.rb | 2 +- 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/app/controllers/budgets/investments_controller.rb b/app/controllers/budgets/investments_controller.rb index bb00f24af..0c3f9a538 100644 --- a/app/controllers/budgets/investments_controller.rb +++ b/app/controllers/budgets/investments_controller.rb @@ -28,8 +28,8 @@ module Budgets respond_to :html, :js def index - @investments = @investments.apply_filters_and_search(@budget, params, @current_filter) - .send("sort_by_#{@current_order}").page(params[:page]).per(10).for_render + @investments = investments.page(params[:page]).per(10).for_render + @investment_ids = @investments.pluck(:id) load_investment_votes(@investments) @tag_cloud = tag_cloud @@ -94,9 +94,7 @@ module Budgets def set_random_seed if params[:order] == 'random' || params[:order].blank? - params[:random_seed] ||= rand(99) / 100.0 - seed = Float(params[:random_seed]) rescue 0 - Budget::Investment.connection.execute("select setseed(#{seed})") + params[:random_seed] ||= rand(9) else params[:random_seed] = nil end @@ -131,6 +129,17 @@ module Budgets TagCloud.new(Budget::Investment, params[:search]) end + def investments + case @current_order + when 'random' + @investments.apply_filters_and_search(@budget, params, @current_filter) + .send("sort_by_#{@current_order}", params[:random_seed]) + else + @investments.apply_filters_and_search(@budget, params, @current_filter) + .send("sort_by_#{@current_order}") + end + end + end end diff --git a/app/models/budget/investment.rb b/app/models/budget/investment.rb index ddf6e819c..8ee768574 100644 --- a/app/models/budget/investment.rb +++ b/app/models/budget/investment.rb @@ -43,7 +43,7 @@ class Budget scope :sort_by_confidence_score, -> { reorder(confidence_score: :desc, id: :desc) } scope :sort_by_ballots, -> { reorder(ballot_lines_count: :desc, id: :desc) } scope :sort_by_price, -> { reorder(price: :desc, confidence_score: :desc, id: :desc) } - scope :sort_by_random, -> { reorder("RANDOM()") } + scope :sort_by_random, ->(seed) { reorder("budget_investments.id % #{seed}, budget_investments.id") } scope :valuation_open, -> { where(valuation_finished: false) } scope :without_admin, -> { valuation_open.where(administrator_id: nil) } From f3527b1311e3501ea950bb3f816954b3627215c8 Mon Sep 17 00:00:00 2001 From: iagirre Date: Wed, 15 Nov 2017 09:01:35 +0100 Subject: [PATCH 19/69] Test added to check the repetition of elements between pages when random order used. Scope variable initialized to 1 --- app/models/budget/investment.rb | 2 +- spec/features/budgets/investments_spec.rb | 19 +++++++++++++++++++ 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/app/models/budget/investment.rb b/app/models/budget/investment.rb index 8ee768574..add7c3587 100644 --- a/app/models/budget/investment.rb +++ b/app/models/budget/investment.rb @@ -43,7 +43,7 @@ class Budget scope :sort_by_confidence_score, -> { reorder(confidence_score: :desc, id: :desc) } scope :sort_by_ballots, -> { reorder(ballot_lines_count: :desc, id: :desc) } scope :sort_by_price, -> { reorder(price: :desc, confidence_score: :desc, id: :desc) } - scope :sort_by_random, ->(seed) { reorder("budget_investments.id % #{seed}, budget_investments.id") } + scope :sort_by_random, ->(seed) { reorder("budget_investments.id % #{seed || 1}, budget_investments.id") } scope :valuation_open, -> { where(valuation_finished: false) } scope :without_admin, -> { valuation_open.where(administrator_id: nil) } diff --git a/spec/features/budgets/investments_spec.rb b/spec/features/budgets/investments_spec.rb index d17bd9c91..ce56dd9b2 100644 --- a/spec/features/budgets/investments_spec.rb +++ b/spec/features/budgets/investments_spec.rb @@ -170,6 +170,25 @@ feature 'Budget Investments' do expect(order).to eq(new_order) end + scenario "Investments are not repeated with random order", :js do + 12.times { create(:budget_investment, heading: heading) } + # 12 instead of per_page + 2 because in each page there are 10 (in this case), not 25 + + visit budget_investments_path(budget, order: 'random') + + first_page_investments = all(".budget-investment h3").collect {|i| i.text } + + click_link 'Next' + expect(page).to have_content "You're on page 2" + + second_page_investments = all(".budget-investment h3").collect {|i| i.text } + + common_values = first_page_investments & second_page_investments + + expect(common_values.length).to eq(0) + + end + scenario 'Proposals are ordered by confidence_score', :js do create(:budget_investment, heading: heading, title: 'Best proposal').update_column(:confidence_score, 10) create(:budget_investment, heading: heading, title: 'Worst proposal').update_column(:confidence_score, 2) From fbb02095bb02544352130c7f754e749fb9e2e0e4 Mon Sep 17 00:00:00 2001 From: iagirre Date: Wed, 15 Nov 2017 09:02:19 +0100 Subject: [PATCH 20/69] Some fixes to new code to make the test pass --- app/controllers/budgets/investments_controller.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/controllers/budgets/investments_controller.rb b/app/controllers/budgets/investments_controller.rb index 0c3f9a538..a18c82cdf 100644 --- a/app/controllers/budgets/investments_controller.rb +++ b/app/controllers/budgets/investments_controller.rb @@ -94,7 +94,7 @@ module Budgets def set_random_seed if params[:order] == 'random' || params[:order].blank? - params[:random_seed] ||= rand(9) + params[:random_seed] ||= rand(1..9) else params[:random_seed] = nil end From 87f6f14d48c5b7b5ee6469da4aaa7673d6ffcd59 Mon Sep 17 00:00:00 2001 From: iagirre Date: Wed, 15 Nov 2017 11:50:06 +0100 Subject: [PATCH 21/69] Bigger random seed range. Tests added to check the randomness between browsers --- .../budgets/investments_controller.rb | 3 +- spec/features/budgets/investments_spec.rb | 47 ++++++++++++++++++- 2 files changed, 47 insertions(+), 3 deletions(-) diff --git a/app/controllers/budgets/investments_controller.rb b/app/controllers/budgets/investments_controller.rb index a18c82cdf..aaf65765f 100644 --- a/app/controllers/budgets/investments_controller.rb +++ b/app/controllers/budgets/investments_controller.rb @@ -94,7 +94,8 @@ module Budgets def set_random_seed if params[:order] == 'random' || params[:order].blank? - params[:random_seed] ||= rand(1..9) + seed = rand(10..99) / 10.0 + params[:random_seed] ||= Float(seed) rescue 0 else params[:random_seed] = nil end diff --git a/spec/features/budgets/investments_spec.rb b/spec/features/budgets/investments_spec.rb index ce56dd9b2..535e272a3 100644 --- a/spec/features/budgets/investments_spec.rb +++ b/spec/features/budgets/investments_spec.rb @@ -1,4 +1,5 @@ require 'rails_helper' +require 'sessions_helper' feature 'Budget Investments' do @@ -176,12 +177,12 @@ feature 'Budget Investments' do visit budget_investments_path(budget, order: 'random') - first_page_investments = all(".budget-investment h3").collect {|i| i.text } + first_page_investments = investments_order click_link 'Next' expect(page).to have_content "You're on page 2" - second_page_investments = all(".budget-investment h3").collect {|i| i.text } + second_page_investments = investments_order common_values = first_page_investments & second_page_investments @@ -206,6 +207,48 @@ feature 'Budget Investments' do expect(current_url).to include('order=confidence_score') expect(current_url).to include('page=1') end + + scenario 'Each user as a different and consistent random budget investment order', :js do + 12.times { create(:budget_investment, heading: heading) } + + in_browser(:one) do + visit budget_investments_path(budget, heading: heading) + @first_user_investments_order = investments_order + end + + in_browser(:two) do + visit budget_investments_path(budget, heading: heading) + @second_user_investments_order = investments_order + end + + expect(@first_user_investments_order).not_to eq(@second_user_investments_order) + + in_browser(:one) do + visit budget_investments_path(budget, heading: heading) +# click_link 'Next' +# expect(page).to have_content "You're on page 2" +# +# click_link 'Previous' +# expect(page).to have_content "You're on page 1" +# + expect(investments_order).to eq(@first_user_investments_order) + end + + in_browser(:two) do + visit budget_investments_path(budget, heading: heading) +# click_link 'Next' +# expect(page).to have_content "You're on page 2" +# +# click_link 'Previous' +# expect(page).to have_content "You're on page 1" +# + expect(investments_order).to eq(@second_user_investments_order) + end + end + + def investments_order + all(".budget-investment h3").collect {|i| i.text } + end end From d1185662349e31517d2c7cbdb4360b358c855bf0 Mon Sep 17 00:00:00 2001 From: iagirre Date: Wed, 15 Nov 2017 12:49:21 +0100 Subject: [PATCH 22/69] Test changed to check the order when navigating through pages --- spec/features/budgets/investments_spec.rb | 30 +++++++++++------------ 1 file changed, 14 insertions(+), 16 deletions(-) diff --git a/spec/features/budgets/investments_spec.rb b/spec/features/budgets/investments_spec.rb index 535e272a3..fa7749a4b 100644 --- a/spec/features/budgets/investments_spec.rb +++ b/spec/features/budgets/investments_spec.rb @@ -207,7 +207,7 @@ feature 'Budget Investments' do expect(current_url).to include('order=confidence_score') expect(current_url).to include('page=1') end - + scenario 'Each user as a different and consistent random budget investment order', :js do 12.times { create(:budget_investment, heading: heading) } @@ -224,28 +224,26 @@ feature 'Budget Investments' do expect(@first_user_investments_order).not_to eq(@second_user_investments_order) in_browser(:one) do - visit budget_investments_path(budget, heading: heading) -# click_link 'Next' -# expect(page).to have_content "You're on page 2" -# -# click_link 'Previous' -# expect(page).to have_content "You're on page 1" -# + click_link 'Next' + expect(page).to have_content "You're on page 2" + + click_link 'Previous' + expect(page).to have_content "You're on page 1" + expect(investments_order).to eq(@first_user_investments_order) end in_browser(:two) do - visit budget_investments_path(budget, heading: heading) -# click_link 'Next' -# expect(page).to have_content "You're on page 2" -# -# click_link 'Previous' -# expect(page).to have_content "You're on page 1" -# + click_link 'Next' + expect(page).to have_content "You're on page 2" + + click_link 'Previous' + expect(page).to have_content "You're on page 1" + expect(investments_order).to eq(@second_user_investments_order) end end - + def investments_order all(".budget-investment h3").collect {|i| i.text } end From 4e086de4935bc9e23ab18d3f1ce48042dd979c8e Mon Sep 17 00:00:00 2001 From: Angel Perez Date: Thu, 26 Oct 2017 16:03:39 -0400 Subject: [PATCH 23/69] Add 'Delete' button to Valuators index/search views --- app/views/admin/valuators/index.html.erb | 17 ++++++++++------- app/views/admin/valuators/search.html.erb | 7 ++++++- config/locales/en/admin.yml | 1 + config/locales/es/admin.yml | 1 + 4 files changed, 18 insertions(+), 8 deletions(-) diff --git a/app/views/admin/valuators/index.html.erb b/app/views/admin/valuators/index.html.erb index 622d01307..dfb93ed80 100644 --- a/app/views/admin/valuators/index.html.erb +++ b/app/views/admin/valuators/index.html.erb @@ -1,6 +1,6 @@

    <%= t("admin.valuators.index.title") %>

    -<%= render 'admin/shared/user_search', url: search_admin_valuators_path %> +<%= render "admin/shared/user_search", url: search_admin_valuators_path %>
    <% if @valuators.any? %> @@ -11,16 +11,13 @@ <%= t("admin.valuators.index.name") %> <%= t("admin.valuators.index.email") %> <%= t("admin.valuators.index.description") %> + <%= t("admin.actions.actions") %> <% @valuators.each do |valuator| %> - - <%= valuator.name %> - - - <%= valuator.email %> - + <%= valuator.name %> + <%= valuator.email %> <% if valuator.description.present? %> <%= valuator.description %> @@ -28,6 +25,12 @@ <%= t("admin.valuators.index.no_description") %> <% end %> + + <%= link_to t("admin.valuators.valuator.delete"), + admin_valuator_path(valuator), + method: :delete, + class: "button hollow alert expanded" %> + <% end %> diff --git a/app/views/admin/valuators/search.html.erb b/app/views/admin/valuators/search.html.erb index 2710cb44d..b383e554d 100644 --- a/app/views/admin/valuators/search.html.erb +++ b/app/views/admin/valuators/search.html.erb @@ -29,7 +29,12 @@ <%= t("admin.valuators.index.no_description") %> <% end %> - <% unless user.valuator? %> + <% if user.valuator? %> + <%= link_to t("admin.valuators.valuator.delete"), + admin_valuator_path(user), + method: :delete, + class: "button hollow alert expanded" %> + <% else %> <%= form_for Valuator.new(user: user), url: admin_valuators_path do |f| %> <%= f.text_field :description, label: false, diff --git a/config/locales/en/admin.yml b/config/locales/en/admin.yml index 823d7084b..911428b01 100644 --- a/config/locales/en/admin.yml +++ b/config/locales/en/admin.yml @@ -481,6 +481,7 @@ en: valuator: description_placeholder: 'Description (optional)' add: Add to valuators + delete: Delete search: title: 'Valuators: User search' summary: diff --git a/config/locales/es/admin.yml b/config/locales/es/admin.yml index 8d0b6cbf8..8b97a4ec0 100644 --- a/config/locales/es/admin.yml +++ b/config/locales/es/admin.yml @@ -481,6 +481,7 @@ es: valuator: description_placeholder: 'Descripción (opcional)' add: Añadir como evaluador + delete: Borrar search: title: 'Evaluadores: Búsqueda de usuarios' summary: From db86cc52166c41dfc681623369a26bc067bc0ef1 Mon Sep 17 00:00:00 2001 From: Angel Perez Date: Thu, 26 Oct 2017 16:12:03 -0400 Subject: [PATCH 24/69] Enable 'destroy' action for Valuator on controller --- app/controllers/admin/valuators_controller.rb | 5 +++++ app/models/abilities/administrator.rb | 2 +- config/routes.rb | 2 +- 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/app/controllers/admin/valuators_controller.rb b/app/controllers/admin/valuators_controller.rb index d567a38b2..8b454a1a2 100644 --- a/app/controllers/admin/valuators_controller.rb +++ b/app/controllers/admin/valuators_controller.rb @@ -19,6 +19,11 @@ class Admin::ValuatorsController < Admin::BaseController redirect_to admin_valuators_path end + def destroy + @valuator.destroy + redirect_to admin_valuators_path + end + def summary @valuators = Valuator.order(spending_proposals_count: :desc) end diff --git a/app/models/abilities/administrator.rb b/app/models/abilities/administrator.rb index 951f06249..3f136f913 100644 --- a/app/models/abilities/administrator.rb +++ b/app/models/abilities/administrator.rb @@ -43,7 +43,7 @@ module Abilities can [:search, :create, :index, :destroy], ::Administrator can [:search, :create, :index, :destroy], ::Moderator - can [:search, :create, :index, :summary], ::Valuator + can [:search, :create, :index, :destroy, :summary], ::Valuator can [:search, :create, :index, :destroy], ::Manager can [:search, :index], ::User diff --git a/config/routes.rb b/config/routes.rb index 491127439..9ce97f45b 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -272,7 +272,7 @@ Rails.application.routes.draw do get :search, on: :collection end - resources :valuators, only: [:index, :create] do + resources :valuators, only: [:index, :create, :destroy] do get :search, on: :collection get :summary, on: :collection end From 6e28e9a5bed89db4fe9bc2fe30e49f5b60d68d0f Mon Sep 17 00:00:00 2001 From: Angel Perez Date: Thu, 26 Oct 2017 16:24:17 -0400 Subject: [PATCH 25/69] Add test for 'Delete Valuator' scenario --- spec/features/admin/valuators_spec.rb | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/spec/features/admin/valuators_spec.rb b/spec/features/admin/valuators_spec.rb index bb631cbc3..f1dfa68b3 100644 --- a/spec/features/admin/valuators_spec.rb +++ b/spec/features/admin/valuators_spec.rb @@ -29,6 +29,14 @@ feature 'Admin valuators' do end end + scenario 'Delete Valuator' do + click_link 'Delete' + + within('#valuators') do + expect(page).to_not have_content(@valuator.name) + end + end + context 'Search' do background do From 554188f8d02b4651e750fe87d1d114ca0e5d7028 Mon Sep 17 00:00:00 2001 From: Bertocq Date: Sat, 18 Nov 2017 10:43:54 +0100 Subject: [PATCH 26/69] Expect pagination url links to contain full path including domain --- spec/features/proposals_spec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/features/proposals_spec.rb b/spec/features/proposals_spec.rb index 81f7fb998..28049644b 100644 --- a/spec/features/proposals_spec.rb +++ b/spec/features/proposals_spec.rb @@ -38,7 +38,7 @@ feature 'Proposals' do within("ul.pagination") do expect(page).to have_content("1") - expect(page).to have_content("2") + expect(page).to have_link('2', href: 'http://www.example.com/proposals?page=2') expect(page).to_not have_content("3") click_link "Next", exact: false end From f4af87f8a1c7d0b3e15b9bede58288b583ebd408 Mon Sep 17 00:00:00 2001 From: Bertocq Date: Sat, 18 Nov 2017 10:44:30 +0100 Subject: [PATCH 27/69] Add kaminari url path helper function --- app/helpers/application_helper.rb | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index 369cabe84..4aecb615c 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -60,4 +60,8 @@ module ApplicationHelper def format_price(number) number_to_currency(number, precision: 0, locale: I18n.default_locale) end + + def kaminari_path(url) + "#{root_url}#{url.delete('/')}" + end end From b2e59272ccb5da7e2da036d0b13a8073180265ab Mon Sep 17 00:00:00 2001 From: Bertocq Date: Sat, 18 Nov 2017 10:44:52 +0100 Subject: [PATCH 28/69] Use kaminari url path helper on kaminari partials --- app/views/kaminari/_first_page.html.erb | 2 +- app/views/kaminari/_last_page.html.erb | 2 +- app/views/kaminari/_next_page.html.erb | 2 +- app/views/kaminari/_page.html.erb | 2 +- app/views/kaminari/_prev_page.html.erb | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/app/views/kaminari/_first_page.html.erb b/app/views/kaminari/_first_page.html.erb index b9802389d..e8afb0431 100644 --- a/app/views/kaminari/_first_page.html.erb +++ b/app/views/kaminari/_first_page.html.erb @@ -1,3 +1,3 @@
  • - <%= link_to t("views.pagination.first").html_safe, url, :remote => remote %> + <%= link_to t("views.pagination.first").html_safe, kaminari_path(url), :remote => remote %>
  • diff --git a/app/views/kaminari/_last_page.html.erb b/app/views/kaminari/_last_page.html.erb index 179f6e7fc..5a49bd7e2 100644 --- a/app/views/kaminari/_last_page.html.erb +++ b/app/views/kaminari/_last_page.html.erb @@ -1,3 +1,3 @@
  • - <%= link_to t("views.pagination.last").html_safe, url, :remote => remote %> + <%= link_to t("views.pagination.last").html_safe, kaminari_path(url), :remote => remote %>
  • diff --git a/app/views/kaminari/_next_page.html.erb b/app/views/kaminari/_next_page.html.erb index f305b1b7d..11c700900 100644 --- a/app/views/kaminari/_next_page.html.erb +++ b/app/views/kaminari/_next_page.html.erb @@ -1,3 +1,3 @@
  • - <%= link_to t("views.pagination.next").html_safe, url, :rel => "next", :remote => remote %> + <%= link_to t("views.pagination.next").html_safe, kaminari_path(url), :rel => "next", :remote => remote %>
  • diff --git a/app/views/kaminari/_page.html.erb b/app/views/kaminari/_page.html.erb index 12610dada..7b380fe4f 100644 --- a/app/views/kaminari/_page.html.erb +++ b/app/views/kaminari/_page.html.erb @@ -5,6 +5,6 @@ <% else %>
  • - <%= link_to page, url, {:remote => remote, :rel => page.next? ? "next" : page.prev? ? "prev" : nil} %> + <%= link_to page, kaminari_path(url), {:remote => remote, :rel => page.next? ? "next" : page.prev? ? "prev" : nil} %>
  • <% end %> diff --git a/app/views/kaminari/_prev_page.html.erb b/app/views/kaminari/_prev_page.html.erb index 902a8c89e..aba1d9369 100644 --- a/app/views/kaminari/_prev_page.html.erb +++ b/app/views/kaminari/_prev_page.html.erb @@ -1,3 +1,3 @@
  • - <%= link_to t("views.pagination.previous").html_safe, url, :rel => "prev", :remote => remote %> + <%= link_to t("views.pagination.previous").html_safe, kaminari_path(url), :rel => "prev", :remote => remote %>
  • From 886a3a0e2a89114230f3758a44454202d1e953b6 Mon Sep 17 00:00:00 2001 From: Bertocq Date: Sat, 18 Nov 2017 10:52:38 +0100 Subject: [PATCH 29/69] Add missing activerecord error messages in english & spanish --- config/locales/en/activerecord.yml | 7 ++++++- config/locales/es/activerecord.yml | 5 +++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/config/locales/en/activerecord.yml b/config/locales/en/activerecord.yml index bceaf5106..0e0c20dfd 100644 --- a/config/locales/en/activerecord.yml +++ b/config/locales/en/activerecord.yml @@ -281,4 +281,9 @@ en: attributes: image: image_width: "Width must be %{required_width}px" - image_height: "Height must be %{required_height}px" \ No newline at end of file + image_height: "Height must be %{required_height}px" + messages: + record_invalid: "Validation failed: %{errors}" + restrict_dependent_destroy: + has_one: "Cannot delete record because a dependent %{record} exists" + has_many: "Cannot delete record because dependent %{record} exist" \ No newline at end of file diff --git a/config/locales/es/activerecord.yml b/config/locales/es/activerecord.yml index d0d3294cd..b52f0bdb8 100644 --- a/config/locales/es/activerecord.yml +++ b/config/locales/es/activerecord.yml @@ -277,3 +277,8 @@ es: image: image_width: "Debe tener %{required_width}px de ancho" image_height: "Debe tener %{required_height}px de alto" + messages: + record_invalid: "La validación falló: %{errors}" + restrict_dependent_destroy: + has_one: No se puede eliminar el registro porque existe un %{record} dependiente + has_many: No se puede eliminar el registro porque existen %{record} dependientes \ No newline at end of file From b2c03192bb35aa45cabf22a6aa2f96633ce2e9c4 Mon Sep 17 00:00:00 2001 From: Bertocq Date: Sun, 19 Nov 2017 13:33:49 +0100 Subject: [PATCH 30/69] Fix kaminari path url helper function --- app/helpers/application_helper.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index 4aecb615c..3191a2ab9 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -62,6 +62,6 @@ module ApplicationHelper end def kaminari_path(url) - "#{root_url}#{url.delete('/')}" + "#{root_url.chomp("\/")}#{url}" end end From 21b2a11339bc2769d4155b9e3f36b9ca280719d1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juanjo=20Baza=CC=81n?= Date: Tue, 21 Nov 2017 14:31:03 +0100 Subject: [PATCH 31/69] adds poll comments to API --- app/models/comment.rb | 6 ++++-- app/models/poll.rb | 1 + spec/lib/graphql_spec.rb | 29 +++++++++++++++++++++++++++-- 3 files changed, 32 insertions(+), 4 deletions(-) diff --git a/app/models/comment.rb b/app/models/comment.rb index 8e3024d06..ccfc04602 100644 --- a/app/models/comment.rb +++ b/app/models/comment.rb @@ -30,9 +30,11 @@ class Comment < ActiveRecord::Base scope :sort_by_flags, -> { order(flags_count: :desc, updated_at: :desc) } scope :public_for_api, -> do where(%{(comments.commentable_type = 'Debate' and comments.commentable_id in (?)) or - (comments.commentable_type = 'Proposal' and comments.commentable_id in (?))}, + (comments.commentable_type = 'Proposal' and comments.commentable_id in (?)) or + (comments.commentable_type = 'Poll' and comments.commentable_id in (?))}, Debate.public_for_api.pluck(:id), - Proposal.public_for_api.pluck(:id)) + Proposal.public_for_api.pluck(:id), + Poll.public_for_api.pluck(:id)) end scope :sort_by_most_voted, -> { order(confidence_score: :desc, created_at: :desc) } diff --git a/app/models/poll.rb b/app/models/poll.rb index 27125d8a1..ffb4e36f4 100644 --- a/app/models/poll.rb +++ b/app/models/poll.rb @@ -28,6 +28,7 @@ class Poll < ActiveRecord::Base scope :recounting, -> { Poll.where(ends_at: (Date.current.beginning_of_day - RECOUNT_DURATION)..Date.current.beginning_of_day) } scope :published, -> { where('published = ?', true) } scope :by_geozone_id, ->(geozone_id) { where(geozones: {id: geozone_id}.joins(:geozones)) } + scope :public_for_api, -> { all } scope :sort_for_list, -> { order(:geozone_restricted, :starts_at, :name) } diff --git a/spec/lib/graphql_spec.rb b/spec/lib/graphql_spec.rb index d6ea071e2..4f03e0f6a 100644 --- a/spec/lib/graphql_spec.rb +++ b/spec/lib/graphql_spec.rb @@ -282,15 +282,16 @@ describe 'ConsulSchema' do end describe 'Comments' do - it 'only returns comments from proposals and debates' do + it 'only returns comments from proposals, debates and polls' do proposal_comment = create(:comment, commentable: create(:proposal)) debate_comment = create(:comment, commentable: create(:debate)) + poll_comment = create(:comment, commentable: create(:poll)) spending_proposal_comment = build(:comment, commentable: create(:spending_proposal)).save(skip_validation: true) response = execute('{ comments { edges { node { commentable_type } } } }') received_commentables = extract_fields(response, 'comments', 'commentable_type') - expect(received_commentables).to match_array ['Proposal', 'Debate'] + expect(received_commentables).to match_array ['Proposal', 'Debate', 'Poll'] end it 'displays comments of authors even if public activity is set to false' do @@ -355,6 +356,19 @@ describe 'ConsulSchema' do expect(received_comments).to match_array [visible_debate_comment.body] end + it 'does not include comments from hidden polls' do + visible_poll = create(:poll) + hidden_poll = create(:poll, hidden_at: Time.current) + + visible_poll_comment = create(:comment, commentable: visible_poll) + hidden_poll_comment = create(:comment, commentable: hidden_poll) + + response = execute('{ comments { edges { node { body } } } }') + received_comments = extract_fields(response, 'comments', 'body') + + expect(received_comments).to match_array [visible_poll_comment.body] + end + it 'does not include comments of debates that are not public' do not_public_debate = create(:debate, :hidden) not_public_debate_comment = create(:comment, commentable: not_public_debate) @@ -377,6 +391,17 @@ describe 'ConsulSchema' do expect(received_comments).to_not include(not_public_proposal_comment.body) end + it 'does not include comments of polls that are not public' do + not_public_poll = create(:poll) + not_public_poll_comment = create(:comment, commentable: not_public_poll) + allow(Comment).to receive(:public_for_api).and_return([]) + + response = execute('{ comments { edges { node { body } } } }') + received_comments = extract_fields(response, 'comments', 'body') + + expect(received_comments).to_not include(not_public_poll_comment.body) + end + it 'only returns date and hour for created_at' do created_at = Time.zone.parse("2017-12-31 9:30:15") create(:comment, created_at: created_at) From 69625b7d34851085a9ad300fdc0c404404082386 Mon Sep 17 00:00:00 2001 From: decabeza Date: Fri, 24 Nov 2017 10:58:16 +0100 Subject: [PATCH 32/69] fixes url images on social meta tags partial --- app/views/shared/_social_media_meta_tags.html.erb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/views/shared/_social_media_meta_tags.html.erb b/app/views/shared/_social_media_meta_tags.html.erb index 8c1196c96..d4d8a42b8 100644 --- a/app/views/shared/_social_media_meta_tags.html.erb +++ b/app/views/shared/_social_media_meta_tags.html.erb @@ -3,7 +3,7 @@ - + <% if setting['url'] %> @@ -14,7 +14,7 @@ <% end %> - + From 510d4822a407653b30b58a2b2e6265df8331dd25 Mon Sep 17 00:00:00 2001 From: decabeza Date: Fri, 24 Nov 2017 14:12:01 +0100 Subject: [PATCH 33/69] adds new setting for site title meta tag --- config/locales/en/settings.yml | 1 + config/locales/es/settings.yml | 1 + db/dev_seeds.rb | 1 + db/seeds.rb | 1 + 4 files changed, 4 insertions(+) diff --git a/config/locales/en/settings.yml b/config/locales/en/settings.yml index 0d5862408..2295660ac 100644 --- a/config/locales/en/settings.yml +++ b/config/locales/en/settings.yml @@ -48,6 +48,7 @@ en: map_zoom: Zoom mailer_from_name: Origin email name mailer_from_address: Origin email address + meta_title: "Site title (SEO)" meta_description: "Site description (SEO)" meta_keywords: "Keywords (SEO)" verification_offices_url: Verification offices URL diff --git a/config/locales/es/settings.yml b/config/locales/es/settings.yml index fcf2eb1db..ae31d0a4a 100644 --- a/config/locales/es/settings.yml +++ b/config/locales/es/settings.yml @@ -48,6 +48,7 @@ es: map_zoom: Zoom mailer_from_name: Nombre email remitente mailer_from_address: Dirección email remitente + meta_title: "Título del sitio (SEO)" meta_description: "Descripción del sitio (SEO)" meta_keywords: "Palabras clave (SEO)" verification_offices_url: URL oficinas verificación diff --git a/db/dev_seeds.rb b/db/dev_seeds.rb index 60493e0a5..f24efa4da 100644 --- a/db/dev_seeds.rb +++ b/db/dev_seeds.rb @@ -55,6 +55,7 @@ section "Creating Settings" do Setting.create(key: 'comments_body_max_length', value: '1000') Setting.create(key: 'mailer_from_name', value: 'CONSUL') Setting.create(key: 'mailer_from_address', value: 'noreply@consul.dev') + Setting.create(key: 'meta_title', value: 'CONSUL') Setting.create(key: 'meta_description', value: 'Citizen Participation and Open Government Application') Setting.create(key: 'meta_keywords', value: 'citizen participation, open government') Setting.create(key: 'verification_offices_url', value: 'http://oficinas-atencion-ciudadano.url/') diff --git a/db/seeds.rb b/db/seeds.rb index fcfa6340c..0e49983a5 100644 --- a/db/seeds.rb +++ b/db/seeds.rb @@ -65,6 +65,7 @@ Setting["org_name"] = "CONSUL" Setting["place_name"] = "CONSUL-land" # Meta tags for SEO +Setting["meta_title"] = nil Setting["meta_description"] = nil Setting["meta_keywords"] = nil From 7fcbd99311f38786d083623ea747cdcea33a73c1 Mon Sep 17 00:00:00 2001 From: decabeza Date: Fri, 24 Nov 2017 14:13:19 +0100 Subject: [PATCH 34/69] adds social media meta tags to welcome index page --- app/views/welcome/index.html.erb | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/app/views/welcome/index.html.erb b/app/views/welcome/index.html.erb index e27f4436e..de64d9cd8 100644 --- a/app/views/welcome/index.html.erb +++ b/app/views/welcome/index.html.erb @@ -4,6 +4,11 @@ <%= render "shared/canonical", href: root_url %> <% end %> +<% provide :social_media_meta_tags do %> + <%= render "shared/social_media_meta_tags", + social_url: root_url %> +<% end %> +
    From ccbd99f88bf8dfc58988078cd0ee44ee3d40cc3d Mon Sep 17 00:00:00 2001 From: decabeza Date: Fri, 24 Nov 2017 14:13:45 +0100 Subject: [PATCH 35/69] improves social media meta tags partial with settings --- app/views/shared/_social_media_meta_tags.html.erb | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/app/views/shared/_social_media_meta_tags.html.erb b/app/views/shared/_social_media_meta_tags.html.erb index d4d8a42b8..8782aad17 100644 --- a/app/views/shared/_social_media_meta_tags.html.erb +++ b/app/views/shared/_social_media_meta_tags.html.erb @@ -1,11 +1,11 @@ - - + + - + <% if setting['url'] %> /> <% end %> @@ -16,5 +16,5 @@ - + From 80d99b71a990a4ae420d6098cc56801917624a03 Mon Sep 17 00:00:00 2001 From: decabeza Date: Fri, 24 Nov 2017 14:14:41 +0100 Subject: [PATCH 36/69] adds specs --- spec/features/social_media_meta_tags_spec.rb | 31 ++++++++++++++++++++ 1 file changed, 31 insertions(+) create mode 100644 spec/features/social_media_meta_tags_spec.rb diff --git a/spec/features/social_media_meta_tags_spec.rb b/spec/features/social_media_meta_tags_spec.rb new file mode 100644 index 000000000..6cc8ee41a --- /dev/null +++ b/spec/features/social_media_meta_tags_spec.rb @@ -0,0 +1,31 @@ +require 'rails_helper' + +feature 'Social media meta tags' do + + context 'Setting social media meta tags' do + + before do + Setting['meta_keywords'] = "citizen, participation, open government" + Setting['meta_title'] = "CONSUL" + Setting['meta_description'] = "Citizen Participation and Open Government Application" + end + + after do + Setting['meta_keywords'] = nil + Setting['meta_title'] = nil + Setting['meta_description'] = nil + end + + scenario 'Social media meta tags partial render settings content' do + + visit root_path + + expect(page).to have_css 'meta[name="keywords"][content="citizen, participation, open government"]', visible: false + expect(page).to have_css 'meta[name="twitter:title"][content="CONSUL"]', visible: false + expect(page).to have_css 'meta[name="twitter:title"][content="CONSUL"]', visible: false + expect(page).to have_css 'meta[property="og:title"][content="CONSUL"]', visible: false + expect(page).to have_css 'meta[property="og:description"][content="Citizen Participation and Open Government Application"]', visible: false + end + end + +end From fe987dd7e9d9a9713b05c362b6ffc7e0abbee909 Mon Sep 17 00:00:00 2001 From: decabeza Date: Fri, 24 Nov 2017 14:29:40 +0100 Subject: [PATCH 37/69] =?UTF-8?q?removes=20unnecessary=20blank=20spaces=20?= =?UTF-8?q?=F0=9F=99=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/views/shared/_social_media_meta_tags.html.erb | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/app/views/shared/_social_media_meta_tags.html.erb b/app/views/shared/_social_media_meta_tags.html.erb index 8782aad17..2b08ca61e 100644 --- a/app/views/shared/_social_media_meta_tags.html.erb +++ b/app/views/shared/_social_media_meta_tags.html.erb @@ -1,9 +1,9 @@ - - - - - + + + + + <% if setting['url'] %> From 1534e6fc421766ede68a34dffad9de4e97afaaf5 Mon Sep 17 00:00:00 2001 From: decabeza Date: Fri, 24 Nov 2017 21:36:38 +0100 Subject: [PATCH 38/69] unifies social media meta tags specs --- spec/features/proposals_spec.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/spec/features/proposals_spec.rb b/spec/features/proposals_spec.rb index 28049644b..192e7949f 100644 --- a/spec/features/proposals_spec.rb +++ b/spec/features/proposals_spec.rb @@ -153,8 +153,8 @@ feature 'Proposals' do proposal = create(:proposal) visit proposal_path(proposal) - expect(page.html).to include "" - expect(page.html).to include "" + expect(page).to have_css "meta[name='twitter:title'][content=\"#{proposal.title}\"]", visible: false + expect(page).to have_css "meta[property='og:title'][content=\"#{proposal.title}\"]", visible: false end scenario 'Create' do From 8bef6d81c82bffef8a6c57c39947a90a40f8e02a Mon Sep 17 00:00:00 2001 From: Bertocq Date: Mon, 27 Nov 2017 13:23:47 +0100 Subject: [PATCH 39/69] Fix value for metatag, and use twitter_handle settings value --- app/views/shared/_social_media_meta_tags.html.erb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/views/shared/_social_media_meta_tags.html.erb b/app/views/shared/_social_media_meta_tags.html.erb index 2b08ca61e..a72ab250e 100644 --- a/app/views/shared/_social_media_meta_tags.html.erb +++ b/app/views/shared/_social_media_meta_tags.html.erb @@ -1,13 +1,13 @@ - + <% if setting['url'] %> - /> + <% end %> <% if setting['facebook_handle'] %> From 33f47e7a63ec8b975015449f209ce4d39ff1d0fd Mon Sep 17 00:00:00 2001 From: Bertocq Date: Mon, 27 Nov 2017 13:24:07 +0100 Subject: [PATCH 40/69] Increase social media meta tags spec --- spec/features/social_media_meta_tags_spec.rb | 39 ++++++++++++++++---- 1 file changed, 31 insertions(+), 8 deletions(-) diff --git a/spec/features/social_media_meta_tags_spec.rb b/spec/features/social_media_meta_tags_spec.rb index 6cc8ee41a..d04df78f6 100644 --- a/spec/features/social_media_meta_tags_spec.rb +++ b/spec/features/social_media_meta_tags_spec.rb @@ -4,27 +4,50 @@ feature 'Social media meta tags' do context 'Setting social media meta tags' do + let(:meta_keywords) { 'citizen, participation, open government' } + let(:meta_title) { 'CONSUL TEST' } + let(:meta_description) { 'Citizen Participation and Open Government Application' } + let(:twitter_handle) { '@consul_test' } + let(:url) { 'http://consul.dev' } + let(:facebook_handle) { 'consultest' } + let(:org_name) { 'CONSUL TEST' } + before do - Setting['meta_keywords'] = "citizen, participation, open government" - Setting['meta_title'] = "CONSUL" - Setting['meta_description'] = "Citizen Participation and Open Government Application" + Setting['meta_keywords'] = meta_keywords + Setting['meta_title'] = meta_title + Setting['meta_description'] = meta_description + Setting['twitter_handle'] = twitter_handle + Setting['url'] = url + Setting['facebook_handle'] = facebook_handle + Setting['org_name'] = org_name end after do Setting['meta_keywords'] = nil Setting['meta_title'] = nil Setting['meta_description'] = nil + Setting['twitter_handle'] = nil + Setting['url'] = 'http://example.com' + Setting['facebook_handle'] = nil + Setting['org_name'] = 'CONSUL' end scenario 'Social media meta tags partial render settings content' do visit root_path - expect(page).to have_css 'meta[name="keywords"][content="citizen, participation, open government"]', visible: false - expect(page).to have_css 'meta[name="twitter:title"][content="CONSUL"]', visible: false - expect(page).to have_css 'meta[name="twitter:title"][content="CONSUL"]', visible: false - expect(page).to have_css 'meta[property="og:title"][content="CONSUL"]', visible: false - expect(page).to have_css 'meta[property="og:description"][content="Citizen Participation and Open Government Application"]', visible: false + expect(page).to have_css 'meta[name="keywords"][content="'+ meta_keywords + '"]', visible: false + expect(page).to have_css 'meta[name="twitter:site"][content="'+ twitter_handle + '"]', visible: false + expect(page).to have_css 'meta[name="twitter:title"][content="'+ meta_title + '"]', visible: false + expect(page).to have_css 'meta[name="twitter:description"][content="' + meta_description + '"]', visible: false + expect(page).to have_css 'meta[name="twitter:image"][content="http://www.example.com/social_media_icon_twitter.png"]', visible: false + expect(page).to have_css 'meta[property="og:title"][content="'+ meta_title + '"]', visible: false + expect(page).to have_css 'meta[property="article:publisher"][content="' + url + '"]', visible: false + expect(page).to have_css 'meta[property="article:author"][content="https://www.facebook.com/' + facebook_handle + '"]', visible: false + expect(page).to have_css 'meta[property="og:url"][content="http://www.example.com/"]', visible: false + expect(page).to have_css 'meta[property="og:image"][content="http://www.example.com/social_media_icon.png"]', visible: false + expect(page).to have_css 'meta[property="og:site_name"][content="' + org_name + '"]', visible: false + expect(page).to have_css 'meta[property="og:description"][content="' + meta_description + '"]', visible: false end end From 20ae7cd6cbaa589a0c9631e7b159dcc0683e4c7d Mon Sep 17 00:00:00 2001 From: Bertocq Date: Mon, 27 Nov 2017 15:58:38 +0100 Subject: [PATCH 41/69] Improve changelog using keepachangelog format --- CHANGELOG.md | 77 ++++++++++++++++++++++++++++++---------------------- 1 file changed, 44 insertions(+), 33 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a487eadb4..ab46ca827 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,38 +1,49 @@ -### 0.9 - 2017-06-15 +# Changelog +All notable changes to this project will be documented in this file. -* New features - * Budgets - * Basic polls - * Collaborative legistlation - * Custom pages - * GraphQL API - * Improved admin section -* Enhancements - * Improved admin section - * Rails 4.2.8 - * Ruby 2.3.2 -* Bug fixes - * CKEditor locale compilation fixed - * Fixed bugs in mobile layouts -* Deprecations - * SpendingProposals are deprecated now in favor of Budgets +The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) +and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html). -### 0.8 - 2016-07-21 +## [Unreleased] -* New features - * Support for customization schema, vía specific custom files, assets and folders -* Enhancements - * Rails 2.4.7 - * Ruby 2.3.1 -* Bug fixes - * Fixed bug causing errors on user deletion +## [0.9.0] - 2017-06-15 +### Added +- Budgets +- Basic polls +- Collaborative legistlation +- Custom pages +- GraphQL API +- Improved admin section -### 0.7 - 2016-04-25 +### Changed +- Improved admin section +- Rails 4.2.8 +- Ruby 2.3.2 -* New features - * Debates - * Proposals - * Basic Spending Proposals -* Enhancements - * Rails 2.4.6 - * Ruby 2.2.3 \ No newline at end of file +### Deprecated +- SpendingProposals are deprecated now in favor of Budgets + +### Fixed +- CKEditor locale compilation fixed +- Fixed bugs in mobile layouts + +## [0.8.0] - 2016-07-21 +### Added +- Support for customization schema, vía specific custom files, assets and folders + +### Changed +- Rails 4.2.7 +- Ruby 2.3.1 + +### Fixed +- Fixed bug causing errors on user deletion + +## [0.7.0] - 2016-04-25 +### Added +- Debates +- Proposals +- Basic Spending Proposals + +### Changed +- Rails 4.2.6 +- Ruby 2.2.3 From 897f7da774d9c3fdc10436675a8c0d2606afd978 Mon Sep 17 00:00:00 2001 From: Bertocq Date: Mon, 27 Nov 2017 16:00:20 +0100 Subject: [PATCH 42/69] Add missing 0.10.0 release to Changelog --- CHANGELOG.md | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index ab46ca827..a08a46902 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,17 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. ## [Unreleased] +## [0.10.0] - 2017-07-05 +### Added +- Milestones on Budget Investment's +- Feature flag to enable/disable Legislative Processes +- Locale site pages customization +- Incompatible investments + +### Changed +- Localization files reorganization. Check migration instruction at https://github.com/consul/consul/releases/tag/v0.10 +- Rails 4.2.9 + ## [0.9.0] - 2017-06-15 ### Added - Budgets From 7a2fc7fbff2cfdf2331aa515d6d49d1ca220abad Mon Sep 17 00:00:00 2001 From: Bertocq Date: Mon, 27 Nov 2017 16:22:14 +0100 Subject: [PATCH 43/69] Add links to version diffs on changelog --- CHANGELOG.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a08a46902..d0e57f93f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,9 +4,9 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html). -## [Unreleased] +## [Unreleased](https://github.com/consul/consul/compare/v0.10...consul:master) -## [0.10.0] - 2017-07-05 +## [0.10.0](https://github.com/consul/consul/compare/v0.9...v0.10) - 2017-07-05 ### Added - Milestones on Budget Investment's - Feature flag to enable/disable Legislative Processes @@ -17,7 +17,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. - Localization files reorganization. Check migration instruction at https://github.com/consul/consul/releases/tag/v0.10 - Rails 4.2.9 -## [0.9.0] - 2017-06-15 +## [0.9.0](https://github.com/consul/consul/compare/v0.8...v0.9) - 2017-06-15 ### Added - Budgets - Basic polls @@ -38,7 +38,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. - CKEditor locale compilation fixed - Fixed bugs in mobile layouts -## [0.8.0] - 2016-07-21 +## [0.8.0](https://github.com/consul/consul/compare/v0.7...v0.8)- 2016-07-21 ### Added - Support for customization schema, vía specific custom files, assets and folders From a7df59985b8d75abaf3db1e7acf4e51af43f51f1 Mon Sep 17 00:00:00 2001 From: rgarcia Date: Tue, 28 Nov 2017 21:07:48 +0100 Subject: [PATCH 44/69] Updates spanish translation for polls --- config/locales/es/admin.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/locales/es/admin.yml b/config/locales/es/admin.yml index 067684df9..ba5ab5515 100644 --- a/config/locales/es/admin.yml +++ b/config/locales/es/admin.yml @@ -557,7 +557,7 @@ es: unassigned: No asignada actions: assign: Asignar urna - unassign: Asignar urna + unassign: Desasignar urna poll_booth_assignments: alert: shifts: "Hay turnos asignados para esta urna. Si la desasignas, esos turnos se eliminarán. ¿Deseas continuar?" From c5fa85e3f6d55b993dda8482d2aa3d785e155dcf Mon Sep 17 00:00:00 2001 From: Bertocq Date: Tue, 28 Nov 2017 22:32:30 +0100 Subject: [PATCH 45/69] Prevent a division by zero from happening on sort by random investment scope --- app/controllers/budgets/investments_controller.rb | 2 +- app/models/budget/investment.rb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/controllers/budgets/investments_controller.rb b/app/controllers/budgets/investments_controller.rb index aaf65765f..435fae04c 100644 --- a/app/controllers/budgets/investments_controller.rb +++ b/app/controllers/budgets/investments_controller.rb @@ -94,7 +94,7 @@ module Budgets def set_random_seed if params[:order] == 'random' || params[:order].blank? - seed = rand(10..99) / 10.0 + seed = rand(11..99) / 10.0 params[:random_seed] ||= Float(seed) rescue 0 else params[:random_seed] = nil diff --git a/app/models/budget/investment.rb b/app/models/budget/investment.rb index add7c3587..bd3e5b466 100644 --- a/app/models/budget/investment.rb +++ b/app/models/budget/investment.rb @@ -43,7 +43,7 @@ class Budget scope :sort_by_confidence_score, -> { reorder(confidence_score: :desc, id: :desc) } scope :sort_by_ballots, -> { reorder(ballot_lines_count: :desc, id: :desc) } scope :sort_by_price, -> { reorder(price: :desc, confidence_score: :desc, id: :desc) } - scope :sort_by_random, ->(seed) { reorder("budget_investments.id % #{seed || 1}, budget_investments.id") } + scope :sort_by_random, ->(seed) { reorder("budget_investments.id % #{seed.to_f&.positive? ? seed : 1}, budget_investments.id") } scope :valuation_open, -> { where(valuation_finished: false) } scope :without_admin, -> { valuation_open.where(administrator_id: nil) } From a138cda364f1b3ed75cdbc97bda46da30a99fadf Mon Sep 17 00:00:00 2001 From: Bertocq Date: Mon, 27 Nov 2017 18:35:41 +0100 Subject: [PATCH 46/69] Create RelatedContent model --- app/models/related_content.rb | 11 +++++++++++ .../20171127171925_create_related_content.rb | 12 ++++++++++++ db/schema.rb | 17 ++++++++++++++++- spec/factories.rb | 3 +++ 4 files changed, 42 insertions(+), 1 deletion(-) create mode 100644 app/models/related_content.rb create mode 100644 db/migrate/20171127171925_create_related_content.rb diff --git a/app/models/related_content.rb b/app/models/related_content.rb new file mode 100644 index 000000000..4a6645f3a --- /dev/null +++ b/app/models/related_content.rb @@ -0,0 +1,11 @@ +class RelatedContent < ActiveRecord::Base + belongs_to :parent_relationable, polymorphic: true + belongs_to :child_relationable, polymorphic: true + + validates :parent_relationable_id, presence: true + validates :parent_relationable_type, presence: true + validates :child_relationable_id, presence: true + validates :child_relationable_type, presence: true + validates :parent_relationable_id, uniqueness: { scope: [:parent_relationable_type, :child_relationable_id, :child_relationable_type] } + +end diff --git a/db/migrate/20171127171925_create_related_content.rb b/db/migrate/20171127171925_create_related_content.rb new file mode 100644 index 000000000..2944938e2 --- /dev/null +++ b/db/migrate/20171127171925_create_related_content.rb @@ -0,0 +1,12 @@ +class CreateRelatedContent < ActiveRecord::Migration + def change + create_table :related_contents do |t| + t.references :parent_relationable, polymorphic: true, index: { name: 'index_related_contents_on_parent_relationable' } + t.references :child_relationable, polymorphic: true, index: { name: 'index_related_contents_on_child_relationable' } + t.references :related_content, index: { name: 'opposite_related_content' } + t.timestamps + end + + add_index :related_contents, [:parent_relationable_id, :parent_relationable_type, :child_relationable_id, :child_relationable_type], name: "unique_parent_child_related_content", unique: true, using: :btree + end +end diff --git a/db/schema.rb b/db/schema.rb index f2dd62428..44bcdf56b 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: 20171115164152) do +ActiveRecord::Schema.define(version: 20171127171925) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -851,6 +851,21 @@ ActiveRecord::Schema.define(version: 20171115164152) do add_index "proposals", ["title"], name: "index_proposals_on_title", using: :btree add_index "proposals", ["tsv"], name: "index_proposals_on_tsv", using: :gin + create_table "related_contents", force: :cascade do |t| + t.integer "parent_relationable_id" + t.string "parent_relationable_type" + t.integer "child_relationable_id" + t.string "child_relationable_type" + t.integer "related_content_id" + t.datetime "created_at" + t.datetime "updated_at" + end + + add_index "related_contents", ["child_relationable_type", "child_relationable_id"], name: "index_related_contents_on_child_relationable", using: :btree + add_index "related_contents", ["parent_relationable_id", "parent_relationable_type", "child_relationable_id", "child_relationable_type"], name: "unique_parent_child_related_content", unique: true, using: :btree + add_index "related_contents", ["parent_relationable_type", "parent_relationable_id"], name: "index_related_contents_on_parent_relationable", using: :btree + add_index "related_contents", ["related_content_id"], name: "opposite_related_content", using: :btree + create_table "settings", force: :cascade do |t| t.string "key" t.string "value" diff --git a/spec/factories.rb b/spec/factories.rb index b98fc7adb..1ac2f3ebd 100644 --- a/spec/factories.rb +++ b/spec/factories.rb @@ -882,4 +882,7 @@ LOREM_IPSUM end end + factory :related_content do + end + end From f0dca7147b7ee8ba0f2ae3f3825ef77b82e48eb5 Mon Sep 17 00:00:00 2001 From: Bertocq Date: Mon, 27 Nov 2017 18:36:55 +0100 Subject: [PATCH 47/69] Add basic RelatedContent model spec to check multiple models can be related --- spec/models/relation_spec.rb | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 spec/models/relation_spec.rb diff --git a/spec/models/relation_spec.rb b/spec/models/relation_spec.rb new file mode 100644 index 000000000..9e75516ce --- /dev/null +++ b/spec/models/relation_spec.rb @@ -0,0 +1,26 @@ +require 'rails_helper' + +describe RelatedContent do + + let(:parent_relationable) { create([:proposal, :debate, :budget_investment].sample) } + let(:child_relationable) { create([:proposal, :debate, :budget_investment].sample) } + + it "should allow relationables from various classes" do + expect(build(:related_content, parent_relationable: parent_relationable, child_relationable: child_relationable)).to be_valid + expect(build(:related_content, parent_relationable: parent_relationable, child_relationable: child_relationable)).to be_valid + expect(build(:related_content, parent_relationable: parent_relationable, child_relationable: child_relationable)).to be_valid + end + + it "should not allow empty relationables" do + expect(build(:related_content)).not_to be_valid + expect(build(:related_content, parent_relationable: parent_relationable)).not_to be_valid + expect(build(:related_content, child_relationable: child_relationable)).not_to be_valid + end + + it "should not allow repeated related contents" do + related_content = create(:related_content, parent_relationable: parent_relationable, child_relationable: child_relationable) + new_related_content = build(:related_content, parent_relationable: related_content.parent_relationable, child_relationable: related_content.child_relationable) + expect(new_related_content).not_to be_valid + end + +end From 8f3769aa7d08da52c0b44070c953d1fec0561ab5 Mon Sep 17 00:00:00 2001 From: Bertocq Date: Mon, 27 Nov 2017 18:37:27 +0100 Subject: [PATCH 48/69] Create Relationable concern --- app/models/concerns/relationable.rb | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 app/models/concerns/relationable.rb diff --git a/app/models/concerns/relationable.rb b/app/models/concerns/relationable.rb new file mode 100644 index 000000000..f4da34ed5 --- /dev/null +++ b/app/models/concerns/relationable.rb @@ -0,0 +1,7 @@ +module Relationable + extend ActiveSupport::Concern + + included do + has_many :related_contents, as: :parent_relationable + end +end From 13f5fa55ab304abf63613ea2293f0a750f2e2480 Mon Sep 17 00:00:00 2001 From: Bertocq Date: Mon, 27 Nov 2017 18:37:40 +0100 Subject: [PATCH 49/69] Use Relationable concern on Debates, Proposals and Budget Investments --- app/models/budget/investment.rb | 1 + app/models/debate.rb | 1 + app/models/proposal.rb | 1 + 3 files changed, 3 insertions(+) diff --git a/app/models/budget/investment.rb b/app/models/budget/investment.rb index bd3e5b466..173a7fd36 100644 --- a/app/models/budget/investment.rb +++ b/app/models/budget/investment.rb @@ -17,6 +17,7 @@ class Budget acts_as_votable acts_as_paranoid column: :hidden_at include ActsAsParanoidAliases + include Relationable belongs_to :author, -> { with_hidden }, class_name: 'User', foreign_key: 'author_id' belongs_to :heading diff --git a/app/models/debate.rb b/app/models/debate.rb index 65c06345d..e949e8092 100644 --- a/app/models/debate.rb +++ b/app/models/debate.rb @@ -9,6 +9,7 @@ class Debate < ActiveRecord::Base include Filterable include HasPublicAuthor include Graphqlable + include Relationable acts_as_votable acts_as_paranoid column: :hidden_at diff --git a/app/models/proposal.rb b/app/models/proposal.rb index 3b0696d26..aaf5bea87 100644 --- a/app/models/proposal.rb +++ b/app/models/proposal.rb @@ -17,6 +17,7 @@ class Proposal < ActiveRecord::Base max_file_size: 3.megabytes, accepted_content_types: [ "application/pdf" ] include EmbedVideosHelper + include Relationable acts_as_votable acts_as_paranoid column: :hidden_at From 03f0534b2f13c3348348ce1e79e8790e995a935d Mon Sep 17 00:00:00 2001 From: Bertocq Date: Mon, 27 Nov 2017 19:13:07 +0100 Subject: [PATCH 50/69] Add scenario to RelatedContent model spec to check opposite related content creation --- app/models/related_content.rb | 10 ++++++++++ spec/models/relation_spec.rb | 15 +++++++++++++++ 2 files changed, 25 insertions(+) diff --git a/app/models/related_content.rb b/app/models/related_content.rb index 4a6645f3a..6b85d14db 100644 --- a/app/models/related_content.rb +++ b/app/models/related_content.rb @@ -1,6 +1,7 @@ class RelatedContent < ActiveRecord::Base belongs_to :parent_relationable, polymorphic: true belongs_to :child_relationable, polymorphic: true + has_one :opposite_related_content, class_name: 'RelatedContent', foreign_key: :related_content_id validates :parent_relationable_id, presence: true validates :parent_relationable_type, presence: true @@ -8,4 +9,13 @@ class RelatedContent < ActiveRecord::Base validates :child_relationable_type, presence: true validates :parent_relationable_id, uniqueness: { scope: [:parent_relationable_type, :child_relationable_id, :child_relationable_type] } + after_create :create_opposite_related_content, unless: proc { opposite_related_content.present? } + + private + + def create_opposite_related_content + related_content = RelatedContent.create!(opposite_related_content: self, parent_relationable: child_relationable, child_relationable: parent_relationable) + self.opposite_related_content = related_content + end + end diff --git a/spec/models/relation_spec.rb b/spec/models/relation_spec.rb index 9e75516ce..1d4bcd91d 100644 --- a/spec/models/relation_spec.rb +++ b/spec/models/relation_spec.rb @@ -23,4 +23,19 @@ describe RelatedContent do expect(new_related_content).not_to be_valid end + describe 'create_opposite_related_content' do + let(:parent_relationable) { create(:proposal) } + let(:child_relationable) { create(:debate) } + let(:related_content) { build(:related_content, parent_relationable: parent_relationable, child_relationable: child_relationable) } + + it 'creates an opposite related_content' do + expect { related_content.save }.to change { RelatedContent.count }.by(2) + expect(related_content.opposite_related_content.child_relationable_id).to eq(parent_relationable.id) + expect(related_content.opposite_related_content.child_relationable_type).to eq(parent_relationable.class.name) + expect(related_content.opposite_related_content.parent_relationable_id).to eq(child_relationable.id) + expect(related_content.opposite_related_content.parent_relationable_type).to eq(child_relationable.class.name) + expect(related_content.opposite_related_content.opposite_related_content.id).to eq(related_content.id) + end + end + end From 04dfc98c3f9393150af9329b83bd4bcc6df4a55d Mon Sep 17 00:00:00 2001 From: Bertocq Date: Mon, 27 Nov 2017 23:42:35 +0100 Subject: [PATCH 51/69] Create RelatedContent model spec to check relationable destroy --- app/models/concerns/relationable.rb | 2 +- app/models/related_content.rb | 4 ++++ spec/models/relation_spec.rb | 10 ++++++++++ 3 files changed, 15 insertions(+), 1 deletion(-) diff --git a/app/models/concerns/relationable.rb b/app/models/concerns/relationable.rb index f4da34ed5..84a945bad 100644 --- a/app/models/concerns/relationable.rb +++ b/app/models/concerns/relationable.rb @@ -2,6 +2,6 @@ module Relationable extend ActiveSupport::Concern included do - has_many :related_contents, as: :parent_relationable + has_many :related_contents, as: :parent_relationable, dependent: :destroy end end diff --git a/app/models/related_content.rb b/app/models/related_content.rb index 6b85d14db..0837cff32 100644 --- a/app/models/related_content.rb +++ b/app/models/related_content.rb @@ -10,6 +10,7 @@ class RelatedContent < ActiveRecord::Base validates :parent_relationable_id, uniqueness: { scope: [:parent_relationable_type, :child_relationable_id, :child_relationable_type] } after_create :create_opposite_related_content, unless: proc { opposite_related_content.present? } + after_destroy :destroy_opposite_related_content, if: proc { opposite_related_content.present? } private @@ -18,4 +19,7 @@ class RelatedContent < ActiveRecord::Base self.opposite_related_content = related_content end + def destroy_opposite_related_content + opposite_related_content.destroy + end end diff --git a/spec/models/relation_spec.rb b/spec/models/relation_spec.rb index 1d4bcd91d..ebefa51fa 100644 --- a/spec/models/relation_spec.rb +++ b/spec/models/relation_spec.rb @@ -38,4 +38,14 @@ describe RelatedContent do end end + describe 'relationable destroy' do + let(:parent_relationable) { create(:proposal) } + let(:child_relationable) { create(:debate) } + + it 'destroys both related contents involved' do + related_content = create(:related_content, parent_relationable: parent_relationable, child_relationable: child_relationable) + expect { related_content.parent_relationable.destroy }.to change { RelatedContent.all.count }.by(-2) + expect(child_relationable.related_contents).to be_empty + end + end end From e02f511b3a69f3c53e2d206e22e433b40cdf649a Mon Sep 17 00:00:00 2001 From: Bertocq Date: Tue, 28 Nov 2017 01:29:02 +0100 Subject: [PATCH 52/69] Add times_reported integer attribute to RelatedContent --- app/models/related_content.rb | 8 ++++++++ db/dev_seeds.rb | 1 + ...20171127230716_add_time_reported_to_related_content.rb | 5 +++++ db/schema.rb | 3 ++- db/seeds.rb | 3 +++ 5 files changed, 19 insertions(+), 1 deletion(-) create mode 100644 db/migrate/20171127230716_add_time_reported_to_related_content.rb diff --git a/app/models/related_content.rb b/app/models/related_content.rb index 0837cff32..ab72aefe3 100644 --- a/app/models/related_content.rb +++ b/app/models/related_content.rb @@ -1,4 +1,6 @@ class RelatedContent < ActiveRecord::Base + RELATED_CONTENTS_REPORT_THRESHOLD = Setting['related_contents_report_threshold'].to_i + belongs_to :parent_relationable, polymorphic: true belongs_to :child_relationable, polymorphic: true has_one :opposite_related_content, class_name: 'RelatedContent', foreign_key: :related_content_id @@ -12,6 +14,12 @@ class RelatedContent < ActiveRecord::Base after_create :create_opposite_related_content, unless: proc { opposite_related_content.present? } after_destroy :destroy_opposite_related_content, if: proc { opposite_related_content.present? } + scope :not_hidden, -> { where('times_reported <= ?', RELATED_CONTENTS_REPORT_THRESHOLD) } + + def hidden_by_reports? + times_reported > RELATED_CONTENTS_REPORT_THRESHOLD + end + private def create_opposite_related_content diff --git a/db/dev_seeds.rb b/db/dev_seeds.rb index f24efa4da..c2a72e2ed 100644 --- a/db/dev_seeds.rb +++ b/db/dev_seeds.rb @@ -64,6 +64,7 @@ section "Creating Settings" do Setting.create(key: 'map_latitude', value: 51.48) Setting.create(key: 'map_longitude', value: 0.0) Setting.create(key: 'map_zoom', value: 10) + Setting.create(key: 'related_contents_report_threshold', value: 2) end section "Creating Geozones" do diff --git a/db/migrate/20171127230716_add_time_reported_to_related_content.rb b/db/migrate/20171127230716_add_time_reported_to_related_content.rb new file mode 100644 index 000000000..5cca12cf3 --- /dev/null +++ b/db/migrate/20171127230716_add_time_reported_to_related_content.rb @@ -0,0 +1,5 @@ +class AddTimeReportedToRelatedContent < ActiveRecord::Migration + def change + add_column :related_contents, :times_reported, :integer, default: 0 + end +end diff --git a/db/schema.rb b/db/schema.rb index 44bcdf56b..4d426cf9e 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: 20171127171925) do +ActiveRecord::Schema.define(version: 20171127230716) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -859,6 +859,7 @@ ActiveRecord::Schema.define(version: 20171127171925) do t.integer "related_content_id" t.datetime "created_at" t.datetime "updated_at" + t.integer "times_reported", default: 0 end add_index "related_contents", ["child_relationable_type", "child_relationable_id"], name: "index_related_contents_on_child_relationable", using: :btree diff --git a/db/seeds.rb b/db/seeds.rb index 0e49983a5..6ef55067c 100644 --- a/db/seeds.rb +++ b/db/seeds.rb @@ -116,3 +116,6 @@ Setting['proposal_improvement_path'] = nil Setting['map_latitude'] = 51.48 Setting['map_longitude'] = 0.0 Setting['map_zoom'] = 10 + +# Related content +Setting['related_contents_report_threshold'] = 5 From 0482eb4098ba9c794bf309a2212aed8143c84e0d Mon Sep 17 00:00:00 2001 From: Bertocq Date: Tue, 28 Nov 2017 01:46:00 +0100 Subject: [PATCH 53/69] Add report_related_content helper funcion on Relationable concern with spec --- app/models/concerns/relationable.rb | 8 ++++++++ spec/models/relation_spec.rb | 12 ++++++++++++ 2 files changed, 20 insertions(+) diff --git a/app/models/concerns/relationable.rb b/app/models/concerns/relationable.rb index 84a945bad..4f4edcd32 100644 --- a/app/models/concerns/relationable.rb +++ b/app/models/concerns/relationable.rb @@ -4,4 +4,12 @@ module Relationable included do has_many :related_contents, as: :parent_relationable, dependent: :destroy end + + def report_related_content(relationable) + related_content = related_contents.find_by(child_relationable: relationable) + if related_content.present? + related_content.increment!(:times_reported) + related_content.opposite_related_content.increment!(:times_reported) + end + end end diff --git a/spec/models/relation_spec.rb b/spec/models/relation_spec.rb index ebefa51fa..9f1b4d70c 100644 --- a/spec/models/relation_spec.rb +++ b/spec/models/relation_spec.rb @@ -48,4 +48,16 @@ describe RelatedContent do expect(child_relationable.related_contents).to be_empty end end + + # TODO: Move this into a Relationable shared context + describe '#report_related_content' do + it 'increments both relation and opposite relation times_reported counters' do + related_content = create(:related_content, parent_relationable: parent_relationable, child_relationable: child_relationable) + parent_relationable.report_related_content(child_relationable) + + expect(related_content.reload.times_reported).to eq(1) + expect(related_content.reload.opposite_related_content.times_reported).to eq(1) + end + end + end From cd021aee4bd2942090241b2041224b858fe720c4 Mon Sep 17 00:00:00 2001 From: Bertocq Date: Tue, 28 Nov 2017 01:46:32 +0100 Subject: [PATCH 54/69] Add relationed_contents helper function on Relationable concern with spec --- app/models/concerns/relationable.rb | 8 ++++++++ spec/models/relation_spec.rb | 13 +++++++++++++ 2 files changed, 21 insertions(+) diff --git a/app/models/concerns/relationable.rb b/app/models/concerns/relationable.rb index 4f4edcd32..26f755f03 100644 --- a/app/models/concerns/relationable.rb +++ b/app/models/concerns/relationable.rb @@ -5,6 +5,14 @@ module Relationable has_many :related_contents, as: :parent_relationable, dependent: :destroy end + def relate_content(relationable) + RelatedContent.find_or_create_by(parent_relationable: self, child_relationable: relationable) + end + + def relationed_contents + related_contents.not_hidden.map { |related_content| related_content.child_relationable } + end + def report_related_content(relationable) related_content = related_contents.find_by(child_relationable: relationable) if related_content.present? diff --git a/spec/models/relation_spec.rb b/spec/models/relation_spec.rb index 9f1b4d70c..86bbe2c14 100644 --- a/spec/models/relation_spec.rb +++ b/spec/models/relation_spec.rb @@ -60,4 +60,17 @@ describe RelatedContent do end end + describe '#relationed_contents' do + before do + create(:related_content, parent_relationable: parent_relationable, child_relationable: create(:proposal), times_reported: 6) + create(:related_content, parent_relationable: parent_relationable, child_relationable: child_relationable) + end + + it 'returns not hidden by reports related contents' do + expect(parent_relationable.relationed_contents.count).to eq(1) + expect(parent_relationable.relationed_contents.first.class.name).to eq(child_relationable.class.name) + expect(parent_relationable.relationed_contents.first.id).to eq(child_relationable.id) + end + end + end From 7a1ec54e35ed0029bb5531a5b5f54fbe25b02391 Mon Sep 17 00:00:00 2001 From: Bertocq Date: Tue, 28 Nov 2017 01:54:51 +0100 Subject: [PATCH 55/69] Preparing next release --- CHANGELOG.md | 84 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 84 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index d0e57f93f..afdd9daad 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,85 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. ## [Unreleased](https://github.com/consul/consul/compare/v0.10...consul:master) +### Added +- Allow social media image meta tags to be overwritten https://github.com/consul/consul/pull/1756 +- Allow users to verify their account against a local Census https://github.com/consul/consul/pull/1752 +- Make Proposals & Budgets Investments followable by users https://github.com/consul/consul/pull/1727 +- Show user followable activity on public user page https://github.com/consul/consul/pull/1750 +- Add Budget results view & table https://github.com/consul/consul/pull/1748 +- Improved Budget winners calculations https://github.com/consul/consul/pull/1738 +- Allow Documents to be uploaded to Proposals and Budget Investments https://github.com/consul/consul/pull/1809 +- Allow Communities creation on Proposals and Budget Investments (Run rake task 'communities:associate_community') https://github.com/consul/consul/pull/1815 https://github.com/consul/consul/pull/1833 +- Allow user to geolocate Proposals and Budget Investments on a map https://github.com/consul/consul/pull/1864 +- Legislation Process Proposals https://github.com/consul/consul/pull/1906 +- Autocomplete user tags https://github.com/consul/consul/pull/1905 +- GraphQL API docs https://github.com/consul/consul/pull/1763 +- Show recommended proposals and debates to users based in their interests https://github.com/consul/consul/pull/1824 +- Allow images & videos to be added to Poll questions https://github.com/consul/consul/pull/1835 https://github.com/consul/consul/pull/1915 +- Add Poll Shifts, to soon replace Poll OfficerAssignments usage entirely (for now just partially) +- Added dropdown menu for advanced users https://github.com/consul/consul/pull/1761 +- Help text headers and footers https://github.com/consul/consul/pull/1807 +- Added a couple of steps for linux installation guidelines https://github.com/consul/consul/pull/1846 +- Added TotalResult model, to replace Poll::FinalRecount https://github.com/consul/consul/pull/1866 1885 +- Preview Budget Results by admins https://github.com/consul/consul/pull/1923 +- Added comments to Polls https://github.com/consul/consul/pull/1961 +- Added images & videos to Polls https://github.com/consul/consul/pull/1990 https://github.com/consul/consul/pull/1989 +- Poll Answers are orderable now https://github.com/consul/consul/pull/2037 +- Poll Booth Assigment management https://github.com/consul/consul/pull/2087 +- Legislation processes documents https://github.com/consul/consul/pull/2084 +- Poll results https://github.com/consul/consul/pull/2082 +- Poll stats https://github.com/consul/consul/pull/2075 +- Added investment user tags admin interface https://github.com/consul/consul/pull/2068 +- Added Poll comments to GraphQL API https://github.com/consul/consul/pull/2148 +- Added option to unassign Valuator role https://github.com/consul/consul/pull/2110 +- Added search by name/email on several Admin sections https://github.com/consul/consul/pull/2105 +- Added Docker support https://github.com/consul/consul/pull/2127 & documentation https://consul_docs.gitbooks.io/docs/content/en/getting_started/docker.html +- Added population restriction validation on Budget Headings #2115 + +### Changed +- Gem versions locked & cleanup https://github.com/consul/consul/pull/1730 +- Upgraded many minor versions https://github.com/consul/consul/pull/1747 +- Rails 4.2.10 https://github.com/consul/consul/pull/2128 +- Updated Code of Conduct to use contributor covenant 1.4 https://github.com/consul/consul/pull/1733 +- Improved consistency to all "Go back" buttons https://github.com/consul/consul/pull/1770 +- New CONSUL brand https://github.com/consul/consul/pull/1808 +- Admin panel redesign https://github.com/consul/consul/pull/1875 https://github.com/consul/consul/pull/2060 +- Swapped Poll White/Null/Total Results for Poll Recount https://github.com/consul/consul/pull/1963 +- Improved Poll index view https://github.com/consul/consul/pull/1959 https://github.com/consul/consul/pull/1987 +- Update secrets and deploy secrets example files https://github.com/consul/consul/pull/1966 +- Improved Poll Officer panel features +- Consistency across all admin profiles sections https://github.com/consul/consul/pull/2089 +- Improved dev_seeds with more Poll content https://github.com/consul/consul/pull/2121 +- Comment count now updates live after publishing a new one https://github.com/consul/consul/pull/2090 + +### Removed +- Removed Tolk gem usage, we've moved to Crowdin service https://github.com/consul/consul/pull/1729 +- Removed Polls manual recounts (model Poll::FinalRecount) https://github.com/consul/consul/pull/1764 +- Skipped specs for deprecated Spending Proposal model https://github.com/consul/consul/pull/1773 +- Moved Documentation to https://github.com/consul/docs https://github.com/consul/consul/pull/1861 +- Remove Poll Officer recounts, add Final & Totals votes https://github.com/consul/consul/pull/1919 +- Remove deprecated Poll results models https://github.com/consul/consul/pull/1964 +- Remove deprecated Poll::Question valid_answers attribute & usage https://github.com/consul/consul/pull/2073 https://github.com/consul/consul/pull/2074 + +### Fixed +- Foundation settings stylesheet https://github.com/consul/consul/pull/1766 +- Budget milestone date localization https://github.com/consul/consul/pull/1734 +- Return datetime format for en locale https://github.com/consul/consul/pull/1795 +- Show bottom proposals button only if proposals exists https://github.com/consul/consul/pull/1798 +- Check SMS verification in a more consistent way https://github.com/consul/consul/pull/1832 +- Allow only YouTube/Vimeo URLs on 'video_url' attributes https://github.com/consul/consul/pull/1854 +- Remove empty comments html https://github.com/consul/consul/pull/1862 +- Fixed admin/poll routing errors https://github.com/consul/consul/pull/1863 +- Display datepicker arrows https://github.com/consul/consul/pull/1869 +- Validate presence poll presence on Poll::Question creation https://github.com/consul/consul/pull/1868 +- Switch flag/unflag buttons on use via ajax https://github.com/consul/consul/pull/1883 +- Flaky specs fixed https://github.com/consul/consul/pull/1888 +- Fixed link back from moderation dashboard to root_path https://github.com/consul/consul/pull/2132 +- Fixed Budget random pagination order https://github.com/consul/consul/pull/2131 +- Fixed `direct_messages_max_per_day` set to nil https://github.com/consul/consul/pull/2100 +- Fixed notification link error when someone commented a Topic https://github.com/consul/consul/pull/2094 +- Lots of small UI/UX/SEO/SEM improvements + ## [0.10.0](https://github.com/consul/consul/compare/v0.9...v0.10) - 2017-07-05 ### Added - Milestones on Budget Investment's @@ -58,3 +137,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. ### Changed - Rails 4.2.6 - Ruby 2.2.3 + +[Unreleased]: https://github.com/consul/consul/compare/v0.10...consul:master +[0.10.0]: https://github.com/consul/consul/compare/v0.9...v0.10 +[0.9.0]: https://github.com/consul/consul/compare/v0.8...v0.9 +[0.8.0]: https://github.com/consul/consul/compare/v0.7...v0.8 From 9e0d2c403ac783045f537d90f5739581f1708ebd Mon Sep 17 00:00:00 2001 From: Bertocq Date: Wed, 29 Nov 2017 23:21:35 +0100 Subject: [PATCH 56/69] Update unreleased section of changelog --- CHANGELOG.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index afdd9daad..6210e7f67 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,7 +7,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. ## [Unreleased](https://github.com/consul/consul/compare/v0.10...consul:master) ### Added -- Allow social media image meta tags to be overwritten https://github.com/consul/consul/pull/1756 +- Allow social media image meta tags to be overwritten https://github.com/consul/consul/pull/1756 & https://github.com/consul/consul/pull/2153 - Allow users to verify their account against a local Census https://github.com/consul/consul/pull/1752 - Make Proposals & Budgets Investments followable by users https://github.com/consul/consul/pull/1727 - Show user followable activity on public user page https://github.com/consul/consul/pull/1750 @@ -34,12 +34,13 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. - Legislation processes documents https://github.com/consul/consul/pull/2084 - Poll results https://github.com/consul/consul/pull/2082 - Poll stats https://github.com/consul/consul/pull/2075 +- Poll stats on admin panel https://github.com/consul/consul/pull/2102 - Added investment user tags admin interface https://github.com/consul/consul/pull/2068 - Added Poll comments to GraphQL API https://github.com/consul/consul/pull/2148 - Added option to unassign Valuator role https://github.com/consul/consul/pull/2110 - Added search by name/email on several Admin sections https://github.com/consul/consul/pull/2105 - Added Docker support https://github.com/consul/consul/pull/2127 & documentation https://consul_docs.gitbooks.io/docs/content/en/getting_started/docker.html -- Added population restriction validation on Budget Headings #2115 +- Added population restriction validation on Budget Headings https://github.com/consul/consul/pull/2115 ### Changed - Gem versions locked & cleanup https://github.com/consul/consul/pull/1730 From 6d8657ab5c576fcd5fb3f120761afbe9d31388c2 Mon Sep 17 00:00:00 2001 From: Bertocq Date: Thu, 30 Nov 2017 11:45:51 +0100 Subject: [PATCH 57/69] Move css styles from custom file to correct admin.scss one --- app/assets/stylesheets/admin.scss | 5 +++++ app/assets/stylesheets/custom.scss | 5 ----- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/app/assets/stylesheets/admin.scss b/app/assets/stylesheets/admin.scss index 85997aecd..a2e3e0e7f 100644 --- a/app/assets/stylesheets/admin.scss +++ b/app/assets/stylesheets/admin.scss @@ -270,6 +270,11 @@ $sidebar-active: #f4fcd0; } } +.sortable thead th:hover { + text-decoration: underline; + cursor: pointer; +} + // 02. Sidebar // ----------- diff --git a/app/assets/stylesheets/custom.scss b/app/assets/stylesheets/custom.scss index 06b4d91ce..090eb0342 100644 --- a/app/assets/stylesheets/custom.scss +++ b/app/assets/stylesheets/custom.scss @@ -3,8 +3,3 @@ // * English: https://github.com/consul/consul/blob/master/CUSTOMIZE_EN.md#css // * Spanish: https://github.com/consul/consul/blob/master/CUSTOMIZE_ES.md#css // - -table.sortable thead th:hover { - text-decoration: underline; - cursor: pointer; -} \ No newline at end of file From b327420e72a2d22ee9c571af51c0504861b3e807 Mon Sep 17 00:00:00 2001 From: Bertocq Date: Mon, 4 Dec 2017 15:42:59 +0100 Subject: [PATCH 58/69] Force setseed value range from -1 o 1 --- app/controllers/budgets/investments_controller.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/controllers/budgets/investments_controller.rb b/app/controllers/budgets/investments_controller.rb index 435fae04c..5a8174f81 100644 --- a/app/controllers/budgets/investments_controller.rb +++ b/app/controllers/budgets/investments_controller.rb @@ -94,7 +94,7 @@ module Budgets def set_random_seed if params[:order] == 'random' || params[:order].blank? - seed = rand(11..99) / 10.0 + seed = rand(-100..100) / 100.0 params[:random_seed] ||= Float(seed) rescue 0 else params[:random_seed] = nil From 05a6c35b651a1fe5165c8e12d2e25c51ebc09afb Mon Sep 17 00:00:00 2001 From: Bertocq Date: Mon, 4 Dec 2017 15:48:09 +0100 Subject: [PATCH 59/69] Switch case statement for if --- app/controllers/budgets/investments_controller.rb | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/app/controllers/budgets/investments_controller.rb b/app/controllers/budgets/investments_controller.rb index 5a8174f81..5e7c1ddf0 100644 --- a/app/controllers/budgets/investments_controller.rb +++ b/app/controllers/budgets/investments_controller.rb @@ -131,8 +131,7 @@ module Budgets end def investments - case @current_order - when 'random' + if @current_order == 'random' @investments.apply_filters_and_search(@budget, params, @current_filter) .send("sort_by_#{@current_order}", params[:random_seed]) else From 88d098242cd6682f80a2db85c7d7f1a5d3ddb57a Mon Sep 17 00:00:00 2001 From: Bertocq Date: Mon, 4 Dec 2017 18:03:35 +0100 Subject: [PATCH 60/69] Add missing public_stats feature flag on dev seeds --- db/dev_seeds.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/db/dev_seeds.rb b/db/dev_seeds.rb index f24efa4da..a6e471d98 100644 --- a/db/dev_seeds.rb +++ b/db/dev_seeds.rb @@ -50,6 +50,7 @@ section "Creating Settings" do Setting.create(key: 'feature.user.recommendations', value: "true") Setting.create(key: 'feature.community', value: "true") Setting.create(key: 'feature.map', value: "true") + Setting.create(key: 'feature.public_stats', value: "true") Setting.create(key: 'per_page_code_head', value: "") Setting.create(key: 'per_page_code_body', value: "") Setting.create(key: 'comments_body_max_length', value: '1000') From 516081d109134ef706831d410ec78458e16f31dc Mon Sep 17 00:00:00 2001 From: Bertocq Date: Mon, 4 Dec 2017 18:17:10 +0100 Subject: [PATCH 61/69] Describe with a request spec the consul.json install details route --- .../installation_controller_spec.rb | 54 +++++++++++++++++++ 1 file changed, 54 insertions(+) create mode 100644 spec/controllers/installation_controller_spec.rb diff --git a/spec/controllers/installation_controller_spec.rb b/spec/controllers/installation_controller_spec.rb new file mode 100644 index 000000000..68c2e7c07 --- /dev/null +++ b/spec/controllers/installation_controller_spec.rb @@ -0,0 +1,54 @@ +require 'rails_helper' + +describe InstallationController, type: :request do + + describe "consul.json" do + let(:feature_settings) do + { + 'debates' => nil, + 'spending_proposals' => 't', + 'polls' => nil, + 'twitter_login' => nil, + 'facebook_login' => nil, + 'google_login' => nil, + 'public_stats' => nil, + 'budgets' => nil, + 'signature_sheets' => nil, + 'legislation' => nil, + 'user.recommendations' => nil, + 'community' => nil, + 'map' => 't', + 'spending_proposal_features.voting_allowed' => 't' + } + end + + before do + feature_settings.each { |feature_name, feature_value| Setting["feature.#{feature_name}"] = feature_value } + end + + after do + Setting['feature.debates'] = true + Setting['feature.spending_proposals'] = nil + Setting['feature.polls'] = true + Setting['feature.twitter_login'] = true + Setting['feature.facebook_login'] = true + Setting['feature.google_login'] = true + Setting['feature.public_stats'] = true + Setting['feature.budgets'] = true + Setting['feature.signature_sheets'] = true + Setting['feature.legislation'] = true + Setting['feature.user.recommendations'] = true + Setting['feature.community'] = true + Setting['feature.map'] = nil + Setting['feature.spending_proposal_features.voting_allowed'] = nil + end + + specify "with query string inside query params" do + get '/consul.json' + + expect(response).to have_http_status(:ok) + expect(JSON.parse(response.body)['release']).not_to be_empty + expect(JSON.parse(response.body)['features']).to eq(feature_settings) + end + end +end From 7339a98b74cc853751e187fecffaa25b2f973152 Mon Sep 17 00:00:00 2001 From: Bertocq Date: Mon, 4 Dec 2017 18:17:53 +0100 Subject: [PATCH 62/69] Create installation controller with consul details method, add route on routes.rb --- app/controllers/installation_controller.rb | 24 ++++++++++++++++++++++ config/routes.rb | 2 ++ 2 files changed, 26 insertions(+) create mode 100644 app/controllers/installation_controller.rb diff --git a/app/controllers/installation_controller.rb b/app/controllers/installation_controller.rb new file mode 100644 index 000000000..a0bc0aa74 --- /dev/null +++ b/app/controllers/installation_controller.rb @@ -0,0 +1,24 @@ +class InstallationController < ApplicationController + + skip_authorization_check + + def details + respond_to do |format| + format.any { render json: consul_installation_details.to_json, content_type: 'application/json' } + end + end + + private + + def consul_installation_details + { + release: 'v0.11' + }.merge(features: settings_feature_flags) + end + + def settings_feature_flags + Setting.where("key LIKE 'feature.%'").each_with_object({}) { |x, n| n[x.key.remove('feature.')] = x.value } + end + +end + diff --git a/config/routes.rb b/config/routes.rb index df7e03a4f..31d811293 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -36,6 +36,8 @@ Rails.application.routes.draw do get '/welcome', to: 'welcome#welcome' get '/cuentasegura', to: 'welcome#verification', as: :cuentasegura + get '/consul.json', to: "installation#details" + resources :debates do member do post :vote From eb28726c82dc861c4d9a061a506458af75435fb8 Mon Sep 17 00:00:00 2001 From: Bertocq Date: Mon, 4 Dec 2017 23:05:12 +0100 Subject: [PATCH 63/69] Prepare CHANGELOG for v0.11 release --- CHANGELOG.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6210e7f67..2f39815c8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,7 +4,9 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html). -## [Unreleased](https://github.com/consul/consul/compare/v0.10...consul:master) +## [Unreleased](https://github.com/consul/consul/compare/v0.11...consul:master) + +## [0.11.0](https://github.com/consul/consul/compare/v0.10...v0.11) - 2017-12-05 ### Added - Allow social media image meta tags to be overwritten https://github.com/consul/consul/pull/1756 & https://github.com/consul/consul/pull/2153 @@ -41,6 +43,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. - Added search by name/email on several Admin sections https://github.com/consul/consul/pull/2105 - Added Docker support https://github.com/consul/consul/pull/2127 & documentation https://consul_docs.gitbooks.io/docs/content/en/getting_started/docker.html - Added population restriction validation on Budget Headings https://github.com/consul/consul/pull/2115 +- Added a `/consul.json` route that returns installation details (current release version and feature flags status) for a future dashboard app https://github.com/consul/consul/pull/2164 ### Changed - Gem versions locked & cleanup https://github.com/consul/consul/pull/1730 From e2d4fbd9ce09faf123480f4dcc093a1c27664891 Mon Sep 17 00:00:00 2001 From: rgarcia Date: Wed, 1 Nov 2017 18:42:22 +0100 Subject: [PATCH 64/69] knapsack_pro setup --- .travis.yml | 8 ++++---- Gemfile | 2 +- Gemfile.lock | 8 +++----- Rakefile | 2 +- spec/spec_helper.rb | 5 +++-- 5 files changed, 12 insertions(+), 13 deletions(-) diff --git a/.travis.yml b/.travis.yml index 4eb86bbf6..cbdeee0b8 100644 --- a/.travis.yml +++ b/.travis.yml @@ -10,10 +10,10 @@ before_script: - bundle exec rake db:setup script: - "bundle exec rake assets:precompile RAILS_ENV=test" - - "bundle exec rake knapsack:rspec" + - "bundle exec rake knapsack_pro:rspec" env: global: - - CI_NODE_TOTAL=2 + - KNAPSACK_PRO_CI_NODE_TOTAL=2 matrix: - - CI_NODE_INDEX=0 - - CI_NODE_INDEX=1 + - KNAPSACK_PRO_CI_NODE_INDEX=0 + - KNAPSACK_PRO_CI_NODE_INDEX=1 diff --git a/Gemfile b/Gemfile index b0c7f2e9a..79383b48f 100644 --- a/Gemfile +++ b/Gemfile @@ -64,7 +64,7 @@ group :development, :test do gem 'factory_girl_rails', '~> 4.8.0' gem 'faker', '~> 1.7.3' gem 'i18n-tasks', '~> 0.9.15' - gem 'knapsack', '~> 1.13.3' + gem 'knapsack_pro', '~> 0.52.0' gem 'launchy', '~> 2.4.3' gem 'letter_opener_web', '~> 1.3.1' gem 'quiet_assets', '~> 1.1.0' diff --git a/Gemfile.lock b/Gemfile.lock index 8bfbbb27c..3b30015e0 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -229,9 +229,8 @@ GEM kaminari-core (= 1.0.1) kaminari-core (1.0.1) kgio (2.11.0) - knapsack (1.13.3) + knapsack_pro (0.52.0) rake - timecop (>= 0.1.0) kramdown (1.14.0) launchy (2.4.3) addressable (~> 2.3) @@ -451,7 +450,6 @@ GEM thread (0.2.2) thread_safe (0.3.6) tilt (2.0.7) - timecop (0.9.1) tins (1.15.0) turbolinks (2.5.3) coffee-rails @@ -531,7 +529,7 @@ DEPENDENCIES jquery-rails (~> 4.3.1) jquery-ui-rails (~> 6.0.1) kaminari (~> 1.0.1) - knapsack (~> 1.13.3) + knapsack_pro (~> 0.52.0) launchy (~> 2.4.3) letter_opener_web (~> 1.3.1) mdl (~> 0.4.0) @@ -573,4 +571,4 @@ DEPENDENCIES whenever (~> 0.9.7) BUNDLED WITH - 1.15.4 + 1.16.0 diff --git a/Rakefile b/Rakefile index ef2c381ff..13a99536b 100644 --- a/Rakefile +++ b/Rakefile @@ -4,4 +4,4 @@ require File.expand_path('../config/application', __FILE__) Rails.application.load_tasks -Knapsack.load_tasks if defined?(Knapsack) \ No newline at end of file +KnapsackPro.load_tasks if defined?(KnapsackPro) diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index a0e4a98b0..7beab6ff1 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -2,7 +2,8 @@ require 'factory_girl_rails' require 'database_cleaner' require 'email_spec' require 'devise' -require 'knapsack' +require 'knapsack_pro' + Dir["./spec/models/concerns/*.rb"].each { |f| require f } Dir["./spec/support/**/*.rb"].sort.each { |f| require f } Dir["./spec/shared/**/*.rb"].sort.each { |f| require f } @@ -107,4 +108,4 @@ RSpec.configure do |config| end # Parallel build helper configuration for travis -Knapsack::Adapters::RSpecAdapter.bind +KnapsackPro::Adapters::RSpecAdapter.bind From d238889deceaca828ad6c0c09cfd84b188ee521e Mon Sep 17 00:00:00 2001 From: rgarcia Date: Fri, 3 Nov 2017 13:09:21 +0100 Subject: [PATCH 65/69] dynamically allocate RSpec tests across CI nodes --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index cbdeee0b8..910227ea1 100644 --- a/.travis.yml +++ b/.travis.yml @@ -10,7 +10,7 @@ before_script: - bundle exec rake db:setup script: - "bundle exec rake assets:precompile RAILS_ENV=test" - - "bundle exec rake knapsack_pro:rspec" + - "bundle exec rake knapsack_pro:queue:rspec" env: global: - KNAPSACK_PRO_CI_NODE_TOTAL=2 From 834bbf4be3ddd2463b8ec57f7bff770158f85634 Mon Sep 17 00:00:00 2001 From: rgarcia Date: Fri, 3 Nov 2017 13:10:08 +0100 Subject: [PATCH 66/69] removes unnecessary binding --- spec/spec_helper.rb | 3 --- 1 file changed, 3 deletions(-) diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 7beab6ff1..43a2990ac 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -106,6 +106,3 @@ RSpec.configure do |config| # as the one that triggered the failure. Kernel.srand config.seed end - -# Parallel build helper configuration for travis -KnapsackPro::Adapters::RSpecAdapter.bind From b1c785408c73b56bae95ecac519f2f57c0bc5f09 Mon Sep 17 00:00:00 2001 From: rgarcia Date: Fri, 3 Nov 2017 13:48:58 +0100 Subject: [PATCH 67/69] brings back knapsackpro binding --- spec/spec_helper.rb | 3 +++ 1 file changed, 3 insertions(+) diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 43a2990ac..7beab6ff1 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -106,3 +106,6 @@ RSpec.configure do |config| # as the one that triggered the failure. Kernel.srand config.seed end + +# Parallel build helper configuration for travis +KnapsackPro::Adapters::RSpecAdapter.bind From 27f46c9239d51f78010053e1ef744ad2487a27f8 Mon Sep 17 00:00:00 2001 From: ArturT Date: Mon, 4 Dec 2017 22:24:50 +0100 Subject: [PATCH 68/69] Allow forked version of repo to run tests with knapsack_pro gem without needed API key KNAPSACK_PRO_TEST_SUITE_TOKEN_RSPEC. Based on: https://github.com/KnapsackPro/knapsack_pro-ruby#how-to-make-knapsack_pr o-works-for-forked-repositories-of-my-project --- .travis.yml | 2 +- bin/knapsack_pro_rspec | 9 +++++++++ 2 files changed, 10 insertions(+), 1 deletion(-) create mode 100755 bin/knapsack_pro_rspec diff --git a/.travis.yml b/.travis.yml index 910227ea1..9da8210d0 100644 --- a/.travis.yml +++ b/.travis.yml @@ -10,7 +10,7 @@ before_script: - bundle exec rake db:setup script: - "bundle exec rake assets:precompile RAILS_ENV=test" - - "bundle exec rake knapsack_pro:queue:rspec" + - "bin/knapsack_pro_rspec" env: global: - KNAPSACK_PRO_CI_NODE_TOTAL=2 diff --git a/bin/knapsack_pro_rspec b/bin/knapsack_pro_rspec new file mode 100755 index 000000000..9aaf762ad --- /dev/null +++ b/bin/knapsack_pro_rspec @@ -0,0 +1,9 @@ +#!/bin/bash +if [ "$KNAPSACK_PRO_TEST_SUITE_TOKEN_RSPEC" = "" ]; then + KNAPSACK_PRO_ENDPOINT=https://api-disabled-for-fork.knapsackpro.com \ + KNAPSACK_PRO_TEST_SUITE_TOKEN_RSPEC=disabled-for-fork \ + bundle exec rake knapsack_pro:rspec # use Regular Mode here always +else + # Queue Mode - dynamic tests allocation across CI nodes + bundle exec rake knapsack_pro:queue:rspec +fi From 79e684e68e06a5920e9d34ce03a5c899a967bd17 Mon Sep 17 00:00:00 2001 From: ArturT Date: Mon, 4 Dec 2017 22:36:59 +0100 Subject: [PATCH 69/69] Use latest version of knapsack_pro 0.53.0 --- Gemfile | 2 +- Gemfile.lock | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Gemfile b/Gemfile index 79383b48f..94002104e 100644 --- a/Gemfile +++ b/Gemfile @@ -64,7 +64,7 @@ group :development, :test do gem 'factory_girl_rails', '~> 4.8.0' gem 'faker', '~> 1.7.3' gem 'i18n-tasks', '~> 0.9.15' - gem 'knapsack_pro', '~> 0.52.0' + gem 'knapsack_pro', '~> 0.53.0' gem 'launchy', '~> 2.4.3' gem 'letter_opener_web', '~> 1.3.1' gem 'quiet_assets', '~> 1.1.0' diff --git a/Gemfile.lock b/Gemfile.lock index 3b30015e0..d7d210576 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -229,7 +229,7 @@ GEM kaminari-core (= 1.0.1) kaminari-core (1.0.1) kgio (2.11.0) - knapsack_pro (0.52.0) + knapsack_pro (0.53.0) rake kramdown (1.14.0) launchy (2.4.3) @@ -529,7 +529,7 @@ DEPENDENCIES jquery-rails (~> 4.3.1) jquery-ui-rails (~> 6.0.1) kaminari (~> 1.0.1) - knapsack_pro (~> 0.52.0) + knapsack_pro (~> 0.53.0) launchy (~> 2.4.3) letter_opener_web (~> 1.3.1) mdl (~> 0.4.0)