about summary refs log tree commit diff
path: root/spec/controllers/settings/identity_proofs_controller_spec.rb
blob: 16f2362278ac706ab1e28e461c165768ac04f04c (plain) (blame)
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
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
require 'rails_helper'

describe Settings::IdentityProofsController do
  include RoutingHelper
  render_views

  let(:user) { Fabricate(:user) }
  let(:valid_token) { '1'*66 }
  let(:kbname) { 'kbuser' }
  let(:provider) { 'keybase' }
  let(:findable_id) { Faker::Number.number(digits: 5) }
  let(:unfindable_id) { Faker::Number.number(digits: 5) }
  let(:new_proof_params) do
    { provider: provider, provider_username: kbname, token: valid_token, username: user.account.username }
  end
  let(:status_text) { "i just proved that i am also #{kbname} on #{provider}." }
  let(:status_posting_params) do
    { post_status: '0', status_text: status_text }
  end
  let(:postable_params) do
    { account_identity_proof: new_proof_params.merge(status_posting_params) }
  end

  before do
    allow_any_instance_of(ProofProvider::Keybase::Verifier).to receive(:status) { { 'proof_valid' => true, 'proof_live' => true } }
    sign_in user, scope: :user
  end

  describe 'new proof creation' do
    context 'GET #new' do
      before do
        allow_any_instance_of(ProofProvider::Keybase::Badge).to receive(:avatar_url) { full_pack_url('media/images/void.png') }
      end

      context 'with all of the correct params' do
        it 'renders the template' do
          get :new, params: new_proof_params
          expect(response).to render_template(:new)
        end
      end

      context 'without any params' do
        it 'redirects to :index' do
          get :new, params: {}
          expect(response).to redirect_to settings_identity_proofs_path
        end
      end

      context 'with params to prove a different, not logged-in user' do
        let(:wrong_user_params) { new_proof_params.merge(username: 'someone_else') }

        it 'shows a helpful alert' do
          get :new, params: wrong_user_params
          expect(flash[:alert]).to eq I18n.t('identity_proofs.errors.wrong_user', proving: 'someone_else', current: user.account.username)
        end
      end

      context 'with params to prove the same username cased differently' do
        let(:capitalized_username) { new_proof_params.merge(username: user.account.username.upcase) }

        it 'renders the new template' do
          get :new, params: capitalized_username
          expect(response).to render_template(:new)
        end
      end
    end

    context 'POST #create' do
      context 'when saving works' do
        before do
          allow(ProofProvider::Keybase::Worker).to receive(:perform_async)
          allow_any_instance_of(ProofProvider::Keybase::Verifier).to receive(:valid?) { true }
          allow_any_instance_of(AccountIdentityProof).to receive(:on_success_path) { root_url }
        end

        it 'serializes a ProofProvider::Keybase::Worker' do
          expect(ProofProvider::Keybase::Worker).to receive(:perform_async)
          post :create, params: postable_params
        end

        it 'delegates redirection to the proof provider' do
          expect_any_instance_of(AccountIdentityProof).to receive(:on_success_path)
          post :create, params: postable_params
          expect(response).to redirect_to root_url
        end

        it 'does not post a status' do
          expect(PostStatusService).not_to receive(:new)
          post :create, params: postable_params
        end

        context 'and the user has requested to post a status' do
          let(:postable_params_with_status) do
            postable_params.tap { |p| p[:account_identity_proof][:post_status] = '1' }
          end

          it 'posts a status' do
            expect_any_instance_of(PostStatusService).to receive(:call).with(user.account, text: status_text)

            post :create, params: postable_params_with_status
          end
        end
      end

      context 'when saving fails' do
        before do
          allow_any_instance_of(ProofProvider::Keybase::Verifier).to receive(:valid?) { false }
        end

        it 'redirects to :index' do
          post :create, params: postable_params
          expect(response).to redirect_to settings_identity_proofs_path
        end

        it 'flashes a helpful message' do
          post :create, params: postable_params
          expect(flash[:alert]).to eq I18n.t('identity_proofs.errors.failed', provider: 'Keybase')
        end
      end

      context 'it can also do an update if the provider and username match an existing proof' do
        before do
          allow_any_instance_of(ProofProvider::Keybase::Verifier).to receive(:valid?) { true }
          allow(ProofProvider::Keybase::Worker).to receive(:perform_async)
          Fabricate(:account_identity_proof, account: user.account, provider: provider, provider_username: kbname)
          allow_any_instance_of(AccountIdentityProof).to receive(:on_success_path) { root_url }
        end

        it 'calls update with the new token' do
          expect_any_instance_of(AccountIdentityProof).to receive(:save) do |proof|
            expect(proof.token).to eq valid_token
          end

          post :create, params: postable_params
        end
      end
    end
  end

  describe 'GET #index' do
    context 'with no existing proofs' do
      it 'shows the helpful explanation' do
        get :index
        expect(response.body).to match I18n.t('identity_proofs.explanation_html')
      end
    end

    context 'with two proofs' do
      before do
        allow_any_instance_of(ProofProvider::Keybase::Verifier).to receive(:valid?) { true }
        @proof1 = Fabricate(:account_identity_proof, account: user.account)
        @proof2 = Fabricate(:account_identity_proof, account: user.account)
        allow_any_instance_of(AccountIdentityProof).to receive(:badge) { double(avatar_url: '', profile_url: '', proof_url: '') }
        allow_any_instance_of(AccountIdentityProof).to receive(:refresh!) {}
      end

      it 'has the first proof username on the page' do
        get :index
        expect(response.body).to match /#{Regexp.quote(@proof1.provider_username)}/
      end

      it 'has the second proof username on the page' do
        get :index
        expect(response.body).to match /#{Regexp.quote(@proof2.provider_username)}/
      end
    end
  end

  describe 'DELETE #destroy' do
    before do
      allow_any_instance_of(ProofProvider::Keybase::Verifier).to receive(:valid?) { true }
      @proof1 = Fabricate(:account_identity_proof, account: user.account)
      allow_any_instance_of(AccountIdentityProof).to receive(:badge) { double(avatar_url: '', profile_url: '', proof_url: '') }
      allow_any_instance_of(AccountIdentityProof).to receive(:refresh!) {}
      delete :destroy, params: { id: @proof1.id }
    end

    it 'redirects to :index' do
      expect(response).to redirect_to settings_identity_proofs_path
    end

    it 'removes the proof' do
      expect(AccountIdentityProof.where(id: @proof1.id).count).to eq 0
    end
  end
end