contentful-management 0.8.0 → 0.9.0

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 (71) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +12 -29
  3. data/.rubocop_todo.yml +24 -0
  4. data/.travis.yml +1 -1
  5. data/.yardopts +4 -0
  6. data/CHANGELOG.md +12 -0
  7. data/Gemfile +1 -0
  8. data/Guardfile +39 -34
  9. data/README.md +42 -1
  10. data/Rakefile +2 -0
  11. data/contentful-management.gemspec +2 -1
  12. data/lib/contentful/management/api_key.rb +65 -0
  13. data/lib/contentful/management/array.rb +3 -2
  14. data/lib/contentful/management/asset.rb +124 -58
  15. data/lib/contentful/management/client.rb +60 -19
  16. data/lib/contentful/management/content_type.rb +104 -49
  17. data/lib/contentful/management/content_type_entry_methods_factory.rb +21 -0
  18. data/lib/contentful/management/dynamic_entry.rb +22 -18
  19. data/lib/contentful/management/entry.rb +138 -80
  20. data/lib/contentful/management/error.rb +23 -23
  21. data/lib/contentful/management/field.rb +16 -13
  22. data/lib/contentful/management/http_client.rb +29 -0
  23. data/lib/contentful/management/link.rb +3 -3
  24. data/lib/contentful/management/locale.rb +55 -26
  25. data/lib/contentful/management/location.rb +1 -1
  26. data/lib/contentful/management/request.rb +11 -12
  27. data/lib/contentful/management/resource.rb +27 -12
  28. data/lib/contentful/management/resource/array_like.rb +1 -1
  29. data/lib/contentful/management/resource/asset_fields.rb +1 -0
  30. data/lib/contentful/management/resource/entry_fields.rb +2 -0
  31. data/lib/contentful/management/resource/field_aware.rb +16 -5
  32. data/lib/contentful/management/resource/fields.rb +16 -8
  33. data/lib/contentful/management/resource/refresher.rb +1 -0
  34. data/lib/contentful/management/resource/system_properties.rb +13 -6
  35. data/lib/contentful/management/resource_builder.rb +43 -40
  36. data/lib/contentful/management/space.rb +67 -28
  37. data/lib/contentful/management/space_api_key_methods_factory.rb +15 -0
  38. data/lib/contentful/management/space_asset_methods_factory.rb +4 -0
  39. data/lib/contentful/management/space_association_all_published_method_factory.rb +11 -0
  40. data/lib/contentful/management/space_association_methods_factory.rb +4 -2
  41. data/lib/contentful/management/space_content_type_methods_factory.rb +4 -0
  42. data/lib/contentful/management/space_entry_methods_factory.rb +4 -0
  43. data/lib/contentful/management/space_locale_methods_factory.rb +2 -0
  44. data/lib/contentful/management/space_webhook_methods_factory.rb +2 -0
  45. data/lib/contentful/management/validation.rb +3 -2
  46. data/lib/contentful/management/version.rb +4 -1
  47. data/lib/contentful/management/webhook.rb +42 -21
  48. data/spec/fixtures/vcr_cassettes/api_key/all_for_space.yml +194 -0
  49. data/spec/fixtures/vcr_cassettes/api_key/create_for_space.yml +113 -0
  50. data/spec/fixtures/vcr_cassettes/api_key/find.yml +113 -0
  51. data/spec/fixtures/vcr_cassettes/api_key/find_for_space_not_found.yml +71 -0
  52. data/spec/fixtures/vcr_cassettes/asset/all_public.yml +112 -0
  53. data/spec/fixtures/vcr_cassettes/content_type/all_public.yml +106 -0
  54. data/spec/fixtures/vcr_cassettes/entry/all_public.yml +102 -0
  55. data/spec/fixtures/vcr_cassettes/locale/destroy.yml +330 -0
  56. data/spec/fixtures/vcr_cassettes/locale/update_both.yml +306 -0
  57. data/spec/fixtures/vcr_cassettes/locale/update_code.yml +306 -0
  58. data/spec/fixtures/vcr_cassettes/locale/update_name.yml +306 -0
  59. data/spec/fixtures/vcr_cassettes/space/api_key/all.yml +410 -0
  60. data/spec/fixtures/vcr_cassettes/space/api_key/create.yml +329 -0
  61. data/spec/fixtures/vcr_cassettes/space/api_key/find.yml +329 -0
  62. data/spec/fixtures/vcr_cassettes/space/asset/all_public.yml +328 -0
  63. data/spec/fixtures/vcr_cassettes/space/content_type/all_public.yml +322 -0
  64. data/spec/fixtures/vcr_cassettes/space/entry/all_public.yml +318 -0
  65. data/spec/lib/contentful/management/api_key_spec.rb +55 -0
  66. data/spec/lib/contentful/management/asset_spec.rb +10 -0
  67. data/spec/lib/contentful/management/content_type_spec.rb +10 -0
  68. data/spec/lib/contentful/management/entry_spec.rb +10 -0
  69. data/spec/lib/contentful/management/locale_spec.rb +58 -0
  70. data/spec/lib/contentful/management/space_spec.rb +53 -0
  71. metadata +58 -9
