contentful 2.14.0 → 2.15.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.rubocop.yml +3 -0
- data/.ruby-version +1 -0
- data/.travis.yml +1 -0
- data/CHANGELOG.md +24 -0
- data/README.md +2 -0
- data/contentful.gemspec +2 -2
- data/contentful.rb.sublime-project +9 -0
- data/contentful.rb.sublime-workspace +2154 -0
- data/lib/contentful/array.rb +9 -4
- data/lib/contentful/array_like.rb +2 -2
- data/lib/contentful/asset.rb +10 -4
- data/lib/contentful/base_resource.rb +15 -1
- data/lib/contentful/client.rb +4 -3
- data/lib/contentful/entry.rb +2 -1
- data/lib/contentful/fields_resource.rb +1 -5
- data/lib/contentful/request.rb +6 -1
- data/lib/contentful/resource_builder.rb +4 -3
- data/lib/contentful/version.rb +1 -1
- data/spec/array_spec.rb +29 -0
- data/spec/client_class_spec.rb +1 -1
- data/spec/client_configuration_spec.rb +17 -0
- data/spec/entry_spec.rb +30 -0
- data/spec/fixtures/vcr_cassettes/entries/unresolvable_assets.yml +89 -0
- data/spec/fixtures/vcr_cassettes/query_array_1.yml +89 -0
- data/spec/fixtures/vcr_cassettes/query_array_2.yml +89 -0
- metadata +49 -36
    
        data/lib/contentful/array.rb
    CHANGED
    
    | @@ -11,13 +11,15 @@ module Contentful | |
| 11 11 |  | 
| 12 12 | 
             
                include Contentful::ArrayLike
         | 
| 13 13 |  | 
| 14 | 
            -
                attr_reader :total, :limit, :skip, :items, :endpoint
         | 
| 14 | 
            +
                attr_reader :total, :limit, :skip, :items, :endpoint, :query
         | 
| 15 15 |  | 
| 16 16 | 
             
                def initialize(item = nil,
         | 
| 17 17 | 
             
                               configuration = {
         | 
| 18 18 | 
             
                                 default_locale: Contentful::Client::DEFAULT_CONFIGURATION[:default_locale]
         | 
| 19 19 | 
             
                               },
         | 
| 20 | 
            -
                               endpoint = '', | 
| 20 | 
            +
                               endpoint = '',
         | 
| 21 | 
            +
                               query = {},
         | 
| 22 | 
            +
                               *)
         | 
| 21 23 | 
             
                  super(item, configuration)
         | 
| 22 24 |  | 
| 23 25 | 
             
                  @endpoint = endpoint
         | 
| @@ -25,11 +27,12 @@ module Contentful | |
| 25 27 | 
             
                  @limit = item.fetch('limit', nil)
         | 
| 26 28 | 
             
                  @skip = item.fetch('skip', nil)
         | 
| 27 29 | 
             
                  @items = item.fetch('items', [])
         | 
| 30 | 
            +
                  @query = query
         | 
| 28 31 | 
             
                end
         | 
| 29 32 |  | 
| 30 33 | 
             
                # @private
         | 
| 31 34 | 
             
                def marshal_dump
         | 
| 32 | 
            -
                  super.merge(endpoint: endpoint)
         | 
| 35 | 
            +
                  super.merge(endpoint: endpoint, query: query)
         | 
| 33 36 | 
             
                end
         | 
| 34 37 |  | 
| 35 38 | 
             
                # @private
         | 
| @@ -39,6 +42,7 @@ module Contentful | |
| 39 42 | 
             
                  @total = raw.fetch('total', nil)
         | 
| 40 43 | 
             
                  @limit = raw.fetch('limit', nil)
         | 
| 41 44 | 
             
                  @skip = raw.fetch('skip', nil)
         | 
| 45 | 
            +
                  @query = raw_object[:query]
         | 
| 42 46 | 
             
                  @items = raw.fetch('items', []).map do |item|
         | 
| 43 47 | 
             
                    require_relative 'resource_builder'
         | 
