contentful-management 0.9.0 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (93) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +1 -1
  3. data/.rubocop_todo.yml +2 -2
  4. data/CHANGELOG.md +27 -3
  5. data/README.md +34 -7
  6. data/lib/contentful/management/api_key.rb +4 -43
  7. data/lib/contentful/management/array.rb +1 -2
  8. data/lib/contentful/management/asset.rb +29 -191
  9. data/lib/contentful/management/client.rb +96 -7
  10. data/lib/contentful/management/client_api_key_methods_factory.rb +15 -0
  11. data/lib/contentful/management/client_asset_methods_factory.rb +13 -0
  12. data/lib/contentful/management/client_association_all_published_method_factory.rb +21 -0
  13. data/lib/contentful/management/client_association_methods_factory.rb +54 -0
  14. data/lib/contentful/management/client_content_type_methods_factory.rb +13 -0
  15. data/lib/contentful/management/client_entry_methods_factory.rb +21 -0
  16. data/lib/contentful/management/client_locale_methods_factory.rb +15 -0
  17. data/lib/contentful/management/client_space_methods_factory.rb +58 -0
  18. data/lib/contentful/management/client_webhook_methods_factory.rb +15 -0
  19. data/lib/contentful/management/content_type.rb +30 -151
  20. data/lib/contentful/management/content_type_entry_methods_factory.rb +9 -3
  21. data/lib/contentful/management/dynamic_entry.rb +20 -39
  22. data/lib/contentful/management/entry.rb +47 -182
  23. data/lib/contentful/management/http_client.rb +41 -8
  24. data/lib/contentful/management/locale.rb +7 -76
  25. data/lib/contentful/management/request.rb +3 -3
  26. data/lib/contentful/management/resource.rb +105 -7
  27. data/lib/contentful/management/resource/all_published.rb +24 -0
  28. data/lib/contentful/management/resource/archiver.rb +37 -0
  29. data/lib/contentful/management/resource/field_aware.rb +49 -29
  30. data/lib/contentful/management/resource/publisher.rb +37 -0
  31. data/lib/contentful/management/resource/refresher.rb +1 -1
  32. data/lib/contentful/management/resource_builder.rb +8 -4
  33. data/lib/contentful/management/resource_requester.rb +96 -0
  34. data/lib/contentful/management/space.rb +40 -43
  35. data/lib/contentful/management/space_association_all_published_method_factory.rb +1 -1
  36. data/lib/contentful/management/space_association_methods_factory.rb +6 -3
  37. data/lib/contentful/management/space_entry_methods_factory.rb +1 -1
  38. data/lib/contentful/management/version.rb +1 -1
  39. data/lib/contentful/management/webhook.rb +9 -82
  40. data/spec/fixtures/vcr_cassettes/asset/create.yml +1 -1
  41. data/spec/fixtures/vcr_cassettes/asset/create_with_locale.yml +1 -1
  42. data/spec/fixtures/vcr_cassettes/asset/process.yml +1 -1
  43. data/spec/fixtures/vcr_cassettes/asset/publish_after_create.yml +1 -1
  44. data/spec/fixtures/vcr_cassettes/content_type/create.yml +1 -1
  45. data/spec/fixtures/vcr_cassettes/content_type/create_with_Array_field.yml +1 -1
  46. data/spec/fixtures/vcr_cassettes/content_type/create_with_Boolean_field.yml +1 -1
  47. data/spec/fixtures/vcr_cassettes/content_type/create_with_Date_field.yml +1 -1
  48. data/spec/fixtures/vcr_cassettes/content_type/create_with_Integer_field.yml +1 -1
  49. data/spec/fixtures/vcr_cassettes/content_type/create_with_Link_field.yml +1 -1
  50. data/spec/fixtures/vcr_cassettes/content_type/create_with_Location_field.yml +1 -1
  51. data/spec/fixtures/vcr_cassettes/content_type/create_with_Number_field.yml +1 -1
  52. data/spec/fixtures/vcr_cassettes/content_type/create_with_Object_field.yml +1 -1
  53. data/spec/fixtures/vcr_cassettes/content_type/create_with_Symbol_field.yml +1 -1
  54. data/spec/fixtures/vcr_cassettes/content_type/create_with_Text_field.yml +1 -1
  55. data/spec/fixtures/vcr_cassettes/content_type/entry/create.yml +1 -1
  56. data/spec/fixtures/vcr_cassettes/content_type/entry/create_only_with_localized_fields.yml +1 -1
  57. data/spec/fixtures/vcr_cassettes/content_type/entry/create_to_single_locale_only_with_localized_fields.yml +1 -1
  58. data/spec/fixtures/vcr_cassettes/content_type/entry/create_with_camel_case_id_to_multiple_locales.yml +1 -1
  59. data/spec/fixtures/vcr_cassettes/content_type/entry/create_with_entries.yml +1 -1
  60. data/spec/fixtures/vcr_cassettes/content_type/entry/create_with_entries_for_multiple_locales.yml +1 -1
  61. data/spec/fixtures/vcr_cassettes/content_type/entry/create_with_multiple_locales.yml +1 -1
  62. data/spec/fixtures/vcr_cassettes/content_type/fields/create_array_types.yml +1 -1
  63. data/spec/fixtures/vcr_cassettes/content_type/save_new.yml +1 -1
  64. data/spec/fixtures/vcr_cassettes/delete_request.yml +38 -0
  65. data/spec/fixtures/vcr_cassettes/entry/create.yml +1 -1
  66. data/spec/fixtures/vcr_cassettes/entry/create_with_asset.yml +1 -1
  67. data/spec/fixtures/vcr_cassettes/entry/create_with_assets.yml +1 -1
  68. data/spec/fixtures/vcr_cassettes/entry/create_with_entries.yml +1 -1
  69. data/spec/fixtures/vcr_cassettes/entry/create_with_entry.yml +1 -1
  70. data/spec/fixtures/vcr_cassettes/entry/create_with_just_id.yml +1 -1
  71. data/spec/fixtures/vcr_cassettes/entry/create_with_location.yml +1 -1
  72. data/spec/fixtures/vcr_cassettes/entry/create_with_specified_locale.yml +1 -1
  73. data/spec/fixtures/vcr_cassettes/entry/create_with_symbols.yml +1 -1
  74. data/spec/fixtures/vcr_cassettes/entry/too_many_requests.yml +1 -1
  75. data/spec/fixtures/vcr_cassettes/entry/update_bool_field.yml +1 -1
  76. data/spec/fixtures/vcr_cassettes/post_request.yml +64 -0
  77. data/spec/fixtures/vcr_cassettes/proxy_request.yml +562 -0
  78. data/spec/fixtures/vcr_cassettes/put_request.yml +40 -0
  79. data/spec/fixtures/vcr_cassettes/space/asset/create.yml +1 -1
  80. data/spec/fixtures/vcr_cassettes/space/asset/create_with_multiple_locales.yml +1 -1
  81. data/spec/fixtures/vcr_cassettes/space/content_type/create.yml +1 -1
  82. data/spec/fixtures/vcr_cassettes/space/create_with_client_default_locale.yml +197 -36
  83. data/spec/fixtures/vcr_cassettes/space/webhook/create.yml +1 -1
  84. data/spec/lib/contentful/management/api_key_spec.rb +7 -1
  85. data/spec/lib/contentful/management/array_spec.rb +1 -1
  86. data/spec/lib/contentful/management/asset_spec.rb +52 -32
  87. data/spec/lib/contentful/management/client_spec.rb +38 -0
  88. data/spec/lib/contentful/management/content_type_spec.rb +37 -22
  89. data/spec/lib/contentful/management/entry_spec.rb +68 -57
  90. data/spec/lib/contentful/management/locale_spec.rb +7 -1
  91. data/spec/lib/contentful/management/space_spec.rb +9 -3
  92. data/spec/lib/contentful/management/webhook_spec.rb +11 -5
  93. metadata +23 -2
