wcc-contentful 1.2.0 → 1.2.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (39) hide show
  1. checksums.yaml +4 -4
  2. data/app/controllers/wcc/contentful/webhook_controller.rb +2 -0
  3. data/lib/tasks/download_schema.rake +1 -1
  4. data/lib/wcc/contentful/configuration.rb +31 -18
  5. data/lib/wcc/contentful/downloads_schema.rb +5 -4
  6. data/lib/wcc/contentful/engine.rb +2 -4
  7. data/lib/wcc/contentful/event.rb +2 -3
  8. data/lib/wcc/contentful/exceptions.rb +2 -3
  9. data/lib/wcc/contentful/indexed_representation.rb +2 -6
  10. data/lib/wcc/contentful/instrumentation.rb +2 -1
  11. data/lib/wcc/contentful/link.rb +1 -3
  12. data/lib/wcc/contentful/link_visitor.rb +2 -4
  13. data/lib/wcc/contentful/middleware/store/caching_middleware.rb +4 -8
  14. data/lib/wcc/contentful/middleware/store.rb +4 -6
  15. data/lib/wcc/contentful/model_api.rb +1 -3
  16. data/lib/wcc/contentful/model_builder.rb +5 -4
  17. data/lib/wcc/contentful/model_methods.rb +10 -12
  18. data/lib/wcc/contentful/model_singleton_methods.rb +1 -1
  19. data/lib/wcc/contentful/rich_text/node.rb +1 -3
  20. data/lib/wcc/contentful/rich_text.rb +1 -1
  21. data/lib/wcc/contentful/rspec.rb +1 -3
  22. data/lib/wcc/contentful/simple_client/response.rb +3 -5
  23. data/lib/wcc/contentful/simple_client.rb +11 -14
  24. data/lib/wcc/contentful/store/base.rb +5 -5
  25. data/lib/wcc/contentful/store/cdn_adapter.rb +1 -1
  26. data/lib/wcc/contentful/store/factory.rb +1 -1
  27. data/lib/wcc/contentful/store/memory_store.rb +2 -2
  28. data/lib/wcc/contentful/store/postgres_store.rb +15 -22
  29. data/lib/wcc/contentful/store/query.rb +2 -2
  30. data/lib/wcc/contentful/store/rspec_examples/include_param.rb +6 -4
  31. data/lib/wcc/contentful/store/rspec_examples/operators.rb +1 -1
  32. data/lib/wcc/contentful/sync_engine.rb +31 -15
  33. data/lib/wcc/contentful/sys.rb +2 -1
  34. data/lib/wcc/contentful/test/double.rb +3 -5
  35. data/lib/wcc/contentful/test/factory.rb +4 -6
  36. data/lib/wcc/contentful/version.rb +1 -1
  37. data/lib/wcc/contentful.rb +5 -7
  38. data/wcc-contentful.gemspec +5 -5
  39. metadata +8 -21
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f05ea585d54f7ca83c96e018021f88776ebb148cc40b7d719d6199b3a3cd9d0c
4
- data.tar.gz: 0da490d12beb9938ec51c0ac40e140420966667b72afebc5c9895cf197308ea8
3
+ metadata.gz: 476f7c65f705c14e012e8c2cbb36f68e29782607377b0a4aa9d0c10fb93458da
4
+ data.tar.gz: 01aeff71919acef51c8d498c63bc42e822ed3c598e7c636f5faf74baeb74c552
5
5
  SHA512:
6
- metadata.gz: 979360a35356b041dbe0f8bbd4f0e5bfcaf91909ccc567322ceef8493de25300ea09a081e755142fe23bf9cfd5ea86ca7f919d3218d5dec44a98bcab5921af7d
7
- data.tar.gz: 9e5f29e70fdcbccffd72aeb8b896e3518d2236cd699704289e8a3fdf1392201dc49671bab0eb83948e79ee079366de90b46add4ce2027e065db2da28b2be4e85
6
+ metadata.gz: '0383a5fe8ef8b042d0a9aca04c964051fc5201b89e702a80b616e5c3b36fd6fa7590d768d178e96f3353c998923fc87458697f5b1112bdd000e6e273fdb07f56'
7
+ data.tar.gz: 776a6ec463edbcd209d28dd2033d6378ac45e44dd9bca790aefe81ea529c4fa4d0cf6725bd3f67e5c4054f41bd930e9905165f8ccd42f2a9f01b3bc0ac1deaf6
@@ -36,6 +36,7 @@ module WCC::Contentful
36
36
  def authorize_contentful
37
37
  config = WCC::Contentful.configuration
38
38
 
39
+ # rubocop:disable Style/SoleNestedConditional
39
40
  if config.webhook_username.present? && config.webhook_password.present?
40
41
  unless authenticate_with_http_basic do |u, p|
41
42
  u == config.webhook_username &&
@@ -45,6 +46,7 @@ module WCC::Contentful
45
46
  return
46
47
  end
47
48
  end
49
+ # rubocop:enable Style/SoleNestedConditional
48
50
 
49
51
  # 'application/vnd.contentful.management.v1+json' is an alias for the 'application/json'
50
52
  # content-type, so 'request.content_type' will give 'application/json'
@@ -5,7 +5,7 @@ require 'wcc/contentful/downloads_schema'
5
5
 
6
6
  namespace :wcc_contentful do
7
7
  desc 'Downloads the schema from the currently configured space and stores it in ' \
8
- 'db/contentful-schema.json'
8
+ 'db/contentful-schema.json'
9
9
  task download_schema: :environment do
10
10
  WCC::Contentful::DownloadsSchema.call
11
11
  end
@@ -3,22 +3,24 @@
3
3
  # This object contains all the configuration options for the `wcc-contentful` gem.
4
4
  class WCC::Contentful::Configuration
5
5
  ATTRIBUTES = %i[
6
- space
7
6
  access_token
8
7
  app_url
9
- management_token
10
- environment
11
- default_locale
12
- preview_token
13
- webhook_username
14
- webhook_password
15
- webhook_jobs
16
8
  connection
17
9
  connection_options
18
- update_schema_file
10
+ default_locale
11
+ environment
12
+ instrumentation_adapter
13
+ management_token
14
+ preview_token
19
15
  schema_file
16
+ space
20
17
  store
21
- instrumentation_adapter
18
+ sync_retry_limit
19
+ sync_retry_wait
20
+ update_schema_file
21
+ webhook_jobs
22
+ webhook_password
23
+ webhook_username
22
24
  ].freeze
23
25
 
24
26
  # (required) Sets the Contentful Space ID.
@@ -57,6 +59,17 @@ class WCC::Contentful::Configuration
57
59
  # to implement a webhook job.
58
60
  attr_accessor :webhook_jobs
59
61
 
