wcc-contentful 1.0.6 → 1.1.1

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 (32) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +174 -9
  3. data/app/jobs/wcc/contentful/webhook_enable_job.rb +7 -7
  4. data/lib/wcc/contentful/instrumentation.rb +20 -2
  5. data/lib/wcc/contentful/link_visitor.rb +26 -30
  6. data/lib/wcc/contentful/middleware/store.rb +2 -1
  7. data/lib/wcc/contentful/model.rb +5 -122
  8. data/lib/wcc/contentful/model_api.rb +182 -0
  9. data/lib/wcc/contentful/model_builder.rb +10 -4
  10. data/lib/wcc/contentful/model_methods.rb +8 -10
  11. data/lib/wcc/contentful/model_singleton_methods.rb +6 -6
  12. data/lib/wcc/contentful/rspec.rb +7 -5
  13. data/lib/wcc/contentful/services.rb +59 -61
  14. data/lib/wcc/contentful/store/cdn_adapter.rb +7 -1
  15. data/lib/wcc/contentful/store/factory.rb +2 -6
  16. data/lib/wcc/contentful/store/memory_store.rb +47 -13
  17. data/lib/wcc/contentful/store/query.rb +22 -2
  18. data/lib/wcc/contentful/store/rspec_examples/basic_store.rb +0 -103
  19. data/lib/wcc/contentful/store/rspec_examples/operators/eq.rb +92 -0
  20. data/lib/wcc/contentful/store/rspec_examples/operators/in.rb +131 -0
  21. data/lib/wcc/contentful/store/rspec_examples/operators/ne.rb +77 -0
  22. data/lib/wcc/contentful/store/rspec_examples/operators/nin.rb +80 -0
  23. data/lib/wcc/contentful/store/rspec_examples/operators.rb +50 -0
  24. data/lib/wcc/contentful/store/rspec_examples.rb +2 -0
  25. data/lib/wcc/contentful/sync_engine.rb +0 -1
  26. data/lib/wcc/contentful/test/attributes.rb +0 -4
  27. data/lib/wcc/contentful/test/double.rb +4 -2
  28. data/lib/wcc/contentful/test/factory.rb +4 -2
  29. data/lib/wcc/contentful/version.rb +1 -1
  30. data/lib/wcc/contentful.rb +14 -8
  31. data/wcc-contentful.gemspec +0 -5
  32. metadata +117 -37
@@ -34,7 +34,10 @@ module WCC::Contentful
34
34
  # Gets the current configuration, after calling WCC::Contentful.configure
35
35
  attr_reader :configuration
36
36
 
37
- attr_reader :types
37
+ def types
38
+ ActiveSupport::Deprecation.warn('Use WCC::Contentful::Model.schema instead')
39
+ WCC::Contentful::Model.schema
40
+ end
38
41
 
39
42
  # Gets all queryable locales.
40
43
  # Reserved for future use.
@@ -91,7 +94,7 @@ module WCC::Contentful
91
94
  end
92
95
  end
93
96
 
94
- @content_types =
97
+ content_types =
95
98
  begin
96
99
  if File.exist?(configuration.schema_file)
97
100
  JSON.parse(File.read(configuration.schema_file))['contentTypes']
@@ -101,32 +104,35 @@ module WCC::Contentful
101
104
  nil
102
105
  end
103
106
 
104
- if !@content_types && %i[if_possible never].include?(configuration.update_schema_file)
107
+ if !content_types && %i[if_possible never].include?(configuration.update_schema_file)
105
108
  # Final fallback - try to grab content types from CDN. We can't update the file
106
109
  # because the CDN doesn't have all the field validation info, but we can at least
107
110
  # build the WCC::Contentful::Model instances.
108
111
  client = Services.instance.management_client ||
109
112
  Services.instance.client
110
113
  begin
111
- @content_types = client.content_types(limit: 1000).items if client
114
+ content_types = client.content_types(limit: 1000).items if client
112
115
  rescue WCC::Contentful::SimpleClient::ApiError => e
113
116
  # indicates bad credentials
114
117
  WCC::Contentful.logger.warn("Unable to load content types from API - #{e.message}")
115
118
  end
116
119
  end
117
120
 
