oas_rails 0.3.0 → 0.4.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (53) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +9 -0
  3. data/app/controllers/oas_rails/oas_rails_controller.rb +1 -1
  4. data/app/views/oas_rails/oas_rails/index.html.erb +1 -1
  5. data/lib/generators/oas_rails/config/templates/oas_rails_initializer.rb +11 -0
  6. data/lib/oas_rails/builders/content_builder.rb +55 -0
  7. data/lib/oas_rails/builders/operation_builder.rb +32 -0
  8. data/lib/oas_rails/builders/parameter_builder.rb +28 -0
  9. data/lib/oas_rails/builders/parameters_builder.rb +39 -0
  10. data/lib/oas_rails/builders/path_item_builder.rb +22 -0
  11. data/lib/oas_rails/builders/request_body_builder.rb +61 -0
  12. data/lib/oas_rails/builders/response_builder.rb +40 -0
  13. data/lib/oas_rails/builders/responses_builder.rb +58 -0
  14. data/lib/oas_rails/configuration.rb +17 -5
  15. data/lib/oas_rails/extractors/oas_route_extractor.rb +66 -0
  16. data/lib/oas_rails/extractors/render_response_extractor.rb +11 -36
  17. data/lib/oas_rails/oas_route.rb +0 -5
  18. data/lib/oas_rails/spec/components.rb +85 -0
  19. data/lib/oas_rails/spec/contact.rb +18 -0
  20. data/lib/oas_rails/spec/hashable.rb +39 -0
  21. data/lib/oas_rails/{info.rb → spec/info.rb} +30 -24
  22. data/lib/oas_rails/spec/license.rb +18 -0
  23. data/lib/oas_rails/spec/media_type.rb +84 -0
  24. data/lib/oas_rails/spec/operation.rb +25 -0
  25. data/lib/oas_rails/spec/parameter.rb +34 -0
  26. data/lib/oas_rails/spec/path_item.rb +33 -0
  27. data/lib/oas_rails/spec/paths.rb +26 -0
  28. data/lib/oas_rails/spec/reference.rb +16 -0
  29. data/lib/oas_rails/spec/request_body.rb +21 -0
  30. data/lib/oas_rails/spec/response.rb +20 -0
  31. data/lib/oas_rails/spec/responses.rb +25 -0
  32. data/lib/oas_rails/spec/server.rb +17 -0
  33. data/lib/oas_rails/spec/specable.rb +51 -0
  34. data/lib/oas_rails/spec/specification.rb +50 -0
  35. data/lib/oas_rails/spec/tag.rb +18 -0
  36. data/lib/oas_rails/utils.rb +59 -0
  37. data/lib/oas_rails/version.rb +1 -1
  38. data/lib/oas_rails.rb +41 -16
  39. metadata +29 -17
  40. data/lib/oas_rails/contact.rb +0 -12
  41. data/lib/oas_rails/license.rb +0 -11
  42. data/lib/oas_rails/media_type.rb +0 -102
  43. data/lib/oas_rails/oas_base.rb +0 -30
  44. data/lib/oas_rails/operation.rb +0 -134
  45. data/lib/oas_rails/parameter.rb +0 -47
  46. data/lib/oas_rails/path_item.rb +0 -25
  47. data/lib/oas_rails/paths.rb +0 -19
  48. data/lib/oas_rails/request_body.rb +0 -29
  49. data/lib/oas_rails/response.rb +0 -12
  50. data/lib/oas_rails/responses.rb +0 -20
  51. data/lib/oas_rails/server.rb +0 -10
  52. data/lib/oas_rails/specification.rb +0 -72
  53. data/lib/oas_rails/tag.rb +0 -17
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c9e40d4f8c810e300bbccaf190fd5143e5be804d2d30f1e86393e0478055965f
4
- data.tar.gz: 0b6de20a5280115b3550d950da6e26d8424f4d52cc15d6f46f5272224831904e
3
+ metadata.gz: 85ae0895f424fb76a5e8b50b5f56c82f526a354ec5e9ec562f76219942da99a4
4
+ data.tar.gz: bcfa9af3b8500e7204b4143173f86ef17d7c36083dfd44490047b7f0beac0c44
5
5
  SHA512:
