summaryrefslogtreecommitdiffstats
path: root/spec/requests/omniauth_callbacks_spec.rb
blob: 27aa5ec506db43e48c132a4a3fae023f4c83d6ca (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
# frozen_string_literal: true

require 'rails_helper'

describe 'OmniAuth callbacks' do
  shared_examples 'omniauth provider callbacks' do |provider|
    subject { post send "user_#{provider}_omniauth_callback_path" }

    context 'with full information in response' do
      before do
        mock_omniauth(provider, {
          provider: provider.to_s,
          uid: '123',
          info: {
            verified: 'true',
            email: 'user@host.example',
          },
        })
      end

      context 'without a matching user' do
        it 'creates a user and an identity and redirects to root path' do
          expect { subject }
            .to change(User, :count)
            .by(1)
            .and change(Identity, :count)
            .by(1)
            .and change(LoginActivity, :count)
            .by(1)

          expect(User.last.email).to eq('user@host.example')
          expect(Identity.find_by(user: User.last).uid).to eq('123')
          expect(response).to redirect_to(root_path)
        end
      end

      context 'with a matching user and no matching identity' do
        before do
          Fabricate(:user, email: 'user@host.example')
        end

        it 'matches the existing user, creates an identity, and redirects to root path' do
          expect { subject }
            .to not_change(User, :count)
            .and change(Identity, :count)
            .by(1)
            .and change(LoginActivity, :count)
            .by(1)

          expect(Identity.find_by(user: User.last).uid).to eq('123')
          expect(response).to redirect_to(root_path)
        end
      end

      context 'with a matching user and a matching identity' do
        before do
          user = Fabricate(:user, email: 'user@host.example')
          Fabricate(:identity, user: user, uid: '123', provider: provider)
        end

        it 'matches the existing records and redirects to root path' do
          expect { subject }
            .to not_change(User, :count)
            .and not_change(Identity, :count)
            .and change(LoginActivity, :count)
            .by(1)

          expect(response).to redirect_to(root_path)
        end
      end
    end

    context 'with a response missing email address' do
      before do
        mock_omniauth(provider, {
          provider: provider.to_s,
          uid: '123',
          info: {
            verified: 'true',
          },
        })
      end

      it 'redirects to the auth setup page' do
        expect { subject }
          .to change(User, :count)
          .by(1)
          .and change(Identity, :count)
          .by(1)
          .and change(LoginActivity, :count)
          .by(1)

        expect(response).to redirect_to(auth_setup_path(missing_email: '1'))
      end
    end

    context 'when a user cannot be built' do
      before do
        allow(User).to receive(:find_for_oauth).and_return(User.new)
      end

      it 'redirects to the new user signup page' do
        expect { subject }
          .to not_change(User, :count)
          .and not_change(Identity, :count)
          .and not_change(LoginActivity, :count)

        expect(response).to redirect_to(new_user_registration_url)
      end
    end
  end

  describe '#openid_connect', if: ENV['OIDC_ENABLED'] == 'true' && ENV['OIDC_SCOPE'].present? do
    include_examples 'omniauth provider callbacks', :openid_connect
  end

  describe '#cas', if: ENV['CAS_ENABLED'] == 'true' do
    include_examples 'omniauth provider callbacks', :cas
  end

  describe '#saml', if: ENV['SAML_ENABLED'] == 'true' do
    include_examples 'omniauth provider callbacks', :saml
  end
end