@@ -15,87 +15,18 @@ module Contentful
15
15
  property :publish, :boolean
16
16
  property :default, :boolean
17
17
 
18
- # Gets a collection of locales.
19
- #
20
- # @param [String] space_id
21
- # @param [Hash] _parameters Search Parameters
22
- # @option _parameters [String] :name
23
- # @option _parameters [String] :code
24
- #
25
- # @return [Contentful::Management::Array<Contentful::Management::Locale>]
26
- def self.all(space_id = nil, _parameters = {})
27
- request = Request.new("/#{space_id}/locales")
28
- response = request.get
29
- result = ResourceBuilder.new(response, { 'Locale' => Locale }, {})
30
- result.run
31
- end
32
-
33
- # Gets a specific locale.
34
- #
35
- # @param [String] space_id
36
- # @param [String] locale_id
37
- #
38
- # @return [Contentful::Management::Locale]
39
- def self.find(space_id, locale_id)
40
- request = Request.new("/#{space_id}/locales/#{locale_id}")
41
- response = request.get
42
- result = ResourceBuilder.new(response, { 'Locale' => Locale }, {})
43
- result.run
44
- end
45
-
46
- # Creates a locale.
47
- #
48
- # @param [String] space_id
49
- # @param [Hash] attributes
50
- # @option attributes [String] :name
51
- # @option attributes [String] :code
52
- #
53
- # @return [Contentful::Management::Locale]
54
- def self.create(space_id, attributes)
55
- request = Request.new(
56
- "/#{space_id}/locales",
18
+ # @private
19
+ def self.create_attributes(_client, attributes)
20
+ {
57
21
  'name' => attributes.fetch(:name),
58
22
  'code' => attributes.fetch(:code)
59
- )
60
- response = request.post
61
- result = ResourceBuilder.new(response, { 'Locale' => Locale }, {})
62
- result.run
23
+ }
63
24
  end
