-
Notifications
You must be signed in to change notification settings - Fork 130
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Paves the way for returning what's in Amazon's Open API models
- Loading branch information
1 parent
7109a59
commit 5748ac3
Showing
7 changed files
with
377 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
# frozen_string_literal: true | ||
|
||
require "delegate" | ||
require "forwardable" | ||
|
||
module Peddler | ||
# Wraps HTTP::Response to allow custom parsing | ||
class ResponseDecorator < SimpleDelegator | ||
extend Forwardable | ||
|
||
# @!method dig(*key) | ||
# Delegates to the Hash returned by {Response#to_h} to extract a nested | ||
# value specified by the sequence of keys | ||
# | ||
# @param [String] key one or more keys | ||
# @see https://ruby-doc.org/core/Hash.html#method-i-dig | ||
def_delegator :to_h, :dig | ||
|
||
class << self | ||
# Decorates an HTTP::Response | ||
# | ||
# @param [HTTP::Response] response | ||
# @param [nil, #call] parser (if any) | ||
# @return [ResponseDecorator] | ||
def decorate(response, parser: nil) | ||
new(response).tap do |decorator| | ||
decorator.parser = parser | ||
end | ||
end | ||
end | ||
|
||
# @return [#call] | ||
attr_accessor :parser | ||
|
||
def parse | ||
parser ? parser.call(__getobj__) : __getobj__.parse | ||
end | ||
|
||
# Converts the response body to a Hash | ||
# | ||
# @return [Hash] | ||
def to_h | ||
(parser && parser.respond_to?(:to_h) ? parser : parse).to_h | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
# frozen_string_literal: true | ||
|
||
require "helper" | ||
|
||
require "peddler/api/reports_2021_06_30" | ||
|
||
module Peddler | ||
class CustomParserTest < Minitest::Test | ||
include FeatureHelpers | ||
|
||
def test_custom_parser_on_instance | ||
api.parser = custom_parser | ||
res = api.get_report("1234567") | ||
|
||
assert_nil(api_class.parser) | ||
assert(api.parser) | ||
assert(res.dig(:reportId)) | ||
end | ||
|
||
def test_custom_parser_on_class | ||
klass = Class.new(api_class) | ||
klass.parser = custom_parser | ||
access_token = request_access_token(grantless: false) | ||
api = klass.new(aws_region, access_token) | ||
res = api.get_report("1234567") | ||
|
||
assert_nil(api_class.parser) | ||
assert(klass.parser) | ||
assert(res.dig(:reportId)) | ||
end | ||
|
||
private | ||
|
||
def custom_parser | ||
->(response) { JSON.parse(response, symbolize_names: true) } | ||
end | ||
|
||
def api_class | ||
API::Reports20210630 | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
# frozen_string_literal: true | ||
|
||
require "helper" | ||
require "peddler/response_decorator" | ||
|
||
module Peddler | ||
class ResponseDecoratorTest < Minitest::Test | ||
def test_parses | ||
decorator = ResponseDecorator.decorate(response) | ||
|
||
assert_equal(payload, decorator.parse) | ||
end | ||
|
||
def test_to_h | ||
decorator = ResponseDecorator.decorate(response) | ||
|
||
assert_equal(payload, decorator.to_h) | ||
end | ||
|
||
def test_dig | ||
decorator = ResponseDecorator.decorate(response) | ||
|
||
assert(decorator.dig("foo")) | ||
end | ||
|
||
def test_parses_with_custom_parser | ||
decorator = ResponseDecorator.decorate( | ||
response, parser: ->(response) { JSON.parse(response, symbolize_names: true) } | ||
) | ||
|
||
assert_equal(payload_with_symbolized_keys, decorator.parse) | ||
end | ||
|
||
def test_to_h_with_custom_parser | ||
decorator = ResponseDecorator.decorate( | ||
response, parser: ->(response) { JSON.parse(response, symbolize_names: true) } | ||
) | ||
|
||
assert_equal(payload_with_symbolized_keys, decorator.to_h) | ||
end | ||
|
||
def test_dig_with_custom_parser | ||
decorator = ResponseDecorator.decorate( | ||
response, parser: ->(response) { JSON.parse(response, symbolize_names: true) } | ||
) | ||
|
||
assert(decorator.dig(:foo)) | ||
end | ||
|
||
private | ||
|
||
def response | ||
HTTP::Response.new( | ||
body: JSON.dump(payload), | ||
headers: { "Content-Type" => "application/json" }, | ||
status: nil, | ||
version: nil, | ||
request: nil, | ||
) | ||
end | ||
|
||
def payload | ||
{ "foo" => "bar" } | ||
end | ||
|
||
def payload_with_symbolized_keys | ||
payload.transform_keys(&:to_sym) | ||
end | ||
end | ||
end |
101 changes: 101 additions & 0 deletions
101
test/vcr_cassettes/Peddler/CustomParserTest/test_custom_parser_on_class.yml
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
Oops, something went wrong.