contentful-management 1.9.0 → 1.10.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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +4 -0
- data/lib/contentful/management/error.rb +186 -28
- data/lib/contentful/management/response.rb +5 -4
- data/lib/contentful/management/version.rb +1 -1
- data/spec/fixtures/json_responses/400_details_errors_object.json +14 -0
- data/spec/fixtures/json_responses/400_details_errors_string.json +12 -0
- data/spec/fixtures/json_responses/400_details_string.json +8 -0
- data/spec/fixtures/json_responses/403_reasons.json +13 -0
- data/spec/fixtures/json_responses/404_details_string.json +8 -0
- data/spec/fixtures/json_responses/404_id.json +11 -0
- data/spec/fixtures/json_responses/404_type.json +10 -0
- data/spec/fixtures/json_responses/422_details.json +22 -0
- data/spec/fixtures/json_responses/default_400.json +7 -0
- data/spec/fixtures/json_responses/default_401.json +7 -0
- data/spec/fixtures/json_responses/default_403.json +7 -0
- data/spec/fixtures/json_responses/default_404.json +7 -0
- data/spec/fixtures/json_responses/default_409.json +7 -0
- data/spec/fixtures/json_responses/default_422.json +7 -0
- data/spec/fixtures/json_responses/default_429.json +7 -0
- data/spec/fixtures/json_responses/default_500.json +7 -0
- data/spec/fixtures/json_responses/default_502.json +7 -0
- data/spec/fixtures/json_responses/default_503.json +7 -0
- data/spec/fixtures/json_responses/not_found.json +13 -0
- data/spec/fixtures/json_responses/other_error.json +9 -0
- data/spec/fixtures/json_responses/other_error_no_details.json +8 -0
- data/spec/fixtures/json_responses/other_error_no_message.json +8 -0
- data/spec/fixtures/json_responses/other_error_no_request_id.json +8 -0
- data/spec/fixtures/json_responses/other_error_nothing.json +6 -0
- data/spec/fixtures/json_responses/unparsable.json +13 -0
- data/spec/fixtures/vcr_cassettes/asset/destroy_published.yml +1 -1
- data/spec/fixtures/vcr_cassettes/content_type/destroy_activated.yml +1 -1
- data/spec/lib/contentful/management/asset_spec.rb +16 -3
- data/spec/lib/contentful/management/content_type_spec.rb +10 -2
- data/spec/lib/contentful/management/entry_spec.rb +25 -5
- data/spec/lib/contentful/management/error_class_spec.rb +369 -0
- data/spec/support/json_responses.rb +18 -0
- metadata +56 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1c4ec83b46a51eb77dec3b180f0e016a8e0955f4
|
4
|
+
data.tar.gz: f399a8297f69fa59fc7bc2d84726b599a90293f2
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2c7b7cc83f3a25c245f7fc5903fd6acc096f6d7a8225c9cb10676d728c2f406ff82c6db899220daaf7a7622bc5c82bc7081db217ee5c0a3ea6d4441322fb9b7a
|
7
|
+
data.tar.gz: 213e66c26d64ba6045f56aec03c4520e3bfa6ef5477cea6007790b56cda5e00af1a6578b3e2665f0d4f352487278ea457cb6b0bfaae0f984b58527f80e968034
|
data/CHANGELOG.md
CHANGED
@@ -12,75 +12,233 @@ module Contentful
|
|
12
12
|
message: response.error_message,
|
13
13
|
details: response.raw.body.instance_variable_get(:@contents)
|
14
14
|
}
|
15
|
-
super
|
15
|
+
super best_available_message
|
16
16
|
end
|
17
17
|
|
18
18
|
# Shortcut for creating specialized error classes
|
19
19
|
# USAGE rescue Contentful::Management::Error[404]
|
20
20
|
def self.[](error_status_code)
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
RateLimitExceeded
|
36
|
-
when 500
|
37
|
-
ServerError
|
38
|
-
when 503
|
39
|
-
ServiceUnavailable
|
40
|
-
else
|
41
|
-
Error
|
42
|
-
end
|
21
|
+
errors = {
|
22
|
+
400 => BadRequest,
|
23
|
+
401 => Unauthorized,
|
24
|
+
403 => AccessDenied,
|
25
|
+
404 => NotFound,
|
26
|
+
409 => Conflict,
|
27
|
+
422 => UnprocessableEntity,
|
28
|
+
429 => RateLimitExceeded,
|
29
|
+
500 => ServerError,
|
30
|
+
502 => BadGateway,
|
31
|
+
503 => ServiceUnavailable
|
32
|
+
}.freeze
|
33
|
+
|
34
|
+
errors.key?(error_status_code) ? errors[error_status_code] : Error
|
43
35
|
end
|
44
|
-
end
|
45
36
|
|
46
|
-
|
47
|
-
|
37
|
+
protected
|
38
|
+
|
39
|
+
def default_error_message
|
40
|
+
"The following error was received: #{@response.raw.body}"
|
41
|
+
end
|
42
|
+
|
43
|
+
def handle_details(details)
|
44
|
+
details.to_s
|
45
|
+
end
|
46
|
+
|
47
|
+
def additional_info?
|
48
|
+
false
|
49
|
+
end
|
50
|
+
|
51
|
+
def additional_info
|
52
|
+
[]
|
53
|
+
end
|
54
|
+
|
55
|
+
def best_available_message
|
56
|
+
error_message = [
|
57
|
+
"HTTP status code: #{@response.raw.status}"
|
58
|
+
]
|
59
|
+
|
60
|
+
begin
|
61
|
+
response_json = @response.load_json
|
62
|
+
message = response_json.fetch('message', default_error_message)
|
63
|
+
details = response_json.fetch('details', nil)
|
64
|
+
request_id = response_json.fetch('requestId', nil)
|
65
|
+
|
66
|
+
error_message << "Message: #{message}"
|
67
|
+
error_message << "Details: #{handle_details(details)}" if details
|
68
|
+
error_message << "Request ID: #{request_id}" if request_id
|
69
|
+
rescue
|
70
|
+
error_message << "Message: #{default_error_message}"
|
71
|
+
end
|
72
|
+
|
73
|
+
error_message << additional_info if additional_info?
|
74
|
+
|
75
|
+
error_message.join("\n")
|
76
|
+
end
|
48
77
|
end
|
49
78
|
|
50
79
|
# 400
|
51
80
|
class BadRequest < Error
|
81
|
+
protected
|
82
|
+
|
83
|
+
def default_error_message
|
84
|
+
'The request was malformed or missing a required parameter.'
|
85
|
+
end
|
86
|
+
|
87
|
+
def handle_details(details)
|
88
|
+
return details if details.is_a?(String)
|
89
|
+
|
90
|
+
handle_detail = proc do |detail|
|
91
|
+
return detail if detail.is_a?(String)
|
92
|
+
detail.fetch('details', nil)
|
93
|
+
end
|
94
|
+
|
95
|
+
inner_details = details['errors'].map { |detail| handle_detail[detail] }.reject(&:nil?)
|
96
|
+
inner_details.join("\n\t")
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
# 401
|
101
|
+
class Unauthorized < Error
|
102
|
+
protected
|
103
|
+
|
104
|
+
def default_error_message
|
105
|
+
'The authorization token was invalid.'
|
106
|
+
end
|
52
107
|
end
|
53
108
|
|
54
109
|
# 403
|
55
110
|
class AccessDenied < Error
|
111
|
+
protected
|
112
|
+
|
113
|
+
def default_error_message
|
114
|
+
'The specified token does not have access to the requested resource.'
|
115
|
+
end
|
116
|
+
|
117
|
+
def handle_details(details)
|
118
|
+
"\n\tReasons:\n\t\t#{details['reasons'].join("\n\t\t")}"
|
119
|
+
end
|
56
120
|
end
|
57
121
|
|
58
|
-
#
|
59
|
-
class
|
122
|
+
# 404
|
123
|
+
class NotFound < Error
|
124
|
+
protected
|
125
|
+
|
126
|
+
def default_error_message
|
127
|
+
'The requested resource or endpoint could not be found.'
|
128
|
+
end
|
129
|
+
|
130
|
+
def handle_details(details)
|
131
|
+
return details if details.is_a?(String)
|
132
|
+
|
133
|
+
message = "The requested #{details['type']} could not be found."
|
134
|
+
|
135
|
+
resource_id = details.fetch('id', nil)
|
136
|
+
message += " ID: #{resource_id}." if resource_id
|
137
|
+
|
138
|
+
message
|
139
|
+
end
|
60
140
|
end
|
61
141
|
|
62
142
|
# 409
|
63
143
|
class Conflict < Error
|
144
|
+
protected
|
145
|
+
|
146
|
+
def default_error_message
|
147
|
+
'Version mismatch error. The version you specified was incorrect. This may be due to someone else editing the content.'
|
148
|
+
end
|
64
149
|
end
|
65
150
|
|
66
151
|
# 422
|
67
152
|
class UnprocessableEntity < Error
|
153
|
+
protected
|
154
|
+
|
155
|
+
def default_error_message
|
156
|
+
'The resource you sent in the body is invalid.'
|
157
|
+
end
|
158
|
+
|
159
|
+
def handle_error(error)
|
160
|
+
name = error['name']
|
161
|
+
path = error['path']
|
162
|
+
value = error['value']
|
163
|
+
|
164
|
+
"\t* Name: #{name} - Path: '#{path}' - Value: '#{value}'"
|
165
|
+
end
|
166
|
+
|
167
|
+
def handle_details(details)
|
168
|
+
errors = []
|
169
|
+
details['errors'].each do |error|
|
170
|
+
errors << handle_error(error)
|
171
|
+
end
|
172
|
+
|
173
|
+
"\n#{errors.join("\n")}"
|
174
|
+
end
|
68
175
|
end
|
69
176
|
|
70
177
|
# 429
|
71
178
|
class RateLimitExceeded < Error
|
179
|
+
# Rate Limit Reset Header Key
|
180
|
+
RATE_LIMIT_RESET_HEADER_KEY = 'x-contentful-ratelimit-reset'.freeze
|
181
|
+
|
182
|
+
def reset_time?
|
183
|
+
# rubocop:disable Style/DoubleNegation
|
184
|
+
!!reset_time
|
185
|
+
# rubocop:enable Style/DoubleNegation
|
186
|
+
end
|
187
|
+
|
188
|
+
# Time until next available request, in seconds.
|
189
|
+
def reset_time
|
190
|
+
@reset_time ||= @response.raw[RATE_LIMIT_RESET_HEADER_KEY]
|
191
|
+
end
|
192
|
+
|
193
|
+
protected
|
194
|
+
|
195
|
+
def additional_info?
|
196
|
+
reset_time?
|
197
|
+
end
|
198
|
+
|
199
|
+
def additional_info
|
200
|
+
["Time until reset (seconds): #{reset_time}"]
|
201
|
+
end
|
202
|
+
|
203
|
+
def default_error_message
|
204
|
+
'Rate limit exceeded. Too many requests.'
|
205
|
+
end
|
72
206
|
end
|
73
207
|
|
74
208
|
# 500
|
75
209
|
class ServerError < Error
|
210
|
+
protected
|
211
|
+
|
212
|
+
def default_error_message
|
213
|
+
'Internal server error.'
|
214
|
+
end
|
215
|
+
end
|
216
|
+
|
217
|
+
# 502
|
218
|
+
class BadGateway < Error
|
219
|
+
protected
|
220
|
+
|
221
|
+
def default_error_message
|
222
|
+
'The requested space is hibernated.'
|
223
|
+
end
|
76
224
|
end
|
77
225
|
|
78
226
|
# 503
|
79
227
|
class ServiceUnavailable < Error
|
228
|
+
protected
|
229
|
+
|
230
|
+
def default_error_message
|
231
|
+
'Service unavailable.'
|
232
|
+
end
|
80
233
|
end
|
81
234
|
|
82
235
|
# Raised when response is no valid json
|
83
236
|
class UnparsableJson < Error
|
237
|
+
protected
|
238
|
+
|
239
|
+
def default_error_message
|
240
|
+
@response.error_message
|
241
|
+
end
|
84
242
|
end
|
85
243
|
|
86
244
|
# Raised when response is not parsable as a Contentful::Management::Resource
|
@@ -41,6 +41,11 @@ module Contentful
|
|
41
41
|
end
|
42
42
|
end
|
43
43
|
|
44
|
+
# Returns the JSON body of the response
|
45
|
+
def load_json
|
46
|
+
MultiJson.load(unzip_response(raw))
|
47
|
+
end
|
48
|
+
|
44
49
|
private
|
45
50
|
|
46
51
|
def error_object?
|
@@ -87,10 +92,6 @@ module Contentful
|
|
87
92
|
UnparsableJson.new(self)
|
88
93
|
end
|
89
94
|
|
90
|
-
def load_json
|
91
|
-
MultiJson.load(unzip_response(raw))
|
92
|
-
end
|
93
|
-
|
94
95
|
def unzip_response(response)
|
95
96
|
parsed_response = response.to_s
|
96
97
|
if response.headers['Content-Encoding'].eql?('gzip')
|
@@ -0,0 +1,22 @@
|
|
1
|
+
{
|
2
|
+
"requestId": "044bb23356babe4f11a3f7f1e77c762a",
|
3
|
+
"message":"The resource you sent in the body is invalid.",
|
4
|
+
"details":{
|
5
|
+
"errors":[
|
6
|
+
{
|
7
|
+
"name":"taken",
|
8
|
+
"path":"display_code",
|
9
|
+
"value":"en-US"
|
10
|
+
},
|
11
|
+
{
|
12
|
+
"name":"fallback locale creates a loop",
|
13
|
+
"path":"fallback_code",
|
14
|
+
"value":"en-US"
|
15
|
+
}
|
16
|
+
]
|
17
|
+
},
|
18
|
+
"sys":{
|
19
|
+
"type":"Error",
|
20
|
+
"id":"ValidationFailed"
|
21
|
+
}
|
22
|
+
}
|
@@ -76,7 +76,12 @@ module Contentful
|
|
76
76
|
vcr('asset/find_not_found') do
|
77
77
|
result = subject.find(space_id, 'not_exist')
|
78
78
|
expect(result).to be_kind_of Contentful::Management::NotFound
|
79
|
-
|
79
|
+
message = [
|
80
|
+
"HTTP status code: 404 Not Found",
|
81
|
+
"Message: The resource could not be found.",
|
82
|
+
"Details: The requested Asset could not be found. ID: not_exist."
|
83
|
+
].join("\n")
|
84
|
+
expect(result.message).to eq message
|
80
85
|
end
|
81
86
|
end
|
82
87
|
end
|
@@ -86,7 +91,11 @@ module Contentful
|
|
86
91
|
vcr('asset/destroy_published') do
|
87
92
|
result = subject.find(space_id, 'r7o2iuDeSc4UmioOuoKq6').destroy
|
88
93
|
expect(result).to be_kind_of Contentful::Management::BadRequest
|
89
|
-
|
94
|
+
message = [
|
95
|
+
"HTTP status code: 400 Bad Request",
|
96
|
+
"Message: Cannot delete published"
|
97
|
+
].join("\n")
|
98
|
+
expect(result.message).to eq message
|
90
99
|
end
|
91
100
|
end
|
92
101
|
it 'returns true when asset is not published' do
|
@@ -112,7 +121,11 @@ module Contentful
|
|
112
121
|
vcr('asset/unpublish_already_unpublished') do
|
113
122
|
result = subject.find(space_id, asset_id_2).unpublish
|
114
123
|
expect(result).to be_kind_of Contentful::Management::BadRequest
|
115
|
-
|
124
|
+
message = [
|
125
|
+
"HTTP status code: 400 Bad Request",
|
126
|
+
"Message: Not published"
|
127
|
+
].join("\n")
|
128
|
+
expect(result.message).to eq message
|
116
129
|
end
|
117
130
|
end
|
118
131
|
end
|
@@ -63,7 +63,11 @@ module Contentful
|
|
63
63
|
vcr('content_type/destroy_activated') do
|
64
64
|
result = subject.find(space_id, '66jvD8UhNKmWGk24KKq0EW').destroy
|
65
65
|
expect(result).to be_kind_of Contentful::Management::BadRequest
|
66
|
-
|
66
|
+
message = [
|
67
|
+
"HTTP status code: 400 Bad Request",
|
68
|
+
"Message: Cannot delete published"
|
69
|
+
].join("\n")
|
70
|
+
expect(result.message).to eq message
|
67
71
|
end
|
68
72
|
end
|
69
73
|
|
@@ -129,7 +133,11 @@ module Contentful
|
|
129
133
|
content_type = subject.find(space_id, deactivate_content)
|
130
134
|
content_type.sys[:version] = -1
|
131
135
|
result = content_type.deactivate
|
132
|
-
|
136
|
+
message = [
|
137
|
+
"HTTP status code: 400 Bad Request",
|
138
|
+
"Message: Not published"
|
139
|
+
].join("\n")
|
140
|
+
expect(result.message).to eq message
|
133
141
|
end
|
134
142
|
end
|
135
143
|
end
|
@@ -122,7 +122,11 @@ module Contentful
|
|
122
122
|
vcr('entry/service_unavailable') do
|
123
123
|
result = subject.find(space_id, 'not_exist')
|
124
124
|
expect(result).to be_kind_of Contentful::Management::ServiceUnavailable
|
125
|
-
|
125
|
+
message = [
|
126
|
+
"HTTP status code: 503 Service Unavailable",
|
127
|
+
"Message: Service unavailable."
|
128
|
+
].join("\n")
|
129
|
+
expect(result.message).to eq message
|
126
130
|
end
|
127
131
|
end
|
128
132
|
end
|
@@ -132,7 +136,11 @@ module Contentful
|
|
132
136
|
vcr('entry/destory_published') do
|
133
137
|
result = subject.find(space_id, '3U7JqGuVzOWIimU40mKeem').destroy
|
134
138
|
expect(result).to be_kind_of Contentful::Management::BadRequest
|
135
|
-
|
139
|
+
message = [
|
140
|
+
"HTTP status code: 400 Bad Request",
|
141
|
+
"Message: Cannot deleted published"
|
142
|
+
].join("\n")
|
143
|
+
expect(result.message).to eq message
|
136
144
|
end
|
137
145
|
end
|
138
146
|
it 'returns true when entry is not published' do
|
@@ -158,7 +166,11 @@ module Contentful
|
|
158
166
|
vcr('entry/unpublish_already_unpublished') do
|
159
167
|
result = subject.find(space_id, entry_id).unpublish
|
160
168
|
expect(result).to be_kind_of Contentful::Management::BadRequest
|
161
|
-
|
169
|
+
message = [
|
170
|
+
"HTTP status code: 400 Bad Request",
|
171
|
+
"Message: Not published"
|
172
|
+
].join("\n")
|
173
|
+
expect(result.message).to eq message
|
162
174
|
expect(result.error[:message]).to eq 'Not published'
|
163
175
|
expect(result.error[:url]).to eq 'spaces/yr5m0jky5hsh/entries/4Rouux8SoUCKwkyCq2I0E0/published'
|
164
176
|
expect(result.error[:details]).to eq "{\n \"sys\": {\n \"type\": \"Error\",\n \"id\": \"BadRequest\"\n },\n \"message\": \"Not published\"\n}\n"
|
@@ -224,7 +236,11 @@ module Contentful
|
|
224
236
|
vcr('entry/unarchive_already_unarchived') do
|
225
237
|
result = subject.find(space_id, entry_id).unarchive
|
226
238
|
expect(result).to be_kind_of Contentful::Management::BadRequest
|
227
|
-
|
239
|
+
message = [
|
240
|
+
"HTTP status code: 400 Bad Request",
|
241
|
+
"Message: Not archived"
|
242
|
+
].join("\n")
|
243
|
+
expect(result.message).to eq message
|
228
244
|
end
|
229
245
|
end
|
230
246
|
end
|
@@ -243,7 +259,11 @@ module Contentful
|
|
243
259
|
vcr('entry/archive_published') do
|
244
260
|
entry = subject.find(space_id, entry_id).archive
|
245
261
|
expect(entry).to be_kind_of Contentful::Management::BadRequest
|
246
|
-
|
262
|
+
message = [
|
263
|
+
"HTTP status code: 400 Bad Request",
|
264
|
+
"Message: Cannot archive published"
|
265
|
+
].join("\n")
|
266
|
+
expect(entry.message).to eq message
|
247
267
|
end
|
248
268
|
end
|
249
269
|
end
|
@@ -0,0 +1,369 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
class MockRequest
|
4
|
+
def endpoint; end
|
5
|
+
end
|
6
|
+
|
7
|
+
describe Contentful::Management::Error do
|
8
|
+
let(:r) { Contentful::Management::Response.new raw_fixture('not_found', 404), MockRequest.new }
|
9
|
+
|
10
|
+
describe '#response' do
|
11
|
+
it 'returns the response the error has been initialized with' do
|
12
|
+
expect(Contentful::Management::Error.new(r).response).to be r
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
describe '#message' do
|
17
|
+
it 'returns the message found in the response json' do
|
18
|
+
message = "HTTP status code: 404\n"\
|
19
|
+
"Message: The resource could not be found.\n"\
|
20
|
+
"Details: {\"type\"=>\"Entry\", \"space\"=>\"cfexampleapi\", \"id\"=>\"not found\"}\n"\
|
21
|
+
"Request ID: 85f-351076632"
|
22
|
+
expect(Contentful::Management::Error.new(r).message).not_to be_nil
|
23
|
+
expect(Contentful::Management::Error.new(r).message).to eq message
|
24
|
+
end
|
25
|
+
|
26
|
+
describe 'message types' do
|
27
|
+
describe 'default messages' do
|
28
|
+
it '400' do
|
29
|
+
response = Contentful::Management::Response.new raw_fixture('default_400', 400), MockRequest.new
|
30
|
+
error = Contentful::Management::Error[response.raw.status].new(response)
|
31
|
+
|
32
|
+
message = "HTTP status code: 400\n"\
|
33
|
+
"Message: The request was malformed or missing a required parameter.\n"\
|
34
|
+
"Request ID: 85f-351076632"
|
35
|
+
expect(error.message).to eq message
|
36
|
+
end
|
37
|
+
|
38
|
+
it '401' do
|
39
|
+
response = Contentful::Management::Response.new raw_fixture('default_401', 401), MockRequest.new
|
40
|
+
error = Contentful::Management::Error[response.raw.status].new(response)
|
41
|
+
|
42
|
+
message = "HTTP status code: 401\n"\
|
43
|
+
"Message: The authorization token was invalid.\n"\
|
44
|
+
"Request ID: 85f-351076632"
|
45
|
+
expect(error.message).to eq message
|
46
|
+
end
|
47
|
+
|
48
|
+
it '403' do
|
49
|
+
response = Contentful::Management::Response.new raw_fixture('default_403', 403), MockRequest.new
|
50
|
+
error = Contentful::Management::Error[response.raw.status].new(response)
|
51
|
+
|
52
|
+
message = "HTTP status code: 403\n"\
|
53
|
+
"Message: The specified token does not have access to the requested resource.\n"\
|
54
|
+
"Request ID: 85f-351076632"
|
55
|
+
expect(error.message).to eq message
|
56
|
+
end
|
57
|
+
|
58
|
+
it '404' do
|
59
|
+
response = Contentful::Management::Response.new raw_fixture('default_404', 404), MockRequest.new
|
60
|
+
error = Contentful::Management::Error[response.raw.status].new(response)
|
61
|
+
|
62
|
+
message = "HTTP status code: 404\n"\
|
63
|
+
"Message: The requested resource or endpoint could not be found.\n"\
|
64
|
+
"Request ID: 85f-351076632"
|
65
|
+
expect(error.message).to eq message
|
66
|
+
end
|
67
|
+
|
68
|
+
it '409' do
|
69
|
+
response = Contentful::Management::Response.new raw_fixture('default_409', 409), MockRequest.new
|
70
|
+
error = Contentful::Management::Error[response.raw.status].new(response)
|
71
|
+
|
72
|
+
message = "HTTP status code: 409\n"\
|
73
|
+
"Message: Version mismatch error. The version you specified was incorrect. This may be due to someone else editing the content.\n"\
|
74
|
+
"Request ID: 85f-351076632"
|
75
|
+
expect(error.message).to eq message
|
76
|
+
end
|
77
|
+
|
78
|
+
it '422' do
|
79
|
+
response = Contentful::Management::Response.new raw_fixture('default_422', 422), MockRequest.new
|
80
|
+
error = Contentful::Management::Error[response.raw.status].new(response)
|
81
|
+
|
82
|
+
message = "HTTP status code: 422\n"\
|
83
|
+
"Message: The resource you sent in the body is invalid.\n"\
|
84
|
+
"Request ID: 85f-351076632"
|
85
|
+
expect(error.message).to eq message
|
86
|
+
end
|
87
|
+
|
88
|
+
it '429' do
|
89
|
+
response = Contentful::Management::Response.new raw_fixture('default_429', 429), MockRequest.new
|
90
|
+
error = Contentful::Management::Error[response.raw.status].new(response)
|
91
|
+
|
92
|
+
message = "HTTP status code: 429\n"\
|
93
|
+
"Message: Rate limit exceeded. Too many requests.\n"\
|
94
|
+
"Request ID: 85f-351076632"
|
95
|
+
expect(error.message).to eq message
|
96
|
+
end
|
97
|
+
|
98
|
+
it '500' do
|
99
|
+
response = Contentful::Management::Response.new raw_fixture('default_500', 500), MockRequest.new
|
100
|
+
error = Contentful::Management::Error[response.raw.status].new(response)
|
101
|
+
|
102
|
+
message = "HTTP status code: 500\n"\
|
103
|
+
"Message: Internal server error.\n"\
|
104
|
+
"Request ID: 85f-351076632"
|
105
|
+
expect(error.message).to eq message
|
106
|
+
end
|
107
|
+
|
108
|
+
it '502' do
|
109
|
+
response = Contentful::Management::Response.new raw_fixture('default_502', 502), MockRequest.new
|
110
|
+
error = Contentful::Management::Error[response.raw.status].new(response)
|
111
|
+
|
112
|
+
message = "HTTP status code: 502\n"\
|
113
|
+
"Message: The requested space is hibernated.\n"\
|
114
|
+
"Request ID: 85f-351076632"
|
115
|
+
expect(error.message).to eq message
|
116
|
+
end
|
117
|
+
|
118
|
+
it '503' do
|
119
|
+
response = Contentful::Management::Response.new raw_fixture('default_503', 503), MockRequest.new
|
120
|
+
error = Contentful::Management::Error[response.raw.status].new(response)
|
121
|
+
|
122
|
+
message = "HTTP status code: 503\n"\
|
123
|
+
"Message: Service unavailable.\n"\
|
124
|
+
"Request ID: 85f-351076632"
|
125
|
+
expect(error.message).to eq message
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
describe 'special cases' do
|
130
|
+
describe '400' do
|
131
|
+
it 'details is a string' do
|
132
|
+
response = Contentful::Management::Response.new raw_fixture('400_details_string', 400), MockRequest.new
|
133
|
+
error = Contentful::Management::Error[response.raw.status].new(response)
|
134
|
+
|
135
|
+
message = "HTTP status code: 400\n"\
|
136
|
+
"Message: The request was malformed or missing a required parameter.\n"\
|
137
|
+
"Details: some error\n"\
|
138
|
+
"Request ID: 85f-351076632"
|
139
|
+
expect(error.message).to eq message
|
140
|
+
end
|
141
|
+
|
142
|
+
it 'details is an object, internal errors are strings' do
|
143
|
+
response = Contentful::Management::Response.new raw_fixture('400_details_errors_string', 400), MockRequest.new
|
144
|
+
error = Contentful::Management::Error[response.raw.status].new(response)
|
145
|
+
|
146
|
+
message = "HTTP status code: 400\n"\
|
147
|
+
"Message: The request was malformed or missing a required parameter.\n"\
|
148
|
+
"Details: some error\n"\
|
149
|
+
"Request ID: 85f-351076632"
|
150
|
+
expect(error.message).to eq message
|
151
|
+
end
|
152
|
+
|
153
|
+
it 'details is an object, internal errors are objects which have details' do
|
154
|
+
response = Contentful::Management::Response.new raw_fixture('400_details_errors_object', 400), MockRequest.new
|
155
|
+
error = Contentful::Management::Error[response.raw.status].new(response)
|
156
|
+
|
157
|
+
message = "HTTP status code: 400\n"\
|
158
|
+
"Message: The request was malformed or missing a required parameter.\n"\
|
159
|
+
"Details: some error\n"\
|
160
|
+
"Request ID: 85f-351076632"
|
161
|
+
expect(error.message).to eq message
|
162
|
+
end
|
163
|
+
end
|
164
|
+
|
165
|
+
describe '403' do
|
166
|
+
it 'has an array of reasons' do
|
167
|
+
response = Contentful::Management::Response.new raw_fixture('403_reasons', 403), MockRequest.new
|
168
|
+
error = Contentful::Management::Error[response.raw.status].new(response)
|
169
|
+
|
170
|
+
message = "HTTP status code: 403\n"\
|
171
|
+
"Message: The specified token does not have access to the requested resource.\n"\
|
172
|
+
"Details: \n\tReasons:\n"\
|
173
|
+
"\t\tfoo\n"\
|
174
|
+
"\t\tbar\n"\
|
175
|
+
"Request ID: 85f-351076632"
|
176
|
+
expect(error.message).to eq message
|
177
|
+
end
|
178
|
+
end
|
179
|
+
|
180
|
+
describe '404' do
|
181
|
+
it 'details is a string' do
|
182
|
+
response = Contentful::Management::Response.new raw_fixture('404_details_string', 404), MockRequest.new
|
183
|
+
error = Contentful::Management::Error[response.raw.status].new(response)
|
184
|
+
|
185
|
+
message = "HTTP status code: 404\n"\
|
186
|
+
"Message: The requested resource or endpoint could not be found.\n"\
|
187
|
+
"Details: The resource could not be found\n"\
|
188
|
+
"Request ID: 85f-351076632"
|
189
|
+
expect(error.message).to eq message
|
190
|
+
end
|
191
|
+
|
192
|
+
it 'has a type' do
|
193
|
+
response = Contentful::Management::Response.new raw_fixture('404_type', 404), MockRequest.new
|
194
|
+
error = Contentful::Management::Error[response.raw.status].new(response)
|
195
|
+
|
196
|
+
message = "HTTP status code: 404\n"\
|
197
|
+
"Message: The requested resource or endpoint could not be found.\n"\
|
198
|
+
"Details: The requested Asset could not be found.\n"\
|
199
|
+
"Request ID: 85f-351076632"
|
200
|
+
expect(error.message).to eq message
|
201
|
+
end
|
202
|
+
|
203
|
+
it 'can specify the resource id' do
|
204
|
+
response = Contentful::Management::Response.new raw_fixture('404_id', 404), MockRequest.new
|
205
|
+
error = Contentful::Management::Error[response.raw.status].new(response)
|
206
|
+
|
207
|
+
message = "HTTP status code: 404\n"\
|
208
|
+
"Message: The requested resource or endpoint could not be found.\n"\
|
209
|
+
"Details: The requested Asset could not be found. ID: foobar.\n"\
|
210
|
+
"Request ID: 85f-351076632"
|
211
|
+
expect(error.message).to eq message
|
212
|
+
end
|
213
|
+
end
|
214
|
+
|
215
|
+
describe '422' do
|
216
|
+
it 'can show formatted details' do
|
217
|
+
response = Contentful::Management::Response.new raw_fixture('422_details', 422), MockRequest.new
|
218
|
+
error = Contentful::Management::Error[response.raw.status].new(response)
|
219
|
+
|
220
|
+
message = "HTTP status code: 422\n"\
|
221
|
+
"Message: The resource you sent in the body is invalid.\n"\
|
222
|
+
"Details: \n"\
|
223
|
+
"\t* Name: taken - Path: 'display_code' - Value: 'en-US'\n"\
|
224
|
+
"\t* Name: fallback locale creates a loop - Path: 'fallback_code' - Value: 'en-US'\n"\
|
225
|
+
"Request ID: 044bb23356babe4f11a3f7f1e77c762a"
|
226
|
+
expect(error.message).to eq message
|
227
|
+
end
|
228
|
+
end
|
229
|
+
|
230
|
+
describe '429' do
|
231
|
+
it 'can show the time until reset' do
|
232
|
+
response = Contentful::Management::Response.new raw_fixture('default_429', 429, false, {'x-contentful-ratelimit-reset' => 60}), MockRequest.new
|
233
|
+
error = Contentful::Management::Error[response.raw.status].new(response)
|
234
|
+
|
235
|
+
message = "HTTP status code: 429\n"\
|
236
|
+
"Message: Rate limit exceeded. Too many requests.\n"\
|
237
|
+
"Request ID: 85f-351076632\n"\
|
238
|
+
"Time until reset (seconds): 60"
|
239
|
+
expect(error.message).to eq message
|
240
|
+
end
|
241
|
+
end
|
242
|
+
end
|
243
|
+
|
244
|
+
describe 'generic error' do
|
245
|
+
it 'with everything' do
|
246
|
+
response = Contentful::Management::Response.new raw_fixture('other_error', 512), MockRequest.new
|
247
|
+
error = Contentful::Management::Error[response.raw.status].new(response)
|
248
|
+
|
249
|
+
message = "HTTP status code: 512\n"\
|
250
|
+
"Message: Some error occurred.\n"\
|
251
|
+
"Details: some text\n"\
|
252
|
+
"Request ID: 85f-351076632"
|
253
|
+
expect(error.message).to eq message
|
254
|
+
end
|
255
|
+
|
256
|
+
it 'no details' do
|
257
|
+
response = Contentful::Management::Response.new raw_fixture('other_error_no_details', 512), MockRequest.new
|
258
|
+
error = Contentful::Management::Error[response.raw.status].new(response)
|
259
|
+
|
260
|
+
message = "HTTP status code: 512\n"\
|
261
|
+
"Message: Some error occurred.\n"\
|
262
|
+
"Request ID: 85f-351076632"
|
263
|
+
expect(error.message).to eq message
|
264
|
+
end
|
265
|
+
|
266
|
+
it 'no request id' do
|
267
|
+
response = Contentful::Management::Response.new raw_fixture('other_error_no_request_id', 512), MockRequest.new
|
268
|
+
error = Contentful::Management::Error[response.raw.status].new(response)
|
269
|
+
|
270
|
+
message = "HTTP status code: 512\n"\
|
271
|
+
"Message: Some error occurred.\n"\
|
272
|
+
"Details: some text"
|
273
|
+
expect(error.message).to eq message
|
274
|
+
end
|
275
|
+
|
276
|
+
it 'no message' do
|
277
|
+
response = Contentful::Management::Response.new raw_fixture('other_error_no_message', 512), MockRequest.new
|
278
|
+
error = Contentful::Management::Error[response.raw.status].new(response)
|
279
|
+
|
280
|
+
message = "HTTP status code: 512\n"\
|
281
|
+
"Message: The following error was received: {\n"\
|
282
|
+
" \"sys\": {\n"\
|
283
|
+
" \"type\": \"Error\",\n"\
|
284
|
+
" \"id\": \"SomeError\"\n"\
|
285
|
+
" },\n"\
|
286
|
+
" \"details\": \"some text\",\n"\
|
287
|
+
" \"requestId\": \"85f-351076632\"\n"\
|
288
|
+
"}\n"\
|
289
|
+
"\n"\
|
290
|
+
"Details: some text\n"\
|
291
|
+
"Request ID: 85f-351076632"
|
292
|
+
expect(error.message).to eq message
|
293
|
+
end
|
294
|
+
|
295
|
+
it 'nothing' do
|
296
|
+
response = Contentful::Management::Response.new raw_fixture('other_error_nothing', 512), MockRequest.new
|
297
|
+
error = Contentful::Management::Error[response.raw.status].new(response)
|
298
|
+
|
299
|
+
message = "HTTP status code: 512\n"\
|
300
|
+
"Message: The following error was received: {\n"\
|
301
|
+
" \"sys\": {\n"\
|
302
|
+
" \"type\": \"Error\",\n"\
|
303
|
+
" \"id\": \"SomeError\"\n"\
|
304
|
+
" }\n"\
|
305
|
+
"}\n"
|
306
|
+
expect(error.message).to eq message
|
307
|
+
end
|
308
|
+
end
|
309
|
+
end
|
310
|
+
end
|
311
|
+
|
312
|
+
describe Contentful::Management::UnparsableJson do
|
313
|
+
describe '#message' do
|
314
|
+
it 'returns the json parser\'s message' do
|
315
|
+
uj = Contentful::Management::Response.new raw_fixture('unparsable'), MockRequest.new
|
316
|
+
expect(Contentful::Management::UnparsableJson.new(uj).message).to \
|
317
|
+
include 'unexpected token'
|
318
|
+
end
|
319
|
+
end
|
320
|
+
end
|
321
|
+
|
322
|
+
describe '.[]' do
|
323
|
+
it 'returns BadRequest error class for 400' do
|
324
|
+
expect(Contentful::Management::Error[400]).to eq Contentful::Management::BadRequest
|
325
|
+
end
|
326
|
+
|
327
|
+
it 'returns Unauthorized error class for 401' do
|
328
|
+
expect(Contentful::Management::Error[401]).to eq Contentful::Management::Unauthorized
|
329
|
+
end
|
330
|
+
|
331
|
+
it 'returns AccessDenied error class for 403' do
|
332
|
+
expect(Contentful::Management::Error[403]).to eq Contentful::Management::AccessDenied
|
333
|
+
end
|
334
|
+
|
335
|
+
it 'returns NotFound error class for 404' do
|
336
|
+
expect(Contentful::Management::Error[404]).to eq Contentful::Management::NotFound
|
337
|
+
end
|
338
|
+
|
339
|
+
it 'returns Conflict error class for 409' do
|
340
|
+
expect(Contentful::Management::Error[409]).to eq Contentful::Management::Conflict
|
341
|
+
end
|
342
|
+
|
343
|
+
it 'returns UnprocessableEntity error class for 422' do
|
344
|
+
expect(Contentful::Management::Error[422]).to eq Contentful::Management::UnprocessableEntity
|
345
|
+
end
|
346
|
+
|
347
|
+
it 'returns RateLimitExceeded error class for 429' do
|
348
|
+
expect(Contentful::Management::Error[429]).to eq Contentful::Management::RateLimitExceeded
|
349
|
+
end
|
350
|
+
|
351
|
+
it 'returns ServerError error class for 500' do
|
352
|
+
expect(Contentful::Management::Error[500]).to eq Contentful::Management::ServerError
|
353
|
+
end
|
354
|
+
|
355
|
+
it 'returns BadGateway error class for 502' do
|
356
|
+
expect(Contentful::Management::Error[502]).to eq Contentful::Management::BadGateway
|
357
|
+
end
|
358
|
+
|
359
|
+
it 'returns ServiceUnavailable error class for 503' do
|
360
|
+
expect(Contentful::Management::Error[503]).to eq Contentful::Management::ServiceUnavailable
|
361
|
+
end
|
362
|
+
|
363
|
+
it 'returns generic error class for any other value' do
|
364
|
+
expect(Contentful::Management::Error[nil]).to eq Contentful::Management::Error
|
365
|
+
expect(Contentful::Management::Error[200]).to eq Contentful::Management::Error
|
366
|
+
end
|
367
|
+
end
|
368
|
+
end
|
369
|
+
|
@@ -0,0 +1,18 @@
|
|
1
|
+
require 'multi_json'
|
2
|
+
|
3
|
+
def raw_fixture(which, status = 200, _as_json = false, headers = {})
|
4
|
+
object = Object.new
|
5
|
+
allow(object).to receive(:status) { status }
|
6
|
+
allow(object).to receive(:headers) { headers }
|
7
|
+
allow(object).to receive(:to_s) { File.read File.dirname(__FILE__) + "/../fixtures/json_responses/#{which}.json" }
|
8
|
+
allow(object).to receive(:body) { object.to_s }
|
9
|
+
allow(object).to receive(:[]) { |key| object.headers[key] }
|
10
|
+
|
11
|
+
object
|
12
|
+
end
|
13
|
+
|
14
|
+
def json_fixture(which, _as_json = false)
|
15
|
+
MultiJson.load(
|
16
|
+
File.read File.dirname(__FILE__) + "/../fixtures/json_responses/#{which}.json"
|
17
|
+
)
|
18
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: contentful-management
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.10.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Piotr Protas
|
@@ -10,7 +10,7 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date: 2017-10-
|
13
|
+
date: 2017-10-30 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: http
|
@@ -375,6 +375,31 @@ files:
|
|
375
375
|
- lib/contentful/management/webhook_health.rb
|
376
376
|
- lib/contentful/management/webhook_webhook_call_methods_factory.rb
|
377
377
|
- lib/contentful/management/webhook_webhook_health_methods_factory.rb
|
378
|
+
- spec/fixtures/json_responses/400_details_errors_object.json
|
379
|
+
- spec/fixtures/json_responses/400_details_errors_string.json
|
380
|
+
- spec/fixtures/json_responses/400_details_string.json
|
381
|
+
- spec/fixtures/json_responses/403_reasons.json
|
382
|
+
- spec/fixtures/json_responses/404_details_string.json
|
383
|
+
- spec/fixtures/json_responses/404_id.json
|
384
|
+
- spec/fixtures/json_responses/404_type.json
|
385
|
+
- spec/fixtures/json_responses/422_details.json
|
386
|
+
- spec/fixtures/json_responses/default_400.json
|
387
|
+
- spec/fixtures/json_responses/default_401.json
|
388
|
+
- spec/fixtures/json_responses/default_403.json
|
389
|
+
- spec/fixtures/json_responses/default_404.json
|
390
|
+
- spec/fixtures/json_responses/default_409.json
|
391
|
+
- spec/fixtures/json_responses/default_422.json
|
392
|
+
- spec/fixtures/json_responses/default_429.json
|
393
|
+
- spec/fixtures/json_responses/default_500.json
|
394
|
+
- spec/fixtures/json_responses/default_502.json
|
395
|
+
- spec/fixtures/json_responses/default_503.json
|
396
|
+
- spec/fixtures/json_responses/not_found.json
|
397
|
+
- spec/fixtures/json_responses/other_error.json
|
398
|
+
- spec/fixtures/json_responses/other_error_no_details.json
|
399
|
+
- spec/fixtures/json_responses/other_error_no_message.json
|
400
|
+
- spec/fixtures/json_responses/other_error_no_request_id.json
|
401
|
+
- spec/fixtures/json_responses/other_error_nothing.json
|
402
|
+
- spec/fixtures/json_responses/unparsable.json
|
378
403
|
- spec/fixtures/pixel.jpg
|
379
404
|
- spec/fixtures/vcr_cassettes/api_key/all_for_space.yml
|
380
405
|
- spec/fixtures/vcr_cassettes/api_key/create_for_space.yml
|
@@ -676,6 +701,7 @@ files:
|
|
676
701
|
- spec/lib/contentful/management/content_type_spec.rb
|
677
702
|
- spec/lib/contentful/management/editor_interface_spec.rb
|
678
703
|
- spec/lib/contentful/management/entry_spec.rb
|
704
|
+
- spec/lib/contentful/management/error_class_spec.rb
|
679
705
|
- spec/lib/contentful/management/locale_spec.rb
|
680
706
|
- spec/lib/contentful/management/organization_spec.rb
|
681
707
|
- spec/lib/contentful/management/personal_access_token_spec.rb
|
@@ -690,6 +716,7 @@ files:
|
|
690
716
|
- spec/lib/contentful/management/webhook_health_spec.rb
|
691
717
|
- spec/lib/contentful/management/webhook_spec.rb
|
692
718
|
- spec/spec_helper.rb
|
719
|
+
- spec/support/json_responses.rb
|
693
720
|
- spec/support/vcr.rb
|
694
721
|
homepage: https://github.com/contentful/contentful-management.rb
|
695
722
|
licenses:
|
@@ -716,6 +743,31 @@ signing_key:
|
|
716
743
|
specification_version: 4
|
717
744
|
summary: contentful management api
|
718
745
|
test_files:
|
746
|
+
- spec/fixtures/json_responses/400_details_errors_object.json
|
747
|
+
- spec/fixtures/json_responses/400_details_errors_string.json
|
748
|
+
- spec/fixtures/json_responses/400_details_string.json
|
749
|
+
- spec/fixtures/json_responses/403_reasons.json
|
750
|
+
- spec/fixtures/json_responses/404_details_string.json
|
751
|
+
- spec/fixtures/json_responses/404_id.json
|
752
|
+
- spec/fixtures/json_responses/404_type.json
|
753
|
+
- spec/fixtures/json_responses/422_details.json
|
754
|
+
- spec/fixtures/json_responses/default_400.json
|
755
|
+
- spec/fixtures/json_responses/default_401.json
|
756
|
+
- spec/fixtures/json_responses/default_403.json
|
757
|
+
- spec/fixtures/json_responses/default_404.json
|
758
|
+
- spec/fixtures/json_responses/default_409.json
|
759
|
+
- spec/fixtures/json_responses/default_422.json
|
760
|
+
- spec/fixtures/json_responses/default_429.json
|
761
|
+
- spec/fixtures/json_responses/default_500.json
|
762
|
+
- spec/fixtures/json_responses/default_502.json
|
763
|
+
- spec/fixtures/json_responses/default_503.json
|
764
|
+
- spec/fixtures/json_responses/not_found.json
|
765
|
+
- spec/fixtures/json_responses/other_error.json
|
766
|
+
- spec/fixtures/json_responses/other_error_no_details.json
|
767
|
+
- spec/fixtures/json_responses/other_error_no_message.json
|
768
|
+
- spec/fixtures/json_responses/other_error_no_request_id.json
|
769
|
+
- spec/fixtures/json_responses/other_error_nothing.json
|
770
|
+
- spec/fixtures/json_responses/unparsable.json
|
719
771
|
- spec/fixtures/pixel.jpg
|
720
772
|
- spec/fixtures/vcr_cassettes/api_key/all_for_space.yml
|
721
773
|
- spec/fixtures/vcr_cassettes/api_key/create_for_space.yml
|
@@ -1017,6 +1069,7 @@ test_files:
|
|
1017
1069
|
- spec/lib/contentful/management/content_type_spec.rb
|
1018
1070
|
- spec/lib/contentful/management/editor_interface_spec.rb
|
1019
1071
|
- spec/lib/contentful/management/entry_spec.rb
|
1072
|
+
- spec/lib/contentful/management/error_class_spec.rb
|
1020
1073
|
- spec/lib/contentful/management/locale_spec.rb
|
1021
1074
|
- spec/lib/contentful/management/organization_spec.rb
|
1022
1075
|
- spec/lib/contentful/management/personal_access_token_spec.rb
|
@@ -1031,4 +1084,5 @@ test_files:
|
|
1031
1084
|
- spec/lib/contentful/management/webhook_health_spec.rb
|
1032
1085
|
- spec/lib/contentful/management/webhook_spec.rb
|
1033
1086
|
- spec/spec_helper.rb
|
1087
|
+
- spec/support/json_responses.rb
|
1034
1088
|
- spec/support/vcr.rb
|