| 44 48 | 
             
                    ResourceBuilder.new(
         | 
| @@ -72,7 +76,8 @@ module Contentful | |
| 72 76 | 
             
                    'Asset' => 'assets',
         | 
| 73 77 | 
             
                    'Locale' => 'locales'
         | 
| 74 78 | 
             
                  }
         | 
| 75 | 
            -
             | 
| 79 | 
            +
             | 
| 80 | 
            +
                  client.public_send(plurals[items.first.type], query.merge(limit: limit, skip: new_skip))
         | 
| 76 81 | 
             
                end
         | 
| 77 82 | 
             
              end
         | 
| 78 83 | 
             
            end
         | 
    
        data/lib/contentful/asset.rb
    CHANGED
    
    | @@ -10,10 +10,7 @@ module Contentful | |
| 10 10 |  | 
| 11 11 | 
             
                # @private
         | 
| 12 12 | 
             
                def marshal_dump
         | 
| 13 | 
            -
                   | 
| 14 | 
            -
                    configuration: @configuration,
         | 
| 15 | 
            -
                    raw: raw
         | 
| 16 | 
            -
                  }
         | 
| 13 | 
            +
                  super.merge(raw: raw)
         | 
| 17 14 | 
             
                end
         | 
| 18 15 |  | 
| 19 16 | 
             
                # @private
         | 
| @@ -23,6 +20,11 @@ module Contentful | |
| 23 20 | 
             
                  define_asset_methods!
         | 
| 24 21 | 
             
                end
         | 
| 25 22 |  | 
| 23 | 
            +
                # @private
         | 
| 24 | 
            +
                def known_link?(*)
         | 
| 25 | 
            +
                  false
         | 
| 26 | 
            +
                end
         | 
| 27 | 
            +
             | 
| 26 28 | 
             
                # @private
         | 
| 27 29 | 
             
                def inspect
         | 
| 28 30 | 
             
                  "<#{repr_name} id='#{sys[:id]}' url='#{url}'>"
         | 
| @@ -91,6 +93,10 @@ module Contentful | |
| 91 93 | 
             
                end
         | 
| 92 94 |  | 
| 93 95 | 
             
                def define_asset_methods!
         | 
| 96 | 
            +
                  define_singleton_method :title do
         | 
| 97 | 
            +
                    fields.fetch(:title, nil)
         | 
| 98 | 
            +
                  end
         | 
| 99 | 
            +
             | 
| 94 100 | 
             
                  define_singleton_method :description do
         | 
| 95 101 | 
             
                    fields.fetch(:description, nil)
         | 
| 96 102 | 
             
                  end
         | 
| @@ -31,14 +31,28 @@ module Contentful | |
| 31 31 |  | 
| 32 32 | 
             
                # @private
         | 
| 33 33 | 
             
                def marshal_dump
         | 
| 34 | 
            +
                  entry_mapping = @configuration[:entry_mapping].each_with_object({}) do |(k, v), res|
         | 
| 35 | 
            +
                    res[k] = v.to_s
         | 
| 36 | 
            +
                  end
         | 
| 37 | 
            +
             | 
| 34 38 | 
             
                  {
         | 
| 35 | 
            -
                     | 
| 39 | 
            +
                    # loggers usually have a file handle that can't be marshalled, so let's not return that
         | 
| 40 | 
            +
                    configuration: @configuration.merge(entry_mapping: entry_mapping, logger: nil),
         | 
| 36 41 | 
             
                    raw: raw
         | 
| 37 42 | 
             
                  }
         | 
| 38 43 | 
             
                end
         | 
| 39 44 |  | 
| 40 45 | 
             
                # @private
         | 
| 41 46 | 
             
                def marshal_load(raw_object)
         | 
| 47 | 
            +
                  raw_object[:configuration][:entry_mapping] = raw_object[:configuration].fetch(:entry_mapping, {}).each_with_object({}) do |(k, v), res|
         | 
| 48 | 
            +
                    begin
         | 
| 49 | 
            +
                      v = v.to_s unless v.is_a?(::String)
         | 
| 50 | 
            +
                      res[k] = v.split('::').inject(Object) { |o, c| o.const_get c }
         | 
| 51 | 
            +
                    rescue
         | 
