Skip to content

Commit

Permalink
Introduce Post-Processing Hook for OpenAPI Spec Customization (#206)
Browse files Browse the repository at this point in the history
  • Loading branch information
ipepe authored Apr 11, 2024
1 parent cdda8fc commit 3bde928
Show file tree
Hide file tree
Showing 6 changed files with 31 additions and 7 deletions.
7 changes: 7 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,13 @@ RSpec::OpenAPI.ignored_path_params = %i[controller action format]
# In that case, you can specify the paths to ignore.
# String or Regexp is acceptable.
RSpec::OpenAPI.ignored_paths = ["/admin/full/path/", Regexp.new("^/_internal/")]

# Your custom post-processing hook (like unrandomizing IDs)
RSpec::OpenAPI.post_process_hook = -> (path, records, spec) do
RSpec::OpenAPI::HashHelper.matched_paths(spec, 'paths.*.*.responses.*.content.*.*.*.id').each do |paths|
spec.dig(*paths[0..-2]).merge!(id: '123')
end
end
```

### Can I use rspec-openapi with `$ref` to minimize duplication of schema?
Expand Down
4 changes: 3 additions & 1 deletion lib/rspec/openapi.rb
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ module RSpec::OpenAPI
@path_records = Hash.new { |h, k| h[k] = [] }
@ignored_path_params = %i[controller action format]
@ignored_paths = []
@post_process_hook = nil

# This is the configuraion override file name we look for within each path.
@config_filename = 'rspec_openapi.rb'
Expand All @@ -54,7 +55,8 @@ class << self
:response_headers,
:path_records,
:ignored_paths,
:ignored_path_params
:ignored_path_params,
:post_process_hook

attr_reader :config_filename
end
Expand Down
21 changes: 16 additions & 5 deletions lib/rspec/openapi/result_recorder.rb
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,8 @@ def record_results!
rescue StandardError, NotImplementedError => e # e.g. SchemaBuilder raises a NotImplementedError
@error_records[e] = record # Avoid failing the build
end
RSpec::OpenAPI::SchemaCleaner.cleanup_conflicting_security_parameters!(spec)
RSpec::OpenAPI::SchemaCleaner.cleanup!(spec, new_from_zero)
RSpec::OpenAPI::ComponentsUpdater.update!(spec, new_from_zero)
RSpec::OpenAPI::SchemaCleaner.cleanup_empty_required_array!(spec)
RSpec::OpenAPI::SchemaSorter.deep_sort!(spec)
cleanup_schema!(new_from_zero, spec)
execute_post_process_hook(path, records, spec)
end
end
end
Expand All @@ -49,4 +46,18 @@ def error_message
#{@error_records.map { |e, record| "#{e.inspect}: #{record.inspect}" }.join("\n")}
ERR_MSG
end

private

def execute_post_process_hook(path, records, spec)
RSpec::OpenAPI.post_process_hook.call(path, records, spec) if RSpec::OpenAPI.post_process_hook.is_a?(Proc)
end

def cleanup_schema!(new_from_zero, spec)
RSpec::OpenAPI::SchemaCleaner.cleanup_conflicting_security_parameters!(spec)
RSpec::OpenAPI::SchemaCleaner.cleanup!(spec, new_from_zero)
RSpec::OpenAPI::ComponentsUpdater.update!(spec, new_from_zero)
RSpec::OpenAPI::SchemaCleaner.cleanup_empty_required_array!(spec)
RSpec::OpenAPI::SchemaSorter.deep_sort!(spec)
end
end
3 changes: 2 additions & 1 deletion spec/apps/rails/doc/openapi.json
Original file line number Diff line number Diff line change
Expand Up @@ -1139,5 +1139,6 @@
"name": "Secret-Key"
}
}
}
},
"custom_field": "custom_value"
}
1 change: 1 addition & 0 deletions spec/apps/rails/doc/openapi.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -742,3 +742,4 @@ components:
type: apiKey
in: header
name: Secret-Key
custom_field: custom_value
2 changes: 2 additions & 0 deletions spec/integration_tests/rails_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@
},
}

RSpec::OpenAPI.post_process_hook = ->(_path, _records, spec) { spec['custom_field'] = 'custom_value' }

class TablesIndexTest < ActionDispatch::IntegrationTest
i_suck_and_my_tests_are_order_dependent!
openapi!
Expand Down

0 comments on commit 3bde928

Please sign in to comment.