Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
R
rspec-rails-swagger
Project
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
open-source
rspec-rails-swagger
Commits
db6e3635
Commit
db6e3635
authored
Sep 19, 2016
by
andrew morton
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Start resolving parameters
parent
f37dda8c
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
124 additions
and
46 deletions
+124
-46
helpers.rb
lib/rspec/swagger/helpers.rb
+40
-20
request_spec.rb
spec/requests/request_spec.rb
+4
-2
helpers_spec.rb
spec/rspec/swagger/helpers_spec.rb
+80
-24
No files found.
lib/rspec/swagger/helpers.rb
View file @
db6e3635
...
...
@@ -11,6 +11,7 @@ module RSpec
config
.
extend
Operation
,
swagger_object: :operation
config
.
extend
Parameters
,
swagger_object: :operation
config
.
extend
Response
,
swagger_object: :status_code
config
.
include
Common
,
:swagger_object
end
...
...
@@ -42,6 +43,8 @@ paths: (Paths)
=end
module
Paths
def
path
template
,
&
block
raise
ArgumentError
,
"Path must start with a /"
unless
template
.
starts_with?
(
'/'
)
#TODO template might be a $ref
meta
=
{
swagger_object: :path_item
,
...
...
@@ -53,6 +56,8 @@ paths: (Paths)
module
PathItem
def
operation
verb
,
desc
,
&
block
# TODO, check verbs against a whitelist
verb
=
verb
.
to_s
.
downcase
meta
=
{
swagger_object: :operation
,
...
...
@@ -72,12 +77,14 @@ paths: (Paths)
raise
ArgumentError
,
"Invalid 'in' parameter, must be one of
#{
locations
}
"
end
# Path attributes are always required
attributes
[
:required
]
=
true
if
attributes
[
:in
]
==
:path
# if name.respond_to?(:has_key?)
# param = { '$ref' => name.delete(:ref) || name.delete('ref') }
# end
params_key
=
"
#{
metadata
[
:swagger_object
]
}
_params"
.
to_sym
params
=
metadata
[
:swagger_data
][
params_key
]
||=
{}
params
=
metadata
[
:swagger_data
][
:params
]
||=
{}
param
=
{
name:
name
.
to_s
}.
merge
(
attributes
)
# Params should be unique based on the 'name' and 'in' values.
...
...
@@ -89,9 +96,8 @@ paths: (Paths)
module
Operation
def
response
status_code
,
desc
,
params
=
{},
headers
=
{},
&
block
unless
status_code
==
:default
||
(
100
..
599
).
cover?
(
status_code
)
raise
ArgumentError
,
"status_code must be
between 100 and 599
or :default"
raise
ArgumentError
,
"status_code must be
an integer 100 to 599,
or :default"
end
meta
=
{
swagger_object: :status_code
,
swagger_data:
metadata
[
:swagger_data
].
merge
(
status_code:
status_code
,
response_description:
desc
)
...
...
@@ -99,30 +105,29 @@ paths: (Paths)
describe
(
"
#{
status_code
}
"
,
meta
)
do
self
.
module_exec
(
&
block
)
if
block_given?
method
=
metadata
[
:swagger_data
][
:operation
]
path
=
metadata
[
:swagger_data
][
:path
]
args
=
if
::
Rails
::
VERSION
::
MAJOR
>=
5
[
path
,
{
params:
params
,
headers:
headers
}]
else
[
path
,
params
,
headers
]
end
# TODO: this needs a better mechanism
if
metadata
[
:capture_example
]
example
=
metadata
[
:swagger_data
][
:example
]
=
{}
end
meta
=
{
swagger_object: :response
# response: metadata[:swagger_data][:response].merge()
}
it
(
"matches"
,
meta
)
do
before
do
|
example
|
method
=
example
.
metadata
[
:swagger_data
][
:operation
]
path
=
resolve_path
(
example
.
metadata
[
:swagger_data
][
:path
],
self
)
args
=
if
::
Rails
::
VERSION
::
MAJOR
>=
5
[
path
,
{
params:
params
,
headers:
headers
}]
else
[
path
,
params
,
headers
]
end
self
.
send
(
method
,
*
args
)
if
response
&&
example
example
.
merge!
(
body:
response
.
body
,
content_type:
response
.
content_type
.
to_s
)
end
# TODO fix the naming collision
# if example
# example.merge!(body: response.body, content_type: response.content_type.to_s)
# end
end
it
(
"matches"
,
{
swagger_object: :response
})
do
expect
(
response
).
to
have_http_status
(
status_code
)
end
end
...
...
@@ -134,6 +139,21 @@ paths: (Paths)
metadata
[
:capture_example
]
=
true
end
end
module
Common
def
resolve_params
swagger_data
,
group_instance
# TODO resolve $refs
# TODO there should only be one body param
# TODO there should not be both body and formData params
swagger_data
[
:params
].
values
.
map
do
|
p
|
p
.
slice
(
:name
,
:in
).
merge
(
value:
group_instance
.
send
(
p
[
:name
]))
end
end
def
resolve_path
template
,
group_instance
template
.
gsub
(
/(\{.*?\})/
){
|
match
|
group_instance
.
send
(
match
[
1
...-
1
])
}
end
end
end
end
end
spec/requests/request_spec.rb
View file @
db6e3635
...
...
@@ -15,8 +15,10 @@ RSpec.describe "Requestsing", type: :request do
end
end
path
'/posts/1'
do
parameter
"path-param"
,
{
in: :path
}
path
'/posts/{post_id}'
do
parameter
"post_id"
,
{
in: :path
}
let
(
:post_id
)
{
1
}
operation
"GET"
,
"fetch item"
do
before
{
Post
.
new
.
save
}
parameter
"op-param"
,
{
in: :query
}
...
...
spec/rspec/swagger/helpers_spec.rb
View file @
db6e3635
require
"spec_helper"
RSpec
.
describe
RSpec
::
Swagger
::
Helpers
::
Paths
do
let
(
:klass
)
do
Class
.
new
do
include
RSpec
::
Swagger
::
Helpers
::
Paths
attr_accessor
:metadata
def
describe
*
args
;
end
end
end
subject
{
klass
.
new
}
it
"requires the path start with a /"
do
expect
{
subject
.
path
(
"foo"
)
}.
to
raise_exception
(
ArgumentError
)
expect
{
subject
.
path
(
"/foo"
)
}.
not_to
raise_exception
end
end
RSpec
.
describe
RSpec
::
Swagger
::
Helpers
::
Parameters
do
let
(
:klass
)
do
Class
.
new
do
...
...
@@ -13,39 +29,28 @@ RSpec.describe RSpec::Swagger::Helpers::Parameters do
before
{
subject
.
metadata
=
{
swagger_object: :path_item
,
swagger_data:
{}}
}
it
"requires 'in' parameter"
do
expect
{
subject
.
parameter
"name"
,
foo: :bar
}.
to
raise_exception
(
ArgumentError
)
expect
{
subject
.
parameter
(
"name"
,
foo: :bar
)
}.
to
raise_exception
(
ArgumentError
)
end
it
"validates 'in' parameter"
do
expect
{
subject
.
parameter
"name"
,
in: :form_data
}.
to
raise_exception
(
ArgumentError
)
expect
{
subject
.
parameter
"name"
,
in:
"formData"
}.
to
raise_exception
(
ArgumentError
)
expect
{
subject
.
parameter
"name"
,
in: :formData
}.
not_to
raise_exception
expect
{
subject
.
parameter
(
"name"
,
in: :form_data
)
}.
to
raise_exception
(
ArgumentError
)
expect
{
subject
.
parameter
(
"name"
,
in:
"formData"
)
}.
to
raise_exception
(
ArgumentError
)
expect
{
subject
.
parameter
(
"name"
,
in: :formData
)
}.
not_to
raise_exception
end
context
"on a path_item
"
do
before
{
subject
.
metadata
=
{
swagger_object: :path_item
,
swagger_data:
{}}
}
it
"marks path parameters as required
"
do
subject
.
parameter
(
"name"
,
in: :path
)
it
"keeps parameters unique by name and in"
do
subject
.
parameter
(
'foo'
,
in: :path
)
subject
.
parameter
(
'foo'
,
in: :path
)
subject
.
parameter
(
'bar'
,
in: :query
)
subject
.
parameter
(
'baz'
,
in: :query
)
expect
(
subject
.
metadata
[
:swagger_data
][
:path_item_params
].
length
).
to
eq
3
end
expect
(
subject
.
metadata
[
:swagger_data
][
:params
].
values
.
first
).
to
include
(
required:
true
)
end
context
"on an operation"
do
before
{
subject
.
metadata
=
{
swagger_object: :operation
,
swagger_data:
{}}
}
it
"keeps parameters unique by name and in"
do
subject
.
parameter
(
'foo'
,
in: :path
)
subject
.
parameter
(
'foo'
,
in: :path
)
subject
.
parameter
(
'bar'
,
in: :query
)
subject
.
parameter
(
'baz'
,
in: :query
)
it
"keeps parameters unique by name and location"
do
subject
.
parameter
(
'foo'
,
in: :path
)
subject
.
parameter
(
'foo'
,
in: :path
)
subject
.
parameter
(
'bar'
,
in: :query
)
subject
.
parameter
(
'baz'
,
in: :query
)
expect
(
subject
.
metadata
[
:swagger_data
][
:operation_params
].
length
).
to
eq
3
end
expect
(
subject
.
metadata
[
:swagger_data
][
:params
].
length
).
to
eq
3
end
end
end
...
...
@@ -76,3 +81,54 @@ RSpec.describe RSpec::Swagger::Helpers::Operation do
end
end
end
RSpec
.
describe
RSpec
::
Swagger
::
Helpers
::
Common
do
# Tthis helper is an include rather than an extend we can get it pulled into
# the test just by matching the filter metadata.
describe
(
"#resolve_params"
,
swagger_object: :something
)
do
let
(
:swagger_data
)
{
{
params:
params
}
}
describe
"with a missing value"
do
let
(
:params
)
{
{
"path&post_id"
=>
{
name:
"post_id"
,
in: :path
}}
}
# TODO best thing would be to lazily evaulate the params so we'd only
# hit this if something was trying to use it.
it
"raises an error"
do
expect
{
resolve_params
(
swagger_data
,
self
)}.
to
raise_exception
(
NoMethodError
)
end
end
describe
"with a valid value"
do
let
(
:params
)
{
{
"path&post_id"
=>
{
name:
"post_id"
,
in: :path
,
description:
"long"
}}
}
let
(
:post_id
)
{
123
}
it
"returns it"
do
expect
(
resolve_params
(
swagger_data
,
self
)).
to
eq
([{
name:
"post_id"
,
in: :path
,
value:
123
}])
end
end
end
describe
(
"#resolve_params"
,
swagger_object: :something
)
do
describe
"with a missing value"
do
it
"raises an error"
do
expect
{
resolve_path
(
'/sites/{site_id}'
,
self
)
}.
to
raise_exception
(
NoMethodError
)
end
end
describe
"with values"
do
let
(
:site_id
)
{
1001
}
let
(
:accountId
)
{
"pickles"
}
it
"substitutes them into the path"
do
expect
(
resolve_path
(
'/sites/{site_id}/accounts/{accountId}'
,
self
)).
to
eq
(
'/sites/1001/accounts/pickles'
)
end
end
describe
"with a base path"
do
xit
"prefixes the path"
do
end
end
end
end
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment