azeroth 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.
- checksums.yaml +4 -4
- data/.circleci/config.yml +20 -6
- data/Dockerfile +1 -1
- data/README.md +2 -1
- data/azeroth.gemspec +1 -1
- data/config/yardstick.yml +1 -0
- data/lib/azeroth/controller_interface.rb +102 -0
- data/lib/azeroth/decorator/method_builder.rb +1 -1
- data/lib/azeroth/options.rb +8 -0
- data/lib/azeroth/request_handler/create.rb +2 -7
- data/lib/azeroth/request_handler/index.rb +34 -2
- data/lib/azeroth/request_handler/update.rb +21 -6
- data/lib/azeroth/request_handler.rb +16 -7
- data/lib/azeroth/resourceable/builder.rb +9 -0
- data/lib/azeroth/version.rb +1 -1
- data/lib/azeroth.rb +9 -8
- data/spec/controllers/paginated_documents_controller_spec.rb +49 -0
- data/spec/controllers/rendering_controller_spec.rb +57 -0
- data/spec/dummy/app/controllers/rendering_controller.rb +7 -0
- data/spec/dummy/app/views/rendering/index.html.erb +5 -0
- data/spec/dummy/app/views/rendering/show.html.erb +1 -0
- data/spec/dummy/config/routes.rb +1 -0
- data/spec/lib/azeroth/controller_interface_spec.rb +82 -0
- data/spec/lib/azeroth/request_handler/index_spec.rb +78 -3
- data/spec/lib/azeroth/request_handler/update_spec.rb +112 -0
- data/spec/lib/azeroth/request_handler_spec.rb +10 -0
- data/spec/support/app/controllers/request_handler_controller.rb +6 -0
- data/spec/support/shared_examples/request_handler.rb +5 -0
- metadata +15 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: fef3f6d11872a3a25c77900028239d743c809aa1aae8d59526df351a1c47e97c
|
4
|
+
data.tar.gz: ae58f2737c72e939067a86061dbc3ab20f1da0ef0d27615c753aacbebb0591d1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ed3b96c2b672b737239713899bfb8ef5546dd1e66d28327fb3a7a66540eede50e93f5e73a3890dcea0474eda4f4bceaaa6804da47a1ea174606430eac14afe93
|
7
|
+
data.tar.gz: ce7d30afc6594731f31aa0591c6747dd110db2f485557d51fffd14cb4f7199e1ab4ebbfb748109dc42da72bda1764de48bd25821461f1ddf15fc49c607a971be
|
data/.circleci/config.yml
CHANGED
@@ -7,8 +7,12 @@ workflows:
|
|
7
7
|
filters:
|
8
8
|
tags:
|
9
9
|
only: /.*/
|
10
|
+
- checks:
|
11
|
+
filters:
|
12
|
+
tags:
|
13
|
+
only: /.*/
|
10
14
|
- build-and-release:
|
11
|
-
requires: [test]
|
15
|
+
requires: [test, checks]
|
12
16
|
filters:
|
13
17
|
tags:
|
14
18
|
only: /\d+\.\d+\.\d+/
|
@@ -18,7 +22,7 @@ workflows:
|
|
18
22
|
jobs:
|
19
23
|
test:
|
20
24
|
docker:
|
21
|
-
- image: darthjee/circleci_rails_gems:0.
|
25
|
+
- image: darthjee/circleci_rails_gems:0.8.0
|
22
26
|
environment:
|
23
27
|
PROJECT: azeroth
|
24
28
|
steps:
|
@@ -32,12 +36,22 @@ jobs:
|
|
32
36
|
- run:
|
33
37
|
name: RSpec
|
34
38
|
command: bundle exec rspec
|
35
|
-
- run:
|
36
|
-
name: Rubocop
|
37
|
-
command: rubocop
|
38
39
|
- run:
|
39
40
|
name: Coverage Test Report
|
40
41
|
command: cc-test-reporter after-build --exit-code $?
|
42
|
+
checks:
|
43
|
+
docker:
|
44
|
+
- image: darthjee/circleci_rails_gems:0.8.0
|
45
|
+
environment:
|
46
|
+
PROJECT: azeroth
|
47
|
+
steps:
|
48
|
+
- checkout
|
49
|
+
- run:
|
50
|
+
name: Bundle Install
|
51
|
+
command: bundle install
|
52
|
+
- run:
|
53
|
+
name: Rubocop
|
54
|
+
command: rubocop
|
41
55
|
- run:
|
42
56
|
name: Yardstick coverage check
|
43
57
|
command: bundle exec rake verify_measurements
|
@@ -52,7 +66,7 @@ jobs:
|
|
52
66
|
command: check_specs
|
53
67
|
build-and-release:
|
54
68
|
docker:
|
55
|
-
- image: darthjee/circleci_rails_gems:0.
|
69
|
+
- image: darthjee/circleci_rails_gems:0.8.0
|
56
70
|
environment:
|
57
71
|
PROJECT: azeroth
|
58
72
|
steps:
|
data/Dockerfile
CHANGED
data/README.md
CHANGED
@@ -11,7 +11,7 @@ Azeroth
|
|
11
11
|
|
12
12
|
Yard Documentation
|
13
13
|
-------------------
|
14
|
-
[https://www.rubydoc.info/gems/azeroth/0.
|
14
|
+
[https://www.rubydoc.info/gems/azeroth/0.9.0](https://www.rubydoc.info/gems/azeroth/0.9.0)
|
15
15
|
|
16
16
|
Azeroth has been designed making the coding of controllers easier
|
17
17
|
as routes in controllers are usually copy, paste and replace of same
|
@@ -61,6 +61,7 @@ It accepts options
|
|
61
61
|
- before_save: Method/Proc to be ran before saving the resource on create or update
|
62
62
|
- after_save: Method/Proc to be ran after saving the resource on create or update
|
63
63
|
- build_with: Method/Block to be ran when building the reource on create
|
64
|
+
- update_with: Method/Block to be ran when updating the reource on update
|
64
65
|
- paginated: Flag when pagination should be applied
|
65
66
|
- per_page: Number of items returned when pagination is active
|
66
67
|
|
data/azeroth.gemspec
CHANGED
@@ -27,7 +27,7 @@ Gem::Specification.new do |gem|
|
|
27
27
|
gem.add_development_dependency 'activerecord', '~> 5.2.x'
|
28
28
|
gem.add_development_dependency 'bundler', '1.16.1'
|
29
29
|
gem.add_development_dependency 'factory_bot', '5.2.0'
|
30
|
-
gem.add_development_dependency 'nokogiri', '1.
|
30
|
+
gem.add_development_dependency 'nokogiri', '1.12.5'
|
31
31
|
gem.add_development_dependency 'pry', '0.12.2'
|
32
32
|
gem.add_development_dependency 'pry-nav', '0.3.0'
|
33
33
|
gem.add_development_dependency 'rails', '~> 5.2.x'
|
data/config/yardstick.yml
CHANGED
@@ -0,0 +1,102 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Azeroth
|
4
|
+
# @api private
|
5
|
+
#
|
6
|
+
# Interface for using the controller
|
7
|
+
class ControllerInterface
|
8
|
+
# @param controller [ApplicationController]
|
9
|
+
def initialize(controller)
|
10
|
+
@controller = controller
|
11
|
+
end
|
12
|
+
|
13
|
+
# Set response headers
|
14
|
+
#
|
15
|
+
# @param headers_hash [Hash] headers to be set
|
16
|
+
#
|
17
|
+
# @return [Hash]
|
18
|
+
def add_headers(headers_hash)
|
19
|
+
controller.instance_eval do
|
20
|
+
headers_hash.each do |key, value|
|
21
|
+
headers[key.to_s] = value
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
# Renders response json
|
27
|
+
#
|
28
|
+
# @return [String]
|
29
|
+
def render_json(json, status)
|
30
|
+
controller.instance_eval do
|
31
|
+
render(json: json, status: status)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
# Set a variable in the controller
|
36
|
+
#
|
37
|
+
# @param variable [String,Symbol] variable name
|
38
|
+
# @param value [Object] value to be set
|
39
|
+
#
|
40
|
+
# @return [Object]
|
41
|
+
def set(variable, value)
|
42
|
+
controller.instance_variable_set("@#{variable}", value)
|
43
|
+
end
|
44
|
+
|
45
|
+
# Forces a controller to run a block
|
46
|
+
#
|
47
|
+
# When the block is a +Proc+ that is evaluated,
|
48
|
+
# when it is a +Symbol+ or +String+, a method is called
|
49
|
+
#
|
50
|
+
# @return [Object] whatever the block returns
|
51
|
+
def run(block)
|
52
|
+
case block
|
53
|
+
when Proc
|
54
|
+
controller.instance_eval(&block)
|
55
|
+
else
|
56
|
+
controller.send(block)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
private
|
61
|
+
|
62
|
+
attr_reader :controller
|
63
|
+
# @method controller
|
64
|
+
# @private
|
65
|
+
# @api private
|
66
|
+
#
|
67
|
+
# Controller where methods will be called
|
68
|
+
#
|
69
|
+
# @return [ApplicationController]
|
70
|
+
|
71
|
+
# @private
|
72
|
+
#
|
73
|
+
# Dispatcher to delegate all methods call to controller
|
74
|
+
#
|
75
|
+
# @param method_name [Symbol] name of the method
|
76
|
+
# called
|
77
|
+
# @param args [Array<Object>] arguments of the
|
78
|
+
# method called
|
79
|
+
#
|
80
|
+
# @return [Object]
|
81
|
+
def method_missing(method_name, *args)
|
82
|
+
if controller.respond_to?(method_name, true)
|
83
|
+
controller.send(method_name, *args)
|
84
|
+
else
|
85
|
+
super
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
# @private
|
90
|
+
#
|
91
|
+
# Checks if a controller responds to a method
|
92
|
+
#
|
93
|
+
# @param method_name [Symbol] name of the method checked
|
94
|
+
# @param include_private [TrueClass,FalseClass] flag
|
95
|
+
# indicating if private methods should be included
|
96
|
+
#
|
97
|
+
# @return [TrueClass,FalseClass]
|
98
|
+
def respond_to_missing?(method_name, include_private)
|
99
|
+
controller.respond_to?(method_name, include_private)
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
data/lib/azeroth/options.rb
CHANGED
@@ -21,6 +21,7 @@ module Azeroth
|
|
21
21
|
before_save: nil,
|
22
22
|
after_save: nil,
|
23
23
|
build_with: nil,
|
24
|
+
update_with: nil,
|
24
25
|
paginated: false,
|
25
26
|
per_page: 20
|
26
27
|
}.freeze
|
@@ -110,6 +111,13 @@ module Azeroth
|
|
110
111
|
#
|
111
112
|
# @return [Symbol,Proc]
|
112
113
|
|
114
|
+
# @method update_with
|
115
|
+
# @api private
|
116
|
+
#
|
117
|
+
# Block or method name to be ran when updating the resource
|
118
|
+
#
|
119
|
+
# @return [Symbol,Proc]
|
120
|
+
|
113
121
|
# @method paginated
|
114
122
|
# @api private
|
115
123
|
#
|
@@ -29,7 +29,7 @@ module Azeroth
|
|
29
29
|
# @return [Object]
|
30
30
|
def build_and_save_resource
|
31
31
|
@resource = build_resource
|
32
|
-
controller.
|
32
|
+
controller.set(model.name, resource)
|
33
33
|
|
34
34
|
trigger_event(:save) do
|
35
35
|
resource.tap(&:save)
|
@@ -47,12 +47,7 @@ module Azeroth
|
|
47
47
|
def build_resource
|
48
48
|
return collection.build(attributes) unless build_with
|
49
49
|
|
50
|
-
|
51
|
-
when Proc
|
52
|
-
controller.instance_eval(&build_with)
|
53
|
-
else
|
54
|
-
controller.send(build_with)
|
55
|
-
end
|
50
|
+
controller.run(build_with)
|
56
51
|
end
|
57
52
|
|
58
53
|
# @private
|
@@ -21,6 +21,21 @@ module Azeroth
|
|
21
21
|
paginated_entries
|
22
22
|
end
|
23
23
|
|
24
|
+
# @private
|
25
|
+
#
|
26
|
+
# returns pagination headers
|
27
|
+
#
|
28
|
+
# @return [Hash] heders
|
29
|
+
def headers
|
30
|
+
return {} unless paginated?
|
31
|
+
|
32
|
+
{
|
33
|
+
pages: pages,
|
34
|
+
page: current_page,
|
35
|
+
per_page: limit
|
36
|
+
}
|
37
|
+
end
|
38
|
+
|
24
39
|
# @private
|
25
40
|
#
|
26
41
|
# paginated collection of the model
|
@@ -39,8 +54,7 @@ module Azeroth
|
|
39
54
|
#
|
40
55
|
# @return [Integer]
|
41
56
|
def offset
|
42
|
-
|
43
|
-
page * limit
|
57
|
+
(current_page - 1) * limit
|
44
58
|
end
|
45
59
|
|
46
60
|
# @private
|
@@ -62,6 +76,24 @@ module Azeroth
|
|
62
76
|
def scoped_entries
|
63
77
|
controller.send(model.plural)
|
64
78
|
end
|
79
|
+
|
80
|
+
# @private
|
81
|
+
#
|
82
|
+
# calculates current page
|
83
|
+
#
|
84
|
+
# @return [Integer]
|
85
|
+
def current_page
|
86
|
+
(params[:page] || 1).to_i
|
87
|
+
end
|
88
|
+
|
89
|
+
# @private
|
90
|
+
#
|
91
|
+
# calculates how many pages are there
|
92
|
+
#
|
93
|
+
# @return [Integer]
|
94
|
+
def pages
|
95
|
+
(scoped_entries.count.to_f / limit).ceil
|
96
|
+
end
|
65
97
|
end
|
66
98
|
end
|
67
99
|
end
|
@@ -8,6 +8,8 @@ module Azeroth
|
|
8
8
|
class Update < RequestHandler
|
9
9
|
private
|
10
10
|
|
11
|
+
delegate :update_with, to: :options
|
12
|
+
|
11
13
|
# @private
|
12
14
|
#
|
13
15
|
# Updates and return an instance of the model
|
@@ -17,20 +19,33 @@ module Azeroth
|
|
17
19
|
#
|
18
20
|
# @return [Object]
|
19
21
|
def resource
|
20
|
-
@resource ||=
|
22
|
+
@resource ||= perform_update
|
21
23
|
end
|
22
24
|
|
23
|
-
#
|
25
|
+
# Update a resource saving it to the database
|
24
26
|
#
|
25
|
-
# @return [Object]
|
26
|
-
def
|
27
|
-
controller.send(model.name)
|
27
|
+
# @return [Object] updated resource
|
28
|
+
def perform_update
|
29
|
+
@resource = controller.send(model.name)
|
30
|
+
resource.tap do
|
28
31
|
trigger_event(:save) do
|
29
|
-
|
32
|
+
update_and_save_resource
|
30
33
|
end
|
31
34
|
end
|
32
35
|
end
|
33
36
|
|
37
|
+
# @private
|
38
|
+
#
|
39
|
+
# Update the resource, either by running update_with
|
40
|
+
# or directly updating the attributes in the object
|
41
|
+
#
|
42
|
+
# @return [Object] updated resource
|
43
|
+
def update_and_save_resource
|
44
|
+
return resource.update(attributes) unless update_with
|
45
|
+
|
46
|
+
controller.run(update_with)
|
47
|
+
end
|
48
|
+
|
34
49
|
# @private
|
35
50
|
#
|
36
51
|
# Response status
|
@@ -19,7 +19,7 @@ module Azeroth
|
|
19
19
|
# @param controller [ApplicationController]
|
20
20
|
# @param model [Azeroth::Model]
|
21
21
|
def initialize(controller, model, options)
|
22
|
-
@controller = controller
|
22
|
+
@controller = ControllerInterface.new(controller)
|
23
23
|
@model = model
|
24
24
|
@options = options
|
25
25
|
end
|
@@ -35,12 +35,11 @@ module Azeroth
|
|
35
35
|
def process
|
36
36
|
return unless json?
|
37
37
|
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
end
|
38
|
+
controller.add_headers(headers)
|
39
|
+
controller.render_json(
|
40
|
+
model.decorate(resource),
|
41
|
+
status
|
42
|
+
)
|
44
43
|
end
|
45
44
|
|
46
45
|
private
|
@@ -141,5 +140,15 @@ module Azeroth
|
|
141
140
|
def collection
|
142
141
|
@collection = controller.send(model.plural)
|
143
142
|
end
|
143
|
+
|
144
|
+
# @private
|
145
|
+
# @abstract
|
146
|
+
#
|
147
|
+
# Headers to be added
|
148
|
+
#
|
149
|
+
# @return [Hash]
|
150
|
+
def headers
|
151
|
+
{}
|
152
|
+
end
|
144
153
|
end
|
145
154
|
end
|
@@ -25,6 +25,7 @@ module Azeroth
|
|
25
25
|
add_params
|
26
26
|
add_resource
|
27
27
|
add_routes
|
28
|
+
add_helpers
|
28
29
|
end
|
29
30
|
|
30
31
|
private
|
@@ -127,6 +128,14 @@ module Azeroth
|
|
127
128
|
RoutesBuilder.new(model, builder, options).append
|
128
129
|
end
|
129
130
|
|
131
|
+
# Add helpers to render objects on template
|
132
|
+
#
|
133
|
+
# @return [String]
|
134
|
+
def add_helpers
|
135
|
+
clazz.public_send(:helper_method, model.name)
|
136
|
+
clazz.public_send(:helper_method, model.plural)
|
137
|
+
end
|
138
|
+
|
130
139
|
# Returns all updatable attributes
|
131
140
|
#
|
132
141
|
# @return [Array<String>]
|
data/lib/azeroth/version.rb
CHANGED
data/lib/azeroth.rb
CHANGED
@@ -11,12 +11,13 @@ require 'jace'
|
|
11
11
|
#
|
12
12
|
# @see Resourceable
|
13
13
|
module Azeroth
|
14
|
-
autoload :
|
15
|
-
autoload :
|
16
|
-
autoload :
|
17
|
-
autoload :
|
18
|
-
autoload :
|
19
|
-
autoload :
|
20
|
-
autoload :
|
21
|
-
autoload :
|
14
|
+
autoload :ControllerInterface, 'azeroth/controller_interface'
|
15
|
+
autoload :Decorator, 'azeroth/decorator'
|
16
|
+
autoload :DummyDecorator, 'azeroth/dummy_decorator'
|
17
|
+
autoload :Model, 'azeroth/model'
|
18
|
+
autoload :RequestHandler, 'azeroth/request_handler'
|
19
|
+
autoload :Resourceable, 'azeroth/resourceable'
|
20
|
+
autoload :ResourceBuilder, 'azeroth/resource_builder'
|
21
|
+
autoload :RoutesBuilder, 'azeroth/routes_builder'
|
22
|
+
autoload :Options, 'azeroth/options'
|
22
23
|
end
|
@@ -38,6 +38,18 @@ describe PaginatedDocumentsController do
|
|
38
38
|
it 'renders documents json' do
|
39
39
|
expect(parsed_response).to eq(expected_json)
|
40
40
|
end
|
41
|
+
|
42
|
+
it 'adds total pages header' do
|
43
|
+
expect(response.headers['pages']).to eq(1)
|
44
|
+
end
|
45
|
+
|
46
|
+
it 'adds current page header' do
|
47
|
+
expect(response.headers['page']).to eq(1)
|
48
|
+
end
|
49
|
+
|
50
|
+
it 'adds per page header' do
|
51
|
+
expect(response.headers['per_page']).to eq(20)
|
52
|
+
end
|
41
53
|
end
|
42
54
|
|
43
55
|
context 'when there are more documents than expected pagination' do
|
@@ -54,6 +66,18 @@ describe PaginatedDocumentsController do
|
|
54
66
|
expect(parsed_response)
|
55
67
|
.to have(20).elements
|
56
68
|
end
|
69
|
+
|
70
|
+
it 'adds total pages header' do
|
71
|
+
expect(response.headers['pages']).to eq(2)
|
72
|
+
end
|
73
|
+
|
74
|
+
it 'adds current page header' do
|
75
|
+
expect(response.headers['page']).to eq(1)
|
76
|
+
end
|
77
|
+
|
78
|
+
it 'adds per page header' do
|
79
|
+
expect(response.headers['per_page']).to eq(20)
|
80
|
+
end
|
57
81
|
end
|
58
82
|
|
59
83
|
context 'when page is given' do
|
@@ -72,6 +96,18 @@ describe PaginatedDocumentsController do
|
|
72
96
|
.to have(documents_count - 20)
|
73
97
|
.elements
|
74
98
|
end
|
99
|
+
|
100
|
+
it 'adds total pages header' do
|
101
|
+
expect(response.headers['pages']).to eq(2)
|
102
|
+
end
|
103
|
+
|
104
|
+
it 'adds current page header' do
|
105
|
+
expect(response.headers['page']).to eq(2)
|
106
|
+
end
|
107
|
+
|
108
|
+
it 'adds per page header' do
|
109
|
+
expect(response.headers['per_page']).to eq(20)
|
110
|
+
end
|
75
111
|
end
|
76
112
|
|
77
113
|
context 'when per_page is given' do
|
@@ -91,6 +127,19 @@ describe PaginatedDocumentsController do
|
|
91
127
|
.to have(per_page)
|
92
128
|
.elements
|
93
129
|
end
|
130
|
+
|
131
|
+
it 'adds total pages header' do
|
132
|
+
expect(response.headers['pages'])
|
133
|
+
.to eq((documents_count.to_f / per_page).ceil)
|
134
|
+
end
|
135
|
+
|
136
|
+
it 'adds current page header' do
|
137
|
+
expect(response.headers['page']).to eq(1)
|
138
|
+
end
|
139
|
+
|
140
|
+
it 'adds per page header' do
|
141
|
+
expect(response.headers['per_page']).to eq(per_page)
|
142
|
+
end
|
94
143
|
end
|
95
144
|
end
|
96
145
|
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
describe RenderingController do
|
6
|
+
let(:parsed_response) do
|
7
|
+
JSON.parse(response.body)
|
8
|
+
end
|
9
|
+
|
10
|
+
describe 'GET index' do
|
11
|
+
render_views
|
12
|
+
|
13
|
+
let(:documents_count) { Random.rand(2..5) }
|
14
|
+
|
15
|
+
let(:expected_content) do
|
16
|
+
documents.map do |document|
|
17
|
+
"<li><strong>Name:</strong>#{document.name}</li>"
|
18
|
+
end.join("\n ")
|
19
|
+
end
|
20
|
+
|
21
|
+
let!(:documents) { create_list(:document, documents_count) }
|
22
|
+
|
23
|
+
context 'when calling on format html' do
|
24
|
+
before do
|
25
|
+
get :index, params: { format: :html }
|
26
|
+
end
|
27
|
+
|
28
|
+
it { expect(response).to be_successful }
|
29
|
+
|
30
|
+
it { expect(response).to render_template('rendering/index') }
|
31
|
+
|
32
|
+
it { expect(response.body).to include(expected_content) }
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
describe 'GET show' do
|
37
|
+
render_views
|
38
|
+
|
39
|
+
let(:document) { create(:document) }
|
40
|
+
let(:document_id) { document.id }
|
41
|
+
let(:expected_content) do
|
42
|
+
"<p><strong>Name:</strong>#{document.name}</p>"
|
43
|
+
end
|
44
|
+
|
45
|
+
context 'when calling on format html' do
|
46
|
+
before do
|
47
|
+
get :show, params: { id: document.id, format: :html }
|
48
|
+
end
|
49
|
+
|
50
|
+
it { expect(response).to be_successful }
|
51
|
+
|
52
|
+
it { expect(response).to render_template('rendering/show') }
|
53
|
+
|
54
|
+
it { expect(response.body).to include(expected_content) }
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
<p><strong>Name:</strong><%= document.name %></p>
|
data/spec/dummy/config/routes.rb
CHANGED
@@ -0,0 +1,82 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
describe Azeroth::ControllerInterface do
|
6
|
+
subject(:interface) { described_class.new(controller) }
|
7
|
+
|
8
|
+
let(:controller) { controller_class.new }
|
9
|
+
let(:controller_class) { RequestHandlerController }
|
10
|
+
|
11
|
+
describe '#add_headers' do
|
12
|
+
let(:controller_headers) do
|
13
|
+
{
|
14
|
+
'old_key': 100
|
15
|
+
}
|
16
|
+
end
|
17
|
+
|
18
|
+
let(:headers) do
|
19
|
+
{
|
20
|
+
key1: 10,
|
21
|
+
key2: 20
|
22
|
+
}
|
23
|
+
end
|
24
|
+
|
25
|
+
before do
|
26
|
+
allow(controller)
|
27
|
+
.to receive(:headers)
|
28
|
+
.and_return(controller_headers)
|
29
|
+
end
|
30
|
+
|
31
|
+
it 'sets controller headers' do
|
32
|
+
expect { interface.add_headers(headers) }
|
33
|
+
.to change { controller_headers }
|
34
|
+
.from(controller_headers)
|
35
|
+
.to(controller_headers.merge(headers.stringify_keys))
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
describe '#render_json' do
|
40
|
+
let(:json) { { key: 'value' } }
|
41
|
+
let(:status) { 200 }
|
42
|
+
|
43
|
+
before do
|
44
|
+
allow(controller)
|
45
|
+
.to receive(:render)
|
46
|
+
.with(json: json, status: status)
|
47
|
+
end
|
48
|
+
|
49
|
+
it 'renders json' do
|
50
|
+
interface.render_json(json, status)
|
51
|
+
|
52
|
+
expect(controller).to have_received(:render)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
describe '#set' do
|
57
|
+
it 'sets instance variable' do
|
58
|
+
expect { interface.set(:name, 20) }
|
59
|
+
.to change { controller.instance_variable_get('@name') }
|
60
|
+
.from(nil)
|
61
|
+
.to(20)
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
describe 'method missing' do
|
66
|
+
before do
|
67
|
+
create(:document)
|
68
|
+
end
|
69
|
+
|
70
|
+
it 'delegates call to controller' do
|
71
|
+
expect(interface.documents)
|
72
|
+
.to eq(Document.all)
|
73
|
+
end
|
74
|
+
|
75
|
+
context 'when method is not defined' do
|
76
|
+
it do
|
77
|
+
expect { interface.pokemons }
|
78
|
+
.to raise_error(NoMethodError)
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
@@ -14,6 +14,21 @@ describe Azeroth::RequestHandler::Index do
|
|
14
14
|
let(:documents_count) { Random.rand(21..30) }
|
15
15
|
let(:expected_resource) { Document.all.limit(20) }
|
16
16
|
let(:options_hash) { { paginated: true } }
|
17
|
+
|
18
|
+
it 'adds total pages header' do
|
19
|
+
handler.process
|
20
|
+
expect(controller_headers['pages']).to eq(2)
|
21
|
+
end
|
22
|
+
|
23
|
+
it 'adds current page header' do
|
24
|
+
handler.process
|
25
|
+
expect(controller_headers['page']).to eq(1)
|
26
|
+
end
|
27
|
+
|
28
|
+
it 'adds per page header' do
|
29
|
+
handler.process
|
30
|
+
expect(controller_headers['per_page']).to eq(20)
|
31
|
+
end
|
17
32
|
end
|
18
33
|
|
19
34
|
context 'when page is given' do
|
@@ -22,6 +37,21 @@ describe Azeroth::RequestHandler::Index do
|
|
22
37
|
let(:expected_resource) { Document.all.offset(20).limit(20) }
|
23
38
|
let(:options_hash) { { paginated: true } }
|
24
39
|
let(:extra_params) { { page: '2' } }
|
40
|
+
|
41
|
+
it 'adds total pages header' do
|
42
|
+
handler.process
|
43
|
+
expect(controller_headers['pages']).to eq(3)
|
44
|
+
end
|
45
|
+
|
46
|
+
it 'adds current page header' do
|
47
|
+
handler.process
|
48
|
+
expect(controller_headers['page']).to eq(2)
|
49
|
+
end
|
50
|
+
|
51
|
+
it 'adds per page header' do
|
52
|
+
handler.process
|
53
|
+
expect(controller_headers['per_page']).to eq(20)
|
54
|
+
end
|
25
55
|
end
|
26
56
|
end
|
27
57
|
|
@@ -31,6 +61,21 @@ describe Azeroth::RequestHandler::Index do
|
|
31
61
|
let(:expected_resource) { Document.all.offset(40) }
|
32
62
|
let(:options_hash) { { paginated: true } }
|
33
63
|
let(:extra_params) { { page: '3' } }
|
64
|
+
|
65
|
+
it 'adds total pages header' do
|
66
|
+
handler.process
|
67
|
+
expect(controller_headers['pages']).to eq(3)
|
68
|
+
end
|
69
|
+
|
70
|
+
it 'adds current page header' do
|
71
|
+
handler.process
|
72
|
+
expect(controller_headers['page']).to eq(3)
|
73
|
+
end
|
74
|
+
|
75
|
+
it 'adds per page header' do
|
76
|
+
handler.process
|
77
|
+
expect(controller_headers['per_page']).to eq(20)
|
78
|
+
end
|
34
79
|
end
|
35
80
|
end
|
36
81
|
|
@@ -39,15 +84,45 @@ describe Azeroth::RequestHandler::Index do
|
|
39
84
|
let(:documents_count) { Random.rand(21..30) }
|
40
85
|
let(:expected_resource) { Document.all.limit(10) }
|
41
86
|
let(:options_hash) { { paginated: true, per_page: 10 } }
|
87
|
+
|
88
|
+
it 'adds total pages header' do
|
89
|
+
handler.process
|
90
|
+
expect(controller_headers['pages']).to eq(3)
|
91
|
+
end
|
92
|
+
|
93
|
+
it 'adds current page header' do
|
94
|
+
handler.process
|
95
|
+
expect(controller_headers['page']).to eq(1)
|
96
|
+
end
|
97
|
+
|
98
|
+
it 'adds per page header' do
|
99
|
+
handler.process
|
100
|
+
expect(controller_headers['per_page']).to eq(10)
|
101
|
+
end
|
42
102
|
end
|
43
103
|
end
|
44
104
|
|
45
105
|
context 'when per page is given in params' do
|
46
106
|
it_behaves_like 'a request handler' do
|
47
107
|
let(:documents_count) { Random.rand(41..50) }
|
48
|
-
let(:expected_resource) { Document.all.offset(
|
49
|
-
let(:options_hash) { { paginated: true, per_page:
|
50
|
-
let(:extra_params) { { page: '2', per_page: '
|
108
|
+
let(:expected_resource) { Document.all.offset(10).limit(10) }
|
109
|
+
let(:options_hash) { { paginated: true, per_page: 15 } }
|
110
|
+
let(:extra_params) { { page: '2', per_page: '10' } }
|
111
|
+
|
112
|
+
it 'adds total pages header' do
|
113
|
+
handler.process
|
114
|
+
expect(controller_headers['pages']).to eq(5)
|
115
|
+
end
|
116
|
+
|
117
|
+
it 'adds current page header' do
|
118
|
+
handler.process
|
119
|
+
expect(controller_headers['page']).to eq(2)
|
120
|
+
end
|
121
|
+
|
122
|
+
it 'adds per page header' do
|
123
|
+
handler.process
|
124
|
+
expect(controller_headers['per_page']).to eq(10)
|
125
|
+
end
|
51
126
|
end
|
52
127
|
end
|
53
128
|
end
|
@@ -30,6 +30,118 @@ describe Azeroth::RequestHandler::Update do
|
|
30
30
|
end
|
31
31
|
end
|
32
32
|
|
33
|
+
context 'when update_with option is given ' do
|
34
|
+
context 'with block' do
|
35
|
+
it_behaves_like 'a request handler' do
|
36
|
+
let(:block) do
|
37
|
+
proc do
|
38
|
+
document.assign_attributes(document_params)
|
39
|
+
document.name = "#{document.name}!"
|
40
|
+
document.save
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
let(:options_hash) do
|
45
|
+
{
|
46
|
+
update_with: block
|
47
|
+
}
|
48
|
+
end
|
49
|
+
|
50
|
+
let(:expected_resource) { document }
|
51
|
+
|
52
|
+
let(:extra_params) do
|
53
|
+
{
|
54
|
+
id: document.id,
|
55
|
+
document: {
|
56
|
+
name: 'New Name'
|
57
|
+
}
|
58
|
+
}
|
59
|
+
end
|
60
|
+
|
61
|
+
let(:expected_json) do
|
62
|
+
{
|
63
|
+
'name' => 'New Name!'
|
64
|
+
}
|
65
|
+
end
|
66
|
+
|
67
|
+
it 'updates the values given by request' do
|
68
|
+
expect { handler.process }
|
69
|
+
.to change { document.reload.name }
|
70
|
+
.from(document.name)
|
71
|
+
.to('New Name!')
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
context 'with symbol' do
|
77
|
+
it_behaves_like 'a request handler' do
|
78
|
+
let(:options_hash) do
|
79
|
+
{
|
80
|
+
update_with: :add_bang_name
|
81
|
+
}
|
82
|
+
end
|
83
|
+
|
84
|
+
let(:expected_resource) { document }
|
85
|
+
|
86
|
+
let(:extra_params) do
|
87
|
+
{
|
88
|
+
id: document.id,
|
89
|
+
document: {
|
90
|
+
name: 'New Name'
|
91
|
+
}
|
92
|
+
}
|
93
|
+
end
|
94
|
+
|
95
|
+
let(:expected_json) do
|
96
|
+
{
|
97
|
+
'name' => 'New Name!'
|
98
|
+
}
|
99
|
+
end
|
100
|
+
|
101
|
+
it 'updates the values given by request' do
|
102
|
+
expect { handler.process }
|
103
|
+
.to change { document.reload.name }
|
104
|
+
.from(document.name)
|
105
|
+
.to('New Name!')
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
context 'with string' do
|
111
|
+
it_behaves_like 'a request handler' do
|
112
|
+
let(:options_hash) do
|
113
|
+
{
|
114
|
+
update_with: 'add_bang_name'
|
115
|
+
}
|
116
|
+
end
|
117
|
+
|
118
|
+
let(:expected_resource) { document }
|
119
|
+
|
120
|
+
let(:extra_params) do
|
121
|
+
{
|
122
|
+
id: document.id,
|
123
|
+
document: {
|
124
|
+
name: 'New Name'
|
125
|
+
}
|
126
|
+
}
|
127
|
+
end
|
128
|
+
|
129
|
+
let(:expected_json) do
|
130
|
+
{
|
131
|
+
'name' => 'New Name!'
|
132
|
+
}
|
133
|
+
end
|
134
|
+
|
135
|
+
it 'updates the values given by request' do
|
136
|
+
expect { handler.process }
|
137
|
+
.to change { document.reload.name }
|
138
|
+
.from(document.name)
|
139
|
+
.to('New Name!')
|
140
|
+
end
|
141
|
+
end
|
142
|
+
end
|
143
|
+
end
|
144
|
+
|
33
145
|
context 'with before_save block option' do
|
34
146
|
it_behaves_like 'a request handler' do
|
35
147
|
let(:block) do
|
@@ -67,5 +67,15 @@ describe Azeroth::RequestHandler do
|
|
67
67
|
expect(controller).not_to have_received(:render)
|
68
68
|
end
|
69
69
|
end
|
70
|
+
|
71
|
+
context 'with format js' do
|
72
|
+
let(:format) { 'js' }
|
73
|
+
|
74
|
+
it do
|
75
|
+
handler.process
|
76
|
+
|
77
|
+
expect(controller).not_to have_received(:render)
|
78
|
+
end
|
79
|
+
end
|
70
80
|
end
|
71
81
|
end
|
@@ -28,4 +28,10 @@ class RequestHandlerController < ActionController::Base
|
|
28
28
|
documents.where(reference: 'X-MAGIC-15')
|
29
29
|
.build(document_params)
|
30
30
|
end
|
31
|
+
|
32
|
+
def add_bang_name
|
33
|
+
document.assign_attributes(document_params)
|
34
|
+
document.name = "#{document.name}!"
|
35
|
+
document.save
|
36
|
+
end
|
31
37
|
end
|
@@ -24,6 +24,8 @@ shared_examples 'a request handler' do |status: :ok|
|
|
24
24
|
{ format: format }.merge(extra_params)
|
25
25
|
end
|
26
26
|
|
27
|
+
let(:controller_headers) { {} }
|
28
|
+
|
27
29
|
before do
|
28
30
|
create_list(:document, documents_count)
|
29
31
|
|
@@ -33,6 +35,9 @@ shared_examples 'a request handler' do |status: :ok|
|
|
33
35
|
allow(controller).to receive(:render)
|
34
36
|
.with(json: expected_json, status: status)
|
35
37
|
.and_return(expected_json)
|
38
|
+
|
39
|
+
allow(controller).to receive(:headers)
|
40
|
+
.and_return(controller_headers)
|
36
41
|
end
|
37
42
|
|
38
43
|
it 'returns all documents json' do
|
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.9.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: 2022-05-19 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
@@ -128,14 +128,14 @@ dependencies:
|
|
128
128
|
requirements:
|
129
129
|
- - '='
|
130
130
|
- !ruby/object:Gem::Version
|
131
|
-
version: 1.
|
131
|
+
version: 1.12.5
|
132
132
|
type: :development
|
133
133
|
prerelease: false
|
134
134
|
version_requirements: !ruby/object:Gem::Requirement
|
135
135
|
requirements:
|
136
136
|
- - '='
|
137
137
|
- !ruby/object:Gem::Version
|
138
|
-
version: 1.
|
138
|
+
version: 1.12.5
|
139
139
|
- !ruby/object:Gem::Dependency
|
140
140
|
name: pry
|
141
141
|
requirement: !ruby/object:Gem::Requirement
|
@@ -456,6 +456,7 @@ files:
|
|
456
456
|
- config/yardstick.yml
|
457
457
|
- docker-compose.yml
|
458
458
|
- lib/azeroth.rb
|
459
|
+
- lib/azeroth/controller_interface.rb
|
459
460
|
- lib/azeroth/decorator.rb
|
460
461
|
- lib/azeroth/decorator/hash_builder.rb
|
461
462
|
- lib/azeroth/decorator/key_value_extractor.rb
|
@@ -484,6 +485,7 @@ files:
|
|
484
485
|
- spec/controllers/paginated_documents_controller_spec.rb
|
485
486
|
- spec/controllers/pokemon_masters_controller_spec.rb
|
486
487
|
- spec/controllers/pokemons_controller_spec.rb
|
488
|
+
- spec/controllers/rendering_controller_spec.rb
|
487
489
|
- spec/dummy/.ruby-version
|
488
490
|
- spec/dummy/Rakefile
|
489
491
|
- spec/dummy/app/assets/config/manifest.js
|
@@ -504,6 +506,7 @@ files:
|
|
504
506
|
- spec/dummy/app/controllers/pokemon_masters_controller.rb
|
505
507
|
- spec/dummy/app/controllers/pokemons_controller.rb
|
506
508
|
- spec/dummy/app/controllers/publishers_controller.rb
|
509
|
+
- spec/dummy/app/controllers/rendering_controller.rb
|
507
510
|
- spec/dummy/app/helpers/application_helper.rb
|
508
511
|
- spec/dummy/app/jobs/application_job.rb
|
509
512
|
- spec/dummy/app/mailers/application_mailer.rb
|
@@ -537,6 +540,8 @@ files:
|
|
537
540
|
- spec/dummy/app/views/layouts/application.html.erb
|
538
541
|
- spec/dummy/app/views/layouts/mailer.html.erb
|
539
542
|
- spec/dummy/app/views/layouts/mailer.text.erb
|
543
|
+
- spec/dummy/app/views/rendering/index.html.erb
|
544
|
+
- spec/dummy/app/views/rendering/show.html.erb
|
540
545
|
- spec/dummy/bin/bundle
|
541
546
|
- spec/dummy/bin/rails
|
542
547
|
- spec/dummy/bin/rake
|
@@ -583,6 +588,7 @@ files:
|
|
583
588
|
- spec/integration/readme/controllers/games_controller_spec.rb
|
584
589
|
- spec/integration/yard/azeroth/decorator_spec.rb
|
585
590
|
- spec/integration/yard/controllers/games_controller_spec.rb
|
591
|
+
- spec/lib/azeroth/controller_interface_spec.rb
|
586
592
|
- spec/lib/azeroth/decorator/hash_builder_spec.rb
|
587
593
|
- spec/lib/azeroth/decorator/key_value_extractor_spec.rb
|
588
594
|
- spec/lib/azeroth/decorator/method_builder_spec.rb
|
@@ -649,6 +655,7 @@ test_files:
|
|
649
655
|
- spec/controllers/paginated_documents_controller_spec.rb
|
650
656
|
- spec/controllers/pokemon_masters_controller_spec.rb
|
651
657
|
- spec/controllers/pokemons_controller_spec.rb
|
658
|
+
- spec/controllers/rendering_controller_spec.rb
|
652
659
|
- spec/dummy/.ruby-version
|
653
660
|
- spec/dummy/Rakefile
|
654
661
|
- spec/dummy/app/assets/config/manifest.js
|
@@ -669,6 +676,7 @@ test_files:
|
|
669
676
|
- spec/dummy/app/controllers/pokemon_masters_controller.rb
|
670
677
|
- spec/dummy/app/controllers/pokemons_controller.rb
|
671
678
|
- spec/dummy/app/controllers/publishers_controller.rb
|
679
|
+
- spec/dummy/app/controllers/rendering_controller.rb
|
672
680
|
- spec/dummy/app/helpers/application_helper.rb
|
673
681
|
- spec/dummy/app/jobs/application_job.rb
|
674
682
|
- spec/dummy/app/mailers/application_mailer.rb
|
@@ -702,6 +710,8 @@ test_files:
|
|
702
710
|
- spec/dummy/app/views/layouts/application.html.erb
|
703
711
|
- spec/dummy/app/views/layouts/mailer.html.erb
|
704
712
|
- spec/dummy/app/views/layouts/mailer.text.erb
|
713
|
+
- spec/dummy/app/views/rendering/index.html.erb
|
714
|
+
- spec/dummy/app/views/rendering/show.html.erb
|
705
715
|
- spec/dummy/bin/bundle
|
706
716
|
- spec/dummy/bin/rails
|
707
717
|
- spec/dummy/bin/rake
|
@@ -748,6 +758,7 @@ test_files:
|
|
748
758
|
- spec/integration/readme/controllers/games_controller_spec.rb
|
749
759
|
- spec/integration/yard/azeroth/decorator_spec.rb
|
750
760
|
- spec/integration/yard/controllers/games_controller_spec.rb
|
761
|
+
- spec/lib/azeroth/controller_interface_spec.rb
|
751
762
|
- spec/lib/azeroth/decorator/hash_builder_spec.rb
|
752
763
|
- spec/lib/azeroth/decorator/key_value_extractor_spec.rb
|
753
764
|
- spec/lib/azeroth/decorator/method_builder_spec.rb
|