@@ -8,9 +8,9 @@ module Contentful
8
8
  def initialize(response)
9
9
  @response = response
10
10
  @error = {
11
- url: response.request.endpoint,
12
- message: response.error_message,
13
- details: response.raw.body.instance_variable_get(:@contents)
11
+ url: response.request.endpoint,
12
+ message: response.error_message,
13
+ details: response.raw.body.instance_variable_get(:@contents)
14
14
  }
15
15
  super @response.error_message
16
16
  end
@@ -19,26 +19,26 @@ module Contentful
19
19
  # USAGE rescue Contentful::Management::Error[404]
20
20
  def self.[](error_status_code)
21
21
  case error_status_code
22
- when 404
23
- NotFound
24
- when 400
25
- BadRequest
26
- when 403
27
- AccessDenied
28
- when 409
29
- Conflict
30
- when 401
31
- Unauthorized
32
- when 422
33
- UnprocessableEntity
34
- when 429
35
- RateLimitExceeded
36
- when 500
37
- ServerError
38
- when 503
39
- ServiceUnavailable
40
- else
41
- Error
22
+ when 404
23
+ NotFound
24
+ when 400
25
+ BadRequest
26
+ when 403
27
+ AccessDenied
28
+ when 409
29
+ Conflict
30
+ when 401
31
+ Unauthorized
32
+ when 422
33
+ UnprocessableEntity
34
+ when 429
35
+ RateLimitExceeded
36
+ when 500
37
+ ServerError
38
+ when 503
39
+ ServiceUnavailable
40
+ else
41
+ Error
42
42
  end
43
43
  end
44
44
  end
@@ -18,6 +18,7 @@ module Contentful
18
18
 
19
19
  # Takes a field object of content type
20
20
  # Merges existing properties, items and validations of field with new one
21
+ # @private
21
22
  def deep_merge!(field)
22
23
  merge_properties(field.properties)
23
24
  merge_items(field.items)
@@ -25,6 +26,7 @@ module Contentful
25
26
  end
26
27
 
27
28
  # Extract values of field to hash
29
+ # @private
28
30
  def properties_to_hash
29
31
  properties.each_with_object({}) do |(key, value), results|
30
32
  results[key] = parse_value(key, value)
@@ -32,17 +34,19 @@ module Contentful
32
34
  end
33
35
 
34
36
  # Return parsed value of field object
37
+ # @private
35
38
  def parse_value(key, value)
36
39
  case key
37
- when :items
38
- value.properties_to_hash if type == 'Array' && value.is_a?(Field)
39
- when :validations
40
- validations_to_hash(value) if value.is_a?(::Array)
41
- else
42
- value if self.class.value_exists?(value)
40
+ when :items
41
+ value.properties_to_hash if type == 'Array' && value.is_a?(Field)
42
+ when :validations
43
+ validations_to_hash(value) if value.is_a?(::Array)
44
+ else
45
+ value if self.class.value_exists?(value)
43
46
  end
44
47
  end
45
48
 
49
+ # @private
46
50
  def self.value_exists?(value)
47
51
  value.respond_to?(:empty?) && !value.empty? || !value.respond_to?(:empty?) && value
48
52
  end
@@ -62,12 +66,12 @@ module Contentful
62
66
  # Takes an array with new validations
63
67
  # Returns merged existing and new validations
64
68
  def merge_validations(new_validations)
