diff --git a/app/models/concerns/verification.rb b/app/models/concerns/verification.rb index 01d660012..3520e5b31 100644 --- a/app/models/concerns/verification.rb +++ b/app/models/concerns/verification.rb @@ -2,6 +2,7 @@ module Verification extend ActiveSupport::Concern included do + scope :residence_verified, -> { where.not(residence_verified_at: nil) } scope :level_three_verified, -> { where.not(verified_at: nil) } scope :level_two_verified, -> { where("users.level_two_verified_at IS NOT NULL OR (users.confirmed_phone IS NOT NULL AND users.residence_verified_at IS NOT NULL) AND verified_at IS NULL") } scope :level_two_or_three_verified, -> { where("users.verified_at IS NOT NULL OR users.level_two_verified_at IS NOT NULL OR (users.confirmed_phone IS NOT NULL AND users.residence_verified_at IS NOT NULL)") } diff --git a/app/models/user.rb b/app/models/user.rb index 2daa64ec2..cf96a69cf 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -22,6 +22,7 @@ class User < ActiveRecord::Base has_many :comments, -> { with_hidden } has_many :failed_census_calls has_many :notifications + belongs_to :geozone validates :username, presence: true, if: :username_required? validates :username, uniqueness: true, if: :username_required? diff --git a/app/models/verification/residence.rb b/app/models/verification/residence.rb index 355ba8225..243bbd85e 100644 --- a/app/models/verification/residence.rb +++ b/app/models/verification/residence.rb @@ -1,15 +1,17 @@ class Verification::Residence include ActiveModel::Model include ActiveModel::Dates + include ActiveModel::Validations::Callbacks attr_accessor :user, :document_number, :document_type, :date_of_birth, :postal_code, :terms_of_service + before_validation :call_census_api + validates_presence_of :document_number validates_presence_of :document_type validates_presence_of :date_of_birth validates_presence_of :postal_code validates :terms_of_service, acceptance: { allow_nil: false } - validates :postal_code, length: { is: 5 } validate :allowed_age @@ -28,6 +30,7 @@ class Verification::Residence return false unless valid? user.update(document_number: document_number, document_type: document_type, + geozone: self.geozone, residence_verified_at: Time.now) end @@ -60,18 +63,29 @@ class Verification::Residence document_number: document_number, document_type: document_type, date_of_birth: date_of_birth, - postal_code: postal_code + postal_code: postal_code, + district_code: district_code }) end + def geozone + Geozone.where(census_code: district_code).first + end + + def district_code + @census_api_response.district_code + end + private - def residency_valid? - response = CensusApi.new.call(document_type, document_number) + def call_census_api + @census_api_response = CensusApi.new.call(document_type, document_number) + end - response.valid? && - response.postal_code == postal_code && - response.date_of_birth == date_to_string(date_of_birth) + def residency_valid? + @census_api_response.valid? && + @census_api_response.postal_code == postal_code && + @census_api_response.date_of_birth == date_to_string(date_of_birth) end def clean_document_number diff --git a/db/migrate/20160218164923_add_geozone_id_to_users.rb b/db/migrate/20160218164923_add_geozone_id_to_users.rb new file mode 100644 index 000000000..162a28653 --- /dev/null +++ b/db/migrate/20160218164923_add_geozone_id_to_users.rb @@ -0,0 +1,5 @@ +class AddGeozoneIdToUsers < ActiveRecord::Migration + def change + add_reference :users, :geozone, index: true, foreign_key: true + end +end diff --git a/db/migrate/20160218172620_add_census_code_to_geozones.rb b/db/migrate/20160218172620_add_census_code_to_geozones.rb new file mode 100644 index 000000000..616518253 --- /dev/null +++ b/db/migrate/20160218172620_add_census_code_to_geozones.rb @@ -0,0 +1,5 @@ +class AddCensusCodeToGeozones < ActiveRecord::Migration + def change + add_column :geozones, :census_code, :string + end +end diff --git a/db/migrate/20160219111057_add_district_code_to_failed_census_call.rb b/db/migrate/20160219111057_add_district_code_to_failed_census_call.rb new file mode 100644 index 000000000..6e10dcd26 --- /dev/null +++ b/db/migrate/20160219111057_add_district_code_to_failed_census_call.rb @@ -0,0 +1,5 @@ +class AddDistrictCodeToFailedCensusCall < ActiveRecord::Migration + def change + add_column :failed_census_calls, :district_code, :string + end +end diff --git a/db/schema.rb b/db/schema.rb index 5b3a8831e..a914e6485 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -11,7 +11,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 20160217101004) do +ActiveRecord::Schema.define(version: 20160219111057) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -161,6 +161,7 @@ ActiveRecord::Schema.define(version: 20160217101004) do t.string "postal_code" t.datetime "created_at", null: false t.datetime "updated_at", null: false + t.string "district_code" end add_index "failed_census_calls", ["user_id"], name: "index_failed_census_calls_on_user_id", using: :btree @@ -183,6 +184,7 @@ ActiveRecord::Schema.define(version: 20160217101004) do t.string "external_code" t.datetime "created_at", null: false t.datetime "updated_at", null: false + t.string "census_code" end create_table "identities", force: :cascade do |t| @@ -408,10 +410,12 @@ ActiveRecord::Schema.define(version: 20160217101004) do t.boolean "registering_with_oauth", default: false t.string "locale" t.string "oauth_email" + t.integer "geozone_id" end add_index "users", ["confirmation_token"], name: "index_users_on_confirmation_token", unique: true, using: :btree add_index "users", ["email"], name: "index_users_on_email", unique: true, using: :btree + add_index "users", ["geozone_id"], name: "index_users_on_geozone_id", using: :btree add_index "users", ["hidden_at"], name: "index_users_on_hidden_at", using: :btree add_index "users", ["reset_password_token"], name: "index_users_on_reset_password_token", unique: true, using: :btree @@ -491,4 +495,5 @@ ActiveRecord::Schema.define(version: 20160217101004) do add_foreign_key "notifications", "users" add_foreign_key "organizations", "users" add_foreign_key "valuators", "users" + add_foreign_key "users", "geozones" end diff --git a/lib/census_api.rb b/lib/census_api.rb index 559a6388e..737f7f873 100644 --- a/lib/census_api.rb +++ b/lib/census_api.rb @@ -45,6 +45,10 @@ class CensusApi data[:datos_vivienda][:item][:codigo_postal] end + def district_code + data[:datos_vivienda][:item][:codigo_distrito] + end + private def data @@ -82,7 +86,7 @@ class CensusApi end def stubbed_response_body - {: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"}}}}} + {: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", :codigo_distrito=>"01"}}}}} end def is_dni?(document_type) diff --git a/lib/tasks/users.rake b/lib/tasks/users.rake index 1094f329b..1ad90a3a6 100644 --- a/lib/tasks/users.rake +++ b/lib/tasks/users.rake @@ -4,7 +4,7 @@ namespace :users do task count_failed_census_calls: :environment do User.find_each{ |user| User.reset_counters(user.id, :failed_census_calls)} end - + desc "Assigns official level to users with the officials' email domain" task check_for_official_emails: :environment do domain = Setting['email_domain_for_officials'] @@ -22,4 +22,19 @@ namespace :users do end end + desc "Associates a geozone to each user who doesn't have it already but has validated his residence using the census API" + task assign_geozones: :environment do + User.residence_verified.where(geozone_id: nil).find_each do |u| + response = CensusApi.new.call(u.document_type, u.document_number) + if response.valid? + u.geozone = Geozone.where(census_code: response.district_code).first + u.save + print "." + else + print "X" + end + end + end + + end diff --git a/spec/factories.rb b/spec/factories.rb index 52abc82cc..0e5831556 100644 --- a/spec/factories.rb +++ b/spec/factories.rb @@ -308,5 +308,6 @@ FactoryGirl.define do factory :geozone do sequence(:name) { |n| "District #{n}" } + census_code { '01' } end end diff --git a/spec/features/admin/stats_spec.rb b/spec/features/admin/stats_spec.rb index a7bb64f58..461f7ef32 100644 --- a/spec/features/admin/stats_spec.rb +++ b/spec/features/admin/stats_spec.rb @@ -59,6 +59,7 @@ feature 'Stats' do end scenario 'Level 2 user' do + create(:geozone) visit account_path click_link 'Verify my account' verify_residence diff --git a/spec/features/verification/level_three_verification_spec.rb b/spec/features/verification/level_three_verification_spec.rb index 9a1cfaa6e..419facf3a 100644 --- a/spec/features/verification/level_three_verification_spec.rb +++ b/spec/features/verification/level_three_verification_spec.rb @@ -2,6 +2,7 @@ require 'rails_helper' feature 'Level three verification' do scenario 'Verification with residency and verified sms' do + create(:geozone) user = create(:user) verified_user = create(:verified_user, @@ -33,6 +34,7 @@ feature 'Level three verification' do end scenario 'Verification with residency and verified email' do + create(:geozone) user = create(:user) verified_user = create(:verified_user, @@ -63,7 +65,7 @@ feature 'Level three verification' do end scenario 'Verification with residency and sms and letter' do - + create(:geozone) user = create(:user) login_as(user) @@ -87,4 +89,4 @@ feature 'Level three verification' do expect(page).to have_content "Thank you for requesting your maximum security code (only required for the final votes). In a few days we will send it to the address featuring in the data we have on file." end -end \ No newline at end of file +end diff --git a/spec/features/verification/level_two_verification_spec.rb b/spec/features/verification/level_two_verification_spec.rb index e0374825f..64673f82c 100644 --- a/spec/features/verification/level_two_verification_spec.rb +++ b/spec/features/verification/level_two_verification_spec.rb @@ -3,6 +3,7 @@ require 'rails_helper' feature 'Level two verification' do scenario 'Verification with residency and sms' do + create(:geozone) user = create(:user) login_as(user) @@ -23,4 +24,4 @@ feature 'Level two verification' do expect(page).to have_content 'Code correct' end -end \ No newline at end of file +end diff --git a/spec/features/verification/residence_spec.rb b/spec/features/verification/residence_spec.rb index 447438472..1961269da 100644 --- a/spec/features/verification/residence_spec.rb +++ b/spec/features/verification/residence_spec.rb @@ -2,6 +2,8 @@ require 'rails_helper' feature 'Residence' do + background { create(:geozone) } + scenario 'Verify resident in Madrid' do user = create(:user) login_as(user) @@ -100,4 +102,4 @@ feature 'Residence' do expect(page).to have_content "You have reached the maximum number of attempts. Please try again later." expect(current_path).to eq(account_path) end -end \ No newline at end of file +end diff --git a/spec/models/residence_spec.rb b/spec/models/residence_spec.rb index 33f339012..13cce2b1b 100644 --- a/spec/models/residence_spec.rb +++ b/spec/models/residence_spec.rb @@ -2,6 +2,7 @@ require 'rails_helper' describe Verification::Residence do + let!(:geozone) { create(:geozone, census_code: "01") } let(:residence) { build(:verification_residence, document_number: "12345678Z") } describe "validations" do @@ -84,7 +85,7 @@ describe Verification::Residence do describe "save" do - it "should store document number and type" do + it "should store document number, document type, and geozone" do user = create(:user) residence.user = user residence.save @@ -92,6 +93,7 @@ describe Verification::Residence do user.reload expect(user.document_number).to eq('12345678Z') expect(user.document_type).to eq("1") + expect(user.geozone).to eq(geozone) end end @@ -121,7 +123,8 @@ describe Verification::Residence do document_number: "12345678Z", document_type: "1", date_of_birth: Date.new(1980, 12, 31), - postal_code: "28001" + postal_code: "28001", + district_code: "01" }) end end