| 52 | 
            +
                      next
         | 
| 53 | 
            +
                    end
         | 
| 54 | 
            +
                  end
         | 
| 55 | 
            +
             | 
| 42 56 | 
             
                  @raw = raw_object[:raw]
         | 
| 43 57 | 
             
                  @configuration = raw_object[:configuration]
         | 
| 44 58 | 
             
                  @default_locale = @configuration[:default_locale]
         | 
    
        data/lib/contentful/client.rb
    CHANGED
    
    | @@ -30,7 +30,6 @@ module Contentful | |
| 30 30 | 
             
                  raw_mode: false,
         | 
| 31 31 | 
             
                  gzip_encoded: true,
         | 
| 32 32 | 
             
                  logger: false,
         | 
| 33 | 
            -
                  log_level: Logger::INFO,
         | 
| 34 33 | 
             
                  proxy_host: nil,
         | 
| 35 34 | 
             
                  proxy_username: nil,
         | 
| 36 35 | 
             
                  proxy_password: nil,
         | 
| @@ -105,7 +104,7 @@ module Contentful | |
| 105 104 | 
             
                # @private
         | 
| 106 105 | 
             
                def setup_logger
         | 
| 107 106 | 
             
                  @logger = configuration[:logger]
         | 
| 108 | 
            -
                  logger.level = configuration[:log_level] if logger
         | 
| 107 | 
            +
                  logger.level = configuration[:log_level] if logger && configuration.key?(:log_level)
         | 
| 109 108 | 
             
                end
         | 
| 110 109 |  | 
| 111 110 | 
             
                # @private
         | 
| @@ -386,7 +385,9 @@ module Contentful | |
| 386 385 | 
             
                    response.object,
         | 
| 387 386 | 
             
                    configuration.merge(endpoint: response.request.endpoint),
         | 
| 388 387 | 
             
                    (response.request.query || {}).fetch(:locale, nil) == '*',
         | 
| 389 | 
            -
                    0
         | 
| 388 | 
            +
                    0,
         | 
| 389 | 
            +
                    [],
         | 
| 390 | 
            +
                    response.request.query || {}
         | 
| 390 391 | 
             
                  ).run
         | 
| 391 392 | 
             
                end
         | 
| 392 393 |  | 
    
        data/lib/contentful/entry.rb
    CHANGED
    
    | @@ -17,7 +17,8 @@ module Contentful | |
| 17 17 | 
             
                private
         | 
| 18 18 |  | 
| 19 19 | 
             
                def coerce(field_id, value, includes, errors, entries = {})
         | 
| 20 | 
            -
                  if Support.link?(value) | 
| 20 | 
            +
                  if Support.link?(value)
         | 
| 21 | 
            +
                    return nil if Support.unresolvable?(value, errors)
         | 
| 21 22 | 
             
                    return build_nested_resource(value, includes, entries, errors)
         | 
| 22 23 | 
             
                  end
         | 
| 23 24 | 
             
                  return coerce_link_array(value, includes, errors, entries) if Support.link_array?(value)
         | 
    
        data/lib/contentful/request.rb
    CHANGED
    
    | @@ -13,7 +13,12 @@ module Contentful | |
| 13 13 |  | 
| 14 14 | 
             
                  if id
         | 
| 15 15 | 
             
                    @type = :single
         | 
| 16 | 
            -
                     | 
| 16 | 
            +
                    # Given the deprecation of `URI::escape` and `URI::encode`
         | 
| 17 | 
            +
                    # it is needed to replace it with `URI::encode_www_form_component`.
         | 
| 18 | 
            +
                    # This method, does replace spaces with `+` instead of `%20`.
         | 
| 19 | 
            +
                    # Therefore, to keep backwards compatibility, we're replacing the resulting `+`
         | 
| 20 | 
            +
                    # back with `%20`.
         | 
| 21 | 
            +
                    @id = URI.encode_www_form_component(id).gsub('+', '%20')
         | 
| 17 22 | 
             
                  else
         | 
| 18 23 | 
             
                    @type = :multi
         | 
| 19 24 | 
             
                    @id = nil
         | 
