diff --git a/CHANGELOG.md b/CHANGELOG.md index f084c97..aed1d80 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] ### Added ### Changed +- Update swagger-ui version to 3.23.11 [#239](https://github.com/rswag/rswag/pull/239) ### Deprecated ### Removed ### Fixed diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 65c7c47..84ae9df 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -55,6 +55,19 @@ Push to your fork and [submit a Pull Request][pr]. [pr]: https://github.com/rswag/rswag/compare/ +## Updating Swagger UI + +Find the latest versions of swagger-ui here: +https://github.com/swagger-api/swagger-ui/releases + +Update the swagger-ui-dist version in the rswag-ui dependencies +``` +./rswag-ui/package.json +``` + +Navigate to the rswag-ui folder and run npm install to update the package-lock.json + + ## Release (for maintainers) diff --git a/Gemfile b/Gemfile index c8d0b12..38bb3ad 100644 --- a/Gemfile +++ b/Gemfile @@ -27,9 +27,10 @@ gem 'rswag-ui', path: './rswag-ui' group :test do gem 'capybara' - gem 'capybara-webkit' + gem 'geckodriver-helper' gem 'generator_spec' gem 'rspec-rails' + gem 'selenium-webdriver' gem 'rswag-specs', path: './rswag-specs' gem 'test-unit' end diff --git a/README.md b/README.md index 3038a6a..11c452b 100644 --- a/README.md +++ b/README.md @@ -768,6 +768,21 @@ end Note how the filter is passed the rack env for the current request. This provides a lot of flexibilty. For example, you can assign the "host" property (as shown) or you could inspect session information or an Authorization header and remove operations based on user permissions. +### Custom Headers for Swagger Files ### + +You can specify custom headers for serving your generated Swagger JSON. For example you may want to force a specific charset for the 'Content-Type' header. You can configure a hash of headers to be sent with the request: + +```ruby +Rswag::Api.configure do |c| + ... + + c.swagger_headers = { 'Content-Type' => 'application/json; charset=UTF-8' } +end +``` + +Take care when overriding Content-Type if you serve both YAML and JSON files as it will no longer switch the Content-Type header correctly. + + ### Enable Swagger Endpoints for swagger-ui ### You can update the _rswag-ui.rb_ initializer, installed with rswag-ui, to specify which Swagger endpoints should be available to power the documentation UI. If you're using rswag-api, these should correspond to the Swagger endpoints it exposes. When the UI is rendered, you'll see these listed in a drop-down to the top right of the page: diff --git a/rswag-api/lib/rswag/api/configuration.rb b/rswag-api/lib/rswag/api/configuration.rb index ff56180..bf64229 100644 --- a/rswag-api/lib/rswag/api/configuration.rb +++ b/rswag-api/lib/rswag/api/configuration.rb @@ -1,7 +1,7 @@ module Rswag module Api class Configuration - attr_accessor :swagger_root, :swagger_filter + attr_accessor :swagger_root, :swagger_filter, :swagger_headers def resolve_swagger_root(env) path_params = env['action_dispatch.request.path_parameters'] || {} diff --git a/rswag-api/lib/rswag/api/middleware.rb b/rswag-api/lib/rswag/api/middleware.rb index 637d42d..77a3b01 100644 --- a/rswag-api/lib/rswag/api/middleware.rb +++ b/rswag-api/lib/rswag/api/middleware.rb @@ -19,11 +19,12 @@ module Rswag swagger = parse_file(filename) @config.swagger_filter.call(swagger, env) unless @config.swagger_filter.nil? mime = Rack::Mime.mime_type(::File.extname(path), 'text/plain') + headers = { 'Content-Type' => mime }.merge(@config.swagger_headers || {}) body = unload_swagger(filename, swagger) return [ '200', - { 'Content-Type' => mime }, + headers, [ body ] ] end diff --git a/rswag-api/spec/rswag/api/middleware_spec.rb b/rswag-api/spec/rswag/api/middleware_spec.rb index e8cc23a..6f90724 100644 --- a/rswag-api/spec/rswag/api/middleware_spec.rb +++ b/rswag-api/spec/rswag/api/middleware_spec.rb @@ -37,6 +37,42 @@ module Rswag end end + context 'when swagger_headers is configured' do + let(:env) { env_defaults.merge('PATH_INFO' => 'v1/swagger.json') } + + context 'replacing the default content type header' do + before do + config.swagger_headers = { 'Content-Type' => 'application/json; charset=UTF-8' } + end + it 'returns a 200 status' do + expect(response.length).to eql(3) + expect(response.first).to eql('200') + end + + it 'applies the headers to the response' do + expect(response[1]).to include( 'Content-Type' => 'application/json; charset=UTF-8') + end + end + + context 'adding an additional header' do + before do + config.swagger_headers = { 'Access-Control-Allow-Origin' => '*' } + end + it 'returns a 200 status' do + expect(response.length).to eql(3) + expect(response.first).to eql('200') + end + + it 'applies the headers to the response' do + expect(response[1]).to include( 'Access-Control-Allow-Origin' => '*') + end + + it 'keeps the default header' do + expect(response[1]).to include( 'Content-Type' => 'application/json') + end + end + end + context "given a path that doesn't map to any swagger file" do let(:env) { env_defaults.merge('PATH_INFO' => 'foobar.json') } before do diff --git a/rswag-ui/package-lock.json b/rswag-ui/package-lock.json index 144573b..8bc72e8 100644 --- a/rswag-ui/package-lock.json +++ b/rswag-ui/package-lock.json @@ -5,9 +5,9 @@ "requires": true, "dependencies": { "swagger-ui-dist": { - "version": "3.18.2", - "resolved": "https://registry.npmjs.org/swagger-ui-dist/-/swagger-ui-dist-3.18.2.tgz", - "integrity": "sha512-pWAEiKkgWUJvjmLW9AojudnutJ+NTn5g6OdNLj1iIJWwCkoy40K3Upwa24DqFbmIE4vLX4XplND61hp2L+s5vg==" + "version": "3.23.11", + "resolved": "https://registry.npmjs.org/swagger-ui-dist/-/swagger-ui-dist-3.23.11.tgz", + "integrity": "sha512-ipENHHH/sqpngTpHXUwg55eAOZ7b2UVayUwwuWPA6nQSPhjBVXX4zOPpNKUwQIFOl3oIwVvZF7mqoxH7pMgVzA==" } } } diff --git a/rswag-ui/package.json b/rswag-ui/package.json index 27dbc6c..fd299d1 100644 --- a/rswag-ui/package.json +++ b/rswag-ui/package.json @@ -3,6 +3,6 @@ "version": "1.0.0", "private": true, "dependencies": { - "swagger-ui-dist": "3.18.2" + "swagger-ui-dist": "3.23.11" } } diff --git a/test-app/db/schema.rb b/test-app/db/schema.rb index 440d919..e01f8f3 100644 --- a/test-app/db/schema.rb +++ b/test-app/db/schema.rb @@ -2,11 +2,11 @@ # of editing this file, please use the migrations feature of Active Record to # incrementally modify your database, and then regenerate this schema definition. # -# Note that this schema.rb definition is the authoritative source for your -# database schema. If you need to create the application database on another -# system, you should be using db:schema:load, not running all the migrations -# from scratch. The latter is a flawed and unsustainable approach (the more migrations -# you'll amass, the slower it'll run and the greater likelihood for issues). +# This file is the source Rails uses to define your schema when running `rails +# db:schema:load`. When creating a new database, `rails db:schema:load` tends to +# be faster and is potentially less error prone than running all of your +# migrations from scratch. Old migrations may fail to apply correctly if those +# migrations use external dependencies or application code. # # It's strongly recommended that you check this file into your version control system. diff --git a/test-app/spec/features/swagger_ui_spec.rb b/test-app/spec/features/swagger_ui_spec.rb index 24d5790..484ad65 100644 --- a/test-app/spec/features/swagger_ui_spec.rb +++ b/test-app/spec/features/swagger_ui_spec.rb @@ -5,8 +5,8 @@ RSpec.feature 'swagger-ui', js: true do scenario 'browsing api-docs' do visit '/api-docs' - expect(page).to have_content('GET /blogs Searches blogs') - expect(page).to have_content('POST /blogs Creates a blog') - expect(page).to have_content('GET /blogs/{id} Retrieves a blog') + expect(page).to have_content('GET /blogs Searches blogs', normalize_ws: true) + expect(page).to have_content('POST /blogs Creates a blog', normalize_ws: true) + expect(page).to have_content('GET /blogs/{id} Retrieves a blog', normalize_ws: true) end end diff --git a/test-app/spec/rails_helper.rb b/test-app/spec/rails_helper.rb index d1bc219..7c64595 100644 --- a/test-app/spec/rails_helper.rb +++ b/test-app/spec/rails_helper.rb @@ -53,7 +53,15 @@ RSpec.configure do |config| # arbitrary gems may also be filtered via: # config.filter_gems_from_backtrace("gem name") - Capybara.javascript_driver = :webkit + Capybara.register_driver :firefox_headless do |app| + options = ::Selenium::WebDriver::Firefox::Options.new + options.args << '--headless' + + Capybara::Selenium::Driver.new(app, browser: :firefox, options: options) + end + + Capybara.javascript_driver = :firefox_headless end Capybara::Webkit.configure(&:block_unknown_urls) +