diff --git a/CHANGELOG.md b/CHANGELOG.md index 0f10b2a..275caf5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,10 +1,12 @@ # Change Log ## Unreleased +### Fixed +* Fixed deeply nested resources now also filter unresolvable entries. [#177](https://github.com/contentful/contentful.rb/issues/177) ## 2.8.0 ### Added -* Add support for `sync` on environments other than `master`. +* Added support for `sync` on environments other than `master`. ## 2.7.0 ### Added diff --git a/lib/contentful/client.rb b/lib/contentful/client.rb index 1afbace..4e92d11 100644 --- a/lib/contentful/client.rb +++ b/lib/contentful/client.rb @@ -364,10 +364,9 @@ def do_build_resource(response) logger.debug(response: response) if logger configuration[:resource_builder].new( response.object, - configuration, + configuration.merge(endpoint: response.request.endpoint), (response.request.query || {}).fetch(:locale, nil) == '*', - 0, - response.request.endpoint + 0 ).run end diff --git a/lib/contentful/entry.rb b/lib/contentful/entry.rb index 31eb5a7..972c5fa 100644 --- a/lib/contentful/entry.rb +++ b/lib/contentful/entry.rb @@ -17,7 +17,7 @@ def entry? def coerce(field_id, value, includes, errors, entries = {}) if Support.link?(value) && !Support.unresolvable?(value, errors) - return build_nested_resource(value, includes, entries) + return build_nested_resource(value, includes, entries, errors) end return coerce_link_array(value, includes, errors, entries) if Support.link_array?(value) @@ -35,7 +35,8 @@ def coerce(field_id, value, includes, errors, entries = {}) def coerce_link_array(value, includes, errors, entries) items = [] value.each do |link| - items << build_nested_resource(link, includes, entries) unless Support.unresolvable?(link, errors) + nested_resource = build_nested_resource(link, includes, entries, errors) unless Support.unresolvable?(link, errors) + items << nested_resource unless nested_resource.nil? end items @@ -45,16 +46,16 @@ def coerce_link_array(value, includes, errors, entries) # in case one of the included items has a reference in an upper level, # so we can keep the include chain for that object as well # Any included object after the maximum include resolution depth will be just a Link - def build_nested_resource(value, includes, entries) + def build_nested_resource(value, includes, entries, errors) if @depth < @configuration.fetch(:max_include_resolution_depth, 20) resource = Support.resource_for_link(value, includes) - return resolve_include(resource, includes, entries) unless resource.nil? + return resolve_include(resource, includes, entries, errors) unless resource.nil? end build_link(value) end - def resolve_include(resource, includes, entries) + def resolve_include(resource, includes, entries, errors) require_relative 'resource_builder' ResourceBuilder.new( @@ -66,7 +67,7 @@ def resolve_include(resource, includes, entries) ), localized, @depth + 1, - includes + errors ).run end diff --git a/lib/contentful/resource_builder.rb b/lib/contentful/resource_builder.rb index d57db18..54a7f87 100644 --- a/lib/contentful/resource_builder.rb +++ b/lib/contentful/resource_builder.rb @@ -32,7 +32,7 @@ class ResourceBuilder attr_reader :json, :default_locale, :endpoint, :depth, :localized, :resource_mapping, :entry_mapping, :resource - def initialize(json, configuration = {}, localized = false, depth = 0, endpoint = nil) + def initialize(json, configuration = {}, localized = false, depth = 0, errors = []) @json = json @default_locale = configuration.fetch(:default_locale, ::Contentful::Client::DEFAULT_CONFIGURATION[:default_locale]) @resource_mapping = default_resource_mapping.merge(configuration.fetch(:resource_mapping, {})) @@ -40,9 +40,10 @@ def initialize(json, configuration = {}, localized = false, depth = 0, endpoint @includes_for_single = configuration.fetch(:includes_for_single, []) @localized = localized @depth = depth - @endpoint = endpoint + @endpoint = configuration.fetch(:endpoint, nil) @configuration = configuration @resource_cache = configuration[:_entries_cache] || {} + @errors = errors end # Starts the parsing process. @@ -58,8 +59,8 @@ def run private def build_array - includes = fetch_includes - errors = fetch_errors + includes = fetch_includes || @includes_for_single + errors = fetch_errors || @errors result = json['items'].map do |item| next if Support.unresolvable?(item, errors) @@ -70,8 +71,9 @@ def build_array end def build_single + return if Support.unresolvable?(json, @errors) includes = @includes_for_single - build_item(json, includes) + build_item(json, includes, @errors) end def build_item(item, includes = [], errors = []) diff --git a/spec/entry_spec.rb b/spec/entry_spec.rb index 9badd99..83332c8 100644 --- a/spec/entry_spec.rb +++ b/spec/entry_spec.rb @@ -493,6 +493,14 @@ def test_dump(nyancat) expect(entry.modules.size).to eq 2 } end + + it 'unresolvable entries get filtered from results in deeply nested objects - #177' do + vcr('entries/unresolvable_filter_deeply_nested') { + client = create_client(space: 'z471hdso7l1a', access_token: '8a0e09fe71f1cb41e8788ace86a8c8d9d084599fe43a40070f232045014d2585', dynamic_entries: :auto) + entry = client.entry('1hb8sipClkQ8ggeGaeSQWm', include: 3) + expect(entry.should_published.first.should_unpublished.size).to eq 0 + } + end end describe 'camel case' do diff --git a/spec/fixtures/vcr_cassettes/entries/unresolvable_filter_deeply_nested.yml b/spec/fixtures/vcr_cassettes/entries/unresolvable_filter_deeply_nested.yml new file mode 100644 index 0000000..45068e5 --- /dev/null +++ b/spec/fixtures/vcr_cassettes/entries/unresolvable_filter_deeply_nested.yml @@ -0,0 +1,167 @@ +--- +http_interactions: +- request: + method: get + uri: https://cdn.contentful.com/spaces/z471hdso7l1a/environments/master/content_types?limit=1000 + body: + encoding: US-ASCII + string: '' + headers: + X-Contentful-User-Agent: + - sdk contentful.rb/2.8.0; platform ruby/2.5.1; os macOS/16; + Authorization: + - Bearer 8a0e09fe71f1cb41e8788ace86a8c8d9d084599fe43a40070f232045014d2585 + Content-Type: + - application/vnd.contentful.delivery.v1+json + Accept-Encoding: + - gzip + Connection: + - close + Host: + - cdn.contentful.com + User-Agent: + - http.rb/2.2.2 + response: + status: + code: 200 + message: OK + headers: + Access-Control-Allow-Headers: + - Accept,Accept-Language,Authorization,Cache-Control,Content-Length,Content-Range,Content-Type,DNT,Destination,Expires,If-Match,If-Modified-Since,If-None-Match,Keep-Alive,Last-Modified,Origin,Pragma,Range,User-Agent,X-Http-Method-Override,X-Mx-ReqToken,X-Requested-With,X-Contentful-Version,X-Contentful-Content-Type,X-Contentful-Organization,X-Contentful-Skip-Transformation,X-Contentful-User-Agent,X-Contentful-Enable-Alpha-Feature + Access-Control-Allow-Methods: + - GET,HEAD,OPTIONS + Access-Control-Allow-Origin: + - "*" + Access-Control-Expose-Headers: + - Etag + Access-Control-Max-Age: + - '86400' + Cache-Control: + - max-age=0 + Content-Encoding: + - gzip + Content-Type: + - application/vnd.contentful.delivery.v1+json + Contentful-Api: + - cda_cached + Etag: + - W/"bd9b085d7149d27eb641ade78b5f9e95" + Server: + - Contentful + X-Content-Type-Options: + - nosniff + X-Contentful-Region: + - us-east-1 + X-Contentful-Request-Id: + - d3448e736eb5c558812b3661b39230cc + Content-Length: + - '519' + Accept-Ranges: + - bytes + Date: + - Thu, 16 Aug 2018 12:15:11 GMT + Via: + - 1.1 varnish + Age: + - '644' + Connection: + - close + X-Served-By: + - cache-hhn1528-HHN + X-Cache: + - HIT + X-Cache-Hits: + - '1' + X-Timer: + - S1534421711.465073,VS0,VE1 + Vary: + - Accept-Encoding + body: + encoding: ASCII-8BIT + string: !binary |- + H4sIAAAAAAAAA+1W3U/CMBB/568gfRayATLDGxp8Mr7ok4aYstXQ0LWz7Uim4X/32u6jIxBmYkxUGhJ21/ve3e/20ev3kSoUmvU/4BEIXWQEKDSXEhcIeLsLI6OFxgz4Y0upDc2ACCzBaEo1UGEQOAbVJDUWn61FZ3fPjXWlMhwbX5WEY3rBGIZlVkHdUb5BxmlzwD3fPJZBP1iLewI0Mfm8T6JwnSgRsRCbtKqzq59tou4gpxN7puoYbgTXhGvr0tOIJcGaJHNTCTQKwqtBcDUIp4/haBbALxxOptMnXyHPkq8pEL6lUvAUnHcqmsshxUoTuV+TrgVdeD5PFk2SLVVUcNMLpXBdU5RQlTFc3FLC7PvgOG3q5yjg3tSBooSoWNJMO4OouXg1Jpr+Mm+s1UEu75Z9I1P7uPc925uqGg9FuhKsVSvERIwZfScm6FfMFPG7C0nyllN55BJSxit25FLA0EC/VFabLiyflva/rN8vnqHVN81QOBtFw8to3HmGDir8hxm6Ps9QM6MHkEGtRc6Sl5xn+YpRtYYhbM20RQ7AIifXPyrX3pQtEz8EGi2f1db1Mz6xOreAbLCEAGEtnC73Fqe/WRdcS/s5UB1vb/4xxMLfhFjBbBINx6PuW/+gwn9ArPkZsbogVje8OiJ1RiuHXBVuld9XgF3L3q73CSJUdwcIDQAA + http_version: + recorded_at: Thu, 16 Aug 2018 12:15:11 GMT +- request: + method: get + uri: https://cdn.contentful.com/spaces/z471hdso7l1a/environments/master/entries?include=3&sys.id=1hb8sipClkQ8ggeGaeSQWm + body: + encoding: US-ASCII + string: '' + headers: + X-Contentful-User-Agent: + - sdk contentful.rb/2.8.0; platform ruby/2.5.1; os macOS/16; + Authorization: + - Bearer 8a0e09fe71f1cb41e8788ace86a8c8d9d084599fe43a40070f232045014d2585 + Content-Type: + - application/vnd.contentful.delivery.v1+json + Accept-Encoding: + - gzip + Connection: + - close + Host: + - cdn.contentful.com + User-Agent: + - http.rb/2.2.2 + response: + status: + code: 200 + message: OK + headers: + Access-Control-Allow-Headers: + - Accept,Accept-Language,Authorization,Cache-Control,Content-Length,Content-Range,Content-Type,DNT,Destination,Expires,If-Match,If-Modified-Since,If-None-Match,Keep-Alive,Last-Modified,Origin,Pragma,Range,User-Agent,X-Http-Method-Override,X-Mx-ReqToken,X-Requested-With,X-Contentful-Version,X-Contentful-Content-Type,X-Contentful-Organization,X-Contentful-Skip-Transformation,X-Contentful-User-Agent,X-Contentful-Enable-Alpha-Feature + Access-Control-Allow-Methods: + - GET,HEAD,OPTIONS + Access-Control-Allow-Origin: + - "*" + Access-Control-Expose-Headers: + - Etag + Access-Control-Max-Age: + - '86400' + Cache-Control: + - max-age=0 + Content-Encoding: + - gzip + Content-Type: + - application/vnd.contentful.delivery.v1+json + Contentful-Api: + - cda_cached + Etag: + - W/"be07dee9caef17c1b08b49fd01c2a0f0" + Server: + - Contentful + X-Content-Type-Options: + - nosniff + X-Contentful-Region: + - us-east-1 + X-Contentful-Request-Id: + - c429d5bbcc5f56956ee750efcbe815e0 + Content-Length: + - '647' + Accept-Ranges: + - bytes + Date: + - Thu, 16 Aug 2018 12:15:13 GMT + Via: + - 1.1 varnish + Age: + - '0' + Connection: + - close + X-Served-By: + - cache-hhn1550-HHN + X-Cache: + - MISS + X-Cache-Hits: + - '0' + X-Timer: + - S1534421714.565119,VS0,VE235 + Vary: + - Accept-Encoding + body: + encoding: ASCII-8BIT + string: !binary |- + H4sIAAAAAAAAA61WXW+bMBR9z6+IeF4qIFlL8xZF3fawqcvaquumanJir7EwNrVNpqzKf68/MBgKJJPGA8LX9v0499wjXkbjcSD2IpiPX9SnWsh9jtQqWHAO9oGyHd7pM5JJQJQ9MiuR4lwtQrMgOMNSb4V2jSXKtMOfxqF124piIokcbHQod8IavVy0wRhdTp8xTQMds35UdJreljnfGI+tAxjqcv7OLqItFOyCREBX5Z5D9W3qtE9g70TbdSJwviTpKnl6Qh8BulndZ57/KrErKvne39hwBCSCC41LEIdRMgmTSXR+G8XzMJ7PpmfJ7PKHf6HI4b9dQHSHOaMZojrGcQxtSRkQEvE2RKfie+XFPIohRzssMKOONCW0G0alyrls2fG8T81t6fntZMAJbSdsA4hhP6KTuxvHk4oZwW+MCKyHRZcUUJCZK18B173wWCS2rCDwV16sCRZbpHloZ8JC4dfeMR8lXgP1m9mr2d8mYYPLU7hbLOmH2fMsDVmM42x5d/2w8CdBTXpnTx9Lq93V70cz9ohzxk+Zc8s8yuQ3JBjZgbWC2EPJFWj8vYUcIgkwaWHeA8ogHOVQTz/t5fmafOf4zz1bLYvn9CFOr6u4pti6SEw3pIDI00eLct3JuosNHS3B79K4/9HrLqVTfoe1rtVhf0ocON0saZx02L+lWzCsetPk7PJ95KueynhY9zqv9CtfP7ID6qcu9dCp7GFzxmrV9aZlCNluHVRR+5Wwv47TM+3Xw4on64Hxb7S8RxfLf4MSpg5tVJGcOn7BEDbmXtdo9bGgfQpZ/z3YGL24HOuh2j+ulBUuwxLhUvHVstl/p5i11Z7V9sPoMHoFbbYo2XUJAAA= + http_version: + recorded_at: Thu, 16 Aug 2018 12:15:13 GMT +recorded_with: VCR 4.0.0