6
- metadata.gz: 832e56a728da8974e07d2e83970f6cfd69b892b2e3a89694e08783520ae50698982a59119cf8497d0f2827ca0a4a443a04b80ef03838fe27c596c8dce30a0c1b
7
- data.tar.gz: 63d37307fc03dd0d832586ce9e9ae4bdbc1f5480b7624991b7d1aa44323bb1f94c86ccd94a523b31e67b0f3f91fb08cfed00793529294c071192b7079bd4a641
6
+ metadata.gz: 7b6543957203039aec05ac6c324bd334df075871963f60408d257084df4f908fcac5facff6c69d867d02ad3bef02596a948b784d4f70e12ae7350d6c6dcf6632
7
+ data.tar.gz: 672a557da4a80d153ecc6d37e73ddabecbc1ad03b7556470cca2f038964214fcb061cedec7866cfe1a2b7e87a3ea77496e0f82e14d182c470e24e4ebcd0e0355
data/README.md CHANGED
@@ -39,6 +39,7 @@ The goal is to minimize the effort required to create comprehensive documentatio
39
39
  - [Tag Information](#tag-information)
40
40
  - [Optional Settings](#optional-settings)
41
41
  - [Authentication Settings](#authentication-settings)
42
+ - [Default Responses (Errors)](#default-responses)
42
43
  - [Usage](#usage)
43
44
  - [Documenting Your Endpoints](#documenting-your-endpoints)
44
45
  - [Example](#example-of-documented-endpoints)
@@ -110,6 +111,14 @@ Then fill it with your data. Below are the available configuration options:
110
111
  - `config.security_schema`: The default security schema used for authentication. Choose a predefined security schema from `[:api_key_cookie, :api_key_header, :api_key_query, :basic, :bearer, :bearer_jwt, :mutual_tls]`.
111
112
  - `config.security_schemas`: Custom security schemas. Follow the [OpenAPI Specification](https://spec.openapis.org/oas/latest.html#security-scheme-object) for defining these schemas.
112
113
 
114
+ ### Default Errors
115
+
116
+ - `config.set_default_responses`: Determines whether to add default errors responses to endpoint. Default is `true`.
117
+
118
+ - `config.possible_default_responses`: Array with possible default errors.(Some will be added depending on the endpoint, example: not_found only works with show/update/delete). Default: [:not_found, :unauthorized, :forbidden]. It should be HTTP status code symbols from the list: `[:not_found, :unauthorized, :forbidden, :internal_server_error, :unprocessable_entity]`
119
+
120
+ - `config.response_body_of_default`: body for use in default responses. It must be a Hash. Default: { message: String }
121
+
113
122
  ## Usage
114
123
 
115
124
  In addition to the information provided in the initializer file and the data that can be extracted from the routes and methods automatically, it is essential to document your API in the following way. The documentation is created **with the help of YARD**, so the methods are documented with **comment tags**.
@@ -6,7 +6,7 @@ module OasRails
6
6
  respond_to do |format|
7
7
  format.html
8
8
  format.json do
9
- render json: Specification.new.to_json, status: :ok
9
+ render json: OasRails.build.to_json, status: :ok
10
10
  end
11
11
  end
12
12
  end
@@ -10,7 +10,7 @@
10
10
  </head>
11
11
  <body>
12
12
  <rapi-doc
13
- spec-url = "<%= main_app.oas_rails_path %>.json"
13
+ spec-url = "<%= OasRails::Engine.routes.find_script_name({}) %>.json"
14
14
  theme = "dark"
15
15
  bg-color="#0F172A"
16
16
  text-color= "#f7f7f7"
@@ -86,4 +86,15 @@ OasRails.configure do |config|
86
86
  # "in": "header"
87
87
  # }
88
88
  # }
89
+
90
+ # ###########################
91
+ # Default Responses (Errors)
92
+ # ###########################
93
+
94
+ # The default responses errors are setted only if the action allow it.
95
+ # Example, if you add forbidden then it will be added only if the endpoint requires authentication.
96
+ # Example: not_found will be setted to the endpoint only if the operation is a show/update/destroy action.
97
+ # config.set_default_responses = true
98
+ # config.possible_default_responses = [:not_found, :unauthorized, :forbidden]
99
+ # config.response_body_of_default = { message: String }
89
100
  end
@@ -0,0 +1,55 @@
1
+ module OasRails
2
+ module Builders
3
+ class ContentBuilder
4
+ def initialize(specification, context)
5
+ @context = context || :incoming
6
+ @specification = specification
7
+ @media_type = Spec::MediaType.new(specification)
8
+ end
9
+
10
+ def with_schema(schema)
11
+ @media_type.schema = @specification.components.add_schema(schema)
12
+
13
+ self
14
+ end
15
+
16
+ def with_examples(examples)
17
+ @media_type.examples = @specification.components.add_example(examples)
18
+
19
+ self
20
+ end
21
+
22
+ def with_examples_from_tags(tags)
23
+ @media_type.examples = @media_type.examples.merge(tags.each_with_object({}).with_index(1) do |(example, result), _index|
24
+ key = example.text.downcase.gsub(' ', '_')
25
+ value = {
26
+ "summary" => example.text,
27
+ "value" => example.content
28
+ }
29
+ result[key] = @specification.components.add_example(value)
30
+ end)
31
+
32
+ self
33
+ end
34
+
35
+ def from_model_class(klass)
36
+ return self unless klass.ancestors.include? ActiveRecord::Base
37
+
38
+ model_schema = EsquemaBuilder.send("build_#{@context}_schema", klass:)
39
+ model_schema["required"] = []
40
+ schema = { type: "object", properties: { klass.to_s.downcase => model_schema } }
41
+ examples = Spec::MediaType.search_for_examples_in_tests(klass, context: @context)
42
+ @media_type.schema = @specification.components.add_schema(schema)
43
+ @media_type.examples = @media_type.examples.merge(examples)
44
+
45
+ self
46
+ end
47
+
48
+ def build
49
+ {
50
+ "application/json": @media_type
51
+ }
52
+ end
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,32 @@
1
+ module OasRails
2
+ module Builders
3
+ class OperationBuilder
4
+ include Extractors::OasRouteExtractor
5
+
6
+ def initialize(specification)
7
+ @specification = specification
8
+ @operation = Spec::Operation.new(specification)
9
+ end
10
+
11
+ def from_oas_route(oas_route)
12
+ @operation.summary = extract_summary(oas_route:)
13
+ @operation.operation_id = extract_operation_id(oas_route:)
14
+ @operation.description = oas_route.docstring
15
+ @operation.tags = extract_tags(oas_route:)
16
+ @operation.security = extract_security(oas_route:)
17
+ @operation.parameters = ParametersBuilder.new(@specification).from_oas_route(oas_route).build
18
+ @operation.request_body = RequestBodyBuilder.new(@specification).from_oas_route(oas_route).reference
19
+ @operation.responses = ResponsesBuilder.new(@specification)
20
+ .from_oas_route(oas_route)
21
+ .add_autodiscovered_responses(oas_route)
22
+ .add_default_responses(oas_route, !@operation.security.empty?).build
23
+
24
+ self
25
+ end
26
+
27
+ def build
28
+ @operation
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,28 @@
1
+ module OasRails
2
+ module Builders
3
+ class ParameterBuilder
4
+ def initialize(specification)
5
+ @specification = specification
6
+ @parameter = Spec::Parameter.new(specification)
7
+ end
8
+
9
+ def from_path(path, param)
10
+ @parameter.name = param
11
+ @parameter.in = 'path'
12
+ @parameter.description = "#{param.split('_')[-1].titleize} of existing #{extract_word_before(path, param).singularize}."
13
+
14
+ self
15
+ end
16
+
17
+ def extract_word_before(string, param)
18
+ regex = %r{/(\w+)/\{#{param}\}}
19
+ match = string.match(regex)
20
+ match ? match[1] : nil
21
+ end
22
+
23
+ def build
24
+ @parameter
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,39 @@
1
+ module OasRails
2
+ module Builders
3
+ class ParametersBuilder
4
+ def initialize(specification)
5
+ @specification = specification
6
+ @parameters = []
7
+ end
8
+
9
+ def from_oas_route(oas_route)
10
+ parameters_from_tags(tags: oas_route.docstring.tags(:parameter))
11
+ oas_route.path_params.try(:map) do |p|
12
+ @parameters << ParameterBuilder.new(@specification).from_path(oas_route.path, p).build unless @parameters.any? { |param| param.name.to_s == p.to_s }
13
+ end
14
+
15
+ self
16
+ end
17
+
18
+ def parameters_from_tags(tags:)
19
+ tags.each do |t|
20
+ parameter = Spec::Parameter.new(@specification)
21
+ parameter.name = t.name
22
+ parameter.in = t.location
23
+ parameter.required = t.required
24
+ parameter.schema = t.schema
25
+ parameter.description = t.text
26
+ @parameters << parameter
27
+ end
28
+
29
+ self
30
+ end
31
+
32
+ def build
33
+ @parameters.map do |p|
34
+ @specification.components.add_parameter(p)
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,22 @@
1
+ module OasRails
2
+ module Builders
3
+ class PathItemBuilder
4
+ def initialize(specification)
5
+ @specification = specification
6
+ @path_item = Spec::PathItem.new(specification)
7
+ end
8
+
9
+ def from_path(path, route_extractor: Extractors::RouteExtractor)
10
+ route_extractor.host_routes_by_path(path).each do |oas_route|
11
+ @path_item.add_operation(oas_route.verb.downcase, OperationBuilder.new(@specification).from_oas_route(oas_route).build)
12
+ end
13
+
14
+ self
15
+ end
16
+
17
+ def build
18
+ @path_item
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,61 @@
1
+ module OasRails
2
+ module Builders
3
+ class RequestBodyBuilder
4
+ def initialize(specification)
5
+ @specification = specification
6
+ @request_body = Spec::RequestBody.new(specification)
7
+ end
8
+
9
+ def from_oas_route(oas_route)
10
+ tag_request_body = oas_route.docstring.tags(:request_body).first
11
+ if tag_request_body.nil? && OasRails.config.autodiscover_request_body
12
+ detect_request_body(oas_route) if %w[create update].include? oas_route.method
13
+ elsif !tag_request_body.nil?
14
+ from_tags(tag: tag_request_body, examples_tags: oas_route.docstring.tags(:request_body_example))
15
+ end
16
+
17
+ self
18
+ end
19
+
20
+ def from_tags(tag:, examples_tags: [])
21
+ if tag.klass.ancestors.include? ActiveRecord::Base
22
+ from_model_class(klass: tag.klass, description: tag.text, required: tag.required, examples_tags:)
23
+ else
24
+ @request_body.description = tag.text
25
+ @request_body.content = ContentBuilder.new(@specification, :incoming).with_schema(tag.schema).with_examples_from_tags(examples_tags).build
26
+ @request_body.required = tag.required
27
+ end
28
+
29
+ self
30
+ end
31
+
32
+ def from_model_class(klass:, **kwargs)
33
+ @request_body.description = kwargs[:description] || klass.to_s
34
+ @request_body.content = ContentBuilder.new(@specification, :incoming).from_model_class(klass).with_examples_from_tags(kwargs[:examples_tags] || {}).build
35
+ @request_body.required = kwargs[:required]
36
+
37
+ self
38
+ end
39
+
40
+ def build
41
+ return {} if @request_body.content == {}
42
+
43
+ @request_body
44
+ end
45
+
46
+ def reference
47
+ return {} if @request_body.content == {}
48
+
49
+ @specification.components.add_request_body(@request_body)
50
+ end
51
+
52
+ private
53
+
54
+ def detect_request_body(oas_route)
55
+ return unless (klass = Utils.find_model_from_route(oas_route.controller))
56
+
57
+ from_model_class(klass:, required: true)
58
+ end
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,40 @@
1
+ module OasRails
2
+ module Builders
3
+ class ResponseBuilder
4
+ def initialize(specification)
5
+ @specification = specification
6
+ @response = Spec::Response.new(specification)
7
+ end
8
+
9
+ def with_description(description)
10
+ @response.description = description
11
+
12
+ self
13
+ end
14
+
15
+ def with_content(content)
16
+ @response.content = content
17
+
18
+ self
19
+ end
20
+
21
+ def with_code(code)
22
+ @response.code = code
23
+
24
+ self
25
+ end
26
+
27
+ def from_tag(tag)
28
+ @response.code = tag.name.to_i
29
+ @response.description = tag.text
30
+ @response.content = ContentBuilder.new(@specification, :outgoing).with_schema(tag.schema).build
31
+
32
+ self
33
+ end
34
+
35
+ def build
36
+ @response
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,58 @@
1
+ module OasRails
2
+ module Builders
3
+ class ResponsesBuilder
4
+ def initialize(specification)
5
+ @specification = specification
6
+ @responses = Spec::Responses.new(specification)
7
+ end
8
+
9
+ def from_oas_route(oas_route)
10
+ oas_route.docstring.tags(:response).each do |tag|
11
+ @responses.add_response(ResponseBuilder.new(@specification).from_tag(tag).build)
12
+ end
13
+
14
+ self
15
+ end
16
+
17
+ def add_autodiscovered_responses(oas_route)
18
+ return unless OasRails.config.autodiscover_responses
19
+
20
+ new_responses = Extractors::RenderResponseExtractor.extract_responses_from_source(@specification, source: oas_route.source_string)
21
+
22
+ new_responses.each do |new_response|
23
+ @responses.add_response(new_response) if @responses.responses[new_response.code].blank?
24
+ end
25
+
26
+ self
27
+ end
28
+
29
+ def add_default_responses(oas_route, security)
30
+ return unless OasRails.config.set_default_responses
31
+
32
+ content = ContentBuilder.new(@specification, :outgoing).with_schema(Utils.hash_to_json_schema(OasRails.config.response_body_of_default)).build
33
+ common_errors = []
34
+ common_errors.push(:unauthorized, :forbidden) if security
35
+
36
+ case oas_route.method
37
+ when "show", "update", "destroy"
38
+ common_errors.push(:not_found)
39
+ when "create", "index"
40
+ # possible errors for this methods?
41
+ end
42
+
43
+ (OasRails.config.possible_default_responses & common_errors).each do |e|
44
+ code = Utils.status_to_integer(e)
45
+ response = ResponseBuilder.new(@specification).with_code(code).with_description(Utils.get_definition(code)).with_content(content).build
46
+
47
+ @responses.add_response(response) if @responses.responses[response.code].blank?
48
+ end
49
+
50
+ self
51
+ end
52
+
53
+ def build
54
+ @responses
55
+ end
56
+ end
57
+ end
58
+ end
@@ -1,10 +1,19 @@
1
1
  module OasRails
2
2
  class Configuration
3
- attr_accessor :info, :default_tags_from, :autodiscover_request_body, :autodiscover_responses, :api_path, :security_schemas, :authenticate_all_routes_by_default
3
+ attr_accessor :info,
4
+ :default_tags_from,
5
+ :autodiscover_request_body,
6
+ :autodiscover_responses,
7
+ :api_path,
8
+ :security_schemas,
9
+ :authenticate_all_routes_by_default,
10
+ :set_default_responses,
11
+ :possible_default_responses,
12
+ :response_body_of_default
4
13
  attr_reader :servers, :tags, :security_schema
5
14
 
6
15
  def initialize
7
- @info = Info.new
16
+ @info = Spec::Info.new
8
17
  @servers = default_servers
9
18
  @tags = []
10
19
  @swagger_version = '3.1.0'
@@ -15,6 +24,9 @@ module OasRails
15
24
  @authenticate_all_routes_by_default = true
16
25
  @security_schema = nil
17
26
  @security_schemas = {}
27
+ @set_default_responses = true
28
+ @possible_default_responses = [:not_found, :unauthorized, :forbidden]
29
+ @response_body_of_default = { message: String }
18
30
  end
19
31
 
20
32
  def security_schema=(value)
@@ -24,15 +36,15 @@ module OasRails
24
36
  end
25
37
 
26
38
  def default_servers
27
- [Server.new(url: "http://localhost:3000", description: "Rails Default Development Server")]
39
+ [Spec::Server.new(url: "http://localhost:3000", description: "Rails Default Development Server")]
28
40
  end
29
41
 
30
42
  def servers=(value)
31
- @servers = value.map { |s| Server.new(url: s[:url], description: s[:description]) }
43
+ @servers = value.map { |s| Spec::Server.new(url: s[:url], description: s[:description]) }
32
44
  end
33
45
 
34
46
  def tags=(value)
35
- @tags = value.map { |t| Tag.new(name: t[:name], description: t[:description]) }
47
+ @tags = value.map { |t| Spec::Tag.new(name: t[:name], description: t[:description]) }
36
48
  end
37
49
 
38
50
  def excluded_columns_incoming
@@ -0,0 +1,66 @@
1
+ module OasRails
2
+ module Extractors
3
+ module OasRouteExtractor
4
+ def extract_summary(oas_route:)
5
+ oas_route.docstring.tags(:summary).first.try(:text) || generate_crud_name(oas_route.method, oas_route.controller.downcase) || "#{oas_route.verb} #{oas_route.path}"
6
+ end
7
+
8
+ def extract_operation_id(oas_route:)
9
+ "#{oas_route.method}#{oas_route.path.gsub('/', '_').gsub(/[{}]/, '')}"
10
+ end
11
+
12
+ def extract_tags(oas_route:)
13
+ tags = oas_route.docstring.tags(:tags).first
14
+ if tags.nil?
15
+ default_tags(oas_route:)
16
+ else
17
+ tags.text.split(",").map(&:strip).map(&:titleize)
18
+ end
19
+ end
20
+
21
+ def default_tags(oas_route:)
22
+ tags = []
23
+ if OasRails.config.default_tags_from == "namespace"
24
+ tag = oas_route.path.split('/').reject(&:empty?).first.try(:titleize)
25
+ tags << tag unless tag.nil?
26
+ else
27
+ tags << oas_route.controller.titleize
28
+ end
29
+ tags
30
+ end
31
+
32
+ def extract_security(oas_route:)
33
+ return [] if oas_route.docstring.tags(:no_auth).any?
34
+
35
+ if (methods = oas_route.docstring.tags(:auth).first)
36
+ OasRails.config.security_schemas.keys.map { |key| { key => [] } }.select do |schema|
37
+ methods.types.include?(schema.keys.first.to_s)
38
+ end
39
+ elsif OasRails.config.authenticate_all_routes_by_default
40
+ OasRails.config.security_schemas.keys.map { |key| { key => [] } }
41
+ else
42
+ []
43
+ end
44
+ end
45
+
46
+ private
47
+
48
+ def generate_crud_name(method, controller)
49
+ controller_name = controller.to_s.underscore.humanize.downcase.pluralize
50
+
51
+ case method.to_sym
52
+ when :index
53
+ "List #{controller_name}"
54
+ when :show
55
+ "View #{controller_name.singularize}"
56
+ when :create
57
+ "Create new #{controller_name.singularize}"
58
+ when :update
59
+ "Update #{controller_name.singularize}"
60
+ when :destroy
61
+ "Delete #{controller_name.singularize}"
62
+ end
63
+ end
64
+ end
65
+ end
66
+ end
@@ -7,12 +7,11 @@ module OasRails
7
7
  #
8
8
  # @param source [String] The source string containing render calls.
9
9
  # @return [Array<Response>] An array of Response objects extracted from the source.
10
- def extract_responses_from_source(source:)
10
+ def extract_responses_from_source(specification, source:)
11
11
  render_calls = extract_render_calls(source)
12
+ return [Builders::ResponseBuilder.new(specification).with_description("No content").with_code(204).build] if render_calls.empty?
12
13
 
13
- return [Response.new(code: 204, description: "No Content", content: {})] if render_calls.empty?
14
-
15
- render_calls.map { |render_content, status| process_render_content(render_content.strip, status) }
14
+ render_calls.map { |render_content, status| process_render_content(specification, render_content.strip, status) }
16
15
  end
17
16
 
18
17
  private
@@ -30,14 +29,12 @@ module OasRails
30
29
  # @param content [String] The content extracted from the render call.
31
30
  # @param status [String] The status code associated with the render call.
32
31
  # @return [Response] A Response object based on the processed content and status.
33
- def process_render_content(content, status)
32
+ def process_render_content(specification, content, status)
34
33
  schema, examples = build_schema_and_examples(content)
35
- status_int = status_to_integer(status)
36
- Response.new(
37
- code: status_int,
38
- description: status_code_to_text(status_int),
39
- content: { "application/json": MediaType.new(schema:, examples:) }
40
- )
34
+ status_int = Utils.status_to_integer(status)
35
+ content = Builders::ContentBuilder.new(specification, :outgoing).with_schema(schema).with_examples(examples).build
36
+
37
+ Builders::ResponseBuilder.new(specification).with_code(status_int).with_description(Utils.status_code_to_text(status_int)).with_content(content).build
41
38
  end
42
39
 
43
40
  # Builds schema and examples based on the content type.
@@ -84,8 +81,9 @@ module OasRails
84
81
  # @return [Array<Hash, Hash>] An array where the first element is the schema and the second is the examples.
85
82
  def build_singular_model_schema_and_examples(_maybe_a_model, errors, klass, schema)
86
83
  if errors.nil?
87
- [schema, MediaType.search_for_examples_in_tests(klass:, context: :outgoing)]
84
+ [schema, Spec::MediaType.search_for_examples_in_tests(klass, context: :outgoing)]
88
85
  else
86
+ # TODO: this is not building the real schema.
89
87
  [
90
88
  {
91
89
  type: "object",
@@ -112,7 +110,7 @@ module OasRails
112
110
  # @param schema [Hash] The schema for the model.
113
111
  # @return [Array<Hash, Hash>] An array where the first element is the schema and the second is the examples.
114
112
  def build_array_model_schema_and_examples(maybe_a_model, klass, schema)
115
- examples = { maybe_a_model => { value: MediaType.search_for_examples_in_tests(klass:, context: :outgoing).values.map { |p| p.dig(:value, maybe_a_model.singularize.to_sym) } } }
113
+ examples = { maybe_a_model => { value: Spec::MediaType.search_for_examples_in_tests(klass, context: :outgoing).values.map { |p| p.dig(:value, maybe_a_model.singularize.to_sym) } } }
116
114
  [{ type: "array", items: schema }, examples]
117
115
  end
118
116
 
@@ -144,29 +142,6 @@ module OasRails
144
142
 
145
143
  structure
146
144
  end
147
-
148
- # Converts a status symbol or string to an integer.
149
- #
150
- # @param status [String, Symbol, nil] The status to convert.
151
- # @return [Integer] The status code as an integer.
152
- def status_to_integer(status)
153
- return 200 if status.nil?
154
-
155
- if status.to_s =~ /^\d+$/
156
- status.to_i
157
- else
158
- status = "unprocessable_content" if status == "unprocessable_entity"
159
- Rack::Utils::SYMBOL_TO_STATUS_CODE[status.to_sym]
160
- end
161
- end
162
-
163
- # Converts a status code to its corresponding text description.
164
- #
165
- # @param status_code [Integer] The status code.
166
- # @return [String] The text description of the status code.
167
- def status_code_to_text(status_code)
168
- Rack::Utils::HTTP_STATUS_CODES[status_code] || "Unknown Status Code"
169
- end
170
145
  end
171
146
  end
172
147
  end
@@ -41,10 +41,5 @@ module OasRails
41
41
  def controller_path_extractor(controller)
42
42
  Rails.root.join("app/controllers/#{controller}_controller.rb").to_s
43
43
  end
44
-
45
- def detect_request_body
46
- klass = @controller.singularize.camelize.constantize
47
- RequestBody.from_model_class(klass:, required: true)
48
- end
49
44
  end
50
45
  end