diff --git a/Gemfile b/Gemfile
index e381bc516..21929a806 100644
--- a/Gemfile
+++ b/Gemfile
@@ -40,6 +40,7 @@ gem 'social-share-button'
gem 'initialjs-rails', '0.2.0'
gem 'unicorn'
gem 'paranoia'
+gem 'savon'
gem 'ahoy_matey', '~> 1.2.1'
gem 'groupdate' # group temporary data
diff --git a/Gemfile.lock b/Gemfile.lock
index cd2ae196d..60af34f06 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -54,6 +54,9 @@ GEM
request_store
user_agent_parser
uuidtools
+ akami (1.3.1)
+ gyoku (>= 0.4.0)
+ nokogiri
arel (6.0.3)
awesome_nested_set (3.0.2)
activerecord (>= 4.0.0, < 5)
@@ -155,10 +158,14 @@ GEM
activesupport (>= 4.1.0)
groupdate (2.4.0)
activesupport (>= 3)
+ gyoku (1.3.1)
+ builder (>= 2.1.2)
hashie (3.4.2)
highline (1.7.3)
http-cookie (1.0.2)
domain_name (~> 0.5)
+ httpi (2.4.1)
+ rack
i18n (0.7.0)
i18n-tasks (0.8.7)
activesupport (>= 2.3.18)
@@ -204,6 +211,7 @@ GEM
netrc (0.10.3)
nokogiri (1.6.6.2)
mini_portile (~> 0.6.0)
+ nori (2.6.0)
oauth (0.4.7)
oauth2 (1.0.0)
faraday (>= 0.8, < 0.10)
@@ -305,6 +313,14 @@ GEM
sprockets (>= 2.8, < 4.0)
sprockets-rails (>= 2.0, < 4.0)
tilt (~> 1.1)
+ savon (2.11.1)
+ akami (~> 1.2)
+ builder (>= 2.1.2)
+ gyoku (~> 1.2)
+ httpi (~> 2.3)
+ nokogiri (>= 1.4.0)
+ nori (~> 2.4)
+ wasabi (~> 3.4)
simple_captcha2 (0.3.4)
rails (>= 4.1)
simplecov (0.10.0)
@@ -353,6 +369,9 @@ GEM
uuidtools (2.1.5)
warden (1.2.3)
rack (>= 1.0)
+ wasabi (3.5.0)
+ httpi (~> 2.0)
+ nokogiri (>= 1.4.2)
web-console (2.2.1)
activemodel (>= 4.0)
binding_of_caller (>= 0.7.2)
@@ -409,6 +428,7 @@ DEPENDENCIES
responders
rspec-rails (~> 3.0)
sass-rails (~> 5.0)
+ savon
simple_captcha2
social-share-button
spring
diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb
index 802dda3bc..4b9e75c56 100644
--- a/app/controllers/application_controller.rb
+++ b/app/controllers/application_controller.rb
@@ -51,4 +51,10 @@ class ApplicationController < ActionController::Base
redirect_to finish_signup_path
end
end
+
+ def verify_resident!
+ unless current_user.residence_verified?
+ redirect_to new_residence_path, alert: t('verification.residence.alert.unconfirmed_residency')
+ end
+ end
end
diff --git a/app/controllers/verification/email_controller.rb b/app/controllers/verification/email_controller.rb
new file mode 100644
index 000000000..ebcbf68ab
--- /dev/null
+++ b/app/controllers/verification/email_controller.rb
@@ -0,0 +1,31 @@
+class Verification::EmailController < ApplicationController
+ before_action :authenticate_user!
+ before_action :set_verified_user
+ skip_authorization_check
+
+ def show
+ if Email.find(current_user, params[:email_verification_token])
+ current_user.update(verified_at: Time.now)
+ redirect_to account_path, notice: t('verification.email.show.flash.success')
+ else
+ redirect_to verified_user_path, alert: t('verification.email.show.alert.failure')
+ end
+ end
+
+ def create
+ @email = Email.new(@verified_user)
+ if @email.save
+ current_user.reload
+ Mailer.email_verification(current_user, @email.recipient, @email.encrypted_token).deliver_now
+ redirect_to account_path, notice: t('verification.email.create.flash.success', email: @verified_user.email)
+ else
+ redirect_to verified_user_path, alert: t('verification.email.create.alert.failure')
+ end
+ end
+
+ private
+
+ def set_verified_user
+ @verified_user = VerifiedUser.by_user(current_user).by_email(params[:recipient]).first
+ end
+end
\ No newline at end of file
diff --git a/app/controllers/verification/letter_controller.rb b/app/controllers/verification/letter_controller.rb
new file mode 100644
index 000000000..eb91ebe6f
--- /dev/null
+++ b/app/controllers/verification/letter_controller.rb
@@ -0,0 +1,32 @@
+class Verification::LetterController < ApplicationController
+ before_action :authenticate_user!
+ before_action :verify_resident!
+ before_action :verify_phone_or_email!
+ skip_authorization_check
+
+ def new
+ @letter = Letter.new(user: current_user)
+ end
+
+ def create
+ @letter = Letter.new(user: current_user)
+ if @letter.save
+ redirect_to account_path, notice: t('verification.letter.create.flash.success')
+ else
+ flash.now.alert = t('verification.letter.create.alert.failure')
+ render :new
+ end
+ end
+
+ private
+
+ def letter_params
+ params.require(:letter).permit()
+ end
+
+ def verify_phone_or_email!
+ unless current_user.confirmed_phone?
+ redirect_to verified_user_path, alert: t('verification.letter.alert.unconfirmed_personal_data')
+ end
+ end
+end
\ No newline at end of file
diff --git a/app/controllers/verification/residence_controller.rb b/app/controllers/verification/residence_controller.rb
new file mode 100644
index 000000000..107e0a1e0
--- /dev/null
+++ b/app/controllers/verification/residence_controller.rb
@@ -0,0 +1,31 @@
+class Verification::ResidenceController < ApplicationController
+ before_action :authenticate_user!
+ before_action :verify_attemps_left!, only: [:new, :create]
+ skip_authorization_check
+
+ def new
+ @residence = Residence.new
+ end
+
+ def create
+ @residence = Residence.new(residence_params.merge(user: current_user))
+ if @residence.save
+ redirect_to verified_user_path, notice: t('verification.residence.create.flash.success')
+ else
+ current_user.update(residence_verification_tries: current_user.residence_verification_tries += 1)
+ render :new
+ end
+ end
+
+ private
+
+ def residence_params
+ params.require(:residence).permit(:document_number, :document_type, :date_of_birth, :postal_code)
+ end
+
+ def verify_attemps_left!
+ if current_user.residence_verification_tries >= 5
+ redirect_to account_path, alert: t('verification.residence.alert.verify_attemps_left')
+ end
+ end
+end
\ No newline at end of file
diff --git a/app/controllers/verification/sms_controller.rb b/app/controllers/verification/sms_controller.rb
new file mode 100644
index 000000000..e0080753e
--- /dev/null
+++ b/app/controllers/verification/sms_controller.rb
@@ -0,0 +1,62 @@
+class Verification::SmsController < ApplicationController
+ before_action :authenticate_user!
+ before_action :verify_resident!
+ before_action :verify_attemps_left!, only: [:new, :create]
+
+ skip_authorization_check
+
+ def new
+ @sms = Sms.new(phone: params[:phone])
+ end
+
+ def create
+ @sms = Sms.new(sms_params.merge(user: current_user))
+ if @sms.save
+ redirect_to edit_sms_path, notice: t('verification.sms.create.flash.success')
+ else
+ render :new
+ end
+ end
+
+ def edit
+ @sms = Sms.new
+ end
+
+ def update
+ @sms = Sms.new(sms_params.merge(user: current_user))
+ if @sms.verify?
+ current_user.update(confirmed_phone: current_user.unconfirmed_phone)
+
+ if VerifiedUser.phone?(current_user)
+ current_user.update(verified_at: Time.now)
+ end
+
+ redirect_to_next_path
+ else
+ @error = t('verification.sms.update.error')
+ render :edit
+ end
+ end
+
+ private
+
+ def sms_params
+ params.require(:sms).permit(:phone, :confirmation_code)
+ end
+
+ def redirect_to_next_path
+ current_user.reload
+ if current_user.level_three_verified?
+ redirect_to account_path, notice: t('verification.sms.update.flash.level_three.success')
+ else
+ redirect_to new_letter_path, notice: t('verification.sms.update.flash.level_two.success')
+ end
+ end
+
+ def verify_attemps_left!
+ if current_user.sms_confirmation_tries >= 3
+ redirect_to account_path, notice: t('verification.sms.alert.verify_attemps_left')
+ end
+ end
+
+end
\ No newline at end of file
diff --git a/app/controllers/verification/verified_user_controller.rb b/app/controllers/verification/verified_user_controller.rb
new file mode 100644
index 000000000..bf2bc65fb
--- /dev/null
+++ b/app/controllers/verification/verified_user_controller.rb
@@ -0,0 +1,9 @@
+class Verification::VerifiedUserController < ApplicationController
+ before_action :authenticate_user!
+ skip_authorization_check
+
+ def show
+ @verified_users = VerifiedUser.by_user(current_user)
+ redirect_to new_sms_path if @verified_users.blank?
+ end
+end
\ No newline at end of file
diff --git a/app/helpers/verification_helper.rb b/app/helpers/verification_helper.rb
new file mode 100644
index 000000000..a7615801e
--- /dev/null
+++ b/app/helpers/verification_helper.rb
@@ -0,0 +1,9 @@
+module VerificationHelper
+
+ def document_types
+ [[t('verification.residence.new.document_type.spanish_id'), 1],
+ [t('verification.residence.new.document_type.passport'), 2],
+ [t('verification.residence.new.document_type.residence_card'), 3]]
+ end
+
+end
\ No newline at end of file
diff --git a/app/mailers/mailer.rb b/app/mailers/mailer.rb
index 04160022e..a3db690a8 100644
--- a/app/mailers/mailer.rb
+++ b/app/mailers/mailer.rb
@@ -14,4 +14,11 @@ class Mailer < ApplicationMailer
mail(to: @recipient.email, subject: t('mailer.reply.subject'))
end
+ def email_verification(user, recipient, token)
+ @user = user
+ @recipient = recipient
+ @token = token
+ mail(to: @recipient, subject: "Verifica tu email")
+ end
+
end
diff --git a/app/models/address.rb b/app/models/address.rb
new file mode 100644
index 000000000..2c0c20b88
--- /dev/null
+++ b/app/models/address.rb
@@ -0,0 +1,3 @@
+class Address < ActiveRecord::Base
+ belongs_to :user
+end
diff --git a/app/models/email.rb b/app/models/email.rb
new file mode 100644
index 000000000..e5e15c49f
--- /dev/null
+++ b/app/models/email.rb
@@ -0,0 +1,34 @@
+class Email
+ include ActiveModel::Model
+
+ attr_accessor :verified_user, :recipient, :plain_token, :encrypted_token
+
+ validates :verified_user, presence: true
+ validates :recipient, presence: true
+
+ def initialize(verified_user)
+ @verified_user = verified_user
+ @recipient = @verified_user.try(:email)
+ end
+
+ def save
+ return false unless valid?
+
+ generate_token
+ user = User.where(document_number: verified_user.document_number).first
+ user.update(email_verification_token: @plain_token)
+ end
+
+ def generate_token
+ @plain_token, @encrypted_token = Devise.token_generator.generate(User, :email_verification_token)
+ end
+
+ def self.find(user, token)
+ self.valid_token?(user, token)
+ end
+
+ def self.valid_token?(user, token)
+ Devise.token_generator.digest(User, :email_verification_token, user.email_verification_token) == token
+ end
+
+end
diff --git a/app/models/letter.rb b/app/models/letter.rb
new file mode 100644
index 000000000..58e326d58
--- /dev/null
+++ b/app/models/letter.rb
@@ -0,0 +1,53 @@
+class Letter
+ include ActiveModel::Model
+
+ attr_accessor :user, :address
+
+ validates :user, presence: true
+ validates :address, presence: true
+ validate :correct_address
+
+ def initialize(attrs={})
+ @user = attrs[:user]
+ end
+
+ def save
+ valid? &&
+ letter_requested! &&
+ update_user_address
+ end
+
+ def address
+ @address ||= UserApi.new(user).address
+ end
+
+ def letter_requested!
+ user.update(letter_requested_at: Time.now)
+ end
+
+ def update_user_address
+ user.address = Address.new(parsed_address)
+ user.save
+ end
+
+ def correct_address
+ errors.add(:address, "Address not found") unless address.present?
+ end
+
+ def parsed_address
+ { postal_code: address[:codigo_postal],
+ street: address[:nombre_via],
+ street_type: address[:sigla_via],
+ number: address[:numero_via],
+ number_type: address[:nominal_via],
+ letter: address[:letra_via],
+ portal: address[:portal],
+ stairway: address[:escalera],
+ floor: address[:planta],
+ door: address[:puerta],
+ km: address[:km],
+ neighbourhood: address[:nombre_barrio],
+ district: address[:nombre_distrito] }
+ end
+
+end
\ No newline at end of file
diff --git a/app/models/organization.rb b/app/models/organization.rb
index de120de9e..20c74d31c 100644
--- a/app/models/organization.rb
+++ b/app/models/organization.rb
@@ -6,9 +6,9 @@ class Organization < ActiveRecord::Base
delegate :email, :phone_number, to: :user
- scope :pending, -> { where(verified_at: nil, rejected_at: nil) }
- scope :verified, -> { where("verified_at is not null and (rejected_at is null or rejected_at < verified_at)") }
- scope :rejected, -> { where("rejected_at is not null and (verified_at is null or verified_at < rejected_at)") }
+ scope :pending, -> { where('organizations.verified_at is null and rejected_at is null') }
+ scope :verified, -> { where("organizations.verified_at is not null and (rejected_at is null or rejected_at < organizations.verified_at)") }
+ scope :rejected, -> { where("rejected_at is not null and (organizations.verified_at is null or organizations.verified_at < rejected_at)") }
def verify
update(verified_at: Time.now)
diff --git a/app/models/residence.rb b/app/models/residence.rb
new file mode 100644
index 000000000..b9610015e
--- /dev/null
+++ b/app/models/residence.rb
@@ -0,0 +1,45 @@
+class Residence
+ include ActiveModel::Model
+ include ActiveModel::Dates
+
+ attr_accessor :user, :document_number, :document_type, :date_of_birth, :postal_code
+
+ validates_presence_of :document_number
+ validates_presence_of :document_type
+ validates_presence_of :date_of_birth
+ validates_presence_of :postal_code
+
+ validates :postal_code, length: { is: 5 }
+
+ validate :residence_in_madrid
+ validate :document_number_uniqueness
+
+ def initialize(attrs={})
+ self.date_of_birth = parse_date('date_of_birth', attrs)
+ attrs = remove_date('date_of_birth', attrs)
+ super
+ end
+
+ def save
+ return false unless valid?
+ user.update(document_number: document_number,
+ document_type: document_type,
+ residence_verified_at: Time.now)
+ end
+
+ def document_number_uniqueness
+ errors.add(:document_number, "Already in use") if User.where(document_number: document_number).any?
+ end
+
+ def residence_in_madrid
+ return if errors.any?
+
+ self.date_of_birth = date_to_string(date_of_birth)
+
+ residency = UserApi.new(self)
+ errors.add(:residence_in_madrid, false) unless residency.valid?
+
+ self.date_of_birth = string_to_date(date_of_birth)
+ end
+
+end
\ No newline at end of file
diff --git a/app/models/sms.rb b/app/models/sms.rb
new file mode 100644
index 000000000..61b06a091
--- /dev/null
+++ b/app/models/sms.rb
@@ -0,0 +1,47 @@
+class Sms
+ include ActiveModel::Model
+
+ attr_accessor :user, :phone, :confirmation_code
+
+ validates_presence_of :phone
+ validates :phone, length: { is: 9 }
+ validate :spanish_phone
+ validate :uniqness_phone
+
+ def spanish_phone
+ errors.add(:phone, :invalid) unless phone.start_with?('6', '7')
+ end
+
+ def uniqness_phone
+ errors.add(:phone, :taken) if User.where(confirmed_phone: phone).any?
+ end
+
+ def save
+ return false unless self.valid?
+ update_user_phone_information
+ send_sms
+ increase_sms_tries
+ end
+
+ def update_user_phone_information
+ user.update(unconfirmed_phone: phone, sms_confirmation_code: four_digit_code)
+ end
+
+ def send_sms
+ SMSApi.new.sms_deliver(user.unconfirmed_phone, user.sms_confirmation_code)
+ end
+
+ def increase_sms_tries
+ user.update(sms_confirmation_tries: user.sms_confirmation_tries += 1)
+ end
+
+ def verify?
+ user.sms_confirmation_code == confirmation_code
+ end
+
+ private
+
+ def four_digit_code
+ rand.to_s[2..5]
+ end
+end
\ No newline at end of file
diff --git a/app/models/user.rb b/app/models/user.rb
index 6941e6d17..d415d7fcd 100644
--- a/app/models/user.rb
+++ b/app/models/user.rb
@@ -1,4 +1,5 @@
class User < ActiveRecord::Base
+ include Verification
OMNIAUTH_EMAIL_PREFIX = 'omniauth@participacion'
OMNIAUTH_EMAIL_REGEX = /\A#{OMNIAUTH_EMAIL_PREFIX}/
@@ -11,6 +12,7 @@ class User < ActiveRecord::Base
acts_as_paranoid column: :hidden_at
include ActsAsParanoidAliases
+ has_one :address
has_one :administrator
has_one :moderator
has_one :organization
diff --git a/app/models/verified_user.rb b/app/models/verified_user.rb
new file mode 100644
index 000000000..ca32eea5c
--- /dev/null
+++ b/app/models/verified_user.rb
@@ -0,0 +1,12 @@
+# make sure document_type is being stored and queried in the correct format (Is it DNI? a number, a string?)
+class VerifiedUser < ActiveRecord::Base
+ scope :by_user, -> (user) { where(document_number: user.document_number,
+ document_type: user.document_type) }
+
+ scope :by_email, -> (email) { where(email: email) }
+ scope :by_phone, -> (phone) { where(phone: phone) }
+
+ def self.phone?(user)
+ by_user(user).by_phone(user.unconfirmed_phone).first.present?
+ end
+end
diff --git a/app/views/account/show.html.erb b/app/views/account/show.html.erb
index fa9ccdd04..ad118d118 100644
--- a/app/views/account/show.html.erb
+++ b/app/views/account/show.html.erb
@@ -2,6 +2,16 @@
<%= link_to t("account.show.change_credentials_link"), edit_user_registration_path, class: 'button radius small secondary right' %>
+
+ <% if current_user.level_three_verified? %>
+ <%= t("account.show.level_three_user") %>
+ <% elsif current_user.level_two_verified? %>
+ <%= t("account.show.level_two_user") %>
+ <% else %>
+ <%= link_to t("account.show.verify_my_account"), new_residence_path, class: 'button radius small secondary right' %>
+ <% end %>
+
+
<%= t("account.show.title") %>
<%= form_for @account, as: :account, url: account_path do |f| %>
diff --git a/app/views/layouts/_header.html.erb b/app/views/layouts/_header.html.erb
index 365b720a6..8c1c169f4 100644
--- a/app/views/layouts/_header.html.erb
+++ b/app/views/layouts/_header.html.erb
@@ -32,7 +32,7 @@
<%= link_to t("layouts.header.welcome"), root_path %>
- <%= link_to t("layouts.header.debates"), debates_path, class: ("active" if current_page?(controller: "debates")) %>
+ <%= link_to t("layouts.header.debates"), debates_path, class: ("active" if current_page?(controller: "/debates")) %>
<%= link_to t("layouts.header.initiatives"), "#" %>
diff --git a/app/views/mailer/email_verification.html.erb b/app/views/mailer/email_verification.html.erb
new file mode 100644
index 000000000..a57a5b0dc
--- /dev/null
+++ b/app/views/mailer/email_verification.html.erb
@@ -0,0 +1,15 @@
+
+
+
+ <%= t("mailers.email_verification.title") %>
+
+
+
+ <%= t("mailers.email_verification.instructions_html",
+ verification_link: link_to(
+ t('mailers.email_verification.click_here_to_verify'),
+ email_url(email_verification_token: @token))) %>
+
+
+ |
+
diff --git a/app/views/shared/_errors.html.erb b/app/views/shared/_errors.html.erb
index 4e22c3038..ae8d65147 100644
--- a/app/views/shared/_errors.html.erb
+++ b/app/views/shared/_errors.html.erb
@@ -3,7 +3,13 @@
<%= pluralize resource.errors.count, t("form.error"), t("form.errors") %>
- <%= t("form.not_saved", resource: t("form.#{resource.class.to_s.downcase}")) %>
+
+ <% if local_assigns[:message].present? %>
+ <%= message %>
+ <% else %>
+ <%= t("form.not_saved", resource: t("form.#{resource.class.to_s.downcase}")) %>
+ <% end %>
+
diff --git a/app/views/verification/email/_form.html.erb b/app/views/verification/email/_form.html.erb
new file mode 100644
index 000000000..94039e5e2
--- /dev/null
+++ b/app/views/verification/email/_form.html.erb
@@ -0,0 +1,4 @@
+<%= form_for Email.new(verified_user), url: email_path, method: :post do |f| %>
+ <%= hidden_field_tag :recipient, verified_user.email %>
+ <%= f.submit t('verification.email.form.submit_button') %>
+<% end %>
\ No newline at end of file
diff --git a/app/views/verification/letter/new.html.erb b/app/views/verification/letter/new.html.erb
new file mode 100644
index 000000000..ab1d3070e
--- /dev/null
+++ b/app/views/verification/letter/new.html.erb
@@ -0,0 +1,15 @@
+
+
+
+
<%= t('verification.letter.new.title') %>
+
+
+ <%= t('verification.letter.new.explanation') %>
+
+
+ <%= form_for @letter, url: letter_path do |f| %>
+ <%= render 'shared/errors', resource: @letter %>
+ <%= f.submit t('verification.letter.new.submit_button') %>
+ <% end %>
+
+
\ No newline at end of file
diff --git a/app/views/verification/residence/_errors.html.erb b/app/views/verification/residence/_errors.html.erb
new file mode 100644
index 000000000..cc64d9fbc
--- /dev/null
+++ b/app/views/verification/residence/_errors.html.erb
@@ -0,0 +1,12 @@
+<% if @residence.errors[:residence_in_madrid].present? %>
+
+
+ <%= t('verification.residence.new.error_verifying_census') %>
+ <%= mail_to "tec.gobiernoabierto@madrid.es" %>
+
+
+<% else %>
+ <%= render 'shared/errors',
+ resource: @residence,
+ message: t('verification.residence.new.form_errors') %>
+<% end %>
\ No newline at end of file
diff --git a/app/views/verification/residence/new.html.erb b/app/views/verification/residence/new.html.erb
new file mode 100644
index 000000000..83e1b6f73
--- /dev/null
+++ b/app/views/verification/residence/new.html.erb
@@ -0,0 +1,19 @@
+
+
+
+
<%= t('verification.residence.new.title') %>
+
+ <%= form_for @residence, url: residence_path do |f| %>
+ <%= render 'errors' %>
+
+ <%= f.select :document_type, document_types, prompt: "" %>
+ <%= f.text_field :document_number %>
+ <%= f.date_select :date_of_birth,
+ prompt: true,
+ start_year: 1900, end_year: 16.years.ago.year %>
+ <%= f.text_field :postal_code %>
+
+ <%= f.submit "Verify" %>
+ <% end %>
+
+
\ No newline at end of file
diff --git a/app/views/verification/sms/_form.html.erb b/app/views/verification/sms/_form.html.erb
new file mode 100644
index 000000000..efa0f74b8
--- /dev/null
+++ b/app/views/verification/sms/_form.html.erb
@@ -0,0 +1,5 @@
+<%= form_for sms, url: sms_path do |f| %>
+ <%= render 'shared/errors', resource: sms %>
+ <%= f.hidden_field :phone %>
+ <%= f.submit t('verification.sms.form.submit_button') %>
+<% end %>
\ No newline at end of file
diff --git a/app/views/verification/sms/edit.html.erb b/app/views/verification/sms/edit.html.erb
new file mode 100644
index 000000000..89fbef5ff
--- /dev/null
+++ b/app/views/verification/sms/edit.html.erb
@@ -0,0 +1,16 @@
+
+
+
+
<%= t('verification.sms.edit.title') %>
+
+ <%= form_for @sms, url: sms_path, method: :put do |f| %>
+
<%= @error %>
+ <%= f.text_field :confirmation_code %>
+
+ <%= f.submit t('verification.sms.edit.submit_button') %>
+ <% end %>
+
+ <%= t('verification.sms.edit.resend_sms_text') %>
+ <%= link_to t('verification.sms.edit.resend_sms_link'), verified_user_path %>
+
+
\ No newline at end of file
diff --git a/app/views/verification/sms/new.html.erb b/app/views/verification/sms/new.html.erb
new file mode 100644
index 000000000..eec63f6c6
--- /dev/null
+++ b/app/views/verification/sms/new.html.erb
@@ -0,0 +1,14 @@
+
+
+
+
<%= t('verification.sms.new.title') %>
+
+ <%= form_for @sms, url: sms_path do |f| %>
+ <%= render 'shared/errors', resource: @sms %>
+
+ <%= f.text_field :phone %>
+
+ <%= f.submit t('verification.sms.new.submit_button') %>
+ <% end %>
+
+
\ No newline at end of file
diff --git a/app/views/verification/verified_user/show.html.erb b/app/views/verification/verified_user/show.html.erb
new file mode 100644
index 000000000..bb61e8546
--- /dev/null
+++ b/app/views/verification/verified_user/show.html.erb
@@ -0,0 +1,49 @@
+
+
+
+
<%= t('verification.verified_user.show.title') %>
+
+ <% if @verified_users.map(&:email).any? %>
+
<%= t('verification.verified_user.show.email_title') %>
+
+ <% @verified_users.each do |verified_user| %>
+ <% if verified_user.email.present? %>
+ -
+
+ <%= verified_user.email %>
+
+
+ <%= render '/verification/email/form', verified_user: verified_user %>
+
+
+
+ <% end %>
+ <% end %>
+
+ <% end %>
+
+ <% if @verified_users.map(&:phone).any? %>
+
<%= t('verification.verified_user.show.phone_title') %>
+
+ <% @verified_users.each do |verified_user| %>
+ <% if verified_user.phone.present? %>
+ -
+
+ <%= verified_user.phone %>
+
+
+ <%= render '/verification/sms/form', sms: Sms.new(phone: verified_user.phone) %>
+
+
+
+ <% end %>
+ <% end %>
+
+ <% end %>
+
+
+ <%= link_to t('verification.verified_user.show.use_another_phone'), new_sms_path %>
+
+
+
+
\ No newline at end of file
diff --git a/config/i18n-tasks.yml b/config/i18n-tasks.yml
index d45c73d9b..c1991cd64 100644
--- a/config/i18n-tasks.yml
+++ b/config/i18n-tasks.yml
@@ -24,6 +24,7 @@ data:
- config/locales/%{locale}.yml
- config/locales/admin.%{locale}.yml
- config/locales/moderation.%{locale}.yml
+ - config/locales/verification.%{locale}.yml
- config/locales/mailers.%{locale}.yml
- config/locales/devise_views.%{locale}.yml
- config/locales/responders.%{locale}.yml
diff --git a/config/locales/activemodel.en.yml b/config/locales/activemodel.en.yml
new file mode 100644
index 000000000..edf91fdc4
--- /dev/null
+++ b/config/locales/activemodel.en.yml
@@ -0,0 +1,16 @@
+en:
+ activemodel:
+ models:
+ residence: Residence
+ sms: SMS
+ attributes:
+ residence:
+ document_type: Document type
+ document_number: Document number(including letter)
+ date_of_birth: Date of birth
+ postal_code: Postal code
+ sms:
+ phone: 'Phone'
+ confirmation_code: 'Confirmation code'
+ email:
+ recipient: 'Email'
\ No newline at end of file
diff --git a/config/locales/activemodel.es.yml b/config/locales/activemodel.es.yml
new file mode 100644
index 000000000..f72fdd385
--- /dev/null
+++ b/config/locales/activemodel.es.yml
@@ -0,0 +1,16 @@
+es:
+ activemodel:
+ models:
+ residence: Residencia
+ sms: SMS
+ attributes:
+ residence:
+ document_type: Tipo documento
+ document_number: Numero de documento (incluida letra)
+ date_of_birth: Fecha de nacimiento
+ postal_code: 'Código postal'
+ sms:
+ phone: 'Teléfono'
+ confirmation_code: 'Código de confirmación'
+ email:
+ recipient: 'Email'
\ No newline at end of file
diff --git a/config/locales/activerecord.en.yml b/config/locales/activerecord.en.yml
index 94b1fa0c9..e78d86512 100644
--- a/config/locales/activerecord.en.yml
+++ b/config/locales/activerecord.en.yml
@@ -7,6 +7,7 @@ en:
user: User
vote: Vote
organization: Organization
+ residence: Residencia
attributes:
comment:
body: Comment
diff --git a/config/locales/en.yml b/config/locales/en.yml
index 48cb717b6..afda0391b 100644
--- a/config/locales/en.yml
+++ b/config/locales/en.yml
@@ -52,6 +52,7 @@ en:
accept_terms: I accept the privacy policy and the legal terms
user: account
debate: debate
+ sms: phone
debates:
index:
create_debate: Create a debate
@@ -149,6 +150,9 @@ en:
phone_number_label: "Phone number"
organization_name_label: "Organization name"
notifications: Notifications
+ level_two_user: You are a level 2 user
+ level_three_user: You are a level 3 user
+ verify_my_account: Verify my account
simple_captcha:
placeholder: "Enter the image value"
label: "Enter the code in the box"
diff --git a/config/locales/es.yml b/config/locales/es.yml
index 76015f4c8..5884f0cfc 100644
--- a/config/locales/es.yml
+++ b/config/locales/es.yml
@@ -52,6 +52,7 @@ es:
accept_terms: Acepto la política de privacidad y el aviso legal
user: la cuenta
debate: el debate
+ sms: el teléfono
debates:
index:
create_debate: Crea un debate
@@ -149,6 +150,9 @@ es:
phone_number_label: "Teléfono"
organization_name_label: "Nombre de la organización"
notifications: Notificaciones
+ level_two_user: Eres un usuario verificado de nivel 2
+ level_three_user: Eres un usuario verificado de nivel 3
+ verify_my_account: Verificar mi cuenta
simple_captcha:
placeholder: "Introduce el texto de la imagen"
label: "Introduce el texto en la caja"
diff --git a/config/locales/mailers.en.yml b/config/locales/mailers.en.yml
index d0550aca9..4e3eeeab3 100644
--- a/config/locales/mailers.en.yml
+++ b/config/locales/mailers.en.yml
@@ -3,8 +3,13 @@ en:
comment:
hi: Hello
title: New comment on your debate
- new_comment_by_html: "There'is a new comment by on"
+ new_comment_by_html: "There is a new comment by %{commenter} on"
reply:
hi: Hello
title: New reply on your comment
new_reply_by_html: "There'is a new reply by %{commenter} to your comment on"
+ email_verification:
+ title: Please verify yourself
+ instructions_html: "We need to verify you using this email, which we got from the Census. %{verification_link}"
+ click_here_to_verify: "Please click here to verify yourself"
+
diff --git a/config/locales/mailers.es.yml b/config/locales/mailers.es.yml
index 8efa1dc22..a6491f032 100644
--- a/config/locales/mailers.es.yml
+++ b/config/locales/mailers.es.yml
@@ -8,3 +8,7 @@ es:
hi: Hola
title: Nueva respuesta a tu comentario
new_reply_by_html: "Hay una nueva respuesta de %{commenter} a tu comentario en"
+ email_verification:
+ title: Por favor verifícate
+ instructions_html: "Vamos a proceder a verificar tu cuenta en la aplicación de participación ciudadana utilizando esta cuenta de correo que sacamos del padrón. %{verification_link}."
+ click_here_to_verify: "Por favor pulsa este enlace para verificarte"
diff --git a/config/locales/rails.es.yml b/config/locales/rails.es.yml
index f29361c45..9a6e698d2 100644
--- a/config/locales/rails.es.yml
+++ b/config/locales/rails.es.yml
@@ -125,6 +125,7 @@ es:
too_short: es demasiado corto (%{count} caracteres mínimo)
wrong_length: no tiene la longitud correcta (%{count} caracteres exactos)
other_than: debe ser distinto de %{count}
+ invalid_date: "no es una fecha valida"
template:
body: 'Se encontraron problemas con los siguientes campos:'
header:
diff --git a/config/locales/verification.en.yml b/config/locales/verification.en.yml
new file mode 100644
index 000000000..f9b2db4fb
--- /dev/null
+++ b/config/locales/verification.en.yml
@@ -0,0 +1,72 @@
+en:
+ verification:
+ residence:
+ new:
+ title: 'Verify residence'
+ document_type:
+ spanish_id: 'Spanish ID'
+ passport: 'Passport'
+ residence_card: 'Residence card'
+ form_errors: 'prevented your residence verification'
+ error_verifying_census: 'The census of the city of Madrid could not verify your information. Pero revise de information and try again or get in touch with us.'
+ create:
+ flash:
+ success: 'Residence verified'
+ alert:
+ verify_attemps_left: 'You have reached the maximum number of Census verification tries'
+ unconfirmed_residency: 'You have not yet confirmed your residence'
+ sms:
+ new:
+ title: Phone verification
+ submit_button: Send
+ create:
+ flash:
+ success: 'Enter the confirmation code we have sent your phone'
+ edit:
+ title: Security code confirmation
+ resend_sms_text: You have not received the confirmation code in your phone?
+ resend_sms_link: Click here to send the confirmation code again
+ submit_button: Send
+ update:
+ error: 'Incorrect confirmation code'
+ flash:
+ level_three:
+ success: 'Correct code. You are now a verified user'
+ level_two:
+ success: 'Correct code'
+ form:
+ submit_button: Send
+ alert:
+ verify_attemps_left: 'You have reached the maximum number of sms verification tries'
+ email:
+ show:
+ flash:
+ success: 'You are now a verified user'
+ alert:
+ failure: 'Incorrect verification code'
+ create:
+ flash:
+ success: "We have send you a confirmation email to your email account: %{email}"
+ alert:
+ failure: "There was a problem sending you an email to your account"
+ form:
+ submit_button: Send
+ letter:
+ new:
+ title: Final Verification
+ explanation: 'To completely verify your account we need to go to one of these offices or send you a letter with a special code to your home address'
+ submit_button: 'Send me a letter'
+ create:
+ flash:
+ success: "You will receive a letter to your home address in the next couple of days"
+ alert:
+ failure: "We could not verify your address with the Census please try again later"
+ alert:
+ unconfirmed_personal_data: 'You have not yet confirmed your personal data'
+ verified_user:
+ show:
+ title: Available information
+ email_title: Emails
+ phone_title: Phones
+ use_another_phone: Use another phone
+
diff --git a/config/locales/verification.es.yml b/config/locales/verification.es.yml
new file mode 100644
index 000000000..b9cda6aed
--- /dev/null
+++ b/config/locales/verification.es.yml
@@ -0,0 +1,71 @@
+es:
+ verification:
+ residence:
+ new:
+ title: 'Verificar residencia'
+ document_type:
+ spanish_id: 'DNI'
+ passport: 'Pasaporte'
+ residence_card: 'Tarjeta de residencia'
+ form_errors: 'evitaron verificar tu residencia'
+ error_verifying_census: 'El Padrón de Madrid no pudo verificar tu información. Revisa la información ó ponte en contacto con nosotros.'
+ create:
+ flash:
+ success: 'Residencia verificada'
+ alert:
+ verify_attemps_left: 'Has llegado al máximo número de intentos de verificar tu residencia.'
+ unconfirmed_residency: 'Aún no has verificado tu residencia'
+ sms:
+ new:
+ title: Verificación de teléfono móvil
+ submit_button: Enviar
+ create:
+ flash:
+ success: 'Introduce el código de confirmación que te hemos enviado por mensaje de texto'
+ edit:
+ title: 'Confirmación de código de seguridad'
+ resend_sms_text: '¿No has recibido un mensaje de texto con tu código de confirmación?'
+ resend_sms_link: 'Haz click aquí para volver a enviártelo'
+ submit_button: Enviar
+ update:
+ error: 'Código de confirmación incorrecto'
+ flash:
+ level_three:
+ success: 'Código correcto. Ya eres un usuario verificado'
+ level_two:
+ success: 'Código incorrecto'
+ form:
+ submit_button: Enviar
+ alert:
+ verify_attemps_left: 'Has llegado al máximo número de intentos de verificar tu teléfono.'
+ email:
+ show:
+ flash:
+ success: 'Eres un usuario verificado'
+ alert:
+ failure: 'Código de verificación incorrecto'
+ create:
+ flash:
+ success: "Te hemos enviado un email de confirmación a tu cuenta: %{email}"
+ alert:
+ failure: "Hubo un problema enviándote un email a tu cuenta"
+ form:
+ submit_button: Enviar
+ letter:
+ new:
+ title: Final Verification
+ explanation: 'To completely verify your account we need to go to one of these offices or send you a letter with a special code to your home address'
+ submit_button: 'Send me a letter'
+ create:
+ flash:
+ success: "You will receive a letter to your home address in the next couple of days"
+ alert:
+ failure: "We could not verify your address with the Census please try again later"
+ alert:
+ unconfirmed_personal_data: 'You have not yet confirmed your personal data'
+ verified_user:
+ show:
+ title: Información disponible
+ email_title: Emails
+ phone_title: Teléfonos
+ use_another_phone: Utilizar otro teléfono
diff --git a/config/routes.rb b/config/routes.rb
index eb3953ea9..2e6a23cb7 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -42,10 +42,13 @@ Rails.application.routes.draw do
end
resource :account, controller: "account", only: [:show, :update]
- resource :stats, only: [:show]
- namespace :api do
- resource :stats, only: [:show]
+ scope module: :verification do
+ resource :residence, controller: "residence", only: [:new, :create]
+ resource :sms, controller: "sms", only: [:new, :create, :edit, :update]
+ resource :verified_user, controller: "verified_user", only: [:show]
+ resource :email, controller: "email", only: [:new, :show, :create]
+ resource :letter, controller: "letter", only: [:new, :create]
end
namespace :admin do
@@ -110,6 +113,12 @@ Rails.application.routes.draw do
end
end
+ resource :stats, only: [:show]
+
+ namespace :api do
+ resource :stats, only: [:show]
+ end
+
# Example of regular route:
# get 'products/:id' => 'catalog#view'
diff --git a/db/migrate/20150819193457_add_sms_verification_code_to_users.rb b/db/migrate/20150819193457_add_sms_verification_code_to_users.rb
new file mode 100644
index 000000000..d886a5ad6
--- /dev/null
+++ b/db/migrate/20150819193457_add_sms_verification_code_to_users.rb
@@ -0,0 +1,6 @@
+class AddSmsVerificationCodeToUsers < ActiveRecord::Migration
+ def change
+ add_column :users, :sms_verification_code, :string
+ add_column :users, :sms_verified_at, :datetime
+ end
+end
diff --git a/db/migrate/20150819203410_add_phone_to_users.rb b/db/migrate/20150819203410_add_phone_to_users.rb
new file mode 100644
index 000000000..7f94bae93
--- /dev/null
+++ b/db/migrate/20150819203410_add_phone_to_users.rb
@@ -0,0 +1,5 @@
+class AddPhoneToUsers < ActiveRecord::Migration
+ def change
+ add_column :users, :phone, :string
+ end
+end
diff --git a/db/migrate/20150822095305_create_verified_users.rb b/db/migrate/20150822095305_create_verified_users.rb
new file mode 100644
index 000000000..bb0c54042
--- /dev/null
+++ b/db/migrate/20150822095305_create_verified_users.rb
@@ -0,0 +1,14 @@
+class CreateVerifiedUsers < ActiveRecord::Migration
+ def change
+ unless ActiveRecord::Base.connection.table_exists? 'verified_users'
+ create_table :verified_users do |t|
+ t.string :document_number
+ t.string :document_type
+ t.string :phone
+ t.string :email
+
+ t.timestamps null: false
+ end
+ end
+ end
+end
diff --git a/db/migrate/20150822100557_add_document_to_users.rb b/db/migrate/20150822100557_add_document_to_users.rb
new file mode 100644
index 000000000..48259c417
--- /dev/null
+++ b/db/migrate/20150822100557_add_document_to_users.rb
@@ -0,0 +1,6 @@
+class AddDocumentToUsers < ActiveRecord::Migration
+ def change
+ add_column :users, :document_number, :string
+ add_column :users, :document_type, :string
+ end
+end
diff --git a/db/migrate/20150822132547_add_residence_verified_at_to_users.rb b/db/migrate/20150822132547_add_residence_verified_at_to_users.rb
new file mode 100644
index 000000000..65750fe82
--- /dev/null
+++ b/db/migrate/20150822132547_add_residence_verified_at_to_users.rb
@@ -0,0 +1,5 @@
+class AddResidenceVerifiedAtToUsers < ActiveRecord::Migration
+ def change
+ add_column :users, :residence_verified_at, :datetime
+ end
+end
diff --git a/db/migrate/20150823111403_add_letter_to_users.rb b/db/migrate/20150823111403_add_letter_to_users.rb
new file mode 100644
index 000000000..bdb7c8684
--- /dev/null
+++ b/db/migrate/20150823111403_add_letter_to_users.rb
@@ -0,0 +1,6 @@
+class AddLetterToUsers < ActiveRecord::Migration
+ def change
+ add_column :users, :letter_requested, :boolean, default: false
+ add_column :users, :letter_sent_at, :datetime
+ end
+end
diff --git a/db/migrate/20150823114519_add_email_verified_at_to_users.rb b/db/migrate/20150823114519_add_email_verified_at_to_users.rb
new file mode 100644
index 000000000..69a6b6ec1
--- /dev/null
+++ b/db/migrate/20150823114519_add_email_verified_at_to_users.rb
@@ -0,0 +1,5 @@
+class AddEmailVerifiedAtToUsers < ActiveRecord::Migration
+ def change
+ add_column :users, :email_verified_at, :datetime
+ end
+end
diff --git a/db/migrate/20150823121109_add_email_verification_to_users.rb b/db/migrate/20150823121109_add_email_verification_to_users.rb
new file mode 100644
index 000000000..4342cc174
--- /dev/null
+++ b/db/migrate/20150823121109_add_email_verification_to_users.rb
@@ -0,0 +1,6 @@
+class AddEmailVerificationToUsers < ActiveRecord::Migration
+ def change
+ add_column :users, :email_verification_token, :string
+ add_column :users, :email_for_verification, :string
+ end
+end
diff --git a/db/migrate/20150824110104_add_verified_user_sms_verified_at_to_users.rb b/db/migrate/20150824110104_add_verified_user_sms_verified_at_to_users.rb
new file mode 100644
index 000000000..06d8f47d0
--- /dev/null
+++ b/db/migrate/20150824110104_add_verified_user_sms_verified_at_to_users.rb
@@ -0,0 +1,5 @@
+class AddVerifiedUserSmsVerifiedAtToUsers < ActiveRecord::Migration
+ def change
+ add_column :users, :verified_user_sms_verified_at, :datetime
+ end
+end
diff --git a/db/migrate/20150825165517_add_sms_tried_to_users.rb b/db/migrate/20150825165517_add_sms_tried_to_users.rb
new file mode 100644
index 000000000..280ab5b15
--- /dev/null
+++ b/db/migrate/20150825165517_add_sms_tried_to_users.rb
@@ -0,0 +1,5 @@
+class AddSmsTriedToUsers < ActiveRecord::Migration
+ def change
+ add_column :users, :sms_tries, :integer, default: 0
+ end
+end
diff --git a/db/migrate/20150825175647_add_residence_verification_tries_to_users.rb b/db/migrate/20150825175647_add_residence_verification_tries_to_users.rb
new file mode 100644
index 000000000..fb8a9ed6c
--- /dev/null
+++ b/db/migrate/20150825175647_add_residence_verification_tries_to_users.rb
@@ -0,0 +1,5 @@
+class AddResidenceVerificationTriesToUsers < ActiveRecord::Migration
+ def change
+ add_column :users, :residence_verification_tries, :integer, default: 0
+ end
+end
diff --git a/db/migrate/20150825201922_create_addresses.rb b/db/migrate/20150825201922_create_addresses.rb
new file mode 100644
index 000000000..f3bc11ec2
--- /dev/null
+++ b/db/migrate/20150825201922_create_addresses.rb
@@ -0,0 +1,23 @@
+class CreateAddresses < ActiveRecord::Migration
+ def change
+ create_table :addresses do |t|
+ t.integer :user_id
+ t.string :street
+ t.string :street_type
+ t.string :number
+ t.string :number_type
+ t.string :letter
+ t.string :portal
+ t.string :stairway
+ t.string :floor
+ t.string :door
+ t.string :km
+ t.string :neighbourhood
+ t.string :district
+ t.string :postal_code
+ t.string :toponymy
+
+ t.timestamps null: false
+ end
+ end
+end
diff --git a/db/migrate/20150826182010_refactor_verification_columns.rb b/db/migrate/20150826182010_refactor_verification_columns.rb
new file mode 100644
index 000000000..1133d323e
--- /dev/null
+++ b/db/migrate/20150826182010_refactor_verification_columns.rb
@@ -0,0 +1,20 @@
+class RefactorVerificationColumns < ActiveRecord::Migration
+ def change
+ rename_column :users, :sms_verification_code, :sms_confirmation_code
+
+ remove_column :users, :sms_verified_at
+ remove_column :users, :email_verified_at
+ remove_column :users, :email_for_verification
+ remove_column :users, :verified_user_sms_verified_at
+ add_column :users, :verified_at, :datetime
+
+ remove_column :users, :phone
+ add_column :users, :unconfirmed_phone, :string
+ add_column :users, :confirmed_phone, :string
+
+ remove_column :users, :letter_requested
+ add_column :users, :letter_requested_at, :datetime
+
+ rename_column :users, :sms_tries, :sms_confirmation_tries
+ end
+end
diff --git a/db/schema.rb b/db/schema.rb
index 0da2f7c6a..fd22d3092 100644
--- a/db/schema.rb
+++ b/db/schema.rb
@@ -16,6 +16,26 @@ ActiveRecord::Schema.define(version: 20150828085718) do
# These are extensions that must be enabled in order to support this database
enable_extension "plpgsql"
+ create_table "addresses", force: :cascade do |t|
+ t.integer "user_id"
+ t.string "street"
+ t.string "street_type"
+ t.string "number"
+ t.string "number_type"
+ t.string "letter"
+ t.string "portal"
+ t.string "stairway"
+ t.string "floor"
+ t.string "door"
+ t.string "km"
+ t.string "neighbourhood"
+ t.string "district"
+ t.string "postal_code"
+ t.string "toponymy"
+ t.datetime "created_at", null: false
+ t.datetime "updated_at", null: false
+ end
+
create_table "administrators", force: :cascade do |t|
t.integer "user_id"
end
@@ -47,8 +67,8 @@ ActiveRecord::Schema.define(version: 20150828085718) do
t.integer "rgt"
t.datetime "created_at"
t.datetime "updated_at"
- t.integer "children_count", default: 0
t.datetime "hidden_at"
+ t.integer "children_count", default: 0
t.integer "flags_count", default: 0
t.datetime "ignored_flag_at"
t.integer "moderator_id"
@@ -70,14 +90,14 @@ ActiveRecord::Schema.define(version: 20150828085718) 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 "hidden_at"
+ t.datetime "created_at", null: false
+ t.datetime "updated_at", null: false
t.string "visit_id"
+ t.datetime "hidden_at"
t.integer "flags_count", default: 0
- t.integer "cached_votes_total", default: 0
- t.integer "cached_votes_up", default: 0
- t.integer "cached_votes_down", default: 0
+ t.integer "cached_votes_total", default: 0
+ t.integer "cached_votes_up", default: 0
+ t.integer "cached_votes_down", default: 0
t.datetime "ignored_flag_at"
t.integer "comments_count", default: 0
t.datetime "confirmed_hide_at"
@@ -161,29 +181,41 @@ ActiveRecord::Schema.define(version: 20150828085718) do
add_index "tags", ["name"], name: "index_tags_on_name", unique: true, using: :btree
create_table "users", force: :cascade do |t|
- t.string "email", default: "", null: false
- t.string "encrypted_password", default: "", null: false
+ t.string "email", default: "", null: false
+ t.string "encrypted_password", default: "", null: false
t.string "reset_password_token"
t.datetime "reset_password_sent_at"
t.datetime "remember_created_at"
- t.integer "sign_in_count", default: 0, null: false
+ t.integer "sign_in_count", default: 0, null: false
t.datetime "current_sign_in_at"
t.datetime "last_sign_in_at"
t.string "current_sign_in_ip"
t.string "last_sign_in_ip"
- t.datetime "created_at", null: false
- t.datetime "updated_at", null: false
+ t.datetime "created_at", null: false
+ t.datetime "updated_at", null: false
t.string "confirmation_token"
t.datetime "confirmed_at"
t.datetime "confirmation_sent_at"
t.string "unconfirmed_email"
- t.boolean "email_on_debate_comment", default: false
- t.boolean "email_on_comment_reply", default: false
+ t.boolean "email_on_debate_comment", default: false
+ t.boolean "email_on_comment_reply", default: false
+ t.string "phone_number", limit: 30
t.string "official_position"
- t.integer "official_level", default: 0
+ t.integer "official_level", default: 0
t.datetime "hidden_at"
- t.string "phone_number", limit: 30
+ t.string "sms_confirmation_code"
t.string "username"
+ t.string "document_number"
+ t.string "document_type"
+ t.datetime "residence_verified_at"
+ t.datetime "letter_sent_at"
+ t.string "email_verification_token"
+ t.integer "sms_confirmation_tries", default: 0
+ t.integer "residence_verification_tries", default: 0
+ t.datetime "verified_at"
+ t.string "unconfirmed_phone"
+ t.string "confirmed_phone"
+ t.datetime "letter_requested_at"
t.datetime "confirmed_hide_at"
end
@@ -192,6 +224,15 @@ ActiveRecord::Schema.define(version: 20150828085718) do
add_index "users", ["hidden_at"], name: "index_users_on_hidden_at", using: :btree
add_index "users", ["reset_password_token"], name: "index_users_on_reset_password_token", unique: true, using: :btree
+ create_table "verified_users", force: :cascade do |t|
+ t.string "document_number"
+ t.string "document_type"
+ t.string "phone"
+ t.string "email"
+ t.datetime "created_at", null: false
+ t.datetime "updated_at", null: false
+ end
+
create_table "visits", id: :uuid, default: nil, force: :cascade do |t|
t.uuid "visitor_id"
t.string "ip"
diff --git a/lib/active_model/dates.rb b/lib/active_model/dates.rb
new file mode 100644
index 000000000..a519e3840
--- /dev/null
+++ b/lib/active_model/dates.rb
@@ -0,0 +1,25 @@
+module ActiveModel::Dates
+
+ def parse_date(field, attrs)
+ day, month, year = attrs["#{field}(1i)"],
+ attrs["#{field}(2i)"],
+ attrs["#{field}(3i)"]
+
+ return nil unless day.present? && month.present? && year.present?
+ Date.new(day.to_i, month.to_i, year.to_i)
+ end
+
+ def remove_date(field, attrs)
+ attrs.except("#{field}(1i)", "#{field}(2i)", "#{field}(3i)")
+ end
+
+ def date_to_string(date)
+ date.strftime("%d-%m-%Y")
+ end
+
+ def string_to_date(value)
+ day, month, year = value.split("-")
+ Date.new(year.to_i, month.to_i, day.to_i)
+ end
+
+end
\ No newline at end of file
diff --git a/lib/sms_api.rb b/lib/sms_api.rb
new file mode 100644
index 000000000..886ed7f34
--- /dev/null
+++ b/lib/sms_api.rb
@@ -0,0 +1,44 @@
+require 'open-uri'
+class SMSApi
+ attr_accessor :client
+
+ def initialize
+ @client = Savon.client(wsdl: url)
+ end
+
+ def url
+ return "" unless end_point_available?
+ open(Rails.application.secrets.sms_end_point).base_uri.to_s
+ end
+
+ def authorization
+ Base64.encode64("#{Rails.application.secrets.sms_username}:#{Rails.application.secrets.sms_password}")
+ end
+
+ def sms_deliver(phone, code)
+ return stubbed_response unless end_point_available?
+
+ response = client.call(:enviar_sms_simples, message: request(phone, code))
+ success?(response)
+ end
+
+ def request(phone, code)
+ { autorizacion: authorization,
+ destinatarios: { destinatario: phone },
+ texto_mensaje: "Código de verificación: #{code}",
+ solicita_notificacion: "All" }
+ end
+
+ def success?(response)
+ response.body[:respuesta_sms][:respuesta_servicio_externo][:texto_respuesta] == "Success"
+ end
+
+ def end_point_available?
+ Rails.env.staging? || Rails.env.production?
+ end
+
+ def stubbed_response
+ {:respuesta_sms=>{:identificador_mensaje=>"1234567", :fecha_respuesta=>"Thu, 20 Aug 2015 16:28:05 +0200", :respuesta_pasarela=>{:codigo_pasarela=>"0000", :descripcion_pasarela=>"Operación ejecutada correctamente."}, :respuesta_servicio_externo=>{:codigo_respuesta=>"1000", :texto_respuesta=>"Success"}}}
+ end
+
+end
diff --git a/lib/user_api.rb b/lib/user_api.rb
new file mode 100644
index 000000000..a5553e279
--- /dev/null
+++ b/lib/user_api.rb
@@ -0,0 +1,56 @@
+class UserApi
+ attr_accessor :client, :citizen, :response
+
+ def initialize(citizen)
+ @citizen = citizen
+ end
+
+ def client
+ @client = Savon.client(wsdl: Rails.application.secrets.padron_end_point)
+ end
+
+ def response
+ return stubbed_response unless end_point_available?
+ client.call(:get_habita_datos, message: request).body
+ end
+
+ def request
+ { request:
+ { codigo_institucion: Rails.application.secrets.institution_code,
+ codigo_portal: Rails.application.secrets.portal_name,
+ codigo_usuario: Rails.application.secrets.user_code,
+ documento: citizen.document_number,
+ tipo_documento: citizen.document_type,
+ codigo_idioma: 102,
+ nivel: 3 }}
+ end
+
+ def data
+ response[:get_habita_datos_response][:get_habita_datos_return]
+ end
+
+ def date_of_birth
+ data[:datos_habitante][:item][:fecha_nacimiento_string]
+ end
+
+ def postal_code
+ data[:datos_vivienda][:item][:codigo_postal]
+ end
+
+ def address
+ response[:get_habita_datos_response][:get_habita_datos_return][:datos_vivienda][:item]
+ end
+
+ def valid?
+ citizen.date_of_birth == date_of_birth &&
+ citizen.postal_code == postal_code
+ end
+
+ def end_point_available?
+ Rails.env.staging? || Rails.env.production?
+ end
+
+ def stubbed_response
+ {:get_habita_datos_response=>{:get_habita_datos_return=>{:hay_errores=>false, :datos_habitante=>{:item=>{:fecha_nacimiento_string=>"31-12-1980", :identificador_documento=>"12345678Z", }}, :datos_vivienda=>{:item=>{:codigo_postal=>"28013", :escalera=>"4", :km=>"0", :letra_via=>"B", :nombre_barrio=>"JUSTICIA", :nombre_distrito=>"CENTRO", :nombre_via=>"ALCALÁ", :nominal_via=>"NUM", :numero_via=>"1", :planta=>"PB", :portal=>"1", :puerta=>"DR", :sigla_via=>"CALLE"}}}}}
+ end
+end
diff --git a/lib/verification.rb b/lib/verification.rb
new file mode 100644
index 000000000..2e784d65c
--- /dev/null
+++ b/lib/verification.rb
@@ -0,0 +1,20 @@
+module Verification
+
+ def residence_verified?
+ residence_verified_at.present?
+ end
+
+ def sms_verified?
+ confirmed_phone.present?
+ end
+
+ def level_two_verified?
+ residence_verified? && sms_verified?
+ end
+
+ def level_three_verified?
+ verified_at.present?
+ end
+
+
+end
\ No newline at end of file
diff --git a/spec/factories.rb b/spec/factories.rb
index 3e355499a..a9bff4ac1 100644
--- a/spec/factories.rb
+++ b/spec/factories.rb
@@ -20,6 +20,33 @@ FactoryGirl.define do
uid "MyString"
end
+ factory :residence do
+ document_number '12345678Z'
+ document_type 1
+ date_of_birth Date.new(1980, 12, 31)
+ postal_code "28013"
+ end
+
+ factory :sms do
+ phone "699999999"
+ end
+
+ factory :letter do
+ user
+ address
+ end
+
+ factory :address do
+ street_type "Calle"
+ street "Alcalá"
+ number "1"
+ end
+
+ factory :verified_user do
+ document_number '12345678Z'
+ document_type 'dni'
+ end
+
factory :debate do
sequence(:title) { |n| "Debate #{n} title" }
description 'Debate description'
diff --git a/spec/features/verification/email_spec.rb b/spec/features/verification/email_spec.rb
new file mode 100644
index 000000000..c886e4ff6
--- /dev/null
+++ b/spec/features/verification/email_spec.rb
@@ -0,0 +1,65 @@
+require 'rails_helper'
+
+feature 'Verify email' do
+
+ scenario 'Verify' do
+ user = create(:user,
+ residence_verified_at: Time.now,
+ document_number: '12345678Z',
+ document_type: 'dni')
+
+ verified_user = create(:verified_user,
+ document_number: '12345678Z',
+ document_type: 'dni',
+ email: 'rock@example.com')
+
+ login_as(user)
+
+ visit verified_user_path
+
+ within("#verified_user_#{verified_user.id}_email") do
+ expect(page).to have_content 'rock@example.com'
+ click_button "Send"
+ end
+
+ expect(page).to have_content 'We have send you a confirmation email to your email account: rock@example.com'
+
+ sent_token = /.*email_verification_token=(.*)".*/.match(ActionMailer::Base.deliveries.last.body.to_s)[1]
+ visit email_path(email_verification_token: sent_token)
+
+ expect(page).to have_content "You are now a verified user"
+
+ expect(page).to_not have_link "Verify my account"
+ expect(page).to have_content "You are a level 3 user"
+ end
+
+ scenario "Errors on token verification" do
+ user = create(:user, residence_verified_at: Time.now)
+
+ login_as(user)
+ visit email_path(email_verification_token: "1234")
+
+ expect(page).to have_content "Incorrect verification code"
+ end
+
+ scenario "Errors on sending confirmation email" do
+ user = create(:user,
+ residence_verified_at: Time.now,
+ document_number: '12345678Z',
+ document_type: 'dni')
+
+ verified_user = create(:verified_user,
+ document_number: '12345678Z',
+ document_type: 'dni',
+ email: 'rock@example.com')
+
+ login_as(user)
+
+ visit verified_user_path
+
+ verified_user.destroy
+ click_button "Send"
+
+ expect(page).to have_content "There was a problem sending you an email to your account"
+ end
+end
\ No newline at end of file
diff --git a/spec/features/verification/letter_spec.rb b/spec/features/verification/letter_spec.rb
new file mode 100644
index 000000000..4816bd9b1
--- /dev/null
+++ b/spec/features/verification/letter_spec.rb
@@ -0,0 +1,60 @@
+require 'rails_helper'
+
+feature 'Verify Letter' do
+
+ scenario 'Send letter level 2 verified with phone' do
+ user = create(:user, residence_verified_at: Time.now, confirmed_phone: "611111111")
+
+ login_as(user)
+ visit new_letter_path
+
+ click_button "Send me a letter"
+
+ expect(page).to have_content "You will receive a letter to your home address"
+ end
+
+ scenario "Error accessing address from UserApi" do
+ user = create(:user, residence_verified_at: Time.now, confirmed_phone: "611111111")
+
+ login_as(user)
+ visit new_letter_path
+
+ allow_any_instance_of(UserApi).to receive(:address).and_return(nil)
+
+ click_button "Send me a letter"
+
+ expect(page).to have_content "We could not verify your address with the Census please try again later"
+ end
+
+ scenario 'Send letter level 2 user verified with email' do
+ user = create(:user, residence_verified_at: Time.now, confirmed_phone: "611111111")
+
+ login_as(user)
+ visit new_letter_path
+
+ click_button "Send me a letter"
+
+ expect(page).to have_content "You will receive a letter to your home address"
+ end
+
+ scenario "Deny access unless verified residence" do
+ user = create(:user)
+
+ login_as(user)
+ visit new_letter_path
+
+ expect(page).to have_content 'You have not yet confirmed your residence'
+ expect(URI.parse(current_url).path).to eq(new_residence_path)
+ end
+
+ scenario "Deny access unless verified phone/email" do
+ user = create(:user, residence_verified_at: Time.now)
+
+ login_as(user)
+ visit new_letter_path
+
+ expect(page).to have_content 'You have not yet confirmed your personal data'
+ expect(URI.parse(current_url).path).to eq(new_sms_path)
+ end
+
+end
\ No newline at end of file
diff --git a/spec/features/verification/level_three_verification_spec.rb b/spec/features/verification/level_three_verification_spec.rb
new file mode 100644
index 000000000..617065379
--- /dev/null
+++ b/spec/features/verification/level_three_verification_spec.rb
@@ -0,0 +1,113 @@
+require 'rails_helper'
+
+feature 'Level three verification' do
+ scenario 'Verification with residency and verified sms' do
+ user = create(:user)
+
+ verified_user = create(:verified_user,
+ document_number: '12345678Z',
+ document_type: '1',
+ phone: '611111111')
+
+ login_as(user)
+
+ visit account_path
+ click_link 'Verify my account'
+
+ select 'Spanish ID', from: 'residence_document_type'
+ fill_in 'residence_document_number', with: "12345678Z"
+ select_date '31-December-1980', from: 'residence_date_of_birth'
+ fill_in 'residence_postal_code', with: '28013'
+
+ click_button 'Verify'
+
+ expect(page).to have_content 'Residence verified'
+
+ within("#verified_user_#{verified_user.id}_phone") do
+ click_button "Send"
+ end
+
+ expect(page).to have_content 'Security code confirmation'
+
+ user = user.reload
+ fill_in 'sms_confirmation_code', with: user.sms_confirmation_code
+ click_button 'Send'
+
+ expect(page).to have_content 'Correct code'
+
+ expect(page).to have_content "You are now a verified user"
+
+ expect(page).to_not have_link "Verify my account"
+ expect(page).to have_content "You are a level 3 user"
+ end
+
+ scenario 'Verification with residency and verified email' do
+ user = create(:user)
+
+ verified_user = create(:verified_user,
+ document_number: '12345678Z',
+ document_type: '1',
+ email: 'rock@example.com')
+
+ login_as(user)
+
+ visit account_path
+ click_link 'Verify my account'
+
+ select 'Spanish ID', from: 'residence_document_type'
+ fill_in 'residence_document_number', with: "12345678Z"
+ select_date '31-December-1980', from: 'residence_date_of_birth'
+ fill_in 'residence_postal_code', with: '28013'
+
+ click_button 'Verify'
+
+ expect(page).to have_content 'Residence verified'
+
+ within("#verified_user_#{verified_user.id}_email") do
+ click_button "Send"
+ end
+
+ expect(page).to have_content 'We have send you a confirmation email to your email account: rock@example.com'
+
+ sent_token = /.*email_verification_token=(.*)".*/.match(ActionMailer::Base.deliveries.last.body.to_s)[1]
+ visit email_path(email_verification_token: sent_token)
+
+ expect(page).to have_content "You are now a verified user"
+
+ expect(page).to_not have_link "Verify my account"
+ expect(page).to have_content "You are a level 3 user"
+ end
+
+ scenario 'Verification with residency and sms and letter' do
+
+ user = create(:user)
+ login_as(user)
+
+ visit account_path
+ click_link 'Verify my account'
+
+ select 'Spanish ID', from: 'residence_document_type'
+ fill_in 'residence_document_number', with: "12345678Z"
+ select_date '31-December-1980', from: 'residence_date_of_birth'
+ fill_in 'residence_postal_code', with: '28013'
+
+ click_button 'Verify'
+
+ expect(page).to have_content 'Residence verified'
+
+ fill_in 'sms_phone', with: "611111111"
+ click_button 'Send'
+
+ expect(page).to have_content 'Security code confirmation'
+
+ user = user.reload
+ fill_in 'sms_confirmation_code', with: user.sms_confirmation_code
+ click_button 'Send'
+
+ expect(page).to have_content 'Correct code'
+
+ click_button "Send me a letter"
+
+ expect(page).to have_content "You will receive a letter to your home address"
+ end
+end
\ No newline at end of file
diff --git a/spec/features/verification/level_two_verification_spec.rb b/spec/features/verification/level_two_verification_spec.rb
new file mode 100644
index 000000000..8358d33fe
--- /dev/null
+++ b/spec/features/verification/level_two_verification_spec.rb
@@ -0,0 +1,33 @@
+require 'rails_helper'
+
+feature 'Level two verification' do
+
+ scenario 'Verification with residency and sms' do
+ user = create(:user)
+ login_as(user)
+
+ visit account_path
+ click_link 'Verify my account'
+
+ select 'Spanish ID', from: 'residence_document_type'
+ fill_in 'residence_document_number', with: "12345678Z"
+ select_date '31-December-1980', from: 'residence_date_of_birth'
+ fill_in 'residence_postal_code', with: '28013'
+
+ click_button 'Verify'
+
+ expect(page).to have_content 'Residence verified'
+
+ fill_in 'sms_phone', with: "611111111"
+ click_button 'Send'
+
+ expect(page).to have_content 'Security code confirmation'
+
+ user = user.reload
+ fill_in 'sms_confirmation_code', with: user.sms_confirmation_code
+ click_button 'Send'
+
+ expect(page).to have_content 'Correct code'
+ end
+
+end
\ No newline at end of file
diff --git a/spec/features/verification/residence_spec.rb b/spec/features/verification/residence_spec.rb
new file mode 100644
index 000000000..95f25ed2b
--- /dev/null
+++ b/spec/features/verification/residence_spec.rb
@@ -0,0 +1,80 @@
+require 'rails_helper'
+
+feature 'Residence' do
+
+ scenario 'Verify resident in Madrid' do
+ user = create(:user)
+ login_as(user)
+
+ visit account_path
+ click_link 'Verify my account'
+
+ fill_in 'residence_document_number', with: "12345678Z"
+ select 'Spanish ID', from: 'residence_document_type'
+ select_date '31-December-1980', from: 'residence_date_of_birth'
+ fill_in 'residence_postal_code', with: '28013'
+
+ click_button 'Verify'
+
+ expect(page).to have_content 'Residence verified'
+ end
+
+ scenario 'Error on verify' do
+ user = create(:user)
+ login_as(user)
+
+ visit account_path
+ click_link 'Verify my account'
+
+ click_button 'Verify'
+
+ expect(page).to have_content /\d errors? prevented your residence verification/
+ end
+
+ scenario 'Error on Madrid census' do
+ user = create(:user)
+ login_as(user)
+
+ visit account_path
+ click_link 'Verify my account'
+
+ fill_in 'residence_document_number', with: "12345678Z"
+ select 'Spanish ID', from: 'residence_document_type'
+ select '1997', from: 'residence_date_of_birth_1i'
+ select 'January', from: 'residence_date_of_birth_2i'
+ select '1', from: 'residence_date_of_birth_3i'
+ fill_in 'residence_postal_code', with: '28013'
+
+ click_button 'Verify'
+
+ expect(page).to have_content 'The census of the city of Madrid could not verify your information'
+ end
+
+ scenario '5 tries allowed' do
+ user = create(:user)
+ login_as(user)
+
+ visit account_path
+ click_link 'Verify my account'
+
+ 5.times do
+ fill_in 'residence_document_number', with: "12345678Z"
+ select 'Spanish ID', from: 'residence_document_type'
+ select '1997', from: 'residence_date_of_birth_1i'
+ select 'January', from: 'residence_date_of_birth_2i'
+ select '1', from: 'residence_date_of_birth_3i'
+ fill_in 'residence_postal_code', with: '28013'
+
+ click_button 'Verify'
+ expect(page).to have_content 'The census of the city of Madrid could not verify your information'
+ end
+
+ click_button 'Verify'
+ expect(page).to have_content 'You have reached the maximum number of Census verification tries'
+ expect(URI.parse(current_url).path).to eq(account_path)
+
+ visit new_residence_path
+ expect(page).to have_content 'You have reached the maximum number of Census verification tries'
+ expect(URI.parse(current_url).path).to eq(account_path)
+ end
+end
\ No newline at end of file
diff --git a/spec/features/verification/sms_spec.rb b/spec/features/verification/sms_spec.rb
new file mode 100644
index 000000000..e445b3a27
--- /dev/null
+++ b/spec/features/verification/sms_spec.rb
@@ -0,0 +1,80 @@
+require 'rails_helper'
+
+feature 'SMS Verification' do
+
+ scenario 'Verify' do
+ user = create(:user, residence_verified_at: Time.now)
+ login_as(user)
+
+ visit new_sms_path
+
+ fill_in 'sms_phone', with: "611111111"
+ click_button 'Send'
+
+ expect(page).to have_content 'Security code confirmation'
+
+ user = user.reload
+ fill_in 'sms_confirmation_code', with: user.sms_confirmation_code
+ click_button 'Send'
+
+ expect(page).to have_content 'Correct code'
+ end
+
+ scenario 'Errors on phone number' do
+ user = create(:user, residence_verified_at: Time.now)
+ login_as(user)
+
+ visit new_sms_path
+
+ click_button 'Send'
+
+ expect(page).to have_content error_message
+ end
+
+ scenario 'Errors on verification code' do
+ user = create(:user, residence_verified_at: Time.now)
+ login_as(user)
+
+ visit new_sms_path
+
+ fill_in 'sms_phone', with: "611111111"
+ click_button 'Send'
+
+ expect(page).to have_content 'Security code confirmation'
+
+ click_button 'Send'
+
+ expect(page).to have_content 'Incorrect confirmation code'
+ end
+
+ scenario 'Deny access unless residency verified' do
+ user = create(:user)
+ login_as(user)
+
+ visit new_sms_path
+
+ expect(page).to have_content 'You have not yet confirmed your residence'
+ expect(URI.parse(current_url).path).to eq(new_residence_path)
+ end
+
+ scenario '3 tries allowed' do
+ user = create(:user, residence_verified_at: Time.now)
+ login_as(user)
+
+ visit new_sms_path
+
+ 3.times do
+ fill_in 'sms_phone', with: "611111111"
+ click_button 'Send'
+ click_link 'Click here to send the confirmation code again'
+ end
+
+ expect(page).to have_content 'You have reached the maximum number of sms verification tries'
+ expect(URI.parse(current_url).path).to eq(account_path)
+
+ visit new_sms_path
+ expect(page).to have_content 'You have reached the maximum number of sms verification tries'
+ expect(URI.parse(current_url).path).to eq(account_path)
+ end
+
+end
\ No newline at end of file
diff --git a/spec/features/verification/verified_user_spec.rb b/spec/features/verification/verified_user_spec.rb
new file mode 100644
index 000000000..ce28ce80f
--- /dev/null
+++ b/spec/features/verification/verified_user_spec.rb
@@ -0,0 +1,132 @@
+require 'rails_helper'
+
+feature 'Verified users' do
+
+ scenario "Verified emails" do
+ user = create(:user,
+ residence_verified_at: Time.now,
+ document_number: '12345678Z',
+ document_type: '2')
+
+ create(:verified_user,
+ document_number: '12345678Z',
+ document_type: '2',
+ email: 'rock@example.com')
+
+ create(:verified_user,
+ document_number: '12345678Z',
+ document_type: '2',
+ email: 'roll@example.com')
+
+ create(:verified_user,
+ document_number: '99999999R',
+ document_type: '2',
+ email: 'another@example.com')
+
+ login_as(user)
+ visit verified_user_path
+
+ expect(page).to have_content 'rock@example.com'
+ expect(page).to have_content 'roll@example.com'
+ end
+
+ scenario "Verified phones" do
+ user = create(:user,
+ residence_verified_at: Time.now,
+ document_number: '12345678Z',
+ document_type: '2')
+
+ create(:verified_user,
+ document_number: '12345678Z',
+ document_type: '2',
+ phone: '611111111')
+
+ create(:verified_user,
+ document_number: '12345678Z',
+ document_type: '2',
+ email: '622222222')
+
+ create(:verified_user,
+ document_number: '99999999R',
+ document_type: '2',
+ email: '633333333')
+
+ login_as(user)
+ visit verified_user_path
+
+ expect(page).to have_content '611111111'
+ expect(page).to have_content '622222222'
+ end
+
+ scenario "Select a verified email" do
+ user = create(:user,
+ residence_verified_at: Time.now,
+ document_number: '12345678Z',
+ document_type: '2')
+
+ verified_user = create(:verified_user,
+ document_number: '12345678Z',
+ document_type: '2',
+ email: 'rock@example.com')
+
+ login_as(user)
+ visit verified_user_path
+
+ within("#verified_user_#{verified_user.id}_email") do
+ click_button "Send"
+ end
+
+ expect(page).to have_content 'We have send you a confirmation email to your email account: rock@example.com'
+ expect(URI.parse(current_url).path).to eq(account_path)
+ end
+
+ scenario "Select a verified phone" do
+ user = create(:user,
+ residence_verified_at: Time.now,
+ document_number: '12345678Z',
+ document_type: '2')
+
+ verified_user = create(:verified_user,
+ document_number: '12345678Z',
+ document_type: '2',
+ phone: '611111111')
+
+ login_as(user)
+ visit verified_user_path
+
+ within("#verified_user_#{verified_user.id}_phone") do
+ click_button "Send"
+ end
+
+ expect(page).to have_content 'Enter the confirmation code'
+ end
+
+ scenario "Continue without selecting any verified information" do
+ user = create(:user,
+ residence_verified_at: Time.now,
+ document_number: '12345678Z',
+ document_type: '2')
+
+ create(:verified_user,
+ document_number: '12345678Z',
+ document_type: '2',
+ phone: '611111111')
+
+ login_as(user)
+ visit verified_user_path
+
+ click_link "Use another phone"
+
+ expect(URI.parse(current_url).path).to eq(new_sms_path)
+ end
+
+ scenario "No verified information" do
+ user = create(:user, residence_verified_at: Time.now)
+
+ login_as(user)
+ visit verified_user_path
+
+ expect(URI.parse(current_url).path).to eq(new_sms_path)
+ end
+
+end
\ No newline at end of file
diff --git a/spec/models/letter_spec.rb b/spec/models/letter_spec.rb
new file mode 100644
index 000000000..e5e871d7c
--- /dev/null
+++ b/spec/models/letter_spec.rb
@@ -0,0 +1,59 @@
+require 'rails_helper'
+
+describe 'Letter' do
+
+ let(:user) { create(:user) }
+
+ describe "validations" do
+
+ let(:letter) { build(:letter) }
+
+ it "should be valid" do
+ expect(letter).to be_valid
+ end
+
+ it "should not be valid without a user" do
+ letter.user = nil
+ expect(letter).to_not be_valid
+ end
+
+ it "should not be valid without an address" do
+ letter.address = {}
+ expect(letter).to_not be_valid
+ end
+
+ end
+
+ describe "save" do
+
+ before(:each) do
+ letter = Letter.new(user: user)
+ letter.save
+ user.reload
+ end
+
+ it "should update letter_requested" do
+ expect(user.letter_requested_at).to be
+ end
+
+ it "should update address" do
+ expect(user.address).to have_attributes({
+ postal_code: "28013",
+ street: "ALCALÁ",
+ street_type: "CALLE",
+ number: "1",
+ number_type: "NUM",
+ letter: "B",
+ portal: "1",
+ stairway: "4",
+ floor: "PB",
+ door: "DR",
+ km: "0",
+ neighbourhood: "JUSTICIA",
+ district: "CENTRO"
+ })
+ end
+
+ end
+
+end
\ No newline at end of file
diff --git a/spec/models/residence_spec.rb b/spec/models/residence_spec.rb
new file mode 100644
index 000000000..66eb34951
--- /dev/null
+++ b/spec/models/residence_spec.rb
@@ -0,0 +1,52 @@
+require 'rails_helper'
+
+describe Residence do
+
+ let(:residence) { build(:residence) }
+
+ describe "validations" do
+
+ it "should be valid" do
+ expect(residence).to be_valid
+ end
+
+ describe "dates" do
+ it "should be valid with a valid date of birth" do
+ residence = Residence.new({"date_of_birth(3i)"=>"1", "date_of_birth(2i)"=>"1", "date_of_birth(1i)"=>"1980"})
+ expect(residence.errors[:date_of_birth].size).to eq(0)
+ end
+
+ it "should not be valid without a date of birth" do
+ residence = Residence.new({"date_of_birth(3i)"=>"", "date_of_birth(2i)"=>"", "date_of_birth(1i)"=>""})
+ residence.valid?
+ expect(residence.errors[:date_of_birth]).to include("can't be blank")
+ end
+ end
+
+ it "should validate uniquness of document_number" do
+ user = create(:user)
+ residence.user = user
+ residence.save
+
+ residence2 = build(:residence)
+
+ residence.valid?
+ expect(residence.errors[:document_number]).to include("Already in use")
+ end
+ end
+
+ describe "save" do
+
+ it "should store document number and type" do
+ user = create(:user)
+ residence.user = user
+ residence.save
+
+ user.reload
+ expect(user.document_number).to eq('12345678Z')
+ expect(user.document_type).to eq("1")
+ end
+
+ end
+
+end
\ No newline at end of file
diff --git a/spec/models/sms_spec.rb b/spec/models/sms_spec.rb
new file mode 100644
index 000000000..bdcd2d739
--- /dev/null
+++ b/spec/models/sms_spec.rb
@@ -0,0 +1,15 @@
+require 'rails_helper'
+
+describe Sms do
+ it "should be valid" do
+ sms = build(:sms)
+ expect(sms).to be_valid
+ end
+
+ it "should validate uniqness of phone" do
+ user = create(:user, confirmed_phone: "699999999")
+ sms = Sms.new(phone: "699999999")
+ expect(sms).to_not be_valid
+ end
+
+end
\ No newline at end of file
diff --git a/spec/support/common_actions.rb b/spec/support/common_actions.rb
index 12d6affd3..591e0cebd 100644
--- a/spec/support/common_actions.rb
+++ b/spec/support/common_actions.rb
@@ -80,4 +80,12 @@ module CommonActions
def expect_to_be_signed_in
expect(find('.top-bar')).to have_content 'My account'
end
+
+ def select_date(values, selector)
+ selector = selector[:from]
+ day, month, year = values.split("-")
+ select day, from: "#{selector}_3i"
+ select month, from: "#{selector}_2i"
+ select year, from: "#{selector}_1i"
+ end
end