| @@ -32,9 +32,9 @@ module Contentful | |
| 32 32 | 
             
                # Buildable Resources
         | 
| 33 33 | 
             
                BUILDABLES = %w[Entry Asset ContentType Space DeletedEntry DeletedAsset Locale].freeze
         | 
| 34 34 |  | 
| 35 | 
            -
                attr_reader :json, :default_locale, :endpoint, :depth, :localized, :resource_mapping, :entry_mapping, :resource
         | 
| 35 | 
            +
                attr_reader :json, :default_locale, :endpoint, :depth, :localized, :resource_mapping, :entry_mapping, :resource, :query
         | 
| 36 36 |  | 
| 37 | 
            -
                def initialize(json, configuration = {}, localized = false, depth = 0, errors = [])
         | 
| 37 | 
            +
                def initialize(json, configuration = {}, localized = false, depth = 0, errors = [], query = {})
         | 
| 38 38 | 
             
                  @json = json
         | 
| 39 39 | 
             
                  @default_locale = configuration.fetch(:default_locale, ::Contentful::Client::DEFAULT_CONFIGURATION[:default_locale])
         | 
| 40 40 | 
             
                  @resource_mapping = default_resource_mapping.merge(configuration.fetch(:resource_mapping, {}))
         | 
| @@ -46,6 +46,7 @@ module Contentful | |
| 46 46 | 
             
                  @configuration = configuration
         | 
| 47 47 | 
             
                  @resource_cache = configuration[:_entries_cache] || {}
         | 
| 48 48 | 
             
                  @errors = errors
         | 
| 49 | 
            +
                  @query = query
         | 
| 49 50 | 
             
                end
         | 
| 50 51 |  | 
| 51 52 | 
             
                # Starts the parsing process.
         | 
| @@ -69,7 +70,7 @@ module Contentful | |
| 69 70 | 
             
                    build_item(item, includes, errors)
         | 
| 70 71 | 
             
                  end
         | 
| 71 72 | 
             
                  array_class = fetch_array_class
         | 
| 72 | 
            -
                  array_class.new(json.merge('items' => result), @configuration, endpoint)
         | 
| 73 | 
            +
                  array_class.new(json.merge('items' => result), @configuration, endpoint, query)
         | 
| 73 74 | 
             
                end
         | 
| 74 75 |  | 
| 75 76 | 
             
                def build_single
         | 
    
        data/lib/contentful/version.rb
    CHANGED
    
    
    
        data/spec/array_spec.rb
    CHANGED
    
    | @@ -36,6 +36,16 @@ describe Contentful::Array do | |
| 36 36 | 
             
                end
         | 
| 37 37 | 
             
              end
         | 
| 38 38 |  | 
| 39 | 
            +
              describe '#[]' do
         | 
| 40 | 
            +
                it 'provides access to items by index' do
         | 
| 41 | 
            +
                  expect(array[0]).to be_a Contentful::BaseResource
         | 
| 42 | 
            +
                end
         | 
| 43 | 
            +
             | 
| 44 | 
            +
                it 'provides access to items by two indices' do
         | 
| 45 | 
            +
                  expect(array[0, 4]).to eq array.items
         | 
| 46 | 
            +
                end
         | 
| 47 | 
            +
              end
         | 
| 48 | 
            +
             | 
| 39 49 | 
             
              describe '#each' do
         | 
| 40 50 | 
             
                it 'is an Enumerator' do
         | 
| 41 51 | 
             
                  expect(array.each).to be_a Enumerator
         | 
| @@ -63,6 +73,25 @@ describe Contentful::Array do | |
| 63 73 | 
             
                it 'will return false if #request not available' do
         | 
| 64 74 | 
             
                  expect(Contentful::Array.new({}).reload).to be_falsey
         | 
| 65 75 | 
             
                end
         | 
| 76 | 
            +
             | 
| 77 | 
            +
                it 'respects query parameters' do
         | 
| 78 | 
            +
                  array_page_1 = vcr('query_array_1') { client.entries(content_type: 'cat', limit: 1) }
         | 
| 79 | 
            +
                  array_page_2 = vcr('query_array_2') { array_page_1.next_page(client) }
         | 