65
- if new_validations
66
- validations_by_type = validations_by_type(validations)
67
- new_validations_by_type = validations_by_type(new_validations)
68
- validations_by_type.delete_if { |type, _v| new_validations_by_type[type] }
69
- self.validations = validations_by_type.values + new_validations_by_type.values
70
- end
69
+ return unless new_validations
70
+
71
+ validations_by_type = validations_by_type(validations)
72
+ new_validations_by_type = validations_by_type(new_validations)
73
+ validations_by_type.delete_if { |type, _v| new_validations_by_type[type] }
74
+ self.validations = validations_by_type.values + new_validations_by_type.values
71
75
  end
72
76
 
73
77
  def validations_by_type(validations)
@@ -84,7 +88,6 @@ module Contentful
84
88
  results << validation.properties_to_hash
85
89
  end
86
90
  end
87
-
88
91
  end
89
92
  end
90
93
  end
@@ -1,18 +1,47 @@
1
1
  module Contentful
2
2
  module Management
3
+ # Thin HTTP Client with Restful Operations
3
4
  module HTTPClient
5
+ # Get Request
6
+ #
7
+ # @param [String] url
8
+ # @param [Hash] query
9
+ # @param [Hash] headers
10
+ #
11
+ # @return [HTTP::Response]
4
12
  def get_http(url, query, headers = {})
5
13
  HTTP[headers].get(url, params: query)
6
14
  end
7
15
 
16
+ # Post Request
17
+ #
18
+ # @param [String] url
19
+ # @param [Hash] params
20
+ # @param [Hash] headers
21
+ #
22
+ # @return [HTTP::Response]
8
23
  def post_http(url, params, headers = {})
9
24
  HTTP[headers].post(url, json: params)
10
25
  end
11
26
 
27
+ # Delete Request
28
+ #
29
+ # @param [String] url
30
+ # @param [Hash] params
31
+ # @param [Hash] headers
32
+ #
33
+ # @return [HTTP::Response]
12
34
  def delete_http(url, params, headers = {})
13
35
  HTTP[headers].delete(url, params: params)
14
36
  end
15
37
 
38
+ # Put Request
39
+ #
40
+ # @param [String] url
41
+ # @param [Hash] params
42
+ # @param [Hash] headers
43
+ #
44
+ # @return [HTTP::Response]
16
45
  def put_http(url, params, headers = {})
17
46
  HTTP[headers].put(url, json: params)
18
47
  end
@@ -9,12 +9,12 @@ module Contentful
9
9
  include Contentful::Management::Resource::SystemProperties
10
10
 
11
11
  # Queries contentful for the Resource the Link is referring to
12
- # Takes an optional query hash
12
+ # @param [Hash] query
13
13
  def resolve(query = {})
14
14
  id_and_query = [(id unless link_type == 'Space')].compact + [query]
15
15
  client.public_send(
16
- Contentful::Management::Support.snakify(link_type).to_sym,
17
- *id_and_query
16
+ Contentful::Management::Support.snakify(link_type).to_sym,
17
+ *id_and_query
18
18
  )
19
19
  end
20
20
  end
@@ -16,58 +16,87 @@ module Contentful
16
16
  property :default, :boolean
17
17
 
18
18
  # Gets a collection of locales.
19
- # Takes an id of a space.
20
- # Returns a Contentful::Management::Array of Contentful::Management::Locale.
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>]
21
26
  def self.all(space_id = nil, _parameters = {})
22
- request = Request.new("/#{ space_id }/locales")
27
+ request = Request.new("/#{space_id}/locales")
23
28
  response = request.get
24
- result = ResourceBuilder.new(response, {'Locale' => Locale}, {})
29
+ result = ResourceBuilder.new(response, { 'Locale' => Locale }, {})
25
30
  result.run
26
31
  end
27
32
 
28
33
  # Gets a specific locale.
29
- # Takes an id of a space and locale id.
30
- # Returns a Contentful::Management::Locale.
34
+ #
35
+ # @param [String] space_id
36
+ # @param [String] locale_id
37
+ #
38
+ # @return [Contentful::Management::Locale]
31
39
  def self.find(space_id, locale_id)
32
- request = Request.new("/#{ space_id }/locales/#{ locale_id }")
40
+ request = Request.new("/#{space_id}/locales/#{locale_id}")
33
41
  response = request.get
34
- result = ResourceBuilder.new(response, {'Locale' => Locale}, {})
42
+ result = ResourceBuilder.new(response, { 'Locale' => Locale }, {})
35
43
  result.run
36
44
  end
