From 7a98af4bc811475dc493474f72d7e726d1ba012a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?TATSUNO=20=E2=80=9CTaz=E2=80=9D=20Yasuhiro?= Date: Mon, 25 Mar 2024 16:33:19 +0900 Subject: [PATCH] Use raw HTML content so example can be generated with Rails 7.1+ (#189) --- .rubocop_todo.yml | 14 +++++++------- lib/rspec/openapi/record_builder.rb | 7 +++++-- lib/rspec/openapi/schema_builder.rb | 1 + spec/rails/app/controllers/pages_controller.rb | 9 +++++++++ spec/rails/config/routes.rb | 2 ++ spec/rails/doc/smart/expected.yaml | 15 +++++++++++++++ spec/requests/rails_smart_merge_spec.rb | 9 +++++++++ 7 files changed, 48 insertions(+), 9 deletions(-) create mode 100644 spec/rails/app/controllers/pages_controller.rb diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index 8c58aef0..f111102b 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -1,12 +1,12 @@ # This configuration was generated by # `rubocop --auto-gen-config` -# on 2024-01-13 11:12:43 UTC using RuboCop version 1.50.2. +# on 2024-03-25 05:35:37 UTC using RuboCop version 1.62.1. # The point is for the user to remove these configuration records # one by one as the offenses are removed from the code base. # Note that changes in the inspected code, or installation of new # versions of RuboCop, may require this file to be generated again. -# Offense count: 9 +# Offense count: 11 # Configuration parameters: AllowedMethods, AllowedPatterns, CountRepeatedAttributes. Metrics/AbcSize: Max: 48 @@ -14,19 +14,19 @@ Metrics/AbcSize: # Offense count: 2 # Configuration parameters: CountComments, CountAsOne. Metrics/ClassLength: - Max: 192 + Max: 207 -# Offense count: 5 +# Offense count: 8 # Configuration parameters: AllowedMethods, AllowedPatterns. Metrics/CyclomaticComplexity: Max: 13 -# Offense count: 16 +# Offense count: 19 # Configuration parameters: CountComments, CountAsOne, AllowedMethods, AllowedPatterns. Metrics/MethodLength: - Max: 31 + Max: 34 -# Offense count: 1 +# Offense count: 3 # Configuration parameters: AllowedMethods, AllowedPatterns. Metrics/PerceivedComplexity: Max: 13 diff --git a/lib/rspec/openapi/record_builder.rb b/lib/rspec/openapi/record_builder.rb index ea243b8a..80cf2e4f 100644 --- a/lib/rspec/openapi/record_builder.rb +++ b/lib/rspec/openapi/record_builder.rb @@ -33,7 +33,7 @@ def build(context, example:) description: description, security: security, status: response.status, - response_body: safe_parse_body(response), + response_body: safe_parse_body(response, response.media_type), response_headers: response_headers, response_content_type: response.media_type, response_content_disposition: response.header['Content-Disposition'], @@ -42,7 +42,10 @@ def build(context, example:) private - def safe_parse_body(response) + def safe_parse_body(response, media_type) + # Use raw body, because Nokogiri-parsed HTML are modified (new lines injection, meta injection, and so on) :( + return response.body if media_type == 'text/html' + response.parsed_body rescue JSON::ParserError nil diff --git a/lib/rspec/openapi/schema_builder.rb b/lib/rspec/openapi/schema_builder.rb index 9d35a825..65428b9b 100644 --- a/lib/rspec/openapi/schema_builder.rb +++ b/lib/rspec/openapi/schema_builder.rb @@ -13,6 +13,7 @@ def build(record) if record.response_body disposition = normalize_content_disposition(record.response_content_disposition) + response[:content] = { normalize_content_type(record.response_content_type) => { schema: build_property(record.response_body, disposition: disposition), diff --git a/spec/rails/app/controllers/pages_controller.rb b/spec/rails/app/controllers/pages_controller.rb new file mode 100644 index 00000000..76967cca --- /dev/null +++ b/spec/rails/app/controllers/pages_controller.rb @@ -0,0 +1,9 @@ +class PagesController < ApplicationController + def get + if params[:head] == '1' + head :no_content + else + render html: 'HelloHello'.html_safe + end + end +end diff --git a/spec/rails/config/routes.rb b/spec/rails/config/routes.rb index 19d10af1..224d5ddb 100644 --- a/spec/rails/config/routes.rb +++ b/spec/rails/config/routes.rb @@ -3,6 +3,8 @@ get '/my_engine/test' => ->(_env) { [200, { 'Content-Type' => 'text/plain' }, ['ANOTHER TEST']] } + get '/pages' => 'pages#get' + defaults format: 'json' do resources :tables, only: [:index, :show, :create, :update, :destroy] resources :images, only: [:index, :show] do diff --git a/spec/rails/doc/smart/expected.yaml b/spec/rails/doc/smart/expected.yaml index 4ce7d42b..d0bc855a 100644 --- a/spec/rails/doc/smart/expected.yaml +++ b/spec/rails/doc/smart/expected.yaml @@ -14,6 +14,21 @@ info: servers: - url: http://localhost:3000 paths: + "/pages": + get: + summary: get + tags: + - Page + responses: + '200': + description: return HTML + content: + "text/html": + schema: + type: string + example: 'HelloHello' +# '204': +# description: return no content "/tables": get: summary: index diff --git a/spec/requests/rails_smart_merge_spec.rb b/spec/requests/rails_smart_merge_spec.rb index 3a98aba5..9b754430 100644 --- a/spec/requests/rails_smart_merge_spec.rb +++ b/spec/requests/rails_smart_merge_spec.rb @@ -110,3 +110,12 @@ end end end + +RSpec.describe 'Pages', type: :request do + describe '#get' do + it 'return HTML' do + get '/pages' + expect(response.status).to eq(200) + end + end +end