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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 4969648cf9b578079bc4d7baca012aa82768fd37edc9279ed2be606ef11b78b4
4
- data.tar.gz: e426759bcab101a0ef02b0b9cc68d56d2cabc43fdea9a30027974dbaebf7a4e5
3
+ metadata.gz: d5495356a8fc2f5a5010cc8639e993a7c53ddf4bce282e7483c9c65368f7e913
4
+ data.tar.gz: dc31a2fb80a880d7d8228434d8364672bbca638c80ea5a1def52018d09f59e9c
5
5
  SHA512:
6
- metadata.gz: 8848cd9189e14cb2ac4ce22b401b2d5c4d5a39af868a38c1746a9e05136018bbf42b5e071f4feff680b823ab70fc9f3320c60fb0b4c982dfee23a2621781bc0a
7
- data.tar.gz: ed36e6cf227e30e6f37dbe8ca109ccfecda6f2747349a1c73e97cf7319af929785aeaa0ccb8ab08265d0524d58a39fbe6a3101f5e95cb1b39998879866f783d2
6
+ metadata.gz: 26105d0876fd07335e6eaed85c5b56318959bff5ecf8290fe1dcb1b6faca9971487cd7bf02295f2f093e0ae9cb91429cafd7af8d14cdc4a20b6ac2088b8a644a
7
+ data.tar.gz: 1e95b957ef01408897acba372e60532346ec0e51bcc9883c540b08f2b5276f9d8443e39c9cf699728634e3d626c8d735f6504c4a7afda2c416a9bc9066f2231f
data/README.md CHANGED
@@ -11,4 +11,4 @@ Azeroth
11
11
 
12
12
  Yard Documentation
13
13
  -------------------
14
- [https://www.rubydoc.info/gems/azeroth/0.2.0](https://www.rubydoc.info/gems/azeroth/0.2.0)
14
+ [https://www.rubydoc.info/gems/azeroth/0.3.0](https://www.rubydoc.info/gems/azeroth/0.3.0)
@@ -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 = ['dev@gmail.com']
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 = model.decorate(resource)
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
- resource = controller.send(model.name)
22
- resource.update(attributes)
23
- resource
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
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Azeroth
4
- VERSION = '0.2.0'
4
+ VERSION = '0.3.0'
5
5
  end
@@ -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 do
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) { Document.create }
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) { Document.create }
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
- .from(nil).to('My document')
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) { Document.create }
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) { Document.create }
311
+ let!(:document) { create(:document) }
259
312
  let(:document_id) { document.id }
260
313
 
261
314
  let(:expected_json) do
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  class Document < ActiveRecord::Base
4
+ validates :name, presence: true
4
5
  end
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Document
4
+ class DecoratorWithError < Azeroth::Decorator
5
+ expose :name
6
+ expose :errors, if: :invalid?
7
+
8
+ def errors
9
+ object.errors.messages
10
+ end
11
+ end
12
+ end
@@ -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
@@ -37,7 +37,7 @@ describe Azeroth::RequestHandler do
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
 
@@ -11,7 +11,7 @@ describe Azeroth::ResourceBuilder do
11
11
 
12
12
  before do
13
13
  resource_builder.append
14
- 10.times { Document.create }
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) { Document.create }
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.times { Document.create }
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.2.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: 2019-11-22 00:00:00.000000000 Z
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
- - dev@gmail.com
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