37
45
 
38
46
  # Creates a locale.
39
- # Takes a space id and hash with attributes:
40
- # :name
41
- # :code
42
- # :contentManagementApi
43
- # :contentDeliveryApi
44
- # :publish
45
- # Returns a Contentful::Management::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]
46
54
  def self.create(space_id, attributes)
47
55
  request = Request.new(
48
- "/#{ space_id }/locales",
49
- 'name' => attributes.fetch(:name),
50
- 'code' => attributes.fetch(:code)
56
+ "/#{space_id}/locales",
57
+ 'name' => attributes.fetch(:name),
58
+ 'code' => attributes.fetch(:code)
51
59
  )
52
60
  response = request.post
53
- result = ResourceBuilder.new(response, {'Locale' => Locale}, {})
61
+ result = ResourceBuilder.new(response, { 'Locale' => Locale }, {})
54
62
  result.run
55
63
  end
56
64
 
57
65
  # Updates a locale.
58
- # Takes a hash with attributes.
59
- # Returns a Contentful::Management::Locale.
66
+ #
67
+ # @param [Hash] attributes
68
+ # @option attributes [String] :name
69
+ # @option attributes [String] :code
70
+ #
71
+ # @return [Contentful::Management::Locale]
60
72
  def update(attributes)
73
+ parameters = {}
74
+ attributes.each { |k, v| parameters[k.to_s] = v }
75
+
61
76
  request = Request.new(
62
- "/#{ space.id }/locales/#{ id }",
63
- {'name' => attributes.fetch(:name)},
64
- id = nil,
65
- version: sys[:version]
77
+ "/#{space.id}/locales/#{id}",
78
+ parameters,
79
+ nil,
80
+ version: sys[:version]
66
81
  )
67
82
  response = request.put
68
- result = ResourceBuilder.new(response, {'Locale' => Locale}, {})
83
+ result = ResourceBuilder.new(response, { 'Locale' => Locale }, {})
69
84
  refresh_data(result.run)
70
85
  end
86
+
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
99
+ end
71
100
  end
72
101
  end
73
102
  end
@@ -3,7 +3,7 @@ require_relative 'resource'
3
3
  module Contentful
4
4
  module Management
5
5
  # Location Field Type
6
- # You can directly query for them: https://www.contentful.com/developers/documentation/content-management-api/#search-filter-geo
6
+ # @see _ You can directly query for them: https://www.contentful.com/developers/documentation/content-management-api/#search-filter-geo
7
7
  class Location
8
8
  include Contentful::Management::Resource
9
9
 
@@ -15,11 +15,8 @@ module Contentful
15
15
  @client.content_type_id = header[:content_type_id]
16
16
  @client.zero_length = query.empty?
17
17
  @endpoint = endpoint
18
- @absolute = true if @endpoint.start_with?('http')
19
18
 
20
- @query = if query && !query.empty?
21
- normalize_query(query)
22
- end
19
+ @query = normalize_query(query) if query && !query.empty?
23
20
 
24
21
  if id
25
22
  @type = :single
@@ -32,7 +29,7 @@ module Contentful
32
29
 
33
30
  # Returns the final URL, relative to a contentful space
34
31
  def url
35
- "#{@endpoint }#{ @type == :single ? "/#{ id }" : '' }"
32
+ "#{@endpoint}#{@type == :single ? "/#{id}" : ''}"
36
33
  end
37
34
 
38
35
  # Delegates the actual HTTP work to the client
@@ -50,13 +47,15 @@ module Contentful
50
47
  client.put(self)
51
48
  end
52
49
 
50
+ # Delegates the actual HTTP DELETE request to the client
53
51
  def delete
54
52
  client.delete(self)
55
53
  end
56
54
 
57
55
  # Returns true if endpoint is an absolute url
56
+ # @return [Boolean]
58
57
  def absolute?
59
- !!@absolute
58
+ @endpoint.start_with?('http')
60
59
  end
61
60
 
62
61
  # Returns a new Request object with the same data
@@ -68,12 +67,12 @@ module Contentful
68
67
 
69
68
  def normalize_query(query)
70
69
  Hash[
71
- query.map do |key, value|
72
- [
73
- key.to_sym,
74
- value
75
- ]
76
- end
70
+ query.map do |key, value|
71
+ [
72
+ key.to_sym,
73
+ value
74
+ ]
75
+ end
77
76
  ]
