wcc-contentful 0.4.0.pre.rc → 1.0.0.pre.rc1

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.
Files changed (66) hide show
  1. checksums.yaml +5 -5
  2. data/Guardfile +43 -0
  3. data/README.md +101 -12
  4. data/app/controllers/wcc/contentful/webhook_controller.rb +25 -24
  5. data/app/jobs/wcc/contentful/webhook_enable_job.rb +36 -2
  6. data/config/routes.rb +1 -1
  7. data/doc/wcc-contentful.png +0 -0
  8. data/lib/tasks/download_schema.rake +12 -0
  9. data/lib/wcc/contentful.rb +70 -16
  10. data/lib/wcc/contentful/active_record_shim.rb +72 -0
  11. data/lib/wcc/contentful/configuration.rb +177 -46
  12. data/lib/wcc/contentful/content_type_indexer.rb +14 -0
  13. data/lib/wcc/contentful/downloads_schema.rb +112 -0
  14. data/lib/wcc/contentful/engine.rb +33 -14
  15. data/lib/wcc/contentful/event.rb +171 -0
  16. data/lib/wcc/contentful/events.rb +41 -0
  17. data/lib/wcc/contentful/exceptions.rb +3 -0
  18. data/lib/wcc/contentful/indexed_representation.rb +2 -2
  19. data/lib/wcc/contentful/instrumentation.rb +31 -0
  20. data/lib/wcc/contentful/link.rb +28 -0
  21. data/lib/wcc/contentful/link_visitor.rb +122 -0
  22. data/lib/wcc/contentful/middleware.rb +7 -0
  23. data/lib/wcc/contentful/middleware/store.rb +158 -0
  24. data/lib/wcc/contentful/middleware/store/caching_middleware.rb +114 -0
  25. data/lib/wcc/contentful/model.rb +37 -3
  26. data/lib/wcc/contentful/model_builder.rb +1 -0
  27. data/lib/wcc/contentful/model_methods.rb +40 -15
  28. data/lib/wcc/contentful/model_singleton_methods.rb +47 -30
  29. data/lib/wcc/contentful/rake.rb +3 -0
  30. data/lib/wcc/contentful/rspec.rb +13 -8
  31. data/lib/wcc/contentful/services.rb +61 -27
  32. data/lib/wcc/contentful/simple_client.rb +81 -25
  33. data/lib/wcc/contentful/simple_client/management.rb +43 -10
  34. data/lib/wcc/contentful/simple_client/response.rb +61 -22
  35. data/lib/wcc/contentful/simple_client/typhoeus_adapter.rb +17 -17
  36. data/lib/wcc/contentful/store.rb +7 -66
  37. data/lib/wcc/contentful/store/README.md +85 -0
  38. data/lib/wcc/contentful/store/base.rb +34 -119
  39. data/lib/wcc/contentful/store/cdn_adapter.rb +71 -12
  40. data/lib/wcc/contentful/store/factory.rb +186 -0
  41. data/lib/wcc/contentful/store/instrumentation.rb +55 -0
  42. data/lib/wcc/contentful/store/interface.rb +82 -0
  43. data/lib/wcc/contentful/store/memory_store.rb +27 -24
  44. data/lib/wcc/contentful/store/postgres_store.rb +253 -107
  45. data/lib/wcc/contentful/store/postgres_store/schema_1.sql +73 -0
  46. data/lib/wcc/contentful/store/postgres_store/schema_2.sql +21 -0
  47. data/lib/wcc/contentful/store/query.rb +246 -0
  48. data/lib/wcc/contentful/store/query/interface.rb +63 -0
  49. data/lib/wcc/contentful/store/rspec_examples.rb +48 -0
  50. data/lib/wcc/contentful/store/rspec_examples/basic_store.rb +629 -0
  51. data/lib/wcc/contentful/store/rspec_examples/include_param.rb +283 -0
  52. data/lib/wcc/contentful/store/rspec_examples/nested_queries.rb +342 -0
  53. data/lib/wcc/contentful/sync_engine.rb +181 -0
  54. data/lib/wcc/contentful/test/attributes.rb +17 -5
  55. data/lib/wcc/contentful/test/factory.rb +22 -46
  56. data/lib/wcc/contentful/version.rb +1 -1
  57. data/wcc-contentful.gemspec +14 -11
  58. metadata +201 -146
  59. data/Gemfile +0 -6
  60. data/app/jobs/wcc/contentful/delayed_sync_job.rb +0 -63
  61. data/lib/wcc/contentful/client_ext.rb +0 -28
  62. data/lib/wcc/contentful/graphql.rb +0 -14
  63. data/lib/wcc/contentful/graphql/builder.rb +0 -177
  64. data/lib/wcc/contentful/graphql/types.rb +0 -54
  65. data/lib/wcc/contentful/simple_client/http_adapter.rb +0 -24
  66. data/lib/wcc/contentful/store/lazy_cache_store.rb +0 -161
@@ -0,0 +1,181 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'wcc/contentful/event'
4
+ require 'wisper'
5
+
6
+ begin
7
+ gem 'activejob'
8
+ require 'active_job'
9
+ rescue Gem::LoadError # rubocop:disable Lint/HandleExceptions
10
+ # suppress
11
+ end
12
+
13
+ module WCC::Contentful
14
+ # The SyncEngine is used to keep the currently configured store up to date
15
+ # using the Sync API. It is available on the WCC::Contentful::Services instance,
16
+ # and the application is responsible to periodically call #next in order to hit
17
+ # the sync API and update the store.
18
+ #
19
+ # If you have mounted the WCC::Contentful::Engine, AND the configured store is
20
+ # one that can be synced (i.e. it responds to `:index`), then
21
+ # the WCC::Contentful::WebhookController will call #next automatically anytime
22
+ # a webhook is received. Otherwise you should hook up to the Webhook events
23
+ # and call the sync engine via your initializer:
24
+ # WCC::Contentful::Events.subscribe(proc do |event|
25
+ # WCC::Contentful::Services.instance.sync_engine.next(up_to: event.dig('sys', 'id'))
26
+ # end, with: :call)
27
+ class SyncEngine
28
+ include ::Wisper::Publisher
29
+
30
+ def state
31
+ (@state&.dup || token_wrapper_factory(nil)).freeze
32
+ end
33
+
34
+ attr_reader :store
35
+ attr_reader :client
36
+
37
+ def should_sync?
38
+ store&.index?
39
+ end
40
+
41
+ def initialize(state: nil, store: nil, client: nil, key: nil)
42
+ @state_key = key || "sync:#{object_id}"
43
+ @client = client || WCC::Contentful::Services.instance.client
44
+ @mutex = Mutex.new
45
+
46
+ if store
47
+ unless %i[index index? find].all? { |m| store.respond_to?(m) }
48
+ raise ArgumentError, ':store param must implement the Store interface'
49
+ end
50
+
51
+ @store = store
52
+ @state = read_state if should_sync?
53
+ end
54
+ if state
55
+ @state = token_wrapper_factory(state)
56
+ raise ArgumentError, ':state param must be a String or Hash' unless @state.is_a? Hash
57
+ unless @state.dig('sys', 'type') == 'token'
58
+ raise ArgumentError, ':state param must be of sys.type = "token"'
59
+ end
60
+ end
61
+ raise ArgumentError, 'either :state or :store must be provided' unless @state || @store
62
+ end
63
+
64
+ # Gets the next increment of data from the Sync API.
65
+ # If the configured store responds to `:index`, that will be called with each
66
+ # item in the Sync response to update the store.
67
+ # If a block is passed, that block will be evaluated with each item in the
68
+ # response.
69
+ # @param [String] up_to_id An ID to look for in the response. The method returns
70
+ # true if the ID was found or no up_to_id was given, false if the ID did not come back.
71
+ # @return [Array] A `[Boolean, Integer]` tuple where the first value is whether the ID was found,
72
+ # and the second value is the number of items returned.
73
+ def next(up_to_id: nil)
74
+ id_found = up_to_id.nil?
75
+ all_events = []
76
+
77
+ @mutex.synchronize do
78
+ @state ||= read_state || token_wrapper_factory(nil)
79
+ next_sync_token = @state['token']
80
+
81
+ sync_resp = client.sync(sync_token: next_sync_token)
82
+ sync_resp.items.each do |item|
83
+ id = item.dig('sys', 'id')
84
+ id_found ||= id == up_to_id
85
+
86
+ store.index(item) if store&.index?
87
+ event = WCC::Contentful::Event.from_raw(item, source: self)
88
+ yield(event) if block_given?
89
+ emit_event(event)
90
+ all_events << event
91
+ end
92
+
93
+ @state['token'] = sync_resp.next_sync_token
94
+ write_state
95
+ end
96
+
97
+ emit_sync_complete(all_events)
98
+
99
+ [id_found, all_events.length]
100
+ end
101
+
102
+ def emit_event(event)
103
+ type = event.dig('sys', 'type')
104
+ raise ArgumentError, "Unknown event type #{event}" unless type.present?
105
+
106
+ broadcast(type, event)
107
+ end
108
+
109
+ def emit_sync_complete(events)
110
+ event = WCC::Contentful::Event::SyncComplete.new(events, source: self)
111
+ broadcast('SyncComplete', event)
112
+ end
113
+
114
+ private
115
+
116
+ def read_state
117
+ return unless found = store&.find(@state_key)
118
+
119
+ # backwards compat - migrate existing state
120
+ token_wrapper_factory(found)
121
+ end
122
+
123
+ def write_state
124
+ store.index(@state) if store&.index?
125
+ end
126
+
127
+ def token_wrapper_factory(state)
128
+ state = { 'token' => state } unless state.is_a? Hash
129
+
130
+ state.merge!('sys' => { 'id' => @state_key, 'type' => 'token' }) unless state['sys']
131
+ state
132
+ end
133
+
134
+ # Define the job only if rails is loaded
135
+ if defined?(ActiveJob)
136
+ # This job uses the Contentful Sync API to update the configured store with
137
+ # the latest data from Contentful.
138
+ class Job < ActiveJob::Base
139
+ include WCC::Contentful::ServiceAccessors
140
+
141
+ self.queue_adapter = :async
142
+ queue_as :default
143
+
144
+ def perform(event = nil)
145
+ return unless sync_engine&.should_sync?
146
+
147
+ up_to_id = nil
148
+ up_to_id = event[:up_to_id] || event.dig('sys', 'id') if event
149
+ sync!(up_to_id: up_to_id)
150
+ end
151
+
152
+ # Calls the Contentful Sync API and updates the configured store with the returned
153
+ # data.
154
+ #
155
+ # @param [String] up_to_id
156
+ # An ID that we know has changed and should come back from the sync.
157
+ # If we don't find this ID in the sync data, then drop a job to try
158
+ # the sync again after a few minutes.
159
+ #
160
+ def sync!(up_to_id: nil)
161
+ id_found, count = sync_engine.next(up_to_id: up_to_id)
162
+
163
+ next_sync_token = sync_engine.state['token']
164
+
165
+ logger.info "Synced #{count} entries. Next sync token:\n #{next_sync_token}"
166
+ logger.info "Should enqueue again? [#{!id_found}]"
167
+ # Passing nil to only enqueue the job 1 more time
168
+ sync_later!(up_to_id: nil) unless id_found
169
+ next_sync_token
170
+ end
171
+
172
+ # Drops an ActiveJob job to invoke WCC::Contentful.sync! after a given amount
173
+ # of time.
174
+ def sync_later!(up_to_id: nil, wait: 10.minutes)
175
+ self.class.set(wait: wait)
176
+ .perform_later(up_to_id: up_to_id)
177
+ end
178
+ end
179
+ end
180
+ end
181
+ end
@@ -5,10 +5,22 @@ module WCC::Contentful::Test::Attributes
5
5
  String: 'test',
6
6
  Int: 0,
7
7
  Float: 0.0,
8
- DateTime: Time.at(0),
8
+ DateTime: Time.at(0).to_s,
9
9
  Boolean: false,
10
- Json: -> { OpenStruct.new },
11
- Coordinates: -> { OpenStruct.new }
10
+ Json: ->(_f) { {} },
11
+ Coordinates: ->(_f) { {} },
12
+ Asset: ->(f) {
13
+ WCC::Contentful::Link.new(
14
+ "fake-#{f.name}-#{SecureRandom.urlsafe_base64[1..6]}",
15
+ :Asset
16
+ ).raw
17
+ },
18
+ Link: ->(f) {
19
+ WCC::Contentful::Link.new(
20
+ "fake-#{f.name}-#{SecureRandom.urlsafe_base64[1..6]}",
21
+ :Link
22
+ ).raw
23
+ }
12
24
  }.freeze
13
25
 
14
26
  class << self
@@ -35,8 +47,8 @@ module WCC::Contentful::Test::Attributes
35
47
  return [] if field.array
36
48
  return unless field.required
37
49
 
38
- val = DEFAULTS[field]
39
- return val.call if val.respond_to?(:call)
50
+ val = DEFAULTS[field.type]
51
+ return val.call(field) if val.respond_to?(:call)
40
52
 
41
53
  val
42
54
  end
