Skip to content

Commit

Permalink
Consultation results (#5188)
Browse files Browse the repository at this point in the history
* Add admin results page for consultations

* Add tests for admin results

* Changelog entry

* english locale normalization

* show only published questions to results

* Remove locale additions from ca/es

* loop n+1 optimization

* extra lines
  • Loading branch information
microstudi authored and oriolgual committed Jun 17, 2019
1 parent ab5b8da commit 7d2bb5b
Show file tree
Hide file tree
Showing 9 changed files with 128 additions and 1 deletion.
1 change: 1 addition & 0 deletions CHANGELOG.md
Expand Up @@ -5,6 +5,7 @@

**Added**:

- **decidim-consultations**: Add admin results page to consultations [#5188](https://github.com/decidim/decidim/pull/5188)
- **decidim-core**: Adds SECURITY.md per Github recommendations [#5181](https://github.com/decidim/decidim/pull/5181)
- **decidim-core**, **decidim-system**: Add force users to authenticate before access to the organization [#5189](https://github.com/decidim/decidim/pull/5189)
- **decidim-proposals**: Add new fields to proposal_serializer [#5186](https://github.com/decidim/decidim/pull/5186)
Expand Down
Expand Up @@ -44,7 +44,7 @@ def edit
render layout: "decidim/admin/consultation"
end

# PUT /admin/initiatives/:id
# PUT /admin/consultations/:slug
def update
enforce_permission_to :update, :consultation, consultation: current_consultation

Expand All @@ -64,6 +64,12 @@ def update
end
end

# GET /admin/consultations/:slug/results
def results
enforce_permission_to :read, :consultation, consultation: current_consultation
render layout: "decidim/admin/consultation"
end

private

def current_consultation
Expand Down
4 changes: 4 additions & 0 deletions decidim-consultations/app/models/decidim/consultation.rb
Expand Up @@ -64,6 +64,10 @@ def questions_by_scope
questions.published.group_by(&:scope)
end

def total_votes
@total_votes ||= questions.published.sum(:votes_count)
end

# This method exists with the only purpose of getting rid of whats seems to be an issue in
# the new scope picker: This engine is a bit special: consultations and questions are a kind of
# nested participatory spaces. When a new question is created the consultation is the participatory space.
Expand Down
Expand Up @@ -59,6 +59,11 @@ def sorted_results
responses.order(votes_count: :desc)
end

# if results can be shown to admins
def publishable_results?
consultation.finished? && sorted_results.any?
end

def most_voted_response
@most_voted_response ||= responses.order(votes_count: :desc).first
end
Expand Down
@@ -0,0 +1,36 @@
<div class="card" id="consultations">
<div class="card-divider">
<h2 class="card-title">
<%= t "decidim.admin.titles.results" %>
<span class="label button--title"><%= t "decidim.admin.consultations.results.total_votes", count: current_consultation.total_votes %></span>
</h2>
</div>
<div class="card-section">
<% current_consultation.questions.published.includes(:responses).each do |question| %>
<% unless question.external_voting %>
<table class="table-list">
<thead>
<tr>
<th><%= decidim_sanitize translated_attribute question.title %></th>
<th class="table-list__actions">
<%= t "decidim.admin.consultations.results.total_votes", count: question.total_votes %>
</th>
</tr>
</thead>
<tbody>
<% if question.publishable_results? %>
<% question.sorted_results.each do |response| %>
<tr>
<td><%= translated_attribute response.title %></td>
<td><%= response.votes_count %></td>
</tr>
<% end %>
<% else %>
<tr><td><em><%= t "decidim.admin.consultations.results.not_visible" %></em></td><td>&nbsp;</td></tr>
<% end %>
</tbody>
</table>
<% end %>
<% end %>
</div>
</div>
Expand Up @@ -14,6 +14,10 @@
<%= aria_selected_link_to t("questions", scope: "decidim.admin.menu.consultations_submenu"),
decidim_admin_consultations.consultation_questions_path(current_consultation) %>
</li>
<li <% if is_active_link?(decidim_admin_consultations.results_consultation_path(current_consultation)) %> class="is-active" <% end %>>
<%= aria_selected_link_to t("results", scope: "decidim.admin.menu.consultations_submenu"),
decidim_admin_consultations.results_consultation_path(current_consultation) %>
</li>
<% end %>
</ul>
</div>
Expand Down
5 changes: 5 additions & 0 deletions decidim-consultations/config/locales/en.yml
Expand Up @@ -88,6 +88,9 @@ en:
new:
create: Create
title: New consultation
results:
not_visible: Results will be available when consultation closes
total_votes: 'Total: %{count} votes'
update:
error: There was a problem updating this consultation.
success: Consultation updated successfully.
Expand All @@ -96,6 +99,7 @@ en:
consultations_submenu:
info: Information
questions: Questions
results: Results
questions_submenu:
components: Components
consultation: Consultation
Expand Down Expand Up @@ -172,6 +176,7 @@ en:
consultations: Consultations
questions: Questions
responses: Responses
results: Results
consultations:
admin:
content_blocks:
Expand Down
Expand Up @@ -15,6 +15,7 @@ class AdminEngine < ::Rails::Engine

routes do
resources :consultations, param: :slug, except: [:show, :destroy] do
get :results, on: :member
resource :publish, controller: "consultation_publications", only: [:create, :destroy]
resource :publish_results, controller: "consultation_results_publications", only: [:create, :destroy]
resources :questions, param: :slug, except: :show, shallow: true do
Expand Down
@@ -0,0 +1,65 @@
# frozen_string_literal: true

require "spec_helper"

describe "Admin manages results", type: :system do
include_context "when administrating a consultation"
let(:votes) { 0 }
let(:total_votes) do
I18n.t("decidim.admin.consultations.results.total_votes", count: votes)
end

before do
switch_to_host(organization.host)
login_as user, scope: :user
visit decidim_admin_consultations.results_consultation_path(consultation)
end

describe "viewing active consultation" do
let!(:consultation) { create(:consultation, :active, :unpublished_results, organization: organization) }

it "Show votes but not responses" do
expect(page).to have_content(/#{total_votes}/i)
expect(page).to have_content(/#{translated(consultation.questions.first.title)}/i)
expect(page).not_to have_content(/#{translated(consultation.questions.first.responses.first.title)}/i)
end
end

describe "viewing active consultations with votes" do
let!(:consultation) { create(:consultation, :active, :unpublished_results, organization: organization) }
let!(:vote) do
consultation.questions.first.votes.create(author: user, response: consultation.questions.first.responses.first)
end
let(:votes) { consultation.questions.first.total_votes }

it "Show votes total" do
visit decidim_admin_consultations.results_consultation_path(consultation)
expect(page).to have_content(/#{total_votes}/i)
expect(page).not_to have_content(/#{translated(consultation.questions.first.responses.first.title)}/i)
end
end

describe "viewing finished consultation" do
let!(:consultation) { create(:consultation, :finished, :unpublished_results, organization: organization) }

it "Shows votes and responses" do
expect(page).to have_content(/#{total_votes}/i)
expect(page).to have_content(/#{translated(consultation.questions.first.title)}/i)
expect(page).to have_content(/#{translated(consultation.questions.first.responses.first.title)}/i)
end
end

describe "viewing finished consultations with votes" do
let!(:consultation) { create(:consultation, :finished, :unpublished_results, organization: organization) }
let!(:vote) do
consultation.questions.first.votes.create(author: user, response: consultation.questions.first.responses.first)
end
let(:votes) { consultation.questions.first.total_votes }

it "Show votes total" do
visit decidim_admin_consultations.results_consultation_path(consultation)
expect(page).to have_content(/#{total_votes}/i)
expect(page).to have_content(/#{translated(consultation.questions.first.responses.first.title)}/i)
end
end
end

0 comments on commit 7d2bb5b

Please sign in to comment.