# frozen_string_literal: true require 'rswag/specs/example_group_helpers' module Rswag module Specs describe ExampleGroupHelpers do subject { double('example_group') } before do subject.extend ExampleGroupHelpers allow(subject).to receive(:describe) allow(subject).to receive(:context) allow(subject).to receive(:metadata).and_return(api_metadata) end let(:api_metadata) { {} } describe '#path(path)' do before { subject.path('/blogs') } it "delegates to 'describe' with 'path' metadata" do expect(subject).to have_received(:describe).with( '/blogs', path_item: { template: '/blogs' } ) end end describe '#get|post|patch|put|delete|head(verb, summary)' do before { subject.post('Creates a blog') } it "delegates to 'describe' with 'operation' metadata" do expect(subject).to have_received(:describe).with( :post, operation: { verb: :post, summary: 'Creates a blog' } ) end end describe '#tags|description|operationId|consumes|produces|schemes|deprecated(value)' do before do subject.tags('Blogs', 'Admin') subject.description('Some description') subject.operationId('createBlog') subject.consumes('application/json', 'application/xml') subject.produces('application/json', 'application/xml') subject.schemes('http', 'https') subject.deprecated(true) end let(:api_metadata) { { operation: {} } } it "adds to the 'operation' metadata" do expect(api_metadata[:operation]).to match( tags: %w[Blogs Admin], description: 'Some description', operationId: 'createBlog', consumes: ['application/json', 'application/xml'], produces: ['application/json', 'application/xml'], schemes: %w[http https], deprecated: true ) end end describe '#tags|description|operationId|consumes|produces|schemes|deprecated|security(value)' do before do subject.tags('Blogs', 'Admin') subject.description('Some description') subject.operationId('createBlog') subject.consumes('application/json', 'application/xml') subject.produces('application/json', 'application/xml') subject.schemes('http', 'https') subject.deprecated(true) subject.security(api_key: []) end let(:api_metadata) { { operation: {} } } it "adds to the 'operation' metadata" do expect(api_metadata[:operation]).to match( tags: %w[Blogs Admin], description: 'Some description', operationId: 'createBlog', consumes: ['application/json', 'application/xml'], produces: ['application/json', 'application/xml'], schemes: %w[http https], deprecated: true, security: { api_key: [] } ) end end describe '#request_body_json(schema)' do let(:api_metadata) { { path_item: {}, operation: {} } } # i.e. operation defined context 'when required is not supplied' do before { subject.request_body_json(schema: { type: 'object' }) } it 'adds required true by default' do expect(api_metadata[:operation][:requestBody]).to match( required: true, content: { 'application/json' => { schema: { type: 'object' } } } ) end end context 'when required is supplied' do before { subject.request_body_json(schema: { type: 'object' }, required: false) } it 'adds required false' do expect(api_metadata[:operation][:requestBody]).to match( required: false, content: { 'application/json' => { schema: { type: 'object' } } } ) end end context 'when required is supplied' do before { subject.request_body_json(schema: { type: 'object' }, description: 'my description') } it 'adds description' do expect(api_metadata[:operation][:requestBody]).to match( description: 'my description', required: true, content: { 'application/json' => { schema: { type: 'object' } } } ) end end end describe '#parameter(attributes)' do context "when called at the 'path' level" do before { subject.parameter(name: :blog, in: :body, schema: { type: 'object' }) } let(:api_metadata) { { path_item: {} } } # i.e. operation not defined yet it "adds to the 'path_item parameters' metadata" do expect(api_metadata[:path_item][:parameters]).to match( [name: :blog, in: :body, schema: { type: 'object' }] ) end end context "when called at the 'operation' level" do before { subject.parameter(name: :blog, in: :body, schema: { type: 'object' }) } let(:api_metadata) { { path_item: {}, operation: {} } } # i.e. operation defined it "adds to the 'operation parameters' metadata" do expect(api_metadata[:operation][:parameters]).to match( [name: :blog, in: :body, schema: { type: 'object' }] ) end end context "'path' parameter" do before { subject.parameter(name: :id, in: :path) } let(:api_metadata) { { operation: {} } } it "automatically sets the 'required' flag" do expect(api_metadata[:operation][:parameters]).to match( [name: :id, in: :path, required: true] ) end end context "when 'in' parameter key is not defined" do before { subject.parameter(name: :id) } let(:api_metadata) { { operation: {} } } it "does not require the 'in' parameter key" do expect(api_metadata[:operation][:parameters]).to match([name: :id]) end end end describe '#response(code, description)' do before { subject.response('201', 'success') } it "delegates to 'context' with 'response' metadata" do expect(subject).to have_received(:context).with( 'success', response: { code: '201', description: 'success' } ) end end describe '#schema(value)' do before { subject.schema(type: 'object') } let(:api_metadata) { { response: {} } } it "adds to the 'response' metadata" do expect(api_metadata[:response][:schema]).to match(type: 'object') end end describe '#header(name, attributes)' do before { subject.header('Date', type: 'string') } let(:api_metadata) { { response: {} } } it "adds to the 'response headers' metadata" do expect(api_metadata[:response][:headers]).to match( 'Date' => { type: 'string' } ) end end describe '#examples(example)' do let(:json_example) do { 'application/json' => { foo: 'bar' } } end let(:api_metadata) { { response: {} } } before do subject.examples(json_example) end it "adds to the 'response examples' metadata" do expect(api_metadata[:response][:examples]).to eq(json_example) end end end end end