@@ -7,62 +7,38 @@ module WCC::Contentful::Test::Factory
7
7
  # Builds a in-memory instance of the Contentful model for the given content_type.
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
- def contentful_create(content_type, **attrs)
10
+ def contentful_create(content_type, context = nil, **attrs)
11
11
  const = WCC::Contentful::Model.resolve_constant(content_type.to_s)
12
12
  attrs = attrs.transform_keys { |a| a.to_s.camelize(:lower) }
13
13
 
14
14
  id = attrs.delete('id')
15
+ sys = attrs.delete('sys')
16
+ raw = attrs.delete('raw') || default_raw(const, id)
15
17
  bad_attrs = attrs.reject { |a| const.content_type_definition.fields.key?(a) }
16
18
  raise ArgumentError, "Attribute(s) do not exist on #{const}: #{bad_attrs.keys}" if bad_attrs.any?
17
19
 
18
- default_instance(const, id).tap do |instance|
19
- attrs.each do |k, v|
20
- field = const.content_type_definition.fields[k]
20
+ raw['sys'].merge!(sys) if sys
21
21
 
22
- raw = v
23
- if %i[Asset Link].include?(field.type)
24
- raw = to_raw(v, field.type)
22
+ attrs.each do |k, v|
23
+ field = const.content_type_definition.fields[k]
25
24
 
26
- unless field.array ? v.any? { |i| i.is_a?(String) } : v.is_a?(String)
27
- instance.instance_variable_set("@#{field.name}_resolved", v)
28
- end
29
- end
25
+ raw_value = v
26
+ raw_value = to_raw(v, field.type) if %i[Asset Link].include?(field.type)
27
+ raw['fields'][field.name][raw.dig('sys', 'locale')] = raw_value
28
+ end
30
29
 
31
- instance.raw['fields'][field.name][instance.sys.locale] = raw
32
- instance.instance_variable_set("@#{field.name}", raw)
33
- end
30
+ instance = const.new(raw, context)
34
31
 
35
- def instance.to_s
36
- "#<#{self.class.name} id=\"#{id}\">"
37
- end
38
- end
39
- end
32
+ attrs.each do |k, v|
33
+ field = const.content_type_definition.fields[k]
34
+ next unless %i[Asset Link].include?(field.type)
40
35
 
41
- class Link
42
- attr_reader :id
43
- attr_reader :link_type
44
- attr_reader :raw
45
-
46
- LINK_TYPES = {
47
- Asset: 'Asset',
48
- Link: 'Entry'
49
- }.freeze
50
-
51
- def initialize(model, link_type = nil)
52
- @id = model.try(:id) || model
53
- @link_type = link_type
54
- @link_type ||= model.is_a?(WCC::Contentful::Model::Asset) ? :Asset : :Link
55
- @raw =
56
- {
57
- 'sys' => {
58
- 'type' => 'Link',
59
- 'linkType' => LINK_TYPES[@link_type],
60
- 'id' => @id
61
- }
62
- }
36
+ unless field.array ? v.any? { |i| i.is_a?(String) } : v.is_a?(String)
37
+ instance.instance_variable_set("@#{field.name}_resolved", v)
38
+ end
63
39
  end
64
40
 
65
- alias_method :to_h, :raw
41
+ instance
66
42
  end
67
43
 
68
44
  private
@@ -72,10 +48,10 @@ module WCC::Contentful::Test::Factory
72
48
  end
73
49
 
74
50
  def default_raw(model, id = nil)
75
- { sys: sys(model, id), fields: fields(model) }.as_json
51
+ { sys: contentful_sys(model, id), fields: contentful_fields(model) }.as_json
76
52
  end
77
53
 
78
- def sys(model, id = nil)
54
+ def contentful_sys(model, id = nil)
79
55
  {
80
56
  space: {
81
57
  sys: {
@@ -107,7 +83,7 @@ module WCC::Contentful::Test::Factory
107
83
  }
108
84
  end
109
85
 
110
- def fields(model)
86
+ def contentful_fields(model)
111
87
  WCC::Contentful::Test::Attributes.defaults(model).each_with_object({}) do |(k, v), h|
112
88
  h[k] = { 'en-US' => v }
113
89
  end
@@ -117,7 +93,7 @@ module WCC::Contentful::Test::Factory
117
93
  if val.is_a? Array
118
94
  val.map { |i| to_raw(i, field_type) }
119
95
  elsif val.is_a? String
120
- Link.new(val, field_type).raw
96
+ WCC::Contentful::Link.new(val, field_type).raw
121
97
  elsif val
122
98
  val.raw
123
99
  end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module WCC
4
4
  module Contentful
5
- VERSION = '0.4.0-rc'
5
+ VERSION = '1.0.0-rc1'
6
6
  end
7
7
  end
@@ -24,39 +24,42 @@ Gem::Specification.new do |spec|
24
24
 
25
25
  spec.require_paths = ['lib']
26
26
 
27
+ spec.add_development_dependency 'byebug', '~> 11.0.1'
27
28
  spec.add_development_dependency 'coveralls'
28
29
  spec.add_development_dependency 'dotenv', '~> 2.2'
30
+ spec.add_development_dependency 'erb_lint', '~> 0.0.26'
29
31
  spec.add_development_dependency 'httplog', '~> 1.0'
30
- spec.add_development_dependency 'rake', '~> 10.0'
32
+ spec.add_development_dependency 'rake', '~> 13.0'
31
33
  spec.add_development_dependency 'rspec', '~> 3.0'
32
- spec.add_development_dependency 'rspec_junit_formatter', '~> 0.3.0'
33
- spec.add_development_dependency 'rubocop', '~> 0.52'
34
+ spec.add_development_dependency 'rspec-instrumentation-matcher'
35
+ spec.add_development_dependency 'rspec_junit_formatter', '~> 0.4.1'
36
+ spec.add_development_dependency 'rubocop', '0.68'
34
37
  spec.add_development_dependency 'simplecov', '~> 0.16.1'
35
- spec.add_development_dependency 'vcr', '~> 4.0'
38
+ spec.add_development_dependency 'vcr', '~> 5.0'
36
39
  spec.add_development_dependency 'webmock', '~> 3.0'
40
+ spec.add_development_dependency 'wisper-rspec'
37
41
 
38
42
  # Makes testing easy via `bundle exec guard`
39
43
  spec.add_development_dependency 'guard', '~> 2.14'
40
44
  spec.add_development_dependency 'guard-rspec', '~> 4.7'
41
45
  spec.add_development_dependency 'guard-rubocop', '~> 1.3.0'
46
+ spec.add_development_dependency 'guard-shell', '~> 0.7.1'
42
47
 
43
48
  # for generators
44
49
  spec.add_development_dependency 'generator_spec', '~> 0.9.4'
45
- spec.add_development_dependency 'rails', '~> 5.1'
46
- spec.add_development_dependency 'rspec-rails', '~> 3.7'
47
- spec.add_development_dependency 'sqlite3'
50
+ # spec.add_development_dependency 'rails', '~> 5.0'
51
+ # spec.add_development_dependency 'rspec-rails', '~> 3.7'
52
+ spec.add_development_dependency 'sqlite3', '~> 1.3.6'
48
53
  spec.add_development_dependency 'timecop', '~> 0.9.1'
49
54
 
50
55
  # optional dependencies
51
56
  spec.add_development_dependency 'connection_pool', '~> 2.2'
52
- spec.add_development_dependency 'contentful', '2.6.0'
53
- spec.add_development_dependency 'contentful-management', '2.0.2'
54
- spec.add_development_dependency 'graphql', '~> 1.7'
57
+ spec.add_development_dependency 'faraday', '~> 0.9'
55
58
  spec.add_development_dependency 'http', '> 1.0', '< 3.0'
56
59
  spec.add_development_dependency 'pg', '~> 1.0'
57
60
  spec.add_development_dependency 'typhoeus', '~> 1.3'
58
61
 
59
62
  spec.add_dependency 'activesupport', '>= 5'
60
- spec.add_dependency 'dry-validation', '~> 0.11.1'
61
63
  spec.add_dependency 'wcc-base', '~> 0.3.1'
64
+ spec.add_dependency 'wisper', '~> 2.0.0'
62
65
  end
metadata CHANGED
@@ -1,15 +1,29 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: wcc-contentful
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.0.pre.rc
4
+ version: 1.0.0.pre.rc1
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: 2018-10-22 00:00:00.000000000 Z
11
+ date: 2021-01-18 00:00:00.000000000 Z
12
12
  dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: byebug
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: 11.0.1
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: 11.0.1
13
27
  - !ruby/object:Gem::Dependency
14
28
  name: coveralls
15
29
  requirement: !ruby/object:Gem::Requirement
@@ -38,6 +52,20 @@ dependencies:
38
52
  - - "~>"
39
53
  - !ruby/object:Gem::Version
40
54
  version: '2.2'
55
+ - !ruby/object:Gem::Dependency
56
+ name: erb_lint
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: 0.0.26
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: 0.0.26
41
69
  - !ruby/object:Gem::Dependency
42
70
  name: httplog
43
71
  requirement: !ruby/object:Gem::Requirement
@@ -58,14 +86,14 @@ dependencies:
58
86
  requirements:
59
87
  - - "~>"
60
88
  - !ruby/object:Gem::Version
61
- version: '10.0'
89
+ version: '13.0'
62
90
  type: :development
63
91
  prerelease: false
64
92
  version_requirements: !ruby/object:Gem::Requirement
65
93
  requirements:
66
94
  - - "~>"
67
95
  - !ruby/object:Gem::Version
68
- version: '10.0'
96
+ version: '13.0'
69
97
  - !ruby/object:Gem::Dependency
70
98
  name: rspec
71
99
  requirement: !ruby/object:Gem::Requirement
@@ -80,34 +108,48 @@ dependencies:
80
108
  - - "~>"
81
109
  - !ruby/object:Gem::Version
82
110
  version: '3.0'
111
+ - !ruby/object:Gem::Dependency
112
+ name: rspec-instrumentation-matcher
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - ">="
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - ">="
123
+ - !ruby/object:Gem::Version
124
+ version: '0'
83
125
  - !ruby/object:Gem::Dependency
84
126
  name: rspec_junit_formatter
85
127
  requirement: !ruby/object:Gem::Requirement
86
128
  requirements:
87
129
  - - "~>"
88
130
  - !ruby/object:Gem::Version
89
- version: 0.3.0
131
+ version: 0.4.1
90
132
  type: :development
91
133
  prerelease: false
92
134
  version_requirements: !ruby/object:Gem::Requirement
93
135
  requirements:
94
136
  - - "~>"
95
137
  - !ruby/object:Gem::Version
96
- version: 0.3.0
138
+ version: 0.4.1
97
139
  - !ruby/object:Gem::Dependency
98
140
  name: rubocop
99
141
  requirement: !ruby/object:Gem::Requirement
100
142
  requirements:
101
- - - "~>"
143
+ - - '='
102
144
  - !ruby/object:Gem::Version
103
- version: '0.52'
145
+ version: '0.68'
104
146
  type: :development
105
147
  prerelease: false
106
148
  version_requirements: !ruby/object:Gem::Requirement
107
149
  requirements:
108
- - - "~>"
150
+ - - '='
109
151
  - !ruby/object:Gem::Version
110
- version: '0.52'
152
+ version: '0.68'
111
153
  - !ruby/object:Gem::Dependency
112
154
  name: simplecov
113
155
  requirement: !ruby/object:Gem::Requirement
@@ -128,14 +170,14 @@ dependencies:
128
170
  requirements:
129
171
  - - "~>"
130
172
  - !ruby/object:Gem::Version
131
- version: '4.0'
173
+ version: '5.0'
132
174
  type: :development
133
175
  prerelease: false
134
176
  version_requirements: !ruby/object:Gem::Requirement
135
177
  requirements:
136
178
  - - "~>"
137
179
  - !ruby/object:Gem::Version
138
- version: '4.0'
180
+ version: '5.0'
139
181
  - !ruby/object:Gem::Dependency
140
182
  name: webmock
141
183
  requirement: !ruby/object:Gem::Requirement
@@ -150,6 +192,20 @@ dependencies:
150
192
  - - "~>"
151
193
  - !ruby/object:Gem::Version
152
194
  version: '3.0'
195
+ - !ruby/object:Gem::Dependency
196
+ name: wisper-rspec
197
+ requirement: !ruby/object:Gem::Requirement
198
+ requirements:
199
+ - - ">="
200
+ - !ruby/object:Gem::Version
201
+ version: '0'
202
+ type: :development
203
+ prerelease: false
204
+ version_requirements: !ruby/object:Gem::Requirement
205
+ requirements:
206
+ - - ">="
207
+ - !ruby/object:Gem::Version
208
+ version: '0'
153
209
  - !ruby/object:Gem::Dependency
154
210
  name: guard
155
211
  requirement: !ruby/object:Gem::Requirement
@@ -193,61 +249,47 @@ dependencies:
193
249
  - !ruby/object:Gem::Version
194
250
  version: 1.3.0
195
251
  - !ruby/object:Gem::Dependency
196
- name: generator_spec
252
+ name: guard-shell
197
253
  requirement: !ruby/object:Gem::Requirement
198
254
  requirements:
199
255
  - - "~>"
200
256
  - !ruby/object:Gem::Version
201
- version: 0.9.4
257
+ version: 0.7.1
202
258
  type: :development
203
259
  prerelease: false
204
260
  version_requirements: !ruby/object:Gem::Requirement
205
261
  requirements:
206
262
  - - "~>"
207
263
  - !ruby/object:Gem::Version
208
- version: 0.9.4
264
+ version: 0.7.1
209
265
  - !ruby/object:Gem::Dependency
210
- name: rails
266
+ name: generator_spec
211
267
  requirement: !ruby/object:Gem::Requirement
212
268
  requirements:
213
269
  - - "~>"
214
270
  - !ruby/object:Gem::Version
215
- version: '5.1'
271
+ version: 0.9.4
216
272
  type: :development
217
273
  prerelease: false
218
274
  version_requirements: !ruby/object:Gem::Requirement
219
275
  requirements:
220
276
  - - "~>"
221
277
  - !ruby/object:Gem::Version
222
- version: '5.1'
278
+ version: 0.9.4
223
279
  - !ruby/object:Gem::Dependency
224
- name: rspec-rails
280
+ name: sqlite3
225
281
  requirement: !ruby/object:Gem::Requirement
226
282
  requirements:
227
283
  - - "~>"
228
284
  - !ruby/object:Gem::Version
229
- version: '3.7'
285
+ version: 1.3.6
230
286
  type: :development
231
287
  prerelease: false
232
288
  version_requirements: !ruby/object:Gem::Requirement
233
289
  requirements:
234
290
  - - "~>"
235
291
  - !ruby/object:Gem::Version
236
- version: '3.7'
237
- - !ruby/object:Gem::Dependency
238
- name: sqlite3
239
- requirement: !ruby/object:Gem::Requirement
240
- requirements:
241
- - - ">="
242
- - !ruby/object:Gem::Version
243
- version: '0'
244
- type: :development
245
- prerelease: false
246
- version_requirements: !ruby/object:Gem::Requirement
247
- requirements:
248
- - - ">="
249
- - !ruby/object:Gem::Version
250
- version: '0'
292
+ version: 1.3.6
251
293
  - !ruby/object:Gem::Dependency
252
294
  name: timecop
253
295
  requirement: !ruby/object:Gem::Requirement
@@ -277,47 +319,19 @@ dependencies:
277
319
  - !ruby/object:Gem::Version
278
320
  version: '2.2'
279
321
  - !ruby/object:Gem::Dependency
280
- name: contentful
281
- requirement: !ruby/object:Gem::Requirement
282
- requirements:
283
- - - '='
284
- - !ruby/object:Gem::Version
285
- version: 2.6.0
286
- type: :development
287
- prerelease: false
288
- version_requirements: !ruby/object:Gem::Requirement
289
- requirements:
290
- - - '='
291
- - !ruby/object:Gem::Version
292
- version: 2.6.0
293
- - !ruby/object:Gem::Dependency
294
- name: contentful-management
295
- requirement: !ruby/object:Gem::Requirement
296
- requirements:
297
- - - '='
298
- - !ruby/object:Gem::Version
299
- version: 2.0.2
300
- type: :development
301
- prerelease: false
302
- version_requirements: !ruby/object:Gem::Requirement
303
- requirements:
304
- - - '='
305
- - !ruby/object:Gem::Version
306
- version: 2.0.2
307
- - !ruby/object:Gem::Dependency
308
- name: graphql
322
+ name: faraday
309
323
  requirement: !ruby/object:Gem::Requirement
310
324
  requirements:
311
325
  - - "~>"
312
326
  - !ruby/object:Gem::Version
313
- version: '1.7'
327
+ version: '0.9'
314
328
  type: :development
315
329
  prerelease: false
316
330
  version_requirements: !ruby/object:Gem::Requirement
317
331
  requirements:
318
332
  - - "~>"
319
333
  - !ruby/object:Gem::Version
320
- version: '1.7'
334
+ version: '0.9'
321
335
  - !ruby/object:Gem::Dependency
322
336
  name: http
323
337
  requirement: !ruby/object:Gem::Requirement
@@ -381,33 +395,33 @@ dependencies:
381
395
  - !ruby/object:Gem::Version
382
396
  version: '5'
383
397
  - !ruby/object:Gem::Dependency
384
- name: dry-validation
398
+ name: wcc-base
385
399
  requirement: !ruby/object:Gem::Requirement
386
400
  requirements:
387
401
  - - "~>"
388
402
  - !ruby/object:Gem::Version
389
- version: 0.11.1
403
+ version: 0.3.1
390
404
  type: :runtime
391
405
  prerelease: false
392
406
  version_requirements: !ruby/object:Gem::Requirement
393
407
  requirements:
394
408
  - - "~>"
395
409
  - !ruby/object:Gem::Version
396
- version: 0.11.1
410
+ version: 0.3.1
397
411
  - !ruby/object:Gem::Dependency
398
- name: wcc-base
412
+ name: wisper
399
413
  requirement: !ruby/object:Gem::Requirement
400
414
  requirements:
401
415
  - - "~>"
402
416
  - !ruby/object:Gem::Version
403
- version: 0.3.1
417
+ version: 2.0.0
404
418
  type: :runtime
405
419
  prerelease: false
406
420
  version_requirements: !ruby/object:Gem::Requirement
407
421
  requirements:
408
422
  - - "~>"
409
423
  - !ruby/object:Gem::Version
410
- version: 0.3.1
424
+ version: 2.0.0
411
425
  description: Contentful API wrapper library exposing an ActiveRecord-like interface
412
426
  email:
413
427
  - dev@watermark.org
@@ -416,12 +430,10 @@ extensions: []
416
430
  extra_rdoc_files: []
417
431
  files:
418
432
  - ".rspec"
419
- - Gemfile
420
433
  - Guardfile
421
434
  - README.md
422
435
  - app/controllers/wcc/contentful/application_controller.rb
423
436
  - app/controllers/wcc/contentful/webhook_controller.rb
424
- - app/jobs/wcc/contentful/delayed_sync_job.rb
425
437
  - app/jobs/wcc/contentful/webhook_enable_job.rb
426
438
  - bin/console
427
439
  - bin/rails
@@ -429,35 +441,55 @@ files:
429
441
  - bin/setup
430
442
  - config/initializers/mime_types.rb
431
443
  - config/routes.rb
444
+ - doc/wcc-contentful.png
445
+ - lib/tasks/download_schema.rake
432
446
  - lib/wcc/contentful.rb
433
- - lib/wcc/contentful/client_ext.rb
447
+ - lib/wcc/contentful/active_record_shim.rb
434
448
  - lib/wcc/contentful/configuration.rb
435
449
  - lib/wcc/contentful/content_type_indexer.rb
450
+ - lib/wcc/contentful/downloads_schema.rb
436
451
  - lib/wcc/contentful/engine.rb
452
+ - lib/wcc/contentful/event.rb
453
+ - lib/wcc/contentful/events.rb
437
454
  - lib/wcc/contentful/exceptions.rb
438
- - lib/wcc/contentful/graphql.rb
439
- - lib/wcc/contentful/graphql/builder.rb
440
- - lib/wcc/contentful/graphql/types.rb
441
455
  - lib/wcc/contentful/helpers.rb
442
456
  - lib/wcc/contentful/indexed_representation.rb
457
+ - lib/wcc/contentful/instrumentation.rb
458
+ - lib/wcc/contentful/link.rb
459
+ - lib/wcc/contentful/link_visitor.rb
460
+ - lib/wcc/contentful/middleware.rb
461
+ - lib/wcc/contentful/middleware/store.rb
462
+ - lib/wcc/contentful/middleware/store/caching_middleware.rb
443
463
  - lib/wcc/contentful/model.rb
444
464
  - lib/wcc/contentful/model_builder.rb
445
465
  - lib/wcc/contentful/model_methods.rb
446
466
  - lib/wcc/contentful/model_singleton_methods.rb
447
467
  - lib/wcc/contentful/rails.rb
468
+ - lib/wcc/contentful/rake.rb
448
469
  - lib/wcc/contentful/rspec.rb
449
470
  - lib/wcc/contentful/services.rb
450
471
  - lib/wcc/contentful/simple_client.rb
451
- - lib/wcc/contentful/simple_client/http_adapter.rb
452
472
  - lib/wcc/contentful/simple_client/management.rb
453
473
  - lib/wcc/contentful/simple_client/response.rb
454
474
  - lib/wcc/contentful/simple_client/typhoeus_adapter.rb
455
475
  - lib/wcc/contentful/store.rb
476
+ - lib/wcc/contentful/store/README.md
456
477
  - lib/wcc/contentful/store/base.rb
457
478
  - lib/wcc/contentful/store/cdn_adapter.rb
458
- - lib/wcc/contentful/store/lazy_cache_store.rb
479
+ - lib/wcc/contentful/store/factory.rb
480
+ - lib/wcc/contentful/store/instrumentation.rb
481
+ - lib/wcc/contentful/store/interface.rb
459
482
  - lib/wcc/contentful/store/memory_store.rb
460
483
  - lib/wcc/contentful/store/postgres_store.rb
484
+ - lib/wcc/contentful/store/postgres_store/schema_1.sql
485
+ - lib/wcc/contentful/store/postgres_store/schema_2.sql
486
+ - lib/wcc/contentful/store/query.rb
487
+ - lib/wcc/contentful/store/query/interface.rb
488
+ - lib/wcc/contentful/store/rspec_examples.rb
489
+ - lib/wcc/contentful/store/rspec_examples/basic_store.rb
490
+ - lib/wcc/contentful/store/rspec_examples/include_param.rb
491
+ - lib/wcc/contentful/store/rspec_examples/nested_queries.rb
492
+ - lib/wcc/contentful/sync_engine.rb
461
493
  - lib/wcc/contentful/sys.rb
462
494
  - lib/wcc/contentful/test.rb
463
495
  - lib/wcc/contentful/test/attributes.rb
@@ -469,7 +501,7 @@ homepage: https://github.com/watermarkchurch/wcc-contentful/wcc-contentful
469
501
  licenses:
470
502
  - MIT
471
503
  metadata: {}
472
- post_install_message:
504
+ post_install_message:
473
505
  rdoc_options: []
474
506
  require_paths:
475
507
  - lib
@@ -484,31 +516,33 @@ required_rubygems_version: !ruby/object:Gem::Requirement
484
516
  - !ruby/object:Gem::Version
485
517
  version: 1.3.1
486
518
  requirements: []
487
- rubyforge_project:
488
- rubygems_version: 2.5.2
489
- signing_key:
519
+ rubyforge_project:
520
+ rubygems_version: 2.7.6.2
521
+ signing_key:
490
522
  specification_version: 4
491
- summary: '[![Gem Version](https://badge.fury.io/rb/wcc-contentful.svg)](https://badge.fury.io/rb/wcc-contentful)
492
- [![CircleCI](https://circleci.com/gh/watermarkchurch/wcc-contentful.svg?style=svg)](https://circleci.com/gh/watermarkchurch/wcc-contentful)
523
+ summary: '[![Gem Version](https://badge.fury.io/rb/wcc-contentful.svg)](https://rubygems.org/gems/wcc-contentful)
524
+ [![Build Status](https://travis-ci.org/watermarkchurch/wcc-contentful.svg?branch=master)](https://travis-ci.org/watermarkchurch/wcc-contentful)
493
525
  [![Coverage Status](https://coveralls.io/repos/github/watermarkchurch/wcc-contentful/badge.svg?branch=master)](https://coveralls.io/github/watermarkchurch/wcc-contentful?branch=master) Full
494
- documentation: https://www.rubydoc.info/github/watermarkchurch/wcc-contentful #
495
- WCC::Contentful ## Installation Add this line to your application''s Gemfile: ```ruby
496
- gem ''wcc-contentful'', require: ''wcc/contentful/rails'' ``` And then execute: $
497
- bundle Or install it yourself as: $ gem install wcc-contentful ## Configure ```ruby
498
- WCC::Contentful.configure do |config| config.access_token = <CONTENTFUL_ACCESS_TOKEN>
499
- config.space = <CONTENTFUL_SPACE_ID> end WCC::Contentful.init! ``` ## Usage ###
500
- WCC::Contentful::Model API The WCC::Contentful::Model API exposes Contentful data
501
- as a set of dynamically generated Ruby objects. These objects are based on the
502
- content types in your Contentful space. All these objects are generated by WCC::Contentful.init! The
503
- following examples show how to use this API to find entries of the `page` content
504
- type: ```ruby # Find objects by id WCC::Contentful::Model::Page.find(''1E2ucWSdacxxf233sfa3'')
505
- # => #<WCC::Contentful::Model::Page:0x0000000005c71a78 @created_at=2018-04-16 18:41:17
506
- UTC...> # Find objects by field WCC::Contentful::Model::Page.find_by(slug: ''/some-slug'')
507
- # => #<WCC::Contentful::Model::Page:0x0000000005c71a78 @created_at=2018-04-16 18:41:17
508
- UTC...> # Use operators to filter by a field # must use full notation for sys attributes
509
- (except ID) WCC::Contentful::Model::Page.find_all(''sys.created_at'' => { lte: Date.today
510
- }) # => [#<WCC::Contentful::Model::Page:0x0000000005c71a78 @created_at=2018-04-16
511
- 18:41:17 UTC...>, ... ] # Nest queries to mimick joins WCC::Contentful::Model::Page.find_by(subpages:
526
+ documentation: https://www.rubydoc.info/gems/wcc-contentful # WCC::Contentful ##
527
+ Installation Add this line to your application''s Gemfile: ```ruby gem ''wcc-contentful'',
528
+ require: ''wcc/contentful/rails'' ``` If you''re not using rails, exclude the `require:`
529
+ parameter. ```ruby gem ''wcc-contentful'' ``` And then execute: ``` $ bundle ```
530
+ Or install it yourself as: ``` $ gem install wcc-contentful ``` ## Configure Put
531
+ this in an initializer: ```ruby # config/initializers/wcc_contentful.rb WCC::Contentful.configure
532
+ do |config| config.access_token = <CONTENTFUL_ACCESS_TOKEN> config.space = <CONTENTFUL_SPACE_ID>
533
+ end WCC::Contentful.init! ``` All configuration options can be found [in the rubydoc](https://www.rubydoc.info/gems/wcc-contentful/WCC/Contentful/Configuration)
534
+ under {WCC::Contentful::Configuration} ## Usage ### WCC::Contentful::Model API The
535
+ WCC::Contentful::Model API exposes Contentful data as a set of dynamically generated
536
+ Ruby objects. These objects are based on the content types in your Contentful space. All
537
+ these objects are generated by `WCC::Contentful.init!` The following examples show
538
+ how to use this API to find entries of the `page` content type: ```ruby # Find
539
+ objects by id WCC::Contentful::Model::Page.find(''1E2ucWSdacxxf233sfa3'') # => #<WCC::Contentful::Model::Page:0x0000000005c71a78
540
+ @created_at=2018-04-16 18:41:17 UTC...> # Find objects by field WCC::Contentful::Model::Page.find_by(slug:
541
+ ''/some-slug'') # => #<WCC::Contentful::Model::Page:0x0000000005c71a78 @created_at=2018-04-16
542
+ 18:41:17 UTC...> # Use operators to filter by a field # must use full notation
543
+ for sys attributes (except ID) WCC::Contentful::Model::Page.find_all(''sys.created_at''
544
+ => { lte: Date.today }) # => [#<WCC::Contentful::Model::Page:0x0000000005c71a78
545
+ @created_at=2018-04-16 18:41:17 UTC...>, ... ] # Nest queries to mimick joins WCC::Contentful::Model::Page.find_by(subpages:
512
546
  { slug: ''/some-slug'' }) # => #<WCC::Contentful::Model::Page:0x0000000005c71a78
513
547
  @created_at=2018-04-16 18:41:17 UTC...> # Pass the preview flag to use the preview
514
548
  client (must have set preview_token config param) preview_redirect = WCC::Contentful::Model::Redirect.find_by({
@@ -541,51 +575,72 @@ summary: '[![Gem Version](https://badge.fury.io/rb/wcc-contentful.svg)](https://
541
575
  # {"sys"=> ...} # "6Fwukxxkxa6qQCC04WCaqg"=> # {"sys"=> ...} # ...} ``` The
542
576
  client handles Paging automatically within the lazy iterator returned by #items.
543
577
  This lazy iterator does not respect the `limit` param - that param is only passed
544
- through to the API to set the page size. Entries included via the `include` parameter
545
- are made available on the #includes field. This is a hash of `<entry ID> => <raw
546
- entry>` and makes it easy to grab links. This hash is added to lazily as you enumerate
547
- the pages. See the {WCC::Contentful::SimpleClient} documentation for more details. ###
548
- Accessing the APIs within application code The Model API is best exposed by defining
549
- your own model classes in the `app/models` directory which inherit from the WCC::Contentful
550
- models. ```ruby # app/models/page.rb class Page < WCC::Contentful::Model::Page #
551
- You can add additional methods here end # app/controllers/pages_controller.rb class
552
- PagesController < ApplicationController def show @page = Page.find_by(slug: params[:slug])
553
- raise Exceptions::PageNotFoundError, params[:slug] unless @page end end ``` The
554
- {WCC::Contentful::Services} singleton gives access to the other configured services.
555
- You can also include the {WCC::Contentful::ServiceAccessors} concern to define these
556
- services as attributes in a class. ```ruby class MyJob < ApplicationJob include
557
- WCC::Contentful::ServiceAccessors def perform Page.find(...) store.find(...) client.entries(...)
558
- end end ``` ## Test Helpers To use the test helpers, include the following in
559
- your rails_helper.rb: ```ruby require ''wcc/contentful/rspec'' ``` This adds the
560
- following helpers to all your specs: ```ruby ## # Builds a in-memory instance of
561
- the Contentful model for the given content_type. # All attributes that are known
562
- to be required fields on the content type # will return a default value based on
563
- the field type. instance = contentful_create(''my-content-type'', my_field: ''some-value'')
564
- # => #<WCC::Contentful::Model::MyContentType:0x0000000005c71a78 @created_at=2018-04-16
565
- 18:41:17 UTC...> instance.my_field # => "some-value" instance.other_required_field
578
+ through to the API to set the page size. If you truly want a limited subset of
579
+ response items, use [`response.items.take(n)`](https://ruby-doc.org/core-2.5.3/Enumerable.html#method-i-take) Entries
580
+ included via the `include` parameter are made available on the #includes field. This
581
+ is a hash of `<entry ID> => <raw entry>` and makes it easy to grab links. This
582
+ hash is added to lazily as you enumerate the pages. See the {WCC::Contentful::SimpleClient}
583
+ documentation for more details. ### Accessing the APIs within application code The
584
+ Model API is best exposed by defining your own model classes in the `app/models`
585
+ directory which inherit from the WCC::Contentful models. ```ruby # app/models/page.rb
586
+ class Page < WCC::Contentful::Model::Page # You can add additional methods here
587
+ end # app/controllers/pages_controller.rb class PagesController < ApplicationController
588
+ def show @page = Page.find_by(slug: params[:slug]) raise Exceptions::PageNotFoundError,
589
+ params[:slug] unless @page end end ``` The {WCC::Contentful::Services} singleton
590
+ gives access to the other configured services. You can also include the {WCC::Contentful::ServiceAccessors}
591
+ concern to define these services as attributes in a class. ```ruby class MyJob
592
+ < ApplicationJob include WCC::Contentful::ServiceAccessors def perform Page.find(...) store.find(...) client.entries(...)
593
+ end end ``` ## Architecture ![wcc-contentful diagram](./doc/wcc-contentful.png) ##
594
+ Test Helpers To use the test helpers, include the following in your rails_helper.rb: ```ruby
595
+ require ''wcc/contentful/rspec'' ``` This adds the following helpers to all your
596
+ specs: ```ruby ## # Builds a in-memory instance of the Contentful model for the
597
+ given content_type. # All attributes that are known to be required fields on the
598
+ content type # will return a default value based on the field type. instance = contentful_create(''my-content-type'',
599
+ my_field: ''some-value'') # => #<WCC::Contentful::Model::MyContentType:0x0000000005c71a78
600
+ @created_at=2018-04-16 18:41:17 UTC...> instance.my_field # => "some-value" instance.other_required_field
566
601
  # => "default-value" instance.other_optional_field # => nil instance.not_a_field
567
- # NoMethodError: undefined method `not_a_field'' for #<Menu:0x00007fbac81ee490> ##
602
+ # NoMethodError: undefined method `not_a_field'' for #<MyContentType:0x00007fbac81ee490> ##
568
603
  # Builds a rspec double of the Contentful model for the given content_type. # All
569
604
  attributes that are known to be required fields on the content type # will return
570
605
  a default value based on the field type. dbl = contentful_double(''my-content-type'',
571
- my_field: ''other-value'') # => #<Double (anonymous)> dbl.my_field # => "other-value" dbl.not_a_field
572
- # => #<Double (anonymous)> received unexpected message :not_a_field with (no args) ##
573
- # Builds out a fake Contentful entry for the given content type, and then # stubs
574
- the Model API to return that content type for `.find` and `.find_by` # query methods.
575
- stubbed = contentful_stub(''my-content-type'', id: ''1234'', my_field: ''test'') WCC::Contentful::Model.find(''1234'')
576
- == stubbed # => true MyContentType.find(''1234'') == stubbed # => true MyContentType.find_by(my_field:
577
- ''test'') == stubbed # => true ``` ## Development After checking out the repo,
578
- run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests.
579
- You can also run `bin/console` for an interactive prompt that will allow you to
580
- experiment. To install this gem onto your local machine, run `bundle exec rake
581
- install`. To release a new version, update the version number in `version.rb`, and
582
- then run `bundle exec rake release`, which will create a git tag for the version,
583
- push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org). ##
584
- Contributing Bug reports and pull requests are welcome on GitHub at https://github.com/watermarkchurch/wcc-contentful.
585
- This project is intended to be a safe, welcoming space for collaboration, and contributors
586
- are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org)
587
- code of conduct. ## License The gem is available as open source under the terms
588
- of the [MIT License](http://opensource.org/licenses/MIT). ## Code of Conduct Everyone
606
+ my_field: ''other-value'') # => #<Double (anonymous)> dbl.my_field # => "other-value" dbl.other_optional_field
607
+ # => nil dbl.not_a_field # => #<Double (anonymous)> received unexpected message
608
+ :not_a_field with (no args) ## # Builds out a fake Contentful entry for the given
609
+ content type, and then # stubs the Model API to return that content type for `.find`
610
+ and `.find_by` # query methods. stubbed = contentful_stub(''my-content-type'', id:
611
+ ''1234'', my_field: ''test'') WCC::Contentful::Model.find(''1234'') == stubbed
612
+ # => true MyContentType.find(''1234'') == stubbed # => true MyContentType.find_by(my_field:
613
+ ''test'') == stubbed # => true ``` ## Advanced Configuration Example Here''s an
614
+ example containing all the configuration options, and a sample setup for automatic
615
+ deployment to Heroku. This is intended to make you aware of what is possible, and
616
+ not as a general recommendation of what your setup should look like. ```ruby #
617
+ config/initializers/wcc_contentful.rb WCC::Contentful.configure do |config| config.access_token
618
+ = ENV[''CONTENTFUL_ACCESS_TOKEN''] config.space = ENV[''CONTENTFUL_SPACE_ID''] config.environment
619
+ = ENV[''CONTENTFUL_ENVIRONMENT''] config.preview_token = ENV[''CONTENTFUL_PREVIEW_ACCESS_TOKEN''] #
620
+ You may or may not want to provide this to your production server... config.management_token
621
+ = ENV[''CONTENTFUL_MANAGEMENT_TOKEN''] unless Rails.env.production? config.app_url
622
+ = "https://#{ENV[''HOSTNAME'']}" config.webhook_username = ''my-app-webhook'' config.webhook_password
623
+ = Rails.application.secrets.webhook_password config.webhook_jobs << MyOnWebhookJob config.store
624
+ = :lazy_sync, Rails.cache if Rails.env.production? # config.store = MyCustomStore.new #
625
+ Use a custom Faraday connection config.connection = Faraday.new do |builder| f.request
626
+ :retry f.request MyFaradayRequestAdapter.new ... end # OR implement some adapter
627
+ like this to use another HTTP client config.connection = MyNetHttpAdapter.new config.update_schema_file
628
+ = :never end WCC::Contentful.init! ``` For Heroku: ```yaml # Procfile web: bundle
629
+ exec rails s worker: bundle exec sidekiq release: bin/release ``` ```sh # bin/release
630
+ #!/bin/sh set -e echo "Migrating database..." bin/rake db:migrate echo "Migrating
631
+ contentful..." migrations_to_be_run=$( ... ) # somehow figure this out node_modules/.bin/contentful-migration
632
+ \ -s $CONTENTFUL_SPACE_ID -a $CONTENTFUL_MANAGEMENT_TOKEN \ -y -p "$migrations_to_be_run" echo
633
+ "Updating schema file..." rake wcc_contentful:download_schema ``` All configuration
634
+ options can be found [in the rubydoc](https://www.rubydoc.info/gems/wcc-contentful/WCC/Contentful/Configuration)
635
+ under {WCC::Contentful::Configuration} ## Development After checking out the
636
+ repo, run `bin/setup` to install dependencies. Then, run `bundle exec rspec` to
637
+ run the tests. You can also run `bin/console` for an interactive prompt that will
638
+ allow you to experiment. ## Contributing Bug reports and pull requests are welcome
639
+ on GitHub at https://github.com/watermarkchurch/wcc-contentful. This project is
640
+ intended to be a safe, welcoming space for collaboration, and contributors are expected
641
+ to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of
642
+ conduct. ## License The gem is available as open source under the terms of the
643
+ [MIT License](http://opensource.org/licenses/MIT). ## Code of Conduct Everyone
589
644
  interacting in the WCC::Contentful project''s codebases, issue trackers, chat rooms
590
645
  and mailing lists is expected to follow the [code of conduct](https://github.com/watermarkchurch/wcc-contentful/blob/master/CODE_OF_CONDUCT.md).'
591
646
  test_files: []