diff --git a/Gemfile b/Gemfile
index f1b251db4..e381bc516 100644
--- a/Gemfile
+++ b/Gemfile
@@ -1,7 +1,7 @@
source 'https://rubygems.org'
# Bundle edge Rails instead: gem 'rails', github: 'rails/rails'
-gem 'rails', '4.2.3'
+gem 'rails', '4.2.4'
# Use PostgreSQL
gem 'pg'
# Use SCSS for stylesheets
@@ -21,6 +21,11 @@ gem 'turbolinks'
gem 'devise'
# Use ActiveModel has_secure_password
# gem 'bcrypt', '~> 3.1.7'
+gem 'omniauth'
+gem 'omniauth-twitter'
+gem 'omniauth-facebook'
+gem 'omniauth-google-oauth2'
+
gem 'kaminari'
gem 'acts_as_commentable_with_threading'
gem 'acts-as-taggable-on'
@@ -32,7 +37,7 @@ gem 'simple_captcha2', require: 'simple_captcha'
gem 'ckeditor'
gem 'cancancan'
gem 'social-share-button'
-gem 'initialjs-rails'
+gem 'initialjs-rails', '0.2.0'
gem 'unicorn'
gem 'paranoia'
@@ -58,6 +63,7 @@ group :development, :test do
gem "capistrano-bundler", '1.1.4', require: false
gem "capistrano-rails", '1.1.3', require: false
gem "capistrano-rvm", require: false
+ gem "bullet"
end
group :test do
diff --git a/Gemfile.lock b/Gemfile.lock
index db469b072..78a442608 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -1,36 +1,36 @@
GEM
remote: https://rubygems.org/
specs:
- actionmailer (4.2.3)
- actionpack (= 4.2.3)
- actionview (= 4.2.3)
- activejob (= 4.2.3)
+ actionmailer (4.2.4)
+ actionpack (= 4.2.4)
+ actionview (= 4.2.4)
+ activejob (= 4.2.4)
mail (~> 2.5, >= 2.5.4)
rails-dom-testing (~> 1.0, >= 1.0.5)
- actionpack (4.2.3)
- actionview (= 4.2.3)
- activesupport (= 4.2.3)
+ actionpack (4.2.4)
+ actionview (= 4.2.4)
+ activesupport (= 4.2.4)
rack (~> 1.6)
rack-test (~> 0.6.2)
rails-dom-testing (~> 1.0, >= 1.0.5)
rails-html-sanitizer (~> 1.0, >= 1.0.2)
- actionview (4.2.3)
- activesupport (= 4.2.3)
+ actionview (4.2.4)
+ activesupport (= 4.2.4)
builder (~> 3.1)
erubis (~> 2.7.0)
rails-dom-testing (~> 1.0, >= 1.0.5)
rails-html-sanitizer (~> 1.0, >= 1.0.2)
- activejob (4.2.3)
- activesupport (= 4.2.3)
+ activejob (4.2.4)
+ activesupport (= 4.2.4)
globalid (>= 0.3.0)
- activemodel (4.2.3)
- activesupport (= 4.2.3)
+ activemodel (4.2.4)
+ activesupport (= 4.2.4)
builder (~> 3.1)
- activerecord (4.2.3)
- activemodel (= 4.2.3)
- activesupport (= 4.2.3)
+ activerecord (4.2.4)
+ activemodel (= 4.2.4)
+ activesupport (= 4.2.4)
arel (~> 6.0)
- activesupport (4.2.3)
+ activesupport (4.2.4)
i18n (~> 0.7)
json (~> 1.7, >= 1.7.7)
minitest (~> 5.1)
@@ -62,6 +62,9 @@ GEM
debug_inspector (>= 0.0.1)
browser (0.9.1)
builder (3.2.2)
+ bullet (4.14.7)
+ activesupport (>= 3.0.0)
+ uniform_notifier (~> 1.9.0)
byebug (6.0.2)
cancancan (1.12.0)
capistrano (3.4.0)
@@ -133,6 +136,8 @@ GEM
factory_girl_rails (4.5.0)
factory_girl (~> 4.5.0)
railties (>= 3.0.0)
+ faraday (0.9.1)
+ multipart-post (>= 1.2, < 3)
foundation-rails (5.5.2.1)
railties (>= 3.1.0)
sass (>= 3.3.0, < 3.5)
@@ -150,6 +155,7 @@ GEM
activesupport (>= 4.1.0)
groupdate (2.4.0)
activesupport (>= 3)
+ hashie (3.4.2)
highline (1.7.3)
http-cookie (1.0.2)
domain_name (~> 0.5)
@@ -162,13 +168,14 @@ GEM
i18n
term-ansicolor (>= 1.3.2)
terminal-table (>= 1.5.1)
- initialjs-rails (0.1.0)
+ initialjs-rails (0.2.0)
railties (>= 3.1, < 5.0)
jquery-rails (4.0.4)
rails-dom-testing (~> 1.0)
railties (>= 4.2.0)
thor (>= 0.14, < 2.0)
json (1.8.3)
+ jwt (1.5.1)
kaminari (0.16.3)
actionpack (>= 3.0.0)
activesupport (>= 3.0.0)
@@ -181,7 +188,7 @@ GEM
actionmailer (>= 3.2)
letter_opener (~> 1.0)
railties (>= 3.2)
- loofah (2.0.2)
+ loofah (2.0.3)
nokogiri (>= 1.5.9)
mail (2.6.3)
mime-types (>= 1.16, < 3)
@@ -189,12 +196,38 @@ GEM
mini_portile (0.6.2)
minitest (5.8.0)
multi_json (1.11.2)
+ multi_xml (0.5.5)
+ multipart-post (2.0.0)
net-scp (1.2.1)
net-ssh (>= 2.6.5)
net-ssh (2.9.2)
netrc (0.10.3)
nokogiri (1.6.6.2)
mini_portile (~> 0.6.0)
+ oauth (0.4.7)
+ oauth2 (1.0.0)
+ faraday (>= 0.8, < 0.10)
+ jwt (~> 1.0)
+ multi_json (~> 1.3)
+ multi_xml (~> 0.5)
+ rack (~> 1.2)
+ omniauth (1.2.2)
+ hashie (>= 1.2, < 4)
+ rack (~> 1.0)
+ omniauth-facebook (2.0.1)
+ omniauth-oauth2 (~> 1.2)
+ omniauth-google-oauth2 (0.2.6)
+ omniauth (> 1.0)
+ omniauth-oauth2 (~> 1.1)
+ omniauth-oauth (1.1.0)
+ oauth
+ omniauth (~> 1.0)
+ omniauth-oauth2 (1.3.1)
+ oauth2 (~> 1.0)
+ omniauth (~> 1.2)
+ omniauth-twitter (1.2.1)
+ json (~> 1.3)
+ omniauth-oauth (~> 1.1)
orm_adapter (0.5.0)
paranoia (2.1.3)
activerecord (~> 4.0)
@@ -209,28 +242,28 @@ GEM
rack (1.6.4)
rack-test (0.6.3)
rack (>= 1.0)
- rails (4.2.3)
- actionmailer (= 4.2.3)
- actionpack (= 4.2.3)
- actionview (= 4.2.3)
- activejob (= 4.2.3)
- activemodel (= 4.2.3)
- activerecord (= 4.2.3)
- activesupport (= 4.2.3)
+ rails (4.2.4)
+ actionmailer (= 4.2.4)
+ actionpack (= 4.2.4)
+ actionview (= 4.2.4)
+ activejob (= 4.2.4)
+ activemodel (= 4.2.4)
+ activerecord (= 4.2.4)
+ activesupport (= 4.2.4)
bundler (>= 1.3.0, < 2.0)
- railties (= 4.2.3)
+ railties (= 4.2.4)
sprockets-rails
rails-deprecated_sanitizer (1.0.3)
activesupport (>= 4.2.0.alpha)
- rails-dom-testing (1.0.6)
+ rails-dom-testing (1.0.7)
activesupport (>= 4.2.0.beta, < 5.0)
nokogiri (~> 1.6.0)
rails-deprecated_sanitizer (>= 1.0.1)
rails-html-sanitizer (1.0.2)
loofah (~> 2.0)
- railties (4.2.3)
- actionpack (= 4.2.3)
- activesupport (= 4.2.3)
+ railties (4.2.4)
+ actionpack (= 4.2.4)
+ activesupport (= 4.2.4)
rake (>= 0.8.7)
thor (>= 0.18.1, < 2.0)
raindrops (0.15.0)
@@ -283,7 +316,7 @@ GEM
coffee-rails
sass-rails
spring (1.3.6)
- sprockets (3.2.0)
+ sprockets (3.3.3)
rack (~> 1.0)
sprockets-rails (2.3.2)
actionpack (>= 3.0)
@@ -315,6 +348,7 @@ GEM
kgio (~> 2.6)
rack
raindrops (~> 0.7)
+ uniform_notifier (1.9.0)
user_agent_parser (2.2.0)
uuidtools (2.1.5)
warden (1.2.3)
@@ -338,6 +372,7 @@ DEPENDENCIES
acts_as_commentable_with_threading
acts_as_votable
ahoy_matey (~> 1.2.1)
+ bullet
byebug
cancancan
capistrano (= 3.4.0)
@@ -357,16 +392,20 @@ DEPENDENCIES
fuubar
groupdate
i18n-tasks
- initialjs-rails
+ initialjs-rails (= 0.2.0)
jquery-rails
kaminari
launchy
letter_opener_web (~> 1.3.0)
+ omniauth
+ omniauth-facebook
+ omniauth-google-oauth2
+ omniauth-twitter
paranoia
pg
poltergeist
quiet_assets
- rails (= 4.2.3)
+ rails (= 4.2.4)
responders
rspec-rails (~> 3.0)
sass-rails (~> 5.0)
diff --git a/README.md b/README.md
index 6c8bbb453..a3433df9d 100644
--- a/README.md
+++ b/README.md
@@ -27,23 +27,29 @@ cd participacion
bundle install
cp config/database.yml.example config/database.yml
cp config/secrets.yml.example config/secrets.yml
-bundle exec bin/rake db:setup
-RAILS_ENV=test bundle exec rake db:setup
+bin/rake db:setup
+RAILS_ENV=test bin/rake db:setup
```
Para ejecutar la aplicación en local:
```
-bundle exec bin/rails s
+bin/rails s
```
-Prerequisitos para los tests: tener instalado PhantomJS >= 2.0
+Prerequisitos para los tests: tener instalado PhantomJS >= 2.0
Para ejecutar los tests:
```
-bundle exec bin/rspec
+bin/rspec
```
+### OAuth
+
+Para probar los servicios de autenticación mediante proveedores externos OAuth — en este momento Twitter, Facebook y Google —, necesitas crear una "aplicación" en cada una de las plataformas soportadas y configurar la *key* y el *secret* proporcionados en tu *secrets.yml*
+
+En el caso de Google, comprueba que las APIs *Contacts API* y *Google+ API* están habilitadas para la aplicación.
+
## Licencia
El código de este proyecto está publicado bajo la licencia AFFERO GPL v3 (ver [LICENSE-AGPLv3.txt](LICENSE-AGPLv3.txt))
diff --git a/README_EN.md b/README_EN.md
index 9ebc58731..a3dd63106 100644
--- a/README_EN.md
+++ b/README_EN.md
@@ -28,13 +28,13 @@ cd participacion
bundle install
cp config/database.yml.example config/database.yml
cp config/secrets.yml.example config/secrets.yml
-bundle exec bin/rake db:setup
-RAILS_ENV=test bundle exec rake db:setup
+bin/rake db:setup
+RAILS_ENV=test bin/rake db:setup
```
Run the app locally:
```
-bundle exec bin/rails s
+bin/rails s
```
Prerequisites for testing: install PhantomJS >= 2.0
@@ -42,7 +42,7 @@ Prerequisites for testing: install PhantomJS >= 2.0
Run the tests with:
```
-bundle exec bin/rspec
+bin/rspec
```
## Licence
diff --git a/app/assets/fonts/icons.eot b/app/assets/fonts/icons.eot
index 2c00f1f5b..a1cc83d43 100644
Binary files a/app/assets/fonts/icons.eot and b/app/assets/fonts/icons.eot differ
diff --git a/app/assets/fonts/icons.svg b/app/assets/fonts/icons.svg
index 2f04723b8..049938913 100644
--- a/app/assets/fonts/icons.svg
+++ b/app/assets/fonts/icons.svg
@@ -29,4 +29,5 @@
+
diff --git a/app/assets/fonts/icons.ttf b/app/assets/fonts/icons.ttf
index 808c75487..aa9c63faa 100644
Binary files a/app/assets/fonts/icons.ttf and b/app/assets/fonts/icons.ttf differ
diff --git a/app/assets/fonts/icons.woff b/app/assets/fonts/icons.woff
index cc9c32cdf..b17f63445 100644
Binary files a/app/assets/fonts/icons.woff and b/app/assets/fonts/icons.woff differ
diff --git a/app/assets/images/logo_email_gobierno_abierto.png b/app/assets/images/logo_email_gobierno_abierto.png
new file mode 100644
index 000000000..8fe100fce
Binary files /dev/null and b/app/assets/images/logo_email_gobierno_abierto.png differ
diff --git a/app/assets/stylesheets/admin.scss b/app/assets/stylesheets/admin.scss
index 7e6096bc3..5afa088d1 100644
--- a/app/assets/stylesheets/admin.scss
+++ b/app/assets/stylesheets/admin.scss
@@ -140,7 +140,7 @@ body.admin {
.delete {
border-bottom: 1px dotted #CF2A0E;
- color: #F04124;
+ color: $delete;
font-size: rem-calc(12);
&:hover, &:active, &:focus {
@@ -151,16 +151,27 @@ body.admin {
.verified {
color: $check;
+
+ a {
+ border-bottom: 1px dotted $check;
+ color: $check;
+ font-size: rem-calc(12);
+ }
}
-.verified a {
- border-bottom: 1px dotted $check;
- color: $check;
+.archived {
+ color: $text-medium;
font-size: rem-calc(12);
}
.rejected {
- color: #F04124;
+ color: $delete;
+}
+
+.date {
+ color: $text-medium;
+ font-size: rem-calc(12);
+ font-style: italic;
}
.level {
diff --git a/app/assets/stylesheets/debates.scss b/app/assets/stylesheets/debates.scss
index 66ea491af..641e7ccff 100644
--- a/app/assets/stylesheets/debates.scss
+++ b/app/assets/stylesheets/debates.scss
@@ -5,6 +5,7 @@
// 03. Show
// 04. New
// 05. Comments
+// 06. Flags
//
// 01. Debates
@@ -541,6 +542,10 @@
font-size: rem-calc(12);
margin: rem-calc(6) 0;
padding: rem-calc(6);
+
+ .divider {
+ color: $text-light;
+ }
}
.comment-user {
@@ -608,3 +613,17 @@
.faded {
opacity: 0.4;
}
+
+// 06. Flags
+// - - - - - - - - - - - - - - - - - - - - - - - - -
+
+.flag-disable {
+ color: $text-medium;
+ line-height: rem-calc(24);
+ vertical-align: middle;
+}
+
+.flag-active {
+ @extend .flag-disable;
+ color: $delete;
+}
diff --git a/app/assets/stylesheets/icons.scss b/app/assets/stylesheets/icons.scss
index ac6bb9dab..6a014579c 100644
--- a/app/assets/stylesheets/icons.scss
+++ b/app/assets/stylesheets/icons.scss
@@ -103,3 +103,7 @@
.icon-x:before {
content: "v";
}
+.icon-flag:before {
+ content: "w";
+}
+
diff --git a/app/assets/stylesheets/participacion.scss b/app/assets/stylesheets/participacion.scss
index 485dbfd60..e20a2cb36 100644
--- a/app/assets/stylesheets/participacion.scss
+++ b/app/assets/stylesheets/participacion.scss
@@ -135,6 +135,7 @@ h1, h2, h3, h4, h5, h6 {
}
.sub-nav dt, .sub-nav dd, .sub-nav li {
+ padding: rem-calc(3) 0;
&.active {
background: #008CBA;
@@ -142,7 +143,7 @@ h1, h2, h3, h4, h5, h6 {
color: white;
cursor: default;
font-weight: normal;
- padding: 0.16667rem 0.88889rem;
+ padding: rem-calc(3) rem-calc(14);
a:hover {
color: #737373;
@@ -150,6 +151,37 @@ h1, h2, h3, h4, h5, h6 {
}
}
+.f-dropdown {
+ li a {
+ font-size: rem-calc(12);
+
+ &:hover {
+ color: $link-hover;
+ }
+ }
+
+ li:hover, .f-dropdown li:focus {
+ background: white;
+ }
+
+ &.open {
+ outline: none;
+ }
+}
+
+.margin {
+ margin-top: $line-height;
+ margin-bottom: $line-height;
+}
+
+.margin-top {
+ margin-top: $line-height;
+}
+
+.margin-bottom {
+ margin-bottom: $line-height;
+}
+
// 04. Header
// - - - - - - - - - - - - - - - - - - - - - - - - -
@@ -494,9 +526,14 @@ footer {
h2 {
clear: both;
- font-size: rem-calc(30);
+ font-size: rem-calc(18);
font-weight: bold;
- line-height: $line-height*2;
+ line-height: $line-height;
+
+ @media (min-width: $small-breakpoint) {
+ font-size: rem-calc(30);
+ line-height: $line-height*2;
+ }
}
.back, .icon-angle-left {
@@ -692,13 +729,13 @@ form {
}
}
-img.admin-avatar, img.moderator-avatar {
+img.avatar, img.admin-avatar, img.moderator-avatar {
border-radius: rem-calc(1000);
position: relative;
}
img.initialjs-avatar {
- @extend .moderator-avatar;
+ @extend .avatar;
}
.author-deleted {
diff --git a/app/assets/stylesheets/variables.scss b/app/assets/stylesheets/variables.scss
index 4be7028e3..6240702d2 100644
--- a/app/assets/stylesheets/variables.scss
+++ b/app/assets/stylesheets/variables.scss
@@ -38,6 +38,7 @@ $votes-like-act: #5D9E7F;
$votes-unlike: #EF8585;
$votes-unlike-act: #BD6A6A;
+$delete: #F04124;
$check: #46DB91;
// 03. Forms
@@ -84,6 +85,7 @@ $comment-official: rgba(70,219,145,.3);
// 06. Responsive
// - - - - - - - - - - - - - - - - - - - - - - - - -
+$small: em-calc(480);
$small-breakpoint: em-calc(640);
$medium-breakpoint: em-calc(1024);
$large-breakpoint: em-calc(1440);
diff --git a/app/controllers/admin/officials_controller.rb b/app/controllers/admin/officials_controller.rb
index 023f0f7fc..f83aa1e18 100644
--- a/app/controllers/admin/officials_controller.rb
+++ b/app/controllers/admin/officials_controller.rb
@@ -1,11 +1,11 @@
class Admin::OfficialsController < Admin::BaseController
def index
- @officials = User.officials.page(params[:page])
+ @officials = User.officials.page(params[:page]).for_render
end
def search
- @users = User.with_email(params[:email]).page(params[:page])
+ @users = User.with_email(params[:email]).page(params[:page]).for_render
end
def edit
@@ -29,4 +29,4 @@ class Admin::OfficialsController < Admin::BaseController
params.require(:user).permit(:official_position, :official_level)
end
-end
\ No newline at end of file
+end
diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb
index b879a4a8d..802dda3bc 100644
--- a/app/controllers/application_controller.rb
+++ b/app/controllers/application_controller.rb
@@ -13,6 +13,8 @@ class ApplicationController < ActionController::Base
# For APIs, you may want to use :null_session instead.
protect_from_forgery with: :exception
+ before_action :ensure_signup_complete
+
rescue_from CanCan::AccessDenied do |exception|
redirect_to main_app.root_url, alert: exception.message
end
@@ -40,4 +42,13 @@ class ApplicationController < ActionController::Base
def set_debate_votes(debates)
@voted_values = current_user ? current_user.debate_votes(debates) : {}
end
+
+ def ensure_signup_complete
+ # Ensure we don't go into an infinite loop
+ return if action_name.in? %w(finish_signup do_finish_signup)
+
+ if user_signed_in? && !current_user.email_provided?
+ redirect_to finish_signup_path
+ end
+ end
end
diff --git a/app/controllers/debates_controller.rb b/app/controllers/debates_controller.rb
index f8e7b968a..cf6d14f65 100644
--- a/app/controllers/debates_controller.rb
+++ b/app/controllers/debates_controller.rb
@@ -5,13 +5,13 @@ class DebatesController < ApplicationController
respond_to :html, :js
def index
- @debates = Debate.includes(:tags).includes(:inappropiate_flags).search(params).page(params[:page])
+ @debates = Debate.search(params).page(params[:page]).for_render
set_debate_votes(@debates)
end
def show
set_debate_votes(@debate)
- @comments = @debate.root_comments.with_hidden.includes(:inappropiate_flags).recent.page(params[:page])
+ @comments = @debate.root_comments.recent.page(params[:page]).for_render
end
def new
diff --git a/app/controllers/moderation/comments_controller.rb b/app/controllers/moderation/comments_controller.rb
index 03667e286..8a4d3768e 100644
--- a/app/controllers/moderation/comments_controller.rb
+++ b/app/controllers/moderation/comments_controller.rb
@@ -19,8 +19,8 @@ class Moderation::CommentsController < Moderation::BaseController
redirect_to request.query_parameters.merge(action: :index)
end
- def mark_as_reviewed
- @comment.mark_as_reviewed
+ def archive
+ @comment.archive
redirect_to request.query_parameters.merge(action: :index)
end
@@ -31,7 +31,7 @@ class Moderation::CommentsController < Moderation::BaseController
end
def set_valid_filters
- @valid_filters = %w{all pending_review reviewed}
+ @valid_filters = %w{all pending archived}
end
def parse_filter
diff --git a/app/controllers/moderation/debates_controller.rb b/app/controllers/moderation/debates_controller.rb
index 22e4eac6b..3492ee423 100644
--- a/app/controllers/moderation/debates_controller.rb
+++ b/app/controllers/moderation/debates_controller.rb
@@ -19,8 +19,8 @@ class Moderation::DebatesController < Moderation::BaseController
redirect_to request.query_parameters.merge(action: :index)
end
- def mark_as_reviewed
- @debate.mark_as_reviewed
+ def archive
+ @debate.archive
redirect_to request.query_parameters.merge(action: :index)
end
@@ -31,7 +31,7 @@ class Moderation::DebatesController < Moderation::BaseController
end
def set_valid_filters
- @valid_filters = %w{all pending_review reviewed}
+ @valid_filters = %w{all pending archived}
end
def parse_filter
diff --git a/app/controllers/organizations/registrations_controller.rb b/app/controllers/organizations/registrations_controller.rb
index 8602ba4ba..630cc64e4 100644
--- a/app/controllers/organizations/registrations_controller.rb
+++ b/app/controllers/organizations/registrations_controller.rb
@@ -5,6 +5,9 @@ class Organizations::RegistrationsController < Devise::RegistrationsController
end
end
+ def success
+ end
+
def create
build_resource(sign_up_params)
if resource.valid_with_captcha?
@@ -17,6 +20,11 @@ class Organizations::RegistrationsController < Devise::RegistrationsController
end
end
+ protected
+ def after_inactive_sign_up_path_for(resource)
+ organizations_sign_up_success_path
+ end
+
private
def sign_up_params
diff --git a/app/controllers/users/omniauth_callbacks_controller.rb b/app/controllers/users/omniauth_callbacks_controller.rb
new file mode 100644
index 000000000..8588ba243
--- /dev/null
+++ b/app/controllers/users/omniauth_callbacks_controller.rb
@@ -0,0 +1,29 @@
+class Users::OmniauthCallbacksController < Devise::OmniauthCallbacksController
+ def self.provides_callback_for(provider)
+ class_eval %Q{
+ def #{provider}
+ @user = User.find_for_oauth(env["omniauth.auth"], current_user)
+
+ if @user.persisted?
+ sign_in_and_redirect @user, event: :authentication
+ set_flash_message(:notice, :success, kind: "#{provider}".capitalize) if is_navigational_format?
+ else
+ session["devise.#{provider}_data"] = env["omniauth.auth"]
+ redirect_to new_user_registration_url
+ end
+ end
+ }
+ end
+
+ [:twitter, :facebook, :google_oauth2].each do |provider|
+ provides_callback_for provider
+ end
+
+ def after_sign_in_path_for(resource)
+ if resource.email_provided?
+ super(resource)
+ else
+ finish_signup_path
+ end
+ end
+end
diff --git a/app/controllers/users/registrations_controller.rb b/app/controllers/users/registrations_controller.rb
index 0ef0ba638..4ce5998c8 100644
--- a/app/controllers/users/registrations_controller.rb
+++ b/app/controllers/users/registrations_controller.rb
@@ -1,4 +1,5 @@
class Users::RegistrationsController < Devise::RegistrationsController
+ prepend_before_filter :authenticate_scope!, only: [:edit, :update, :destroy, :finish_signup, :do_finish_signup]
def create
build_resource(sign_up_params)
@@ -9,6 +10,19 @@ class Users::RegistrationsController < Devise::RegistrationsController
end
end
+ def finish_signup
+ end
+
+ def do_finish_signup
+ if current_user.update(sign_up_params)
+ current_user.skip_reconfirmation!
+ sign_in(current_user, bypass: true)
+ redirect_to root_url
+ else
+ render :finish_signup
+ end
+ end
+
private
def sign_up_params
diff --git a/app/models/ability.rb b/app/models/ability.rb
index a29f09a60..c8ed63d22 100644
--- a/app/models/ability.rb
+++ b/app/models/ability.rb
@@ -53,14 +53,14 @@ class Ability
can :hide, Comment, hidden_at: nil
cannot :hide, Comment, user_id: user.id
- can :mark_as_reviewed, Comment, reviewed_at: nil, hidden_at: nil
- cannot :mark_as_reviewed, Comment, user_id: user.id
+ can :archive, Comment, archived_at: nil, hidden_at: nil
+ cannot :archive, Comment, user_id: user.id
can :hide, Debate, hidden_at: nil
cannot :hide, Debate, author_id: user.id
- can :mark_as_reviewed, Debate, reviewed_at: nil, hidden_at: nil
- cannot :mark_as_reviewed, Debate, author_id: user.id
+ can :archive, Debate, archived_at: nil, hidden_at: nil
+ cannot :archive, Debate, author_id: user.id
can :hide, User
cannot :hide, User, id: user.id
diff --git a/app/models/comment.rb b/app/models/comment.rb
index 824f1dbf0..bbfeca4f5 100644
--- a/app/models/comment.rb
+++ b/app/models/comment.rb
@@ -9,19 +9,20 @@ class Comment < ActiveRecord::Base
validates :body, presence: true
validates :user, presence: true
- belongs_to :commentable, polymorphic: true
+ belongs_to :commentable, polymorphic: true, counter_cache: true
belongs_to :user, -> { with_hidden }
has_many :inappropiate_flags, :as => :flaggable
- default_scope { includes(:user) }
scope :recent, -> { order(id: :desc) }
scope :sorted_for_moderation, -> { order(inappropiate_flags_count: :desc, updated_at: :desc) }
- scope :pending_review, -> { where(reviewed_at: nil, hidden_at: nil) }
- scope :reviewed, -> { where("reviewed_at IS NOT NULL AND hidden_at IS NULL") }
+ scope :pending, -> { where(archived_at: nil, hidden_at: nil) }
+ scope :archived, -> { where("archived_at IS NOT NULL AND hidden_at IS NULL") }
scope :flagged_as_inappropiate, -> { where("inappropiate_flags_count > 0") }
+ scope :for_render, -> { with_hidden.includes(user: :organization) }
+
def self.build(commentable, user, body)
new commentable: commentable,
user_id: user.id,
@@ -49,15 +50,23 @@ class Comment < ActiveRecord::Base
end
def total_votes
- votes_for.size
+ cached_votes_total
+ end
+
+ def total_likes
+ cached_votes_up
+ end
+
+ def total_dislikes
+ cached_votes_down
end
def not_visible?
hidden? || user.hidden?
end
- def reviewed?
- reviewed_at.present?
+ def archived?
+ archived_at.present?
end
def as_administrator?
@@ -68,8 +77,8 @@ class Comment < ActiveRecord::Base
moderator_id.present?
end
- def mark_as_reviewed
- update(reviewed_at: Time.now)
+ def archive
+ update(archived_at: Time.now)
end
# TODO: faking counter cache since there is a bug with acts_as_nested_set :counter_cache
@@ -80,4 +89,8 @@ class Comment < ActiveRecord::Base
children.count
end
+ def after_hide
+ commentable_type.constantize.reset_counters(commentable_id, :comment_threads)
+ end
+
end
diff --git a/app/models/debate.rb b/app/models/debate.rb
index c16048f70..15590fc60 100644
--- a/app/models/debate.rb
+++ b/app/models/debate.rb
@@ -24,9 +24,10 @@ class Debate < ActiveRecord::Base
before_validation :sanitize_tag_list
scope :sorted_for_moderation, -> { order(inappropiate_flags_count: :desc, updated_at: :desc) }
- scope :pending_review, -> { where(reviewed_at: nil, hidden_at: nil) }
- scope :reviewed, -> { where("reviewed_at IS NOT NULL AND hidden_at IS NULL") }
+ scope :pending, -> { where(archived_at: nil, hidden_at: nil) }
+ scope :archived, -> { where("archived_at IS NOT NULL AND hidden_at IS NULL") }
scope :flagged_as_inappropiate, -> { where("inappropiate_flags_count > 0") }
+ scope :for_render, -> { includes(:tags) }
# Ahoy setup
visitable # Ahoy will automatically assign visit_id on create
@@ -40,15 +41,15 @@ class Debate < ActiveRecord::Base
end
def likes
- get_likes.size
+ cached_votes_up
end
def dislikes
- get_dislikes.size
+ cached_votes_down
end
def total_votes
- votes_for.size
+ cached_votes_total
end
def editable?
@@ -74,12 +75,12 @@ class Debate < ActiveRecord::Base
count < 0 ? 0 : count
end
- def reviewed?
- reviewed_at.present?
+ def archived?
+ archived_at.present?
end
- def mark_as_reviewed
- update(reviewed_at: Time.now)
+ def archive
+ update(archived_at: Time.now)
end
protected
diff --git a/app/models/identity.rb b/app/models/identity.rb
new file mode 100644
index 000000000..3ba19e3fa
--- /dev/null
+++ b/app/models/identity.rb
@@ -0,0 +1,17 @@
+class Identity < ActiveRecord::Base
+ belongs_to :user
+
+ validates :provider, presence: true
+ validates :uid, presence: true, uniqueness: { scope: :provider }
+
+ def self.find_for_oauth(auth)
+ where(uid: auth.uid, provider: auth.provider).first_or_create
+ end
+
+ def update_user(new_user)
+ return unless user != new_user
+
+ self.user = new_user
+ save!
+ end
+end
diff --git a/app/models/user.rb b/app/models/user.rb
index 179686725..355a1c326 100644
--- a/app/models/user.rb
+++ b/app/models/user.rb
@@ -1,8 +1,12 @@
class User < ActiveRecord::Base
include ActsAsParanoidAliases
+
+ OMNIAUTH_EMAIL_PREFIX = 'omniauth@participacion'
+ OMNIAUTH_EMAIL_REGEX = /\A#{OMNIAUTH_EMAIL_PREFIX}/
+
apply_simple_captcha
devise :database_authenticatable, :registerable, :confirmable,
- :recoverable, :rememberable, :trackable, :validatable
+ :recoverable, :rememberable, :trackable, :validatable, :omniauthable
acts_as_voter
acts_as_paranoid column: :hidden_at
@@ -11,19 +15,58 @@ class User < ActiveRecord::Base
has_one :moderator
has_one :organization
has_many :inappropiate_flags
+ has_many :identities, dependent: :destroy
- validates :username, presence: true, unless: :organization?
+ validates :username, presence: true, unless: :organization?
validates :official_level, inclusion: {in: 0..5}
+ validates_format_of :email, without: OMNIAUTH_EMAIL_REGEX, on: :update
validates_associated :organization, message: false
accepts_nested_attributes_for :organization
- default_scope { includes(:organization) }
scope :administrators, -> { joins(:administrators) }
scope :moderators, -> { joins(:moderator) }
scope :organizations, -> { joins(:organization) }
scope :officials, -> { where("official_level > 0") }
+ scope :for_render, -> { includes(:organization) }
+
+ def self.find_for_oauth(auth, signed_in_resource = nil)
+ # Get the identity and user if they exist
+ identity = Identity.find_for_oauth(auth)
+
+ # If a signed_in_resource is provided it always overrides the existing user
+ # to prevent the identity being locked with accidentally created accounts.
+ # Note that this may leave zombie accounts (with no associated identity) which
+ # can be cleaned up at a later date.
+ user = signed_in_resource ? signed_in_resource : identity.user
+ user ||= first_or_create_for_oauth(auth)
+
+ # Associate the identity with the user if needed
+ identity.update_user(user)
+ user
+ end
+
+ # Get the existing user by email if the provider gives us a verified email.
+ # If no verified email was provided we assign a temporary email and ask the
+ # user to verify it on the next step via RegistrationsController.finish_signup
+ def self.first_or_create_for_oauth(auth)
+ email = auth.info.email if auth.info.verified || auth.info.verified_email
+ user = User.where(email: email).first if email
+
+ # Create the user if it's a new registration
+ if user.nil?
+ user = User.new(
+ username: auth.info.nickname || auth.extra.raw_info.name.parameterize('-') || auth.uid,
+ email: email ? email : "#{OMNIAUTH_EMAIL_PREFIX}-#{auth.uid}-#{auth.provider}.com",
+ password: Devise.friendly_token[0,20]
+ )
+ user.skip_confirmation!
+ user.save!
+ end
+
+ user
+ end
def name
organization? ? organization.name : username
@@ -71,4 +114,8 @@ class User < ActiveRecord::Base
moderator? ? self.moderator.destroy : create_moderator
end
+ def email_provided?
+ !!(email && email !~ OMNIAUTH_EMAIL_REGEX) ||
+ !!(unconfirmed_email && unconfirmed_email !~ OMNIAUTH_EMAIL_REGEX)
+ end
end
diff --git a/app/views/account/show.html.erb b/app/views/account/show.html.erb
index d24343ea5..fa9ccdd04 100644
--- a/app/views/account/show.html.erb
+++ b/app/views/account/show.html.erb
@@ -26,7 +26,7 @@
<%= t("account.show.avatar")%>
- <%= avatar_image(@account, size: 100) %>
+ <%= avatar_image(@account, seed: @account.id, size: 100) %>
<%= t("account.show.notifications")%>
diff --git a/app/views/comments/_actions.html.erb b/app/views/comments/_actions.html.erb
index 5454179f0..51a6743e0 100644
--- a/app/views/comments/_actions.html.erb
+++ b/app/views/comments/_actions.html.erb
@@ -1,12 +1,16 @@
+
+ <%= render 'comments/flag_as_inappropiate_actions', comment: comment %>
+
+
<% if can? :hide, comment %>
- |
+ •
<%= link_to t("admin.actions.hide").capitalize, hide_moderation_comment_path(comment),
method: :put, remote: true, data: { confirm: t('admin.actions.confirm') } %>
<% end %>
<% if can? :hide, comment.user %>
- |
+ •
<%= link_to t("admin.actions.hide_author").capitalize, hide_moderation_user_path(comment.user_id, debate_id: @debate.id),
method: :put, data: { confirm: t('admin.actions.confirm') } %>
<% end %>
diff --git a/app/views/comments/_comment.html.erb b/app/views/comments/_comment.html.erb
index ca7474ebd..5ffff4a85 100644
--- a/app/views/comments/_comment.html.erb
+++ b/app/views/comments/_comment.html.erb
@@ -14,7 +14,7 @@
<% if comment.user.organization? %>
<%= image_tag("collective_avatar.png", size: 32, class: "avatar left") %>
<% else %>
- <%= avatar_image(comment.user, size: 32, class: "left") %>
+ <%= avatar_image(comment.user, seed: comment.user_id, size: 32, class: "left") %>
<% end %>
<% if comment.user.hidden? %>
@@ -58,10 +58,6 @@
<% end %>
• <%= time_ago_in_words(comment.created_at) %>
-
-
- <%= render 'comments/flag_as_inappropiate_actions', comment: comment %>
-
<% if comment.as_administrator? %>
@@ -81,11 +77,11 @@
<%= render 'comments/votes', comment: comment %>
-
+
<%= t("debates.comment.responses", count: comment.children_count) %>
<% if user_signed_in? %>
- |
+ |
<%= link_to(comment_link_text(comment), "",
class: "js-add-comment-link", data: {'id': dom_id(comment)}) %>
@@ -93,13 +89,13 @@
<%= render 'comments/form', {parent: comment, toggeable: true} %>
<% end %>
-
+
<% end %>
diff --git a/app/views/comments/_flag_as_inappropiate_actions.html.erb b/app/views/comments/_flag_as_inappropiate_actions.html.erb
index fad83d4d6..9fba8b5b2 100644
--- a/app/views/comments/_flag_as_inappropiate_actions.html.erb
+++ b/app/views/comments/_flag_as_inappropiate_actions.html.erb
@@ -1,6 +1,23 @@
<% if can? :flag_as_inappropiate, comment %>
- <%= link_to t('shared.flag_as_inappropiate'), flag_as_inappropiate_comment_path(comment), method: :put, remote: true %>
+ |
+
+
+
+
<% end %>
+
<% if can? :undo_flag_as_inappropiate, comment %>
- <%= link_to t('shared.undo_flag_as_inappropiate'), undo_flag_as_inappropiate_comment_path(comment), method: :put, remote: true %>
+ |
+
+
+
+
<% end %>
diff --git a/app/views/comments/_votes.html.erb b/app/views/comments/_votes.html.erb
index 73efa56ba..d7af65bff 100644
--- a/app/views/comments/_votes.html.erb
+++ b/app/views/comments/_votes.html.erb
@@ -1,5 +1,4 @@
-
<%= t('debates.comment.votes', count: comment.total_votes) %>
|
@@ -8,7 +7,7 @@
method: "post", remote: true do %>
<% end %>
- <%= comment.get_likes.size %>
+ <%= comment.total_likes %>
@@ -16,5 +15,5 @@
method: "post", remote: true do %>
<% end %>
- <%= comment.get_dislikes.size %>
+ <%= comment.total_dislikes %>
diff --git a/app/views/debates/_debate.html.erb b/app/views/debates/_debate.html.erb
index 4dd866df2..2d1e2deb4 100644
--- a/app/views/debates/_debate.html.erb
+++ b/app/views/debates/_debate.html.erb
@@ -9,7 +9,7 @@
<%= link_to debate.title, debate %>
- <%= link_to t("debates.debate.comments", count: debate.comment_threads.count), debate_path(debate, anchor: "comments") %>
+ <%= link_to t("debates.debate.comments", count: debate.comments_count), debate_path(debate, anchor: "comments") %>
<%= link_to debate.description, debate %>
diff --git a/app/views/debates/_flag_as_inappropiate_actions.html.erb b/app/views/debates/_flag_as_inappropiate_actions.html.erb
index 8003600e0..6c3d34236 100644
--- a/app/views/debates/_flag_as_inappropiate_actions.html.erb
+++ b/app/views/debates/_flag_as_inappropiate_actions.html.erb
@@ -1,6 +1,21 @@
<% if can? :flag_as_inappropiate, debate %>
- <%= link_to t('shared.flag_as_inappropiate'), flag_as_inappropiate_debate_path(debate), method: :put, remote: true %>
+
+
+
+
+ -
+ <%= link_to t('shared.flag_as_inappropiate'), flag_as_inappropiate_debate_path(debate), method: :put, remote: true, id: "flag-debate-#{ debate.id }" %>
+
+
<% end %>
+
<% if can? :undo_flag_as_inappropiate, debate %>
- <%= link_to t('shared.undo_flag_as_inappropiate'), undo_flag_as_inappropiate_debate_path(debate), method: :put, remote: true %>
+
+
+
+
+ -
+ <%= link_to t('shared.undo_flag_as_inappropiate'), undo_flag_as_inappropiate_debate_path(debate), method: :put, remote: true, id: "unflag-debate-#{ debate.id }" %>
+
+
<% end %>
diff --git a/app/views/debates/show.html.erb b/app/views/debates/show.html.erb
index 47ff9e34f..af25f28b1 100644
--- a/app/views/debates/show.html.erb
+++ b/app/views/debates/show.html.erb
@@ -13,7 +13,7 @@
<%= @debate.title %>
- <%= avatar_image(@debate.author, size: 32, class: 'author-photo') %>
+ <%= avatar_image(@debate.author, seed: @debate.author_id, size: 32, class: 'author-photo') %>
<% if @debate.author.hidden? %>
@@ -40,9 +40,9 @@
<%= l @debate.created_at.to_date %>
•
- <%= link_to t("debates.show.comments", count: @debate.comment_threads.count), "#comments" %>
-
-
+ <%= link_to t("debates.show.comments", count: @debate.comments_count), "#comments" %>
+ •
+
<%= render 'debates/flag_as_inappropiate_actions', debate: @debate %>
@@ -79,7 +79,7 @@
<%= t("debates.show.comments_title") %>
- (<%= @debate.comment_threads.count %>)
+ (<%= @debate.comments_count %>)
<% if user_signed_in? %>
<%= render 'comments/form', {parent: @debate, toggeable: false} %>
diff --git a/app/views/devise/_omniauth_form.html.erb b/app/views/devise/_omniauth_form.html.erb
new file mode 100644
index 000000000..fdd812b4f
--- /dev/null
+++ b/app/views/devise/_omniauth_form.html.erb
@@ -0,0 +1,7 @@
+
+
+<%= link_to t("omniauth.twitter.sign_in"), user_omniauth_authorize_path(:twitter), class: 'button radius expand' %>
+<%= link_to t("omniauth.facebook.sign_in"), user_omniauth_authorize_path(:facebook), class: 'button radius expand' %>
+<%= link_to t("omniauth.google_oauth2.sign_in"), user_omniauth_authorize_path(:google_oauth2), class: 'button radius expand' %>
+
+
diff --git a/app/views/devise/mailer/confirmation_instructions.html.erb b/app/views/devise/mailer/confirmation_instructions.html.erb
index 1f504444d..c81e6fc74 100644
--- a/app/views/devise/mailer/confirmation_instructions.html.erb
+++ b/app/views/devise/mailer/confirmation_instructions.html.erb
@@ -1,5 +1,18 @@
-
<%= t("devise_views.mailer.confirmation_instructions.welcome") %> <%= @email %>
+
- <%= t("devise_views.mailer.confirmation_instructions.text") %>
+
+ <%= t("devise_views.mailer.confirmation_instructions.title") %>
+
-<%= link_to t("devise_views.mailer.confirmation_instructions.confirm_link"), confirmation_url(@resource, confirmation_token: @token) %>
+
+ <%= t("devise_views.mailer.confirmation_instructions.welcome") %> <%= @email %>
+
+
+
+ <%= t("devise_views.mailer.confirmation_instructions.text") %>
+
+
+
+ <%= link_to t("devise_views.mailer.confirmation_instructions.confirm_link"), confirmation_url(@resource, confirmation_token: @token), style: "color: #2895F1; text-decoration:none;" %>
+
+ |
diff --git a/app/views/devise/mailer/reset_password_instructions.html.erb b/app/views/devise/mailer/reset_password_instructions.html.erb
index 78923ce92..a67e77f08 100644
--- a/app/views/devise/mailer/reset_password_instructions.html.erb
+++ b/app/views/devise/mailer/reset_password_instructions.html.erb
@@ -1,8 +1,22 @@
-
<%= t("devise_views.mailer.reset_password_instructions.hello") %> <%= @resource.email %>
+
- <%= t("devise_views.mailer.reset_password_instructions.text") %>
+
+ <%= t("devise_views.mailer.reset_password_instructions.title") %>
+
-<%= link_to t("devise_views.mailer.reset_password_instructions.change_link"), edit_password_url(@resource, reset_password_token: @token) %>
+
+ <%= t("devise_views.mailer.reset_password_instructions.hello") %> <%= @resource.email %>
+
-<%= t("devise_views.mailer.reset_password_instructions.ignore_text") %>
-<%= t("devise_views.mailer.reset_password_instructions.info_text") %>
+
+ <%= t("devise_views.mailer.reset_password_instructions.text") %>
+
+
+
+ <%= link_to t("devise_views.mailer.reset_password_instructions.change_link"), edit_password_url(@resource, reset_password_token: @token), style: "color: #2895F1; text-decoration:none;" %>
+
+
+
+ <%= t("devise_views.mailer.reset_password_instructions.ignore_text") %> <%= t("devise_views.mailer.reset_password_instructions.info_text") %>
+
+ |
diff --git a/app/views/devise/mailer/unlock_instructions.html.erb b/app/views/devise/mailer/unlock_instructions.html.erb
index 12f4d2b62..41ddc2f19 100644
--- a/app/views/devise/mailer/unlock_instructions.html.erb
+++ b/app/views/devise/mailer/unlock_instructions.html.erb
@@ -1,7 +1,22 @@
-
<%= t("devise_views.mailer.unlock_instructions.hello") %> <%= @resource.email %>
+
- <%= t("devise_views.mailer.unlock_instructions.info_text") %>
+
+ <%= t("devise_views.mailer.unlock_instructions.title") %>
+
-<%= t("devise_views.mailer.unlock_instructions.instructions_text") %>
+
+ <%= t("devise_views.mailer.unlock_instructions.hello") %> <%= @resource.email %>
+
-<%= link_to t("devise_views.mailer.unlock_instructions.unlock_link"), unlock_url(@resource, unlock_token: @token) %>
+
+ <%= t("devise_views.mailer.unlock_instructions.info_text") %>
+
+
+
+ <%= t("devise_views.mailer.unlock_instructions.instructions_text") %>
+
+
+
+ <%= link_to t("devise_views.mailer.unlock_instructions.unlock_link"), unlock_url(@resource, unlock_token: @token), style: "color: #2895F1; text-decoration:none;" %>
+
+ |
diff --git a/app/views/devise/menu/_login_items.html.erb b/app/views/devise/menu/_login_items.html.erb
index 4959553f9..6cd27160d 100644
--- a/app/views/devise/menu/_login_items.html.erb
+++ b/app/views/devise/menu/_login_items.html.erb
@@ -7,11 +7,11 @@
<%= link_to(t("devise_views.menu.login_items.logout"), destroy_user_session_path, method: :delete) %>
<% else %>
-
- <%= link_to(t("devise_views.menu.login_items.login"), new_user_session_path) %>
-
-
- <%= link_to(t("devise_views.menu.login_items.signup"), new_user_registration_path, class: "button radius small") %>
-
+
+ <%= link_to(t("devise_views.menu.login_items.login"), new_user_session_path) %>
+
+
+ <%= link_to(t("devise_views.menu.login_items.signup"), new_user_registration_path, class: "button radius small") %>
+
<% end %>
-
\ No newline at end of file
+
diff --git a/app/views/devise/passwords/new.html.erb b/app/views/devise/passwords/new.html.erb
index 78a8b8b4c..1219c393d 100644
--- a/app/views/devise/passwords/new.html.erb
+++ b/app/views/devise/passwords/new.html.erb
@@ -19,4 +19,4 @@
<%= render "devise/shared/links" %>
-
\ No newline at end of file
+
diff --git a/app/views/devise/sessions/new.html.erb b/app/views/devise/sessions/new.html.erb
index 391ef186c..ab0b22426 100644
--- a/app/views/devise/sessions/new.html.erb
+++ b/app/views/devise/sessions/new.html.erb
@@ -3,6 +3,8 @@
<%= t("devise_views.sessions.new.title") %>
+ <%= render 'devise/omniauth_form' %>
+
<%= form_for(resource, as: resource_name, url: session_path(resource_name)) do |f| %>
@@ -28,4 +30,4 @@
<%= render "devise/shared/links" %>
-
\ No newline at end of file
+
diff --git a/app/views/devise/shared/_links.html.erb b/app/views/devise/shared/_links.html.erb
index 0fd80f429..7f8142144 100644
--- a/app/views/devise/shared/_links.html.erb
+++ b/app/views/devise/shared/_links.html.erb
@@ -25,7 +25,7 @@
<%= link_to t("devise_views.shared.links.new_unlock"), new_unlock_path(resource_name) %>
<% end -%>
- <%- if devise_mapping.omniauthable? %>
+ <%- if devise_mapping.omniauthable? && devise_mapping.name == 'user' %>
<%- resource_class.omniauth_providers.each do |provider| %>
<%= link_to t("devise_views.shared.links.signin_with_provider", provider: provider.to_s.titleize), omniauth_authorize_path(resource_name, provider) %>
<% end -%>
diff --git a/app/views/layouts/mailer.html.erb b/app/views/layouts/mailer.html.erb
index 991cf0ffa..91f31ab18 100644
--- a/app/views/layouts/mailer.html.erb
+++ b/app/views/layouts/mailer.html.erb
@@ -1,5 +1,42 @@
-
-
- <%= yield %>
-
+
+
+
+ Gobierno abierto
+
+
+
+
+
+
+
+ |
+
+ |
+
+
+ <%= yield %>
+
+
+
+
+
diff --git a/app/views/mailer/comment.html.erb b/app/views/mailer/comment.html.erb
index eb95c8031..959b8e0a0 100644
--- a/app/views/mailer/comment.html.erb
+++ b/app/views/mailer/comment.html.erb
@@ -1,6 +1,18 @@
-<%= t('mailers.comment.hi', recipient: @debate.author.name) %>
+
- <%= link_to @debate.title, debate_url(@debate) %>
-<%= t('mailers.comment.new_comment_by', commenter: @comment.author.name) %>
+
+ <%= t("mailers.comment.title") %>
+
-<%= @comment.body %>
+
+ <%= t("mailers.comment.hi") %> <%= @debate.author.name %>,
+
+
+
+ <%= t("mailers.comment.new_comment_by_html", commenter: @comment.author.name) %> <%= link_to @debate.title, debate_url(@debate), style: "color: #2895F1; text-decoration:none;" %>
+
+
+
+ <%= @comment.body %>
+
+ |
diff --git a/app/views/mailer/reply.html.erb b/app/views/mailer/reply.html.erb
index 21cfeba1e..924234f02 100644
--- a/app/views/mailer/reply.html.erb
+++ b/app/views/mailer/reply.html.erb
@@ -1,6 +1,18 @@
-<%= t('mailers.reply.hi', recipient: @recipient.name) %>
+
- <%= link_to @debate.title, debate_url(@debate) %>
-<%= t('mailers.reply.new_reply_by', commenter: @reply.author.name) %>
+
+ <%= t("mailers.reply.title") %>
+
-<%= @reply.body %>
+
+ <%= t("mailers.reply.hi") %> <%= @recipient.name %>,
+
+
+
+ <%= t("mailers.reply.new_reply_by_html", commenter: @reply.author.name) %> <%= link_to @debate.title, debate_url(@debate), style: "color: #2895F1; text-decoration:none;" %>
+
+
+
+ <%= @reply.body %>
+
+ |
diff --git a/app/views/moderation/_menu.html.erb b/app/views/moderation/_menu.html.erb
index 41e84287a..f64eeec3a 100644
--- a/app/views/moderation/_menu.html.erb
+++ b/app/views/moderation/_menu.html.erb
@@ -4,17 +4,17 @@
<%= t("moderation.dashboard.index.title") %>
- >
+ >
<%= link_to moderation_debates_path do %>
-
+
<%= t('moderation.menu.flagged_debates') %>
<% end %>
- >
+ >
<%= link_to moderation_comments_path do %>
-
- <%= t('moderation.menu.flagged_comments') %>
+
+ <%= t("moderation.menu.flagged_comments") %>
<% end %>
diff --git a/app/views/moderation/comments/index.html.erb b/app/views/moderation/comments/index.html.erb
index 0d89114f1..f4ce8ec67 100644
--- a/app/views/moderation/comments/index.html.erb
+++ b/app/views/moderation/comments/index.html.erb
@@ -1,45 +1,52 @@
-<%= t('moderation.comments.index.title') %>
+<%= t("moderation.comments.index.title") %>
+
+
+ - <%= t("moderation.comments.index.filter") %>:
-
- <%= t('moderation.comments.index.filter') %>:
<% @valid_filters.each do |filter| %>
<% if @filter == filter %>
- <%= t("moderation.comments.index.filters.#{filter}") %>
+
- <%= t("moderation.comments.index.filters.#{filter}") %>
<% else %>
- <%= link_to t("moderation.comments.index.filters.#{filter}"),
- moderation_comments_path(filter: filter) %>
+ - <%= link_to t("moderation.comments.index.filters.#{filter}"),
+ moderation_comments_path(filter: filter) %>
<% end %>
<% end %>
-
+
<%= page_entries_info @comments %>
- | <%= t('moderation.comments.index.headers.flags') %> |
- <%= t('moderation.comments.index.headers.updated_at') %> |
- <%= t('moderation.comments.index.headers.commentable_type') %> |
- <%= t('moderation.comments.index.headers.commentable') %> |
- <%= t('moderation.comments.index.headers.comment') %> |
+
+ <%= t("moderation.comments.index.headers.commentable") %> |
+ <%= t("moderation.comments.index.headers.commentable_type") %> |
+ <%= t("moderation.comments.index.headers.updated_at") %>
+ |
+ <%= t("moderation.comments.index.headers.comment") %> |
+ <%= t("moderation.comments.index.headers.flags") %> |
+ <%= t("moderation.debates.index.headers.actions") %> |
<% @comments.each do |comment| %>
@@ -47,4 +54,3 @@
<%= paginate @comments %>
-
diff --git a/app/views/moderation/dashboard/index.html.erb b/app/views/moderation/dashboard/index.html.erb
index 16eb4508f..df41493e6 100644
--- a/app/views/moderation/dashboard/index.html.erb
+++ b/app/views/moderation/dashboard/index.html.erb
@@ -1 +1,5 @@
-<%= t("moderation.dashboard.index.title") %>
+<%= t("moderation.dashboard.index.title") %>
+
+Lorem ipsum moderator sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.
+
+Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem.
diff --git a/app/views/moderation/debates/index.html.erb b/app/views/moderation/debates/index.html.erb
index 611f68e16..ac11d2159 100644
--- a/app/views/moderation/debates/index.html.erb
+++ b/app/views/moderation/debates/index.html.erb
@@ -1,43 +1,51 @@
-<%= t('moderation.debates.index.title') %>
+<%= t("moderation.debates.index.title") %>
+
+
+ - <%= t("moderation.debates.index.filter") %>:
-
- <%= t('moderation.debates.index.filter') %>:
<% @valid_filters.each do |filter| %>
<% if @filter == filter %>
- <%= t("moderation.debates.index.filters.#{filter}") %>
+
- <%= t("moderation.debates.index.filters.#{filter}") %>
<% else %>
- <%= link_to t("moderation.debates.index.filters.#{filter}"),
- moderation_debates_path(filter: filter) %>
+ - <%= link_to t("moderation.debates.index.filters.#{filter}"),
+ moderation_debates_path(filter: filter) %>
<% end %>
<% end %>
-
+
<%= page_entries_info @debates %>
- | <%= t('moderation.debates.index.headers.flags') %> |
- <%= t('moderation.debates.index.headers.updated_at') %> |
- <%= t('moderation.debates.index.headers.title') %> |
- <%= t('moderation.debates.index.headers.description') %> |
+
+ <%= t("moderation.debates.index.headers.title") %> |
+ <%= t("moderation.debates.index.headers.updated_at") %> |
+ <%= t("moderation.debates.index.headers.description") %>
+ |
+ <%= t("moderation.debates.index.headers.flags") %> |
+ <%= t("moderation.debates.index.headers.actions") %> |
<% @debates.each do |debate| %>
- | <%= debate.inappropiate_flags_count %> |
- <%= l debate.updated_at.to_date %> |
- <%= link_to debate.title, debate %> |
- <%= debate.description %> |
- <%= link_to t('moderation.debates.index.hide'), hide_in_moderation_screen_moderation_debate_path(debate, request.query_parameters), method: :put %>
+ <%= link_to debate.title, debate, target: "_blank" %>
+
+ <%= l debate.updated_at.to_date %>
+
+ <%= debate.description %>
|
- <% if can? :mark_as_reviewed, debate %>
+ <%= debate.inappropiate_flags_count %> |
+
+ <%= link_to t("moderation.debates.index.hide"), hide_in_moderation_screen_moderation_debate_path(debate, request.query_parameters), method: :put, class: "delete" %>
+ |
+ <% if can? :archive, debate %>
- <%= link_to t('moderation.debates.index.mark_as_reviewed'), mark_as_reviewed_moderation_debate_path(debate, request.query_parameters), method: :put %>
+ <%= link_to t("moderation.debates.index.archive"), archive_moderation_debate_path(debate, request.query_parameters), method: :put, class: "button radius tiny warning" %>
|
<% end %>
- <% if debate.reviewed? %>
-
- <%= t('moderation.debates.index.reviewed') %>
+ <% if debate.archived? %>
+ |
+ <%= t("moderation.debates.index.archived") %>
|
<% end %>
@@ -45,4 +53,3 @@
<%= paginate @debates %>
-
diff --git a/app/views/organizations/registrations/success.html.erb b/app/views/organizations/registrations/success.html.erb
new file mode 100644
index 000000000..e246365f5
--- /dev/null
+++ b/app/views/organizations/registrations/success.html.erb
@@ -0,0 +1,15 @@
+
+
+
+
<%= t("devise_views.organizations.registrations.success.title") %>
+
<%= t("devise_views.organizations.registrations.success.thank_you") %>
+
<%= t("devise_views.organizations.registrations.success.instructions_1_html") %>
+
<%= t("devise_views.organizations.registrations.success.instructions_2_html") %>
+
<%= t("devise_views.organizations.registrations.success.instructions_3_html") %>
+
+ <%= link_to t("devise_views.organizations.registrations.success.back_to_index"),
+ root_path, class: "button radius small margin-top" %>
+
+
+
+
diff --git a/app/views/shared/_tags.html.erb b/app/views/shared/_tags.html.erb
index 6a61bd4b4..2b599ec77 100644
--- a/app/views/shared/_tags.html.erb
+++ b/app/views/shared/_tags.html.erb
@@ -10,4 +10,4 @@
<%= link_to "#{debate.tags_count_out_of_limit(limit)}+", debate_path(debate) %>
<% end %>
-<% end %>
+<% end %>
\ No newline at end of file
diff --git a/app/views/users/registrations/finish_signup.html.erb b/app/views/users/registrations/finish_signup.html.erb
new file mode 100644
index 000000000..c57f01a8e
--- /dev/null
+++ b/app/views/users/registrations/finish_signup.html.erb
@@ -0,0 +1,13 @@
+
+
+
+
<%= t('omniauth.finish_signup.title') %>
+
+ <%= form_for current_user, as: :user, url: do_finish_signup_path, html: { role: 'form'} do |f| %>
+ <%= render 'shared/errors', resource: current_user %>
+ <%= f.email_field :email, placeholder: t("devise_views.users.registrations.new.email_label"), value: nil %>
+ <%= f.submit t("devise_views.users.registrations.new.submit"), class: 'button radius' %>
+ <% end %>
+
+
+
diff --git a/app/views/users/registrations/new.html.erb b/app/views/users/registrations/new.html.erb
index 92344b76f..2ac5b7af6 100644
--- a/app/views/users/registrations/new.html.erb
+++ b/app/views/users/registrations/new.html.erb
@@ -2,6 +2,9 @@
<%= t("devise_views.users.registrations.new.title") %>
+
+ <%= render 'devise/omniauth_form' %>
+
<%= form_for(resource, as: resource_name, url: registration_path(resource_name)) do |f| %>
<%= render 'shared/errors', resource: resource %>
diff --git a/app/views/welcome/_featured_debate.html.erb b/app/views/welcome/_featured_debate.html.erb
index 11cb3b733..7ad53608b 100644
--- a/app/views/welcome/_featured_debate.html.erb
+++ b/app/views/welcome/_featured_debate.html.erb
@@ -8,7 +8,7 @@
<%= link_to featured_debate.title, featured_debate %>
- <%= link_to t("debates.show.comments", count: featured_debate.comment_threads.count), debate_path(featured_debate, anchor: "comments") %>
+ <%= link_to t("debates.show.comments", count: featured_debate.comments_count), debate_path(featured_debate, anchor: "comments") %>
<%= link_to featured_debate.description, featured_debate %>
diff --git a/config/deploy/shared/secrets.yml.erb b/config/deploy/shared/secrets.yml.erb
index a1cc29fb8..42a8c48a6 100644
--- a/config/deploy/shared/secrets.yml.erb
+++ b/config/deploy/shared/secrets.yml.erb
@@ -2,4 +2,10 @@
recaptcha_public_key: <%= ENV["MADRID_RECAPTCHA_PUBLIC_KEY"] %>
recaptcha_private_key: <%= ENV["MADRID_RECAPTCHA_PRIVATE_KEY"] %>
secret_key_base: <%= ENV["SECRET_KEY_BASE"] %>
- server_name: <%= fetch(:server_name) %>
\ No newline at end of file
+ twitter_key: <%= ENV["TWITTER_KEY"] %>
+ twitter_secret: <%= ENV["TWITTER_SECRET"] %>
+ facebook_key: <%= ENV["FACEBOOK_KEY"] %>
+ facebook_secret: <%= ENV["FACEBOOK_SECRET"] %>
+ google_oauth2_key: <%= ENV["GOOGLE_KEY"] %>
+ google_oauth2_secret: <%= ENV["GOOGLE_SECRET"] %>
+ server_name: <%= fetch(:server_name) %>
diff --git a/config/environments/development.rb b/config/environments/development.rb
index acf67286d..566d4ebc5 100644
--- a/config/environments/development.rb
+++ b/config/environments/development.rb
@@ -16,6 +16,7 @@ Rails.application.configure do
# Don't care if the mailer can't send.
config.action_mailer.raise_delivery_errors = false
config.action_mailer.default_url_options = { host: 'localhost', port: 3000 }
+ config.action_mailer.asset_host = "http://localhost:3000"
# Deliver emails to a development mailbox at /letter_opener
config.action_mailer.delivery_method = :letter_opener
@@ -44,4 +45,13 @@ Rails.application.configure do
# config.action_view.raise_on_missing_translations = true
config.cache_store = :null_store
+
+ config.after_initialize do
+ Bullet.enable = true
+ Bullet.bullet_logger = true
+ if ENV['BULLET']
+ Bullet.rails_logger = true
+ Bullet.add_footer = true
+ end
+ end
end
diff --git a/config/environments/staging.rb b/config/environments/staging.rb
index e84606f73..7a21a1df4 100644
--- a/config/environments/staging.rb
+++ b/config/environments/staging.rb
@@ -42,7 +42,7 @@ Rails.application.configure do
# config.action_dispatch.x_sendfile_header = 'X-Accel-Redirect' # for NGINX
# Force all access to the app over SSL, use Strict-Transport-Security, and use secure cookies.
- # config.force_ssl = true
+ config.force_ssl = true
# Use the lowest log level to ensure availability of diagnostic information
# when problems arise.
diff --git a/config/environments/test.rb b/config/environments/test.rb
index a76376fe6..cef568af6 100644
--- a/config/environments/test.rb
+++ b/config/environments/test.rb
@@ -45,4 +45,13 @@ Rails.application.configure do
# config.action_view.raise_on_missing_translations = true
config.cache_store = :null_store
+
+ config.after_initialize do
+ Bullet.enable = true
+ Bullet.bullet_logger = true
+ if ENV['BULLET']
+ Bullet.raise = true # raise an error if n+1 query occurs
+ end
+ end
+
end
diff --git a/config/initializers/devise.rb b/config/initializers/devise.rb
index f7cdfb292..6b1c860a9 100644
--- a/config/initializers/devise.rb
+++ b/config/initializers/devise.rb
@@ -239,6 +239,9 @@ Devise.setup do |config|
# Add a new OmniAuth provider. Check the wiki for more information on setting
# up on your models and hooks.
# config.omniauth :github, 'APP_ID', 'APP_SECRET', scope: 'user,public_repo'
+ config.omniauth :twitter, Rails.application.secrets.twitter_key, Rails.application.secrets.twitter_secret
+ config.omniauth :facebook, Rails.application.secrets.facebook_key, Rails.application.secrets.facebook_secret
+ config.omniauth :google_oauth2, Rails.application.secrets.google_oauth2_key, Rails.application.secrets.google_oauth2_secret
# ==> Warden configuration
# If you want to use other strategies, that are not supported by Devise, or
@@ -263,3 +266,7 @@ Devise.setup do |config|
# so you need to do it manually. For the users scope, it would be:
# config.omniauth_path_prefix = '/my_engine/users/auth'
end
+
+Rails.application.config.to_prepare do
+ Devise::Mailer.layout "mailer" # email.haml or email.erb
+end
\ No newline at end of file
diff --git a/config/locales/devise.es.yml b/config/locales/devise.es.yml
index f39099f57..c2bc246e9 100644
--- a/config/locales/devise.es.yml
+++ b/config/locales/devise.es.yml
@@ -55,4 +55,4 @@ es:
not_locked: "no estaba bloqueado."
not_saved:
one: "1 error impidió que este %{resource} fuera guardado:"
- other: "%{count} errores impidieron que este %{resource} fuera guardado:"
\ No newline at end of file
+ other: "%{count} errores impidieron que este %{resource} fuera guardado:"
diff --git a/config/locales/devise_views.en.yml b/config/locales/devise_views.en.yml
index e1b2a571d..08a303834 100644
--- a/config/locales/devise_views.en.yml
+++ b/config/locales/devise_views.en.yml
@@ -6,17 +6,20 @@ en:
submit: "Resend confirmation instructions"
mailer:
confirmation_instructions:
+ title: "Welcome to open government"
welcome: "Welcome"
text: "You can confirm your account email through the link below:"
confirm_link: "Confirm my account"
reset_password_instructions:
hello: "Hello"
- text: "Someone has requested a link to change your password. You can do this through the link below."
+ title: Change your password
+ text: "Someone has requested to change your password. You can do this through the link below:"
change_link: "Change my password"
ignore_text: "If you didn't request this, please ignore this email."
info_text: "Your password won't change until you access the link above and create a new one."
unlock_instructions:
hello: "Hello"
+ title: Your account has been locked
info_text: "Your account has been locked due to an excessive number of unsuccessful sign in attempts."
instructions_text: "Click the link below to unlock your account:"
unlock_link: "Unlock my account"
@@ -66,6 +69,13 @@ en:
phone_number_label: "Phone number"
password_confirmation_label: "Confirm password"
submit: "Sign up"
+ success:
+ title: "Registration of organization / collective"
+ thank_you: "Thank you for registering your organization or collective in the website. Now is pending verification."
+ instructions_1_html: "We will contact you soon in order to verify that you represent your collective."
+ instructions_2_html: "Meanwhile, review your email. We have sent you a confirmation link to activate your account."
+ instructions_3_html: "When you confirm your account will then be able to participate as a non-verified organization."
+ back_to_index: "Ok, go back to index"
sessions:
new:
title: "Log in"
diff --git a/config/locales/devise_views.es.yml b/config/locales/devise_views.es.yml
index 7ed5298de..6ab6ebbb5 100644
--- a/config/locales/devise_views.es.yml
+++ b/config/locales/devise_views.es.yml
@@ -6,17 +6,20 @@ es:
submit: "Reenviar instrucciones de confirmación"
mailer:
confirmation_instructions:
- welcome: "Bienvenido"
+ title: "Bienvenido/a a gobierno abierto"
+ welcome: "Bienvenido/a"
text: "Puedes confirmar tu cuenta de correo electrónico en el siguiente enlace:"
confirm_link: "Confirmar mi cuenta"
reset_password_instructions:
hello: "Hola"
- text: "Se ha solicitado un enlace para cambiar tu contraseña, puedes hacerlo en el siguiente enlace:"
- change_link: "cambiar mi contraseña"
- ignore_text: "Si tu no lo has solicitado, puedes ignorar este email"
+ title: "Cambiar tu contraseña"
+ text: "Se ha solicitado cambiar tu contraseña, puedes hacerlo en el siguiente enlace:"
+ change_link: "Cambiar mi contraseña"
+ ignore_text: "Si tu no lo has solicitado, puedes ignorar este email."
info_text: "Tu contraseña no cambiará hasta que no accedas al enlace y la modifiques."
unlock_instructions:
hello: "Hola"
+ title: Tu cuenta ha sido bloqueada
info_text: "Tu cuenta ha sido bloqueada debido a un excesivo número de intentos fallidos de alta."
instructions_text: "Sigue el siguiente enlace para desbloquear tu cuenta:"
unlock_link: "Desbloquear mi cuenta"
@@ -66,6 +69,13 @@ es:
phone_number_label: "Teléfono"
password_confirmation_label: "Confirmar contraseña"
submit: "Registrarse"
+ success:
+ title: "Registro de organización / colectivo"
+ thank_you: "Gracias por registrar tu colectivo en la web. Ahora está pendiente de verificación."
+ instructions_1_html: "En breve nos pondremos en contacto contigo para verificar que realmente representas a este colectivo."
+ instructions_2_html: "Mientras revisa tu correo electrónico, te hemos enviado un enlace para confirmar tu cuenta."
+ instructions_3_html: "Una vez confirmado, podrás empezar a participar como colectivo no verificado."
+ back_to_index: "Entendido, volver a la página principal"
sessions:
new:
title: "Entrar"
diff --git a/config/locales/en.yml b/config/locales/en.yml
index ce3339b25..322cf585f 100644
--- a/config/locales/en.yml
+++ b/config/locales/en.yml
@@ -61,7 +61,6 @@ en:
zero: No votes
one: 1 vote
other: "%{count} votes"
- votes_weighted_score: "Total: %{score}"
form:
debate_title: Debate title
title_instructions: "SBe clear and precise with the title, but make it informative"
@@ -134,8 +133,8 @@ en:
shared:
tags_cloud:
tags: Topics
- flag_as_inappropiate: Flag as inappropiate
- undo_flag_as_inappropiate: Undo flag as inappropiate
+ flag_as_inappropiate: Flag as inappropriate
+ undo_flag_as_inappropiate: Undo flag
collective: Collective
mailer:
comment:
@@ -148,3 +147,12 @@ en:
all: "You are not authorized to %{action} %{subject}."
welcome:
last_debates: Last debates
+ omniauth:
+ finish_signup:
+ title: Add Email
+ twitter:
+ sign_in: Sign in with Twitter
+ facebook:
+ sign_in: Sign in with Facebook
+ google_oauth2:
+ sign_in: Sign in with Google
diff --git a/config/locales/es.yml b/config/locales/es.yml
index 1e2cca785..5c21c039e 100644
--- a/config/locales/es.yml
+++ b/config/locales/es.yml
@@ -61,7 +61,6 @@ es:
zero: Sin votos
one: 1 voto
other: "%{count} votos"
- votes_weighted_score: "Total: %{score}"
form:
debate_title: Título del debate
title_instructions: "Sé claro y conciso a la hora de poner un título, pero recuerda que debe explicar bien tu idea, ¡es tu carta de entrada!"
@@ -135,7 +134,7 @@ es:
tags_cloud:
tags: Temas
flag_as_inappropiate: Denunciar como inapropiado
- undo_flag_as_inappropiate: Deshacer denunciar como inapropiado
+ undo_flag_as_inappropiate: Deshacer denuncia
collective: Colectivo
mailer:
comment:
@@ -148,3 +147,12 @@ es:
all: "No tienes permiso para realizar la acción '%{action}' sobre %{subject}."
welcome:
last_debates: Últimos debates
+ omniauth:
+ finish_signup:
+ title: Añade tu email
+ twitter:
+ sign_in: Entra con Twitter
+ facebook:
+ sign_in: Entra con Facebook
+ google_oauth2:
+ sign_in: Entra con Google
diff --git a/config/locales/mailers.en.yml b/config/locales/mailers.en.yml
index cbc6c5bd6..d0550aca9 100644
--- a/config/locales/mailers.en.yml
+++ b/config/locales/mailers.en.yml
@@ -1,8 +1,10 @@
en:
mailers:
comment:
- hi: "Hello, %{recipient}"
- new_comment_by: "There'is a new comment by %{commenter}"
+ hi: Hello
+ title: New comment on your debate
+ new_comment_by_html: "There'is a new comment by on"
reply:
- hi: "Hello, %{recipient}"
- new_reply_by: "There'is a new reply by %{commenter} to your comment"
\ No newline at end of file
+ hi: Hello
+ title: New reply on your comment
+ new_reply_by_html: "There'is a new reply by %{commenter} to your comment on"
diff --git a/config/locales/mailers.es.yml b/config/locales/mailers.es.yml
index e595967c4..8efa1dc22 100644
--- a/config/locales/mailers.es.yml
+++ b/config/locales/mailers.es.yml
@@ -1,8 +1,10 @@
es:
mailers:
comment:
- hi: "Hola, %{recipient}"
- new_comment_by: "Hay un nuevo comentario de %{commenter}"
+ hi: Hola
+ title: Nuevo comentario en tu debate
+ new_comment_by_html: "Hay un nuevo comentario de %{commenter} en"
reply:
- hi: "Hola, %{recipient}"
- new_reply_by: "Hay una nueva respuesta de %{commenter} a tu comentario"
\ No newline at end of file
+ hi: Hola
+ title: Nueva respuesta a tu comentario
+ new_reply_by_html: "Hay una nueva respuesta de %{commenter} a tu comentario en"
diff --git a/config/locales/moderation.en.yml b/config/locales/moderation.en.yml
index 2728f10d9..3d61c93a2 100644
--- a/config/locales/moderation.en.yml
+++ b/config/locales/moderation.en.yml
@@ -8,7 +8,7 @@ en:
title: Moderation
comments:
index:
- title: Comments flagged as inappropiate
+ title: Comments flagged as inappropriate
headers:
flags: Flags
updated_at: Date
@@ -16,27 +16,27 @@ en:
commentable: Root
comment: Comment
hide: Hide
- mark_as_reviewed: Mark as reviewed
- reviewed: Reviewed
+ archive: Archive
+ archived: Archived
filter: Filter
filters:
all: All
- pending_review: Pending
- reviewed: Reviewed
+ pending: Pending
+ archived: Archived
debates:
index:
- title: Debates flagged as inappropiate
+ title: Debates flagged as inappropriate
headers:
flags: Flags
updated_at: Date
title: Title
description: Description
+ actions: Actions
hide: Hide
- mark_as_reviewed: Mark as reviewed
- reviewed: Reviewed
+ archive: Archive
+ archived: Archived
filter: Filter
filters:
all: All
- pending_review: Pending
- reviewed: Reviewed
-
+ pending: Pending
+ archived: Archived
diff --git a/config/locales/moderation.es.yml b/config/locales/moderation.es.yml
index 2afaec7a9..73886ddb0 100644
--- a/config/locales/moderation.es.yml
+++ b/config/locales/moderation.es.yml
@@ -8,7 +8,7 @@ es:
title: Moderación
comments:
index:
- title: Comentarios Denunciados como Inapropiados
+ title: Comentarios denunciados como inapropiados
headers:
flags: Denuncias
updated_at: Fecha
@@ -16,28 +16,27 @@ es:
commentable: Raíz
comment: Comentario
hide: Ocultar
- mark_as_reviewed: Marcar como revisado
- reviewed: Revisado
+ archive: Archivar
+ archived: Archivado
filter: Filtrar
filters:
all: Todos
- pending_review: Pendientes
- reviewed: Revisados
+ pending: Pendientes
+ archived: Archivados
debates:
index:
- title: Debates Denunciados como Inapropiados
+ title: Debates denunciados como inapropiados
headers:
flags: Denuncias
updated_at: Fecha
title: Título
description: Descripción
+ actions: Acciones
hide: Ocultar
- mark_as_reviewed: Marcar como revisado
- reviewed: Revisado
+ archive: Archivar
+ archived: Archivado
filter: Filtrar
filters:
all: Todos
- pending_review: Pendientes
- reviewed: Revisados
-
-
+ pending: Pendientes
+ archived: Archivados
diff --git a/config/routes.rb b/config/routes.rb
index 212ab2808..67f3734e9 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -1,10 +1,23 @@
Rails.application.routes.draw do
- devise_for :users, controllers: { registrations: 'users/registrations' }
+ devise_for :users, controllers: {
+ registrations: 'users/registrations',
+ omniauth_callbacks: 'users/omniauth_callbacks'
+ }
devise_for :organizations, class_name: 'User',
controllers: {
registrations: 'organizations/registrations',
- sessions: 'devise/sessions'
- }
+ sessions: 'devise/sessions',
+ },
+ skip: [:omniauth_callbacks]
+
+ devise_scope :organization do
+ get "organizations/sign_up/success", to: "organizations/registrations#success"
+ end
+
+ devise_scope :user do
+ get :finish_signup, to: 'users/registrations#finish_signup'
+ patch :do_finish_signup, to: 'users/registrations#do_finish_signup'
+ end
# The priority is based upon order of creation: first created -> highest priority.
# See how all your routes lay out with "rake routes".
@@ -79,7 +92,7 @@ Rails.application.routes.draw do
member do
put :hide
put :hide_in_moderation_screen
- put :mark_as_reviewed
+ put :archive
end
end
@@ -87,7 +100,7 @@ Rails.application.routes.draw do
member do
put :hide
put :hide_in_moderation_screen
- put :mark_as_reviewed
+ put :archive
end
end
end
diff --git a/config/secrets.yml.example b/config/secrets.yml.example
index f4ad98027..1d1312ea6 100644
--- a/config/secrets.yml.example
+++ b/config/secrets.yml.example
@@ -14,12 +14,30 @@ default: &default
development:
secret_key_base: 56792feef405a59b18ea7db57b4777e855103882b926413d4afdfb8c0ea8aa86ea6649da4e729c5f5ae324c0ab9338f789174cf48c544173bc18fdc3b14262e4
+ twitter_key: AAAA
+ twitter_secret: BBBB
+ facebook_key: AAAA
+ facebook_secret: BBBB
+ google_oauth2_key: AAAA
+ google_oauth2_secret: BBBB
<<: *default
test:
secret_key_base: 4d5adf961ddd27aef19622d6c0b3234d555f9ee003f022b1f829c92bbe33aaee907be7feb67bd54c14a1a32512fa968565ad405971fbc41bd0797af73c26a796
+ twitter_key: AAAA
+ twitter_secret: BBBB
+ facebook_key: AAAA
+ facebook_secret: BBBB
+ google_oauth2_key: AAAA
+ google_oauth2_secret: BBBB
<<: *default
production:
secret_key_base: <%= ENV["SECRET_KEY_BASE"] %>
- <<: *default
\ No newline at end of file
+ twitter_key: <%= ENV["TWITTER_KEY"] %>
+ twitter_secret: <%= ENV["TWITTER_SECRET"] %>
+ facebook_key: <%= ENV["FACEBOOK_KEY"] %>
+ facebook_secret: <%= ENV["FACEBOOK_SECRET"] %>
+ google_oauth2_key: <%= ENV["GOOGLE_KEY"] %>
+ google_oauth2_secret: <%= ENV["GOOGLE_SECRET"] %>
+ <<: *default
diff --git a/db/migrate/20150824144524_create_identities.rb b/db/migrate/20150824144524_create_identities.rb
new file mode 100644
index 000000000..38a5e603a
--- /dev/null
+++ b/db/migrate/20150824144524_create_identities.rb
@@ -0,0 +1,11 @@
+class CreateIdentities < ActiveRecord::Migration
+ def change
+ create_table :identities do |t|
+ t.references :user, index: true, foreign_key: true
+ t.string :provider
+ t.string :uid
+
+ t.timestamps null: false
+ end
+ end
+end
diff --git a/db/migrate/20150825124821_adds_votable_cache_field_to_comments.rb b/db/migrate/20150825124821_adds_votable_cache_field_to_comments.rb
new file mode 100644
index 000000000..e2da7e12f
--- /dev/null
+++ b/db/migrate/20150825124821_adds_votable_cache_field_to_comments.rb
@@ -0,0 +1,11 @@
+class AddsVotableCacheFieldToComments < ActiveRecord::Migration
+ def change
+ add_column :comments, :cached_votes_total, :integer, default: 0
+ add_column :comments, :cached_votes_up, :integer, default: 0
+ add_column :comments, :cached_votes_down, :integer, default: 0
+
+ add_index :comments, :cached_votes_total
+ add_index :comments, :cached_votes_up
+ add_index :comments, :cached_votes_down
+ end
+end
diff --git a/db/migrate/20150825124827_adds_votable_cache_field_to_debates.rb b/db/migrate/20150825124827_adds_votable_cache_field_to_debates.rb
new file mode 100644
index 000000000..07df8cf22
--- /dev/null
+++ b/db/migrate/20150825124827_adds_votable_cache_field_to_debates.rb
@@ -0,0 +1,11 @@
+class AddsVotableCacheFieldToDebates < ActiveRecord::Migration
+ def change
+ add_column :debates, :cached_votes_total, :integer, default: 0
+ add_column :debates, :cached_votes_up, :integer, default: 0
+ add_column :debates, :cached_votes_down, :integer, default: 0
+
+ add_index :debates, :cached_votes_total
+ add_index :debates, :cached_votes_up
+ add_index :debates, :cached_votes_down
+ end
+end
diff --git a/db/migrate/20150826112411_rename_reviewed_at_to_archived_at_in_comments_and_debates.rb b/db/migrate/20150826112411_rename_reviewed_at_to_archived_at_in_comments_and_debates.rb
new file mode 100644
index 000000000..86bebd8e1
--- /dev/null
+++ b/db/migrate/20150826112411_rename_reviewed_at_to_archived_at_in_comments_and_debates.rb
@@ -0,0 +1,6 @@
+class RenameReviewedAtToArchivedAtInCommentsAndDebates < ActiveRecord::Migration
+ def change
+ rename_column :comments, :reviewed_at, :archived_at
+ rename_column :debates, :reviewed_at, :archived_at
+ end
+end
diff --git a/db/migrate/20150826112500_add_comments_count_to_debate.rb b/db/migrate/20150826112500_add_comments_count_to_debate.rb
new file mode 100644
index 000000000..bf416b669
--- /dev/null
+++ b/db/migrate/20150826112500_add_comments_count_to_debate.rb
@@ -0,0 +1,5 @@
+class AddCommentsCountToDebate < ActiveRecord::Migration
+ def change
+ add_column :debates, :comments_count, :integer, default: 0
+ end
+end
diff --git a/db/schema.rb b/db/schema.rb
index 6f4d26c5b..1d7972417 100644
--- a/db/schema.rb
+++ b/db/schema.rb
@@ -11,7 +11,7 @@
#
# It's strongly recommended that you check this file into your version control system.
-ActiveRecord::Schema.define(version: 20150824113326) do
+ActiveRecord::Schema.define(version: 20150826112500) do
# These are extensions that must be enabled in order to support this database
enable_extension "plpgsql"
@@ -41,7 +41,7 @@ ActiveRecord::Schema.define(version: 20150824113326) do
t.string "title"
t.text "body"
t.string "subject"
- t.integer "user_id", null: false
+ t.integer "user_id", null: false
t.integer "parent_id"
t.integer "lft"
t.integer "rgt"
@@ -51,11 +51,17 @@ ActiveRecord::Schema.define(version: 20150824113326) do
t.datetime "hidden_at"
t.datetime "flagged_as_inappropiate_at"
t.integer "inappropiate_flags_count", default: 0
- t.datetime "reviewed_at"
+ t.datetime "archived_at"
t.integer "moderator_id"
t.integer "administrator_id"
+ t.integer "cached_votes_total", default: 0
+ t.integer "cached_votes_up", default: 0
+ t.integer "cached_votes_down", default: 0
end
+ add_index "comments", ["cached_votes_down"], name: "index_comments_on_cached_votes_down", using: :btree
+ add_index "comments", ["cached_votes_total"], name: "index_comments_on_cached_votes_total", using: :btree
+ add_index "comments", ["cached_votes_up"], name: "index_comments_on_cached_votes_up", using: :btree
add_index "comments", ["commentable_id", "commentable_type"], name: "index_comments_on_commentable_id_and_commentable_type", using: :btree
add_index "comments", ["hidden_at"], name: "index_comments_on_hidden_at", using: :btree
add_index "comments", ["user_id"], name: "index_comments_on_user_id", using: :btree
@@ -64,17 +70,34 @@ ActiveRecord::Schema.define(version: 20150824113326) do
t.string "title", limit: 80
t.text "description"
t.integer "author_id"
- 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.datetime "hidden_at"
t.string "visit_id"
t.datetime "flagged_as_inappropiate_at"
t.integer "inappropiate_flags_count", default: 0
- t.datetime "reviewed_at"
+ t.integer "cached_votes_total", default: 0
+ t.integer "cached_votes_up", default: 0
+ t.integer "cached_votes_down", default: 0
+ t.datetime "archived_at"
+ t.integer "comments_count", default: 0
end
+ add_index "debates", ["cached_votes_down"], name: "index_debates_on_cached_votes_down", using: :btree
+ add_index "debates", ["cached_votes_total"], name: "index_debates_on_cached_votes_total", using: :btree
+ add_index "debates", ["cached_votes_up"], name: "index_debates_on_cached_votes_up", using: :btree
add_index "debates", ["hidden_at"], name: "index_debates_on_hidden_at", using: :btree
+ create_table "identities", force: :cascade do |t|
+ t.integer "user_id"
+ t.string "provider"
+ t.string "uid"
+ t.datetime "created_at", null: false
+ t.datetime "updated_at", null: false
+ end
+
+ add_index "identities", ["user_id"], name: "index_identities_on_user_id", using: :btree
+
create_table "inappropiate_flags", force: :cascade do |t|
t.integer "user_id"
t.string "flaggable_type"
@@ -214,7 +237,8 @@ ActiveRecord::Schema.define(version: 20150824113326) do
add_index "votes", ["voter_id", "voter_type", "vote_scope"], name: "index_votes_on_voter_id_and_voter_type_and_vote_scope", using: :btree
add_foreign_key "administrators", "users"
+ add_foreign_key "identities", "users"
add_foreign_key "inappropiate_flags", "users"
add_foreign_key "moderators", "users"
add_foreign_key "organizations", "users"
-end
+end
\ No newline at end of file
diff --git a/lib/acts_as_paranoid_aliases.rb b/lib/acts_as_paranoid_aliases.rb
index dbb0d8350..b4faa19b9 100644
--- a/lib/acts_as_paranoid_aliases.rb
+++ b/lib/acts_as_paranoid_aliases.rb
@@ -5,11 +5,15 @@ module ActsAsParanoidAliases
def hide
update_attribute(:hidden_at, Time.now)
+ after_hide
end
def hidden?
deleted?
end
+
+ def after_hide
+ end
end
module ClassMethods
diff --git a/spec/factories.rb b/spec/factories.rb
index 038a0102e..ded2e20a0 100644
--- a/spec/factories.rb
+++ b/spec/factories.rb
@@ -1,5 +1,4 @@
FactoryGirl.define do
-
factory :user do
username 'Manuela'
sequence(:email) { |n| "manuela#{n}@madrid.es" }
@@ -7,6 +6,12 @@ FactoryGirl.define do
confirmed_at { Time.now }
end
+ factory :identity do
+ user nil
+ provider "Twitter"
+ uid "MyString"
+ end
+
factory :debate do
sequence(:title) { |n| "Debate #{n} title" }
description 'Debate description'
@@ -17,8 +22,8 @@ FactoryGirl.define do
hidden_at Time.now
end
- trait :reviewed do
- reviewed_at Time.now
+ trait :archived do
+ archived_at Time.now
end
trait :flagged_as_inappropiate do
@@ -32,6 +37,9 @@ FactoryGirl.define do
association :votable, factory: :debate
association :voter, factory: :user
vote_flag true
+ after(:create) do |vote, _|
+ vote.votable.update_cached_votes
+ end
end
factory :comment do
@@ -43,8 +51,8 @@ FactoryGirl.define do
hidden_at Time.now
end
- trait :reviewed do
- reviewed_at Time.now
+ trait :archived do
+ archived_at Time.now
end
trait :flagged_as_inappropiate do
diff --git a/spec/features/comments_spec.rb b/spec/features/comments_spec.rb
index 4ed16d915..58626b02b 100644
--- a/spec/features/comments_spec.rb
+++ b/spec/features/comments_spec.rb
@@ -133,7 +133,7 @@ feature 'Comments' do
expect(page).to have_css(".comment.comment.comment.comment.comment.comment.comment.comment")
end
- scenario "Flagging as inappropiate", :js do
+ scenario "Flagging as inappropriate", :js do
user = create(:user)
debate = create(:debate)
comment = create(:comment, commentable: debate)
@@ -142,15 +142,16 @@ feature 'Comments' do
visit debate_path(debate)
within "#comment_#{comment.id}" do
- expect(page).to_not have_link "Undo flag as inappropiate"
- click_on 'Flag as inappropiate'
- expect(page).to have_link "Undo flag as inappropiate"
+ page.find("#flag-expand-comment-#{comment.id}").click
+ page.find("#flag-comment-#{comment.id}").click
+
+ expect(page).to have_css("#unflag-expand-comment-#{comment.id}")
end
expect(InappropiateFlag.flagged?(user, comment)).to be
end
- scenario "Undoing flagging as inappropiate", :js do
+ scenario "Undoing flagging as inappropriate", :js do
user = create(:user)
debate = create(:debate)
comment = create(:comment, commentable: debate)
@@ -160,9 +161,10 @@ feature 'Comments' do
visit debate_path(debate)
within "#comment_#{comment.id}" do
- expect(page).to_not have_link("Flag as inappropiate", exact: true)
- click_on 'Undo flag as inappropiate'
- expect(page).to have_link("Flag as inappropiate", exact: true)
+ page.find("#unflag-expand-comment-#{comment.id}").click
+ page.find("#unflag-comment-#{comment.id}").click
+
+ expect(page).to have_css("#flag-expand-comment-#{comment.id}")
end
expect(InappropiateFlag.flagged?(user, comment)).to_not be
@@ -286,4 +288,4 @@ feature 'Comments' do
end
end
-end
\ No newline at end of file
+end
diff --git a/spec/features/debates_spec.rb b/spec/features/debates_spec.rb
index c685725d8..22b689308 100644
--- a/spec/features/debates_spec.rb
+++ b/spec/features/debates_spec.rb
@@ -323,9 +323,10 @@ feature 'Debates' do
visit debate_path(debate)
within "#debate_#{debate.id}" do
- expect(page).to_not have_link "Undo flag as inappropiate"
- click_on 'Flag as inappropiate'
- expect(page).to have_link "Undo flag as inappropiate"
+ page.find("#flag-expand-debate-#{debate.id}").click
+ page.find("#flag-debate-#{debate.id}").click
+
+ expect(page).to have_css("#unflag-expand-debate-#{debate.id}")
end
expect(InappropiateFlag.flagged?(user, debate)).to be
@@ -340,9 +341,10 @@ feature 'Debates' do
visit debate_path(debate)
within "#debate_#{debate.id}" do
- expect(page).to_not have_link("Flag as inappropiate", exact: true)
- click_on 'Undo flag as inappropiate'
- expect(page).to have_link("Flag as inappropiate", exact: true)
+ page.find("#unflag-expand-debate-#{debate.id}").click
+ page.find("#unflag-debate-#{debate.id}").click
+
+ expect(page).to have_css("#flag-expand-debate-#{debate.id}")
end
expect(InappropiateFlag.flagged?(user, debate)).to_not be
diff --git a/spec/features/moderation/comments_spec.rb b/spec/features/moderation/comments_spec.rb
index 5a4100f77..2e3d1196e 100644
--- a/spec/features/moderation/comments_spec.rb
+++ b/spec/features/moderation/comments_spec.rb
@@ -104,57 +104,57 @@ feature 'Moderate Comments' do
visit moderation_comments_path
expect(page).to_not have_link('All')
expect(page).to have_link('Pending')
- expect(page).to have_link('Reviewed')
+ expect(page).to have_link('Archived')
visit moderation_comments_path(filter: 'all')
expect(page).to_not have_link('All')
expect(page).to have_link('Pending')
- expect(page).to have_link('Reviewed')
+ expect(page).to have_link('Archived')
- visit moderation_comments_path(filter: 'pending_review')
+ visit moderation_comments_path(filter: 'pending')
expect(page).to have_link('All')
expect(page).to_not have_link('Pending')
- expect(page).to have_link('Reviewed')
+ expect(page).to have_link('Archived')
- visit moderation_comments_path(filter: 'reviewed')
+ visit moderation_comments_path(filter: 'archived')
expect(page).to have_link('All')
expect(page).to have_link('Pending')
- expect(page).to_not have_link('Reviewed')
+ expect(page).to_not have_link('Archived')
end
scenario "Filtering comments" do
create(:comment, :flagged_as_inappropiate, body: "Pending comment")
create(:comment, :flagged_as_inappropiate, :hidden, body: "Hidden comment")
- create(:comment, :flagged_as_inappropiate, :reviewed, body: "Reviewed comment")
+ create(:comment, :flagged_as_inappropiate, :archived, body: "Archived comment")
visit moderation_comments_path(filter: 'all')
expect(page).to have_content('Pending comment')
expect(page).to_not have_content('Hidden comment')
- expect(page).to have_content('Reviewed comment')
+ expect(page).to have_content('Archived comment')
- visit moderation_comments_path(filter: 'pending_review')
+ visit moderation_comments_path(filter: 'pending')
expect(page).to have_content('Pending comment')
expect(page).to_not have_content('Hidden comment')
- expect(page).to_not have_content('Reviewed comment')
+ expect(page).to_not have_content('Archived comment')
- visit moderation_comments_path(filter: 'reviewed')
+ visit moderation_comments_path(filter: 'archived')
expect(page).to_not have_content('Pending comment')
expect(page).to_not have_content('Hidden comment')
- expect(page).to have_content('Reviewed comment')
+ expect(page).to have_content('Archived comment')
end
scenario "Reviewing links remember the pagination setting and the filter" do
per_page = Kaminari.config.default_per_page
(per_page + 2).times { create(:comment, :flagged_as_inappropiate) }
- visit moderation_comments_path(filter: 'pending_review', page: 2)
+ visit moderation_comments_path(filter: 'pending', page: 2)
- click_link('Mark as reviewed', match: :first)
+ click_link('Archive', match: :first, exact: true)
uri = URI.parse(current_url)
query_params = Rack::Utils.parse_nested_query(uri.query).symbolize_keys
- expect(query_params[:filter]).to eq('pending_review')
+ expect(query_params[:filter]).to eq('pending')
expect(query_params[:page]).to eq('2')
end
@@ -172,7 +172,7 @@ feature 'Moderate Comments' do
expect(page).to have_content('spammy spam')
expect(page).to have_content('1')
expect(page).to have_link('Hide')
- expect(page).to have_link('Mark as reviewed')
+ expect(page).to have_link('Archive')
end
end
@@ -187,18 +187,18 @@ feature 'Moderate Comments' do
expect(@comment.reload).to be_hidden
end
- scenario 'Marking the comment as reviewed' do
+ scenario 'Marking the comment as archived' do
within("#comment_#{@comment.id}") do
- click_link('Mark as reviewed')
+ click_link('Archive')
end
expect(current_path).to eq(moderation_comments_path)
within("#comment_#{@comment.id}") do
- expect(page).to have_content('Reviewed')
+ expect(page).to have_content('Archived')
end
- expect(@comment.reload).to be_reviewed
+ expect(@comment.reload).to be_archived
end
end
end
diff --git a/spec/features/moderation/debates_spec.rb b/spec/features/moderation/debates_spec.rb
index 1ea3101e0..b1234bb1b 100644
--- a/spec/features/moderation/debates_spec.rb
+++ b/spec/features/moderation/debates_spec.rb
@@ -47,57 +47,57 @@ feature 'Moderate debates' do
visit moderation_debates_path
expect(page).to_not have_link('All')
expect(page).to have_link('Pending')
- expect(page).to have_link('Reviewed')
+ expect(page).to have_link('Archived')
visit moderation_debates_path(filter: 'all')
expect(page).to_not have_link('All')
expect(page).to have_link('Pending')
- expect(page).to have_link('Reviewed')
+ expect(page).to have_link('Archived')
- visit moderation_debates_path(filter: 'pending_review')
+ visit moderation_debates_path(filter: 'pending')
expect(page).to have_link('All')
expect(page).to_not have_link('Pending')
- expect(page).to have_link('Reviewed')
+ expect(page).to have_link('Archived')
- visit moderation_debates_path(filter: 'reviewed')
+ visit moderation_debates_path(filter: 'archived')
expect(page).to have_link('All')
expect(page).to have_link('Pending')
- expect(page).to_not have_link('Reviewed')
+ expect(page).to_not have_link('Archived')
end
scenario "Filtering debates" do
create(:debate, :flagged_as_inappropiate, title: "Pending debate")
create(:debate, :flagged_as_inappropiate, :hidden, title: "Hidden debate")
- create(:debate, :flagged_as_inappropiate, :reviewed, title: "Reviewed debate")
+ create(:debate, :flagged_as_inappropiate, :archived, title: "Archived debate")
visit moderation_debates_path(filter: 'all')
expect(page).to have_content('Pending debate')
expect(page).to_not have_content('Hidden debate')
- expect(page).to have_content('Reviewed debate')
+ expect(page).to have_content('Archived debate')
- visit moderation_debates_path(filter: 'pending_review')
+ visit moderation_debates_path(filter: 'pending')
expect(page).to have_content('Pending debate')
expect(page).to_not have_content('Hidden debate')
- expect(page).to_not have_content('Reviewed debate')
+ expect(page).to_not have_content('Archived debate')
- visit moderation_debates_path(filter: 'reviewed')
+ visit moderation_debates_path(filter: 'archived')
expect(page).to_not have_content('Pending debate')
expect(page).to_not have_content('Hidden debate')
- expect(page).to have_content('Reviewed debate')
+ expect(page).to have_content('Archived debate')
end
scenario "Reviewing links remember the pagination setting and the filter" do
per_page = Kaminari.config.default_per_page
(per_page + 2).times { create(:debate, :flagged_as_inappropiate) }
- visit moderation_debates_path(filter: 'pending_review', page: 2)
+ visit moderation_debates_path(filter: 'pending', page: 2)
- click_link('Mark as reviewed', match: :first)
+ click_link('Archive', match: :first, exact: true)
uri = URI.parse(current_url)
query_params = Rack::Utils.parse_nested_query(uri.query).symbolize_keys
- expect(query_params[:filter]).to eq('pending_review')
+ expect(query_params[:filter]).to eq('pending')
expect(query_params[:page]).to eq('2')
end
@@ -114,7 +114,7 @@ feature 'Moderate debates' do
expect(page).to have_content('buy buy buy')
expect(page).to have_content('1')
expect(page).to have_link('Hide')
- expect(page).to have_link('Mark as reviewed')
+ expect(page).to have_link('Archive')
end
end
@@ -129,18 +129,18 @@ feature 'Moderate debates' do
expect(@debate.reload).to be_hidden
end
- scenario 'Marking the debate as reviewed' do
+ scenario 'Marking the debate as archived' do
within("#debate_#{@debate.id}") do
- click_link('Mark as reviewed')
+ click_link('Archive')
end
expect(current_path).to eq(moderation_debates_path)
within("#debate_#{@debate.id}") do
- expect(page).to have_content('Reviewed')
+ expect(page).to have_content('Archived')
end
- expect(@debate.reload).to be_reviewed
+ expect(@debate.reload).to be_archived
end
end
end
diff --git a/spec/features/users_spec.rb b/spec/features/users_spec.rb
index 42511f28c..1fa30bcbe 100644
--- a/spec/features/users_spec.rb
+++ b/spec/features/users_spec.rb
@@ -2,44 +2,159 @@ require 'rails_helper'
feature 'Users' do
- scenario 'Sign up' do
- visit '/'
- click_link 'Sign up'
+ context 'Regular authentication' do
+ scenario 'Sign up' do
+ visit '/'
+ click_link 'Sign up'
- fill_in 'user_username', with: 'Manuela Carmena'
- fill_in 'user_email', with: 'manuela@madrid.es'
- fill_in 'user_password', with: 'judgementday'
- fill_in 'user_password_confirmation', with: 'judgementday'
- fill_in 'user_captcha', with: correct_captcha_text
+ fill_in 'user_username', with: 'Manuela Carmena'
+ fill_in 'user_email', with: 'manuela@madrid.es'
+ fill_in 'user_password', with: 'judgementday'
+ fill_in 'user_password_confirmation', with: 'judgementday'
+ fill_in 'user_captcha', with: correct_captcha_text
- click_button 'Sign up'
+ click_button 'Sign up'
- expect(page).to have_content "A message with a confirmation link has been sent to your email address. Please follow the link to activate your account."
+ expect(page).to have_content "A message with a confirmation link has been sent to your email address. Please follow the link to activate your account."
- sent_token = /.*confirmation_token=(.*)".*/.match(ActionMailer::Base.deliveries.last.body.to_s)[1]
- visit user_confirmation_path(confirmation_token: sent_token)
+ sent_token = /.*confirmation_token=(.*)".*/.match(ActionMailer::Base.deliveries.last.body.to_s)[1]
+ visit user_confirmation_path(confirmation_token: sent_token)
- expect(page).to have_content "Your email address has been successfully confirmed"
+ expect(page).to have_content "Your email address has been successfully confirmed"
+ end
+
+ scenario 'Errors on sign up' do
+ visit '/'
+ click_link 'Sign up'
+ click_button 'Sign up'
+
+ expect(page).to have_content error_message
+ end
+
+ scenario 'Sign in' do
+ create(:user, email: 'manuela@madrid.es', password: 'judgementday')
+
+ visit '/'
+ click_link 'Log in'
+ fill_in 'user_email', with: 'manuela@madrid.es'
+ fill_in 'user_password', with: 'judgementday'
+ click_button 'Log in'
+
+ expect(page).to have_content 'Signed in successfully.'
+ end
end
- scenario 'Errors on sign up' do
- visit '/'
- click_link 'Sign up'
- click_button 'Sign up'
+ context 'OAuth authentication' do
+ context 'Twitter' do
+ background do
+ #request.env["devise.mapping"] = Devise.mappings[:user]
+ end
- expect(page).to have_content error_message
- end
+ scenario 'Sign up, when email was provided by OAuth provider' do
+ omniauth_twitter_hash = { 'provider' => 'twitter',
+ 'uid' => '12345',
+ 'info' => {
+ 'name' => 'manuela',
+ 'email' => 'manuelacarmena@example.com',
+ 'nickname' => 'ManuelaRocks',
+ 'verified' => '1'
+ },
+ 'extra' => { 'raw_info' =>
+ { 'location' => 'Madrid',
+ 'name' => 'Manuela de las Carmenas'
+ }
+ }
+ }
- scenario 'Sign in' do
- create(:user, email: 'manuela@madrid.es', password: 'judgementday')
+ OmniAuth.config.add_mock(:twitter, omniauth_twitter_hash)
- visit '/'
- click_link 'Log in'
- fill_in 'user_email', with: 'manuela@madrid.es'
- fill_in 'user_password', with: 'judgementday'
- click_button 'Log in'
+ visit '/'
+ click_link 'Sign up'
- expect(page).to have_content 'Signed in successfully.'
+ expect do
+ expect do
+ expect do
+ click_link 'Sign in with Twitter'
+ end.not_to change { ActionMailer::Base.deliveries.size }
+ end.to change { Identity.count }.by(1)
+ end.to change { User.count }.by(1)
+
+ expect(current_path).to eq(root_path)
+ expect_to_be_signed_in
+
+ user = User.last
+ expect(user.username).to eq('ManuelaRocks')
+ expect(user.email).to eq('manuelacarmena@example.com')
+ expect(user.confirmed?).to eq(true)
+ end
+
+ scenario 'Sign up, when neither email nor nickname were provided by OAuth provider' do
+ omniauth_twitter_hash = { 'provider' => 'twitter',
+ 'uid' => '12345',
+ 'info' => {
+ 'name' => 'manuela'
+ },
+ 'extra' => { 'raw_info' =>
+ { 'location' => 'Madrid',
+ 'name' => 'Manuela de las Carmenas'
+ }
+ }
+ }
+
+ OmniAuth.config.add_mock(:twitter, omniauth_twitter_hash)
+
+ visit '/'
+ click_link 'Sign up'
+
+ expect do
+ expect do
+ expect do
+ click_link 'Sign in with Twitter'
+ end.not_to change { ActionMailer::Base.deliveries.size }
+ end.to change { Identity.count }.by(1)
+ end.to change { User.count }.by(1)
+
+ expect(current_path).to eq(finish_signup_path)
+
+ user = User.last
+ expect(user.username).to eq('manuela-de-las-carmenas')
+ expect(user.email).to eq("omniauth@participacion-12345-twitter.com")
+
+ fill_in 'user_email', with: 'manueladelascarmenas@example.com'
+ click_button 'Sign up'
+
+ sent_token = /.*confirmation_token=(.*)".*/.match(ActionMailer::Base.deliveries.last.body.to_s)[1]
+ visit user_confirmation_path(confirmation_token: sent_token)
+
+ expect(page).to have_content "Your email address has been successfully confirmed"
+
+ expect(user.reload.email).to eq('manueladelascarmenas@example.com')
+ end
+
+ scenario 'Sign in, user was already signed up with OAuth' do
+ user = create(:user, email: 'manuela@madrid.es', password: 'judgementday')
+ identity = create(:identity, uid: '12345', provider: 'twitter', user: user)
+ omniauth_twitter_hash = { 'provider' => 'twitter',
+ 'uid' => '12345',
+ 'info' => {
+ 'name' => 'manuela'
+ }
+ }
+
+ OmniAuth.config.add_mock(:twitter, omniauth_twitter_hash)
+
+ visit '/'
+ click_link 'Log in'
+
+ expect do
+ expect do
+ click_link 'Sign in with Twitter'
+ end.not_to change { Identity.count }
+ end.not_to change { User.count }
+
+ expect_to_be_signed_in
+ end
+ end
end
scenario 'Sign out' do
@@ -73,5 +188,4 @@ feature 'Users' do
expect(page).to have_content "Your password has been changed successfully. You are now signed in."
end
-
end
diff --git a/spec/models/ability_spec.rb b/spec/models/ability_spec.rb
index ff3e3800c..a7cfd195f 100644
--- a/spec/models/ability_spec.rb
+++ b/spec/models/ability_spec.rb
@@ -131,8 +131,8 @@ describe Ability do
let(:own_debate) { create(:debate, author: user) }
let(:hidden_comment) { create(:comment, :hidden) }
let(:hidden_debate) { create(:debate, :hidden) }
- let(:reviewed_comment) { create(:comment, :reviewed) }
- let(:reviewed_debate) { create(:debate, :reviewed) }
+ let(:archived_comment) { create(:comment, :archived) }
+ let(:archived_debate) { create(:debate, :archived) }
it { should be_able_to(:hide, comment) }
it { should be_able_to(:hide_in_moderation_screen, comment) }
@@ -144,15 +144,15 @@ describe Ability do
it { should_not be_able_to(:hide, hidden_debate) }
it { should_not be_able_to(:hide, own_debate) }
- it { should be_able_to(:mark_as_reviewed, comment) }
- it { should_not be_able_to(:mark_as_reviewed, hidden_comment) }
- it { should_not be_able_to(:mark_as_reviewed, reviewed_comment) }
- it { should_not be_able_to(:mark_as_reviewed, own_comment) }
+ it { should be_able_to(:archive, comment) }
+ it { should_not be_able_to(:archive, hidden_comment) }
+ it { should_not be_able_to(:archive, archived_comment) }
+ it { should_not be_able_to(:archive, own_comment) }
- it { should be_able_to(:mark_as_reviewed, debate) }
- it { should_not be_able_to(:mark_as_reviewed, hidden_debate) }
- it { should_not be_able_to(:mark_as_reviewed, reviewed_debate) }
- it { should_not be_able_to(:mark_as_reviewed, own_debate) }
+ it { should be_able_to(:archive, debate) }
+ it { should_not be_able_to(:archive, hidden_debate) }
+ it { should_not be_able_to(:archive, archived_debate) }
+ it { should_not be_able_to(:archive, own_debate) }
it { should_not be_able_to(:hide, user) }
it { should be_able_to(:hide, other_user) }
diff --git a/spec/models/comment_spec.rb b/spec/models/comment_spec.rb
index 98420c000..4115fedcf 100644
--- a/spec/models/comment_spec.rb
+++ b/spec/models/comment_spec.rb
@@ -8,6 +8,15 @@ describe Comment do
expect(comment).to be_valid
end
+ it "should update cache_counter in debate after hide" do
+ debate = create(:debate)
+ comment = create(:comment, commentable: debate)
+
+ expect(debate.reload.comments_count).to eq(1)
+ comment.hide
+ expect(debate.reload.comments_count).to eq(0)
+ end
+
describe "#children_count" do
let(:comment) { create(:comment) }
let(:debate) { comment.debate }
diff --git a/spec/models/identity_spec.rb b/spec/models/identity_spec.rb
new file mode 100644
index 000000000..82d5c4be3
--- /dev/null
+++ b/spec/models/identity_spec.rb
@@ -0,0 +1,9 @@
+require 'rails_helper'
+
+RSpec.describe Identity, type: :model do
+ let(:identity) { build(:identity) }
+
+ it "should be valid" do
+ expect(identity).to be_valid
+ end
+end
diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb
index 5a4bbdf88..e0260285a 100644
--- a/spec/models/user_spec.rb
+++ b/spec/models/user_spec.rb
@@ -50,6 +50,26 @@ describe User do
end
end
+ describe 'OmniAuth' do
+ describe '#email_provided?' do
+ it "is false if the email matchs was temporarely assigned by the OmniAuth process" do
+ subject.email = 'omniauth@participacion-ABCD-twitter.com'
+ expect(subject.email_provided?).to eq(false)
+ end
+
+ it "is true if the email is not omniauth-like" do
+ subject.email = 'manuelacarmena@example.com'
+ expect(subject.email_provided?).to eq(true)
+ end
+
+ it "is true if the user's real email is pending to be confirmed" do
+ subject.email = 'omniauth@participacion-ABCD-twitter.com'
+ subject.unconfirmed_email = 'manuelacarmena@example.com'
+ expect(subject.email_provided?).to eq(true)
+ end
+ end
+ end
+
describe "administrator?" do
it "is false when the user is not an admin" do
expect(subject.administrator?).to be false
diff --git a/spec/rails_helper.rb b/spec/rails_helper.rb
index d073cc173..c2f5db0fe 100644
--- a/spec/rails_helper.rb
+++ b/spec/rails_helper.rb
@@ -22,3 +22,5 @@ RSpec.configure do |config|
end
Capybara.javascript_driver = :poltergeist
+
+OmniAuth.config.test_mode = true
diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb
index 0e0b14960..bf1a65776 100644
--- a/spec/spec_helper.rb
+++ b/spec/spec_helper.rb
@@ -27,6 +27,15 @@ RSpec.configure do |config|
DatabaseCleaner.clean
end
+ config.before(:each, type: :feature) do
+ Bullet.start_request
+ end
+
+ config.after(:each, type: :feature) do
+ Bullet.perform_out_of_channel_notifications if Bullet.notification?
+ Bullet.end_request
+ end
+
# Allows RSpec to persist some state between runs in order to support
# the `--only-failures` and `--next-failure` CLI options.
config.example_status_persistence_file_path = "spec/examples.txt"
@@ -57,4 +66,6 @@ RSpec.configure do |config|
# test failures related to randomization by passing the same `--seed` value
# as the one that triggered the failure.
Kernel.srand config.seed
+
+
end
diff --git a/spec/support/common_actions.rb b/spec/support/common_actions.rb
index 21a98f56f..12d6affd3 100644
--- a/spec/support/common_actions.rb
+++ b/spec/support/common_actions.rb
@@ -77,4 +77,7 @@ module CommonActions
/\d errors? prohibited this (.*) from being saved:/
end
+ def expect_to_be_signed_in
+ expect(find('.top-bar')).to have_content 'My account'
+ end
end