Merge branch 'master' into api-dev

This commit is contained in:
Alberto Miedes Garcés
2016-11-18 16:40:33 +01:00
118 changed files with 516 additions and 510 deletions

View File

@@ -34,6 +34,16 @@ If you want to contribute code to solve an issue:
* Follow these [best practices](https://github.com/styleguide/ruby)
* Open a *pull request* to the main repository describing what issue you are addressing.
## Cleaning up
In the rush of time sometimes things get messy, you can help us cleaning things up:
* implement [pending specs](https://travis-ci.org/consul/consul)
* increase [code coverage](https://coveralls.io/github/consul/consul?branch=master)
* improve [code quality](https://codeclimate.com/github/consul/consul)
* update [dependencies](https://gemnasium.com/consul/consul)
* make [code consistent](https://github.com/bbatsov/rubocop)
## Other ways of contributing without coding
* If you think there's a feature missing, or find a bug, create an issue (make sure it has not already been reported).

View File

@@ -34,6 +34,16 @@ Cuando quieras resolver una incidencia mediante código:
* Sigue estas [buenas prácticas](https://github.com/styleguide/ruby)
* Envía una *pull request* al repositorio principal indicando la incidencia que se está arreglando
## Limpiar
En la urgencia del momento, las cosas a veces se ensucian, puedes ayudarnos a limpiar la casa:
* implementando [tests pendientes](https://travis-ci.org/consul/consul)
* incrementando la [cobertura de tests](https://coveralls.io/github/consul/consul?branch=master)
* mejorando la [calidad del código](https://codeclimate.com/github/consul/consul)
* actualizando [dependecias](https://gemnasium.com/consul/consul)
* haciendo el [código consistente](https://github.com/bbatsov/rubocop)
## Otras formas de contribuir sin código
* Si crees que hay una funcionalidad que hace falta, o descubres un problema, abre una incidencia (asegúrate de que

View File

@@ -88,6 +88,7 @@ group :development, :test do
gem 'capistrano3-delayed-job', '~> 1.0'
gem "bullet"
gem "faker"
gem 'rubocop', '~> 0.45.0', require: false
end
group :test do

View File

@@ -59,7 +59,7 @@ GEM
ancestry (2.2.1)
activerecord (>= 3.0.0)
arel (6.0.3)
ast (2.2.0)
ast (2.3.0)
babel-source (5.8.35)
babel-transpiler (0.7.0)
babel-source (>= 4.0, < 6)
@@ -274,7 +274,7 @@ GEM
orm_adapter (0.5.0)
paranoia (2.2.0)
activerecord (>= 4.0, < 5.1)
parser (2.3.0.6)
parser (2.3.1.4)
ast (~> 2.2)
pg (0.19.0)
pg_search (1.0.6)
@@ -285,6 +285,7 @@ GEM
capybara (~> 2.1)
cliver (~> 0.3.1)
websocket-driver (>= 0.2.0)
powerpack (0.1.1)
quiet_assets (1.1.0)
railties (>= 3.1, < 5.0)
rack (1.6.4)
@@ -318,6 +319,7 @@ GEM
activesupport (= 4.2.7.1)
rake (>= 0.8.7)
thor (>= 0.18.1, < 2.0)
rainbow (2.1.0)
raindrops (0.16.0)
rake (11.3.0)
redcarpet (3.3.4)
@@ -349,6 +351,12 @@ GEM
rspec-mocks (~> 3.5.0)
rspec-support (~> 3.5.0)
rspec-support (3.5.0)
rubocop (0.45.0)
parser (>= 2.3.1.1, < 3.0)
powerpack (~> 0.1)
rainbow (>= 1.99.1, < 3.0)
ruby-progressbar (~> 1.7)
unicode-display_width (~> 1.0, >= 1.0.1)
ruby-progressbar (1.8.1)
safe_yaml (1.0.4)
safely_block (0.1.1)
@@ -415,6 +423,7 @@ GEM
thread_safe (~> 0.1)
uglifier (3.0.3)
execjs (>= 0.3.0, < 3)
unicode-display_width (1.1.1)
unicorn (5.1.0)
kgio (~> 2.6)
raindrops (~> 0.7)
@@ -499,6 +508,7 @@ DEPENDENCIES
rinku (~> 2.0.2)
rollbar (~> 2.13.3)
rspec-rails (~> 3.5)
rubocop (~> 0.45.0)
sass-rails (~> 5.0, >= 5.0.4)
savon
social-share-button

View File

@@ -45,6 +45,7 @@
//= require valuation_spending_proposal_form
//= require embed_video
//= require banners
//= require social_share
//= require custom
var initialize_modules = function() {
@@ -66,6 +67,7 @@ var initialize_modules = function() {
App.ValuationSpendingProposalForm.initialize();
App.EmbedVideo.initialize();
App.Banners.initialize();
App.SocialShare.initialize();
};
$(function(){

View File

@@ -0,0 +1,7 @@
App.SocialShare =
initialize: ->
$(".social-share-button a").each ->
element = $(this)
site = element.data('site')
element.append("<span class='sr-only'>#{site}</span>")

View File

@@ -51,6 +51,7 @@ $base-font-size: rem-calc(17);
$base-line: rem-calc(26);
$small-font-size: rem-calc(14);
$line-height: rem-calc(24);
$tiny-font-size: rem-calc(12);
$brand: #004A83;
$dark: darken($brand, 10%);
@@ -66,7 +67,6 @@ $link-hover: darken($link, 20%);
$debates: #008CCF;
$votes: #26AEEE;
$like: #7BD2A8;
$unlike: #EF8585;
@@ -79,7 +79,7 @@ $budget: #454372;
$budget-hover: #7571BF;
$highlight: #E7F2FC;
$featured: #FED900;
$featured: #FFDC5C;
$footer-border: #BFC1C3;

View File

@@ -475,10 +475,18 @@ header {
&.active {
border-bottom: 2px solid $brand;
color: $brand;
&:hover {
text-decoration: none;
}
}
}
h2 {
font-size: $base-font-size;
}
}
.search-form-header input[type=text] {
max-width: none;
}
@@ -1247,13 +1255,14 @@ table {
}
.share-supported {
text-align: center;
.social-share-button {
display: inline-block;
}
.ssb-twitter {
background: none;
background: #45B0E3;
color: white;
height: $line-height;
position: relative;
@@ -1276,7 +1285,7 @@ table {
}
.ssb-facebook {
background: none;
background: #3B5998;
color: white;
height: rem-calc(24);
position: relative;
@@ -1299,7 +1308,7 @@ table {
}
.ssb-google_plus {
background: none;
background: #DE4C34;
color: white;
height: rem-calc(24);
position: relative;
@@ -1550,7 +1559,7 @@ table {
.comment-votes {
color: $text-medium;
font-size: rem-calc(14);
font-size: $small-font-size;
line-height: $line-height;
a {
@@ -1560,12 +1569,21 @@ table {
&:hover {
color: $text-medium;
text-decoration: none;
.icon-like {
color: $like;
}
.icon-unlike {
color: $unlike;
}
}
}
[class^="icon-"] {
font-size: rem-calc(20);
vertical-align: middle;
font-size: $base-font-size;
vertical-align: sub;
}
}
@@ -1685,7 +1703,8 @@ table {
}
.flag-disable, .flag-active {
vertical-align: middle;
line-height: 0;
vertical-align: sub;
}
.flag-disable {

View File

@@ -12,14 +12,21 @@
// ----------------------
@mixin votes {
background: $votes;
margin: 0 rem-calc(-12);
padding: rem-calc(14) rem-calc(12);
border-top: 1px solid $border;
margin-top: $line-height;
padding: $line-height 0;
position: relative;
@include breakpoint(medium) {
border-left: 1px solid $border;
border-top: 0;
margin-top: 0;
padding-top: $line-height*2;
}
.icon-like, .icon-unlike {
background: white;
border: 2px solid $votes;
border: 2px solid $text-light;
border-radius: rem-calc(3);
color: $text-light;
display: inline-block;
@@ -29,7 +36,6 @@
position: relative;
&:hover, &:active {
border-color: white;
color: white;
cursor: pointer;
opacity: 1 !important;
@@ -40,6 +46,7 @@
&:hover, &:active {
background: $like;
border: 2px solid $like;
}
}
@@ -47,50 +54,64 @@
&:hover, &:active {
background: $unlike;
border: 2px solid $unlike;
}
}
.like, .unlike {
line-height: rem-calc(48);
vertical-align: super;
text-decoration: none;
span.percentage {
color: white;
color: $text;
display: inline-block;
font-size: rem-calc(16);
font-size: $small-font-size;
line-height: $line-height*2;
padding-left: rem-calc(8);
padding-right: $line-height/2;
vertical-align: top;
@include breakpoint(medium) {
display: block;
line-height: $line-height;
padding-right: 0;
}
}
}
.voted {
.icon-like, .icon-unlike {
border-color: white;
color: white;
}
.icon-like {
background: $like;
border: 2px solid $like;
}
.icon-unlike {
background: $unlike;
border: 2px solid $unlike;
}
}
.no-voted {
.icon-like, .icon-unlike {
opacity: .5;
opacity: .3;
}
}
.total-votes {
color: white;
font-weight: bold;
float: right;
line-height: $line-height*2;
@include breakpoint(medium) {
display: block;
float: none;
}
}
.divider {
@@ -99,64 +120,65 @@
}
@mixin supports {
background: $proposals;
margin: 0 rem-calc(-12);
padding: rem-calc(14) rem-calc(12);
padding: $line-height 0;
position: relative;
.progress {
background-color: rgba(255,255,255,.8);
height: $line-height/2;
background: lighten($proposals, 35%);
border: 1px solid lighten($proposals, 35%);
height: rem-calc(14);
position: relative;
.meter {
background: $like;
background: $proposals;
border-radius: 0;
border-bottom-right-radius: rem-calc(3);
border-top-right-radius: rem-calc(3);
display: block;
height: $line-height/2;
}
}
.percentage {
font-size: rem-calc(10);
color: $brand;
vertical-align: top;
color: $text;
font-size: $tiny-font-size;
position: absolute;
top: 13px;
right: 20px;
right: 6px;
top: -2px;
vertical-align: top;
}
abbr {
color: white;
color: $text-medium;
&[title] {
border-bottom: 1px dotted white;
border-bottom: 1px dotted $text-medium;
}
}
.button-support {
background: white;
background: $proposals;
color: $text;
display: inline-block;
font-size: $small-font-size;
margin-top: rem-calc(12);
&:hover {
background: darken($proposals, 35%);
color: white;
&:hover, &:active {
background: lighten($proposals, 25%);
cursor: pointer;
}
&:active {
opacity: .75;
}
}
.total-supports {
color: white;
color: $text;
display: block;
font-weight: bold;
text-align: center;
font-size: $small-font-size;
span {
display: block;
font-size: $small-font-size;
font-weight: normal;
}
}
@@ -165,23 +187,17 @@
}
.supported {
color: white;
color: $text;
margin-top: rem-calc(12);
}
}
.message {
@include supports;
background: none;
border-top: 0;
.supports-container {
border-top: 1px solid $border;
@include breakpoint(medium) {
border-left: 1px solid $border;
margin: $line-height rem-calc(-25) 0 rem-calc(12);
}
p {
font-size: $small-font-size;
border-top: 0;
}
}
@@ -276,7 +292,9 @@
// 03. Show participation
// ----------------------
.debate-show, .proposal-show, .investment-project-show {
.debate-show,
.proposal-show,
.investment-project-show {
p {
word-wrap: break-word;
@@ -413,47 +431,8 @@
}
}
.votes {
@include votes;
border: 0;
border-radius: 0;
margin: 0;
.total-votes {
display: block;
float: none;
line-height: $line-height;
}
@include breakpoint(small + rem-calc(1) and medium down) {
.in-favor, .against {
text-align: left;
width: rem-calc(100);
}
}
.divider {
display: none;
}
@include breakpoint(medium) {
.divider {
display: inline-block;
}
}
}
.supports {
@include supports;
border: 0;
border-radius: 0;
margin: 0;
.total-supports {
display: block;
float: none;
line-height: $line-height;
}
}
.leave-comment {
@@ -478,6 +457,17 @@
word-break: break-word;
}
.proposal-show, .investment-project-show {
.supports {
padding: $line-height/2 0 0;
}
.share-supported {
display: none;
}
}
// 04. List participation
// ----------------------
@@ -496,8 +486,7 @@
}
.debate, .proposal, .investment-project {
margin-bottom: 0;
margin-top: 0;
margin: $line-height/4 0;
.panel {
background: white;
@@ -651,107 +640,30 @@
}
}
.debate {
.debate, .debate-show {
.votes {
@include votes;
border: 1px solid $votes;
margin: 0 rem-calc(-12);
@include breakpoint(medium) {
border-top-left-radius: 3px;
border-bottom-left-radius: 3px;
margin: 0 rem-calc(-25) 0 rem-calc(12);
}
&:after {
content: none;
position: absolute;
display: block;
border-style: solid;
border-color: #166387 transparent transparent transparent;
bottom: -14px;
border-left-width: 0;
border-right-color: transparent;
right: -1px;
border-width: 13px 13px 0 0;
@include breakpoint(medium) {
content: "";
}
}
.total-votes {
display: inline-block;
line-height: $line-height;
margin-left: rem-calc(24);
padding-top: rem-calc(12);
vertical-align: top;
@include breakpoint(medium) {
display: block;
float: none;
line-height: $line-height*2;
margin-left: 0;
padding-top: 0;
}
.against {
margin-left: $line-height/4;
}
@include breakpoint(medium) {
.like, .unlike {
text-align: center;
}
}
}
span.percentage {
display: block;
line-height: $line-height/2;
}
}
}
}
.debate-show .votes {
border: 0;
padding: $line-height/2 0;
}
.proposal {
.supports {
@include supports;
border: 1px solid $proposals;
margin: 0 rem-calc(-12);
@include breakpoint(medium) {
border-top-left-radius: 3px;
border-bottom-left-radius: 3px;
margin: 0 rem-calc(-25) 0 rem-calc(12);
}
&:after {
content: none;
position: absolute;
display: block;
border-style: solid;
border-color: #664212 transparent transparent transparent;
bottom: -14px;
border-left-width: 0;
border-right-color: transparent;
right: -1px;
border-width: 13px 13px 0 0;
@include breakpoint(medium) {
content: "";
}
}
.total-supports {
display: inline-block;
line-height: $line-height;
padding-top: rem-calc(12);
vertical-align: top;
@include breakpoint(medium) {
display: block;
float: none;
margin-left: 0;
padding-top: 0;
}
}
}
}
@@ -759,20 +671,6 @@
.supports {
@include supports;
background: none;
border: 0;
border-left: 1px solid $border;
margin: 0 rem-calc(-12);
min-height: rem-calc(180);
padding-top: 0;
@include breakpoint(medium) {
padding-top: $line-height*1.5;
}
&:after {
content: none;
}
.investment-project-amount {
color: $budget;
@@ -802,32 +700,13 @@
font-weight: bold;
}
.supported {
color: $budget;
margin-top: 0;
width: 100%;
}
.remove .icon-check-circle {
display: block;
font-size: rem-calc(70);
line-height: rem-calc(70);
}
.share-supported {
.ssb-twitter,
.ssb-facebook,
.ssb-google_plus {
color: $budget;
}
}
}
}
.investment-project-show .supports {
border: 0;
}
.proposals-summary {
@@ -903,7 +782,14 @@
}
.button-support {
background: $text;
color: $featured;
margin-top: 0;
&:hover {
background: white;
color: $text;
}
}
.participation-not-allowed {
@@ -924,6 +810,7 @@
.supported {
margin-top: 0;
font-size: $small-font-size;
}
.share-supported {
@@ -931,7 +818,10 @@
.ssb-twitter,
.ssb-facebook,
.ssb-google_plus {
height: rem-calc(33);
background: none;
color: $text;
height: rem-calc(33) !important;
&:before {
font-size: rem-calc(18);

View File

@@ -38,6 +38,7 @@ class Admin::BannersController < Admin::BaseController
end
private
def banner_params
params.require(:banner).permit(:title, :description, :target_url, :style, :image, :post_started_at, :post_ended_at)
end
@@ -53,4 +54,5 @@ class Admin::BannersController < Admin::BaseController
def banner_imgs
@banner_imgs = Setting.all.banner_img.map { |banner_img| [banner_img.value, banner_img.key.split('.')[1]] }
end
end

View File

@@ -20,6 +20,7 @@ class Admin::CommentsController < Admin::BaseController
end
private
def load_comment
@comment = Comment.with_hidden.find(params[:id])
end

View File

@@ -25,6 +25,7 @@ class Admin::OfficialsController < Admin::BaseController
end
private
def user_params
params.require(:user).permit(:official_position, :official_level)
end

View File

@@ -15,7 +15,9 @@ class Admin::SettingsController < Admin::BaseController
end
private
def settings_params
params.require(:setting).permit(:value)
end
end

View File

@@ -32,4 +32,5 @@ class Admin::StatsController < Admin::BaseController
@direct_messages = DirectMessage.count
@users_who_have_sent_message = DirectMessage.select(:sender_id).distinct.count
end
end

View File

@@ -30,8 +30,10 @@ class Admin::ValuatorsController < Admin::BaseController
end
private
def create_params
params[:valuator][:description] = nil if params[:valuator][:description].blank?
params.require(:valuator).permit(:user_id, :description)
end
end

View File

@@ -1,6 +1,7 @@
module Polymorphic
private
def resource
@resource ||= instance_variable_get("@#{resource_name}")
end

View File

@@ -6,6 +6,7 @@ class Management::AccountController < Management::BaseController
end
private
def only_verified_users
check_verified_user t("management.account.alert.unverified_user")
end

View File

@@ -24,6 +24,7 @@ class Organizations::RegistrationsController < Devise::RegistrationsController
end
protected
def after_inactive_sign_up_path_for(resource)
organizations_sign_up_success_path
end

View File

@@ -56,5 +56,4 @@ class Verification::LetterController < ApplicationController
end
end
end

View File

@@ -9,6 +9,7 @@ class Verification::VerifiedUserController < ApplicationController
end
private
def user_data_present?
return false if @verified_users.blank?

View File

@@ -16,5 +16,4 @@ class WelcomeController < ApplicationController
redirect_to verification_path if signed_in?
end
end

View File

@@ -1,5 +1,7 @@
module BannersHelper
def has_banners
@banners.count > 0
end
end

View File

@@ -39,4 +39,5 @@ module CommentsHelper
"" # Default not author class
end
end
end

View File

@@ -3,4 +3,5 @@ module DebatesHelper
def has_featured?
Debate.all.featured.count > 0
end
end

View File

@@ -9,15 +9,15 @@ module EmbedVideosHelper
end
if server == "Vimeo"
regExp = /vimeo.*(staffpicks\/|channels\/|videos\/|video\/|\/)([^#\&\?]*).*/
reg_exp = /vimeo.*(staffpicks\/|channels\/|videos\/|video\/|\/)([^#\&\?]*).*/
src = "https://player.vimeo.com/video/"
elsif server == "YouTube"
regExp = /youtu.*(be\/|v\/|u\/\w\/|embed\/|watch\?v=|\&v=)([^#\&\?]*).*/
reg_exp = /youtu.*(be\/|v\/|u\/\w\/|embed\/|watch\?v=|\&v=)([^#\&\?]*).*/
src = "https://www.youtube.com/embed/"
end
if regExp
match = link.match(regExp)
if reg_exp
match = link.match(reg_exp)
end
if match and match[2]

View File

@@ -1,4 +1,2 @@
module NotificationsHelper
end

View File

@@ -20,4 +20,5 @@ module StatsHelper
opt[:data][:graph] = admin_api_stats_path(spending_proposals: true)
content_tag :div, "", opt
end
end

View File

@@ -1,4 +1,5 @@
module TracksHelper
def track_event(data={})
track_data = ""
prefix = " data-track-event-"
@@ -9,4 +10,5 @@ module TracksHelper
track_data
end
end
end

View File

@@ -49,4 +49,5 @@ class Notification < ActiveRecord::Base
def linkable_resource
notifiable.is_a?(ProposalNotification) ? notifiable.proposal : notifiable
end
end

View File

@@ -246,6 +246,7 @@ class User < ActiveRecord::Base
delegate :can?, :cannot?, to: :ability
private
def clean_document_number
self.document_number = self.document_number.gsub(/[^a-z0-9]+/i, "").upcase unless self.document_number.blank?
end

View File

@@ -6,13 +6,17 @@
<span class="in_favor">
<% if can?(:vote, comment) %>
<%= link_to vote_comment_path(comment, value: 'yes'),
method: "post", remote: true do %>
<span class="icon-angle-up">
method: "post", remote: true, title: t('votes.agree') do %>
<span class="icon-like">
<span class="sr-only"><%= t('votes.agree') %></span>
</span>
<% end %>
<% else %>
<span class="icon-angle-up"></span>
<%= link_to new_user_session_path do %>
<span class="icon-like">
<span class="sr-only"><%= t('votes.agree') %></span>
</span>
<% end %>
<% end %>
<%= comment.total_likes %>
</span>
@@ -20,13 +24,15 @@
<span class="against">
<% if can?(:vote, comment) %>
<%= link_to vote_comment_path(comment, value: 'no'),
method: "post", remote: true do %>
<span class="icon-angle-down">
method: "post", remote: true, title: t('votes.disagree') do %>
<span class="icon-unlike">
<span class="sr-only"><%= t('votes.disagree') %></span>
</span>
<% end %>
<% else %>
<span class="icon-angle-down"></span>
<span class="icon-unlike">
<span class="sr-only"><%= t('votes.disagree') %></span>
</span>
<% end %>
<%= comment.total_dislikes %>
</span>
@@ -40,26 +46,40 @@
<span class="in_favor">
<% if can?(:vote, comment) %>
<%= link_to vote_comment_path(comment, value: 'yes'),
method: "post", remote: true do %>
<span class="icon-angle-up"></span>
method: "post", remote: true, title: t('votes.agree') do %>
<span class="icon-like">
<span class="sr-only"><%= t('votes.agree') %></span>
</span>
<% end %>
<% else %>
<span class="icon-angle-up"></span>
<%= link_to new_user_session_path do %>
<span class="icon-like">
<span class="sr-only"><%= t('votes.agree') %></span>
</span>
<% end %>
<% end %>
<%= comment.total_likes %>
</span>
<span class="against">
<% if can?(:vote, comment) %>
<%= link_to vote_comment_path(comment, value: 'no'),
method: "post", remote: true do %>
<span class="icon-angle-down"></span>
method: "post", remote: true, title: t('votes.disagree') do %>
<span class="icon-unlike">
<span class="sr-only"><%= t('votes.disagree') %></span>
</span>
<% end %>
<% else %>
<span class="icon-angle-down"></span>
<%= link_to new_user_session_path do %>
<span class="icon-unlike">
<span class="sr-only"><%= t('votes.disagree') %></span>
</span>
<% end %>
<% end %>
<%= comment.total_dislikes %>
</span>
</div>
<div class="participation-not-allowed" style='display:none' aria-hidden="false">
<%= t("votes.comment_unauthenticated",
signin: link_to(t("votes.signin"), new_user_session_path),

View File

@@ -48,7 +48,7 @@
</div>
</div>
<div id="<%= dom_id(debate) %>_votes" class="small-12 medium-3 column text-center">
<div id="<%= dom_id(debate) %>_votes" class="small-12 medium-3 column">
<%= render 'debates/votes', debate: debate %>
</div>

View File

@@ -6,6 +6,8 @@
<% end %>
<main>
<h1 class="sr-only"><%= t("shared.outline.debates") %></h1>
<div class="row">
<div id="debates" class="debates-list small-12 medium-9 column">

View File

@@ -45,11 +45,9 @@
<aside class="small-12 medium-3 column">
<div class="sidebar-divider"></div>
<h3><%= t("votes.supports") %></h3>
<div class="text-center">
<div id="<%= dom_id(@debate) %>_votes">
<%= render 'debates/votes', debate: @debate %>
</div>
</div>
<div class="sidebar-divider"></div>
<h3><%= t("debates.show.share") %></h3>
<div class="social-share-full">

View File

@@ -1,6 +1,7 @@
<%= paginator.render do -%>
<div class="pagination-centered">
<nav>
<h1 class="sr-only"><%= t("shared.outline.pagination") %></h1>
<ul class="pagination text-center margin-top" aria-label="Pagination">
<%= first_page_tag unless current_page.first? %>
<%= prev_page_tag unless current_page.first? %>

View File

@@ -22,6 +22,8 @@
<%= setting['per_page_code'].try(:html_safe) %>
</head>
<body>
<h1 class="sr-only"><%= setting['org_name'] %></h1>
<div class="wrapper">
<%= render 'layouts/header' %>

View File

@@ -1,4 +1,4 @@
<div class="supports">
<div class="supports text-center">
<div class="in-favor">
<% if voted_for?(@featured_proposals_votes, proposal) %>
<div class="supported">

View File

@@ -52,26 +52,22 @@
</div>
</div>
<div id="<%= dom_id(proposal) %>_votes" class="small-12 medium-3 column">
<div id="<%= dom_id(proposal) %>_votes" class="small-12 medium-3 column supports-container">
<div class="supports text-center">
<% if proposal.successfull? %>
<div class="message">
<p>
<%= t("proposal_ballots.successfull",
voting: link_to(t("proposal_ballots.voting"), proposal_ballots_path)).html_safe %>
</p>
</div>
<% elsif proposal.archived? %>
<div class="message">
<strong><%= t("proposals.proposal.supports", count: proposal.total_votes) %></strong>
<p><%= t("proposals.proposal.archived") %></p>
</div>
<% else %>
<div class="text-center">
<%= render 'votes',
{ proposal: proposal, vote_url: vote_proposal_path(proposal, value: 'yes') } %>
</div>
<% end %>
</div>
</div>
</div>
</div>
</div>

View File

@@ -1,5 +1,3 @@
<div class="supports">
<div class="progress small-12 round">
<span class="meter" style="width: <%= progress_bar_percentage(proposal) %>%;"></span>
<span class="percentage">
@@ -18,7 +16,7 @@
<div class="in-favor">
<% if voted_for?(@proposal_votes, proposal) %>
<div class="supported">
<div class="supported callout success">
<%= t("proposals.proposal.already_supported") %>
</div>
<% else %>
@@ -56,4 +54,3 @@
<%= social_share_button_tag("#{proposal.title} #{setting['twitter_hashtag']}", url: proposal_url(proposal), via: setting['twitter_handle']) %>
</div>
<% end %>
</div>

View File

@@ -6,6 +6,8 @@
<% end %>
<main>
<h1 class="sr-only"><%= t("shared.outline.proposals") %></h1>
<div class="row">
<div id="proposals" class="proposals-list small-12 medium-9 column">

View File

@@ -102,22 +102,20 @@
<aside class="small-12 medium-3 column">
<div class="sidebar-divider"></div>
<h3><%= t("votes.supports") %></h3>
<div id="<%= dom_id(@proposal) %>_votes">
<div id="<%= dom_id(@proposal) %>_votes" class="supports text-center">
<% if @proposal.successfull? %>
<p>
<%= t("proposal_ballots.successfull",
voting: link_to(t("proposal_ballots.voting"), proposal_ballots_path)).html_safe %>
</p>
<% elsif @proposal.archived? %>
<p class="text-center">
<p>
<strong><%= t("proposals.proposal.supports", count: @proposal.total_votes) %></strong>
</p>
<p><%= t("proposals.proposal.archived") %></p>
<% else %>
<div class="text-center">
<%= render 'votes',
{ proposal: @proposal, vote_url: vote_proposal_path(@proposal, value: 'yes') } %>
</div>
<% end %>
</div>
<div id="social-share" class="sidebar-divider"></div>

View File

@@ -1,7 +1,9 @@
<section class="submenu">
<div class="submenu">
<% valid_orders.each do |order| %>
<%= link_to t("#{i18n_namespace}.orders.#{order}"),
current_path_with_query_params(order: order, page: 1),
class: order == @current_order ? 'active' : '' %>
<%= link_to current_path_with_query_params(order: order, page: 1), class: order == @current_order ? 'active' : '' do %>
<%= content_tag(order == @current_order ? :h2 : :span) do %>
<%= t("#{i18n_namespace}.orders.#{order}") %>
<% end %>
</section>
<% end %>
<% end %>
</div>

View File

@@ -1,4 +1,5 @@
<div id="search_form" class="search-form-header">
<h1 class="sr-only"><%= t("shared.outline.searcher") %></h1>
<%= form_tag search_path, method: :get do %>
<div class="input-group">
<label class="sr-only"><%= t("#{i18n_namespace}.title") %></label>

View File

@@ -1,8 +1,7 @@
<section class="top-links hide-for-small-only">
<div class="top-links hide-for-small-only">
<div class="row">
<%= render "shared/locale_switcher" %>
<div class="external-links">
<%= link_to setting['org_name'], root_path, class: ("selected" unless current_page?("/opendata")) %>&nbsp;|
<%= link_to t("layouts.header.external_link_transparency"), t("layouts.header.external_link_transparency_url") %>&nbsp;|
<%= link_to t("layouts.header.external_link_opendata"), "/opendata", class: ("selected" if current_page?("/opendata")) %>
<% if setting['blog_url'] %>
@@ -13,4 +12,4 @@
<% end %>
</div>
</div>
</section>
</div>

View File

@@ -49,7 +49,7 @@
</div>
</div>
<div id="<%= dom_id(spending_proposal) %>_votes" class="small-12 medium-3 column text-center">
<div id="<%= dom_id(spending_proposal) %>_votes" class="small-12 medium-3 column supports-container">
<%= render 'votes',
{ spending_proposal: spending_proposal, vote_url: vote_spending_proposal_path(spending_proposal, value: 'yes') } %>
</div>

View File

@@ -1,4 +1,4 @@
<div class="supports">
<div class="supports text-center">
<% reason = spending_proposal.reason_for_not_being_votable_by(current_user) %>
<% voting_allowed = true unless reason.presence == :not_voting_allowed %>
@@ -10,7 +10,7 @@
<div class="in-favor">
<% if user_voted_for %>
<div class="supported">
<div class="supported callout success">
<%= t("spending_proposals.spending_proposal.already_supported") %>
</div>
<% elsif voting_allowed %>

View File

@@ -6,6 +6,8 @@
<% end %>
<main>
<h1 class="sr-only"><%= t("shared.outline.budget") %></h1>
<div class="row">
<div id="investment-projects" class="investment-projects-list small-12 medium-9 column">

View File

@@ -343,7 +343,7 @@ en:
other: "%{count} comments"
zero: No comments
proposal: Proposal
reason_for_supports_necessary: 2% of Census
reason_for_supports_necessary: 1% of Census
support: Support
support_title: Support this proposal
supports:
@@ -449,6 +449,12 @@ en:
categories: "Categories"
target_blank_html: " (link opens in new window)"
unflag: Unflag
outline:
debates: Debates
proposals: Proposals
budget: Participatory budget
pagination: Pagination
searcher: Searcher
social:
blog: Blog
facebook: Facebook

View File

@@ -343,7 +343,7 @@ es:
other: "%{count} Comentarios"
zero: Sin comentarios
proposal: Propuesta
reason_for_supports_necessary: 2% del Censo
reason_for_supports_necessary: 1% del Censo
support: Apoyar
support_title: Apoyar esta propuesta
supports:
@@ -449,6 +449,12 @@ es:
categories: "Categorías"
target_blank_html: " (se abre en ventana nueva)"
unflag: Deshacer denuncia
outline:
debates: Debates
proposals: Propuestas
budget: Presupuestos ciudadanos
pagination: Paginación
searcher: Buscador
social:
blog: Blog
facebook: Facebook

View File

@@ -1316,7 +1316,7 @@ fr:
other: "%{count} commentaires"
zero: Aucun commentaire
proposal: Proposition
reason_for_supports_necessary: 2% du Recensement
reason_for_supports_necessary: 1% du Recensement
support: Soutenir
supports:
one: 1 soutien

View File

@@ -39,7 +39,7 @@ en:
The proposals can be supported by every citizen registered that has verified their account in the participation platform. In this way, the citizenship, and not someone in its name, will decide which are the proposals that are worthwhile to carry out.
One that the proposal has achive support of 2% census, it will be studied by a city council group and to move beyond the popular referendum phase, in which citizenship will vote if it is carried out or not. The maximum period to obtain support enough is 12 months.
One that the proposal has achive support of 1% census, it will be studied by a city council group and to move beyond the popular referendum phase, in which citizenship will vote if it is carried out or not. The maximum period to obtain support enough is 12 months.
how_to_use:
text: |-
Use it in your local government or help us to improve it, it is free software.

View File

@@ -39,7 +39,7 @@ es:
Las propuestas pueden ser apoyadas por ciudadanos empadronados que hayan verificado su cuenta en la plataforma de participación, de tal manera que será la propia ciudadanía, y nadie en su nombre, la que decida cuáles son las propuestas que merecen la pena ser llevadas a cabo.
Una vez que una propuesta alcance una cantidad de apoyos equivalente al 2% del censo, automáticamente pasa a ser estudiada por un grupo de trabajo del Ayuntamiento y pasará a la siguiente fase de consulta popular, en la que la ciudadanía votará si se lleva a cabo o no. El plazo máximo para recabar los apoyos necesarios será de 12 meses.
Una vez que una propuesta alcance una cantidad de apoyos equivalente al 1% del censo, automáticamente pasa a ser estudiada por un grupo de trabajo del Ayuntamiento y pasará a la siguiente fase de consulta popular, en la que la ciudadanía votará si se lleva a cabo o no. El plazo máximo para recabar los apoyos necesarios será de 12 meses.
how_to_use:
text: |-
Utilízalo en tu municipio libremente o ayúdanos a mejorarlo, es software libre.

View File

@@ -1214,8 +1214,8 @@ pt-BR:
podem ser apoiadas por todos os cidadãos registrados em Madrid que verificaram
a sua conta na plataforma de participação. Desta forma, a cidadania e não
alguém em seu nome, irá decidir quais são as propostas que valem a pena
levar a cabo.\r\n\r\nAssim que a proposta atingir o apoio de 2% Madrid recenseada
(cerca de 53.000 pessoas), será estudado por um grupo conselheiro da cidade,
levar a cabo.\r\n\r\nAssim que a proposta atingir o apoio de 1% Madrid recenseada
(cerca de 28.000 pessoas), será estudado por um grupo conselheiro da cidade,
avançar além da fase de consulta popular, em que a cidadania de Madrid vai
votar se a proposta será realizada ou não. O prazo máximo para obter apoio
suficiente é de 12 meses."
@@ -1339,7 +1339,7 @@ pt-BR:
other: "%{count} comentários"
zero: Nenhum comentário
proposal: Proposta
reason_for_supports_necessary: 2% do Censo
reason_for_supports_necessary: 1% do Censo
support: Apoiar
supports:
one: 1 apoio

View File

@@ -81,10 +81,10 @@ end
(1..40).each do |i|
user = create_user("user#{i}@consul.dev")
level = [1, 2, 3].sample
if level >= 2 then
if level >= 2
user.update(residence_verified_at: Time.now, confirmed_phone: Faker::PhoneNumber.phone_number, document_number: Faker::Number.number(10), document_type: "1" )
end
if level == 3 then
if level == 3
user.update(verified_at: Time.now, document_number: Faker::Number.number(10) )
end
end
@@ -113,7 +113,7 @@ ActsAsTaggableOn::Tag.create!(name: "Medio Ambiente", featured: true, kind: "ca
puts "Creating Debates"
tags = Faker::Lorem.words(25)
(1..30).each do |i|
(1..30).each do
author = User.reorder("RANDOM()").first
description = "<p>#{Faker::Lorem.paragraphs.join('</p><p>')}</p>"
debate = Debate.create!(author: author,
@@ -128,7 +128,7 @@ end
tags = ActsAsTaggableOn::Tag.where(kind: 'category')
(1..30).each do |i|
(1..30).each do
author = User.reorder("RANDOM()").first
description = "<p>#{Faker::Lorem.paragraphs.join('</p><p>')}</p>"
debate = Debate.create!(author: author,
@@ -165,7 +165,7 @@ end
puts "Creating Archived Proposals"
tags = Faker::Lorem.words(25)
(1..5).each do |i|
(1..5).each do
author = User.reorder("RANDOM()").first
description = "<p>#{Faker::Lorem.paragraphs.join('</p><p>')}</p>"
proposal = Proposal.create!(author: author,
@@ -185,7 +185,7 @@ end
tags = ActsAsTaggableOn::Tag.where(kind: 'category')
(1..30).each do |i|
(1..30).each do
author = User.reorder("RANDOM()").first
description = "<p>#{Faker::Lorem.paragraphs.join('</p><p>')}</p>"
proposal = Proposal.create!(author: author,
@@ -205,7 +205,7 @@ end
puts "Commenting Debates"
(1..100).each do |i|
(1..100).each do
author = User.reorder("RANDOM()").first
debate = Debate.reorder("RANDOM()").first
Comment.create!(user: author,
@@ -229,7 +229,7 @@ end
puts "Commenting Comments"
(1..200).each do |i|
(1..200).each do
author = User.reorder("RANDOM()").first
parent = Comment.reorder("RANDOM()").first
Comment.create!(user: author,
@@ -243,7 +243,7 @@ end
puts "Voting Debates, Proposals & Comments"
(1..100).each do |i|
(1..100).each do
voter = not_org_users.reorder("RANDOM()").first
vote = [true, false].sample
debate = Debate.reorder("RANDOM()").first
@@ -257,7 +257,7 @@ end
comment.vote_by(voter: voter, vote: vote)
end
(1..100).each do |i|
(1..100).each do
voter = User.level_two_or_three_verified.reorder("RANDOM()").first
proposal = Proposal.reorder("RANDOM()").first
proposal.vote_by(voter: voter, vote: true)
@@ -266,19 +266,19 @@ end
puts "Flagging Debates & Comments"
(1..40).each do |i|
(1..40).each do
debate = Debate.reorder("RANDOM()").first
flagger = User.where(["users.id <> ?", debate.author_id]).reorder("RANDOM()").first
Flag.flag(flagger, debate)
end
(1..40).each do |i|
(1..40).each do
comment = Comment.reorder("RANDOM()").first
flagger = User.where(["users.id <> ?", comment.user_id]).reorder("RANDOM()").first
Flag.flag(flagger, comment)
end
(1..40).each do |i|
(1..40).each do
proposal = Proposal.reorder("RANDOM()").first
flagger = User.where(["users.id <> ?", proposal.author_id]).reorder("RANDOM()").first
Flag.flag(flagger, proposal)
@@ -288,7 +288,7 @@ puts "Creating Spending Proposals"
tags = Faker::Lorem.words(10)
(1..60).each do |i|
(1..60).each do
geozone = Geozone.reorder("RANDOM()").first
author = User.reorder("RANDOM()").first
description = "<p>#{Faker::Lorem.paragraphs.join('</p><p>')}</p>"

View File

@@ -30,7 +30,6 @@ class DeviseCreateUsers < ActiveRecord::Migration
# t.string :unlock_token # Only if unlock strategy is :email or :both
# t.datetime :locked_at
t.timestamps null: false
end

View File

@@ -1,12 +1,12 @@
class CreateSimpleCaptchaData < ActiveRecord::Migration
def self.up
create_table :simple_captcha_data do |t|
t.string :key, :limit => 40
t.string :value, :limit => 6
t.string :key, limit: 40
t.string :value, limit: 6
t.timestamps
end
add_index :simple_captcha_data, :key, :name => "idx_key"
add_index :simple_captcha_data, :key, name: "idx_key"
end
def self.down

View File

@@ -6,7 +6,7 @@ class CreateTolkTables < ActiveRecord::Migration
t.datetime :updated_at
end
add_index :tolk_locales, :name, :unique => true
add_index :tolk_locales, :name, unique: true
create_table :tolk_phrases do |t|
t.text :key
@@ -19,17 +19,17 @@ class CreateTolkTables < ActiveRecord::Migration
t.integer :locale_id
t.text :text
t.text :previous_text
t.boolean :primary_updated, :default => false
t.boolean :primary_updated, default: false
t.datetime :created_at
t.datetime :updated_at
end
add_index :tolk_translations, [:phrase_id, :locale_id], :unique => true
add_index :tolk_translations, [:phrase_id, :locale_id], unique: true
end
def self.down
remove_index :tolk_translations, :column => [:phrase_id, :locale_id]
remove_index :tolk_locales, :column => :name
remove_index :tolk_translations, column: [:phrase_id, :locale_id]
remove_index :tolk_locales, column: :name
drop_table :tolk_translations
drop_table :tolk_phrases

View File

@@ -1,4 +1,5 @@
namespace :proposals do
desc "Updates all proposals by recalculating their hot_score"
task touch: :environment do
Proposal.find_in_batches do |proposals|

View File

@@ -1,4 +1,5 @@
namespace :spending_proposals do
desc "Sends an email to the authors of unfeasible spending proposals"
task send_unfeasible_emails: :environment do
SpendingProposal.find_each do |spending_proposal|

View File

@@ -6,6 +6,7 @@ require 'rails_helper'
describe 'CustomizationEngine' do
let(:test_key) { I18n.t('account.show.change_credentials_link') }
let!(:default_path) { I18n.load_path }
it "should load custom and override original locales" do
I18n.load_path += Dir[Rails.root.join('spec', 'support', 'locales', 'custom', '*.{rb,yml}')]
@@ -19,4 +20,10 @@ describe 'CustomizationEngine' do
I18n.reload!
expect(test_key).to eq 'Not overriden string with custom locales'
end
after(:each) do
I18n.load_path = default_path
I18n.reload!
end
end

View File

@@ -1,6 +1,7 @@
require 'rails_helper'
feature 'Admin banners magement' do
background do
login_as(create(:administrator).user)
end
@@ -124,8 +125,8 @@ feature 'Admin banners magement' do
fill_in 'banner_description', with: 'Edited text'
within('div#js-banner-style') do
expect(page).to have_selector('h2', :text => 'Modified title')
expect(page).to have_selector('h3', :text => 'Edited text')
expect(page).to have_selector('h2', text: 'Modified title')
expect(page).to have_selector('h3', text: 'Edited text')
end
click_button 'Save changes'
@@ -139,13 +140,14 @@ feature 'Admin banners magement' do
end
scenario 'Delete a banner' do
banner1 = create(:banner, title: 'Ugly banner',
create(:banner, title: 'Ugly banner',
description: 'Bad text',
target_url: 'http://www.url.com',
style: 'banner-style.banner-one',
image: 'banner-img.banner-one',
post_started_at: (Time.now + 4.days),
post_ended_at: (Time.now + 10.days))
visit admin_root_path
within("#side_menu") do

View File

@@ -60,4 +60,5 @@ feature 'Admin feature flags' do
expect(page).to have_link "Spending proposals"
end
end
end

View File

@@ -33,5 +33,5 @@ feature 'Admin managers' do
expect(page).to_not have_content @manager.name
end
end
end
end

View File

@@ -27,4 +27,5 @@ feature 'Admin settings' do
expect(page).to have_content 'Value updated'
end
end

View File

@@ -956,7 +956,6 @@ feature 'Debates' do
end
end
context 'Suggesting debates' do
scenario 'Shows up to 5 suggestions', :js do
author = create(:user)
@@ -1029,7 +1028,6 @@ feature 'Debates' do
end
end
scenario 'Index include featured debates' do
admin = create(:administrator)
login_as(admin.user)

View File

@@ -25,7 +25,6 @@ feature 'Proposal ballots' do
successfull_proposals.each do |proposal|
within("#proposal_#{proposal.id}_votes") do
expect(page).to_not have_css(".supports")
expect(page).to have_content "This proposal has reached the required supports"
end
end
@@ -37,7 +36,6 @@ feature 'Proposal ballots' do
successfull_proposals.each do |proposal|
visit proposal_path(proposal)
within("#proposal_#{proposal.id}_votes") do
expect(page).to_not have_css(".supports")
expect(page).to have_content "This proposal has reached the required supports"
end
end

View File

@@ -723,7 +723,6 @@ feature 'Proposals' do
within("#proposals-list") do
archived_proposals.each do |proposal|
within("#proposal_#{proposal.id}_votes") do
expect(page).to_not have_css(".supports")
expect(page).to have_content "This proposal has been archived and can't collect supports"
end
end
@@ -734,7 +733,6 @@ feature 'Proposals' do
archived_proposal = create(:proposal, :archived)
visit proposal_path(archived_proposal)
expect(page).to_not have_css(".supports")
expect(page).to have_content "This proposal has been archived and can't collect supports"
end

View File

@@ -52,7 +52,6 @@ feature 'Users' do
uid: '12345',
info: {name: 'manuela', email: 'manuelacarmena@example.com', verified: '1'}} }
scenario 'Sign up when Oauth provider has a verified email' do
OmniAuth.config.add_mock(:twitter, twitter_hash_with_verified_email)

View File

@@ -98,4 +98,5 @@ feature 'Verification path' do
expect(page).to have_content 'Your account is already verified'
end
end
end

View File

@@ -85,7 +85,7 @@ describe EmailDigest do
user = create(:user)
proposal_notification = create(:proposal_notification)
notification = create(:notification, notifiable: proposal_notification, user: user, emailed_at: Time.now)
create(:notification, notifiable: proposal_notification, user: user, emailed_at: Time.now)
reset_mailer
email_digest = EmailDigest.new(user)

View File

@@ -651,28 +651,28 @@ describe Proposal do
context "no results" do
it "no words match" do
proposal = create(:proposal, title: 'save world')
create(:proposal, title: 'save world')
results = Proposal.search('destroy planet')
expect(results).to eq([])
end
it "too many typos" do
proposal = create(:proposal, title: 'fantastic')
create(:proposal, title: 'fantastic')
results = Proposal.search('frantac')
expect(results).to eq([])
end
it "too much stemming" do
proposal = create(:proposal, title: 'reloj')
create(:proposal, title: 'reloj')
results = Proposal.search('superrelojimetro')
expect(results).to eq([])
end
it "empty" do
proposal = create(:proposal, title: 'great')
create(:proposal, title: 'great')
results = Proposal.search('')
expect(results).to eq([])

View File

@@ -9,7 +9,7 @@ RSpec.configure do |config|
config.filter_run :focus
config.run_all_when_everything_filtered = true
config.include Devise::TestHelpers, :type => :controller
config.include Devise::TestHelpers, type: :controller
config.include FactoryGirl::Syntax::Methods
config.include(EmailSpec::Helpers)
config.include(EmailSpec::Matchers)

View File

@@ -159,4 +159,5 @@ shared_examples_for "verifiable" do
expect(user.verification_letter_sent?).to eq(false)
end
end
end