62
+ # Sets the maximum number of times that the SyncEngine will retry synchronization
63
+ # when it detects that the Contentful CDN's cache has not been updated after a webhook.
64
+ # Default: 2
65
+ attr_accessor :sync_retry_limit
66
+
67
+ # Sets the base ActiveSupport::Duration that the SyncEngine will wait before retrying.
68
+ # Each subsequent retry uses an exponential backoff, so the second retry will be
69
+ # after (2 * sync_retry_wait), the third after (4 * sync_retry_wait), etc.
70
+ # Default: 2.seconds
71
+ attr_accessor :sync_retry_wait
72
+
60
73
  # Returns true if the currently configured environment is pointing at `master`.
61
74
  def master?
62
75
  !environment.present?
@@ -145,9 +158,7 @@ class WCC::Contentful::Configuration
145
158
  # WCC::Contentful::InitializationError if the API cannot be reached.
146
159
  def update_schema_file=(sym)
147
160
  valid_syms = %i[never if_possible if_missing always]
148
- unless valid_syms.include?(sym)
149
- raise ArgumentError, "update_schema_file must be one of #{valid_syms}"
150
- end
161
+ raise ArgumentError, "update_schema_file must be one of #{valid_syms}" unless valid_syms.include?(sym)
151
162
 
152
163
  @update_schema_file = sym
153
164
  end
@@ -172,22 +183,24 @@ class WCC::Contentful::Configuration
172
183
  attr_accessor :instrumentation_adapter
173
184
 
174
185
  def initialize
175
- @access_token = ENV['CONTENTFUL_ACCESS_TOKEN']
176
- @app_url = ENV['APP_URL']
186
+ @access_token = ENV.fetch('CONTENTFUL_ACCESS_TOKEN', nil)
187
+ @app_url = ENV.fetch('APP_URL', nil)
177
188
  @connection_options = {
178
189
  api_url: 'https://cdn.contentful.com/',
179
190
  preview_api_url: 'https://preview.contentful.com/',
180
191
  management_api_url: 'https://api.contentful.com'
181
192
  }
182
- @management_token = ENV['CONTENTFUL_MANAGEMENT_TOKEN']
183
- @preview_token = ENV['CONTENTFUL_PREVIEW_TOKEN']
184
- @space = ENV['CONTENTFUL_SPACE_ID']
193
+ @management_token = ENV.fetch('CONTENTFUL_MANAGEMENT_TOKEN', nil)
194
+ @preview_token = ENV.fetch('CONTENTFUL_PREVIEW_TOKEN', nil)
195
+ @space = ENV.fetch('CONTENTFUL_SPACE_ID', nil)
185
196
  @default_locale = nil
186
197
  @middleware = []
187
198
  @update_schema_file = :if_possible
188
199
  @schema_file = 'db/contentful-schema.json'
189
200
  @webhook_jobs = []
190
201
  @store_factory = WCC::Contentful::Store::Factory.new(self, :direct)
202
+ @sync_retry_limit = 3
203
+ @sync_retry_wait = 1.second
191
204
  end
192
205
 
193
206
  # Validates the configuration, raising ArgumentError if anything is wrong. This
@@ -36,7 +36,7 @@ class WCC::Contentful::DownloadsSchema
36
36
  begin
37
37
  JSON.parse(File.read(@file))
38
38
  rescue JSON::ParserError
39
- return true
39
+ return true # rubocop:disable Lint/NoReturnInBeginEndBlocks
40
40
  end
41
41
 
42
42
  existing_cts = contents['contentTypes'].sort_by { |ct| ct.dig('sys', 'id') }
@@ -83,13 +83,14 @@ class WCC::Contentful::DownloadsSchema
83
83
  end
84
84
 
85
85
  def deep_contains_all(expected, actual)
86
- if expected.is_a? Array
86
+ case expected
87
+ when Array
87
88
  expected.each_with_index do |val, i|
88
89
  return false unless actual[i]
89
90
  return false unless deep_contains_all(val, actual[i])
90
91
  end
91
92
  true
92
- elsif expected.is_a? Hash
93
+ when Hash
93
94
  expected.each do |(key, val)|
94
95
  return false unless actual.key?(key)
95
96
  return false unless deep_contains_all(val, actual[key])
@@ -107,6 +108,6 @@ class WCC::Contentful::DownloadsSchema
107
108
  # only in its treatment of empty arrays in the "validations" field.
108
109
  json_string = json_string.gsub(/\[\n\n\s+\]/, '[]')
109
110
  # contentful-shell also adds a newline at the end.
110
- json_string + "\n"
111
+ "#{json_string}\n"
111
112
  end
112
113
  end
@@ -6,9 +6,7 @@ module WCC::Contentful
6
6
  config = WCC::Contentful.configuration
7
7
 
8
8
  jobs = []
9
- if WCC::Contentful::Services.instance.sync_engine&.should_sync?
10
- jobs << WCC::Contentful::SyncEngine::Job
11
- end
9
+ jobs << WCC::Contentful::SyncEngine::Job if WCC::Contentful::Services.instance.sync_engine&.should_sync?
12
10
  jobs.push(*WCC::Contentful.configuration.webhook_jobs)
13
11
 
14
12
  jobs.each do |job|
@@ -19,7 +17,7 @@ module WCC::Contentful
19
17
  job.perform_later(event.to_h)
20
18
  else
21
19
  Rails.logger.error "Misconfigured webhook job: #{job} does not respond to " \
22
- ':perform_later'
20
+ ':perform_later'
23
21
  end
24
22
  rescue StandardError => e
25
23
  warn "Error in job #{job}: #{e}"
@@ -23,9 +23,7 @@ module WCC::Contentful::Event
23
23
 
24
24
  def register(constant)
25
25
  name = constant.try(:type) || constant.name.demodulize
26
- unless constant.respond_to?(:new)
27
- raise ArgumentError, "Constant #{constant} does not define 'new'"
28
- end
26
+ raise ArgumentError, "Constant #{constant} does not define 'new'" unless constant.respond_to?(:new)
29
27
 
30
28
  @event_types ||= {}
31
29
  @event_types[name] = constant
@@ -58,6 +56,7 @@ module WCC::Contentful::Event
58
56
  attr_reader :sys
59
57
  attr_reader :raw
60
58
  attr_reader :source
59
+
61
60
  delegate :id, to: :sys
62
61
  delegate :type, to: :sys
63
62
  delegate :created_at, to: :sys
@@ -12,8 +12,7 @@ module WCC::Contentful
12
12
  # Raised when an entry contains a circular reference and cannot be represented
13
13
  # as a flat tree.
14
14
  class CircularReferenceError < StandardError
15
- attr_reader :stack
16
- attr_reader :id
15
+ attr_reader :stack, :id
17
16
 
