Fixes #voodoorai2000 comments
Fixes some comments from #voodoorai2000 for the PR to consul
This commit is contained in:
@@ -5,7 +5,7 @@
|
||||
(function(){
|
||||
'use strict';
|
||||
|
||||
var ProposalGraph = function(url) {
|
||||
let ProposalGraph = function(url) {
|
||||
this.url = url;
|
||||
this.successfulProposalDataUrl = null;
|
||||
this.proposalAchievementsUrl = null;
|
||||
@@ -15,12 +15,11 @@
|
||||
this.progressLabel = 'Progress';
|
||||
this.supportsLabel = 'Supports';
|
||||
this.successLabel = 'Success';
|
||||
this.chart = null;
|
||||
this.goals = null;
|
||||
this.achievements = null;
|
||||
this.xColumnValues = null;
|
||||
this.succesfulColumnValues = null;
|
||||
this.progressColumnValues = null;
|
||||
this.resourcesUrl = null;
|
||||
};
|
||||
|
||||
ProposalGraph.prototype.refresh = function() {
|
||||
@@ -33,7 +32,7 @@
|
||||
|
||||
ProposalGraph.prototype.refreshGoals = function () {
|
||||
return $.ajax({
|
||||
url: '/dashboard/resources.json',
|
||||
url: this.resourcesUrl,
|
||||
cache: false,
|
||||
success: function(data) {
|
||||
this.parseGoals(data);
|
||||
@@ -42,7 +41,7 @@
|
||||
};
|
||||
|
||||
ProposalGraph.prototype.parseGoals = function(data) {
|
||||
var i, l;
|
||||
let i, l;
|
||||
|
||||
this.goals = [];
|
||||
for (i = 0, l = data.length; i < l; i += 1) {
|
||||
@@ -67,7 +66,7 @@
|
||||
};
|
||||
|
||||
ProposalGraph.prototype.parseData = function(data) {
|
||||
var key;
|
||||
let key;
|
||||
|
||||
this.xColumnValues = [ ];
|
||||
this.progressColumnValues = [ this.progressLabel ];
|
||||
@@ -94,7 +93,7 @@
|
||||
};
|
||||
|
||||
ProposalGraph.prototype.parseSuccessfulProposalData = function(data) {
|
||||
var key;
|
||||
let key;
|
||||
|
||||
this.successfulColumnValues = [ this.successLabel ];
|
||||
|
||||
@@ -120,7 +119,7 @@
|
||||
};
|
||||
|
||||
ProposalGraph.prototype.parseAchievements = function(data) {
|
||||
var group;
|
||||
let group;
|
||||
|
||||
this.achievements = [];
|
||||
for (group in data) {
|
||||
@@ -128,7 +127,7 @@
|
||||
this.addXColumnValue(group);
|
||||
this.achievements.push({
|
||||
value: group,
|
||||
text: data[group][data[group].length - 1].title
|
||||
text: data[group].title
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -138,12 +137,12 @@
|
||||
if (this.xColumnValues.indexOf(value) === -1) {
|
||||
this.xColumnValues.push(value);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
ProposalGraph.prototype.draw = function(data) {
|
||||
ProposalGraph.prototype.draw = function() {
|
||||
this.formatXColumnValues();
|
||||
|
||||
this.chart = c3.generate({
|
||||
c3.generate({
|
||||
bindto: '#' + this.targetId,
|
||||
data: {
|
||||
x: 'x',
|
||||
@@ -176,9 +175,6 @@
|
||||
y: {
|
||||
lines: this.goals
|
||||
}
|
||||
//x: {
|
||||
// lines: this.achievements
|
||||
//}
|
||||
},
|
||||
legend: {
|
||||
position: 'right'
|
||||
@@ -187,7 +183,7 @@
|
||||
};
|
||||
|
||||
ProposalGraph.prototype.formatXColumnValues = function () {
|
||||
var i, l, parts;
|
||||
let i, l, parts;
|
||||
|
||||
this.xColumnValues = this.xColumnValues.sort();
|
||||
|
||||
@@ -199,7 +195,7 @@
|
||||
}
|
||||
|
||||
this.xColumnValues.unshift('x');
|
||||
}
|
||||
};
|
||||
|
||||
ProposalGraph.prototype.isDailyGrouped = function() {
|
||||
return this.groupBy === undefined || this.groupBy === '' || this.groupBy === null
|
||||
@@ -207,7 +203,7 @@
|
||||
|
||||
$(document).ready(function () {
|
||||
$('[data-proposal-graph-url]').each(function () {
|
||||
var graph = new ProposalGraph($(this).data('proposal-graph-url'));
|
||||
let graph = new ProposalGraph($(this).data('proposal-graph-url'));
|
||||
graph.successfulProposalDataUrl = $(this).data('successful-proposal-graph-url');
|
||||
graph.proposalAchievementsUrl = $(this).data('proposal-achievements-url');
|
||||
graph.targetId = $(this).attr('id');
|
||||
@@ -216,6 +212,7 @@
|
||||
graph.supportsLabel = $(this).data('proposal-graph-supports-label');
|
||||
graph.successLabel = $(this).data('proposal-graph-success-label');
|
||||
graph.proposalSuccess = parseInt($(this).data('proposal-success'), 10);
|
||||
graph.resourcesUrl = $(this).data('proposal-resources-url');
|
||||
|
||||
graph.refresh();
|
||||
});
|
||||
|
||||
15
app/controllers/concerns/dashboard/expects_date_range.rb
Normal file
15
app/controllers/concerns/dashboard/expects_date_range.rb
Normal file
@@ -0,0 +1,15 @@
|
||||
module Dashboard::ExpectsDateRange
|
||||
extend ActiveSupport::Concern
|
||||
|
||||
include Dashboard::HasProposal
|
||||
|
||||
def start_date
|
||||
return Date.parse(params[:start_date]) unless params[:start_date].blank?
|
||||
proposal.created_at.to_date
|
||||
end
|
||||
|
||||
def end_date
|
||||
return Date.parse(params[:end_date]) unless params[:end_date].blank?
|
||||
Date.today
|
||||
end
|
||||
end
|
||||
7
app/controllers/concerns/dashboard/has_proposal.rb
Normal file
7
app/controllers/concerns/dashboard/has_proposal.rb
Normal file
@@ -0,0 +1,7 @@
|
||||
module Dashboard::HasProposal
|
||||
extend ActiveSupport::Concern
|
||||
|
||||
def proposal
|
||||
@proposal ||= Proposal.includes(:community).find(params[:proposal_id])
|
||||
end
|
||||
end
|
||||
44
app/controllers/dashboard/achievements_controller.rb
Normal file
44
app/controllers/dashboard/achievements_controller.rb
Normal file
@@ -0,0 +1,44 @@
|
||||
class Dashboard::AchievementsController < Dashboard::BaseController
|
||||
include Dashboard::ExpectsDateRange
|
||||
|
||||
def index
|
||||
authorize! :dashboard, proposal
|
||||
render json: processed_groups
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def processed_groups
|
||||
grouped_results = groups
|
||||
grouped_results.each do |key, results|
|
||||
grouped_results[key] = {
|
||||
executed_at: results.last.executed_at,
|
||||
title: results.last.action.title
|
||||
}
|
||||
end
|
||||
|
||||
grouped_results
|
||||
end
|
||||
|
||||
def groups
|
||||
if params[:group_by] == 'week'
|
||||
return executed_proposed_actions.group_by { |v| "#{v.executed_at.to_date.cweek}/#{v.executed_at.to_date.year}"}
|
||||
end
|
||||
|
||||
if params[:group_by] == 'month'
|
||||
return executed_proposed_actions.group_by { |v| "#{v.executed_at.to_date.year}-#{v.executed_at.to_date.month}"}
|
||||
end
|
||||
|
||||
executed_proposed_actions.group_by { |a| a.executed_at.to_date }
|
||||
end
|
||||
|
||||
def executed_proposed_actions
|
||||
@executed_proposed_actions ||= Dashboard::ExecutedAction
|
||||
.joins(:action)
|
||||
.includes(:action)
|
||||
.where(proposal: proposal)
|
||||
.where(executed_at: start_date.beginning_of_day..end_date.end_of_day)
|
||||
.where(dashboard_actions: { action_type: 0 })
|
||||
.order(executed_at: :asc)
|
||||
end
|
||||
end
|
||||
@@ -1,6 +1,8 @@
|
||||
class Dashboard::BaseController < ApplicationController
|
||||
before_action :authenticate_user!
|
||||
|
||||
include Dashboard::HasProposal
|
||||
|
||||
helper_method :proposal, :proposed_actions, :resource, :resources, :next_goal, :next_goal_supports, :next_goal_progress, :community_members_count
|
||||
|
||||
respond_to :html
|
||||
@@ -8,10 +10,6 @@ class Dashboard::BaseController < ApplicationController
|
||||
|
||||
private
|
||||
|
||||
def proposal
|
||||
@proposal ||= Proposal.includes(:community).find(params[:proposal_id])
|
||||
end
|
||||
|
||||
def proposed_actions
|
||||
@proposed_actions ||= Dashboard::Action.proposed_actions.active_for(proposal).order(order: :asc)
|
||||
end
|
||||
|
||||
58
app/controllers/dashboard/successful_supports_controller.rb
Normal file
58
app/controllers/dashboard/successful_supports_controller.rb
Normal file
@@ -0,0 +1,58 @@
|
||||
class Dashboard::SuccessfulSupportsController < Dashboard::BaseController
|
||||
include Dashboard::ExpectsDateRange
|
||||
|
||||
def index
|
||||
authorize! :dashboard, proposal
|
||||
render json: accumulated_grouped_supports
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def accumulated_grouped_supports
|
||||
grouped_votes = grouped_supports
|
||||
grouped_votes.each do |group, votes|
|
||||
grouped_votes[group] = votes.inject(0) { |sum, vote| sum + vote.vote_weight }
|
||||
end
|
||||
|
||||
accumulated = 0
|
||||
grouped_votes.each do |k, v|
|
||||
accumulated += v
|
||||
grouped_votes[k] = accumulated
|
||||
end
|
||||
|
||||
grouped_votes
|
||||
end
|
||||
|
||||
def grouped_supports
|
||||
if params[:group_by] == 'week'
|
||||
return supports.group_by { |v| "#{v.voted_at.to_date.cweek}/#{v.voted_at.to_date.year}" }
|
||||
end
|
||||
|
||||
if params[:group_by] == 'month'
|
||||
return supports.group_by { |v| "#{v.voted_at.to_date.year}-#{v.voted_at.to_date.month}" }
|
||||
end
|
||||
|
||||
supports.group_by { |v| v.voted_at.to_date }
|
||||
end
|
||||
|
||||
def supports
|
||||
return [] if successful_proposal.nil?
|
||||
|
||||
Vote
|
||||
.select("created_at + interval '#{days_diff} day' voted_at, *")
|
||||
.where(votable: successful_proposal)
|
||||
.where("created_at + interval '#{days_diff} day' between ? and ?", start_date.beginning_of_day, end_date.end_of_day)
|
||||
.order(created_at: :asc)
|
||||
end
|
||||
|
||||
def successful_proposal
|
||||
@successful_proposal ||= Proposal.find_by(id: Setting['proposals.successful_proposal_id'])
|
||||
end
|
||||
|
||||
def days_diff
|
||||
return 0 if successful_proposal.nil?
|
||||
return 0 if proposal.published_at.nil?
|
||||
|
||||
(proposal.published_at.to_date - successful_proposal.published_at.to_date).to_i
|
||||
end
|
||||
end
|
||||
43
app/controllers/dashboard/supports_controller.rb
Normal file
43
app/controllers/dashboard/supports_controller.rb
Normal file
@@ -0,0 +1,43 @@
|
||||
class Dashboard::SupportsController < Dashboard::BaseController
|
||||
include Dashboard::ExpectsDateRange
|
||||
|
||||
def index
|
||||
authorize! :dashboard, proposal
|
||||
render json: accumulated_supports
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def accumulated_supports
|
||||
grouped_votes = grouped_supports
|
||||
grouped_votes.each do |group, votes|
|
||||
grouped_votes[group] = votes.inject(0) { |sum, vote| sum + vote.vote_weight }
|
||||
end
|
||||
|
||||
accumulated = 0
|
||||
grouped_votes.each do |k, v|
|
||||
accumulated += v
|
||||
grouped_votes[k] = accumulated
|
||||
end
|
||||
|
||||
grouped_votes
|
||||
end
|
||||
|
||||
def grouped_supports
|
||||
if params[:group_by] == 'week'
|
||||
return supports.group_by { |v| "#{v.created_at.to_date.cweek}/#{v.created_at.to_date.year}" }
|
||||
end
|
||||
|
||||
if params[:group_by] == 'month'
|
||||
return supports.group_by { |v| "#{v.created_at.to_date.year}-#{v.created_at.to_date.month}" }
|
||||
end
|
||||
|
||||
supports.group_by { |v| v.created_at.to_date }
|
||||
end
|
||||
|
||||
def supports
|
||||
@supports ||= Vote
|
||||
.where(votable: proposal, created_at: start_date.beginning_of_day..end_date.end_of_day)
|
||||
.order(created_at: :asc)
|
||||
end
|
||||
end
|
||||
@@ -37,7 +37,7 @@ class DashboardController < Dashboard::BaseController
|
||||
if @dashboard_executed_action.save
|
||||
Dashboard::AdministratorTask.create(source: @dashboard_executed_action)
|
||||
|
||||
redirect_to progress_proposal_dashboard_index_path(proposal.to_param), { flash: { info: t('.success') } }
|
||||
redirect_to progress_proposal_dashboard_index_path(proposal.to_param), { flash: { info: t('dashboard.create_request.success') } }
|
||||
else
|
||||
flash.now[:alert] = @dashboard_executed_action.errors.full_messages.join('<br>')
|
||||
render :new_request
|
||||
@@ -52,21 +52,6 @@ class DashboardController < Dashboard::BaseController
|
||||
authorize! :dashboard, proposal
|
||||
end
|
||||
|
||||
def supports
|
||||
authorize! :dashboard, proposal
|
||||
render json: ProposalSupportsQuery.for(params)
|
||||
end
|
||||
|
||||
def successful_supports
|
||||
authorize! :dashboard, proposal
|
||||
render json: SuccessfulProposalSupportsQuery.for(params)
|
||||
end
|
||||
|
||||
def achievements
|
||||
authorize! :dashboard, proposal
|
||||
render json: ProposalAchievementsQuery.for(params)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def dashboard_action
|
||||
|
||||
@@ -5,7 +5,7 @@ class Poll::Question < ActiveRecord::Base
|
||||
acts_as_paranoid column: :hidden_at
|
||||
include ActsAsParanoidAliases
|
||||
|
||||
belongs_to :poll, inverse_of: :questions
|
||||
belongs_to :poll
|
||||
belongs_to :author, -> { with_hidden }, class_name: 'User', foreign_key: 'author_id'
|
||||
|
||||
has_many :comments, as: :commentable
|
||||
|
||||
@@ -1,61 +0,0 @@
|
||||
class ProposalAchievementsQuery
|
||||
attr_reader :params
|
||||
|
||||
def self.for(params)
|
||||
query = ProposalAchievementsQuery.new params
|
||||
query.results
|
||||
end
|
||||
|
||||
def initialize(params)
|
||||
@params = params
|
||||
end
|
||||
|
||||
def results
|
||||
grouped_results = groups
|
||||
grouped_results.each do |key, achievements|
|
||||
grouped_results[key] = []
|
||||
|
||||
achievements.each do |achievement|
|
||||
grouped_results[key] << {
|
||||
executed_at: achievements.last.executed_at,
|
||||
title: achievements.last.action.title
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
grouped_results
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def groups
|
||||
return achievements.group_by { |v| v.executed_at.to_date.year } if params[:group_by] == 'year'
|
||||
return achievements.group_by { |v| "#{v.executed_at.to_date.cweek}/#{v.executed_at.to_date.year}" } if params[:group_by] == 'week'
|
||||
return achievements.group_by { |v| "#{v.executed_at.to_date.year}-#{v.executed_at.to_date.month}" } if params[:group_by] == 'month'
|
||||
achievements.group_by { |a| a.executed_at.to_date }
|
||||
end
|
||||
|
||||
def achievements
|
||||
Dashboard::ExecutedAction
|
||||
.joins(:action)
|
||||
.includes(:action)
|
||||
.where(proposal: proposal, executed_at: start_date.beginning_of_day..end_date.end_of_day)
|
||||
.where(dashboard_actions: { action_type: 0 })
|
||||
.order(executed_at: :asc)
|
||||
end
|
||||
|
||||
def proposal
|
||||
@proposal ||= Proposal.find(params[:proposal_id])
|
||||
end
|
||||
|
||||
def start_date
|
||||
return Date.parse(params[:start_date]) unless params[:start_date].blank?
|
||||
proposal.created_at.to_date
|
||||
end
|
||||
|
||||
def end_date
|
||||
return Date.parse(params[:end_date]) unless params[:end_date].blank?
|
||||
Date.today
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,54 +0,0 @@
|
||||
class ProposalSupportsQuery
|
||||
attr_reader :params
|
||||
|
||||
def self.for(params)
|
||||
query = ProposalSupportsQuery.new params
|
||||
query.results
|
||||
end
|
||||
|
||||
def initialize(params)
|
||||
@params = params
|
||||
end
|
||||
|
||||
def results
|
||||
grouped_votes = groups
|
||||
grouped_votes.each do |group, votes|
|
||||
grouped_votes[group] = votes.inject(0) { |sum, vote| sum + vote.vote_weight }
|
||||
end
|
||||
|
||||
accumulated = 0
|
||||
grouped_votes.each do |k, v|
|
||||
accumulated += v
|
||||
grouped_votes[k] = accumulated
|
||||
end
|
||||
|
||||
grouped_votes
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def groups
|
||||
return votes.group_by { |v| v.created_at.to_date.year } if params[:group_by] == 'year'
|
||||
return votes.group_by { |v| "#{v.created_at.to_date.cweek}/#{v.created_at.to_date.year}" } if params[:group_by] == 'week'
|
||||
return votes.group_by { |v| "#{v.created_at.to_date.year}-#{v.created_at.to_date.month}" } if params[:group_by] == 'month'
|
||||
votes.group_by { |v| v.created_at.to_date }
|
||||
end
|
||||
|
||||
def votes
|
||||
Vote.where(votable: proposal, created_at: start_date.beginning_of_day..end_date.end_of_day).order(created_at: :asc)
|
||||
end
|
||||
|
||||
def proposal
|
||||
@proposal ||= Proposal.find(params[:proposal_id])
|
||||
end
|
||||
|
||||
def start_date
|
||||
return Date.parse(params[:start_date]) unless params[:start_date].blank?
|
||||
proposal.created_at.to_date
|
||||
end
|
||||
|
||||
def end_date
|
||||
return Date.parse(params[:end_date]) unless params[:end_date].blank?
|
||||
Date.today
|
||||
end
|
||||
end
|
||||
@@ -1,72 +0,0 @@
|
||||
class SuccessfulProposalSupportsQuery
|
||||
attr_reader :params
|
||||
|
||||
def self.for(params)
|
||||
query = SuccessfulProposalSupportsQuery.new params
|
||||
query.results
|
||||
end
|
||||
|
||||
def initialize(params)
|
||||
@params = params
|
||||
end
|
||||
|
||||
def results
|
||||
grouped_votes = groups
|
||||
grouped_votes.each do |group, votes|
|
||||
grouped_votes[group] = votes.inject(0) { |sum, vote| sum + vote.vote_weight }
|
||||
end
|
||||
|
||||
accumulated = 0
|
||||
grouped_votes.each do |k, v|
|
||||
accumulated += v
|
||||
grouped_votes[k] = accumulated
|
||||
end
|
||||
|
||||
grouped_votes
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def groups
|
||||
return votes.group_by { |v| v.voted_at.to_date.year } if params[:group_by] == 'year'
|
||||
return votes.group_by { |v| "#{v.voted_at.to_date.cweek}/#{v.voted_at.to_date.year}" } if params[:group_by] == 'week'
|
||||
return votes.group_by { |v| "#{v.voted_at.to_date.year}-#{v.voted_at.to_date.month}" } if params[:group_by] == 'month'
|
||||
votes.group_by { |v| v.voted_at.to_date }
|
||||
end
|
||||
|
||||
def votes
|
||||
return [] if successful_proposal.nil?
|
||||
|
||||
Vote
|
||||
.select("created_at + interval '#{days_diff} day' voted_at, *")
|
||||
.where(votable: successful_proposal)
|
||||
.where("created_at + interval '#{days_diff} day' between ? and ?", start_date.beginning_of_day, end_date.end_of_day)
|
||||
.order(created_at: :asc)
|
||||
end
|
||||
|
||||
def proposal
|
||||
@proposal ||= Proposal.find(params[:proposal_id])
|
||||
end
|
||||
|
||||
def successful_proposal
|
||||
@successful_proposal ||= Proposal.find_by(id: Setting['proposals.successful_proposal_id'])
|
||||
end
|
||||
|
||||
def days_diff
|
||||
return 0 if successful_proposal.nil?
|
||||
return 0 if proposal.published_at.nil?
|
||||
|
||||
(proposal.published_at.to_date - successful_proposal.published_at.to_date).to_i
|
||||
end
|
||||
|
||||
def start_date
|
||||
return Date.parse(params[:start_date]) unless params[:start_date].blank?
|
||||
proposal.created_at.to_date
|
||||
end
|
||||
|
||||
def end_date
|
||||
return Date.parse(params[:end_date]) unless params[:end_date].blank?
|
||||
Date.today
|
||||
end
|
||||
end
|
||||
|
||||
@@ -251,4 +251,5 @@
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
@@ -18,14 +18,15 @@
|
||||
|
||||
<div class="small-12 column">
|
||||
<div id="proposal-graph"
|
||||
data-proposal-graph-url="<%= supports_proposal_dashboard_index_path(proposal, format: :json) %>"
|
||||
data-successful-proposal-graph-url="<%= successful_supports_proposal_dashboard_index_path(proposal, format: :json) %>"
|
||||
data-proposal-achievements-url="<%= achievements_proposal_dashboard_index_path(proposal, format: :json) %>"
|
||||
data-proposal-graph-url="<%= proposal_dashboard_supports_path(proposal, format: :json) %>"
|
||||
data-successful-proposal-graph-url="<%= proposal_dashboard_successful_supports_path(proposal, format: :json) %>"
|
||||
data-proposal-achievements-url="<%= proposal_dashboard_achievements_path(proposal, format: :json) %>"
|
||||
data-proposal-graph-group-by="<%= params[:group_by] %>"
|
||||
data-proposal-graph-progress-label="<%= t("dashboard.progress.progress") %>"
|
||||
data-proposal-graph-supports-label="<%= t("dashboard.progress.supports") %>"
|
||||
data-proposal-graph-success-label="<%= t("dashboard.progress.success") %>"
|
||||
data-proposal-success="<%= Setting["votes_for_proposal_success"] %>"
|
||||
data-proposal-resources-url="<%= proposal_dashboard_resources_path(proposal, format: :json) %>"
|
||||
class="c3 proposal-graph"
|
||||
style="max-height: 320px; position: relative;"></div>
|
||||
</div>
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
<div class="row margin-top">
|
||||
<div class="small-12 column">
|
||||
<ul class="menu simple clear">
|
||||
<%# if current_user && current_user.administrator? || @poll.results_enabled? %>
|
||||
<% if can?(:results, @poll) %>
|
||||
<% if controller_name == "polls" && action_name == "results" %>
|
||||
<li class="is-active">
|
||||
|
||||
@@ -1,16 +1,9 @@
|
||||
namespace :dashboard do
|
||||
resources :resources, only: [:index]
|
||||
end
|
||||
|
||||
resources :proposals do
|
||||
resources :dashboard, only: [:index] do
|
||||
collection do
|
||||
patch :publish
|
||||
get :supports
|
||||
get :successful_supports
|
||||
get :progress
|
||||
get :community
|
||||
get :achievements
|
||||
end
|
||||
|
||||
member do
|
||||
@@ -21,6 +14,10 @@ resources :proposals do
|
||||
end
|
||||
|
||||
namespace :dashboard do
|
||||
resources :resources, only: [:index]
|
||||
resources :achievements, only: [:index]
|
||||
resources :successful_supports, only: [:index]
|
||||
resources :supports, only: [:index]
|
||||
resources :polls, except: [:show, :destroy]
|
||||
resources :mailing, only: [:index, :new, :create]
|
||||
end
|
||||
|
||||
@@ -69,4 +69,11 @@ section "Creating Settings" do
|
||||
Setting['feature.homepage.widgets.feeds.proposals'] = true
|
||||
Setting['feature.homepage.widgets.feeds.debates'] = true
|
||||
Setting['feature.homepage.widgets.feeds.processes'] = true
|
||||
|
||||
Setting['proposals.successful_proposal_id'] = nil
|
||||
Setting['proposals.poll_short_title'] = nil
|
||||
Setting['proposals.poll_description'] = nil
|
||||
Setting['proposals.poll_link'] = nil
|
||||
Setting['proposals.email_short_title'] = nil
|
||||
Setting['proposals.email_description'] = nil
|
||||
end
|
||||
|
||||
@@ -1,9 +1,5 @@
|
||||
class AddPublishedAtToProposal < ActiveRecord::Migration
|
||||
def change
|
||||
add_column :proposals, :published_at, :datetime, null: true
|
||||
|
||||
Proposal.draft.find_each do |proposal|
|
||||
proposal.update(published_at: proposal.created_at)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
class AddTimestampsToDashboardActions < ActiveRecord::Migration
|
||||
def change
|
||||
add_column :dashboard_actions, :created_at, :datetime
|
||||
add_column :dashboard_actions, :updated_at, :datetime
|
||||
end
|
||||
end
|
||||
@@ -11,7 +11,7 @@
|
||||
#
|
||||
# It's strongly recommended that you check this file into your version control system.
|
||||
|
||||
ActiveRecord::Schema.define(version: 20180723112930) do
|
||||
ActiveRecord::Schema.define(version: 20180726055120) do
|
||||
|
||||
# These are extensions that must be enabled in order to support this database
|
||||
enable_extension "plpgsql"
|
||||
@@ -318,6 +318,8 @@ ActiveRecord::Schema.define(version: 20180723112930) do
|
||||
t.datetime "hidden_at"
|
||||
t.integer "action_type", default: 0, null: false
|
||||
t.string "short_description"
|
||||
t.datetime "created_at"
|
||||
t.datetime "updated_at"
|
||||
end
|
||||
|
||||
create_table "dashboard_administrator_tasks", force: :cascade do |t|
|
||||
|
||||
@@ -27,6 +27,13 @@ namespace :proposal_actions do
|
||||
end
|
||||
end
|
||||
|
||||
desc 'Publish all proposals'
|
||||
task publish_all: :environment do
|
||||
Proposal.draft.find_each do |proposal|
|
||||
proposal.update(published_at: proposal.created_at)
|
||||
end
|
||||
end
|
||||
|
||||
desc 'Simulate successful proposal'
|
||||
task create_successful_proposal: :environment do
|
||||
expected_supports = [
|
||||
|
||||
@@ -1038,7 +1038,7 @@ LOREM_IPSUM
|
||||
end
|
||||
|
||||
factory :dashboard_action, class: 'Dashboard::Action' do
|
||||
title { Faker::Lorem.sentence }
|
||||
title { Faker::Lorem.sentence[0..80] }
|
||||
description { Faker::Lorem.sentence }
|
||||
link nil
|
||||
request_to_administrators true
|
||||
|
||||
@@ -26,6 +26,14 @@ feature 'Polls' do
|
||||
end
|
||||
end
|
||||
|
||||
scenario "Proposal polls won't be listed" do
|
||||
proposal = create(:proposal)
|
||||
_poll = create(:poll, related: proposal)
|
||||
|
||||
visit polls_path
|
||||
expect(page).to have_content('There are no open votings')
|
||||
end
|
||||
|
||||
scenario 'Filtering polls' do
|
||||
create(:poll, name: "Current poll")
|
||||
create(:poll, :incoming, name: "Incoming poll")
|
||||
|
||||
@@ -1029,12 +1029,12 @@ describe Budget::Investment do
|
||||
investment.heading = heading2
|
||||
investment.store_reclassified_votes("heading_changed")
|
||||
|
||||
reclassified_vote = Budget::ReclassifiedVote.first
|
||||
|
||||
expect(Budget::ReclassifiedVote.count).to eq(3)
|
||||
Budget::ReclassifiedVote.find_each do |reclassified_vote|
|
||||
expect(reclassified_vote.investment_id).to eq(investment.id)
|
||||
expect(reclassified_vote.user_id).to eq(Budget::Ballot.first.user.id)
|
||||
expect(reclassified_vote.reason).to eq("heading_changed")
|
||||
expect(Budget::Ballot.where(user_id: reclassified_vote.user_id)).not_to be_empty
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@@ -18,118 +18,135 @@ describe Dashboard::Action do
|
||||
let(:request_to_administrators) { true }
|
||||
let(:action_type) { 'resource' }
|
||||
|
||||
it { should be_valid }
|
||||
|
||||
context 'when validating title' do
|
||||
context 'and title is blank' do
|
||||
let(:title) { nil }
|
||||
|
||||
it { should_not be_valid }
|
||||
it 'is invalid when title is blank' do
|
||||
action = build(:dashboard_action, title: '')
|
||||
expect(action).not_to be_valid
|
||||
end
|
||||
|
||||
context 'and title is very short' do
|
||||
let(:title) { 'abc' }
|
||||
|
||||
it { should_not be_valid }
|
||||
it 'is invalid when title is too short' do
|
||||
action = build(:dashboard_action, title: 'abc')
|
||||
expect(action).not_to be_valid
|
||||
end
|
||||
|
||||
context 'and title is very long' do
|
||||
let(:title) { 'a' * 81 }
|
||||
|
||||
it { should_not be_valid }
|
||||
end
|
||||
it 'is invalid when title is too long' do
|
||||
action = build(:dashboard_action, title: 'a' * 81)
|
||||
expect(action).not_to be_valid
|
||||
end
|
||||
|
||||
context 'when validating day_offset' do
|
||||
context 'and day_offset is nil' do
|
||||
let(:day_offset) { nil }
|
||||
|
||||
it { should_not be_valid }
|
||||
it 'is invalid when day_offset is not defined' do
|
||||
action = build(:dashboard_action, day_offset: nil)
|
||||
expect(action).not_to be_valid
|
||||
end
|
||||
|
||||
context 'and day_offset is negative' do
|
||||
let(:day_offset) { -1 }
|
||||
|
||||
it { should_not be_valid }
|
||||
it 'is invalid when day_offset is negative' do
|
||||
action = build(:dashboard_action, day_offset: -1)
|
||||
expect(action).not_to be_valid
|
||||
end
|
||||
|
||||
context 'and day_offset is not an integer' do
|
||||
let(:day_offset) { 1.23 }
|
||||
|
||||
it { should_not be_valid }
|
||||
end
|
||||
it 'is invalid when day_offset not an integer' do
|
||||
action = build(:dashboard_action, day_offset: 1.23)
|
||||
expect(action).not_to be_valid
|
||||
end
|
||||
|
||||
context 'when validating required_supports' do
|
||||
context 'and required_supports is nil' do
|
||||
let(:required_supports) { nil }
|
||||
|
||||
it { should_not be_valid }
|
||||
it 'is invalid when required_supports is nil' do
|
||||
action = build(:dashboard_action, required_supports: nil)
|
||||
expect(action).not_to be_valid
|
||||
end
|
||||
|
||||
context 'and required_supports is negative' do
|
||||
let(:required_supports) { -1 }
|
||||
|
||||
it { should_not be_valid }
|
||||
it 'is invalid when required_supports is negative' do
|
||||
action = build(:dashboard_action, required_supports: -1)
|
||||
expect(action).not_to be_valid
|
||||
end
|
||||
|
||||
context 'and required_supports is not an integer' do
|
||||
let(:required_supports) { 1.23 }
|
||||
|
||||
it { should_not be_valid }
|
||||
end
|
||||
it 'is invalid when required_supports is not an integer' do
|
||||
action = build(:dashboard_action, required_supports: 1.23)
|
||||
expect(action).not_to be_valid
|
||||
end
|
||||
|
||||
context 'when action type is nil' do
|
||||
let(:action_type) { nil }
|
||||
|
||||
it { should_not be_valid }
|
||||
it 'is invalid when action_type is nil' do
|
||||
action = build(:dashboard_action, action_type: nil)
|
||||
expect(action).not_to be_valid
|
||||
end
|
||||
|
||||
context 'active_for?' do
|
||||
let(:proposal) { create(:proposal, published_at: published_at, cached_votes_up: cached_votes_up) }
|
||||
let(:published_at) { Time.current }
|
||||
let(:cached_votes_up) { Proposal.votes_needed_for_success + 100 }
|
||||
it 'is active when required supports is 0 and day_offset is 0' do
|
||||
action = build(:dashboard_action, required_supports: 0, day_offset: 0)
|
||||
proposal = build(:proposal)
|
||||
|
||||
it { should be_active_for(proposal) }
|
||||
|
||||
context 'and not enough supports' do
|
||||
let(:required_supports) { cached_votes_up + 100 }
|
||||
|
||||
it { should_not be_active_for(proposal) }
|
||||
expect(action).to be_active_for(proposal)
|
||||
end
|
||||
|
||||
context 'and not passed enough time since publication' do
|
||||
let(:day_offset) { 10 }
|
||||
it 'is active when published after day_offset' do
|
||||
action = build(:dashboard_action, required_supports: 0, day_offset: 10)
|
||||
proposal = build(:proposal, published_at: Time.current - 10.days)
|
||||
|
||||
it { should_not be_active_for(proposal) }
|
||||
expect(action).to be_active_for(proposal)
|
||||
end
|
||||
|
||||
it 'is active when have enough supports' do
|
||||
action = build(:dashboard_action, required_supports: 10, day_offset: 0)
|
||||
proposal = build(:proposal, cached_votes_up: 10)
|
||||
|
||||
expect(action).to be_active_for(proposal)
|
||||
end
|
||||
|
||||
it 'is not active when not enough time published' do
|
||||
action = build(:dashboard_action, required_supports: 0, day_offset: 10)
|
||||
proposal = build(:proposal, published_at: Time.current - 9.days)
|
||||
|
||||
expect(action).not_to be_active_for(proposal)
|
||||
end
|
||||
|
||||
it 'is not active when not enough supports' do
|
||||
action = build(:dashboard_action, required_supports: 10, day_offset: 0)
|
||||
proposal = build(:proposal, cached_votes_up: 9)
|
||||
|
||||
expect(action).not_to be_active_for(proposal)
|
||||
end
|
||||
end
|
||||
|
||||
context 'executed_for? and requested_for?' do
|
||||
let(:proposal) { create(:proposal) }
|
||||
subject { create(:dashboard_action, :active, :admin_request, :resource) }
|
||||
context 'requested_for?' do
|
||||
it 'is not requested when no administrator task' do
|
||||
proposal = create(:proposal)
|
||||
action = create(:dashboard_action, :active, :admin_request, :resource)
|
||||
|
||||
it { should_not be_requested_for(proposal) }
|
||||
it { should_not be_executed_for(proposal) }
|
||||
|
||||
context 'and executed action' do
|
||||
let(:executed_action) { create(:dashboard_executed_action, proposal: proposal, action: subject) }
|
||||
|
||||
context 'and pending administrator task' do
|
||||
let!(:task) { create(:dashboard_administrator_task, :pending, source: executed_action) }
|
||||
|
||||
it { should be_requested_for(proposal) }
|
||||
it { should_not be_executed_for(proposal) }
|
||||
expect(action).not_to be_requested_for(proposal)
|
||||
end
|
||||
|
||||
context 'and solved administrator task' do
|
||||
let!(:task) { create(:dashboard_administrator_task, :done, source: executed_action) }
|
||||
it 'is requested when administrator task' do
|
||||
proposal = create(:proposal)
|
||||
action = create(:dashboard_action, :active, :admin_request, :resource)
|
||||
executed_action = create(:dashboard_executed_action, proposal: proposal, action: action)
|
||||
_task = create(:dashboard_administrator_task, :pending, source: executed_action)
|
||||
|
||||
it { should be_requested_for(proposal) }
|
||||
it { should be_executed_for(proposal) }
|
||||
end
|
||||
end
|
||||
expect(action).to be_requested_for(proposal)
|
||||
end
|
||||
end
|
||||
|
||||
context 'executed_for?' do
|
||||
it 'is not executed when no administrator task' do
|
||||
proposal = create(:proposal)
|
||||
action = create(:dashboard_action, :active, :admin_request, :resource)
|
||||
|
||||
expect(action).not_to be_executed_for(proposal)
|
||||
end
|
||||
|
||||
it 'is not executed when pending administrator task' do
|
||||
proposal = create(:proposal)
|
||||
action = create(:dashboard_action, :active, :admin_request, :resource)
|
||||
executed_action = create(:dashboard_executed_action, proposal: proposal, action: action)
|
||||
_task = create(:dashboard_administrator_task, :pending, source: executed_action)
|
||||
|
||||
expect(action).not_to be_executed_for(proposal)
|
||||
end
|
||||
|
||||
it 'is executed when done administrator task' do
|
||||
proposal = create(:proposal)
|
||||
action = create(:dashboard_action, :active, :admin_request, :resource)
|
||||
executed_action = create(:dashboard_executed_action, proposal: proposal, action: action)
|
||||
_task = create(:dashboard_administrator_task, :done, source: executed_action)
|
||||
|
||||
expect(action).to be_executed_for(proposal)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,15 +1,8 @@
|
||||
require 'rails_helper'
|
||||
|
||||
describe Dashboard::AdministratorTask do
|
||||
subject { build :dashboard_administrator_task, source: executed_action }
|
||||
let(:executed_action) { build :dashboard_executed_action }
|
||||
|
||||
it { should be_valid }
|
||||
|
||||
context 'when source is nil' do
|
||||
let(:executed_action) { nil }
|
||||
|
||||
it { should_not be_valid }
|
||||
it 'is invalid when source is nil' do
|
||||
task = build(:dashboard_administrator_task, source: nil)
|
||||
expect(task).not_to be_valid
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@@ -1,49 +1,29 @@
|
||||
require 'rails_helper'
|
||||
|
||||
describe Dashboard::ExecutedAction do
|
||||
subject do
|
||||
build :dashboard_executed_action,
|
||||
proposal: proposal,
|
||||
action: action,
|
||||
executed_at: executed_at
|
||||
end
|
||||
|
||||
let(:proposal) { create :proposal }
|
||||
let(:action) do
|
||||
create :dashboard_action, request_to_administrators: request_to_administrators, link: Faker::Internet.url
|
||||
end
|
||||
let(:request_to_administrators) { false }
|
||||
let(:executed_at) { Time.current }
|
||||
|
||||
it { should be_valid }
|
||||
|
||||
context 'when proposal is nil' do
|
||||
let(:proposal) { nil }
|
||||
|
||||
it { should_not be_valid }
|
||||
create :dashboard_action, request_to_administrators: true, link: Faker::Internet.url
|
||||
end
|
||||
|
||||
context 'when action is nil' do
|
||||
let(:action) { nil }
|
||||
|
||||
it { should_not be_valid }
|
||||
it 'is invalid when proposal is nil' do
|
||||
action = build(:dashboard_executed_action, proposal: nil)
|
||||
expect(action).not_to be_valid
|
||||
end
|
||||
|
||||
context 'when executed_at is nil' do
|
||||
let(:executed_at) { nil }
|
||||
|
||||
it { should_not be_valid }
|
||||
it 'is invalid when action is nil' do
|
||||
action = build(:dashboard_executed_action, action: nil)
|
||||
expect(action).not_to be_valid
|
||||
end
|
||||
|
||||
context 'when the action sends a request to the administrators' do
|
||||
let(:request_to_administrators) { true }
|
||||
|
||||
it { should be_valid }
|
||||
it 'is invalid when executed_at is nil' do
|
||||
action = build(:dashboard_executed_action, executed_at: nil)
|
||||
expect(action).not_to be_valid
|
||||
end
|
||||
|
||||
context 'when it has been already executed' do
|
||||
let!(:executed) { create(:dashboard_executed_action, proposal: proposal, action: action) }
|
||||
|
||||
it { should_not be_valid }
|
||||
it 'when action has been already executed it is invalid' do
|
||||
_executed = create(:dashboard_executed_action, proposal: proposal, action: action)
|
||||
action = build(:dashboard_executed_action, proposal: proposal, action: action)
|
||||
expect(action).not_to be_valid
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,29 +1,15 @@
|
||||
require 'rails_helper'
|
||||
|
||||
describe Link do
|
||||
subject do
|
||||
build :link,
|
||||
linkable: dashboard_action,
|
||||
label: label,
|
||||
url: url,
|
||||
open_in_new_tab: true
|
||||
let(:action) { build :dashboard_action }
|
||||
|
||||
it 'is invalid when label is blank' do
|
||||
link = build(:link, linkable: action, label: '')
|
||||
expect(link).not_to be_valid
|
||||
end
|
||||
|
||||
let(:dashboard_action) { build :dashboard_action }
|
||||
let(:label) { Faker::Lorem.sentence }
|
||||
let(:url) { Faker::Internet.url }
|
||||
|
||||
it { should be_valid }
|
||||
|
||||
context 'when label is blank' do
|
||||
let(:label) { '' }
|
||||
|
||||
it { should_not be_valid }
|
||||
end
|
||||
|
||||
context 'when url is blank' do
|
||||
let(:url) { '' }
|
||||
|
||||
it { should_not be_valid }
|
||||
it 'is invalid when url is blank' do
|
||||
link = build(:link, linkable: action, url: '')
|
||||
expect(link).not_to be_valid
|
||||
end
|
||||
end
|
||||
|
||||
51
spec/requests/dashboard/achievements_spec.rb
Normal file
51
spec/requests/dashboard/achievements_spec.rb
Normal file
@@ -0,0 +1,51 @@
|
||||
require 'rails_helper'
|
||||
|
||||
describe "Retrieves achievements for a proposal" do
|
||||
let(:created_at) { DateTime.parse("2018-01-01 12:00:00") }
|
||||
let(:proposal) { create(:proposal, created_at: created_at) }
|
||||
let(:executed_actions) { create_list(:dashboard_action, 8, :active, :proposed_action) }
|
||||
let!(:non_executed_actions) { create_list(:dashboard_action, 8, :active, :proposed_action) }
|
||||
|
||||
before do
|
||||
sign_in(proposal.author)
|
||||
|
||||
executed_actions.each_with_index do |action, index|
|
||||
create(:dashboard_executed_action, proposal: proposal, action: action, executed_at: proposal.created_at + index.days)
|
||||
end
|
||||
end
|
||||
|
||||
it "returns a list of most recent executed achievements grouped by day" do
|
||||
get proposal_dashboard_achievements_path(proposal, format: :json)
|
||||
|
||||
json = JSON.parse(response.body, symbolize_names: true)
|
||||
|
||||
expect(response).to have_http_status(200)
|
||||
expect(json.length).to eq(8)
|
||||
|
||||
executed_actions.each do |action|
|
||||
expect(json.values.select { |a| a[:title] == action.title }).not_to be_empty
|
||||
end
|
||||
|
||||
non_executed_actions.each do |action|
|
||||
expect(json.values.select { |a| a[:title] == action.title }).to be_empty
|
||||
end
|
||||
end
|
||||
|
||||
it "returns a list of most recent executed achievements grouped by week" do
|
||||
get proposal_dashboard_achievements_path(proposal, group_by: 'week', format: :json)
|
||||
|
||||
json = JSON.parse(response.body, symbolize_names: true)
|
||||
|
||||
expect(response).to have_http_status(200)
|
||||
expect(json.length).to eq(2)
|
||||
end
|
||||
|
||||
it "returns a list of most recent executed achievements grouped by month" do
|
||||
get proposal_dashboard_achievements_path(proposal, group_by: 'month', format: :json)
|
||||
|
||||
json = JSON.parse(response.body, symbolize_names: true)
|
||||
|
||||
expect(response).to have_http_status(200)
|
||||
expect(json.length).to eq(1)
|
||||
end
|
||||
end
|
||||
58
spec/requests/dashboard/successful_supports_spec.rb
Normal file
58
spec/requests/dashboard/successful_supports_spec.rb
Normal file
@@ -0,0 +1,58 @@
|
||||
require 'rails_helper'
|
||||
|
||||
describe "Retrieves number of supports for the successful proposal" do
|
||||
let(:created_at) { DateTime.parse("2018-01-01 12:00:00") }
|
||||
let(:proposal) { create(:proposal, created_at: created_at) }
|
||||
|
||||
before do
|
||||
@successful_proposal_id = Setting['proposals.successful_proposal_id']
|
||||
Setting['proposals.successful_proposal_id'] = proposal.id
|
||||
|
||||
8.times do |i|
|
||||
user = create(:user, :verified)
|
||||
Vote.create!(
|
||||
votable: proposal,
|
||||
voter: user,
|
||||
vote_weight: 1,
|
||||
created_at: proposal.created_at + i.days,
|
||||
updated_at: proposal.created_at + i.days
|
||||
)
|
||||
end
|
||||
|
||||
sign_in(proposal.author)
|
||||
end
|
||||
|
||||
after do
|
||||
Setting['proposals.successful_proposal_id'] = @successful_proposal_id
|
||||
end
|
||||
|
||||
it "returns the number of supports grouped by day" do
|
||||
get proposal_dashboard_successful_supports_path(proposal, format: :json)
|
||||
|
||||
json = JSON.parse(response.body, symbolize_names: true)
|
||||
|
||||
expect(response).to have_http_status(200)
|
||||
expect(json.length).to eq(8)
|
||||
expect(json.values.last).to eq(8)
|
||||
end
|
||||
|
||||
it "returns the number of supports grouped by week" do
|
||||
get proposal_dashboard_successful_supports_path(proposal, group_by: 'week', format: :json)
|
||||
|
||||
json = JSON.parse(response.body, symbolize_names: true)
|
||||
|
||||
expect(response).to have_http_status(200)
|
||||
expect(json.length).to eq(2)
|
||||
expect(json.values.last).to eq(8)
|
||||
end
|
||||
|
||||
it "returns the number of supports grouped by month" do
|
||||
get proposal_dashboard_successful_supports_path(proposal, group_by: 'month', format: :json)
|
||||
|
||||
json = JSON.parse(response.body, symbolize_names: true)
|
||||
|
||||
expect(response).to have_http_status(200)
|
||||
expect(json.length).to eq(1)
|
||||
expect(json.values.last).to eq(8)
|
||||
end
|
||||
end
|
||||
45
spec/requests/dashboard/supports_spec.rb
Normal file
45
spec/requests/dashboard/supports_spec.rb
Normal file
@@ -0,0 +1,45 @@
|
||||
require 'rails_helper'
|
||||
|
||||
describe "Retrieves number of supports for a proposal" do
|
||||
let(:created_at) { DateTime.parse("2018-01-01 12:00:00") }
|
||||
let(:proposal) { create(:proposal, created_at: created_at) }
|
||||
|
||||
before do
|
||||
8.times do |i|
|
||||
user = create(:user, :verified)
|
||||
Vote.create!(votable: proposal, voter: user, vote_weight: 1, created_at: proposal.created_at + i.days, updated_at: proposal.created_at + i.days)
|
||||
end
|
||||
|
||||
sign_in(proposal.author)
|
||||
end
|
||||
|
||||
it "returns the number of supports grouped by day" do
|
||||
get proposal_dashboard_supports_path(proposal, format: :json)
|
||||
|
||||
json = JSON.parse(response.body, symbolize_names: true)
|
||||
|
||||
expect(response).to have_http_status(200)
|
||||
expect(json.length).to eq(8)
|
||||
expect(json.values.last).to eq(8)
|
||||
end
|
||||
|
||||
it "returns the number of supports grouped by week" do
|
||||
get proposal_dashboard_supports_path(proposal, group_by: 'week', format: :json)
|
||||
|
||||
json = JSON.parse(response.body, symbolize_names: true)
|
||||
|
||||
expect(response).to have_http_status(200)
|
||||
expect(json.length).to eq(2)
|
||||
expect(json.values.last).to eq(8)
|
||||
end
|
||||
|
||||
it "returns the number of supports grouped by month" do
|
||||
get proposal_dashboard_supports_path(proposal, group_by: 'month', format: :json)
|
||||
|
||||
json = JSON.parse(response.body, symbolize_names: true)
|
||||
|
||||
expect(response).to have_http_status(200)
|
||||
expect(json.length).to eq(1)
|
||||
expect(json.values.last).to eq(8)
|
||||
end
|
||||
end
|
||||
22
spec/shared/request_spec_helper.rb
Normal file
22
spec/shared/request_spec_helper.rb
Normal file
@@ -0,0 +1,22 @@
|
||||
module RequestSpecHelper
|
||||
include Warden::Test::Helpers
|
||||
|
||||
def self.included(base)
|
||||
base.before(:each) { Warden.test_mode! }
|
||||
base.after(:each) { Warden.test_reset! }
|
||||
end
|
||||
|
||||
def sign_in(resource)
|
||||
login_as(resource, scope: warden_scope(resource))
|
||||
end
|
||||
|
||||
def sign_out(resource)
|
||||
logout(warden_scope(resource))
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def warden_scope(resource)
|
||||
resource.class.name.underscore.to_sym
|
||||
end
|
||||
end
|
||||
@@ -14,6 +14,7 @@ RSpec.configure do |config|
|
||||
config.filter_run :focus
|
||||
config.run_all_when_everything_filtered = true
|
||||
config.include Devise::TestHelpers, type: :controller
|
||||
config.include RequestSpecHelper, type: :request
|
||||
config.include FactoryBot::Syntax::Methods
|
||||
config.include(EmailSpec::Helpers)
|
||||
config.include(EmailSpec::Matchers)
|
||||
|
||||
Reference in New Issue
Block a user