|
1 | 1 | # frozen_string_literal: true |
2 | 2 |
|
3 | | -describe TwoFactorAuthenticationsController, :type => :controller do |
| 3 | +describe TwoFactorAuthenticationsController, type: :controller do |
4 | 4 | before do |
5 | | - sign_in alice |
| 5 | + @user = FactoryGirl.create :user |
| 6 | + sign_in @user |
6 | 7 | end |
7 | 8 |
|
8 | 9 | describe "#show" do |
9 | | - it "shows the current state of 2fa" do |
| 10 | + it "shows the deactivated state of 2fa" do |
10 | 11 | get :show |
11 | | - expect(response.body).to match I18n.t('two_factor_auth.title') |
12 | | - expect(response.body).to match I18n.t('two_factor_auth.deactivated.status') |
| 12 | + expect(response.body).to match I18n.t("two_factor_auth.title") |
| 13 | + expect(response.body).to match I18n.t("two_factor_auth.deactivated.status") |
| 14 | + expect(@user).to have_attributes(otp_required_for_login: nil) |
| 15 | + end |
| 16 | + |
| 17 | + it "shows the activated state of 2fa" do |
| 18 | + activate_2fa |
| 19 | + get :show |
| 20 | + expect(response.body).to match I18n.t("two_factor_auth.title") |
| 21 | + expect(response.body).to match I18n.t("two_factor_auth.activated.status") |
| 22 | + expect(response.body).to match I18n.t("two_factor_auth.input_token.label") |
| 23 | + expect(response.body).to match I18n.t("two_factor_auth.recovery.button") |
| 24 | + expect(@user).to have_attributes(otp_required_for_login: true) |
13 | 25 | end |
14 | 26 | end |
15 | 27 |
|
16 | 28 | describe "#create" do |
17 | | - it "it starts the 2fa activation workflow" do |
| 29 | + it "sets the otp_secret flag" do |
18 | 30 | post :create, params: {user: {otp_required_for_login: "true"}} |
19 | 31 | expect(response).to be_redirect |
20 | 32 | expect(response.location).to match confirm_two_factor_authentication_path |
21 | 33 | end |
22 | 34 | end |
23 | 35 |
|
24 | | - describe "#confirm_2fa" |
| 36 | + describe "#confirm_2fa" do |
| 37 | + before do |
| 38 | + create_otp_token |
| 39 | + end |
| 40 | + it "shows the QR verification code" do |
| 41 | + get :confirm_2fa |
| 42 | + expect(response.body).to match I18n.t("two_factor_auth.confirm.title") |
| 43 | + expect(response.body).to include("svg") |
| 44 | + expect(response.body).to match(/#{@user.otp_secret.scan(/.{4}/).join(" ")}/) |
| 45 | + expect(response.body).to match I18n.t("two_factor_auth.input_token.label") |
| 46 | + end |
| 47 | + end |
25 | 48 |
|
26 | | - describe "#confirm_and_activate_2fa" |
| 49 | + describe "#confirm_and_activate_2fa" do |
| 50 | + before do |
| 51 | + create_otp_token |
| 52 | + end |
| 53 | + it "redirects back to confirm when token was wrong" do |
| 54 | + post :confirm_and_activate_2fa, params: {user: {code: "not valid token"}} |
| 55 | + expect(response.location).to match confirm_two_factor_authentication_path |
| 56 | + expect(flash[:alert]).to match I18n.t("two_factor_auth.flash.error_token") |
| 57 | + end |
| 58 | + it "redirects to #recovery_codes when token was correct" do |
| 59 | + post :confirm_and_activate_2fa, params: {user: {code: @user.current_otp}} |
| 60 | + expect(response.location).to match recovery_codes_two_factor_authentication_path |
| 61 | + expect(flash[:notice]).to match I18n.t("two_factor_auth.flash.success_activation") |
| 62 | + end |
| 63 | + end |
27 | 64 |
|
28 | | - describe "recovery_codes" |
| 65 | + describe "#recovery_codes" do |
| 66 | + before do |
| 67 | + activate_2fa |
| 68 | + end |
| 69 | + it "shows recovery codes page" do |
| 70 | + get :recovery_codes |
| 71 | + expect(response.body).to match I18n.t("two_factor_auth.recovery.title") |
| 72 | + expect(@user).to have_attributes(otp_required_for_login: true) |
| 73 | + end |
| 74 | + end |
29 | 75 |
|
30 | | - describe "#destroy" |
| 76 | + describe "#destroy" do |
| 77 | + before do |
| 78 | + activate_2fa |
| 79 | + end |
| 80 | + it "deactivates 2fa if token is correct" do |
| 81 | + delete :destroy, params: {two_factor_authentication: {code: @user.current_otp}} |
| 82 | + expect(response).to be_redirect |
| 83 | + expect(flash[:notice]).to match I18n.t("two_factor_auth.flash.success_deactivation") |
| 84 | + end |
| 85 | + |
| 86 | + it "does nothing if token is wrong" do |
| 87 | + delete :destroy, params: {two_factor_authentication: {code: "a wrong code"}} |
| 88 | + expect(response).to be_redirect |
| 89 | + expect(flash[:alert]).to match I18n.t("two_factor_auth.flash.error_token") |
| 90 | + end |
| 91 | + end |
| 92 | + |
| 93 | + def create_otp_token |
| 94 | + @user.otp_secret = User.generate_otp_secret(32) |
| 95 | + @user.save! |
| 96 | + end |
| 97 | + |
| 98 | + def confirm_activation |
| 99 | + @user.otp_required_for_login = true |
| 100 | + @user.save! |
| 101 | + end |
| 102 | + |
| 103 | + def activate_2fa |
| 104 | + create_otp_token |
| 105 | + confirm_activation |
| 106 | + end |
31 | 107 | end |
0 commit comments