18
17
  def initialize(stack, id)
19
18
  @id = id
@@ -25,7 +24,7 @@ module WCC::Contentful
25
24
  return super unless stack
26
25
 
27
26
  super + "\n " \
28
- "#{stack.last} points to #{id} which is also it's ancestor\n " +
27
+ "#{stack.last} points to #{id} which is also it's ancestor\n " +
29
28
  stack.join('->')
30
29
  end
31
30
  end
@@ -109,9 +109,7 @@ module WCC::Contentful
109
109
  ].freeze
110
110
 
111
111
  def type=(raw_type)
112
- unless TYPES.include?(raw_type)
113
- raise ArgumentError, "Unknown type #{raw_type}, expected one of: #{TYPES}"
114
- end
112
+ raise ArgumentError, "Unknown type #{raw_type}, expected one of: #{TYPES}" unless TYPES.include?(raw_type)
115
113
 
116
114
  @type = raw_type
117
115
  end
@@ -131,9 +129,7 @@ module WCC::Contentful
131
129
 
132
130
  if raw_type = hash_or_id.delete('type')
133
131
  raw_type = raw_type.to_sym
134
- unless TYPES.include?(raw_type)
135
- raise ArgumentError, "Unknown type #{raw_type}, expected one of: #{TYPES}"
136
- end
132
+ raise ArgumentError, "Unknown type #{raw_type}, expected one of: #{TYPES}" unless TYPES.include?(raw_type)
137
133
 
138
134
  @type = raw_type
139
135
  end
@@ -7,11 +7,12 @@ module WCC::Contentful
7
7
  def _instrumentation_event_prefix
8
8
  @_instrumentation_event_prefix ||=
9
9
  # WCC::Contentful => contentful.wcc
10
- '.' + (is_a?(Class) || is_a?(Module) ? self : self.class)
10
+ '.' + (is_a?(Class) || is_a?(Module) ? self : self.class) # rubocop:disable Style/StringConcatenation
11
11
  .name.parameterize.split('-').reverse.join('.')
12
12
  end
13
13
 
14
14
  attr_writer :_instrumentation
15
+
15
16
  def _instrumentation
16
17
  # look for per-instance instrumentation then try class level
17
18
  @_instrumentation || self.class._instrumentation
@@ -1,9 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  class WCC::Contentful::Link
4
- attr_reader :id
5
- attr_reader :link_type
6
- attr_reader :raw
4
+ attr_reader :id, :link_type, :raw
7
5
 
8
6
  LINK_TYPES = {
9
7
  Asset: 'Asset',
@@ -4,9 +4,7 @@
4
4
  # It is used internally by the Store layer to compose the resulting resolved hashes.
5
5
  # But you can use it too!
6
6
  class WCC::Contentful::LinkVisitor
7
- attr_reader :entry
8
- attr_reader :fields
9
- attr_reader :depth
7
+ attr_reader :entry, :fields, :depth
10
8
 
11
9
  # @param [Hash] entry The entry hash (resolved or unresolved) to walk
12
10
  # @param [Array<Symbol>] The type of fields to select from the entry tree.
@@ -66,7 +64,7 @@ class WCC::Contentful::LinkVisitor
66
64
 
67
65
  def each_field(field)
68
66
  each_locale(field) do |val, locale|
69
- if val&.is_a?(Array)
67
+ if val.is_a?(Array)
70
68
  val.each_with_index do |v, index|
71
69
  yield(v, field, locale, index) unless v.nil?
72
70
  end
@@ -36,12 +36,8 @@ module WCC::Contentful::Middleware::Store
36
36
  # figure out how to cache the results of a find_by query, ex:
37
37
  # `find_by('slug' => '/about')`
38
38
  def find_by(content_type:, filter: nil, options: nil)
39
- if filter&.keys == ['sys.id']
40
- # Direct ID lookup, like what we do in `WCC::Contentful::ModelMethods.resolve`
41
- # We can return just this item. Stores are not required to implement :include option.
42
- if found = @cache.read(filter['sys.id'])
43
- return found
44
- end
39
+ if filter&.keys == ['sys.id'] && found = @cache.read(filter['sys.id'])
40
+ return found
45
41
  end
46
42
 
47
43
  store.find_by(content_type: content_type, filter: filter, options: options)
@@ -79,8 +75,8 @@ module WCC::Contentful::Middleware::Store
79
75
  prev = @cache.read(id)
80
76
  return if prev.nil? && LAZILY_CACHEABLE_TYPES.include?(type)
81
77
 
82
- if (prev_rev = prev&.dig('sys', 'revision')) && (next_rev = json.dig('sys', 'revision'))
83
- return prev if next_rev < prev_rev
78
+ if (prev_rev = prev&.dig('sys', 'revision')) && (next_rev = json.dig('sys', 'revision')) && (next_rev < prev_rev)
79
+ return prev
84
80
  end
85
81
 
86
82
  # we also set DeletedEntry objects in the cache - no need to go hit the API when we know
@@ -96,9 +96,9 @@ module WCC::Contentful::Middleware::Store
96
96
 
97
97
  def count
98
98
  if middleware.has_select?
99
- raise NameError, "Count cannot be determined because the middleware '#{middleware}'" \
100
- " implements the #select? method. Please use '.to_a.count' to count entries that" \
101
- ' pass the #select? method.'
99
+ raise NameError, "Count cannot be determined because the middleware '#{middleware}' " \
100
+ "implements the #select? method. Please use '.to_a.count' to count entries that " \
101
+ 'pass the #select? method.'
102
102
  end
103
103
 
104
104
  # The wrapped query may get count from the "Total" field in the response,
@@ -112,9 +112,7 @@ module WCC::Contentful::Middleware::Store
112
112
  result = wrapped_query.to_enum
113
113
  result = result.select { |x| middleware.select?(x) } if middleware.has_select?
114
114
 
115
- if options && options[:include]
116
- result = result.map { |x| middleware.resolve_includes(x, options[:include]) }
117
- end
115
+ result = result.map { |x| middleware.resolve_includes(x, options[:include]) } if options && options[:include]
118
116
 
119
117
  result.map { |x| middleware.transform(x) }
120
118
  end
@@ -51,9 +51,7 @@ module WCC::Contentful::ModelAPI
51
51
 
52
52
  file = configuration.schema_file
53
53
  schema_json = JSON.parse(File.read(file))['contentTypes']
54
- unless schema_json
55
- raise ArgumentError, 'Please give either a JSON array of content types or file to load from'
56
- end
54
+ raise ArgumentError, 'Please give either a JSON array of content types or file to load from' unless schema_json
57
55
 
58
56
  @schema = WCC::Contentful::ContentTypeIndexer.from_json_schema(schema_json).types
59
57
  end
@@ -61,7 +61,7 @@ module WCC::Contentful
61
61
  ct = content_type_from_raw(raw)
62
62
  if ct != typedef.content_type
63
63
  raise ArgumentError, 'Wrong Content Type - ' \
64
- "'#{raw.dig('sys', 'id')}' is a #{ct}, expected #{typedef.content_type}"
64
+ "'#{raw.dig('sys', 'id')}' is a #{ct}, expected #{typedef.content_type}"
65
65
  end
66
66
  @raw = raw.freeze
67
67
 
@@ -107,12 +107,13 @@ module WCC::Contentful
107
107
  # array fields need to resolve to an empty array when nothing is there
108
108
  raw_value = []
109
109
  end
110
- instance_variable_set('@' + f.name, raw_value)
110
+ instance_variable_set("@#{f.name}", raw_value)
111
111
  end
112
112
  end
113
113
 
114
114
  attr_reader :sys
115
115
  attr_reader :raw
116
+
116
117
  delegate :id, to: :sys
117
118
  delegate :created_at, to: :sys
118
119
  delegate :updated_at, to: :sys
@@ -122,11 +123,11 @@ module WCC::Contentful
122
123
  # Make a field for each column:
123
124
  typedef.fields.each_value do |f|
124
125
  name = f.name
125
- var_name = '@' + name
126
+ var_name = "@#{name}"
126
127
  case f.type
127
128
  when :Asset, :Link
128
129
  define_method(name) do
129
- val = instance_variable_get(var_name + '_resolved')
130
+ val = instance_variable_get("#{var_name}_resolved")
130
131
  return val if val.present?
131
132
 
132
133
  _resolve_field(name)
@@ -54,17 +54,15 @@ module WCC::Contentful::ModelMethods
54
54
  _instrument 'resolve', id: id, depth: depth, backlinks: backlinked_ids do
55
55
  # use include param to do resolution
56
56
  store.find_by(content_type: self.class.content_type,
57
- filter: { 'sys.id' => id },
58
- options: context.except(*MODEL_LAYER_CONTEXT_KEYS).merge!({
59
- include: [depth, 10].min
60
- }))
57
+ filter: { 'sys.id' => id },
58
+ options: context.except(*MODEL_LAYER_CONTEXT_KEYS).merge!({
59
+ include: [depth, 10].min
60
+ }))
61
61
  end