64
25
 
65
- # Updates a locale.
66
- #
67
- # @param [Hash] attributes
68
- # @option attributes [String] :name
69
- # @option attributes [String] :code
70
- #
71
- # @return [Contentful::Management::Locale]
72
- def update(attributes)
73
- parameters = {}
74
- attributes.each { |k, v| parameters[k.to_s] = v }
75
-
76
- request = Request.new(
77
- "/#{space.id}/locales/#{id}",
78
- parameters,
79
- nil,
80
- version: sys[:version]
81
- )
82
- response = request.put
83
- result = ResourceBuilder.new(response, { 'Locale' => Locale }, {})
84
- refresh_data(result.run)
85
- end
26
+ protected
86
27
 
87
- # Deletes a locale.
88
- #
89
- # @return [true, Contentful::Management::Error] success
90
- def destroy
91
- request = Request.new("/#{space.id}/locales/#{id}")
92
- response = request.delete
93
- if response.status == :no_content
94
- return true
95
- else
96
- result = ResourceBuilder.new(response, {}, {})
97
- result.run
98
- end
28
+ def query_attributes(attributes)
29
+ attributes.each_with_object({}) { |(k, v), result| result[k.to_sym] = v }
99
30
  end
100
31
  end
101
32
  end
@@ -6,10 +6,10 @@ module Contentful
6
6
  class Request
7
7
  attr_reader :client, :type, :query, :id, :endpoint
8
8
 
9
- def initialize(endpoint, query = {}, id = nil, header = {})
9
+ def initialize(client, endpoint, query = {}, id = nil, header = {})
10
10
  @header = header
11
11
  @initial_id = id
12
- @client = Contentful::Management::Client.shared_instance
12
+ @client = client
13
13
  @client.version = header[:version]
14
14
  @client.organization_id = header[:organization_id]
15
15
  @client.content_type_id = header[:content_type_id]
@@ -60,7 +60,7 @@ module Contentful
60
60
 
61
61
  # Returns a new Request object with the same data
62
62
  def copy
63
- self.class.new(@endpoint, @query, @initial_id, @header)
63
+ self.class.new(@client, @endpoint, @query, @initial_id, @header)
64
64
  end
65
65
 
66
66
  private