78
77
  end
79
78
  end
@@ -12,7 +12,12 @@ module Contentful
12
12
  #
13
13
  # Take a look at examples/resource_mapping.rb on how to register them to be returned
14
14
  # by the client by default
15
+ #
16
+ # @see _ examples/custom_classes.rb Custom Class as Resource
17
+ # @see _ examples/resource_mapping.rb Mapping a Custom Class
15
18
  module Resource
19
+ # @private
20
+ # rubocop:disable Style/DoubleNegation
16
21
  COERCIONS = {
17
22
  string: ->(value) { !value.nil? ? value.to_s : nil },
18
23
  integer: ->(value) { value.to_i },
@@ -20,10 +25,16 @@ module Contentful
20
25
  boolean: ->(value) { !!value },
21
26
  date: ->(value) { !value.nil? ? DateTime.parse(value) : nil }
22
27
  }
28
+ # rubocop:enable Style/DoubleNegation
23
29
 
24
30
  attr_reader :properties, :request, :client, :default_locale, :raw_object
25
31
 
26
- def initialize(object = nil, request = nil, client = nil, nested_locale_fields = false, default_locale = Contentful::Management::Client::DEFAULT_CONFIGURATION[:default_locale])
32
+ # @private
33
+ def initialize(object = nil,
34
+ request = nil,
35
+ client = nil,
36
+ nested_locale_fields = false,
37
+ default_locale = Contentful::Management::Client::DEFAULT_CONFIGURATION[:default_locale])
27
38
  self.class.update_coercions!
28
39
  @nested_locale_fields = nested_locale_fields
29
40
  @default_locale = default_locale
@@ -34,9 +45,10 @@ module Contentful
34
45
  @raw_object = object
35
46
  end
36
47
 
48
+ # @private
37
49
  def inspect(info = nil)
38
- properties_info = properties.empty? ? '' : " @properties=#{ properties.inspect }"
39
- "#<#{ self.class }:#{ properties_info }#{ info }>"
50
+ properties_info = properties.empty? ? '' : " @properties=#{properties.inspect}"
51
+ "#<#{self.class}:#{properties_info}#{info}>"
40
52
  end
41
53
 
42
54
  # Returns true for resources that behave like an array
@@ -46,7 +58,9 @@ module Contentful
46
58
 
47
59
  # By default, fields come flattened in the current locale. This is different for syncs
48
60
  def nested_locale_fields?
61
+ # rubocop:disable Style/DoubleNegation
49
62
  !!@nested_locale_fields
63
+ # rubocop:enable Style/DoubleNegation
50
64
  end
51
65
 
52
66
  # Resources that don't include SystemProperties return nil for #sys
@@ -71,8 +85,8 @@ module Contentful
71
85
  keys ||= object.keys
72
86
  keys.each.with_object({}) do |name, res|
73
87
  res[name.to_sym] = coerce_value_or_array(
74
- object.is_a?(::Array) ? object : object[name.to_s],
75
- self.class.public_send(:"#{ namespace }_coercions")[name.to_sym]
88
+ object.is_a?(::Array) ? object : object[name.to_s],
89
+ self.class.public_send(:"#{namespace}_coercions")[name.to_sym]
76
90
  )
77
91
  end
78
92
  else
@@ -90,16 +104,17 @@ module Contentful
90
104
 
91
105
  def coerce_or_create_class(value, what)
92
106
  case what
93
- when Symbol
94
- COERCIONS[what] ? COERCIONS[what][value] : value
95
- when Class
96
- what.new(value, client)
97
- else
98
- value
107
+ when Symbol
108
+ COERCIONS[what] ? COERCIONS[what][value] : value
109
+ when Class
110
+ what.new(value, client)
111
+ else
112
+ value
99
113
  end
100
114
  end
101
115
 
102
116
  # Register the resources properties on class level by using the #property method
117
+ # @private
103
118
  module ClassMethods
104
119
  # By default, fields come flattened in the current locale. This is different for sync
105
120
  def nested_locale_fields?
@@ -132,7 +147,7 @@ module Contentful
132
147
  define_method accessor_name do
133
148
  properties[name.to_sym]
134
149
  end
135
- define_method "#{ accessor_name }=" do |value|
150
+ define_method "#{accessor_name}=" do |value|
136
151
  properties[name.to_sym] = value
137
152
  end
138
153
  end