62
- unless raw
63
- raise WCC::Contentful::ResolveError, "Cannot find #{self.class.content_type} with ID #{id}"
64
- end
62
+ raise WCC::Contentful::ResolveError, "Cannot find #{self.class.content_type} with ID #{id}" unless raw
65
63
 
66
64
  @raw = raw.freeze
67
- links.each { |f| instance_variable_set('@' + f, raw.dig('fields', f, sys.locale)) }
65
+ links.each { |f| instance_variable_set("@#{f}", raw.dig('fields', f, sys.locale)) }
68
66
  end
69
67
 
70
68
  links.each { |f| _resolve_field(f, depth, context, options) }
@@ -142,7 +140,7 @@ module WCC::Contentful::ModelMethods
142
140
  def _resolve_field(field_name, depth = 1, context = {}, options = {})
143
141
  return if depth <= 0
144
142
 
145
- var_name = '@' + field_name
143
+ var_name = "@#{field_name}"
146
144
  return unless val = instance_variable_get(var_name)
147
145
 
148
146
  context = sys.context.to_h.merge(context)
@@ -182,17 +180,17 @@ module WCC::Contentful::ModelMethods
182
180
  val = _try_map(val) { |v| load.call(v) }
183
181
  val = val.compact if val.is_a? Array
184
182
 
185
- instance_variable_set(var_name + '_resolved', val)
183
+ instance_variable_set("#{var_name}_resolved", val)
186
184
  rescue WCC::Contentful::CircularReferenceError
187
185
  raise unless options[:circular_reference] == :ignore
188
186
  end
189
187
  end
190
188
 
191
189
  def _resolved_field?(field_name, depth = 1)
192
- var_name = '@' + field_name
190
+ var_name = "@#{field_name}"
193
191
  raw = instance_variable_get(var_name)
194
192
  return true if raw.nil? || (raw.is_a?(Array) && raw.all?(&:nil?))
195
- return false unless val = instance_variable_get(var_name + '_resolved')
193
+ return false unless val = instance_variable_get("#{var_name}_resolved")
196
194
  return true if depth <= 1
197
195
 
198
196
  return val.resolved?(depth: depth - 1) unless val.is_a? Array
@@ -66,7 +66,7 @@ module WCC::Contentful::ModelSingletonMethods
66
66
  new(result, options) if result
67
67
  end
68
68
 
69
- def inherited(subclass)
69
+ def inherited(subclass) # rubocop:disable Lint/MissingSuper
70
70
  # If another different class is already registered for this content type,
71
71
  # don't auto-register this one.
72
72
  return if model_namespace.registered?(content_type)
@@ -37,9 +37,7 @@ module WCC::Contentful::RichText
37
37
  end
38
38
 
39
39
  def tokenize(raw, context = nil)
40
- unless raw['nodeType'] == node_type
41
- raise ArgumentError, "Expected '#{node_type}', got '#{raw['nodeType']}'"
42
- end
40
+ raise ArgumentError, "Expected '#{node_type}', got '#{raw['nodeType']}'" unless raw['nodeType'] == node_type
43
41
 
44
42
  values =
45
43
  members.map do |symbol|
@@ -43,7 +43,7 @@ module WCC::Contentful::RichText
43
43
  EmbeddedEntryBlock
44
44
  when 'embedded-asset-block'
45
45
  EmbeddedAssetBlock
46
- when /heading\-(\d+)/
46
+ when /heading-(\d+)/
47
47
  size = Regexp.last_match(1)
48
48
  const_get("Heading#{size}")
49
49
  else
@@ -13,9 +13,7 @@ module WCC::Contentful::RSpec
13
13
  # stubs the Model API to return that content type for `.find` and `.find_by`
14
14
  # query methods.
15
15
  def contentful_stub(const, **attrs)
16
- unless const.respond_to?(:content_type_definition)
17
- const = WCC::Contentful::Model.resolve_constant(const.to_s)
18
- end
16
+ const = WCC::Contentful::Model.resolve_constant(const.to_s) unless const.respond_to?(:content_type_definition)
19
17
  instance = contentful_create(const, **attrs)
20
18
 
21
19
  # mimic what's going on inside model_singleton_methods.rb
@@ -6,9 +6,7 @@ class WCC::Contentful::SimpleClient
6
6
  class Response
7
7
  include ::WCC::Contentful::Instrumentation
8
8
 
9
- attr_reader :raw_response
10
- attr_reader :client
11
- attr_reader :request
9
+ attr_reader :raw_response, :client, :request
12
10
 
13
11
  delegate :status, to: :raw_response
14
12
  alias_method :code, :status
@@ -26,7 +24,7 @@ class WCC::Contentful::SimpleClient
26
24
  def error_message
27
25
  parsed_message =
28
26
  begin
29
- raw.dig('message')
27
+ raw['message']
30
28
  rescue JSON::ParserError
31
29
  nil
32
30
  end
@@ -105,7 +103,7 @@ class WCC::Contentful::SimpleClient
105
103
 
106
104
  def includes
107
105
  @includes ||=
108
- raw.dig('includes')&.each_with_object({}) do |(_t, entries), h|
106
+ raw['includes']&.each_with_object({}) do |(_t, entries), h|
109
107
  entries.each { |e| h[e.dig('sys', 'id')] = e }
110
108
  end || {}
111
109
  end
@@ -24,8 +24,7 @@ module WCC::Contentful
24
24
  class SimpleClient
25
25
  include WCC::Contentful::Instrumentation
26
26
 
27
- attr_reader :api_url
28
- attr_reader :space
27
+ attr_reader :api_url, :space
29
28
 
30
29
  # Creates a new SimpleClient with the given configuration.
31
30
  #
@@ -41,7 +40,7 @@ module WCC::Contentful
41
40
  # @option options [Number] rate_limit_wait_timeout The maximum time to block the thread waiting
42
41
  # on a rate limit response. By default will wait for one 429 and then fail on the second 429.
43
42
  def initialize(api_url:, space:, access_token:, **options)
44
- @api_url = URI.join(api_url, '/spaces/', space + '/')
43
+ @api_url = URI.join(api_url, '/spaces/', "#{space}/")
45
44
  @space = space
46
45
  @access_token = access_token
47
46
 
@@ -57,7 +56,7 @@ module WCC::Contentful
57
56
 
58
57
  return unless options[:environment].present?
59
58
 
60
- @api_url = URI.join(@api_url, 'environments/', options[:environment] + '/')
59
+ @api_url = URI.join(@api_url, 'environments/', "#{options[:environment]}/")
61
60
  end
62
61
 
63
62
  # performs an HTTP GET request to the specified path within the configured
@@ -84,15 +83,13 @@ module WCC::Contentful
84
83
  case adapter
85
84
  when nil
86
85
  ADAPTERS.each do |a, spec|
87
- begin
88
- gem(*spec)
89
- return load_adapter(a)
90
- rescue Gem::LoadError
91
- next
92
- end
86
+ gem(*spec)
87
+ return load_adapter(a)
88
+ rescue Gem::LoadError
89
+ next
93
90
  end
94
- raise ArgumentError, 'Unable to load adapter! Please install one of '\
95
- "#{ADAPTERS.values.map(&:join).join(',')}"
91
+ raise ArgumentError, 'Unable to load adapter! Please install one of ' \
92
+ "#{ADAPTERS.values.map(&:join).join(',')}"
96
93
  when :faraday
97
94
  require 'faraday'
98
95
  ::Faraday.new do |faraday|
@@ -104,8 +101,8 @@ module WCC::Contentful
104
101
  TyphoeusAdapter.new
105
102
  else
106
103
  unless adapter.respond_to?(:get)
107
- raise ArgumentError, "Adapter #{adapter} is not invokeable! Please "\
108
- "pass use one of #{ADAPTERS.keys} or create a Faraday-compatible adapter"
104
+ raise ArgumentError, "Adapter #{adapter} is not invokeable! Please " \
105
+ "pass use one of #{ADAPTERS.keys} or create a Faraday-compatible adapter"
109
106
  end
110
107
  adapter
111
108
  end
@@ -61,11 +61,11 @@ module WCC::Contentful::Store
61
61
  set(json.dig('sys', 'id'), json)
62
62
  end
63
63
 
64
- if (prev_rev = prev&.dig('sys', 'revision')) && (next_rev = json.dig('sys', 'revision'))
65
- if next_rev < prev_rev
66
- # Uh oh! we overwrote an entry with a prior revision. Put the previous back.
67
- return index(prev)
68
- end
64
+ if (prev_rev = prev&.dig('sys', 'revision')) &&
65
+ (next_rev = json.dig('sys', 'revision')) &&
66
+ (next_rev < prev_rev)
67
+ # Uh oh! we overwrote an entry with a prior revision. Put the previous back.
68
+ return index(prev)
69
69
  end
70
70
 
71
71
  case type
@@ -3,7 +3,7 @@
3
3
  module WCC::Contentful::Store
4
4
  class CDNAdapter
5
5
  include WCC::Contentful::Store::Interface
6
- # Note: CDNAdapter should not instrument store events cause it's not a store.
6
+ # NOTE: CDNAdapter should not instrument store events cause it's not a store.
7
7
 
8
8
  attr_writer :client, :preview_client
9
9
 
@@ -90,7 +90,7 @@ module WCC::Contentful::Store
90
90
  next if m[0].respond_to?(:call)
91
91
 
92
92
  raise ArgumentError, "The middleware '#{m[0]&.try(:name) || m[0]}' cannot be applied! " \
93
- 'It must respond to :call'
93
+ 'It must respond to :call'
94
94
  end
95
95
 
96
96
  validate_store!(store)
@@ -41,8 +41,8 @@ module WCC::Contentful::Store
41
41
  SUPPORTED_OPS = %i[eq ne in nin].freeze
42
42
 
43
43
  def execute(query)
44
- (query.conditions.map(&:op) - SUPPORTED_OPS).each do |op|
45
- raise ArgumentError, "Operator :#{op} not supported"
44
+ if bad_op = (query.conditions.map(&:op) - SUPPORTED_OPS).first
45
+ raise ArgumentError, "Operator :#{bad_op} not supported"
46
46
  end
47
47
 
48
48
  relation = mutex.with_read_lock { @hash.values }
@@ -45,12 +45,9 @@ module WCC::Contentful::Store
45
45
  JSON.parse(val) if val
46
46
  end
47
47
 
48
- if views_need_update?(value, previous_value)
49
- # mark dirty - we need to refresh the materialized view
50
- unless mutex.with_read_lock { @dirty }
51
- _instrument 'mark_dirty'
52
- mutex.with_write_lock { @dirty = true }
53
- end
48
+ if views_need_update?(value, previous_value) && !mutex.with_read_lock { @dirty }
49
+ _instrument 'mark_dirty'
50
+ mutex.with_write_lock { @dirty = true }
54
51
  end
55
52
 
56
53
  previous_value
@@ -105,7 +102,7 @@ module WCC::Contentful::Store
105
102
  end