| 80 | 
            +
             | 
| 81 | 
            +
                  expect(array_page_1).to be_a Contentful::Array
         | 
| 82 | 
            +
                  expect(array_page_2).to be_a Contentful::Array
         | 
| 83 | 
            +
             | 
| 84 | 
            +
                  expect(array_page_1.query).to include(content_type: 'cat')
         | 
| 85 | 
            +
                  expect(array_page_2.query).to include(content_type: 'cat')
         | 
| 86 | 
            +
             | 
| 87 | 
            +
                  expect(array_page_1.size).to eq 1
         | 
| 88 | 
            +
                  expect(array_page_2.size).to eq 1
         | 
| 89 | 
            +
             | 
| 90 | 
            +
                  expect(array_page_1[0].content_type.id).to eq 'cat'
         | 
| 91 | 
            +
                  expect(array_page_2[0].content_type.id).to eq 'cat'
         | 
| 92 | 
            +
             | 
| 93 | 
            +
                  expect(array_page_1[0].id).not_to eq array_page_2[0].id
         | 
| 94 | 
            +
                end
         | 
| 66 95 | 
             
              end
         | 
| 67 96 |  | 
| 68 97 | 
             
              describe 'marshalling' do
         | 
    
        data/spec/client_class_spec.rb
    CHANGED
    
    
| @@ -48,6 +48,23 @@ describe 'Client Configuration Options' do | |
| 48 48 | 
             
                end
         | 
| 49 49 | 
             
              end
         | 
| 50 50 |  | 
| 51 | 
            +
              describe ':log_level' do
         | 
| 52 | 
            +
             | 
| 53 | 
            +
                let(:logger) { Logger.new(STDOUT) }
         | 
| 54 | 
            +
             | 
| 55 | 
            +
                it 'changes the level of the logger instance when given' do
         | 
| 56 | 
            +
                  expect do
         | 
| 57 | 
            +
                    create_client(logger: logger, log_level: ::Logger::WARN)
         | 
| 58 | 
            +
                  end.to change { logger.level }.from(::Logger::DEBUG).to(::Logger::WARN)
         | 
| 59 | 
            +
                end
         | 
| 60 | 
            +
             | 
| 61 | 
            +
                it 'does not change the level of the logger instance when not given' do
         | 
| 62 | 
            +
                  expect do
         | 
| 63 | 
            +
                    create_client(logger: logger)
         | 
| 64 | 
            +
                  end.not_to change { logger.level }
         | 
| 65 | 
            +
                end
         | 
| 66 | 
            +
              end
         | 
| 67 | 
            +
             | 
| 51 68 | 
             
              describe ':dynamic_entries' do
         | 
| 52 69 | 
             
                before :each do
         | 
| 53 70 | 
             
                  Contentful::ContentTypeCache.clear!
         | 
    
        data/spec/entry_spec.rb
    CHANGED
    
    | @@ -160,6 +160,7 @@ describe Contentful::Entry do | |
| 160 160 | 
             
              describe 'can be marshalled' do
         | 
| 161 161 | 
             
                def test_dump(nyancat)
         | 
| 162 162 | 
             
                  dump = Marshal.dump(nyancat)
         | 
| 163 | 
            +
                  yield if block_given?
         | 
| 163 164 | 
             
                  new_cat = Marshal.load(dump)
         | 
| 164 165 |  | 
| 165 166 | 
             
                  # Attributes
         | 
| @@ -184,6 +185,14 @@ describe Contentful::Entry do | |
| 184 185 | 
             
                  expect(new_cat.image.file.url).to eq "//images.contentful.com/cfexampleapi/4gp6taAwW4CmSgumq2ekUm/9da0cd1936871b8d72343e895a00d611/Nyan_cat_250px_frame.png"
         | 
| 185 186 | 
             
                end
         | 
| 186 187 |  | 
| 188 | 
            +
                it 'marshals properly when entry_mapping changed' do
         | 
