Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Introduce Post-Processing Hook for OpenAPI Spec Customization #206

Merged
merged 2 commits into from
Apr 11, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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