118
- unless @content_types
121
+ unless content_types
119
122
  raise InitializationError, 'Unable to load content types from schema file or API!' \
120
123
  ' Check your access token and space ID.'
121
124
  end
122
125
 
123
- indexer = ContentTypeIndexer.from_json_schema(@content_types)
124
- @types = indexer.types
126
+ # Set the schema on the default WCC::Contentful::Model
127
+ WCC::Contentful::Model.configure(
128
+ configuration,
129
+ schema: WCC::Contentful::ContentTypeIndexer.from_json_schema(content_types).types,
130
+ services: WCC::Contentful::Services.instance
131
+ )
125
132
 
126
133
  # Drop an initial sync
127
134
  WCC::Contentful::SyncEngine::Job.perform_later if defined?(WCC::Contentful::SyncEngine::Job)
128
135
 
129
- WCC::Contentful::ModelBuilder.new(@types).build_models
130
136
  @configuration = @configuration.freeze
131
137
  @initialized = true
132
138
  end
@@ -24,11 +24,6 @@ Gem::Specification.new do |spec|
24
24
 
25
25
  spec.required_ruby_version = '>= 2.3'
26
26
 
27
- spec.files =
28
- `git ls-files -z`.split("\x0").reject do |f|
29
- f.match(%r{^(test|spec|features)/})
30
- end
31
-
32
27
  spec.files = Dir['app/**/*', 'config/**/*', 'lib/**/*'] +
33
28
  %w[Rakefile README.md wcc-contentful.gemspec]
34
29
 
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.0.6
4
+ version: 1.1.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: 2021-12-21 00:00:00.000000000 Z
11
+ date: 2022-02-16 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: byebug
@@ -455,6 +455,7 @@ files:
455
455
  - lib/wcc/contentful/middleware/store.rb
456
456
  - lib/wcc/contentful/middleware/store/caching_middleware.rb
457
457
  - lib/wcc/contentful/model.rb
458
+ - lib/wcc/contentful/model_api.rb
458
459
  - lib/wcc/contentful/model_builder.rb
459
460
  - lib/wcc/contentful/model_methods.rb
460
461
  - lib/wcc/contentful/model_singleton_methods.rb
@@ -483,6 +484,11 @@ files:
483
484
  - lib/wcc/contentful/store/rspec_examples/basic_store.rb
484
485
  - lib/wcc/contentful/store/rspec_examples/include_param.rb
485
486
  - lib/wcc/contentful/store/rspec_examples/nested_queries.rb
487
+ - lib/wcc/contentful/store/rspec_examples/operators.rb
488
+ - lib/wcc/contentful/store/rspec_examples/operators/eq.rb
489
+ - lib/wcc/contentful/store/rspec_examples/operators/in.rb
490
+ - lib/wcc/contentful/store/rspec_examples/operators/ne.rb
491
+ - lib/wcc/contentful/store/rspec_examples/operators/nin.rb
486
492
  - lib/wcc/contentful/sync_engine.rb
487
493
  - lib/wcc/contentful/sys.rb
488
494
  - lib/wcc/contentful/test.rb
@@ -495,8 +501,8 @@ homepage: https://github.com/watermarkchurch/wcc-contentful/wcc-contentful
495
501
  licenses:
496
502
  - MIT
497
503
  metadata:
498
- documentation_uri: https://watermarkchurch.github.io/wcc-contentful/1.0/wcc-contentful
499
- post_install_message:
504
+ documentation_uri: https://watermarkchurch.github.io/wcc-contentful/1.1/wcc-contentful
505
+ post_install_message:
500
506
  rdoc_options: []
501
507
  require_paths:
502
508
  - lib
@@ -511,9 +517,9 @@ required_rubygems_version: !ruby/object:Gem::Requirement
511
517
  - !ruby/object:Gem::Version
512
518
  version: '0'
513
519
  requirements: []
514
- rubyforge_project:
520
+ rubyforge_project:
515
521
  rubygems_version: 2.7.6.2
516
- signing_key:
522
+ signing_key:
517
523
  specification_version: 4
518
524
  summary: '[![Gem Version](https://badge.fury.io/rb/wcc-contentful.svg)](https://rubygems.org/gems/wcc-contentful)
