简体   繁体   中英

RSPEC: How to test that a JSON Web Token is returned by controller action

I am using Devise and JWT's to authenticate users in a project I am writing. I am having a hard time figuring out how to write a useful test to expect a JWT response.body (since each is encrypted).

The only thing I can think of is to test that they are structured as a JWT should be (a 3 segment, '.' delimited string).

Has anyone encountered testing random/hashed returns and come up with a better solution?

describe SessionTokensController, type: :controller do
  let(:current_user) { FactoryGirl.create(:user) }

  before(:each) do
    sign_in current_user
  end

  describe '#create' do
    it 'responds with a JWT' do
      post :create
      token = JSON.parse(response.body)['token']

      expect(token).to be_kind_of(String)
      segments = token.split('.')
      expect(segments.size).to eql(3)
    end
  end
end

It really depends on what exactly you want to test.

If you simply want to test if the returned token exists and is valid you can do the following:

it 'responds with a valid JWT' do
  post :create
  token = JSON.parse(response.body)['token']

  expect { JWT.decode(token, key) }.to_not raise_error(JWT::DecodeError)
end

Although it seems much more useful to validate the claims that the token includes:

let(:claims) { JWT.decode(JSON.parse(response.body)['token'], key) }

it 'returns a JWT with valid claims' do
  post :create
  expect(claims['user_id']).to eq(123)
end

In the latter example you can validate the exact claims you included in the JWT.

    let(:user) { create(:user, password: "123456") }

      describe "POST authenticate_user" do
        context "with a valid password" do
          it "authenticates successfully" do
            post :authenticate_user, params:{email: user.email, password: "123456"}, format: :json
            parsed_body = JSON.parse(response.body)
            # binding.pry
            expect(parsed_body.keys).to match_array(["auth_token", "user"])
            expect(parsed_body['user']['email']).to eql("joe@gmail.com")
            expect(parsed_body['user']['id']).to eql(user.id)
          end

          it "authentication fails" do
            post :authenticate_user, params:{email: user.email, password: "123456789"}, format: :json
            parsed_body = JSON.parse(response.body)
            expect(parsed_body['errors'][0]).to eql("Invalid Username/Password")
          end
        end
      end

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM