I have some common parameters which are called in almost all API calls so is it possible to create component for those parameters and call them in rswag api request.
Something like schema '$ref' => '#/definitions/parameters'
Thanks!
Add in your swagger_helper.rb
Example:
# spec/swagger_helper.rb
config.swagger_docs = {
'v1/swagger.json' => {
swagger: '2.0',
info: {
title: 'API V1'
},
definitions: {
errors_object: {
type: 'object',
properties: {
errors: { '$ref' => '#/definitions/errors_map' }
}
},
errors_map: {
type: 'object',
additionalProperties: {
type: 'array',
items: { type: 'string' }
}
}
}
}
}
# spec/integration/blogs_spec.rb
describe 'Blogs API' do
path '/blogs' do
post 'Creates a blog' do
response 422, 'invalid request' do
schema '$ref' => '#/definitions/errors_object'
...
end
# spec/integration/comments_spec.rb
describe 'Blogs API' do
path '/blogs/{blog_id}/comments' do
post 'Creates a comment' do
response 422, 'invalid request' do
schema '$ref' => '#/definitions/errors_object'
...
end
From: https://www.rubydoc.info/github/domaindrivendev/rswag#referenced-parameters-and-schema-definitions
You need to define your object in spec/swagger_helper.rb
Then in integration spec file define
path '/api/client/v0/blog' do
put 'Create a blog' do
tags :Blog
include_examples 'header_with_recognition_definitions'
parameter name: :input_param, in: :body, schema: { '$ref' => '#/definitions/input_parameter_object' }
response 200, 'blog was created successfully' do
include_examples 'header_with_recognition_lets'
...
run_test!
end
end
Related
I have spent a lot of time trying to emplement ability of validation incoming params is rswag specs, my code:
# incoming-parameter
params = {
login: 'www',
id: 15
}
# test rswag-spec
path '/controller/hello' do
post('Say Hello!') do
tags 'users'
consumes 'application/json'
produces 'application/json'
parameter name: :my_params, in: :body, schema: {
type: :object,
required: %i[id name],
properties: {
id: { type: :string },
name: { type: :string }
}
}
response(200, 'successful') do
# schema '$ref' => '#/components/schemas/UserRegistrationResponse'
describe 'new user with valid reg_params' do
let(:my_params) { params }
run_test! do |response|
data = JSON.parse(response.body)
puts "data = #{data}"
end
end
end
end
end
You expecting that incoming params won't pass validation, because id - is an integer, and name field is absent. But that's doesn't matter and test is compliting with success.
Can you say what's wrong with my code an why don't work validation of incoming parameters those declarated in rswag docs?
I'm getting this error when I run the rspec
Response body: {"success":false,"errors":["Invalid login credentials"]}
here is my code
path '/api/auth/validate_token' do
get 'check token' do
tags 'TokenValidations'
consumes 'application/json'
security [client: {}, uid: {}, access_token: {}]
response '200', 'success' do
let(:headers) { user.create_new_auth_token }
run_test!
end
end
end
Thanks in advance
I think I had the same problem and tried to execute below, then worked for me.
let(:user) { FactoryBot.create(:user, password: 'password') }
let(:tokens) do
post "/api/v1/authority/sign_in",
params: { email: user[:email], password: 'password' },
as: :json
response.headers.slice('client', 'access-token', 'uid')
end
path '/api/v1/messages/' do
get 'Retrieves some messages' do
description 'Get some messages from provided data'
produces 'application/json'
parameter name: 'access-token', in: :header, type: :string
parameter name: 'client', in: :header, type: :string
parameter name: 'uid', in: :header, type: :string
response '200', 'messages found' do
let(:client) { tokens['client'] }
let('access-token') { tokens['access-token'] }
let(:uid) { tokens['uid'] }
schema '$ref' => '#/components/schemas/messages'
run_test!
end
end
end
I am trying to figure out why I can't use use both params and headers in an request spec.
What works:
RSpec.describe Api::V1::UsersController, :type => :request do
before { host! 'api.localhost:3000'}
let(:params) {
{
"user": {
"identifier_for_vendor": "BD43813E"
}
}
}
describe 'Post /users' do
context 'when request is valid' do
before {
post api_users_path,
params: params
}
it "is successful" do
expect(response).to be_successful
end
end
end
end
What does not:
RSpec.describe Api::V1::UsersController, :type => :request do
let(:params) {
{
"user": {
"identifier_for_vendor": "BD43813E"
}
}
}
let(:headers) {
{
"host": "api.localhost:3000",
"Accept": "application/vnd.domain_name.v1",
"Content-Type": "application/vnd.api+json",
"X-API-Key": "fake087uakey"
}
}
describe 'Post /users' do
context 'when request is valid' do
before {
post api_users_path,
params: params,
headers: headers
}
it "successful" do
expect(response).to be_successful
end
end
end
end
The above fails, returning the error:
1) Api::V1::UsersController Post /users when request is valid is successful
Failure/Error: params.require(:user).permit(:identifier_for_vendor)
ActionController::ParameterMissing:
param is missing or the value is empty: user
The headers are needed due to having to ensure that valid api-keys are included in the request.
Would appreciate feedback on what I am missing. Thank you
Versions:
Ruby version: 2.6.3
Rails version: 6.0.3.4
RSpec 3.10
So issue had to do with how params and headers objects are created.
Params:
I passed in:
{"user": {"identifier_for_vendor": "OFJPJ"} }
the correct object is:
{:params=>{:user=>{:identifier_for_vendor=>"OFJPJ"}}}
Headers:
I passed in:
{
"host": "api.localhost:3000",
"Accept": "application/vnd.domain_name.v1",
"Content-Type": "application/vnd.api+json",
"X-API-Key": "fake087uakey"
}
the correct object is:
{
"headers" => {
"host" => "api.localhost:3000",
"Accept" => "application/vnd.domain_name.v1",
"X-API-Key" => "api_key"
}
}
Final solution looks like this:
RSpec.describe Api::V1::UsersController, :type => :request do
describe 'Post /users' do
context 'when request is valid' do
before do
post api_users_path,
:params => params,
:headers => headers
end
it "is successful" do
expect(response).to be_successful
end
it "returns a data of type user" do
expect(json_data["type"]).to eq("user")
end
end
end
end
The key to figuring this out was reading the documentation and realizing the my formatting was wrong.
I didn't find any examples of how to use rswag to generate documentation according to json api.
spec/integration/pets_spec.rb
require 'swagger_helper'
It is possible to change the code to generate the format of json api?
describe 'Pets API' do
path '/api/v1/pets' do
post 'Creates a pet' do
tags 'Pets'
consumes 'application/json', 'application/xml'
parameter name: :pet, in: :body, schema: {
type: :object,
properties: {
name: { type: :string },
photo_url: { type: :string },
status: { type: :string }
},
required: [ 'name', 'status' ]
}
response '201', 'pet created' do
let(:pet) { { name: 'Dodo', status: 'available' } }
run_test!
end
response '422', 'invalid request' do
let(:pet) { { name: 'foo' } }
run_test!
end
end
end
path '/api/v1/pets/{id}' do
get 'Retrieves a pet' do
tags 'Pets'
produces 'application/json', 'application/xml'
parameter name: :id, :in => :path, :type => :string
response '200', 'name found' do
schema type: :object,
properties: {
id: { type: :integer, },
name: { type: :string },
photo_url: { type: :string },
status: { type: :string }
},
required: [ 'id', 'name', 'status' ]
let(:id) { Pet.create(name: 'foo', status: 'bar', photo_url: 'http://example.com/avatar.jpg').id }
run_test!
end
response '404', 'pet not found' do
let(:id) { 'invalid' }
run_test!
end
end
end
end
If rswag what tips would you give me?
You need to change the swagger_helper.rb file. Change the file format to JSON. I have attached the screenshot for that one below:
https://i.stack.imgur.com/MzOR9.png
How do I add a custom parameter in my rswag-specification?
Rswag seems to consumate only parameters which exists as fields
but I need to add a custom parameter. So whatever I do - I can see in controllers params only fields of my model.
RSpec.describe Api::V1::LogsController, type: :request do
path '/api/v1/logs' do
post 'Create a Log' do
tags 'Logs'
security [ApiKeyAuth: {}]
consumes 'application/json'
produces 'application/json'
parameter name: :log, in: :body, schema: {
type: :object,
properties: {
title: { type: :string },
description: { type: :string },
my_custom_parameter: { type: :string }
},
required: %w(title description user_phone_number),
}
response '200', 'New Log created' do
let(:Authorization) { "Token token=#{company.api_key}" }
run_test!
end
end
end
end
you can add any parameters with any name that you liked,
and then you can give values to those parameters in the response block like below:
parameter name: :params, in: :body, schema: {
type: :object,
properties: {
profile_attributes: {
type: :object,
properties: {
email: { type: :string, example: Faker::Internet.email(Faker::Name.first_name) }
},
required: %w[email]
}
response('201', 'successfully') do
let(:params) do
{
profile_attributes: { email: Faker::Internet.email(Faker::Name.first_name) }
}
end