Skip to content

Commit

Permalink
Merge pull request #5 from instacart/stephen_merge_upstream
Browse files Browse the repository at this point in the history
  • Loading branch information
ziyunli authored Jan 10, 2022
2 parents cb77feb + 9552c11 commit 28e268c
Show file tree
Hide file tree
Showing 33 changed files with 981 additions and 156 deletions.
61 changes: 61 additions & 0 deletions .github/workflows/ruby.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
name: Ruby

on:
push:
branches: [ master ]
pull_request:
branches: [ master ]

jobs:
test:
runs-on: ubuntu-latest
strategy:
matrix:
ruby: [2.6, 2.7, truffleruby-head]
rails: [5.2.4.4, 6.0.3.4]
env:
RAILS_VERSION: ${{ matrix.rails }}

steps:
- uses: actions/checkout@v2
- uses: ruby/setup-ruby@v1
with:
ruby-version: ${{ matrix.ruby }}
bundler-cache: true # runs 'bundle install' and caches installed gems automatically

- uses: actions/cache@v2
id: cache
with:
path: |
rswag-ui/node_modules
vendor/bundle
key: ${{ runner.os }}-ruby_${{ matrix.ruby }}-rails_${{ matrix.rails }}-${{ hashFiles('Gemfile', '**/package-lock.json') }}

- name: Install dependencies
run: |
bundle install
cd rswag-ui && npm install
- name: rswag-api
run: |
cd rswag-api
bundle exec rspec
- name: rswag-specs
if: success() || failure()
run: |
cd rswag-specs
bundle exec rspec
- name: rswag-ui
if: success() || failure()
run: |
cd rswag-ui
bundle exec rspec
- name: test-app
if: success() || failure()
run: |
cd test-app
bundle exec rake db:migrate db:test:prepare
bundle exec rspec
2 changes: 1 addition & 1 deletion .ruby-version
Original file line number Diff line number Diff line change
@@ -1 +1 @@
2.6.3
2.7.2
25 changes: 20 additions & 5 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,16 +1,31 @@
# rswag
All notable changes to this project will be documented in this file.

The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [Unreleased]

### Changed
- Update swagger-ui to 3.52.5

