Merge branch 'master' into api-coding-madrid

This commit is contained in:
Alberto Miedes Garcés
2016-11-10 22:33:27 +01:00
58 changed files with 679 additions and 386 deletions

33
Gemfile
View File

@@ -3,26 +3,27 @@ source 'https://rubygems.org'
# Bundle edge Rails instead: gem 'rails', github: 'rails/rails'
gem 'rails', '4.2.7.1'
# Use PostgreSQL
gem 'pg'
gem 'pg', '~> 0.19.0'
# Use SCSS for stylesheets
gem 'sass-rails', '~> 5.0', '>= 5.0.4'
# Use Uglifier as compressor for JavaScript assets
gem 'uglifier', '>= 1.3.0'
gem 'uglifier', '>= 3.0.3'
# Use CoffeeScript for .coffee assets and views
gem 'coffee-rails', '~> 4.2.1'
# See https://github.com/rails/execjs#readme for more supported runtimes
# gem 'therubyracer', platforms: :ruby
# Use jquery as the JavaScript library
gem 'jquery-rails'
gem 'jquery-rails', '~> 4.2.1'
gem 'jquery-ui-rails'
# Turbolinks makes following links in your web application faster. Read more: https://github.com/rails/turbolinks
gem 'turbolinks'
# Fix sprockets on the
gem 'sprockets', '~> 3.6.3'
gem 'sprockets', '~> 3.7.0'
gem 'devise', '~> 3.5.7'
gem 'devise_security_extension'
# Use ActiveModel has_secure_password
# gem 'bcrypt', '~> 3.1.7'
gem 'omniauth'
@@ -31,11 +32,11 @@ gem 'omniauth-facebook', '~> 3.0.0'
gem 'omniauth-google-oauth2', '~> 0.4.0'
gem 'kaminari'
gem 'ancestry'
gem 'ancestry', '~> 2.2.1'
gem 'acts-as-taggable-on'
gem 'responders'
gem 'foundation-rails'
gem 'foundation_rails_helper'
gem 'responders', '~> 2.3.0'
gem 'foundation-rails', '~> 6.2.4.0'
gem 'foundation_rails_helper', '~> 2.0.0'
gem 'acts_as_votable'
gem 'ckeditor', '~> 4.2.0'
gem 'invisible_captcha', '~> 0.9.1'
@@ -43,24 +44,24 @@ gem 'cancancan'
gem 'social-share-button'
gem 'initialjs-rails', '0.2.0.4'
gem 'unicorn', '~> 5.1.0'
gem 'paranoia'
gem 'rinku', require: 'rails_rinku'
gem 'paranoia', '~> 2.2.0'
gem 'rinku', '~> 2.0.2', require: 'rails_rinku'
gem 'savon'
gem 'dalli'
gem 'rollbar', '~> 2.12.0'
gem 'rollbar', '~> 2.13.3'
gem 'delayed_job_active_record', '~> 4.1.0'
gem 'daemons'
gem 'devise-async'
gem 'newrelic_rpm', '~> 3.16'
gem 'newrelic_rpm', '~> 3.17.0.325'
gem 'whenever', require: false
gem 'pg_search'
gem 'ahoy_matey', '~> 1.4.0'
gem 'groupdate' # group temporary data
gem 'tolk' # Web interface for translations
gem 'ahoy_matey', '~> 1.4.2'
gem 'groupdate', '~> 3.1.0' # group temporary data
gem 'tolk', '~> 2.0.0' # Web interface for translations
gem 'browser'
gem 'turnout'
gem 'turnout', '~> 2.4.0'
gem 'redcarpet'
gem 'graphql'

View File