| 189 | 
            +
                  vcr('entry/marshall') {
         | 
| 190 | 
            +
                    class TestEntryMapping; end
         | 
| 191 | 
            +
                    nyancat = create_client(gzip_encoded: false, max_include_resolution_depth: 2, entry_mapping: { 'irrelevant_model' => TestEntryMapping }).entries(include: 2, 'sys.id' => 'nyancat').first
         | 
| 192 | 
            +
                    test_dump(nyancat) { Object.send(:remove_const, :TestEntryMapping) }
         | 
| 193 | 
            +
                  }
         | 
| 194 | 
            +
                end
         | 
| 195 | 
            +
             | 
| 187 196 | 
             
                it 'marshals properly' do
         | 
| 188 197 | 
             
                  vcr('entry/marshall') {
         | 
| 189 198 | 
             
                    nyancat = create_client(gzip_encoded: false, max_include_resolution_depth: 2).entries(include: 2, 'sys.id' => 'nyancat').first
         | 
| @@ -191,6 +200,16 @@ describe Contentful::Entry do | |
| 191 200 | 
             
                  }
         | 
| 192 201 | 
             
                end
         | 
| 193 202 |  | 
| 203 | 
            +
                it 'marshals with a logger set but keeps the instance' do
         | 
| 204 | 
            +
                  logger = Logger.new(IO::NULL)
         | 
| 205 | 
            +
                  vcr('entry/marshall') {
         | 
| 206 | 
            +
                    nyancat = create_client(gzip_encoded: false, max_include_resolution_depth: 2, logger: logger).entries(include: 2, 'sys.id' => 'nyancat').first
         | 
| 207 | 
            +
                    expect(nyancat.instance_variable_get(:@configuration)[:logger]).to eq(logger)
         | 
| 208 | 
            +
                    test_dump(nyancat)
         | 
| 209 | 
            +
                    expect(nyancat.instance_variable_get(:@configuration)[:logger]).to eq(logger)
         | 
| 210 | 
            +
                  }
         | 
| 211 | 
            +
                end
         | 
| 212 | 
            +
             | 
| 194 213 | 
             
                it 'can remarshall an unmarshalled object' do
         | 