519
525
  [![Build Status](https://circleci.com/gh/watermarkchurch/wcc-contentful.svg?style=svg)](https://circleci.com/gh/watermarkchurch/wcc-contentful)
@@ -525,17 +531,18 @@ summary: '[![Gem Version](https://badge.fury.io/rb/wcc-contentful.svg)](https://
525
531
  2. [Installation](#installation) 3. [Configuration](#configure) 4. [Usage](#usage)
526
532
  1. [Model API](#wcccontentfulmodel-api) 2. [Store API](#store-api) 3. [Direct CDN
527
533
  client](#direct-cdn-api-simpleclient) 4. [Accessing the APIs](#accessing-the-apis-within-application-code)
528
- 5. [Architecture](#architecture) 6. [Test Helpers](#test-helpers) 7. [Advanced Configuration
529
- Example](#advanced-configuration-example) 8. [Development](#development) 9. [Contributing](#contributing)
530
- 10. [License](#license) ## Why did you rewrite the Contentful ruby stack? We
531
- started working with Contentful almost 3 years ago. Since that time, Contentful''s
532
- ruby stack has improved, but there are still a number of pain points that we feel
533
- we have addressed better with our gem. These are: * [Low-level caching](#low-level-caching)
534
- * [Better integration with Rails & Rails models](#better-rails-integration) * [Automatic
535
- pagination and Automatic link resolution](#automatic-pagination-and-link-resolution)
536
- * [Automatic webhook management](#automatic-webhook-management) Our gem no longer
537
- depends on any of the Contentful gems and interacts directly with the [Contentful
538
- CDA](https://www.contentful.com/developers/docs/references/content-delivery-api/)
534
+ 5. [Architecture](#architecture) 1. [Client Layer](#client-layer) 2. [Store Layer](#store-layer)
535
+ 3. [Model Layer](#model-layer) 6. [Test Helpers](#test-helpers) 7. [Advanced Configuration
536
+ Example](#advanced-configuration-example) 8. [Connecting to Multiple Spaces](#connecting-to-multiple-spaces-or-environments)
537
+ 9. [Development](#development) 10. [Contributing](#contributing) 11. [License](#license) ##
538
+ Why did you rewrite the Contentful ruby stack? We started working with Contentful
539
+ almost 3 years ago. Since that time, Contentful''s ruby stack has improved, but
540
+ there are still a number of pain points that we feel we have addressed better with
541
+ our gem. These are: * [Low-level caching](#low-level-caching) * [Better integration
542
+ with Rails & Rails models](#better-rails-integration) * [Automatic pagination and
543
+ Automatic link resolution](#automatic-pagination-and-link-resolution) * [Automatic
544
+ webhook management](#automatic-webhook-management) Our gem no longer depends on
545
+ any of the Contentful gems and interacts directly with the [Contentful CDA](https://www.contentful.com/developers/docs/references/content-delivery-api/)
539
546
  and [Content Management API](https://www.contentful.com/developers/docs/references/content-management-api/)
540
547
  over HTTPS. ### Low-level caching The wcc-contentful gem enables caching at two
541
548
  levels: the HTTP response using [Faraday HTTP cache middleware](https://github.com/sourcelevel/faraday-http-cache),
@@ -552,7 +559,7 @@ summary: '[![Gem Version](https://badge.fury.io/rb/wcc-contentful.svg)](https://
552
559
  for one implementation). Using Faraday makes it easy to add Middleware. As an
553
560
  example, our flagship Rails app that powers watermark.org uses the following configuration
554
561
  in Production, which provides us with instrumentation through statsd, logging, and
555
- caching: ```rb config.connection = Faraday.new do |builder| builder.use :http_cache,
562
+ caching: ```ruby config.connection = Faraday.new do |builder| builder.use :http_cache,
556
563
  shared_cache: false, store: ActiveSupport::Cache::MemoryStore.new(size: 512.megabytes),
557
564
  logger: Rails.logger, serializer: Marshal, instrumenter: ActiveSupport::Notifications builder.use
558
565
  :gzip builder.response :logger, Rails.logger, headers: false, bodies: false if Rails.env.development?
@@ -584,7 +591,7 @@ summary: '[![Gem Version](https://badge.fury.io/rb/wcc-contentful.svg)](https://
584
591
  content model registry allows easy definition of custom models in your `app/models`
585
592
  directory to override fields. This plays nice with other gems like algoliasearch-rails,
586
593
  which allows you to declaratively manage your Algolia indexes. Another example
587
- from our flagship watermark.org: ```rb class Page < WCC::Contentful::Model::Page
594
+ from our flagship watermark.org: ```ruby class Page < WCC::Contentful::Model::Page
588
595
  include AlgoliaSearch algoliasearch(index_name: ''pages'') do attribute(:title,
589
596
  :slug) ... end ``` ### Automatic Pagination and Link Resolution Using the `contentful_model`
590
597
  gem, calling `Page.all.load` does not give you all Page entries if there are more
@@ -678,12 +685,55 @@ summary: '[![Gem Version](https://badge.fury.io/rb/wcc-contentful.svg)](https://
678
685
  gives access to the other configured services. You can also include the {WCC::Contentful::ServiceAccessors}
679
686
  concern to define these services as attributes in a class. ```ruby class MyJob
680
687
  < ApplicationJob include WCC::Contentful::ServiceAccessors def perform Page.find(...) store.find(...) client.entries(...)
681
- end end ``` ## Architecture ![wcc-contentful diagram](./doc-static/wcc-contentful.png) ##
682
- Test Helpers To use the test helpers, include the following in your rails_helper.rb: ```ruby
683
- require ''wcc/contentful/rspec'' ``` This adds the following helpers to all your
684
- specs: ```ruby ## # Builds a in-memory instance of the Contentful model for the
685
- given content_type. # All attributes that are known to be required fields on the
686
- content type # will return a default value based on the field type. instance = contentful_create(''my-content-type'',
688
+ end end ``` ## Architecture ![wcc-contentful diagram](./doc-static/wcc-contentful.png) From
689
+ the bottom up: ### Client Layer The {WCC::Contentful::SimpleClient} provides methods
690
+ to access the [Contentful Content Delivery API](https://www.contentful.com/developers/docs/references/content-delivery-api/)
691
+ through your favorite HTTP client gem. The SimpleClient expects an Adapter that
692
+ conforms to the Faraday interface. Creating a SimpleClient to connect using different
693
+ credentials, or to connect without setting up all the rest of WCC::Contentful, is
694
+ easy: ```ruby WCC::Contentful::SimpleClient::Cdn.new( # required access_token:
695
+ ''xxxx'', space: ''1234'', # optional environment: ''staging'', # omit to use master
696
+ default_locale: ''*'', rate_limit_wait_timeout: 10, instrumentation: ActiveSupport::Notifications,
697
+ connection: Faraday.new { |builder| ... }, ) ``` You can also create a {WCC::Contentful::SimpleClient::Preview}
698
+ to talk to the Preview API, or a {WCC::Contentful::SimpleClient::Management} to
699
+ talk to the Management API. ### Store Layer The Store Layer represents the data
700
+ store where Contentful entries are kept for querying. By default, `WCC::Contentful.init!`
701
+ creates a {WCC::Contentful::Store::CDNAdapter} which uses a {WCC::Contentful::SimpleClient::Cdn}
702
+ instance to query entries from the [Contentful Content Delivery API](https://www.contentful.com/developers/docs/references/content-delivery-api/). You
703
+ can also query entries from another source like Postgres or an in-memory hash if
704
+ your data is small enough. You can also implement your own store if you want! The
705
+ gem contains a suite of RSpec shared examples that give you a baseline for implementing
706
+ your own store. In your RSpec suite: ```ruby # frozen_string_literal: true require
707
+ ''my_store'' require ''wcc/contentful/store/rspec_examples'' RSpec.describe MyStore
708
+ do it_behaves_like ''contentful store'', { # Set which store features your store
709
+ implements. nested_queries: true, # Does your store implement JOINs? include_param:
710
+ true # Does your store resolve links when given the :include option? } ``` The
711
+ store is kept up-to-date by the {WCC::Contentful::SyncEngine}. The `SyncEngine#next`
712
+ methodcalls the `#index` method on the configured store in order to update it with
713
+ the latest data via the [Contentful Sync API](https://www.contentful.com/developers/docs/references/content-delivery-api/#/reference/synchronization). For
714
+ example, the {WCC::Contentful::Store::MemoryStore} uses this to update the hash
715
+ with the newest version of an entry, or delete an entry out of the hash. #### Store
716
+ Middleware The store layer is made up of a base store (which implements {WCC::Contentful::Store::Interface}),
717
+ and optional middleware. The middleware allows custom transformation of received
718
+ entries via the `#select` and `#transform` methods. To create your own middleware
719
+ simply include {WCC::Contentful::Middleware::Store} and implement those methods,
720
+ then call `use` when configuring the store: ```ruby config.store :direct do use
721
+ MyMiddleware, param1: ''xxx'' end ``` The most useful middleware is the {WCC::Contentful::Middleware::Store::CachingMiddleware},
722
+ which enables `:lazy_sync` mode (see {WCC::Contentful::Configuration#store}) ###
723
+ Model Layer This is the global top layer where your Rails app looks up content
724
+ similarly to ActiveModel. The models are namespaced under the root class {WCC::Contentful::Model}.
725
+ Each model''s implementation of `.find`, `.find_by`, and `.find_all` simply call
726
+ into the configured Store. The main benefit of the Model layer is lazy link resolution. When
727
+ a model''s property is accessed, if that property is a link that has not been resolved
728
+ yet (for example using the `include: n` parameter on `.find_by`), the model will
729
+ automatically call `#find` on the store to resolve that linked entry. Note that
730
+ this can easily result in lots of CDN calls to Contentful! To optimize this you
731
+ should use the `include` parameter and/or use a different store. ## Test Helpers To
732
+ use the test helpers, include the following in your rails_helper.rb: ```ruby require
733
+ ''wcc/contentful/rspec'' ``` This adds the following helpers to all your specs: ```ruby
734
+ ## # Builds a in-memory instance of the Contentful model for the given content_type.
735
+ # All attributes that are known to be required fields on the content type # will
736
+ return a default value based on the field type. instance = contentful_create(''my-content-type'',
687
737
  my_field: ''some-value'') # => #<WCC::Contentful::Model::MyContentType:0x0000000005c71a78
688
738
  @created_at=2018-04-16 18:41:17 UTC...> instance.my_field # => "some-value" instance.other_required_field
689
739
  # => "default-value" instance.other_optional_field # => nil instance.not_a_field
@@ -720,16 +770,46 @@ summary: '[![Gem Version](https://badge.fury.io/rb/wcc-contentful.svg)](https://
720
770
  \ -s $CONTENTFUL_SPACE_ID -a $CONTENTFUL_MANAGEMENT_TOKEN \ -y -p "$migrations_to_be_run" echo
721
771
  "Updating schema file..." rake wcc_contentful:download_schema ``` All configuration
722
772
  options can be found [in the rubydoc](https://www.rubydoc.info/gems/wcc-contentful/WCC/Contentful/Configuration)
723
- under {WCC::Contentful::Configuration} ## Development After checking out the
724
- repo, run `bin/setup` to install dependencies. Then, run `bundle exec rspec` to
725
- run the tests. You can also run `bin/console` for an interactive prompt that will
726
- allow you to experiment. ## Contributing Bug reports and pull requests are welcome
727
- on GitHub at https://github.com/watermarkchurch/wcc-contentful. The developers
728
- at Watermark Community Church have pledged to govern their interactions with each
729
- other, with their clients, and with the larger wcc-contentful user community in
730
- accordance with the "instruments of good works" from chapter 4 of The Rule of St.
731
- Benedict (hereafter: "The Rule"). This code of ethics has proven its mettle in thousands
732
- of diverse communities for over 1,500 years, and has served as a baseline for many
733
- civil law codes since the time of Charlemagne. [See the full Code of Ethics](https://github.com/watermarkchurch/wcc-contentful/blob/master/CODE_OF_ETHICS.md) ##
773
+ under {WCC::Contentful::Configuration} ## Connecting to multiple spaces or environments When
774
+ initializing the WCC::Contentful gem using `WCC::Contentful.init!`, the gem will
775
+ by default connect to the single Contentful space that you specify in the `WCC::Contentful.configure`
776
+ step. However the gem is also capable of connecting to multiple spaces within the
777
+ same ruby process! You just have to create and initialize a namespace. The {WCC::Contentful::ModelAPI}
778
+ concern makes this straightforward. Start by creating your Namespace and including
779
+ the concern: ```ruby # app/models/my_second_space.rb class MySecondSpace include
780
+ WCC::Contentful::ModelAPI end # app/models/other_page.rb class OtherPage < MySecondSpace::Page
781
+ end ``` Then configure it in an initializer: ```ruby # config/initializers/my_second_space.rb
782
+ MySecondSpace.configure do |config| # Make sure to point to a different schema file
783
+ from your first space! config.schema_file = Rails.root.join(''db/second-contentful-schema.json'') config.access_token
784
+ = ENV[''SECOND_CONTENTFUL_ACCESS_TOKEN''] config.preview_token = ENV[''SECOND_CONTENTFUL_PREVIEW_ACCESS_TOKEN'']
785
+ config.space = ENV[''SECOND_CONTENTFUL_SPACE_ID''] config.environment = ENV[''CONTENTFUL_ENVIRONMENT'']
786
+ end ``` Finally, use it: ```ruby OtherPage.find(''1234'') # GET https://cdn.contentful.com/spaces/other-space/environments/other-env/entries/1234
787
+ # => #<OtherPage:0x0000000005c71a78 @created_at=2018-04-16 18:41:17 UTC...> Page.find(''1234'')
788
+ # GET https://cdn.contentful.com/spaces/first-space/environments/first-env/entries/1234
789
+ # => #<Page:0x0000000001271b70 @created_at=2018-04-15 12:02:14 UTC...> ``` The
790
+ ModelAPI defines a second stack of services that you can access for lower level
791
+ connections: ```ruby store = MySecondSpace.services.store # => #<WCC::Contentful::Store::CDNAdapter:0x00007f888edac118
792
+ client = MySecondSpace.services.client # => #<WCC::Contentful::SimpleClient::Cdn:0x00007f88942a8888
793
+ preview_client = MySecondSpace.services.preview_client # => #<WCC::Contentful::SimpleClient::Preview:0x00007f888ccafa00
794
+ sync_engine = MySecondSpace.services.sync_engine # => #<WCC::Contentful::SyncEngine:0x00007f88960b6b40
795
+ ``` Note that the above services are not accessible on {WCC::Contentful::Services.instance}
796
+ or via the {WCC::Contentful::ServiceAccessors}. ### Using a sync store with a second
797
+ space If you use something other than the CDNAdapter with your second space, you
798
+ will need to find a way to trigger `MySecondSpace.services.sync_engine.next` to
799
+ keep it up-to-date. The {WCC::Contentful::Engine} will only manage the global SyncEngine
800
+ configured by the global {WCC::Contentful.configure}. The easiest way to do this
801
+ is to set up your own Rails route to respond to Contentful webhooks and then configure
802
+ the second Contentful space to send webhooks to this route. You could also do this
803
+ by triggering it periodically in a background job using Sidekiq and [sidekiq-scheduler](https://github.com/Moove-it/sidekiq-scheduler). ##
804
+ Development After checking out the repo, run `bin/setup` to install dependencies.
805
+ Then, run `bundle exec rspec` to run the tests. You can also run `bin/console` for
806
+ an interactive prompt that will allow you to experiment. ## Contributing Bug reports
807
+ and pull requests are welcome on GitHub at https://github.com/watermarkchurch/wcc-contentful. The
808
+ developers at Watermark Community Church have pledged to govern their interactions
809
+ with each other, with their clients, and with the larger wcc-contentful user community
810
+ in accordance with the "instruments of good works" from chapter 4 of The Rule of
811
+ St. Benedict (hereafter: "The Rule"). This code of ethics has proven its mettle
812
+ in thousands of diverse communities for over 1,500 years, and has served as a baseline
813
+ for many civil law codes since the time of Charlemagne. [See the full Code of Ethics](https://github.com/watermarkchurch/wcc-contentful/blob/master/CODE_OF_ETHICS.md) ##
734
814
  License The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).'
735
815
  test_files: []