@@ -56,7 +56,7 @@ GEM
akami (1.3.1)
gyoku (>= 0.4.0)
nokogiri
ancestry (2.1.0)
ancestry (2.2.1)
activerecord (>= 3.0.0)
arel (6.0.3)
ast (2.2.0)
@@ -138,6 +138,9 @@ GEM
warden (~> 1.2.3)
devise-async (0.10.2)
devise (>= 3.2, < 4.0)
devise_security_extension (0.10.0)
devise (>= 3.0.0, < 4.0)
railties (>= 3.2.6, < 5.0)
diff-lcs (1.2.5)
docile (1.1.5)
easy_translate (0.5.0)
@@ -160,11 +163,11 @@ GEM
i18n (~> 0.5)
faraday (0.9.2)
multipart-post (>= 1.2, < 3)
foundation-rails (6.2.3.0)
foundation-rails (6.2.4.0)
railties (>= 3.1.0)
sass (>= 3.3.0, < 3.5)
sprockets-es6 (>= 0.9.0)
foundation_rails_helper (1.2.1)
foundation_rails_helper (2.0.0)
actionpack (>= 4.1)
activemodel (>= 4.1)
activesupport (>= 4.1)
@@ -173,13 +176,13 @@ GEM
fuubar (2.1.1)
rspec (~> 3.0)
ruby-progressbar (~> 1.4)
geocoder (1.3.7)
geocoder (1.4.0)
globalid (0.3.7)
activesupport (>= 4.1.0)
graphiql-rails (1.3.0)
rails
graphql (0.18.11)
groupdate (3.0.2)
groupdate (3.1.1)
activesupport (>= 3)
gyoku (1.3.1)
builder (>= 2.1.2)
@@ -203,7 +206,7 @@ GEM
railties (>= 3.1, < 6.0)
invisible_captcha (0.9.1)
rails
jquery-rails (4.1.1)
jquery-rails (4.2.1)
rails-dom-testing (>= 1, < 3)
railties (>= 4.2.0)
thor (>= 0.14, < 2.0)
@@ -238,10 +241,9 @@ GEM
net-scp (1.2.1)
net-ssh (>= 2.6.5)
net-ssh (3.2.0)
newrelic_rpm (3.16.3.323)
nokogiri (1.6.8)
newrelic_rpm (3.17.0.325)
nokogiri (1.6.8.1)
mini_portile2 (~> 2.1.0)
pkg-config (~> 1.1.7)
nori (2.6.0)
oauth (0.5.0)
oauth2 (1.0.0)
@@ -270,16 +272,15 @@ GEM
json (~> 1.3)
omniauth-oauth (~> 1.1)
orm_adapter (0.5.0)
paranoia (2.1.5)
activerecord (~> 4.0)
paranoia (2.2.0)
activerecord (>= 4.0, < 5.1)
parser (2.3.0.6)
ast (~> 2.2)
pg (0.18.4)
pg (0.19.0)
pg_search (1.0.6)
activerecord (>= 3.1)
activesupport (>= 3.1)
arel
pkg-config (1.1.7)
poltergeist (1.10.0)
capybara (~> 2.1)
cliver (~> 0.3.1)
@@ -289,7 +290,7 @@ GEM
rack (1.6.4)
rack-accept (0.4.5)
rack (>= 0.4)
rack-attack (4.4.1)
rack-attack (5.0.1)
rack
rack-test (0.6.3)
rack (>= 1.0)
@@ -322,10 +323,10 @@ GEM
redcarpet (3.3.4)
referer-parser (0.3.0)
request_store (1.3.1)
responders (2.2.0)
responders (2.3.0)
railties (>= 4.2.0, < 5.1)
rinku (2.0.0)
rollbar (2.12.0)
rinku (2.0.2)
rollbar (2.13.3)
multi_json
rspec (3.5.0)
rspec-core (~> 3.5.0)
@@ -378,14 +379,14 @@ GEM
spring (1.7.2)
spring-commands-rspec (1.0.4)
spring (>= 0.9.1)
sprockets (3.6.3)
sprockets (3.7.0)
concurrent-ruby (~> 1.0)
rack (> 1, < 3)
sprockets-es6 (0.9.0)
sprockets-es6 (0.9.2)
babel-source (>= 5.8.11)
babel-transpiler
sprockets (>= 3.0.0)
sprockets-rails (3.1.1)
sprockets-rails (3.2.0)
actionpack (>= 4.0)
activesupport (>= 4.0)
sprockets (>= 3.0.0)
@@ -400,18 +401,19 @@ GEM
thread_safe (0.3.5)
tilt (2.0.5)
tins (1.11.0)
tolk (1.9.3)
rails (>= 4.0, < 4.3)
tolk (2.0.0)
rails (>= 4.0)
safe_yaml (>= 0.8.6)
turbolinks (2.5.3)
coffee-rails
turnout (2.3.1)
rack (~> 1.3)
turnout (2.4.0)
i18n (~> 0.7)
rack (>= 1.3, < 3)
rack-accept (~> 0.4)
tilt (>= 1.4, < 3)
tzinfo (1.2.2)
thread_safe (~> 0.1)
uglifier (3.0.2)
uglifier (3.0.3)
execjs (>= 0.3.0, < 3)
unicorn (5.1.0)
kgio (~> 2.6)
@@ -442,8 +444,8 @@ PLATFORMS
DEPENDENCIES
acts-as-taggable-on
acts_as_votable
ahoy_matey (~> 1.4.0)
ancestry
ahoy_matey (~> 1.4.2)
ancestry (~> 2.2.1)
browser
bullet
byebug
@@ -463,49 +465,50 @@ DEPENDENCIES
delayed_job_active_record (~> 4.1.0)
devise (~> 3.5.7)
devise-async
devise_security_extension
email_spec
factory_girl_rails
faker
foundation-rails
foundation_rails_helper
foundation-rails (~> 6.2.4.0)
foundation_rails_helper (~> 2.0.0)
fuubar
graphiql-rails
graphql
groupdate
groupdate (~> 3.1.0)
i18n-tasks
initialjs-rails (= 0.2.0.4)
invisible_captcha (~> 0.9.1)
jquery-rails
jquery-rails (~> 4.2.1)
jquery-ui-rails
kaminari
launchy
letter_opener_web (~> 1.3.0)
newrelic_rpm (~> 3.16)
newrelic_rpm (~> 3.17.0.325)
omniauth
omniauth-facebook (~> 3.0.0)
omniauth-google-oauth2 (~> 0.4.0)
omniauth-twitter
paranoia
pg
paranoia (~> 2.2.0)
pg (~> 0.19.0)
pg_search
poltergeist
quiet_assets
rails (= 4.2.7.1)
redcarpet
responders
rinku
rollbar (~> 2.12.0)
responders (~> 2.3.0)
rinku (~> 2.0.2)
rollbar (~> 2.13.3)
rspec-rails (~> 3.5)
sass-rails (~> 5.0, >= 5.0.4)
savon
social-share-button
spring
spring-commands-rspec
sprockets (~> 3.6.3)
tolk
sprockets (~> 3.7.0)
tolk (~> 2.0.0)
turbolinks
turnout
uglifier (>= 1.3.0)
turnout (~> 2.4.0)
uglifier (>= 3.0.3)
unicorn (~> 5.1.0)
web-console (= 3.3.0)
whenever

View File

@@ -34,7 +34,6 @@ cd consul
bundle install
cp config/database.yml.example config/database.yml
cp config/secrets.yml.example config/secrets.yml
rake db:create
bin/rake db:setup
bin/rake db:dev_seed
RAILS_ENV=test rake db:setup

View File

@@ -34,7 +34,6 @@ cd consul
bundle install
cp config/database.yml.example config/database.yml
cp config/secrets.yml.example config/secrets.yml
rake db:create
bin/rake db:setup
bin/rake db:dev_seed
RAILS_ENV=test rake db:setup

View File

@@ -3,17 +3,11 @@ App.Votes =
hoverize: (votes) ->
$(document).on {
'mouseenter focus': ->
$("div.anonymous-votes", this).show();
$("div.organizations-votes", this).show();
$("div.not-logged", this).show();
$("div.no-supports-allowed", this).show();
$("div.logged", this).hide();
$("div.participation-not-allowed", this).show();
$("div.participation-allowed", this).hide();
mouseleave: ->
$("div.anonymous-votes", this).hide();
$("div.organizations-votes", this).hide();
$("div.not-logged", this).hide();
$("div.no-supports-allowed", this).hide();
$("div.logged", this).show();
$("div.participation-not-allowed", this).hide();
$("div.participation-allowed", this).show();
}, votes
initialize: ->

View File

@@ -48,37 +48,32 @@
// --------------------
$base-font-size: rem-calc(17);
$base-line-height: rem-calc(26);
$base-line: rem-calc(26);
$small-font-size: rem-calc(14);
$line-height: rem-calc(24);
$brand: #004A83;
$body: #E9E9E9;
$background: #EDEFF0;
$border: #DEE0E3;
$dark: darken($brand, 10%);
$text: #222222;
$text-medium: #999999;
$text-light: #CCCCCC;
$border: #DEE0E3;
$link: #2895F1;
$link-hover: #2178BF;
$link-hover: darken($link, 20%);
$debates: #008CCF;
$votes-bg: #26AEEE;
$votes-border: #1F94CB;
$votes-like: #7BD2A8;
$votes-like-act: #5D9E7F;
$votes-unlike: #EF8585;
$votes-unlike-act: #BD6A6A;
$votes: #26AEEE;
$like: #7BD2A8;
$unlike: #EF8585;
$delete: #F04124;
$check: #46DB91;
$proposals: #FFA42D;
$proposals-border: #CC8425;
$budget: #454372;
$budget-hover: #7571BF;
@@ -86,9 +81,6 @@ $budget-hover: #7571BF;
$highlight: #E7F2FC;
$featured: #FED900;
$footer-bg: #DEE0E2;
$footer-color: #171819;
$footer-link: #454A4C;
$footer-border: #BFC1C3;
$success-bg: #DFF0D8;