106
103
  end
107
104
 
108
- logger&.debug('[PostgresStore] ' + statement + "\n" + params.inspect)
105
+ logger&.debug("[PostgresStore] #{statement}\n#{params.inspect}")
109
106
  _instrument 'exec' do
110
107
  @connection_pool.with { |conn| conn.exec(statement, params) }
111
108
  end
@@ -231,16 +228,12 @@ module WCC::Contentful::Store
231
228
  end
232
229
 
233
230
  statement =
234
- select_statement +
235
- " FROM #{table} AS t \n" +
236
- joins.join("\n") + "\n" +
237
- statement +
238
- (limit_statement || '')
231
+ "#{select_statement} FROM #{table} AS t \n#{joins.join("\n")}\n#{statement}#{limit_statement || ''}"
239
232
 
240
233
  [statement, params]
241
234
  end
242
235
 
243
- def _eq(path, expected, params)
236
+ def _eq(path, expected, params) # rubocop:disable Layout/LineContinuationLeadingSpace
244
237
  return " AND t.id = $#{push_param(expected, params)}" if path == %w[sys id]
245
238
 
246
239
  if path[3] == 'sys'
@@ -248,12 +241,12 @@ module WCC::Contentful::Store
248
241
  # into it to detect whether it contains `{ "sys": { "id" => expected } }`
249
242
  expected = { 'sys' => { path[4] => expected } }.to_json
250
243
  return ' AND fn_contentful_jsonb_any_to_jsonb_array(t.data->' \
251
- "#{quote_parameter_path(path.take(3))}) @> " \
252
- "jsonb_build_array($#{push_param(expected, params)}::jsonb)"
244
+ "#{quote_parameter_path(path.take(3))}) @> " \
245
+ "jsonb_build_array($#{push_param(expected, params)}::jsonb)"
253
246
  end
254
247
 
255
- " AND t.data->#{quote_parameter_path(path)}" \
256
- " @> to_jsonb($#{push_param(expected, params)})"
248
+ " AND t.data->#{quote_parameter_path(path)} " \
249
+ "@> to_jsonb($#{push_param(expected, params)})"
257
250
  end
258
251
 
259
252
  PARAM_TYPES = {
@@ -292,7 +285,7 @@ module WCC::Contentful::Store
292
285
  def push_join(_path, joins)
293
286
  table_alias = "s#{joins.length}"
294
287
  joins << "JOIN contentful_raw AS #{table_alias} ON " \
295
- "#{table_alias}.id=ANY(t.links)"
288
+ "#{table_alias}.id=ANY(t.links)"
296
289
  table_alias
297
290
  end
298
291
  end
@@ -326,8 +319,8 @@ module WCC::Contentful::Store
326
319
  end
327
320
 
328
321
  def schema_ensured?(conn)
329
- result = conn.exec('SELECT version FROM wcc_contentful_schema_version' \
330
- ' ORDER BY version DESC LIMIT 1')
322
+ result = conn.exec('SELECT version FROM wcc_contentful_schema_version ' \
323
+ 'ORDER BY version DESC LIMIT 1')
331
324
  return false if result.num_tuples == 0
332
325
 
333
326
  result[0]['version'].to_i >= EXPECTED_VERSION
@@ -339,8 +332,8 @@ module WCC::Contentful::Store
339
332
  def ensure_schema(conn)
340
333
  result =
341
334
  begin
342
- conn.exec('SELECT version FROM wcc_contentful_schema_version' \
343
- ' ORDER BY version DESC')
335
+ conn.exec('SELECT version FROM wcc_contentful_schema_version ' \
336
+ 'ORDER BY version DESC')
344
337
  rescue PG::UndefinedTable
345
338
  []
346
339
  end
@@ -36,7 +36,7 @@ module WCC::Contentful::Store
36
36
 
37
37
  FALSE_VALUES = [
38
38
  false, 0,
39
- '0', :"0",
39
+ '0', :'0',
40
40
  'f', :f,
41
41
  'F', :F,
42
42
  'false', :false, # rubocop:disable Lint/BooleanSymbol
@@ -237,7 +237,7 @@ module WCC::Contentful::Store
237
237
 
238
238
  Condition =
239
239
  Struct.new(:path, :op, :expected) do
240
- LINK_KEYS = %w[id type linkType].freeze
240
+ LINK_KEYS = %w[id type linkType].freeze # rubocop:disable Lint/ConstantDefinitionInBlock
241
241
 
242
242
  def path_tuples
243
243
  @path_tuples ||=
@@ -15,10 +15,12 @@ RSpec.shared_examples 'supports include param' do |feature_set|
15
15
  'fields' => {
16
16
  'name' => { 'en-US' => 'root' },
17
17
  'link' => { 'en-US' => make_link_to('deep1') },
18
- 'links' => { 'en-US' => [
19
- make_link_to('shallow3'),
20
- make_link_to('deep2')
21
- ] }
18
+ 'links' => {
19
+ 'en-US' => [
20
+ make_link_to('shallow3'),
21
+ make_link_to('deep2')
22
+ ]
23
+ }
22
24
  }
23
25
  }
24
26
  end
@@ -40,7 +40,7 @@ RSpec.shared_examples 'operators' do |feature_set|
40
40
  end
41
41
  end
42
42
 
43
- supported_operators.each do |op, value|
43
+ supported_operators.each do |op, value| # rubocop:disable Style/CombinableLoops
44
44
  next unless value
45
45
 
46
46
  it_behaves_like "supports :#{op} operator" do
@@ -31,15 +31,18 @@ module WCC::Contentful
31
31
  (@state&.dup || token_wrapper_factory(nil)).freeze
32
32
  end
33
33
 
34
- attr_reader :store
35
- attr_reader :client
34
+ attr_reader :store, :client, :options
36
35
 
37
36
  def should_sync?
38
37
  store&.index?
39
38
  end
40
39
 
41
- def initialize(state: nil, store: nil, client: nil, key: nil)
42
- @state_key = key || "sync:#{object_id}"
40
+ def initialize(client: nil, store: nil, state: nil, **options)
41
+ @options = {
42
+ key: "sync:#{object_id}"
43
+ }.merge!(options).freeze
44
+
45
+ @state_key = @options[:key] || "sync:#{object_id}"
43
46
  @client = client || WCC::Contentful::Services.instance.client
44
47
  @mutex = Mutex.new
45
48
 
@@ -53,9 +56,7 @@ module WCC::Contentful
53
56
  if state
54
57
  @state = token_wrapper_factory(state)
55
58
  raise ArgumentError, ':state param must be a String or Hash' unless @state.is_a? Hash
56
- unless @state.dig('sys', 'type') == 'token'
57
- raise ArgumentError, ':state param must be of sys.type = "token"'
58
- end
59
+ raise ArgumentError, ':state param must be of sys.type = "token"' unless @state.dig('sys', 'type') == 'token'
59
60
  end
60
61
  raise ArgumentError, 'either :state or :store must be provided' unless @state || @store
61
62
  end
@@ -144,8 +145,12 @@ module WCC::Contentful
144
145
  return unless sync_engine&.should_sync?
145
146
 
146
147
  up_to_id = nil
147
- up_to_id = event[:up_to_id] || event.dig('sys', 'id') if event
148
- sync!(up_to_id: up_to_id)
148
+ retry_count = 0
149
+ if event
150
+ up_to_id = event[:up_to_id] || event.dig('sys', 'id')
151
+ retry_count = event[:retry_count] if event[:retry_count]
152
+ end
153
+ sync!(up_to_id: up_to_id, retry_count: retry_count)
149
154
  end
150
155
 
151
156
  # Calls the Contentful Sync API and updates the configured store with the returned
@@ -156,21 +161,32 @@ module WCC::Contentful
156
161
  # If we don't find this ID in the sync data, then drop a job to try
157
162
  # the sync again after a few minutes.
158
163
  #
159
- def sync!(up_to_id: nil)
164
+ def sync!(up_to_id: nil, retry_count: 0)
160
165
  id_found, count = sync_engine.next(up_to_id: up_to_id)
161
166
 
162
167
  next_sync_token = sync_engine.state['token']
163
168
 
164
169
  logger.info "Synced #{count} entries. Next sync token:\n #{next_sync_token}"
165
- logger.info "Should enqueue again? [#{!id_found}]"
166
- # Passing nil to only enqueue the job 1 more time
167
- sync_later!(up_to_id: nil) unless id_found
170
+ unless id_found
171
+ if retry_count >= configuration.sync_retry_limit
172
+ logger.error "Unable to find item with id '#{up_to_id}' on the Sync API. " \
173
+ "Abandoning after #{retry_count} retries."
174
+ else
175
+ wait = (2**retry_count) * configuration.sync_retry_wait.seconds
176
+ logger.info "Unable to find item with id '#{up_to_id}' on the Sync API. " \
177
+ "Retrying after #{wait.inspect} " \
178
+ "(#{configuration.sync_retry_limit - retry_count} retries remaining)"
179
+
180
+ self.class.set(wait: wait)
181
+ .perform_later(up_to_id: up_to_id, retry_count: retry_count + 1)
182
+ end
183
+ end
168
184
  next_sync_token
169
185
  end
170
186
 
171
- # Drops an ActiveJob job to invoke WCC::Contentful.sync! after a given amount
187
+ # Enqueues an ActiveJob job to invoke WCC::Contentful.sync! after a given amount
172
188
  # of time.
173
- def sync_later!(up_to_id: nil, wait: 10.minutes)
189
+ def sync_later!(up_to_id: nil, wait: 10.seconds)
174
190
  self.class.set(wait: wait)
175
191
  .perform_later(up_to_id: up_to_id)
176
192
  end
@@ -11,7 +11,7 @@ WCC::Contentful::Sys =
11
11
  :revision,
12
12
  :context
13
13
  ) do