| 195 214 | 
             
                  vcr('entry/marshall') {
         | 
| 196 215 | 
             
                    nyancat = create_client(max_include_resolution_depth: 2).entries(include: 2, 'sys.id' => 'nyancat').first
         | 
| @@ -477,6 +496,17 @@ describe Contentful::Entry do | |
| 477 496 | 
             
              end
         | 
| 478 497 |  | 
| 479 498 | 
             
              describe 'issues' do
         | 
| 499 | 
            +
                it 'filters out unresolvable assets' do
         | 
| 500 | 
            +
                  vcr('entries/unresolvable_assets') {
         | 
| 501 | 
            +
                    client = create_client(space: 'facgnwwgj5fe', access_token: '4d0f55d940975f78139daae5d965b463c0816e88ad16062d2c1ee3d6cb930521')
         | 
| 502 | 
            +
                    entry = client.entry('gLVzQlb09IeOeU181fwtz')
         | 
| 503 | 
            +
             | 
| 504 | 
            +
                    expect(entry.single_asset).to be_nil
         | 
| 505 | 
            +
                    expect(entry.multi_asset.size).to eq 1
         | 
| 506 | 
            +
                    expect(entry.raw["fields"]["multiAsset"].size).to eq 2
         | 
| 507 | 
            +
                  }
         | 
| 508 | 
            +
                end
         | 
| 509 | 
            +
             | 
| 480 510 | 
             
                it 'Symbol/Text field with null values should be serialized as nil - #117' do
         | 
| 481 511 | 
             
                  vcr('entries/issue_117') {
         | 
| 482 512 | 
             
                    client = create_client(space: '8jbbayggj9gj', access_token: '4ce0108f04e55c76476ba84ab0e6149734db73d67cd1b429323ef67f00977e07')
         | 
| @@ -0,0 +1,89 @@ | |
| 1 | 
            +
            ---
         | 
| 2 | 
            +
            http_interactions:
         | 
| 3 | 
            +
            - request:
         | 
| 4 | 
            +
                method: get
         | 
| 5 | 
            +
                uri: https://cdn.contentful.com/spaces/facgnwwgj5fe/environments/master/entries?sys.id=gLVzQlb09IeOeU181fwtz
         | 
| 6 | 
            +
                body:
         | 
| 7 | 
            +
                  encoding: UTF-8
         | 
| 8 | 
            +
                  string: ''
         | 
| 9 | 
            +
                headers:
         | 
| 10 | 
            +
                  X-Contentful-User-Agent:
         | 
| 11 | 
            +
                  - sdk contentful.rb/2.15.1; platform ruby/2.6.3; os macOS/18;
         | 
| 12 | 
            +
                  Authorization:
         | 
| 13 | 
            +
                  - Bearer 4d0f55d940975f78139daae5d965b463c0816e88ad16062d2c1ee3d6cb930521
         | 
| 14 | 
            +
                  Content-Type:
         | 
| 15 | 
            +
                  - application/vnd.contentful.delivery.v1+json
         | 
| 16 | 
            +
                  Accept-Encoding:
         | 
| 17 | 
            +
                  - gzip
         | 
| 18 | 
            +
                  Connection:
         | 
| 19 | 
            +
                  - close
         | 
| 20 | 
            +
                  Host:
         | 
| 21 | 
            +
                  - cdn.contentful.com
         | 
| 22 | 
            +
                  User-Agent:
         | 
| 23 | 
            +
                  - http.rb/4.2.0
         | 
| 24 | 
            +
              response:
         | 
| 25 | 
            +
                status:
         | 
| 26 | 
            +
                  code: 200
         | 
| 27 | 
            +
                  message: OK
         | 
| 28 | 
            +
                headers:
         | 
| 29 | 
            +
                  Access-Control-Allow-Headers:
         | 
| 30 | 
            +
                  - 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
         | 
| 31 | 
            +
                  Access-Control-Allow-Methods:
         | 
| 32 | 
            +
                  - GET,HEAD,OPTIONS
         | 
| 33 | 
            +
                  Access-Control-Allow-Origin:
         | 
| 34 | 
            +
                  - "*"
         | 
| 35 | 
            +
                  Access-Control-Expose-Headers:
         | 
| 36 | 
            +
                  - Etag
         | 
| 37 | 
            +
                  Access-Control-Max-Age:
         | 
| 38 | 
            +
                  - '86400'
         | 
| 39 | 
            +
                  Cf-Environment-Id:
         | 
| 40 | 
            +
                  - master
         | 
| 41 | 
            +
                  Cf-Environment-Uuid:
         | 
| 42 | 
            +
                  - 7df33faa-1d21-4dea-83e9-9ebda5f47ba9
         | 
| 43 | 
            +
                  Cf-Organization-Id:
         | 
| 44 | 
            +
                  - 4SsuxQCaMaemfIms52Jr8s
         | 
| 45 | 
            +
                  Cf-Space-Id:
         | 
| 46 | 
            +
                  - facgnwwgj5fe
         | 
| 47 | 
            +
                  Content-Encoding:
         | 
| 48 | 
            +
                  - gzip
         | 
| 49 | 
            +
                  Content-Type:
         | 
| 50 | 
            +
                  - application/vnd.contentful.delivery.v1+json
         | 
| 51 | 
            +
                  Contentful-Api:
         | 
| 52 | 
            +
                  - cda_cached
         | 
| 53 | 
            +
                  Etag:
         | 
| 54 | 
            +
                  - W/"14036385179019726604"
         | 
| 55 | 
            +
                  Server:
         | 
| 56 | 
            +
                  - Contentful
         | 
| 57 | 
            +
                  X-Content-Type-Options:
         | 
| 58 | 
            +
                  - nosniff
         | 
| 59 | 
            +
                  X-Contentful-Region:
         | 
| 60 | 
            +
                  - us-east-1
         | 
| 61 | 
            +
                  Content-Length:
         | 
| 62 | 
            +
                  - '832'
         | 
| 63 | 
            +
                  Accept-Ranges:
         | 
| 64 | 
            +
                  - bytes
         | 
| 65 | 
            +
                  Date:
         | 
| 66 | 
            +
                  - Thu, 19 Dec 2019 09:54:02 GMT
         | 
| 67 | 
            +
                  Via:
         | 
| 68 | 
            +
                  - 1.1 varnish
         | 
| 69 | 
            +
                  Age:
         | 
| 70 | 
            +
                  - '0'
         | 
| 71 | 
            +
                  Connection:
         | 
| 72 | 
            +
                  - close
         | 
| 73 | 
            +
                  X-Served-By:
         | 
| 74 | 
            +
                  - cache-ams21023-AMS
         | 
| 75 | 
            +
                  X-Cache:
         | 
| 76 | 
            +
                  - MISS
         | 
| 77 | 
            +
                  X-Cache-Hits:
         | 
| 78 | 
            +
                  - '0'
         | 
| 79 | 
            +
                  Vary:
         | 
| 80 | 
            +
                  - Accept-Encoding
         | 
| 81 | 
            +
                  X-Contentful-Request-Id:
         | 
| 82 | 
            +
                  - e8767cee-9cbe-46be-8fab-47d35d6c5db7
         | 
| 83 | 
            +
                body:
         | 
| 84 | 
            +
                  encoding: ASCII-8BIT
         | 
| 85 | 
            +
                  string: !binary |-
         | 
| 86 | 
            +
                    H4sIAAAAAAAAA81WW2+bMBR+769APK8J5NbSt25r127VqqZJq22qIgMHYkoMwiZZWuW/zxdIHEpINk3TUBRhG5/znet3Xo8Mw6RLap4Zr/yVL9gyBb4yz7MMLU2+t3onvmEJQzHft+WKPuOULyy5iPEMM3FkqTVmMBMCf0iBSmxFi9REU+QJVeUXalPDIjbkZonpBpNnU+jcPFw7eR4VmO+lxMoH2BfmBMgLyWIRRv0AhFXls1q/SzvVY6o74c3Dy13sWs413MLYPrWDBXvRxK9xXRCWLfUDLwPEwD8XbjE7lu0c251j2xlZzlnf5r9Wtzf4rl/IU//3LgCZ4ywhMyBCx34XKotmiDLIqh461L0Xms69LsxgjilOSJkzhWe9hDCOuYjYftyHYvugya1NgJykuRtjOuVhoRQY3Z8FceKhWBYDkOPxfXlhnShmgCH2N7UjTDQZZurOeKPQKDRqGUYxCWOQ+wfF71A/KIm1HhhEEXr46OZkNIiW6PLh5+XYuRrvd8MsjxkukaqiVsHUo1dT4EXEG5DL5rEp3zrs/BOVup34PWTzG5/ln/E1HV4NrShiCx09b1V6Vuo++KdIH++6wym6fQzpt9GXr/e9IB/M4waga9BPxZsyQ/w/yQYLWZZkh3RU5SmSsCHQJJ4jl2eilnNlJKS8t9nsA0M4rqZz0VorrbcxbgdFrDBSwdtNEv+XSc0lVI0bJl6c+6CRa7WKNnm5RcJF5dQR5N+oszqaXNfZLqJsqK4i3vV5r5fhZriQfW/rqIEye5w1rVZ/YOuUyQE3kOauK7tpc7djG6iTXzq8ve2gzybH1pOoaJv11FRMa0X+1NCTAFwS1Kck9oEYGbAMwxwyg88snJWMFIfUCJKkEqAAS16rtNI8E1Oh2W7jGQqBtjwWIEmvLQKsrSdTuzY/2l3PPUXd7kkHen3/xHVcO+gg1wPUCzpgn1ptBXOyhjlRMCcC5kTAbEVpWB1p6npZWVX4Rdjh2J2T7jZPihoQVryxUhL7Avtsyo/6asxV0sp/cwo4nAoqH/QdjYXEuc5KWwGSYoVbv6KZHDP+yNTtiUpZ0I5SCHcw+xbJCMpZHa2OfgEgI0mYCAwAAA==
         | 
| 87 | 
            +
                http_version: 
         | 
| 88 | 
            +
              recorded_at: Thu, 19 Dec 2019 09:54:02 GMT
         | 
| 89 | 
            +
            recorded_with: VCR 5.0.0
         |