azeroth 0.2.0 → 0.3.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/README.md +1 -1
- data/azeroth.gemspec +1 -1
- data/lib/azeroth/request_handler.rb +17 -2
- data/lib/azeroth/request_handler/create.rb +16 -0
- data/lib/azeroth/request_handler/update.rb +20 -3
- data/lib/azeroth/version.rb +1 -1
- data/spec/controllers/documents_controller_spec.rb +67 -14
- data/spec/dummy/app/models/document.rb +1 -0
- data/spec/dummy/app/models/document/decorator_with_error.rb +12 -0
- data/spec/lib/azeroth/decorator_spec.rb +37 -0
- data/spec/lib/azeroth/request_handler/create_spec.rb +23 -1
- data/spec/lib/azeroth/request_handler/update_spec.rb +26 -1
- data/spec/lib/azeroth/request_handler_spec.rb +1 -1
- data/spec/lib/azeroth/resource_builder_spec.rb +2 -2
- data/spec/lib/azeroth/routes_builder_spec.rb +3 -3
- data/spec/support/shared_examples/request_handler.rb +2 -2
- metadata +5 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d5495356a8fc2f5a5010cc8639e993a7c53ddf4bce282e7483c9c65368f7e913
|
4
|
+
data.tar.gz: dc31a2fb80a880d7d8228434d8364672bbca638c80ea5a1def52018d09f59e9c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 26105d0876fd07335e6eaed85c5b56318959bff5ecf8290fe1dcb1b6faca9971487cd7bf02295f2f093e0ae9cb91429cafd7af8d14cdc4a20b6ac2088b8a644a
|
7
|
+
data.tar.gz: 1e95b957ef01408897acba372e60532346ec0e51bcc9883c540b08f2b5276f9d8443e39c9cf699728634e3d626c8d735f6504c4a7afda2c416a9bc9066f2231f
|
data/README.md
CHANGED
data/azeroth.gemspec
CHANGED
@@ -8,7 +8,7 @@ Gem::Specification.new do |gem|
|
|
8
8
|
gem.name = 'azeroth'
|
9
9
|
gem.version = Azeroth::VERSION
|
10
10
|
gem.authors = ['Darthjee']
|
11
|
-
gem.email = ['
|
11
|
+
gem.email = ['darthjee@gmail.com']
|
12
12
|
gem.summary = 'Azeroth'
|
13
13
|
gem.description = gem.description
|
14
14
|
gem.homepage = 'https://github.com/darthjee/azeroth'
|
@@ -34,10 +34,11 @@ module Azeroth
|
|
34
34
|
def process
|
35
35
|
return unless json?
|
36
36
|
|
37
|
-
json
|
37
|
+
json = model.decorate(resource)
|
38
|
+
response_status = status
|
38
39
|
|
39
40
|
controller.instance_eval do
|
40
|
-
render(json: json)
|
41
|
+
render(json: json, status: response_status)
|
41
42
|
end
|
42
43
|
end
|
43
44
|
|
@@ -89,5 +90,19 @@ module Azeroth
|
|
89
90
|
def resource
|
90
91
|
raise 'must be implemented in subclass'
|
91
92
|
end
|
93
|
+
|
94
|
+
# @private
|
95
|
+
#
|
96
|
+
# Response status
|
97
|
+
#
|
98
|
+
# For most requests, status is 200 (+:ok+)
|
99
|
+
#
|
100
|
+
# Must be implemented in subclasses that will handle
|
101
|
+
# status differently
|
102
|
+
#
|
103
|
+
# @return [Symbol]
|
104
|
+
def status
|
105
|
+
:ok
|
106
|
+
end
|
92
107
|
end
|
93
108
|
end
|
@@ -17,10 +17,26 @@ module Azeroth
|
|
17
17
|
#
|
18
18
|
# @return [Object]
|
19
19
|
def resource
|
20
|
+
@resource ||= build_resource
|
21
|
+
end
|
22
|
+
|
23
|
+
def build_resource
|
20
24
|
attributes = controller.send("#{model.name}_params")
|
21
25
|
collection = controller.send(model.plural)
|
22
26
|
collection.create(attributes)
|
23
27
|
end
|
28
|
+
|
29
|
+
# @private
|
30
|
+
#
|
31
|
+
# Response status
|
32
|
+
#
|
33
|
+
# For success, returns +:created+, for
|
34
|
+
# validation errors, it returns +:unprocessable_entity+
|
35
|
+
#
|
36
|
+
# @return [Symbol]
|
37
|
+
def status
|
38
|
+
resource.valid? ? :created : :unprocessable_entity
|
39
|
+
end
|
24
40
|
end
|
25
41
|
end
|
26
42
|
end
|
@@ -17,10 +17,27 @@ module Azeroth
|
|
17
17
|
#
|
18
18
|
# @return [Object]
|
19
19
|
def resource
|
20
|
+
@resource ||= update_resource
|
21
|
+
end
|
22
|
+
|
23
|
+
def update_resource
|
20
24
|
attributes = controller.send("#{model.name}_params")
|
21
|
-
|
22
|
-
|
23
|
-
|
25
|
+
|
26
|
+
controller.send(model.name).tap do |entry|
|
27
|
+
entry.update(attributes)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
# @private
|
32
|
+
#
|
33
|
+
# Response status
|
34
|
+
#
|
35
|
+
# For success, returns +:ok+, for
|
36
|
+
# validation errors, it returns +:unprocessable_entity+
|
37
|
+
#
|
38
|
+
# @return [Symbol]
|
39
|
+
def status
|
40
|
+
resource.valid? ? :ok : :unprocessable_entity
|
24
41
|
end
|
25
42
|
end
|
26
43
|
end
|
data/lib/azeroth/version.rb
CHANGED
@@ -10,9 +10,7 @@ describe DocumentsController do
|
|
10
10
|
describe 'GET index' do
|
11
11
|
let(:documents_count) { 0 }
|
12
12
|
let!(:documents) do
|
13
|
-
documents_count.times.map
|
14
|
-
Document.create
|
15
|
-
end
|
13
|
+
documents_count.times.map { create(:document) }
|
16
14
|
end
|
17
15
|
|
18
16
|
let(:expected_json) do
|
@@ -53,7 +51,7 @@ describe DocumentsController do
|
|
53
51
|
end
|
54
52
|
|
55
53
|
describe 'GET show' do
|
56
|
-
let(:document) {
|
54
|
+
let(:document) { create(:document) }
|
57
55
|
let(:document_id) { document.id }
|
58
56
|
|
59
57
|
let(:expected_json) do
|
@@ -99,12 +97,15 @@ describe DocumentsController do
|
|
99
97
|
end
|
100
98
|
|
101
99
|
describe 'POST create' do
|
100
|
+
let(:payload) do
|
101
|
+
{
|
102
|
+
name: 'My document'
|
103
|
+
}
|
104
|
+
end
|
102
105
|
let(:parameters) do
|
103
106
|
{
|
104
107
|
format: format,
|
105
|
-
document:
|
106
|
-
name: 'My document'
|
107
|
-
}
|
108
|
+
document: payload
|
108
109
|
}
|
109
110
|
end
|
110
111
|
|
@@ -130,23 +131,51 @@ describe DocumentsController do
|
|
130
131
|
.to change(Document, :count).by(1)
|
131
132
|
end
|
132
133
|
end
|
134
|
+
|
135
|
+
context 'when there is validation error' do
|
136
|
+
let(:format) { :json }
|
137
|
+
let(:payload) { { reference: 'x01' } }
|
138
|
+
|
139
|
+
let(:expected_json) do
|
140
|
+
Document::Decorator.new(Document.new(payload)).as_json
|
141
|
+
end
|
142
|
+
|
143
|
+
it do
|
144
|
+
post :create, params: parameters
|
145
|
+
expect(response).not_to be_successful
|
146
|
+
end
|
147
|
+
|
148
|
+
it 'returns created document json' do
|
149
|
+
post :create, params: parameters
|
150
|
+
expect(parsed_response).to eq(expected_json)
|
151
|
+
end
|
152
|
+
|
153
|
+
it do
|
154
|
+
expect { post :create, params: parameters }
|
155
|
+
.not_to change(Document, :count)
|
156
|
+
end
|
157
|
+
end
|
133
158
|
end
|
134
159
|
|
135
160
|
describe 'PATCH update' do
|
136
|
-
let(:document) {
|
161
|
+
let(:document) { create(:document) }
|
137
162
|
let(:document_id) { document.id }
|
138
163
|
|
139
164
|
let(:expected_json) do
|
140
165
|
Document::Decorator.new(Document.last).as_json
|
141
166
|
end
|
142
167
|
|
168
|
+
let(:payload) do
|
169
|
+
{
|
170
|
+
name: 'My document'
|
171
|
+
}
|
172
|
+
end
|
173
|
+
|
143
174
|
let(:parameters) do
|
144
175
|
{
|
145
176
|
id: document_id,
|
146
177
|
format: :json,
|
147
|
-
document:
|
148
|
-
name: 'My document'
|
149
|
-
}
|
178
|
+
document: payload
|
150
179
|
}
|
151
180
|
end
|
152
181
|
|
@@ -163,7 +192,7 @@ describe DocumentsController do
|
|
163
192
|
it do
|
164
193
|
expect { patch :update, params: parameters }
|
165
194
|
.to change { document.reload.name }
|
166
|
-
.
|
195
|
+
.to('My document')
|
167
196
|
end
|
168
197
|
|
169
198
|
context 'when calling on an inexistent id' do
|
@@ -180,6 +209,30 @@ describe DocumentsController do
|
|
180
209
|
expect(response.body).to eq('')
|
181
210
|
end
|
182
211
|
end
|
212
|
+
|
213
|
+
context 'when there is validation error' do
|
214
|
+
let(:format) { :json }
|
215
|
+
let(:payload) { { name: nil } }
|
216
|
+
|
217
|
+
let(:expected_json) do
|
218
|
+
{ 'name' => '' }
|
219
|
+
end
|
220
|
+
|
221
|
+
it do
|
222
|
+
post :create, params: parameters
|
223
|
+
expect(response).not_to be_successful
|
224
|
+
end
|
225
|
+
|
226
|
+
it 'returns created document json' do
|
227
|
+
post :create, params: parameters
|
228
|
+
expect(parsed_response).to eq(expected_json)
|
229
|
+
end
|
230
|
+
|
231
|
+
it 'does not update entry' do
|
232
|
+
expect { post :create, params: parameters }
|
233
|
+
.not_to(change { document.reload.name })
|
234
|
+
end
|
235
|
+
end
|
183
236
|
end
|
184
237
|
|
185
238
|
describe 'GET new' do
|
@@ -209,7 +262,7 @@ describe DocumentsController do
|
|
209
262
|
end
|
210
263
|
|
211
264
|
describe 'GET edit' do
|
212
|
-
let(:document) {
|
265
|
+
let(:document) { create(:document) }
|
213
266
|
let(:document_id) { document.id }
|
214
267
|
|
215
268
|
context 'when calling on format json' do
|
@@ -255,7 +308,7 @@ describe DocumentsController do
|
|
255
308
|
end
|
256
309
|
|
257
310
|
describe 'DELETE destroy' do
|
258
|
-
let!(:document) {
|
311
|
+
let!(:document) { create(:document) }
|
259
312
|
let(:document_id) { document.id }
|
260
313
|
|
261
314
|
let(:expected_json) do
|
@@ -112,6 +112,43 @@ describe Azeroth::Decorator do
|
|
112
112
|
expect(decorator.as_json).to eq(expected_json)
|
113
113
|
end
|
114
114
|
end
|
115
|
+
|
116
|
+
context 'with decotator for model with validation' do
|
117
|
+
subject(:decorator) do
|
118
|
+
Document::DecoratorWithError.new(object)
|
119
|
+
end
|
120
|
+
|
121
|
+
context 'with valid model' do
|
122
|
+
let(:object) { build(:document) }
|
123
|
+
|
124
|
+
let(:expected_json) do
|
125
|
+
{
|
126
|
+
name: object.name
|
127
|
+
}.stringify_keys
|
128
|
+
end
|
129
|
+
|
130
|
+
it 'returns meta data defined json' do
|
131
|
+
expect(decorator.as_json).to eq(expected_json)
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
context 'with invalid model' do
|
136
|
+
let(:object) { build(:document, name: nil) }
|
137
|
+
|
138
|
+
let(:expected_json) do
|
139
|
+
{
|
140
|
+
name: nil,
|
141
|
+
errors: {
|
142
|
+
name: ["can't be blank"]
|
143
|
+
}
|
144
|
+
}.stringify_keys
|
145
|
+
end
|
146
|
+
|
147
|
+
it 'returns meta data defined json' do
|
148
|
+
expect(decorator.as_json).to eq(expected_json)
|
149
|
+
end
|
150
|
+
end
|
151
|
+
end
|
115
152
|
end
|
116
153
|
|
117
154
|
describe '#method_missing' do
|
@@ -4,7 +4,7 @@ require 'spec_helper'
|
|
4
4
|
|
5
5
|
describe Azeroth::RequestHandler::Create do
|
6
6
|
describe '#process' do
|
7
|
-
it_behaves_like 'a request handler' do
|
7
|
+
it_behaves_like 'a request handler', status: :created do
|
8
8
|
let(:extra_params) do
|
9
9
|
{
|
10
10
|
document: {
|
@@ -24,4 +24,26 @@ describe Azeroth::RequestHandler::Create do
|
|
24
24
|
end
|
25
25
|
end
|
26
26
|
end
|
27
|
+
|
28
|
+
context 'when payload is invalid' do
|
29
|
+
it_behaves_like 'a request handler',
|
30
|
+
status: :unprocessable_entity do
|
31
|
+
let(:extra_params) do
|
32
|
+
{
|
33
|
+
document: {
|
34
|
+
reference: 'my_reference'
|
35
|
+
}
|
36
|
+
}
|
37
|
+
end
|
38
|
+
|
39
|
+
let(:expected_json) do
|
40
|
+
{ 'name' => nil }
|
41
|
+
end
|
42
|
+
|
43
|
+
it 'does not create entry' do
|
44
|
+
expect { handler.process }
|
45
|
+
.not_to change(Document, :count)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
27
49
|
end
|
@@ -4,9 +4,10 @@ require 'spec_helper'
|
|
4
4
|
|
5
5
|
describe Azeroth::RequestHandler::Update do
|
6
6
|
describe '#process' do
|
7
|
+
let!(:document) { create(:document) }
|
8
|
+
|
7
9
|
it_behaves_like 'a request handler' do
|
8
10
|
let(:expected_resource) { document }
|
9
|
-
let!(:document) { create(:document) }
|
10
11
|
|
11
12
|
let(:extra_params) do
|
12
13
|
{
|
@@ -28,5 +29,29 @@ describe Azeroth::RequestHandler::Update do
|
|
28
29
|
.to('New Name')
|
29
30
|
end
|
30
31
|
end
|
32
|
+
|
33
|
+
context 'when payload is invalid' do
|
34
|
+
it_behaves_like 'a request handler',
|
35
|
+
status: :unprocessable_entity do
|
36
|
+
let(:expected_resource) { document }
|
37
|
+
let(:extra_params) do
|
38
|
+
{
|
39
|
+
id: document.id,
|
40
|
+
document: {
|
41
|
+
name: nil
|
42
|
+
}
|
43
|
+
}
|
44
|
+
end
|
45
|
+
|
46
|
+
let(:expected_json) do
|
47
|
+
{ 'name' => nil }
|
48
|
+
end
|
49
|
+
|
50
|
+
it 'does not update entry' do
|
51
|
+
expect { handler.process }
|
52
|
+
.not_to(change { document.reload.name })
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
31
56
|
end
|
32
57
|
end
|
@@ -11,7 +11,7 @@ describe Azeroth::ResourceBuilder do
|
|
11
11
|
|
12
12
|
before do
|
13
13
|
resource_builder.append
|
14
|
-
10
|
14
|
+
create_list(:document, 10)
|
15
15
|
end
|
16
16
|
|
17
17
|
describe '#append' do
|
@@ -29,7 +29,7 @@ describe Azeroth::ResourceBuilder do
|
|
29
29
|
|
30
30
|
describe 'after the build' do
|
31
31
|
let(:controller) { klass.new(document_id: document.id) }
|
32
|
-
let(:document) {
|
32
|
+
let(:document) { create(:document) }
|
33
33
|
|
34
34
|
before { builder.build }
|
35
35
|
|
@@ -31,13 +31,13 @@ describe Azeroth::RoutesBuilder do
|
|
31
31
|
end
|
32
32
|
|
33
33
|
before do
|
34
|
-
10
|
34
|
+
create_list(:document, 10)
|
35
35
|
|
36
36
|
allow(controller).to receive(:params)
|
37
37
|
.and_return(params)
|
38
38
|
|
39
39
|
allow(controller).to receive(:render)
|
40
|
-
.with(json: expected_json)
|
40
|
+
.with(json: expected_json, status: :ok)
|
41
41
|
.and_return(expected_json)
|
42
42
|
end
|
43
43
|
|
@@ -61,7 +61,7 @@ describe Azeroth::RoutesBuilder do
|
|
61
61
|
controller.index
|
62
62
|
|
63
63
|
expect(controller).to have_received(:render)
|
64
|
-
.with(json: expected_json)
|
64
|
+
.with(json: expected_json, status: :ok)
|
65
65
|
end
|
66
66
|
end
|
67
67
|
end
|
@@ -1,6 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
shared_examples 'a request handler' do
|
3
|
+
shared_examples 'a request handler' do |status: :ok|
|
4
4
|
subject(:handler) { described_class.new(controller, model) }
|
5
5
|
|
6
6
|
let(:controller) { controller_class.new }
|
@@ -27,7 +27,7 @@ shared_examples 'a request handler' do
|
|
27
27
|
.and_return(params)
|
28
28
|
|
29
29
|
allow(controller).to receive(:render)
|
30
|
-
.with(json: expected_json)
|
30
|
+
.with(json: expected_json, status: status)
|
31
31
|
.and_return(expected_json)
|
32
32
|
end
|
33
33
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: azeroth
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Darthjee
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2020-01-17 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
@@ -376,7 +376,7 @@ dependencies:
|
|
376
376
|
version: 0.9.9
|
377
377
|
description: ''
|
378
378
|
email:
|
379
|
-
-
|
379
|
+
- darthjee@gmail.com
|
380
380
|
executables:
|
381
381
|
- test
|
382
382
|
extensions: []
|
@@ -439,6 +439,7 @@ files:
|
|
439
439
|
- spec/dummy/app/models/concerns/.keep
|
440
440
|
- spec/dummy/app/models/document.rb
|
441
441
|
- spec/dummy/app/models/document/decorator.rb
|
442
|
+
- spec/dummy/app/models/document/decorator_with_error.rb
|
442
443
|
- spec/dummy/app/models/dummy_model.rb
|
443
444
|
- spec/dummy/app/models/dummy_model/decorator.rb
|
444
445
|
- spec/dummy/app/models/user.rb
|
@@ -562,6 +563,7 @@ test_files:
|
|
562
563
|
- spec/dummy/app/models/concerns/.keep
|
563
564
|
- spec/dummy/app/models/document.rb
|
564
565
|
- spec/dummy/app/models/document/decorator.rb
|
566
|
+
- spec/dummy/app/models/document/decorator_with_error.rb
|
565
567
|
- spec/dummy/app/models/dummy_model.rb
|
566
568
|
- spec/dummy/app/models/dummy_model/decorator.rb
|
567
569
|
- spec/dummy/app/models/user.rb
|