14
-
14
+ # rubocop:disable Lint/ConstantDefinitionInBlock
15
15
  ATTRIBUTES = %i[
16
16
  id
17
17
  type
@@ -22,6 +22,7 @@ WCC::Contentful::Sys =
22
22
  revision
23
23
  context
24
24
  ].freeze
25
+ # rubocop:enable Lint/ConstantDefinitionInBlock
25
26
 
26
27
  undef []=
27
28
  ATTRIBUTES.each { |a| __send__(:undef_method, "#{a}=") }
@@ -8,9 +8,7 @@ module WCC::Contentful::Test::Double
8
8
  # All attributes that are known to be required fields on the content type
9
9
  # will return a default value based on the field type.
10
10
  def contentful_double(const, **attrs)
11
- unless const.respond_to?(:content_type_definition)
12
- const = WCC::Contentful::Model.resolve_constant(const.to_s)
13
- end
11
+ const = WCC::Contentful::Model.resolve_constant(const.to_s) unless const.respond_to?(:content_type_definition)
14
12
  attrs.symbolize_keys!
15
13
 
16
14
  bad_attrs = attrs.reject { |a| const.instance_methods.include?(a) }
@@ -45,7 +43,7 @@ module WCC::Contentful::Test::Double
45
43
  sys: {
46
44
  type: 'Link',
47
45
  linkType: 'Space',
48
- id: ENV['CONTENTFUL_SPACE_ID']
46
+ id: ENV.fetch('CONTENTFUL_SPACE_ID', nil)
49
47
  }
50
48
  },
51
49
  id: SecureRandom.urlsafe_base64,
@@ -62,7 +60,7 @@ module WCC::Contentful::Test::Double
62
60
  revision: rand(100),
63
61
  locale: 'en-US'
64
62
  },
65
- fields: attrs.each_with_object({}) { |(k, v), h| h[k] = { 'en-US' => v } }
63
+ fields: attrs.transform_values { |v| { 'en-US' => v } }
66
64
  }
67
65
 
68
66
  double(attrs)
@@ -8,9 +8,7 @@ module WCC::Contentful::Test::Factory
8
8
  # All attributes that are known to be required fields on the content type
9
9
  # will return a default value based on the field type.
10
10
  def contentful_create(const, context = nil, **attrs)
11
- unless const.respond_to?(:content_type_definition)
12
- const = WCC::Contentful::Model.resolve_constant(const.to_s)
13
- end
11
+ const = WCC::Contentful::Model.resolve_constant(const.to_s) unless const.respond_to?(:content_type_definition)
14
12
  attrs = attrs.transform_keys { |a| a.to_s.camelize(:lower) }
15
13
 
16
14
  id = attrs.delete('id')
@@ -59,7 +57,7 @@ module WCC::Contentful::Test::Factory
59
57
  sys: {
60
58
  type: 'Link',
61
59
  linkType: 'Space',
62
- id: ENV['CONTENTFUL_SPACE_ID']
60
+ id: ENV.fetch('CONTENTFUL_SPACE_ID', nil)
63
61
  }
64
62
  },
65
63
  id: id || SecureRandom.urlsafe_base64,
@@ -86,8 +84,8 @@ module WCC::Contentful::Test::Factory
86
84
  end
87
85
 
88
86
  def contentful_fields(model)
89
- WCC::Contentful::Test::Attributes.defaults(model).each_with_object({}) do |(k, v), h|
90
- h[k] = { 'en-US' => v }
87
+ WCC::Contentful::Test::Attributes.defaults(model).transform_values do |v|
88
+ { 'en-US' => v }
91
89
  end
92
90
  end
