From 7e98bcd57ccaa31c8f40c93c1a2ec7dd74a04c77 Mon Sep 17 00:00:00 2001 From: Sina Eftekhar Date: Mon, 25 Sep 2023 17:41:48 +0300 Subject: [PATCH] Add tests for signing in with access code --- .../decidim/helsinki_smsauth/signin_code.rb | 2 +- .../helsinki_smsauth/test/factories.rb | 10 +++- spec/shared/shared_context.rb | 12 ++++ spec/spec_helper.rb | 23 ++++++++ spec/system/log_in_with_access_code_spec.rb | 55 +++++++++++++++++++ 5 files changed, 100 insertions(+), 2 deletions(-) create mode 100644 spec/system/log_in_with_access_code_spec.rb diff --git a/app/models/decidim/helsinki_smsauth/signin_code.rb b/app/models/decidim/helsinki_smsauth/signin_code.rb index 61b1d60..326a413 100644 --- a/app/models/decidim/helsinki_smsauth/signin_code.rb +++ b/app/models/decidim/helsinki_smsauth/signin_code.rb @@ -6,7 +6,7 @@ class SigninCode < ApplicationRecord belongs_to :signin_code_set, foreign_key: "decidim_signin_code_set_id", class_name: "::Decidim::HelsinkiSmsauth::SigninCodeSet" validates :code_hash, uniqueness: true, if: -> { code_hash.present? } - before_save :generate! + before_create :generate! after_destroy :increment_used_codes # generate method should be public, since it should be accessible by GenerateAccessCode diff --git a/lib/decidim/helsinki_smsauth/test/factories.rb b/lib/decidim/helsinki_smsauth/test/factories.rb index 1126928..41c0f9e 100644 --- a/lib/decidim/helsinki_smsauth/test/factories.rb +++ b/lib/decidim/helsinki_smsauth/test/factories.rb @@ -8,7 +8,7 @@ generated_code_amount { 1 } metadata do { - school: Faker::Name.name, + school: Decidim::HelsinkiSmsauth::SchoolMetadata.school_options.map { |sc| sc[1] }.sample, grade: Faker::Number.between(from: 1, to: 6) } end @@ -19,6 +19,14 @@ end factory :signin_code, class: "Decidim::HelsinkiSmsauth::SigninCode" do + transient do + code { 10.times.map { (("0".."9").to_a + ("A".."Z").to_a).sample }.join } + end + signin_code_set { create(signin_code_set) } + + before(:create) do |signin_code, evaluator| + signin_code.code_hash = Digest::MD5.hexdigest("#{evaluator.code}-#{Rails.application.secrets.secret_key_base}") + end end end diff --git a/spec/shared/shared_context.rb b/spec/shared/shared_context.rb index c400ceb..7c6a57d 100644 --- a/spec/shared/shared_context.rb +++ b/spec/shared/shared_context.rb @@ -23,3 +23,15 @@ def initialize(phone_number, code, organization: nil, queued: false) allow_any_instance_of(dummy_class).to receive(:deliver_code).and_return(true) # rubocop:disable RSpec/AnyInstance end end + +shared_context "with single access code" do + let(:organization) { create(:organization) } + let!(:auth_metadata) { { school: "0004", grade: 1, phone_number: "+3584551122334" } } + let!(:creator) { create(:user, :confirmed, :admin, organization: organization) } + + let!(:signin_code_set) { create(:signin_code_set, creator: creator) } + + # before do + # allow_any_instance_of(::Decidim::HelsinkiSmsauth::SigninCode).to receive(:generate!).and_return { raise "CALLED " } # rubocop:disable RSpec/AnyInstance + # end +end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 720b39b..a657f1e 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -9,3 +9,26 @@ require "decidim/dev/test/base_spec_helper" require "decidim/helsinki_smsauth/test/spec_helper" + +RSpec.configure do |config| + config.before do + # Re-define the password validators due to a bug in the "email included" + # check which does not work well for domains such as "1.lvh.me" that we are + # using during tests. + PasswordValidator.send(:remove_const, :VALIDATION_METHODS) + PasswordValidator.const_set( + :VALIDATION_METHODS, + [ + :password_too_short?, + :password_too_long?, + :not_enough_unique_characters?, + :name_included_in_password?, + :nickname_included_in_password?, + # :email_included_in_password?, + :domain_included_in_password?, + :password_too_common?, + :blacklisted? + ].freeze + ) + end +end diff --git a/spec/system/log_in_with_access_code_spec.rb b/spec/system/log_in_with_access_code_spec.rb new file mode 100644 index 0000000..3eef677 --- /dev/null +++ b/spec/system/log_in_with_access_code_spec.rb @@ -0,0 +1,55 @@ +# frozen_string_literal: true + +require "spec_helper" + +describe "log in with access code", type: :system do + let!(:organization) { create(:organization) } + let(:access_code) { "ABCDE12345" } + let(:incorrect_code) { "FalseCode" } + + include_context "with single access code" + before do + switch_to_host(organization.host) + visit_helsinki_smsauth + click_link "Log in with a code given by your teacher" + end + + it "does not authenticate when incorrect code" do + fill_in "sms_verification[access_code]", with: incorrect_code + click_button "Log in" + within_flash_messages do + expect(page).to have_content("Failed to verify the access code. Make sure that you have entered the correct code and try again.") + end + expect(page).to have_current_path("/users/auth/sms/access_code_validation") + end + + context "when correct code" do + let!(:auth_metadata) { { school: "0004", grade: 1, phone_number: "+3584551122334" } } + let!(:creator) { create(:user, :confirmed, :admin, organization: organization) } + let!(:signin_code_set) { create(:signin_code_set, creator: creator) } + let!(:signin_code) { create(:signin_code, code: access_code, signin_code_set: signin_code_set) } + + it "creates users and signs in with correct code" do + expect(signin_code_set.used_code_amount).to eq(0) + + # digest = "#{access_code}-#{Rails.application.secrets.secret_key_base}" + # puts "TEST:digest is: #{digest} " + # puts "TEST: the code hash is:#{Digest::MD5.hexdigest(digest)}" + # puts "The access code is #{::Decidim::HelsinkiSmsauth::SigninCode.last.code_hash}" + + fill_in "sms_verification[access_code]", with: access_code + click_button "Log in" + expect(page).to have_content("Login successful.") + signin_code_set.reload + expect(signin_code_set.used_code_amount).to eq(1) + + expect(page).to have_current_path("/authorizations") + authorization = Decidim::Authorization.last + expect(authorization.metadata["school"]).to eq(signin_code_set.metadata["school"]) + expect(authorization.metadata["grade"]).to eq(signin_code_set.metadata["grade"]) + within_flash_messages do + expect(page).to have_content "Login successful" + end + end + end +end