View File

@@ -82,7 +82,7 @@ body.admin {
.admin-content {
.proposal-new, .proposal-edit {
.proposal-form {
padding-top: 0;
}

View File

@@ -23,6 +23,11 @@
// 01. Global styles
// -----------------
::selection {
color: white;
background-color: $brand;
}
body {
font-size: $base-font-size;
}
@@ -35,7 +40,7 @@ h1, h2, h3, h4, h5, h6 {
p {
font-size: $base-font-size;
font-weight: 400;
line-height: $base-line-height;
line-height: $base-line;
}
a {
@@ -148,10 +153,6 @@ a {
height: 100%;
}
.wrap {
background: white;
}
.footer, .push {
clear: both;
min-height: $line-height*12;
@@ -486,7 +487,7 @@ header {
// ----------
footer {
color: $footer-color;
color: $text;
.logo a {
font-family: 'Lato' !important;
@@ -506,10 +507,11 @@ footer {
}
a, a:active, a:focus {
color: $footer-link;
color: $text;
text-decoration: underline;
&:hover {
color: $footer-color;
color: $text-medium;
}
}
@@ -518,7 +520,7 @@ footer {
}
h2 a {
border-bottom: 1px solid $footer-border;
border-bottom: 1px solid $text-light;
display: block;
font-size: rem-calc(24);
line-height: rem-calc(31);
@@ -528,14 +530,14 @@ footer {
}
.footer {
background: $footer-bg;
background: $border;
border-top: 6px solid $brand;
margin-top: $line-height*2;
padding-top: $line-height;
}
.subfooter {
border-top: 1px solid $footer-border;
border-top: 1px solid $text-light;
padding-top: $line-height/2;
}
@@ -562,8 +564,8 @@ footer {
color: $link;
&:hover {
background: $highlight;
color: $link-hover;
background: $brand;
color: white;
}
}
@@ -732,6 +734,56 @@ form {
// 07. Callout
// -----------
.callout-slide {
animation-duration: 1s;
-webkit-animation-duration: 1s;
animation-fill-mode: both;
-webkit-animation-fill-mode: both;
animation-name: slide;
-webkit-animation-name: slide;
}
@-webkit-keyframes slide {
from {
-webkit-transform: translate3d(100%, 0, 0);
transform: translate3d(100%, 0, 0);
visibility: visible;
}
to {
-webkit-transform: translate3d(0, 0, 0);
transform: translate3d(0, 0, 0);
}
}
@keyframes slide {
from {
-webkit-transform: translate3d(100%, 0, 0);
transform: translate3d(100%, 0, 0);
visibility: visible;
}
to {
-webkit-transform: translate3d(0, 0, 0);
transform: translate3d(0, 0, 0);
}
}
.notice-container {
min-width: $line-height*12;
position: absolute;
right: 24px;
top: 24px;
.notice {
height: $line-height*4;
.notice-text {
width: 95%;
}
}
}
.callout {
font-size: $small-font-size;
@@ -951,15 +1003,6 @@ img.avatar, img.admin-avatar, img.moderator-avatar, img.initialjs-avatar {
// 09. Search
// ----------
.search-form h3 {
border-top: 1px solid $votes-border;
display: inline-block;
font-size: rem-calc(16);
margin: -1px 0 $line-height/2;
padding-top: $line-height/4;
text-transform: uppercase;
}
.search-results h2 {
margin-bottom: 0;
}
@@ -1537,6 +1580,7 @@ table {
font-size: $small-font-size;
margin: rem-calc(6) 0;
padding: rem-calc(6);
position: relative;
[class^="icon-arrow"] {
font-size: rem-calc(18);

View File

@@ -13,7 +13,7 @@
font-size: rem-calc(24);
font-weight: lighter;
@include breakpoint(small) {
@include breakpoint(medium) {
line-height: $line-height*2;
margin-top: 0;
}
@@ -22,7 +22,7 @@
height: 48px;
width: 48px;
@include breakpoint(small) {
@include breakpoint(medium) {
height: 80px;
margin-right: $line-height/2;
margin-top: 0;

View File

@@ -12,15 +12,14 @@
// ----------------------
@mixin votes {
background: $votes-bg;
border-top: 1px solid $votes-border;
background: $votes;
margin: 0 rem-calc(-12);
padding: rem-calc(14) rem-calc(12);
position: relative;
.icon-like {
.icon-like, .icon-unlike {
background: white;
border: 2px solid $votes-border;
border: 2px solid $votes;
border-radius: rem-calc(3);
color: $text-light;
display: inline-block;
@@ -29,40 +28,25 @@
padding: rem-calc(3) rem-calc(6);
position: relative;
&:hover {
background: $votes-like;
&:hover, &:active {
border-color: white;
color: white;
cursor: pointer;
opacity: 1 !important;
}
}
&:active {
border-color: $votes-like-act;
.icon-like {
&:hover, &:active {
background: $like;
}
}
.icon-unlike {
background: white;
border: 2px solid $votes-border;
border-radius: rem-calc(3);
color: $text-light;
display: inline-block;
font-size: rem-calc(30);
line-height: rem-calc(30);
padding: rem-calc(3) rem-calc(6);
position: relative;
&:hover {
background: $votes-unlike;
border-color: white;
color: white;
cursor: pointer;
opacity: 1 !important;
}
&:active {
border-color: $votes-unlike-act;
&:hover, &:active {
background: $unlike;
}
}
@@ -81,20 +65,23 @@
}
.voted {
.icon-like {
background: $votes-like;
.icon-like, .icon-unlike {
border-color: white;
color: white;
}
.icon-like {
background: $like;
}
.icon-unlike {
background: $votes-unlike;
border-color: white;
color: white;
background: $unlike;
}
}
.no-voted {
.icon-like, .icon-unlike {
opacity: .5;
}
@@ -109,54 +96,10 @@
.divider {
margin: 0 rem-calc(6);
}
.not-logged {
background: rgba(22,99,135,.9);
color: white;
font-size: $small-font-size;
height: 100%;
left: 0;
position: absolute;
text-align: center;
top: 0;
width: 100%;
filter: progid:DXImageTransform.Microsoft.gradient(GradientType=0,startColorstr='#222222', endColorstr='#222222'); /* IE */
a {
color: white;
text-decoration: underline;
}
}
.anonymous-votes, .organizations-votes {
background: $warning-bg;
color: $color-warning;
height: 100%;
left: 0;
line-height: $line-height;
padding-top: rem-calc(12);
position: absolute;
text-align: center;
top: 0;
width: 100%;
p {
color: $color-warning;
margin: 0 rem-calc(12);
text-align: left;
}
a {
color: $color-warning;
font-weight: bold;
text-decoration: underline;
}
}
}
@mixin supports {
background: $proposals;
border-top: 1px solid $proposals-border;
margin: 0 rem-calc(-12);
padding: rem-calc(14) rem-calc(12);
position: relative;
@@ -166,7 +109,7 @@
height: $line-height/2;
.meter {
background: $votes-like;
background: $like;
display: block;
height: $line-height/2;
}
@@ -197,7 +140,7 @@
margin-top: rem-calc(12);
&:hover {
background: $proposals-border;
background: darken($proposals, 35%);
color: white;
cursor: pointer;
}
@@ -221,49 +164,6 @@
margin: 0 rem-calc(6);
}
.not-logged {
background: rgba(255,164,45,.9);
color: white;
font-size: $small-font-size;
height: 100%;
left: 0;
position: absolute;
text-align: center;
top: 0;
width: 100%;
filter: progid:DXImageTransform.Microsoft.gradient(GradientType=0,startColorstr='#222222', endColorstr='#222222'); /* IE */
a {
color: white;
text-decoration: underline;
}
}
.anonymous-votes, .organizations-votes, .no-supports-allowed {
background: $warning-bg;
color: $color-warning;
height: 100%;
left: 0;
line-height: $line-height;
padding-top: rem-calc(12);
position: absolute;
text-align: center;
top: 0;
width: 100%;
p {
color: $color-warning;
margin: 0 rem-calc(12);
text-align: left;
}
a {
color: $color-warning;
font-weight: bold;
text-decoration: underline;
}
}
.supported {
color: white;
margin-top: rem-calc(12);
@@ -285,32 +185,61 @@
}
}
.participation-not-allowed {
background: $warning-bg;
color: $color-warning;
height: 100%;
left: 0;
line-height: $line-height;
padding: $line-height $line-height/2;
position: absolute;
text-align: center;
top: 0;
width: 100%;
z-index: 2;
p {
color: $color-warning !important;
margin: 0 rem-calc(12);
text-align: left;
}
a {
color: $color-warning !important;
font-weight: bold;
text-decoration: underline;
}
}
.reply .participation-not-allowed {
padding-right: $line-height/2;
padding-top: $line-height/6;
text-align: right;
}
// 02. New participation
// ---------------------
.debate-new, .debate-edit,
.proposal-new, .proposal-edit,
.spending-proposal-new, .spending-proposal-edit {
.debate-form,
.proposal-form,
.spending-proposal-form {
.icon-debates, .icon-proposals, .icon-budget {
font-size: rem-calc(50);
line-height: $line-height;
opacity: .5;
}
.icon-debates {
color: $debates;
font-size: rem-calc(60);
line-height: $line-height;
opacity: .5;
}
.icon-proposals {
color: $proposals;
font-size: rem-calc(50);
line-height: $line-height;
opacity: .5;
}
.icon-budget {
color: $budget;
font-size: rem-calc(50);
line-height: $line-height;
opacity: .5;
}
.recommendations {
@@ -330,14 +259,14 @@
}
}
.debate-new, .debate-edit {
.debate-form {
.recommendations li:before {
color: $debates;
}
}
.proposal-new, .proposal-edit {
.proposal-form {
.recommendations li:before {
color: $proposals;
@@ -496,11 +425,6 @@
line-height: $line-height;
}
.not-logged {
line-height: $line-height;
padding: rem-calc(24);
}
@include breakpoint(small + rem-calc(1) and medium down) {
.in-favor, .against {
text-align: left;
@@ -530,11 +454,6 @@
float: none;
line-height: $line-height;
}
.not-logged {
line-height: $line-height;
padding: rem-calc(24);
}
}
.leave-comment {
@@ -711,15 +630,6 @@
}
}
.not-logged {
line-height: $line-height;
padding-top: rem-calc(24);
}
.anonymous-votes, .organizations-votes {
padding-top: rem-calc(24);
}
.divider {
display: none;
}
@@ -745,7 +655,7 @@
.votes {
@include votes;
border: 1px solid $votes-border;
border: 1px solid $votes;
margin: 0 rem-calc(-12);
@include breakpoint(medium) {
@@ -803,7 +713,7 @@
.supports {
@include supports;
border: 1px solid $proposals-border;
border: 1px solid $proposals;
margin: 0 rem-calc(-12);
@include breakpoint(medium) {
@@ -904,16 +814,6 @@
line-height: rem-calc(70);
}
.no-supports-allowed {
background: rgba(69,67,114,.96);
color: white;
padding: rem-calc(12);
}
.no-supports-allowed p, .no-supports-allowed a {
color: white;
}
.share-supported {
.ssb-twitter,
@@ -1006,18 +906,13 @@
margin-top: 0;
}
.not-logged,
.organizations-votes,
.anonymous-votes {
.participation-not-allowed {
background: $featured;
color: $color-warning;
font-size: $small-font-size;
line-height: $line-height;
padding-top: 0;
a {
color: $color-warning;
font-weight: bold;
}
p {

View File

@@ -0,0 +1,8 @@
module LocalesHelper
def name_for_locale(locale)
default = I18n.t("locale", locale: locale)
I18n.backend.translate(locale, "i18n.language.name", default: default)
end
end

View File

@@ -2,8 +2,8 @@ class User < ActiveRecord::Base
include Verification
devise :database_authenticatable, :registerable, :confirmable,
:recoverable, :rememberable, :trackable, :validatable, :omniauthable, :async
devise :database_authenticatable, :registerable, :confirmable, :recoverable, :rememberable,
:trackable, :validatable, :omniauthable, :async, :password_expirable, :secure_validatable
acts_as_voter
acts_as_paranoid column: :hidden_at

View File

@@ -33,7 +33,7 @@
<% elsif !user_signed_in? %>
<div class="logged" >
<div class="participation-allowed">
<%= t('comments.comment.votes', count: comment.total_votes) %>
&nbsp;|&nbsp;
@@ -60,7 +60,7 @@
<%= comment.total_dislikes %>
</span>
</div>
<div class="not-logged" style='display:none'>
<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),
signup: link_to(t("votes.signup"), new_user_registration_path)).html_safe %>

View File

@@ -26,23 +26,23 @@
</span>
<% if user_signed_in? && current_user.organization? %>
<div class="organizations-votes" style='display:none' aria-hidden="false">
<p>
<%= t("votes.organizations") %>
</p>
</div>
<div class="participation-not-allowed" style='display:none' aria-hidden="false">
<p>
<%= t("votes.organizations") %>
</p>
</div>
<% elsif user_signed_in? && !debate.votable_by?(current_user)%>
<div class="anonymous-votes" style='display:none' aria-hidden="false">
<p>
<%= t("votes.anonymous",
verify_account: link_to(t("votes.verify_account"), verification_path )).html_safe %>
</p>
</div>
<div class="participation-not-allowed" style='display:none' aria-hidden="false">
<p>
<%= t("votes.anonymous",
verify_account: link_to(t("votes.verify_account"), verification_path )).html_safe %>
</p>
</div>
<% elsif !user_signed_in? %>
<div class="not-logged" style='display:none' aria-hidden="false">
<%= t("votes.unauthenticated",
signin: link_to(t("votes.signin"), new_user_session_path),
signup: link_to(t("votes.signup"), new_user_registration_path)).html_safe %>
</div>
<div class="participation-not-allowed" style='display:none' aria-hidden="false">
<%= t("votes.unauthenticated",
signin: link_to(t("votes.signin"), new_user_session_path),
signup: link_to(t("votes.signup"), new_user_registration_path)).html_safe %>
</div>
<% end %>
</div>

View File

@@ -1,4 +1,4 @@
<div class="debate-edit row">
<div class="debate-form row">
<div class="small-12 column">
<%= render "shared/back_link" %>

View File

@@ -6,7 +6,7 @@
<% end %>
<main>
<div class="wrap row">
<div class="row">
<div id="debates" class="debates-list small-12 medium-9 column">
<div class="small-12 search-results">

View File

@@ -1,4 +1,4 @@
<div class="debate-new row">
<div class="debate-form row">
<div class="small-12 medium-9 column">
<%= render "shared/back_link" %>

View File

@@ -0,0 +1,13 @@
<h2><%= t("devise.password_expired.expire_password") %></h2>
<%= form_for(resource, :as => resource_name, :url => [resource_name, :password_expired], :html => { :method => :put }) do |f| %>
<%= f.password_field :current_password %></p>
<%= f.label t("devise.password_expired.new_password") %>
<%= f.password_field :password, label: false %></p>
<%= f.password_field :password_confirmation %></p>
<p><%= f.submit t("devise.password_expired.change_password") %></p>
<% end %>

View File

@@ -13,6 +13,6 @@
</div>
<h1><%= @direct_message.title %></h1>
<p><%= @direct_message.body %></p>
<p><%= simple_format text_with_links(@direct_message.body), {}, sanitize: false %></p>
</div>
</div>

View File

@@ -1,10 +1,12 @@
<% flash.each do |flash_key, flash_message| %>
<div id="<%= flash_key %>" data-alert class="row" data-closable>
<div class="callout <%= flash_key %>">
<div id="<%= flash_key %>" data-alert class="notice-container callout-slide" data-closable>
<div class="callout notice <%= flash_key %>">
<button class="close-button" aria-label="<%= t("application.close") %>" type="button" data-close>
<span aria-hidden="true">&times;</span>
</button>
<%= flash_message %>
<div class="notice-text">
<%= flash_message %>
</div>
</div>
</div>
<% end %>

View File

@@ -3,9 +3,9 @@
<%= @direct_message.title %>
</h1>
<p style="font-family: 'Open Sans','Helvetica Neue',arial,sans-serif;font-size: 14px;font-weight: normal;line-height: 24px;">
<%= @direct_message.body %>
</p>
<div style="font-family: 'Open Sans','Helvetica Neue',arial,sans-serif;font-size: 14px;font-weight: normal;line-height: 24px;">
<%= simple_format text_with_links(@direct_message.body), {}, sanitize: false %>
</div>
<table style="width: 100%; border-top: 1px solid #DEE0E3; margin-top: 60px;">
<tbody>

View File

@@ -9,7 +9,7 @@
<%= @direct_message.title %>
</h2>
<p style="font-family: 'Open Sans','Helvetica Neue',arial,sans-serif;font-size: 14px;font-weight: normal;line-height: 24px;">
<%= @direct_message.body %>
</p>
<div style="font-family: 'Open Sans','Helvetica Neue',arial,sans-serif;font-size: 14px;font-weight: normal;line-height: 24px;">
<%= simple_format text_with_links(@direct_message.body), {}, sanitize: false %>
</div>
</td>

View File

@@ -1,7 +1,7 @@
<main>
<%= render 'admin/shared/proposal_search', url: management_proposals_path %>
<div class="wrap row">
<div class="row">
<div id="proposals" class="proposals-list small-12 medium-9 column">
<div class="filters">

View File

@@ -1,4 +1,4 @@
<div class="proposal-new">
<div class="proposal-form">
<div class="clear float-right">
<%= render '/shared/print' %>

View File

@@ -3,7 +3,7 @@
<%= render 'admin/shared/spending_proposal_search', url: management_spending_proposals_path %>
</span>
<div class="wrap row">
<div class="row">
<div id="investment-projects" class="investment-projects-list small-12 medium-9 column">

View File

@@ -1,4 +1,4 @@
<div class="spending-proposal-new">
<div class="spending-proposal-form">
<div class="clear float-right">
<%= render '/shared/print' %>

View File

@@ -14,24 +14,24 @@
</div>
<% if user_signed_in? && current_user.organization? %>
<div class="organizations-votes" style='display:none'>
<p>
<%= t("votes.organizations") %>
</p>
</div>
<div class="participation-not-allowed" style='display:none' aria-hidden="false">
<p>
<%= t("votes.organizations") %>
</p>
</div>
<% elsif user_signed_in? && !proposal.votable_by?(current_user)%>
<div class="anonymous-votes" style='display:none'>
<p>
<%= t("votes.verified_only",
verify_account: link_to(t("votes.verify_account"), verification_path )).html_safe %>
</p>
</div>
<div class="participation-not-allowed" style='display:none' aria-hidden="false">
<p>
<%= t("votes.verified_only",
verify_account: link_to(t("votes.verify_account"), verification_path )).html_safe %>
</p>
</div>
<% elsif !user_signed_in? %>
<div class="not-logged" style='display:none'>
<%= t("votes.unauthenticated",
signin: link_to(t("votes.signin"), new_user_session_path),
signup: link_to(t("votes.signup"), new_user_registration_path)).html_safe %>
</div>
<div class="participation-not-allowed" style='display:none' aria-hidden="false">
<%= t("votes.unauthenticated",
signin: link_to(t("votes.signin"), new_user_session_path),
signup: link_to(t("votes.signup"), new_user_registration_path)).html_safe %>
</div>
<% end %>
<% if voted_for?(@featured_proposals_votes, proposal) %>

View File

@@ -31,24 +31,24 @@
</div>
<% if user_signed_in? && current_user.organization? %>
<div class="organizations-votes" style='display:none' aria-hidden="false">
<p>
<%= t("votes.organizations") %>
</p>
</div>
<div class="participation-not-allowed" style='display:none' aria-hidden="false">
<p>
<%= t("votes.organizations") %>
</p>
</div>
<% elsif user_signed_in? && !proposal.votable_by?(current_user)%>
<div class="anonymous-votes" style='display:none' aria-hidden="false">
<p>
<%= t("votes.verified_only",
verify_account: link_to(t("votes.verify_account"), verification_path )).html_safe %>
</p>
</div>
<div class="participation-not-allowed" style='display:none' aria-hidden="false">
<p>
<%= t("votes.verified_only",
verify_account: link_to(t("votes.verify_account"), verification_path )).html_safe %>
</p>
</div>
<% elsif !user_signed_in? %>
<div class="not-logged" style='display:none' aria-hidden="false">
<%= t("votes.unauthenticated",
signin: link_to(t("votes.signin"), new_user_session_path),
signup: link_to(t("votes.signup"), new_user_registration_path)).html_safe %>
</div>
<div class="participation-not-allowed" style='display:none' aria-hidden="false">
<%= t("votes.unauthenticated",
signin: link_to(t("votes.signin"), new_user_session_path),
signup: link_to(t("votes.signup"), new_user_registration_path)).html_safe %>
</div>
<% end %>
<% if voted_for?(@proposal_votes, proposal) && setting['twitter_handle'] %>

View File

@@ -6,7 +6,7 @@
<% end %>
<main>
<div class="wrap row">
<div class="row">
<div id="proposals" class="proposals-list small-12 medium-9 column">
<div class="small-12 search-results">

View File

@@ -1,4 +1,4 @@
<div class="proposal-new row">
<div class="proposal-form row">
<div class="small-12 medium-9 column">
<%= render "shared/back_link" %>

View File

@@ -1,5 +1,5 @@
<main>
<div class="wrap row proposals-summary">
<div class="row proposals-summary">
<div id="proposals" class="proposals-list small-12 medium-9 column">
<%= render "shared/back_link" %>

View File

@@ -8,7 +8,7 @@
<% I18n.available_locales.map do |loc| %>
<option <%= "selected" if loc == I18n.locale %>
value="<%= current_path_with_query_params(locale: loc) %>">
<%= I18n.t("locale", locale: loc) %>
<%= name_for_locale(loc) %>
</option>
<% end %>
</select>

View File

@@ -24,7 +24,7 @@
</div>
<% if reason.present? && !user_voted_for %>
<div class="no-supports-allowed" style='display:none' aria-hidden="false">
<div class="participation-not-allowed" style='display:none' aria-hidden="false">
<p>
<%= t("votes.spending_proposals.#{reason}",
verify_account: link_to(t("votes.verify_account"), verification_path),

View File

@@ -6,7 +6,7 @@
<% end %>
<main>
<div class="wrap row">
<div class="row">
<div id="investment-projects" class="investment-projects-list small-12 medium-9 column">
<div class="small-12 search-results">

View File

@@ -1,4 +1,4 @@
<div class="spending-proposal-new row margin-top">
<div class="spending-proposal-form row margin-top">
<div class="small-12 medium-9 column">
<%= render "shared/back_link" %>

View File

@@ -20,11 +20,8 @@ module Consul
# The default locale is :en and all translations from config/locales/*.rb,yml are auto loaded.
# config.i18n.load_path += Dir[Rails.root.join('my', 'locales', '*.{rb,yml}').to_s]
config.i18n.default_locale = :es
config.i18n.available_locales = [:en, :es]
# Add the new directories to the locales load path
config.i18n.load_path += Dir[Rails.root.join('config', 'locales', '**', '*.{rb,yml}')]
config.i18n.available_locales = [:en, :es, :fr, 'pt-BR']
config.i18n.fallbacks = {'fr' => 'es', 'pt-br' => 'es'}
config.assets.paths << Rails.root.join("app", "assets", "fonts")
@@ -44,6 +41,7 @@ module Consul
config.autoload_paths << "#{Rails.root}/app/controllers/custom"
config.autoload_paths << "#{Rails.root}/app/models/custom"
config.paths['app/views'].unshift(Rails.root.join('app', 'views', 'custom'))
config.i18n.load_path += Dir[Rails.root.join('config', 'locales', 'custom', '*.{rb,yml}')]
end
end

View File

@@ -3,7 +3,7 @@
# The "main" locale.
base_locale: en
## All available locales are inferred from the data by default. Alternatively, specify them explicitly:
# locales: [es, fr]
locales: [en, es]
## Reporting locale, default: en. Available: en, ru.
# internal_locale: en
@@ -101,6 +101,7 @@ ignore_missing:
- 'errors.messages.taken'
- 'devise.failure.invalid'
- 'devise.registrations.destroyed'
- 'devise.password_expired.*'
## Consider these keys used:
ignore_unused:

View File

@@ -0,0 +1,71 @@
Devise.setup do |config|
# ==> Security Extension
# Configure security extension for devise
# Should the password expire (e.g 3.months)
# config.expire_password_after = false
config.expire_password_after = 1.year
# Need 1 char of A-Z, a-z and 0-9
# config.password_regex = /(?=.*\\d)(?=.*[a-z])(?=.*[A-Z])/
# How many passwords to keep in archive
#config.password_archiving_count = 5
# Deny old password (true, false, count)
# config.deny_old_passwords = true
# enable email validation for :secure_validatable. (true, false, validation_options)
# dependency: need an email validator like rails_email_validator
# config.email_validation = true
# captcha integration for recover form
# config.captcha_for_recover = true
# captcha integration for sign up form
# config.captcha_for_sign_up = true
# captcha integration for sign in form
# config.captcha_for_sign_in = true
# captcha integration for unlock form
# config.captcha_for_unlock = true
# captcha integration for confirmation form
# config.captcha_for_confirmation = true
# Time period for account expiry from last_activity_at
# config.expire_after = 90.days
end
module Devise
module Models
module PasswordExpirable
def need_change_password?
self.administrator? && password_expired?
end
def password_expired?
self.password_changed_at < self.expire_password_after.ago
end
end
module SecureValidatable
def self.included(base)
base.extend ClassMethods
assert_secure_validations_api!(base)
base.class_eval do
validate :current_equal_password_validation
end
end
def current_equal_password_validation
if !self.new_record? && !self.encrypted_password_change.nil? && !self.erased?
dummy = self.class.new
dummy.encrypted_password = self.encrypted_password_change.first
dummy.password_salt = self.password_salt_change.first if self.respond_to? :password_salt_change and not self.password_salt_change.nil?
self.errors.add(:password, :equal_to_current_password) if dummy.valid_password?(self.password)
end
end
end
end
end

View File

@@ -54,6 +54,7 @@ en:
username: "Username"
password_confirmation: "Password confirmation"
password: "Password"
current_password: "Current password"
phone_number: "Phone number"
official_position: "Official position"
official_level: "Official level"

View File

@@ -54,6 +54,7 @@ es:
username: "Nombre de usuario"
password_confirmation: "Confirmación de contraseña"
password: "Contraseña"
current_password: "Contraseña actual"
phone_number: "Teléfono"
official_position: "Cargo público"
official_level: "Nivel del cargo"

View File

@@ -2,6 +2,12 @@
en:
devise:
password_expired:
expire_password: "Password expired"
change_required: "Your password is expired"
change_password: "Change your password"
new_password: "New password"
updated: "Password successfully updated"
confirmations:
confirmed: "Your account has been confirmed."
send_instructions: "In a few minutes you will receive an email containing instructions on how to reset your password."
@@ -62,3 +68,4 @@ en:
not_saved:
one: "1 error prevented this %{resource} from being saved:"
other: "%{count} errors prevented this %{resource} from being saved:"
equal_to_current_password: "must be different than the current password."

View File

@@ -1,5 +1,11 @@
es:
devise:
password_expired:
expire_password: "Contraseña caducada"
change_required: "Tu contraseña ha caducado"
change_password: "Cambia tu contraseña"
new_password: "Nueva contraseña"
updated: "Contraseña actualizada con éxito"
confirmations:
confirmed: "Tu cuenta ha sido confirmada. Por favor autentifícate con tu red social o tu usuario y contraseña"
send_instructions: "Recibirás un correo electrónico en unos minutos con instrucciones sobre cómo restablecer tu contraseña."
@@ -60,3 +66,4 @@ es:
not_saved:
one: "1 error impidió que este %{resource} fuera guardado:"
other: "%{count} errores impidieron que este %{resource} fuera guardado:"
equal_to_current_password: "debe ser diferente a la contraseña actual"

View File

@@ -1,5 +1,8 @@
---
pt-BR:
i18n:
language:
name: Português
account:
show:
change_credentials_link: Alterar meus dados pessoais

View File

@@ -14,7 +14,18 @@ en:
months_to_archive_proposals: "Months to archive Proposals"
email_domain_for_officials: "Email domain for public officials"
per_page_code: "Code to be included on every page"
twitter_handle: "Twitter handle"
twitter_hashtag: "Twitter hashtag"
facebook_handle: "Facebook handle"
youtube_handle: "Youtube handle"
blog_url: "Blog URL"
url: "Main URL"
org_name: "Organization"
place_name: "Place"
feature:
twitter_login: Twitter login
facebook_login: Facebook login
google_login: Google login
debates: Debates
spending_proposals: Investment projects
spending_proposal_features:

View File

@@ -14,7 +14,18 @@ es:
months_to_archive_proposals: "Meses para archivar las Propuestas"
email_domain_for_officials: "Dominio de email para cargos públicos"
per_page_code: "Código a incluir en cada página"
twitter_handle: "Usuario de Twitter"
twitter_hashtag: "Hashtag para Twitter"
facebook_handle: "Identificador de Facebook"
youtube_handle: "Usuario de Youtube"
blog_url: "URL del blog"
url: "URL general de la web"
org_name: "Nombre de la organización"
place_name: "Nombre del lugar"
feature:
twitter_login: Registro con Twitter
facebook_login: Registro con Facebook
google_login: Registro con Google
debates: Debates
spending_proposals: Propuestas de inversión
spending_proposal_features:

View File

@@ -0,0 +1,6 @@
class AddPasswordExpired < ActiveRecord::Migration
def change
add_column :users, :password_changed_at, :datetime
add_index :users, :password_changed_at
end
end

View File

@@ -0,0 +1,5 @@
class DefaultPasswordChangedAt < ActiveRecord::Migration
def change
change_column :users, :password_changed_at, :datetime, null: false, default: Time.now
end
end

View File

@@ -11,7 +11,7 @@
#
# It's strongly recommended that you check this file into your version control system.
ActiveRecord::Schema.define(version: 20160803154011) do
ActiveRecord::Schema.define(version: 20161102133838) do
# These are extensions that must be enabled in order to support this database
enable_extension "plpgsql"
@@ -413,17 +413,17 @@ ActiveRecord::Schema.define(version: 20160803154011) do
create_table "users", force: :cascade do |t|
t.string "email", default: ""
t.string "encrypted_password", default: "", null: false
t.string "encrypted_password", default: "", null: false
t.string "reset_password_token"
t.datetime "reset_password_sent_at"
t.datetime "remember_created_at"
t.integer "sign_in_count", default: 0, null: false
t.integer "sign_in_count", default: 0, null: false
t.datetime "current_sign_in_at"
t.datetime "last_sign_in_at"
t.string "current_sign_in_ip"
t.string "last_sign_in_ip"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.string "confirmation_token"
t.datetime "confirmed_at"
t.datetime "confirmation_sent_at"
@@ -464,12 +464,14 @@ ActiveRecord::Schema.define(version: 20160803154011) do
t.boolean "email_digest", default: true
t.boolean "email_on_direct_message", default: true
t.boolean "official_position_badge", default: false
t.datetime "password_changed_at", default: '2016-11-02 13:51:14', null: false
end
add_index "users", ["confirmation_token"], name: "index_users_on_confirmation_token", unique: true, using: :btree
add_index "users", ["email"], name: "index_users_on_email", unique: true, using: :btree
add_index "users", ["geozone_id"], name: "index_users_on_geozone_id", using: :btree
add_index "users", ["hidden_at"], name: "index_users_on_hidden_at", using: :btree
add_index "users", ["password_changed_at"], name: "index_users_on_password_changed_at", using: :btree
add_index "users", ["reset_password_token"], name: "index_users_on_reset_password_token", unique: true, using: :btree
add_index "users", ["username"], name: "index_users_on_username", using: :btree

View File

@@ -2,6 +2,8 @@
## Linux
See [here](dev_test_setup_linux.md)
## Mac OS X
See [here](dev_test_setup_osx.md)

View File

@@ -0,0 +1,126 @@
# Configuration for development and test environments (GNU/Linux)
## Git
Git is officially maintained in Debian/Ubuntu:
```
sudo apt-get install git
```
## Ruby
Ruby versions packaged in official repositories are not suitable to work with consul (at least Debian 7 and 8), so we'll have to install it manually.
The preferred method is via rvm:
(only the multi user option installs all dependencies automatically, as we use 'sudo'.)
###as local user:
```
curl -L https://get.rvm.io | bash -s stable
```
###for all system users
```
curl -L https://get.rvm.io | sudo bash -s stable
```
and then add your user to rvm group
```
sudo usermod -a -G rvm <user>
```
and finally, add rvm script source to user's bash (~/.bashrc) (this step it's only necessary if you still can't execute rvm command)
```
[[ -s /usr/local/rvm/scripts/rvm ]] && source /usr/local/rvm/scripts/rvm
```
with all this, you are suppose to be able to install a ruby version from rvm, as for example version 2.3.0:
```
sudo rvm install 2.3.0
```
## Bundler
with
```
gem install bundler
```
or there is more methods [here](https://rvm.io/integration/bundler) that should be better as:
```
gem install rubygems-bundler
```
## PostgreSQL (>=9.4)
PostgreSQL version 9.4 is not official in debian 7 (wheezy), in 8 it seems to be officially maintained.
So you have to add a repository, the official postgresql works fine.
Add the repository to apt, for example creating file */etc/apt/sources.list.d/pgdg.list* with:
```
deb http://apt.postgresql.org/pub/repos/apt/ wheezy-pgdg main
```
afterwards you'll have to download the key, and install it, by:
```
wget https://www.postgresql.org/media/keys/ACCC4CF8.asc
apt-key add ACCC4CF8.asc
```
and install postgresql
```
apt-get update
apt-get install postgresql-9.4
```
## Ghostscript
```
apt-get install ghostscript
```
## Cloning the repository
Now, with all the dependencies installed, clone the Consul repository:
```
git clone https://github.com/consul/consul.git
cd consul
bundle install
cp config/database.yml.example config/database.yml
cp config/secrets.yml.example config/secrets.yml
```
Perhaps it's needed to create a superuser rol with password in postgresql, and write it in */config/database.yml* 'user:' and 'password:' fields.
Also, it seems that postgresql use as default an unix socket for localhost communications. If we encounter problems creating database (connection problems) we can change in */config/database.yml* the line:
```
host: localhost
```
for:
```
host: /var/run/postgresql
```
After this:
```
rake db:create
rake db:setup
rake db:dev_seed
RAILS_ENV=test bin/rake db:setup
```

View File

@@ -76,4 +76,12 @@ namespace :users do
task remove_erased_identities: :environment do
Identity.joins(:user).where('users.erased_at IS NOT NULL').destroy_all
end
desc "Update password changed at for existing users"
task update_password_changed_at: :environment do
User.all.each do |user|
user.update(password_changed_at: user.created_at)
end
end
end

View File

@@ -0,0 +1,22 @@
require 'rails_helper'
# This module tests functionality related with custom application files
# TODO test models, controllers, etc...
describe 'CustomizationEngine' do
let(:test_key) { I18n.t('account.show.change_credentials_link') }
it "should load custom and override original locales" do
I18n.load_path += Dir[Rails.root.join('spec', 'support', 'locales', 'custom', '*.{rb,yml}')]
I18n.reload!
expect(test_key).to eq 'Overriden string with custom locales'
end
it "should not override original locales" do
I18n.load_path.delete_if {|item| item =~ /spec\/support\/locales\/custom/ }
I18n.load_path += Dir[Rails.root.join('spec', 'support', 'locales', '**', '*.{rb,yml}')]
I18n.reload!
expect(test_key).to eq 'Not overriden string with custom locales'
end
end

View File

@@ -285,4 +285,59 @@ feature 'Users' do
expect(page).to have_content "Your password has been changed successfully."
end
scenario 'Sign in, admin with password expired' do
user = create(:user, password_changed_at: Time.now - 1.year)
admin = create(:administrator, user: user)
login_as(admin.user)
visit root_path
expect(page).to have_content "Your password is expired"
fill_in 'user_current_password', with: 'judgmentday'
fill_in 'user_password', with: '123456789'
fill_in 'user_password_confirmation', with: '123456789'
click_button 'Change your password'
expect(page).to have_content "Password successfully updated"
end
scenario 'Sign in, admin without password expired' do
user = create(:user, password_changed_at: Time.now - 360.days)
admin = create(:administrator, user: user)
login_as(admin.user)
visit root_path
expect(page).to_not have_content "Your password is expired"
end
scenario 'Sign in, user with password expired' do
user = create(:user, password_changed_at: Time.now - 1.year)
login_as(user)
visit root_path
expect(page).to_not have_content "Your password is expired"
end
scenario 'Admin with password expired trying to use same password' do
user = create(:user, password_changed_at: Time.now - 1.year, password: '123456789')
admin = create(:administrator, user: user)
login_as(admin.user)
visit root_path
expect(page).to have_content "Your password is expired"
fill_in 'user_current_password', with: 'judgmentday'
fill_in 'user_password', with: '123456789'
fill_in 'user_password_confirmation', with: '123456789'
click_button 'Change your password'
expect(page).to have_content "must be different than the current password."
end
end

View File

@@ -793,54 +793,50 @@ describe Proposal do
end
describe "retired" do
before(:all) do
@proposal1 = create(:proposal)
@proposal2 = create(:proposal, retired_at: Time.now)
end
let!(:proposal1) { create(:proposal) }
let!(:proposal2) { create(:proposal, retired_at: Time.now) }
it "retired? is true" do
expect(@proposal1.retired?).to eq false
expect(@proposal2.retired?).to eq true
expect(proposal1.retired?).to eq false
expect(proposal2.retired?).to eq true
end
it "scope retired" do
retired = Proposal.retired
expect(retired.size).to eq(1)
expect(retired.first).to eq(@proposal2)
expect(retired.first).to eq(proposal2)
end
it "scope not_retired" do
not_retired = Proposal.not_retired
expect(not_retired.size).to eq(1)
expect(not_retired.first).to eq(@proposal1)
expect(not_retired.first).to eq(proposal1)
end
end
describe "archived" do
before(:each) do
@new_proposal = create(:proposal)
@archived_proposal = create(:proposal, :archived)
end
let!(:new_proposal) { create(:proposal) }
let!(:archived_proposal) { create(:proposal, :archived) }
it "archived? is true only for proposals created more than n (configured months) ago" do
expect(@new_proposal.archived?).to eq false
expect(@archived_proposal.archived?).to eq true
expect(new_proposal.archived?).to eq false
expect(archived_proposal.archived?).to eq true
end
it "scope archived" do
archived = Proposal.archived
expect(archived.size).to eq(1)
expect(archived.first).to eq(@archived_proposal)
expect(archived.first).to eq(archived_proposal)
end
it "scope archived" do
not_archived = Proposal.not_archived
expect(not_archived.size).to eq(1)
expect(not_archived.first).to eq(@new_proposal)
expect(not_archived.first).to eq(new_proposal)
end
end

View File

@@ -161,8 +161,8 @@ module CommonActions
def expect_message_you_need_to_sign_in_to_vote_comments
expect(page).to have_content 'You must Sign in or Sign up to vote'
expect(page).to have_selector('.logged', visible: false)
expect(page).to have_selector('.not-logged', visible: true)
expect(page).to have_selector('.participation-allowed', visible: false)
expect(page).to have_selector('.participation-not-allowed', visible: true)
end
def expect_message_to_many_anonymous_votes

View File

@@ -0,0 +1,5 @@
---
en:
account:
show:
change_credentials_link: Overriden string with custom locales

View File

@@ -0,0 +1,5 @@
---
en:
account:
show:
change_credentials_link: Not overriden string with custom locales