## [2.4.0] - 2021-02-09
### Added
- Added `SWAGGER_DRY_RUN` env variable [#274](https://github.com/rswag/rswag/pull/274)

## [2.3.3] - 2021-02-07

### Fixed
- Include response examples [#394](https://github.com/rswag/rswag/pull/394)

### Changed
### Deprecated
### Removed
- Update swagger-ui to 3.42.0

## [2.3.2] - 2021-01-27
### Added
- RequestBody now supports the `required` flag [#342](https://github.com/rswag/rswag/pull/342)
### Fixed
### Security
- Fix response example rendering [#330](https://github.com/rswag/rswag/pull/330)
- Fix empty content block [#347](https://github.com/rswag/rswag/pull/347)

## [2.3.1] - 2020-04-08
### Fixed
Expand Down
4 changes: 2 additions & 2 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,11 +57,11 @@ Push to your fork and [submit a Pull Request][pr].

## Updating Swagger UI

Find the latest versions of swagger-ui here:
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
```

Expand Down
8 changes: 5 additions & 3 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -25,23 +25,25 @@ end
gem 'rswag-api', path: './rswag-api'
gem 'rswag-ui', path: './rswag-ui'

group :development, :test do
gem 'rswag-specs', path: './rswag-specs'
end

group :test do
gem 'capybara'
gem 'geckodriver-helper'
gem 'generator_spec'
gem 'rspec-rails'
gem 'selenium-webdriver'
gem 'rswag-specs', path: './rswag-specs'
gem 'test-unit'
end

group :development do
gem 'rswag-specs', path: './rswag-specs'
gem 'rubocop'
end

group :assets do
gem 'therubyracer'
gem 'mini_racer'
gem 'uglifier'
end

Expand Down
55 changes: 29 additions & 26 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ rswag

OpenApi 3.0 and Swagger 2.0 compatible!

Seeking maintainers! Got a pet-bug that needs fixing? Just let us know in your issue/pr that you'd like to step up to help.

Rswag extends rspec-rails "request specs" with a Swagger-based DSL for describing and testing API operations. You describe your API operations with a succinct, intuitive syntax, and it automaticaly runs the tests. Once you have green tests, run a rake task to auto-generate corresponding Swagger files and expose them as YAML or JSON endpoints. Rswag also provides an embedded version of the awesome [swagger-ui](https://github.com/swagger-api/swagger-ui) that's powered by the exposed file. This toolchain makes it seamless to go from integration specs, which youre probably doing in some form already, to living documentation for your API consumers.

Api Rswag creates [Swagger](http://swagger.io) tooling for Rails API's. Generate beautiful API documentation, including a UI to explore and test operations, directly from your rspec integration tests.
Expand All @@ -18,7 +20,7 @@ Once you have an API that can describe itself in Swagger, you've opened the trea

|Rswag Version|Swagger (OpenAPI) Spec.|swagger-ui|
|----------|----------|----------|
|[master](https://github.com/rswag/rswag/tree/master)|3.0.3|3.28.0|
|[master](https://github.com/rswag/rswag/tree/master)|3.0.3|3.52.5|
|[2.3.0](https://github.com/rswag/rswag/tree/2.3.0)|3.0.3|3.23.11|
|[2.2.0](https://github.com/rswag/rswag/tree/2.2.0)|2.0|3.18.2|
|[1.6.0](https://github.com/rswag/rswag/tree/1.6.0)|2.0|2.2.5|
Expand Down Expand Up @@ -136,7 +138,7 @@ There is also a generator which can help get you started `rails generate rspec:s
path '/blogs/{id}' do
get 'Retrieves a blog' do
tags 'Blogs'
tags 'Blogs', 'Another Tag'
produces 'application/json', 'application/xml'
parameter name: :id, in: :path, type: :string
Expand Down Expand Up @@ -363,8 +365,8 @@ you should use the folowing syntax, making sure there are no whitespaces at the

### Specifying/Testing API Security ###

Swagger allows for the specification of different security schemes and their applicability to operations in an API.
To leverage this in rswag, you define the schemes globally in _swagger_helper.rb_ and then use the "security" attribute at the operation level to specify which schemes, if any, are applicable to that operation.
Swagger allows for the specification of different security schemes and their applicability to operations in an API.
To leverage this in rswag, you define the schemes globally in _swagger_helper.rb_ and then use the "security" attribute at the operation level to specify which schemes, if any, are applicable to that operation.
Swagger supports :basic, :bearer, :apiKey and :oauth2 and :openIdConnect scheme types. See [the spec](https://swagger.io/docs/specification/authentication/) for more info, as this underwent major changes between Swagger 2.0 and Open API 3.0

```ruby
Expand Down Expand Up @@ -416,7 +418,7 @@ describe 'Blogs API' do
end

# example of documenting an endpoint that handles basic auth and api key based security
describe 'Auth examples API' do
describe 'Auth examples API' do
path '/auth-tests/basic-and-api-key' do
post 'Authenticates with basic auth and api key' do
tags 'Auth Tests'
Expand All @@ -437,11 +439,11 @@ describe 'Auth examples API' do
end
end
end


```

__NOTE:__ Depending on the scheme types, you'll be required to assign a corresponding parameter value with each example.
__NOTE:__ Depending on the scheme types, you'll be required to assign a corresponding parameter value with each example.
For example, :basic auth is required above and so the :Authorization (header) parameter must be set accordingly

## Configuration & Customization ##
Expand Down Expand Up @@ -479,9 +481,9 @@ rake rswag:specs:swaggerize PATTERN="spec/swagger/**/*_spec.rb"

### Referenced Parameters and Schema Definitions ###

Swagger allows you to describe JSON structures inline with your operation descriptions OR as referenced globals.
Swagger allows you to describe JSON structures inline with your operation descriptions OR as referenced globals.
For example, you might have a standard response structure for all failed operations.
Again, this is a structure that changed since swagger 2.0. Notice the new "schemas" section for these.
Again, this is a structure that changed since swagger 2.0. Notice the new "schemas" section for these.
Rather than repeating the schema in every operation spec, you can define it globally and provide a reference to it in each spec:

```ruby
Expand Down Expand Up @@ -560,7 +562,7 @@ end

### Response headers ###

In Rswag, you could use `header` method inside the response block to specify header objects for this response.
In Rswag, you could use `header` method inside the response block to specify header objects for this response.
Rswag will validate your response headers with those header objects and inject them into the generated swagger file:

```ruby
Expand Down Expand Up @@ -608,19 +610,20 @@ To enable examples generation from responses add callback above run_test! like:

```
after do |example|
example.metadata[:response][:examples] = { 'application/json' => JSON.parse(response.body, symbolize_names: true) }
example.metadata[:response][:content] = {
'application/json' => {
example: JSON.parse(response.body, symbolize_names: true)
}
}
end
```

You need to disable --dry-run option for Rspec > 3
#### Dry Run Option ####

<!-- This is now enabled by default in rswag.
You need to set the ``` config.swagger_dry_run = false``` value in the spec/spec_helper.rb file.
This is one of the more powerful features of rswag. When rswag runs your integration test suite via ```bundle exec rspec```, it will capture the request and response bodies and output those values in the examples section.
These integration tests are usually written with ```let``` variables for post body parameters, and since its an integration test the service is returning actual values.
We might as well re-use these values and embed them into the generated swagger to provide a more real world example for request/response examples. -->
The `--dry-run` option is enabled by default for Rspec 3, but if you need to
disable it you can use the environment varible `SWAGGER_DRY_RUN=0` during the
generation command or add the following to your `config/environments/test.rb`:

Add to config/environments/test.rb:
```ruby
RSpec.configure do |config|
config.swagger_dry_run = false
Expand Down Expand Up @@ -656,8 +659,8 @@ describe 'Blogs API', document: false do
```

##### rswag helper methods #####
<!--
There are some helper methods to help with documenting request bodies.
<!--
There are some helper methods to help with documenting request bodies.
```ruby
describe 'Blogs API', type: :request, swagger_doc: 'v1/swagger.json' do
let(:api_key) { 'fake_key' }
Expand Down Expand Up @@ -693,7 +696,7 @@ describe 'Blogs API', type: :request, swagger_doc: 'v1/swagger.json' do
end
end
end
end
end
```
In the above example, we see methods ```request_body_json``` ```request_body_plain``` ```request_body_xml```.
Expand All @@ -703,7 +706,7 @@ and the examples: :blog which will create a named example "blog" under the "requ
Again, documenting request response examples changed in Open API 3.0. The example above would generate a swagger.json snippet that looks like this:
```json
...
...
{"requestBody": {
"required": true,
"content": {
Expand Down Expand Up @@ -737,9 +740,9 @@ Again, documenting request response examples changed in Open API 3.0. The exampl
}
```
*NOTE:* for this example request body to work in the tests properly, you need to ``let`` a variable named *blog*.
*NOTE:* for this example request body to work in the tests properly, you need to ``let`` a variable named *blog*.
The variable with the matching name (blog in this case) is eval-ed and captured to be placed in the examples section.
This ```let``` value is used in the integration test to run the test AND captured and injected into the requestBody section.
This ```let``` value is used in the integration test to run the test AND captured and injected into the requestBody section.
##### rswag response examples #####
Expand Down Expand Up @@ -837,7 +840,7 @@ You can specify custom headers for serving your generated Swagger JSON. For exam
```ruby
Rswag::Api.configure do |c|
...

c.swagger_headers = { 'Content-Type' => 'application/json; charset=UTF-8' }
end
```
Expand Down Expand Up @@ -909,5 +912,5 @@ docker pull swaggerapi/swagger-editor
```
docker run -d -p 80:8080 swaggerapi/swagger-editor
```
This will run the swagger editor in the docker daemon and can be accessed
This will run the swagger editor in the docker daemon and can be accessed
at ```http://localhost```. From here, you can use the UI to load the generated swagger.json to validate the output.
6 changes: 3 additions & 3 deletions rswag-api/rswag-api.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,11 @@ Gem::Specification.new do |s|
s.authors = ['Richie Morris', 'Greg Myers', 'Jay Danielian']
s.email = ['[email protected]']
s.homepage = 'https://github.com/rswag/rswag'
s.summary = 'A Rails Engine that exposes Swagger files as JSON endpoints'
s.description = 'Open up your API to the phenomenal Swagger ecosystem by exposing Swagger files, that describe your service, as JSON endpoints'
s.summary = 'A Rails Engine that exposes OpenAPI (formerly called Swagger) files as JSON endpoints'
s.description = 'Open up your API to the phenomenal OpenAPI ecosystem by exposing OpenAPI files, that describe your service, as JSON endpoints. More about the OpenAPI initiative here: http://spec.openapis.org/'
s.license = 'MIT'

s.files = Dir['{lib}/**/*'] + ['MIT-LICENSE', 'Rakefile']

s.add_dependency 'railties', '>= 3.1', '< 7.0'
s.add_dependency 'railties', '>= 3.1', '< 7.1'
end
6 changes: 5 additions & 1 deletion rswag-specs/lib/generators/rspec/templates/spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,11 @@
<% end -%>
after do |example|
example.metadata[:response][:examples] = { 'application/json' => JSON.parse(response.body, symbolize_names: true) }
example.metadata[:response][:content] = {
'application/json' => {
example: JSON.parse(response.body, symbolize_names: true)
}
}
end
run_test!
end
Expand Down
6 changes: 4 additions & 2 deletions rswag-specs/lib/rswag/specs/configuration.rb
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,11 @@ def swagger_docs
end

def swagger_dry_run
@swagger_dry_run ||= begin
@rspec_config.swagger_dry_run.nil? || @rspec_config.swagger_dry_run
return @swagger_dry_run if defined? @swagger_dry_run
if ENV.key?('SWAGGER_DRY_RUN')
@rspec_config.swagger_dry_run = ENV['SWAGGER_DRY_RUN'] == '1'
end
@swagger_dry_run = @rspec_config.swagger_dry_run.nil? || @rspec_config.swagger_dry_run
end

def swagger_format
Expand Down
5 changes: 4 additions & 1 deletion rswag-specs/lib/rswag/specs/example_group_helpers.rb
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,10 @@ def header(name, attributes)
def examples(example = nil)
return super() if example.nil?

metadata[:response][:examples] = example
metadata[:response][:content] =
example.each_with_object({}) do |(mime, example_object), memo|
memo[mime] = { example: example_object }
end
end

def run_test!(&block)
Expand Down
Loading

0 comments on commit 28e268c

Please sign in to comment.