I have an API that accepts a JWT bearer token. Expected results:
| token description | status | message, if any | 
|---|---|---|
| valid token | 200 | |
| corrupt token | 400 | Your JWT appears to be invalid | 
| no token | 401 | Did not receive auth token | 
| valid but unauth | 401 | You can't do that | 
My thinking is that in the past, I have worked on APIs where I wasn't sure if my auth was even getting through... am I using the wrong key for this token? So I let the user know "I got your token, but it's not right."
Here's the issue: Using rswag, I can't figure out how to test both sending an auth token and NOT sending an auth token.
# frozen_string_literal: true
require 'rails_helper'
RSpec.configure do |config|
  # Specify a root folder where Swagger JSON files are generated
  # NOTE: If you're using the rswag-api to serve API descriptions, you'll need
  # to ensure that it's configured to serve Swagger from the same folder
  config.swagger_root = Rails.root.join('swagger').to_s
  # Define one or more Swagger documents and provide global metadata for each one
  # When you run the 'rswag:specs:swaggerize' rake task, the complete Swagger will
  # be generated at the provided relative path under swagger_root
  # By default, the operations defined in spec files are added to the first
  # document below. You can override this behavior by adding a swagger_doc tag to the
  # the root example_group in your specs, e.g. describe '...', swagger_doc: 'v2/swagger.json'
  config.swagger_docs = {
    'v1/swagger.yaml' => {
      openapi: '3.0.1',
      info: {
        title: 'My API',
        version: 'v1'
      },
      paths: {},
      servers: [
        {
          url: 'https://{defaultHost}',
          variables: {
            defaultHost: {
              default: 'www.example.com'
            }
          }
        }
      ],
      components: {
        securitySchemes: {
          AuthToken: {
            type: :http, scheme: :bearer, bearerFormat: JWT
          }
        }
      },
      security: [ { AuthToken: [] } ]
    }
  }
  # Specify the format of the output Swagger file when running 'rswag:specs:swaggerize'.
  # The swagger_docs configuration option has the filename including format in
  # the key, this may want to be changed to avoid putting yaml in json files.
  # Defaults to json. Accepts ':json' and ':yaml'.
  config.swagger_format = :yaml
end
the test:
RSpec.describe 'api/v1/unicorns', type: :request do
  path '/unicorns.json' do
    let(:user) { create(:perceptyx_owner) }
    let(:account) { create(:account, owners: [user]) }
    get 'retrieves a list of accessible unicorns' do
      tags 'unicorns'
      produces 'application/vnd.api+json'
      security [ {AuthToken: [], NoAuth: []} ]
      response '200', 'properly authenticated request' do
        let(:Authorization) { JWT.encode({ auth: { user_id: user.pyx_user_id } }, nil, 'none') }
        run_test!
      end
      response '400', 'malformatted auth token' do
        let(:Authorization) { 'AAABBBCCCDDDDEEE-invalid' }
        run_test!
      end
      response '401', 'no authentication' do
        # it's not clear how you would run a test that did
        # not include a bearer token header -- this tests results
        # in "undefined method `Authorization'"
 
        run_test!
      end
    end
  end
end
I thought about using another securityScheme list here setting up a secondary authorization like ApiKeyAuth, which my app would ignore. But when I try to set security in the test, rather than as a default, it seems to apply to every test within the "path", not the individual "response".
I also tried setting "Authorization" to nil... but obviously that sent a key with no value. Which isn't the same thing.
Can this be done? How? I haven't gotten to the step of seeing this in the documentation yet but any clues about what I can do to set myself up for success there would be appreciated -- though not part of this question. :)
 
                        
Try setting Authorization to nil.