@@ -27,7 +27,8 @@ module Contentful
27
27
  }
28
28
  # rubocop:enable Style/DoubleNegation
29
29
 
30
- attr_reader :properties, :request, :client, :default_locale, :raw_object
30
+ attr_reader :properties, :request, :default_locale, :raw_object
31
+ attr_accessor :client
31
32
 
32
33
  # @private
33
34
  def initialize(object = nil,
@@ -45,6 +46,33 @@ module Contentful
45
46
  @raw_object = object
46
47
  end
47
48
 
49
+ # @private
50
+ def after_create(_attributes)
51
+ end
52
+
53
+ # Updates a resource.
54
+ #
55
+ # @param [Hash] attributes
56
+ #
57
+ # @see _ README for more information on how to create each resource
58
+ #
59
+ # @return [Contentful::Management::Resource]
60
+ def update(attributes)
61
+ ResourceRequester.new(client, self.class).update(
62
+ self,
63
+ { space_id: space.id, resource_id: id },
64
+ query_attributes(attributes),
65
+ version: sys[:version]
66
+ )
67
+ end
68
+
69
+ # Destroys a resource.
70
+ #
71
+ # @return [true, Contentful::Management::Error] success
72
+ def destroy
73
+ ResourceRequester.new(client, self.class).destroy(space_id: space.id, resource_id: id)
74
+ end
75
+
48
76
  # @private
49
77
  def inspect(info = nil)
50
78
  properties_info = properties.empty? ? '' : " @properties=#{properties.inspect}"
@@ -78,6 +106,17 @@ module Contentful
78
106
  Contentful::Management::Client.shared_instance
79
107
  end
80
108
 
109
+ # @return [true]
110
+ def resource?
111
+ true
112
+ end
113
+
114
+ protected
115
+
116
+ def query_attributes(attributes)
117
+ attributes
118
+ end
119
+
81
120
  private
82
121
 
83
122
  def extract_from_object(object, namespace, keys = nil)
@@ -114,22 +153,80 @@ module Contentful
114
153
  end
115
154
 
116
155
  # Register the resources properties on class level by using the #property method
117
- # @private
118
156
  module ClassMethods
157
+ # @private
158
+ def endpoint
159
+ "#{Support.snakify(name.split('::')[-1])}s"
160
+ end
161
+
162
+ # @private
163
+ def build_endpoint(endpoint_options)
164
+ return "/#{endpoint_options[:space_id]}/public/#{endpoint}" if endpoint_options.key?(:public)
165
+ base = "/#{endpoint_options[:space_id]}/#{endpoint}"
166
+ return "#{base}/#{endpoint_options[:resource_id]}#{endpoint_options[:suffix]}" if endpoint_options.key?(:resource_id)
167
+ base
168
+ end
169
+
170
+ # Gets a collection of resources.
171
+ #
172
+ # @param [Contentful::Management::Client] client
173
+ # @param [String] space_id
174
+ # @param [Hash] parameters Search Options
175
+ # @see _ For complete option list: http://docs.contentfulcda.apiary.io/#reference/search-parameters
176
+ #
177
+ # @return [Contentful::Management::Array<Contentful::Management::Resource>]
178
+ def all(client, space_id, parameters = {})
179
+ ResourceRequester.new(client, self).all({ space_id: space_id }, parameters)
180
+ end
181
+
182
+ # Gets a specific resource.
183
+ #
184
+ # @param [Contentful::Management::Client] client
185
+ # @param [String] space_id
186
+ # @param [String] resource_id
187
+ #
188
+ # @return [Contentful::Management::Resource]
189
+ def find(client, space_id, resource_id)
190
+ ResourceRequester.new(client, self).find(space_id: space_id, resource_id: resource_id)
191
+ end
192
+
193
+ # Creates a resource.
194
+ #
195
+ # @param [Contentful::Management::Client] client
196
+ # @param [String] space_id
197
+ # @param [Hash] attributes
198
+ # @see _ README for full attribute list for each resource.
199
+ #
200
+ # @return [Contentful::Management::Resource]
201
+ def create(client, space_id, attributes)
202
+ endpoint_options = { space_id: space_id }
203
+ endpoint_options[:resource_id] = attributes[:id] if attributes.key?(:id)
204
+ ResourceRequester.new(client, self).create(
205
+ endpoint_options,
206
+ attributes
207
+ )
208
+ end
209
+
210
+ # @private
211
+ def create_attributes(_client, _attributes)
212
+ {}
213
+ end
214
+
215
+ # @private
216
+ def create_headers(_client, _attributes)
217
+ {}
218
+ end
219
+
119
220
  # By default, fields come flattened in the current locale. This is different for sync
120
221
  def nested_locale_fields?
121
222
  false
122
223
  end
123
224
 
225
+ # Default property coercions
124
226
  def property_coercions
125
227
  @property_coercions ||= {}
126
228
  end
127
229
 
128
- # Shared instance of the API client
129
- def client
130
- Contentful::Management::Client.shared_instance
131
- end
132
-
133
230
  # Defines which properties of a resource your class expects
134
231
  # Define them in :camelCase, they will be available as #snake_cased methods
135
232
  #
@@ -172,6 +269,7 @@ module Contentful
172
269
  end
173
270
  end
174
271
 
272
+ # @private
175
273
  def self.included(base)
176
274
  base.extend(ClassMethods)
177
275
  end
@@ -0,0 +1,24 @@
1
+ module Contentful
2
+ module Management
3
+ module Resource
4
+ # Wrapper Class for Resources with '/public' API calls
5
+ module AllPublished
6
+ # Gets a collection of published resources.
7
+ #
8
+ # @param [Contentful::Management::Client] client
9
+ # @param [String] space_id
10
+ # @param [Hash] parameters
11
+ # @see _ For complete option list: http://docs.contentfulcda.apiary.io/#reference/search-parameters
12
+ # @option parameters [String] 'sys.id' Entry ID
13
+ # @option parameters [String] :content_type
14
+ # @option parameters [Integer] :limit
15
+ # @option parameters [Integer] :skip
16
+ #
17
+ # @return [Contentful::Management::Array<Contentful::Management::Resource>]
18
+ def all_published(client, space_id, parameters = {})
19
+ client_association_class.new(client).all_published(space_id, parameters)
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,37 @@
1
+ module Contentful
2
+ module Management
3
+ module Resource
4
+ # Wrapper for Resources with /archived API
5
+ module Archiver
6
+ # Archives a resource.
7
+ #
8
+ # @return [Contentful::Management::Resource]
9
+ def archive
10
+ ResourceRequester.new(client, self.class).archive(
11
+ self,
12
+ { space_id: space.id, resource_id: id, suffix: '/archived' },
13
+ version: sys[:version]
14
+ )
15
+ end
16
+
17
+ # Unarchives a resource.
18
+ #
19
+ # @return [Contentful::Management::Resource]
20
+ def unarchive
21
+ ResourceRequester.new(client, self.class).unarchive(
22
+ self,
23
+ { space_id: space.id, resource_id: id, suffix: '/archived' },
24
+ version: sys[:version]
25
+ )
26
+ end
27
+
28
+ # Checks if a resource is archived.
29
+ #
30
+ # @return [Boolean]
31
+ def archived?
32
+ sys[:archivedAt] ? true : false
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
@@ -6,40 +6,55 @@ module Contentful
6
6
  # Creates fields for entry based on it's ContentType
7
7
  #
8
8
  # @param [Entry] entry the expected entry to modify
9
- def self.create_fields_for_content_type(entry)
10
- entry.instance_eval do
11
- content_type.fields.each do |field|
12
- localized_or_default_locale = Contentful::Management::Resource::FieldAware.localized_or_default_locale(
13
- field,
14
- default_locale,
15
- locale
16
- )
17
-
18
- accessor_name = Support.snakify(field.id)
19
- define_singleton_method accessor_name do
20
- fields[field.id.to_sym]
21
- end
22
- define_singleton_method "#{accessor_name}_with_locales" do
23
- fields_for_query[field.id.to_sym]
24
- end
25
- define_singleton_method "#{accessor_name}=" do |value|
26
- if localized_or_default_locale
27
- @fields[locale] ||= {}
28
- @fields[locale][field.id.to_sym] = value
29
- end
30
- end
31
- define_singleton_method "#{accessor_name}_with_locales=" do |values|
32
- values.each do |locale, value|
33
- if localized_or_default_locale
34
- @fields[locale] ||= {}
35
- @fields[locale][field.id.to_sym] = value
36
- end
37
- end
9
+ def self.create_fields_for_content_type(entry, method = :instance)
10
+ entry.content_type.fields.each do |field|
11
+ accessor_name = Support.snakify(field.id)
12
+
13
+ FieldAware.create_getter(entry, accessor_name, field, method)
14
+ FieldAware.create_setter(entry, accessor_name, field, method)
15
+ end
16
+ end
17
+
18
+ # Creates getters for field
19
+ # @private
20
+ def self.create_getter(entry, accessor_name, field, method)
21
+ entry.send("#{method}_eval") do
22
+ send(FieldAware.define(method), accessor_name) do
23
+ fields[field.id.to_sym]
24
+ end
25
+
26
+ send(FieldAware.define(method), "#{accessor_name}_with_locales") do
27
+ fields_for_query[field.id.to_sym]
28
+ end
29
+ end
30
+ end
31
+
32
+ # Creates setters for field
33
+ # @private
34
+ def self.create_setter(entry, accessor_name, field, method)
35
+ entry.send("#{method}_eval") do
36
+ send(FieldAware.define(method), "#{accessor_name}=") do |value|
37
+ FieldAware.create_setter_field(self, field, value, locale, default_locale)
38
+ end
39
+
40
+ send(FieldAware.define(method), "#{accessor_name}_with_locales=") do |values|
41
+ values.each do |locale, value|
42
+ FieldAware.create_setter_field(self, field, value, locale, default_locale)
38
43
  end
39
44
  end
40
45
  end
41
46
  end
42
47
 
48
+ # Sets fields with value for locale
49
+ # @private
50
+ def self.create_setter_field(entry, field, value, locale, default_locale)
51
+ fields = entry.instance_variable_get(:@fields)
52
+ if localized_or_default_locale(field, default_locale, locale)
53
+ fields[locale] ||= {}
54
+ fields[locale][field.id.to_sym] = value
55
+ end
56
+ end
57
+
43
58
  # Verifies if field is localized or default locale matches current locale
44
59
  #
45
60
  # @param [Field] field an entry field
@@ -50,6 +65,11 @@ module Contentful
50
65
  def self.localized_or_default_locale(field, default_locale, locale)
51
66
  field.localized || default_locale == locale
52
67
  end
68
+
69
+ # @private
70
+ def self.define(class_or_instance)
71
+ "define_#{class_or_instance == :instance ? 'singleton_' : ''}method"
72
+ end
53
73
  end
54
74
  end
55
75
  end
@@ -0,0 +1,37 @@
1
+ module Contentful
2
+ module Management
3
+ module Resource
4
+ # Wrapper for Resources with /published API
5
+ module Publisher
6
+ # Publishes a resource.
7
+ #
8
+ # @return [Contentful::Management::Resource]
9
+ def publish
10
+ ResourceRequester.new(client, self.class).publish(
11
+ self,
12
+ { space_id: space.id, resource_id: id, suffix: '/published' },
13
+ version: sys[:version]
14
+ )
15
+ end
16
+
17
+ # Unpublishes a resource.
18
+ #
19
+ # @return [Contentful::Management::Resource]
20
+ def unpublish
21
+ ResourceRequester.new(client, self.class).unpublish(
22
+ self,
23
+ { space_id: space.id, resource_id: id, suffix: '/published' },
24
+ version: sys[:version]
25
+ )
26
+ end
27
+
28
+ # Checks if a resource is published.
29
+ #
30
+ # @return [Boolean]
31
+ def published?
32
+ sys[:publishedAt] ? true : false
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end