93
91
 
@@ -2,6 +2,6 @@
2
2
 
3
3
  module WCC
4
4
  module Contentful
5
- VERSION = '1.2.0'
5
+ VERSION = '1.2.1'
6
6
  end
7
7
  end
@@ -48,7 +48,7 @@ module WCC::Contentful
48
48
  def logger
49
49
  return Rails.logger if defined?(Rails)
50
50
 
51
- @logger ||= Logger.new(STDERR)
51
+ @logger ||= Logger.new($stderr)
52
52
  end
53
53
  end
54
54
 
@@ -82,7 +82,7 @@ module WCC::Contentful
82
82
 
83
83
  if configuration.update_schema_file == :always ||
84
84
  (configuration.update_schema_file == :if_possible && Services.instance.management_client) ||
85
- configuration.update_schema_file == :if_missing && !File.exist?(configuration.schema_file)
85
+ (configuration.update_schema_file == :if_missing && !File.exist?(configuration.schema_file))
86
86
 
87
87
  begin
88
88
  downloader = WCC::Contentful::DownloadsSchema.new
@@ -96,9 +96,7 @@ module WCC::Contentful
96
96
 
97
97
  content_types =
98
98
  begin
99
- if File.exist?(configuration.schema_file)
100
- JSON.parse(File.read(configuration.schema_file))['contentTypes']
101
- end
99
+ JSON.parse(File.read(configuration.schema_file))['contentTypes'] if File.exist?(configuration.schema_file)
102
100
  rescue JSON::ParserError
103
101
  WCC::Contentful.logger.warn("Schema file invalid, ignoring it: #{configuration.schema_file}")
104
102
  nil
@@ -119,8 +117,8 @@ module WCC::Contentful
119
117
  end
120
118
 
121
119
  unless content_types
122
- raise InitializationError, 'Unable to load content types from schema file or API!' \
123
- ' Check your access token and space ID.'
120
+ raise InitializationError, 'Unable to load content types from schema file or API! ' \
121
+ 'Check your access token and space ID.'
124
122
  end
125
123
 
126
124
  # Set the schema on the default WCC::Contentful::Model
@@ -6,7 +6,7 @@ require 'wcc/contentful/version'
6
6
 
7
7
  doc_version = Gem::Version.new(WCC::Contentful::VERSION).release.to_s.sub(/\.\d+$/, '')
8
8
 
9
- # rubocop:disable Metrics/LineLength
9
+ # rubocop:disable Layout/LineLength
10
10
  Gem::Specification.new do |spec|
11
11
  spec.name = 'wcc-contentful'
12
12
  spec.version = WCC::Contentful::VERSION
@@ -19,10 +19,11 @@ Gem::Specification.new do |spec|
19
19
  spec.license = 'MIT'
20
20
 
21
21
  spec.metadata = {
22
- 'documentation_uri' => "https://watermarkchurch.github.io/wcc-contentful/#{doc_version}/wcc-contentful"
22
+ 'documentation_uri' => "https://watermarkchurch.github.io/wcc-contentful/#{doc_version}/wcc-contentful",
23
+ 'rubygems_mfa_required' => 'true'
23
24
  }
24
25
 
25
- spec.required_ruby_version = '>= 2.3'
26
+ spec.required_ruby_version = '>= 2.7'
26
27
 
27
28
  spec.files = Dir['app/**/*', 'config/**/*', 'lib/**/*'] +
28
29
  %w[Rakefile README.md wcc-contentful.gemspec]
@@ -38,7 +39,6 @@ Gem::Specification.new do |spec|
38
39
  spec.add_development_dependency 'rspec', '~> 3.0'
39
40
  spec.add_development_dependency 'rspec-instrumentation-matcher'
40
41
  spec.add_development_dependency 'rspec_junit_formatter', '~> 0.4.1'
41
- spec.add_development_dependency 'rubocop', '0.68'
42
42
  spec.add_development_dependency 'simplecov', '~> 0.16.1'
43
43
  spec.add_development_dependency 'vcr', '~> 5.0'
44
44
  spec.add_development_dependency 'webmock', '~> 3.0'
@@ -68,4 +68,4 @@ Gem::Specification.new do |spec|
68
68
  spec.add_dependency 'wcc-base', '~> 0.3.1'
69
69
  spec.add_dependency 'wisper', '~> 2.0.0'
70
70
  end
71
- # rubocop:enable Metrics/LineLength
71
+ # rubocop:enable Layout/LineLength
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: wcc-contentful
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.0
4
+ version: 1.2.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Watermark Dev
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-06-30 00:00:00.000000000 Z
11
+ date: 2022-08-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: byebug
@@ -136,20 +136,6 @@ dependencies:
136
136
  - - "~>"
137
137
  - !ruby/object:Gem::Version
138
138
  version: 0.4.1
139
- - !ruby/object:Gem::Dependency
140
- name: rubocop
141
- requirement: !ruby/object:Gem::Requirement
142
- requirements:
143
- - - '='
144
- - !ruby/object:Gem::Version
145
- version: '0.68'
146
- type: :development
147
- prerelease: false
148
- version_requirements: !ruby/object:Gem::Requirement
149
- requirements:
150
- - - '='
151
- - !ruby/object:Gem::Version
152
- version: '0.68'
153
139
  - !ruby/object:Gem::Dependency
154
140
  name: simplecov
155
141
  requirement: !ruby/object:Gem::Requirement
@@ -504,7 +490,8 @@ licenses:
504
490
  - MIT
505
491
  metadata:
506
492
  documentation_uri: https://watermarkchurch.github.io/wcc-contentful/1.2/wcc-contentful
507
- post_install_message:
493
+ rubygems_mfa_required: 'true'
494
+ post_install_message:
508
495
  rdoc_options: []
509
496
  require_paths:
510
497
  - lib
@@ -512,15 +499,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
512
499
  requirements:
513
500
  - - ">="
514
501
  - !ruby/object:Gem::Version
515
- version: '2.3'
502
+ version: '2.7'
516
503
  required_rubygems_version: !ruby/object:Gem::Requirement
517
504
  requirements:
518
505
  - - ">="
519
506
  - !ruby/object:Gem::Version
520
507
  version: '0'
521
508
  requirements: []
522
- rubygems_version: 3.3.7
523
- signing_key:
509
+ rubygems_version: 3.1.6
510
+ signing_key:
524
511
  specification_version: 4
525
512
  summary: '[![Gem Version](https://badge.fury.io/rb/wcc-contentful.svg)](https://rubygems.org/gems/wcc-contentful)
526
513
  [![Build Status](https://circleci.com/gh/watermarkchurch/wcc-contentful.svg?style=svg)](https://circleci.com/gh/watermarkchurch/wcc-contentful)