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?
Related
With RSwag and RSpec in Ruby on Rails, is it possible to send a parameter that is not defined as a parameter via the run_test!?
Example test:
# frozen_string_literal: true
require "swagger_helper"
describe "Resources", type: :request, swagger_doc: "api/resources.json" do
path "/resources" do
get "get resources" do
tags "resources"
parameter name: "sort[column]",
in: :query,
type: :string,
enum: ["created_at", "updated_at"]
required: false
parameter name: "sort[order]",
in: :query,
type: :string,
enum: ["asc", "desc"]
required: false
response "422", "Unprocessable Entity" do
context "with unrecognized param" do
# define sort[direction] here
run_test! do |respone|
expect(json_response["errors"]).to contain_exactly(
# my serialized response error
)
end
end
end
end
end
end
I'd like to send sort[direction] in my context. What I have tried so far:
let(:"sort[direction]") { "asc" }
let(:sort) { { direction: "asc" } }
let(:sort) { { "direction" => "asc" } }
with no avail - I got HTTP 200 Success, even though the same request sent via Postman with sort[direction] defined responds with expected HTTP 422 Unprocessable Entity.
I have managed to do it this way:
context "with unrecognized sort param" do
before do |example|
example.metadata[:example_group][:operation][:parameters] += [{
name: "sort[direction]",
in: :query,
type: :string,
required: false
}]
end
let(:"sort[direction]") { "asc" }
run_test! do |respone|
expect(json_response["errors"]).to contain_exactly(
# my serialized response error
)
end
end
It does not add the params to the generated OpenAPI JSON file, which is good.
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
when running RSpec, in the action of controller,(use byebug or pry)
the specific value like (email or password) did not exist in the request parameters,
and so the result of the test become failed
for more details, see my below code
path '/api/v1/admin/authentications/sign_in' do
post('admin sign_in') do
produces 'application/json'
parameter name: :params, in: :body, schema: {
type: :object,
properties: {
email: { type: :string },
password: { type: :string }
},
required: %w[email password]
}
let(:admin) { create(:admin) }
response('200', 'sign in successfully') do
let(:params) { { email: admin.email, password: '***' } }
run_test!
end
end
end
add consume type for your request:
consumes 'application/json'
I also had the same problem with the latest version of gem rswag. You can change the version of gem to "1.6" to fix it
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
I'm doing a serializer for my application and i need to test it, but it always return 'json atom at path "name" is missing' when i run the specs. I'm using FastJson do build my serializer.
My StudentSerializer (all the attributes is in Students Model):
# frozen_string_literal: true
class Api::V2::StudentSerializer < ApplicationSerializer
attributes :email, :name, :school_id
end
My StudentSerializer_Spec:
require 'rails_helper'
RSpec.describe Api::V2::StudentSerializer, type: :serializer do
subject(:serializer) { described_class.new(student) }
context 'is student serialize working?' do
let(:student) { build_stubbed(:student) }
it 'serializes' do
Api::V2:: StudentSerializer.new (student)
expect(serializer).to include_json(
name: student.name
)
end
end
end
When i run the rspec, that's the result i get:
Api::V2::StudentSerializer
is student serialize working?
serializes (FAILED - 1)
1) Api::V2::StudentSerializer is student serialize working? serializes
Failure/Error:
expect(serializer).to include_json(
name: student.name
)
json atom at path "name" is missing
I figure it out!
By using FastJson, the Json start with 'data:':
{:data=>
{:id=>"1",
:attributes=>
{:email=>"",
:name=>"Burdette Schmeler",
:school_id=>1}}}
So, in my spec file, i need to put in this way:
context 'is student serialize working?' do
let(:student) { create(:student) }
it 'serializes' do
expect(serializer).to include_json(
data: {
id: student.id.to_s,
attributes: {
name: student.name,
email: student.email,
school_id: student.school_id,
}
}
)