Merge branch 'master' into admin-77
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -19,5 +19,6 @@
|
||||
/spec/examples.txt
|
||||
/config/database.yml
|
||||
/config/secrets.yml
|
||||
/config/deploy-secrets.yml
|
||||
|
||||
/coverage
|
||||
|
||||
@@ -43,3 +43,5 @@ Cuando quieras resolver una incidencia mediante código:
|
||||
* Lo que se esperaba que pasara
|
||||
* Lo que ha pasado
|
||||
* También es buena idea que incluyas tu sistema operativo, navegador, versión de navegador y plugins instalados.
|
||||
|
||||
¡Gracias! :heart: :heart: :heart:
|
||||
|
||||
46
CONTRIBUTING_EN.md
Normal file
46
CONTRIBUTING_EN.md
Normal file
@@ -0,0 +1,46 @@
|
||||
## Team members
|
||||
|
||||
* Raimond Garcia [github](https://github.com/voodoorai2000) | [twitter](https://twitter.com/voodoorai2000)
|
||||
* Juanjo Bazán [github](https://github.com/xuanxu) | [twitter](https://twitter.com/xuanxu)
|
||||
* Enrique García Cota [github](https://github.com/kikito) | [twitter](https://twitter.com/otikik)
|
||||
* Alberto Garcia Cabeza [github](https://github.com/decabeza) | [twitter](https://twitter.com/decabeza)
|
||||
|
||||
## Report an issue
|
||||
|
||||
The prefered way to report any bug is [opening an issue in the project's Github repo](https://github.com/AyuntamientoMadrid/participacion/issues/new).
|
||||
|
||||
For more informal communication, contact team members via twitter
|
||||
|
||||
## Resolve an issue
|
||||
|
||||
Admins tag issues using two label related with collaboration availability:
|
||||
|
||||
* `PRs-welcome`: [issues labeled with PRs-welcome](https://github.com/AyuntamientoMadrid/participacion/labels/PRs-welcome) are well defined features ready to be implemented by whoever wants to do it.
|
||||
|
||||
* `Not-ready`: with this label admins mark features or changes that are not well defined yet or subject to an internal decision. Is not a good idea to start implementation of these isuues.
|
||||
|
||||
If you want to contribute code to solve an issue:
|
||||
|
||||
* Add a comment to tell everyone you are working on the issue.
|
||||
* If an issue has someone assigned it means that person is already working on it.
|
||||
* Fork the project.
|
||||
* Create a topic branch based on master.
|
||||
* Commit there your code to solve the issue.
|
||||
* Make sure all test are passing (and add specs to test any new feature if needed).
|
||||
* Open a *pull request* to the main repository describing what issue you are addressing.
|
||||
|
||||
## Other ways of contributing without coding
|
||||
|
||||
* If you think there's a feature missing, or find a bug, create an issue (make sure it has not already been reported).
|
||||
* You can also help promoting the project talking about it in your social networks.
|
||||
|
||||
## How to report an issue
|
||||
|
||||
* Try to use a descriptive and to-the-point title
|
||||
* Is a good idea to include some of there sections:
|
||||
* Steps to reproduce the bug
|
||||
* Expected behaviour/response
|
||||
* Actual response
|
||||
* Sometimes it is also helpful if you mention your operating system, browser version and installed plugins.
|
||||
|
||||
Thanks! :heart: :heart: :heart:
|
||||
14
Capfile
Normal file
14
Capfile
Normal file
@@ -0,0 +1,14 @@
|
||||
# Load DSL and set up stages
|
||||
require 'capistrano/setup'
|
||||
|
||||
# Include default deployment tasks
|
||||
require 'capistrano/deploy'
|
||||
|
||||
require 'capistrano/rvm'
|
||||
require 'capistrano/bundler'
|
||||
require 'capistrano/rails/assets'
|
||||
require 'capistrano/rails/migrations'
|
||||
require 'capistrano/passenger'
|
||||
|
||||
# Load custom tasks from `lib/capistrano/tasks` if you have any defined
|
||||
Dir.glob('lib/capistrano/tasks/*.rake').each { |r| import r }
|
||||
15
Gemfile
15
Gemfile
@@ -1,6 +1,5 @@
|
||||
source 'https://rubygems.org'
|
||||
|
||||
|
||||
# Bundle edge Rails instead: gem 'rails', github: 'rails/rails'
|
||||
gem 'rails', '4.2.3'
|
||||
# Use PostgreSQL
|
||||
@@ -26,11 +25,6 @@ gem 'devise'
|
||||
# Use ActiveModel has_secure_password
|
||||
# gem 'bcrypt', '~> 3.1.7'
|
||||
gem 'acts_as_commentable_with_threading'
|
||||
# Use Unicorn as the app server
|
||||
# gem 'unicorn'
|
||||
|
||||
# Use Capistrano for deployment
|
||||
# gem 'capistrano-rails', group: :development
|
||||
gem 'acts-as-taggable-on'
|
||||
gem "responders"
|
||||
gem 'foundation-rails'
|
||||
@@ -53,6 +47,11 @@ group :development, :test do
|
||||
gem 'quiet_assets'
|
||||
gem 'letter_opener_web', '~> 1.2.0'
|
||||
gem 'i18n-tasks'
|
||||
gem 'capistrano', '3.4.0', require: false
|
||||
gem "capistrano-bundler", '1.1.4', require: false
|
||||
gem "capistrano-rails", '1.1.3', require: false
|
||||
gem "capistrano-rvm", require: false
|
||||
gem "capistrano-passenger", require: false
|
||||
end
|
||||
|
||||
group :test do
|
||||
@@ -61,3 +60,7 @@ group :test do
|
||||
gem 'coveralls', require: false
|
||||
end
|
||||
|
||||
group :test do
|
||||
gem 'email_spec'
|
||||
end
|
||||
|
||||
|
||||
32
Gemfile.lock
32
Gemfile.lock
@@ -54,6 +54,21 @@ GEM
|
||||
byebug (5.0.0)
|
||||
columnize (= 0.9.0)
|
||||
cancancan (1.12.0)
|
||||
capistrano (3.4.0)
|
||||
i18n
|
||||
rake (>= 10.0.0)
|
||||
sshkit (~> 1.3)
|
||||
capistrano-bundler (1.1.4)
|
||||
capistrano (~> 3.1)
|
||||
sshkit (~> 1.2)
|
||||
capistrano-passenger (0.1.1)
|
||||
capistrano (~> 3.0)
|
||||
capistrano-rails (1.1.3)
|
||||
capistrano (~> 3.1)
|
||||
capistrano-bundler (~> 1.1)
|
||||
capistrano-rvm (0.1.2)
|
||||
capistrano (~> 3.0)
|
||||
sshkit (~> 1.2)
|
||||
capybara (2.4.4)
|
||||
mime-types (>= 1.16)
|
||||
nokogiri (>= 1.3.3)
|
||||
@@ -75,6 +90,7 @@ GEM
|
||||
coffee-script-source
|
||||
execjs
|
||||
coffee-script-source (1.9.1.1)
|
||||
colorize (0.7.7)
|
||||
columnize (0.9.0)
|
||||
coveralls (0.8.2)
|
||||
json (~> 1.8)
|
||||
@@ -99,6 +115,9 @@ GEM
|
||||
json
|
||||
thread
|
||||
thread_safe
|
||||
email_spec (1.6.0)
|
||||
launchy (~> 2.1)
|
||||
mail (~> 2.2)
|
||||
erubis (2.7.0)
|
||||
execjs (2.5.2)
|
||||
factory_girl (4.5.0)
|
||||
@@ -146,6 +165,9 @@ GEM
|
||||
mini_portile (0.6.2)
|
||||
minitest (5.7.0)
|
||||
multi_json (1.11.2)
|
||||
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)
|
||||
@@ -233,6 +255,10 @@ GEM
|
||||
actionpack (>= 3.0)
|
||||
activesupport (>= 3.0)
|
||||
sprockets (>= 2.8, < 4.0)
|
||||
sshkit (1.7.1)
|
||||
colorize (>= 0.7.0)
|
||||
net-scp (>= 1.1.2)
|
||||
net-ssh (>= 2.8.0)
|
||||
term-ansicolor (1.3.2)
|
||||
tins (~> 1.0)
|
||||
terminal-table (1.5.2)
|
||||
@@ -273,12 +299,18 @@ DEPENDENCIES
|
||||
acts_as_votable
|
||||
byebug
|
||||
cancancan
|
||||
capistrano (= 3.4.0)
|
||||
capistrano-bundler (= 1.1.4)
|
||||
capistrano-passenger
|
||||
capistrano-rails (= 1.1.3)
|
||||
capistrano-rvm
|
||||
capybara
|
||||
ckeditor
|
||||
coffee-rails (~> 4.1.0)
|
||||
coveralls
|
||||
database_cleaner
|
||||
devise
|
||||
email_spec
|
||||
factory_girl_rails
|
||||
foundation-rails
|
||||
i18n-tasks
|
||||
|
||||
@@ -27,8 +27,8 @@ 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:create db:schema:load
|
||||
RAILS_ENV=test bundle exec rake db:create db:schema:load
|
||||
bundle exec bin/rake db:setup
|
||||
RAILS_ENV=test bundle exec rake db:setup
|
||||
```
|
||||
|
||||
Para ejecutar la aplicación en local:
|
||||
@@ -47,4 +47,4 @@ El código de este proyecto está publicado bajo la licencia MIT (ver MIT-licens
|
||||
|
||||
## Contribuciones
|
||||
|
||||
Ver fichero CONTRIBUTING.md
|
||||
Ver fichero [CONTRIBUTING.md](CONTRIBUTING.md)
|
||||
|
||||
51
README_EN.md
Normal file
51
README_EN.md
Normal file
@@ -0,0 +1,51 @@
|
||||
# Ayuntamiento de Madrid (Madrid city's government) eParticipation application
|
||||
|
||||
[](https://travis-ci.org/AyuntamientoMadrid/participacion)
|
||||
[](https://codeclimate.com/github/AyuntamientoMadrid/participacion)
|
||||
[](https://gemnasium.com/AyuntamientoMadrid/participacion)
|
||||
[](https://coveralls.io/github/AyuntamientoMadrid/participacion?branch=master)
|
||||
|
||||
This is the opensource code repository of Madrid City government eParticipation website
|
||||
|
||||
## Current state
|
||||
|
||||
Development started on [2015 July 15th](https://github.com/AyuntamientoMadrid/participacion/commit/8db36308379accd44b5de4f680a54c41a0cc6fc6)
|
||||
|
||||
The project is in its early stages. Features currently present in the code (and their names) are subject to change.
|
||||
|
||||
## Tech stack
|
||||
|
||||
The application backend is written in the [Ruby language](https://www.ruby-lang.org/) using the [Ruby on Rails](http://rubyonrails.org/) framework.
|
||||
|
||||
Frontend tools used include [SCSS](http://sass-lang.com/) over [Foundation](http://foundation.zurb.com/) for the styles.
|
||||
|
||||
## Configuration for development and test environments
|
||||
|
||||
Prerequisites: install git, Ruby 2.2.2, bundler gem and PostgreSQL.
|
||||
|
||||
```
|
||||
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
|
||||
```
|
||||
|
||||
Run the app locally:
|
||||
```
|
||||
bundle exec bin/rails s
|
||||
```
|
||||
|
||||
Run the tests with:
|
||||
```
|
||||
bundle exec bin/rspec
|
||||
```
|
||||
|
||||
## Licence
|
||||
|
||||
Code published under MIT license (see [MIT-license.md](MIT-license.md))
|
||||
|
||||
## Contributions
|
||||
|
||||
See [CONTRIBUTING_EN.md](CONTRIBUTING_EN.md)
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 129 KiB After Width: | Height: | Size: 201 KiB |
@@ -93,6 +93,13 @@ header {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.button {
|
||||
color: white;
|
||||
font-family: inherit;
|
||||
margin-top: $line-height;
|
||||
}
|
||||
|
||||
.home-page {
|
||||
.button {
|
||||
color: white;
|
||||
font-family: inherit;
|
||||
@@ -100,18 +107,53 @@ header {
|
||||
}
|
||||
}
|
||||
|
||||
.selected {
|
||||
position: relative;
|
||||
|
||||
&:before {
|
||||
top: -14px;
|
||||
left: 50%;
|
||||
border: solid transparent;
|
||||
content: " ";
|
||||
height: 0;
|
||||
width: 0;
|
||||
position: absolute;
|
||||
border-top-color: #fff;
|
||||
border-width: 8px;
|
||||
margin-left: -8px;
|
||||
}
|
||||
}
|
||||
|
||||
.language {
|
||||
float: none;
|
||||
text-align: center;
|
||||
|
||||
@media (min-width: 480px) {
|
||||
float: left;
|
||||
}
|
||||
}
|
||||
|
||||
.external-links {
|
||||
@extend .language;
|
||||
|
||||
@media (min-width: 480px) {
|
||||
float: right;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.contain-to-grid {
|
||||
background: none;
|
||||
}
|
||||
|
||||
.top-bar {
|
||||
background: white;
|
||||
color: $header-color;
|
||||
background: rgba(0,0,0,.5);
|
||||
color: white; //$header-color;
|
||||
height: $line-height*4;
|
||||
max-width: 1170px !important;
|
||||
|
||||
.name a {
|
||||
color: black;
|
||||
color: white;
|
||||
font-family: 'Lato';
|
||||
font-size: rem-calc(36);
|
||||
font-weight: lighter;
|
||||
@@ -119,7 +161,7 @@ header {
|
||||
padding-left: 0;
|
||||
|
||||
span {
|
||||
color: $brand;
|
||||
// color: $brand;
|
||||
font-size: rem-calc(24);
|
||||
font-weight: normal;
|
||||
}
|
||||
@@ -131,14 +173,29 @@ header {
|
||||
}
|
||||
|
||||
.top-bar-section {
|
||||
margin-right: $line-height;
|
||||
|
||||
ul li > a {
|
||||
font-size: rem-calc(14);
|
||||
}
|
||||
|
||||
ul li, ul li:hover:not(.has-form) > a {
|
||||
background: none;
|
||||
}
|
||||
|
||||
li:not(.has-form) a:not(.button) {
|
||||
background: white;
|
||||
color: $brand;
|
||||
background: none;
|
||||
color: white;
|
||||
line-height: $line-height*4;
|
||||
|
||||
&:hover {
|
||||
background: none;
|
||||
color: $link-hover;
|
||||
}
|
||||
}
|
||||
|
||||
li.active:not(.has-form) a:not(.button) {
|
||||
background: none;
|
||||
height: $line-height*4;
|
||||
line-height: $line-height*4;
|
||||
}
|
||||
@@ -147,9 +204,13 @@ header {
|
||||
.top-links {
|
||||
color: white;
|
||||
font-size: rem-calc(14);
|
||||
height: $line-height*2;
|
||||
height: $line-height*3;
|
||||
padding: $line-height/2 0;
|
||||
|
||||
@media (min-width: 480px) {
|
||||
height: $line-height*2;
|
||||
}
|
||||
|
||||
a {
|
||||
color: white;
|
||||
}
|
||||
@@ -179,7 +240,7 @@ header {
|
||||
|
||||
.icon-like {
|
||||
background: white;
|
||||
border: 2px solid white;
|
||||
border: 2px solid $votes-border;
|
||||
border-radius: rem-calc(3);
|
||||
color: $votes-neutral;
|
||||
display: inline-block;
|
||||
@@ -187,10 +248,10 @@ header {
|
||||
line-height: rem-calc(30);
|
||||
padding: rem-calc(3) rem-calc(6);
|
||||
position: relative;
|
||||
//when active => color: $votes-like;
|
||||
|
||||
&:hover {
|
||||
background: $votes-like;
|
||||
border-color: white;
|
||||
color: white;
|
||||
cursor: pointer;
|
||||
}
|
||||
@@ -202,7 +263,7 @@ header {
|
||||
|
||||
.icon-unlike {
|
||||
background: white;
|
||||
border: 2px solid white;
|
||||
border: 2px solid $votes-border;
|
||||
border-radius: rem-calc(3);
|
||||
color: $votes-neutral;
|
||||
display: inline-block;
|
||||
@@ -210,10 +271,10 @@ header {
|
||||
line-height: rem-calc(30);
|
||||
padding: rem-calc(3) rem-calc(6);
|
||||
position: relative;
|
||||
//when active => color: $votes-unlike;
|
||||
|
||||
&:hover {
|
||||
background: $votes-unlike;
|
||||
border-color: white;
|
||||
color: white;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
@@ -26,7 +26,8 @@ $comments-info: #A5B2B9;
|
||||
$comments-text: #3F4549;
|
||||
|
||||
$header-color: #292B33;
|
||||
$link: #0077B9;
|
||||
$link: #2895F1;
|
||||
$link-hover: #2178BF;
|
||||
|
||||
$tags-bg: #FAFAFA;
|
||||
$tags-border: #F0F0F0;
|
||||
@@ -37,8 +38,8 @@ $text-medium: #999999;
|
||||
$text-light: #A3A6AD;
|
||||
|
||||
$votes: #31708f;
|
||||
$votes-background: #0081B3;
|
||||
$votes-border: #005b80;
|
||||
$votes-background: #26AEEE;//#0081B3;
|
||||
$votes-border: #1F94CB;//#005b80;
|
||||
$votes-like: #7BD2A8;
|
||||
$votes-like-act: #5D9E7F;
|
||||
$votes-neutral: #CCCCCC;
|
||||
|
||||
@@ -17,7 +17,7 @@ class AccountController < ApplicationController
|
||||
end
|
||||
|
||||
def account_params
|
||||
params.require(:account).permit(:first_name, :last_name, :nickname, :use_nickname)
|
||||
params.require(:account).permit(:first_name, :last_name, :nickname, :use_nickname, :email_on_debate_comment, :email_on_comment_reply)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
@@ -7,6 +7,10 @@ class CommentsController < ApplicationController
|
||||
@comment = Comment.build(@debate, current_user, params[:comment][:body])
|
||||
@comment.save!
|
||||
@comment.move_to_child_of(@parent) if reply?
|
||||
|
||||
Mailer.comment(@comment).deliver_now if email_on_debate_comment?
|
||||
Mailer.reply(@comment).deliver_now if email_on_comment_reply?
|
||||
|
||||
respond_with @comment
|
||||
end
|
||||
|
||||
@@ -32,4 +36,12 @@ class CommentsController < ApplicationController
|
||||
def reply?
|
||||
@parent.class == Comment
|
||||
end
|
||||
|
||||
def email_on_debate_comment?
|
||||
@comment.debate.author.email_on_debate_comment?
|
||||
end
|
||||
|
||||
def email_on_comment_reply?
|
||||
reply? && @parent.author.email_on_comment_reply?
|
||||
end
|
||||
end
|
||||
4
app/mailers/application_mailer.rb
Normal file
4
app/mailers/application_mailer.rb
Normal file
@@ -0,0 +1,4 @@
|
||||
class ApplicationMailer < ActionMailer::Base
|
||||
default from: "participacion@madrid.es"
|
||||
layout 'mailer'
|
||||
end
|
||||
16
app/mailers/mailer.rb
Normal file
16
app/mailers/mailer.rb
Normal file
@@ -0,0 +1,16 @@
|
||||
class Mailer < ApplicationMailer
|
||||
|
||||
def comment(comment)
|
||||
@comment = comment
|
||||
@debate = comment.debate
|
||||
mail(to: @debate.author.email, subject: t('mailer.comment.subject'))
|
||||
end
|
||||
|
||||
def reply(reply)
|
||||
@reply = reply
|
||||
@debate = @reply.debate
|
||||
parent = Comment.find(@reply.parent_id)
|
||||
mail(to: parent.author.email, subject: t('mailer.reply.subject'))
|
||||
end
|
||||
|
||||
end
|
||||
@@ -17,4 +17,13 @@ class Comment < ActiveRecord::Base
|
||||
def self.find_parent(params)
|
||||
params[:commentable_type].constantize.find(params[:commentable_id])
|
||||
end
|
||||
|
||||
def debate
|
||||
commentable if commentable.class == Debate
|
||||
end
|
||||
|
||||
def author
|
||||
user
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
@@ -15,6 +15,16 @@
|
||||
<%= f.label :nickname, t("account.show.nickname_label") %>
|
||||
<%= f.text_field :nickname %>
|
||||
|
||||
<div>
|
||||
<%= f.check_box :email_on_debate_comment %>
|
||||
<%= f.label :email_on_debate_comment, t("account.show.email_on_debate_comment_label") %>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<%= f.check_box :email_on_comment_reply %>
|
||||
<%= f.label :email_on_comment_reply, t("account.show.email_on_comment_reply_label") %>
|
||||
</div>
|
||||
|
||||
<%= f.submit t("account.show.save_changes_submit"), class: "button radius" %>
|
||||
<% end %>
|
||||
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
<ul class="right">
|
||||
<% if user_signed_in? %>
|
||||
<li>
|
||||
<%= link_to(t("layouts.header.my_account_link"), account_path) %>
|
||||
</li>
|
||||
<li>
|
||||
<%= link_to(t("devise_views.menu.login_items.logout"), destroy_user_session_path, method: :delete) %>
|
||||
</li>
|
||||
@@ -7,8 +10,8 @@
|
||||
<li>
|
||||
<%= link_to(t("devise_views.menu.login_items.login"), new_user_session_path) %>
|
||||
</li>
|
||||
<li class="active">
|
||||
<%= link_to(t("devise_views.menu.login_items.signup"), new_user_registration_path) %>
|
||||
<li>
|
||||
<%= link_to(t("devise_views.menu.login_items.signup"), new_user_registration_path, class: "button radius small") %>
|
||||
</li>
|
||||
<% end %>
|
||||
</ul>
|
||||
@@ -1,23 +1,24 @@
|
||||
<header class="<%= header_css %>">
|
||||
<section class="top-links">
|
||||
<div class="row">
|
||||
<div class="small-12 column">
|
||||
<div class="right">
|
||||
<a href="#"><%= t("layouts.header.external_link_transparency") %></a> | <a href="#"><%= t("layouts.header.external_link_opendata") %></a>
|
||||
|
|
||||
<div class="language">
|
||||
<span id="locale-switcher">
|
||||
<%= t("layouts.header.language") %>
|
||||
[
|
||||
<% available_locales_to_switch.each do |locale| %>
|
||||
<%= link_to(locale, params.merge(locale: locale), id: "locale-link-#{locale}") %>
|
||||
<% end %>
|
||||
]
|
||||
</span>
|
||||
</div>
|
||||
<div class="external-links">
|
||||
<%= link_to t("layouts.header.participation"), root_path, class: "selected" %> |
|
||||
<a href="#"><%= t("layouts.header.external_link_transparency") %></a> |
|
||||
<a href="#"><%= t("layouts.header.external_link_opendata") %></a>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<div class="contain-to-grid">
|
||||
<div class="contain-to-grid clear">
|
||||
<nav class="top-bar" data-topbar role="navigation">
|
||||
<ul class="title-area">
|
||||
<li class="name">
|
||||
@@ -31,18 +32,12 @@
|
||||
|
||||
<section class="top-bar-section">
|
||||
<%= render 'devise/menu/login_items' %>
|
||||
|
||||
<% if user_signed_in? %>
|
||||
<ul class="right">
|
||||
<li><%= link_to(t("layouts.header.my_account_link"), account_path) %></li>
|
||||
</ul>
|
||||
<% end %>
|
||||
</section>
|
||||
</nav>
|
||||
</div>
|
||||
|
||||
<% if home_page? %>
|
||||
<div class="row">
|
||||
<div class="row home-page">
|
||||
<div class="small-12 column text-center">
|
||||
<h1><%= t("layouts.header.open_city") %></h1>
|
||||
<h2><%= t("layouts.header.open_city_slogan") %></h2>
|
||||
|
||||
5
app/views/layouts/mailer.html.erb
Normal file
5
app/views/layouts/mailer.html.erb
Normal file
@@ -0,0 +1,5 @@
|
||||
<html>
|
||||
<body>
|
||||
<%= yield %>
|
||||
</body>
|
||||
</html>
|
||||
7
app/views/mailer/comment.html.erb
Normal file
7
app/views/mailer/comment.html.erb
Normal file
@@ -0,0 +1,7 @@
|
||||
Hello,
|
||||
|
||||
<div><%= @comment.author.name %></div>
|
||||
|
||||
<div><%= @comment.body %></div>
|
||||
|
||||
<div><%= link_to @debate.title, debate_url(@debate) %></div>
|
||||
7
app/views/mailer/reply.html.erb
Normal file
7
app/views/mailer/reply.html.erb
Normal file
@@ -0,0 +1,7 @@
|
||||
Hello,
|
||||
|
||||
<div><%= @reply.author.name %></div>
|
||||
|
||||
<div><%= @reply.body %></div>
|
||||
|
||||
<div><%= link_to @debate.title, debate_url(@debate) %></div>
|
||||
18
config/deploy-secrets.yml.example
Normal file
18
config/deploy-secrets.yml.example
Normal file
@@ -0,0 +1,18 @@
|
||||
staging:
|
||||
deploy_to: "/var/www/participacion"
|
||||
ssh_port: 21
|
||||
server: staging.participacion.madrid.es
|
||||
user: xxxxx
|
||||
|
||||
preproduction:
|
||||
deploy_to: "/var/www/participacion"
|
||||
ssh_port: 2222
|
||||
server: xxx.xxx.xxx.xxx
|
||||
user: xxxxx
|
||||
|
||||
production:
|
||||
deploy_to: "/var/www/participacion"
|
||||
ssh_port: 2222
|
||||
server: xxx.xxx.xxx.xxx
|
||||
user: xxxxx
|
||||
|
||||
38
config/deploy.rb
Normal file
38
config/deploy.rb
Normal file
@@ -0,0 +1,38 @@
|
||||
# config valid only for current version of Capistrano
|
||||
lock '3.4.0'
|
||||
|
||||
def deploysecret(key)
|
||||
@deploy_secrets_yml ||= YAML.load_file('config/deploy-secrets.yml')[fetch(:stage).to_s]
|
||||
@deploy_secrets_yml[key.to_s]
|
||||
end
|
||||
|
||||
set :rails_env, fetch(:stage)
|
||||
set :rvm_ruby_version, '2.2.2'
|
||||
|
||||
set :application, 'participacion'
|
||||
set :repo_url, 'git@github.com:AyuntamientoMadrid/participacion.git'
|
||||
|
||||
set :scm, :git
|
||||
set :revision, `git rev-parse --short #{fetch(:branch)}`.strip
|
||||
|
||||
set :log_level, :info
|
||||
|
||||
set :linked_files, %w{config/database.yml config/secrets.yml}
|
||||
set :linked_dirs, %w{log tmp public/system public/assets}
|
||||
|
||||
set :keep_releases, 5
|
||||
|
||||
set :local_user, ENV['USER']
|
||||
|
||||
namespace :deploy do
|
||||
|
||||
after :restart, :clear_cache do
|
||||
on roles(:web), in: :groups, limit: 3, wait: 10 do
|
||||
# Here we can do anything such as:
|
||||
# within release_path do
|
||||
# execute :rake, 'cache:clear'
|
||||
# end
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
5
config/deploy/preproduction.rb
Normal file
5
config/deploy/preproduction.rb
Normal file
@@ -0,0 +1,5 @@
|
||||
set :deploy_to, deploysecret(:deploy_to)
|
||||
set :branch, :production
|
||||
set :ssh_options, port: deploysecret(:ssh_port)
|
||||
|
||||
server deploysecret(:server), user: deploysecret(:user), roles: %w(web app db importer)
|
||||
5
config/deploy/production.rb
Normal file
5
config/deploy/production.rb
Normal file
@@ -0,0 +1,5 @@
|
||||
set :deploy_to, deploysecret(:deploy_to)
|
||||
set :branch, :production
|
||||
set :ssh_options, port: deploysecret(:ssh_port)
|
||||
|
||||
server deploysecret(:server), user: deploysecret(:user), roles: %w(web app db importer)
|
||||
7
config/deploy/staging.rb
Normal file
7
config/deploy/staging.rb
Normal file
@@ -0,0 +1,7 @@
|
||||
set :deploy_to, deploysecret(:deploy_to)
|
||||
set :branch, :master
|
||||
set :ssh_options, port: deploysecret(:ssh_port)
|
||||
|
||||
set :passenger_restart_with_sudo, false
|
||||
|
||||
server deploysecret(:server), user: deploysecret(:user), roles: %w(web app db importer)
|
||||
@@ -11,6 +11,7 @@ en:
|
||||
open_city_slogan: So the citizens can decide what kind of city they want.
|
||||
create_debate: Create a debate
|
||||
my_account_link: My account
|
||||
language: Site language
|
||||
admin:
|
||||
dashboard:
|
||||
index:
|
||||
@@ -70,6 +71,8 @@ en:
|
||||
show:
|
||||
title: "My account"
|
||||
save_changes_submit: "Save changes"
|
||||
email_on_debate_comment_label: "Receive email when someone comments on my debates"
|
||||
email_on_comment_reply_label: "Receive email when someone replies to my comments"
|
||||
change_credentials_link: "Change my credentials"
|
||||
first_name_label: "First Name"
|
||||
last_name_label: "Last Name"
|
||||
@@ -81,3 +84,8 @@ en:
|
||||
shared:
|
||||
tags_cloud:
|
||||
tags: Tags
|
||||
mailer:
|
||||
comment:
|
||||
subject: Someone has commented on your debate
|
||||
reply:
|
||||
subject: Someone has replied to your comment
|
||||
|
||||
@@ -11,6 +11,7 @@ es:
|
||||
open_city_slogan: Para que todos los madrileños decidamos que ciudad queremos tener.
|
||||
create_debate: Crea un debate
|
||||
my_account_link: Mi cuenta
|
||||
language: Idioma de la página
|
||||
admin:
|
||||
dashboard:
|
||||
index:
|
||||
@@ -70,6 +71,8 @@ es:
|
||||
show:
|
||||
title: "Mi cuenta"
|
||||
save_changes_submit: "Guardar cambios"
|
||||
email_on_debate_comment_label: "Recibir un email cuando alguien commenta en mis debates"
|
||||
email_on_comment_reply_label: "Recibir un email cuando alguien contesta a mis comentarios"
|
||||
change_credentials_link: "Cambiar mi contraseña"
|
||||
first_name_label: "Nombre"
|
||||
last_name_label: "Apellidos"
|
||||
@@ -81,4 +84,8 @@ es:
|
||||
shared:
|
||||
tags_cloud:
|
||||
tags: Etiquetas
|
||||
|
||||
mailer:
|
||||
comment:
|
||||
subject: Alguien ha comentado en tu debate
|
||||
reply:
|
||||
subject: Alguien ha respondido a tu comentario
|
||||
|
||||
6
db/migrate/20150806163142_add_preferences_to_users.rb
Normal file
6
db/migrate/20150806163142_add_preferences_to_users.rb
Normal file
@@ -0,0 +1,6 @@
|
||||
class AddPreferencesToUsers < ActiveRecord::Migration
|
||||
def change
|
||||
add_column :users, :email_on_debate_comment, :boolean, default: false
|
||||
add_column :users, :email_on_comment_reply, :boolean, default: false
|
||||
end
|
||||
end
|
||||
@@ -94,6 +94,8 @@ ActiveRecord::Schema.define(version: 20150807140346) do
|
||||
t.string "unconfirmed_email"
|
||||
t.string "nickname"
|
||||
t.boolean "use_nickname", default: false, null: false
|
||||
t.boolean "email_on_debate_comment", default: false
|
||||
t.boolean "email_on_comment_reply", default: false
|
||||
end
|
||||
|
||||
add_index "users", ["confirmation_token"], name: "index_users_on_confirmation_token", unique: true, using: :btree
|
||||
|
||||
@@ -21,6 +21,8 @@ feature 'Account' do
|
||||
|
||||
fill_in 'account_first_name', with: 'Larry'
|
||||
fill_in 'account_last_name', with: 'Bird'
|
||||
check 'account_email_on_debate_comment'
|
||||
check 'account_email_on_comment_reply'
|
||||
click_button 'Save changes'
|
||||
|
||||
expect(page).to have_content "Saved"
|
||||
@@ -29,5 +31,7 @@ feature 'Account' do
|
||||
|
||||
expect(page).to have_selector("input[value='Larry']")
|
||||
expect(page).to have_selector("input[value='Bird']")
|
||||
expect(page).to have_selector("input[id='account_email_on_debate_comment'][value='1']")
|
||||
expect(page).to have_selector("input[id='account_email_on_comment_reply'][value='1']")
|
||||
end
|
||||
end
|
||||
@@ -41,11 +41,11 @@ feature 'Comments' do
|
||||
login_as(user)
|
||||
visit debate_path(debate)
|
||||
|
||||
fill_in 'comment_body', with: '¿Has pensado en esto...?'
|
||||
fill_in 'comment_body', with: 'Have you thought about...?'
|
||||
click_button 'Publish comment'
|
||||
|
||||
within "#comments" do
|
||||
expect(page).to have_content '¿Has pensado en esto...?'
|
||||
expect(page).to have_content 'Have you thought about...?'
|
||||
end
|
||||
end
|
||||
|
||||
@@ -60,12 +60,12 @@ feature 'Comments' do
|
||||
|
||||
click_link "Reply"
|
||||
within "#js-comment-form-comment_#{comment.id}" do
|
||||
fill_in 'comment_body', with: 'La semana que viene está hecho.'
|
||||
fill_in 'comment_body', with: 'It will be done next week.'
|
||||
click_button 'Publish reply'
|
||||
end
|
||||
|
||||
within "#comment-#{comment.id}" do
|
||||
expect(page).to have_content 'La semana que viene está hecho.'
|
||||
expect(page).to have_content 'It will be done next week.'
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
63
spec/features/emails_spec.rb
Normal file
63
spec/features/emails_spec.rb
Normal file
@@ -0,0 +1,63 @@
|
||||
require 'rails_helper'
|
||||
|
||||
feature 'Emails' do
|
||||
|
||||
background do
|
||||
reset_mailer
|
||||
end
|
||||
|
||||
scenario "Signup Email" do
|
||||
sign_up
|
||||
|
||||
email = open_last_email
|
||||
expect(email).to have_subject('Confirmation instructions')
|
||||
expect(email).to deliver_to('manuela@madrid.es')
|
||||
expect(email).to have_body_text(user_confirmation_path)
|
||||
end
|
||||
|
||||
scenario "Reset password" do
|
||||
reset_password
|
||||
|
||||
email = open_last_email
|
||||
expect(email).to have_subject('Reset password instructions')
|
||||
expect(email).to deliver_to('manuela@madrid.es')
|
||||
expect(email).to have_body_text(edit_user_password_path)
|
||||
end
|
||||
|
||||
scenario "Debate comment", :js do
|
||||
user = create(:user, email_on_debate_comment: true)
|
||||
debate = create(:debate, author: user)
|
||||
comment_on(debate)
|
||||
|
||||
email = open_last_email
|
||||
expect(email).to have_subject('Someone has commented on your debate')
|
||||
expect(email).to deliver_to(debate.author)
|
||||
expect(email).to have_body_text(debate_path(debate))
|
||||
end
|
||||
|
||||
scenario "Comment reply", :js do
|
||||
user = create(:user, email_on_comment_reply: true)
|
||||
reply_to(user)
|
||||
|
||||
email = open_last_email
|
||||
expect(email).to have_subject('Someone has replied to your comment')
|
||||
expect(email).to deliver_to(user)
|
||||
expect(email).to have_body_text(debate_path(Comment.first.debate))
|
||||
end
|
||||
|
||||
scenario 'Do not send email about debate comment unless set in preferences', :js do
|
||||
user = create(:user, email_on_debate_comment: false)
|
||||
debate = create(:debate, author: user)
|
||||
comment_on(debate)
|
||||
|
||||
expect { open_last_email }.to raise_error "No email has been sent!"
|
||||
end
|
||||
|
||||
scenario "Do not send email about comment reply unless set in preferences", :js do
|
||||
user = create(:user, email_on_comment_reply: false)
|
||||
reply_to(user)
|
||||
|
||||
expect { open_last_email }.to raise_error "No email has been sent!"
|
||||
end
|
||||
|
||||
end
|
||||
@@ -44,4 +44,26 @@ feature 'Users' do
|
||||
expect(page).to have_content 'Signed out successfully.'
|
||||
end
|
||||
|
||||
scenario 'Reset password' do
|
||||
create(:user, email: 'manuela@madrid.es')
|
||||
|
||||
visit '/'
|
||||
click_link 'Log in'
|
||||
click_link 'Forgot your password?'
|
||||
|
||||
fill_in 'user_email', with: 'manuela@madrid.es'
|
||||
click_button 'Send me reset password instructions'
|
||||
|
||||
expect(page).to have_content "You will receive an email with instructions on how to reset your password in a few minutes."
|
||||
|
||||
sent_token = /.*reset_password_token=(.*)".*/.match(ActionMailer::Base.deliveries.last.body.to_s)[1]
|
||||
visit edit_user_password_path(reset_password_token: sent_token)
|
||||
|
||||
fill_in 'user_password', with: 'new password'
|
||||
fill_in 'user_password_confirmation', with: 'new password'
|
||||
click_button 'Change my password'
|
||||
|
||||
expect(page).to have_content "Your password has been changed successfully. You are now signed in."
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
@@ -34,6 +34,20 @@ describe User do
|
||||
expect(subject).to be_valid
|
||||
end
|
||||
|
||||
describe 'preferences' do
|
||||
describe 'email_on_debate_comment' do
|
||||
it 'should be false by default' do
|
||||
expect(subject.email_on_debate_comment).to eq(false)
|
||||
end
|
||||
end
|
||||
|
||||
describe 'email_on_comment_reply' do
|
||||
it 'should be false by default' do
|
||||
expect(subject.email_on_comment_reply).to eq(false)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe 'use_nickname' do
|
||||
describe 'when true' do
|
||||
before { subject.use_nickname = true }
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
require 'factory_girl_rails'
|
||||
require 'database_cleaner'
|
||||
require "email_spec"
|
||||
Dir["./spec/support/**/*.rb"].sort.each { |f| require f}
|
||||
|
||||
RSpec.configure do |config|
|
||||
config.use_transactional_fixtures = false
|
||||
@@ -7,7 +9,9 @@ RSpec.configure do |config|
|
||||
config.filter_run :focus
|
||||
config.run_all_when_everything_filtered = true
|
||||
config.include FactoryGirl::Syntax::Methods
|
||||
|
||||
config.include(EmailSpec::Helpers)
|
||||
config.include(EmailSpec::Matchers)
|
||||
config.include(CommonActions)
|
||||
config.before(:suite) do
|
||||
DatabaseCleaner.clean_with :truncation
|
||||
end
|
||||
|
||||
54
spec/support/common_actions.rb
Normal file
54
spec/support/common_actions.rb
Normal file
@@ -0,0 +1,54 @@
|
||||
module CommonActions
|
||||
|
||||
def sign_up
|
||||
visit '/'
|
||||
click_link 'Sign up'
|
||||
|
||||
fill_in 'user_first_name', with: 'Manuela'
|
||||
fill_in 'user_last_name', with: 'Carmena'
|
||||
fill_in 'user_email', with: 'manuela@madrid.es'
|
||||
fill_in 'user_password', with: 'judgementday'
|
||||
fill_in 'user_password_confirmation', with: 'judgementday'
|
||||
|
||||
click_button 'Sign up'
|
||||
end
|
||||
|
||||
def reset_password
|
||||
create(:user, email: 'manuela@madrid.es')
|
||||
|
||||
visit '/'
|
||||
click_link 'Log in'
|
||||
click_link 'Forgot your password?'
|
||||
|
||||
fill_in 'user_email', with: 'manuela@madrid.es'
|
||||
click_button 'Send me reset password instructions'
|
||||
end
|
||||
|
||||
def comment_on(debate)
|
||||
user2 = create(:user)
|
||||
|
||||
login_as(user2)
|
||||
visit debate_path(debate)
|
||||
|
||||
fill_in 'comment_body', with: 'Have you thought about...?'
|
||||
click_button 'Publish comment'
|
||||
expect(page).to have_content 'Have you thought about...?'
|
||||
end
|
||||
|
||||
def reply_to(user)
|
||||
manuela = create(:user)
|
||||
debate = create(:debate)
|
||||
comment = create(:comment, commentable: debate, user: user)
|
||||
|
||||
login_as(manuela)
|
||||
visit debate_path(debate)
|
||||
|
||||
click_link "Reply"
|
||||
within "#js-comment-form-comment_#{comment.id}" do
|
||||
fill_in 'comment_body', with: 'It will be done next week.'
|
||||
click_button 'Publish reply'
|
||||
end
|
||||
expect(page).to have_content 'It will be done next week.'
|
||||
end
|
||||
|
||||
end
|
||||
Reference in New Issue
Block a user