azeroth 0.6.5 → 0.7.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 +36 -1
- data/README.md +54 -4
- data/azeroth.gemspec +1 -0
- data/lib/azeroth.rb +1 -0
- data/lib/azeroth/options.rb +30 -1
- data/lib/azeroth/request_handler.rb +39 -2
- data/lib/azeroth/request_handler/create.rb +6 -3
- data/lib/azeroth/request_handler/update.rb +3 -3
- data/lib/azeroth/resourceable.rb +20 -0
- data/lib/azeroth/resourceable/class_methods.rb +31 -11
- data/lib/azeroth/routes_builder.rb +2 -1
- data/lib/azeroth/version.rb +1 -1
- data/scripts/build.sh +47 -0
- data/spec/controllers/pokemon_masters_controller_spec.rb +56 -0
- data/spec/controllers/pokemons_controller_spec.rb +56 -0
- data/spec/dummy/app/controllers/pokemon_masters_controller.rb +9 -0
- data/spec/dummy/app/controllers/pokemons_controller.rb +27 -0
- data/spec/dummy/config/routes.rb +4 -0
- data/spec/lib/azeroth/request_handler/create_spec.rb +83 -0
- data/spec/lib/azeroth/request_handler/update_spec.rb +91 -0
- data/spec/lib/azeroth/request_handler_spec.rb +3 -1
- data/spec/support/app/controllers/request_handler_controller.rb +5 -1
- data/spec/support/factories/pokemon.rb +8 -0
- data/spec/support/shared_examples/request_handler.rb +5 -2
- metadata +27 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: e12fe40f870d7fdb3cea6050cd78c2e9fc664645afc834be42036f01261d7078
|
|
4
|
+
data.tar.gz: ce539d54b582033f05342045a923313367a307bb999d8ec7c2b7e9aabc550edb
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 744f9bf09c7c3ab19c8ea8541f322c498983904ec1b084dc52bb9e07f05e8fdeddc05c30dc5d52d8553412c4b00a1f82c1cdcd83fa08e8cc5e1ca86ed894097f
|
|
7
|
+
data.tar.gz: bffa4c272a0e8610d694b3762627eb3ad81416bc979da72f789ea6b29be97e8ff0b3790a14a74108b1a81dc932b69fff2dc27a9cc4bcd07874fe437efc3069d8
|
data/.circleci/config.yml
CHANGED
|
@@ -1,6 +1,22 @@
|
|
|
1
1
|
version: 2
|
|
2
|
+
workflows:
|
|
3
|
+
version: 2
|
|
4
|
+
test-and-build:
|
|
5
|
+
jobs:
|
|
6
|
+
- test:
|
|
7
|
+
filters:
|
|
8
|
+
tags:
|
|
9
|
+
only: /.*/
|
|
10
|
+
- build-and-release:
|
|
11
|
+
requires: [test]
|
|
12
|
+
filters:
|
|
13
|
+
tags:
|
|
14
|
+
only: /\d+\.\d+\.\d+/
|
|
15
|
+
branches:
|
|
16
|
+
only:
|
|
17
|
+
- master
|
|
2
18
|
jobs:
|
|
3
|
-
|
|
19
|
+
test:
|
|
4
20
|
docker:
|
|
5
21
|
- image: darthjee/circleci_rails_gems:0.5.1
|
|
6
22
|
environment:
|
|
@@ -34,3 +50,22 @@ jobs:
|
|
|
34
50
|
- run:
|
|
35
51
|
name: Check unit tests
|
|
36
52
|
command: check_specs
|
|
53
|
+
build-and-release:
|
|
54
|
+
docker:
|
|
55
|
+
- image: darthjee/circleci_rails_gems:0.5.1
|
|
56
|
+
environment:
|
|
57
|
+
PROJECT: azeroth
|
|
58
|
+
steps:
|
|
59
|
+
- checkout
|
|
60
|
+
- run:
|
|
61
|
+
name: Bundle Install
|
|
62
|
+
command: bundle install
|
|
63
|
+
- run:
|
|
64
|
+
name: Signin
|
|
65
|
+
command: scripts/build.sh signin
|
|
66
|
+
- run:
|
|
67
|
+
name: Build Gem
|
|
68
|
+
command: scripts/build.sh build
|
|
69
|
+
- run:
|
|
70
|
+
name: Push Gem
|
|
71
|
+
command: scripts/build.sh push
|
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.7.0](https://www.rubydoc.info/gems/azeroth/0.7.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
|
|
@@ -25,6 +25,25 @@ does not perform database operations
|
|
|
25
25
|
Future versions will enable `html` rendering to also perform
|
|
26
26
|
database operations.
|
|
27
27
|
|
|
28
|
+
Installation
|
|
29
|
+
---------------
|
|
30
|
+
|
|
31
|
+
- Install it
|
|
32
|
+
|
|
33
|
+
```ruby
|
|
34
|
+
gem install azeroth
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
- Or add Sinclair to your `Gemfile` and `bundle install`:
|
|
38
|
+
|
|
39
|
+
```ruby
|
|
40
|
+
gem 'azeroth'
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
bundle install azeroth
|
|
45
|
+
```
|
|
46
|
+
|
|
28
47
|
Usage
|
|
29
48
|
-----
|
|
30
49
|
|
|
@@ -36,9 +55,10 @@ which adds a resource and action methods for `create`, `show`, `index`,
|
|
|
36
55
|
`update`, `delete`, `edit`
|
|
37
56
|
|
|
38
57
|
It accepts options
|
|
39
|
-
- only List of actions to be built
|
|
40
|
-
- except List of actions to not to be built
|
|
41
|
-
- decorator Decorator class or flag allowing/disallowing decorators
|
|
58
|
+
- only: List of actions to be built
|
|
59
|
+
- except: List of actions to not to be built
|
|
60
|
+
- decorator: Decorator class or flag allowing/disallowing decorators
|
|
61
|
+
- before_save: Method/Proc to be ran before saving the resource on create or update
|
|
42
62
|
|
|
43
63
|
```ruby
|
|
44
64
|
# publishers_controller.rb
|
|
@@ -76,6 +96,36 @@ It accepts options
|
|
|
76
96
|
end
|
|
77
97
|
```
|
|
78
98
|
|
|
99
|
+
```ruby
|
|
100
|
+
# pokemons_controller.rb
|
|
101
|
+
|
|
102
|
+
class PokemonsController < ApplicationController
|
|
103
|
+
include Azeroth::Resourceable
|
|
104
|
+
|
|
105
|
+
resource_for :pokemon,
|
|
106
|
+
only: %i[create update],
|
|
107
|
+
before_save: :set_favorite
|
|
108
|
+
|
|
109
|
+
private
|
|
110
|
+
|
|
111
|
+
def set_favorite
|
|
112
|
+
pokemon.favorite = true
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
def pokemons
|
|
116
|
+
master.pokemons
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
def master
|
|
120
|
+
@master ||= PokemonMaster.find(master_id)
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
def master_id
|
|
124
|
+
params.require(:pokemon_master_id)
|
|
125
|
+
end
|
|
126
|
+
end
|
|
127
|
+
```
|
|
128
|
+
|
|
79
129
|
## Azeroth::Decorator
|
|
80
130
|
|
|
81
131
|
[Decorators](https://www.rubydoc.info/gems/azeroth/Azeroth/Decorator) are
|
data/azeroth.gemspec
CHANGED
|
@@ -20,6 +20,7 @@ Gem::Specification.new do |gem|
|
|
|
20
20
|
|
|
21
21
|
gem.add_runtime_dependency 'activesupport', '~> 5.2.0'
|
|
22
22
|
gem.add_runtime_dependency 'darthjee-active_ext', '>= 1.3.2'
|
|
23
|
+
gem.add_runtime_dependency 'jace', '>= 0.0.3'
|
|
23
24
|
gem.add_runtime_dependency 'sinclair', '>= 1.6.4'
|
|
24
25
|
|
|
25
26
|
gem.add_development_dependency 'actionpack', '5.2.4.2'
|
data/lib/azeroth.rb
CHANGED
data/lib/azeroth/options.rb
CHANGED
|
@@ -10,10 +10,15 @@ module Azeroth
|
|
|
10
10
|
# Sinclair::Options
|
|
11
11
|
class Options < Sinclair::Options
|
|
12
12
|
# Default options
|
|
13
|
+
#
|
|
14
|
+
# @api public
|
|
15
|
+
#
|
|
16
|
+
# @see Resourceable::ClassMethods#resource_for
|
|
13
17
|
DEFAULT_OPTIONS = {
|
|
14
18
|
only: %i[create destroy edit index new show update],
|
|
15
19
|
except: [],
|
|
16
|
-
decorator: true
|
|
20
|
+
decorator: true,
|
|
21
|
+
before_save: nil
|
|
17
22
|
}.freeze
|
|
18
23
|
|
|
19
24
|
with_options DEFAULT_OPTIONS
|
|
@@ -25,6 +30,19 @@ module Azeroth
|
|
|
25
30
|
[only].flatten.map(&:to_sym) - [except].flatten.map(&:to_sym)
|
|
26
31
|
end
|
|
27
32
|
|
|
33
|
+
# Returns event dispatcher
|
|
34
|
+
#
|
|
35
|
+
# Event dispatcher is responsible for
|
|
36
|
+
# sending events such as +before_save+
|
|
37
|
+
# to it's correct calling point
|
|
38
|
+
#
|
|
39
|
+
# @return [Jace::Dispatcher]
|
|
40
|
+
def event_dispatcher(event)
|
|
41
|
+
Jace::Dispatcher.new(
|
|
42
|
+
before: try("before_#{event}")
|
|
43
|
+
)
|
|
44
|
+
end
|
|
45
|
+
|
|
28
46
|
# @method only
|
|
29
47
|
# @api private
|
|
30
48
|
#
|
|
@@ -50,5 +68,16 @@ module Azeroth
|
|
|
50
68
|
# model.as_json
|
|
51
69
|
#
|
|
52
70
|
# @return [Decorator,TrueClass,FalseClass]
|
|
71
|
+
|
|
72
|
+
# @method before_save
|
|
73
|
+
# @api private
|
|
74
|
+
#
|
|
75
|
+
# Block or method name to be run before save
|
|
76
|
+
#
|
|
77
|
+
# The given method or block will be ran
|
|
78
|
+
# before committing changes in models
|
|
79
|
+
# to database
|
|
80
|
+
#
|
|
81
|
+
# @return [Symbol,Proc]
|
|
53
82
|
end
|
|
54
83
|
end
|
|
@@ -18,9 +18,10 @@ module Azeroth
|
|
|
18
18
|
|
|
19
19
|
# @param controller [ApplicationController]
|
|
20
20
|
# @param model [Azeroth::Model]
|
|
21
|
-
def initialize(controller, model)
|
|
21
|
+
def initialize(controller, model, options)
|
|
22
22
|
@controller = controller
|
|
23
23
|
@model = model
|
|
24
|
+
@options = options
|
|
24
25
|
end
|
|
25
26
|
|
|
26
27
|
# process the request
|
|
@@ -44,7 +45,7 @@ module Azeroth
|
|
|
44
45
|
|
|
45
46
|
private
|
|
46
47
|
|
|
47
|
-
attr_reader :controller, :model
|
|
48
|
+
attr_reader :controller, :model, :options
|
|
48
49
|
# @method controller
|
|
49
50
|
# @api private
|
|
50
51
|
# @private
|
|
@@ -61,6 +62,14 @@ module Azeroth
|
|
|
61
62
|
#
|
|
62
63
|
# @return [Azeroth::Model]
|
|
63
64
|
|
|
65
|
+
# @method options
|
|
66
|
+
# @api private
|
|
67
|
+
# @private
|
|
68
|
+
#
|
|
69
|
+
# Handling options
|
|
70
|
+
#
|
|
71
|
+
# @return [Azeroth::Options]
|
|
72
|
+
|
|
64
73
|
delegate :params, to: :controller
|
|
65
74
|
# @method params
|
|
66
75
|
# @api private
|
|
@@ -104,5 +113,33 @@ module Azeroth
|
|
|
104
113
|
def status
|
|
105
114
|
:ok
|
|
106
115
|
end
|
|
116
|
+
|
|
117
|
+
# @private
|
|
118
|
+
#
|
|
119
|
+
# Run a block triggering the event
|
|
120
|
+
#
|
|
121
|
+
# @return [Object] Result of given block
|
|
122
|
+
def trigger_event(event, &block)
|
|
123
|
+
options.event_dispatcher(event)
|
|
124
|
+
.dispatch(controller, &block)
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
# @private
|
|
128
|
+
#
|
|
129
|
+
# Attributes to be used on resource creating
|
|
130
|
+
#
|
|
131
|
+
# @return [Hash]
|
|
132
|
+
def attributes
|
|
133
|
+
@attributes ||= controller.send("#{model.name}_params")
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
# @private
|
|
137
|
+
#
|
|
138
|
+
# Collection scope of the resource
|
|
139
|
+
#
|
|
140
|
+
# @return [ActiveRecord::Relation]
|
|
141
|
+
def collection
|
|
142
|
+
@collection = controller.send(model.plural)
|
|
143
|
+
end
|
|
107
144
|
end
|
|
108
145
|
end
|
|
@@ -24,9 +24,12 @@ module Azeroth
|
|
|
24
24
|
#
|
|
25
25
|
# @return [Object]
|
|
26
26
|
def build_resource
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
27
|
+
@resource = collection.build(attributes)
|
|
28
|
+
controller.instance_variable_set("@#{model.name}", resource)
|
|
29
|
+
|
|
30
|
+
trigger_event(:save) do
|
|
31
|
+
resource.tap(&:save)
|
|
32
|
+
end
|
|
30
33
|
end
|
|
31
34
|
|
|
32
35
|
# @private
|
|
@@ -24,10 +24,10 @@ module Azeroth
|
|
|
24
24
|
#
|
|
25
25
|
# @return [Object]
|
|
26
26
|
def update_resource
|
|
27
|
-
attributes = controller.send("#{model.name}_params")
|
|
28
|
-
|
|
29
27
|
controller.send(model.name).tap do |entry|
|
|
30
|
-
|
|
28
|
+
trigger_event(:save) do
|
|
29
|
+
entry.update(attributes)
|
|
30
|
+
end
|
|
31
31
|
end
|
|
32
32
|
end
|
|
33
33
|
|
data/lib/azeroth/resourceable.rb
CHANGED
|
@@ -21,6 +21,26 @@ module Azeroth
|
|
|
21
21
|
autoload :Builder, 'azeroth/resourceable/builder'
|
|
22
22
|
autoload :ClassMethods, 'azeroth/resourceable/class_methods'
|
|
23
23
|
|
|
24
|
+
class << self
|
|
25
|
+
# @method self.resource_for(name, **options)
|
|
26
|
+
# @api public
|
|
27
|
+
#
|
|
28
|
+
# @param name [String, Symbol] Name of the resource
|
|
29
|
+
# @param options [Hash] resource building options
|
|
30
|
+
# @option options only [Array<Symbol,String>] List of
|
|
31
|
+
# actions to be built
|
|
32
|
+
# @option options except [Array<Symbol,String>] List of
|
|
33
|
+
# actions to not to be built
|
|
34
|
+
# @option options decorator [Azeroth::Decorator,TrueClass,FalseClass]
|
|
35
|
+
# Decorator class or flag allowing/disallowing decorators
|
|
36
|
+
# @option options before_save [Symbol,Proc] method/block
|
|
37
|
+
# to be ran on the controller before saving the resource
|
|
38
|
+
#
|
|
39
|
+
# @return [Array<MethodDefinition>] list of methods created
|
|
40
|
+
#
|
|
41
|
+
# @see Options::DEFAULT_OPTIONS
|
|
42
|
+
end
|
|
43
|
+
|
|
24
44
|
private
|
|
25
45
|
|
|
26
46
|
# @api private
|
|
@@ -9,18 +9,11 @@ module Azeroth
|
|
|
9
9
|
module ClassMethods
|
|
10
10
|
# Adds resource methods for resource
|
|
11
11
|
#
|
|
12
|
-
# @param
|
|
13
|
-
# @
|
|
14
|
-
# @
|
|
15
|
-
# actions to be built
|
|
16
|
-
# @option options except [Array<Symbol,String>] List of
|
|
17
|
-
# actions to not to be built
|
|
18
|
-
# @option options decorator [Azeroth::Decorator,TrueClass,FalseClass]
|
|
19
|
-
# Decorator class or flag allowing/disallowing decorators
|
|
12
|
+
# @param (see Resourceable.resource_for)
|
|
13
|
+
# @option (see Resourceable.resource_for)
|
|
14
|
+
# @return (see Resourceable.resource_for)
|
|
20
15
|
#
|
|
21
|
-
# @
|
|
22
|
-
#
|
|
23
|
-
# @see Options
|
|
16
|
+
# @see (see Resourceable.resource_for)
|
|
24
17
|
#
|
|
25
18
|
# @example Controller without delete
|
|
26
19
|
# class DocumentsController < ApplicationController
|
|
@@ -124,6 +117,33 @@ module Azeroth
|
|
|
124
117
|
# # name: 'Nintendo'
|
|
125
118
|
# # }
|
|
126
119
|
# }
|
|
120
|
+
#
|
|
121
|
+
# @example Controller with before_save
|
|
122
|
+
# class PokemonsController < ApplicationController
|
|
123
|
+
# include Azeroth::Resourceable
|
|
124
|
+
#
|
|
125
|
+
# resource_for :pokemon,
|
|
126
|
+
# only: %i[create update],
|
|
127
|
+
# before_save: :set_favorite
|
|
128
|
+
#
|
|
129
|
+
# private
|
|
130
|
+
#
|
|
131
|
+
# def set_favorite
|
|
132
|
+
# pokemon.favorite = true
|
|
133
|
+
# end
|
|
134
|
+
#
|
|
135
|
+
# def pokemons
|
|
136
|
+
# master.pokemons
|
|
137
|
+
# end
|
|
138
|
+
#
|
|
139
|
+
# def master
|
|
140
|
+
# @master ||= PokemonMaster.find(master_id)
|
|
141
|
+
# end
|
|
142
|
+
#
|
|
143
|
+
# def master_id
|
|
144
|
+
# params.require(:pokemon_master_id)
|
|
145
|
+
# end
|
|
146
|
+
# end
|
|
127
147
|
def resource_for(name, **options)
|
|
128
148
|
Builder.new(
|
|
129
149
|
self, name, Azeroth::Options.new(options)
|
|
@@ -62,13 +62,14 @@ module Azeroth
|
|
|
62
62
|
|
|
63
63
|
def route_code(route)
|
|
64
64
|
model_interface = model
|
|
65
|
+
options_object = options
|
|
65
66
|
handler_class = Azeroth::RequestHandler.const_get(
|
|
66
67
|
route.to_s.capitalize
|
|
67
68
|
)
|
|
68
69
|
|
|
69
70
|
proc do
|
|
70
71
|
handler_class.new(
|
|
71
|
-
self, model_interface
|
|
72
|
+
self, model_interface, options_object
|
|
72
73
|
).process
|
|
73
74
|
end
|
|
74
75
|
end
|
data/lib/azeroth/version.rb
CHANGED
data/scripts/build.sh
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
|
|
3
|
+
function version() {
|
|
4
|
+
echo $(cat lib/$PROJECT/version.rb | grep VERSION | sed -e "s/.*'\\(.*\\)'.*/\\1/g")
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
function isTagged() {
|
|
8
|
+
VERSION=$(version)
|
|
9
|
+
TAG=$(git tag | tail -n 1)
|
|
10
|
+
|
|
11
|
+
if [ $VERSION = $TAG ]; then
|
|
12
|
+
return 0
|
|
13
|
+
else
|
|
14
|
+
return 1
|
|
15
|
+
fi
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
ACTION=$1
|
|
19
|
+
|
|
20
|
+
case $ACTION in
|
|
21
|
+
"signin")
|
|
22
|
+
mkdir ~/.gem
|
|
23
|
+
echo "---" > ~/.gem/credentials
|
|
24
|
+
echo ":rubygems_api_key: $RUBY_GEMS_API_KEY" >> ~/.gem/credentials
|
|
25
|
+
chmod 600 ~/.gem/credentials
|
|
26
|
+
;;
|
|
27
|
+
"build")
|
|
28
|
+
if $(isTagged); then
|
|
29
|
+
rake build
|
|
30
|
+
else
|
|
31
|
+
echo version did not change
|
|
32
|
+
fi
|
|
33
|
+
;;
|
|
34
|
+
"push")
|
|
35
|
+
if $(isTagged); then
|
|
36
|
+
VERSION=$(version)
|
|
37
|
+
gem push "pkg/$PROJECT-$VERSION.gem"
|
|
38
|
+
else
|
|
39
|
+
echo version did not change
|
|
40
|
+
fi
|
|
41
|
+
;;
|
|
42
|
+
*)
|
|
43
|
+
echo Usage:
|
|
44
|
+
echo "$0 build # builds gem"
|
|
45
|
+
echo "$0 push # pushes gem"
|
|
46
|
+
;;
|
|
47
|
+
esac
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'spec_helper'
|
|
4
|
+
|
|
5
|
+
RSpec.describe PokemonMastersController do
|
|
6
|
+
describe 'POST create' do
|
|
7
|
+
let(:parameters) do
|
|
8
|
+
{
|
|
9
|
+
format: :json,
|
|
10
|
+
pokemon_master: {
|
|
11
|
+
first_name: 'Ash'
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
it 'creates pokemon master' do
|
|
17
|
+
expect { post :create, params: parameters }
|
|
18
|
+
.to change(PokemonMaster, :count)
|
|
19
|
+
.by(1)
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
it 'updates pokemon master age' do
|
|
23
|
+
post :create, params: parameters
|
|
24
|
+
|
|
25
|
+
expect(PokemonMaster.last.age).to eq(10)
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
describe 'POST update' do
|
|
30
|
+
let(:master) do
|
|
31
|
+
create(:pokemon_master, age: 20, last_name: nil)
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
let(:parameters) do
|
|
35
|
+
{
|
|
36
|
+
id: master.id,
|
|
37
|
+
format: :json,
|
|
38
|
+
pokemon_master: { last_name: 'Joe' }
|
|
39
|
+
}
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
it 'updates pokemon master' do
|
|
43
|
+
expect { post :update, params: parameters }
|
|
44
|
+
.to change { master.reload.last_name }
|
|
45
|
+
.from(nil)
|
|
46
|
+
.to('Joe')
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
it 'updates pokemon master age' do
|
|
50
|
+
expect { post :update, params: parameters }
|
|
51
|
+
.to change { master.reload.age }
|
|
52
|
+
.from(20)
|
|
53
|
+
.to(10)
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
end
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'spec_helper'
|
|
4
|
+
|
|
5
|
+
RSpec.describe PokemonsController do
|
|
6
|
+
let(:master) { create(:pokemon_master) }
|
|
7
|
+
|
|
8
|
+
describe 'POST create' do
|
|
9
|
+
let(:parameters) do
|
|
10
|
+
{
|
|
11
|
+
pokemon_master_id: master.id,
|
|
12
|
+
format: :json,
|
|
13
|
+
pokemon: { name: 'Bulbasaur' }
|
|
14
|
+
}
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
it 'creates pokemon' do
|
|
18
|
+
expect { post :create, params: parameters }
|
|
19
|
+
.to change(Pokemon, :count)
|
|
20
|
+
.by(1)
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
it 'updates pokemon to be favorite' do
|
|
24
|
+
expect { post :create, params: parameters }
|
|
25
|
+
.to change { master.reload.favorite_pokemon }
|
|
26
|
+
.from(nil)
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
describe 'POST update' do
|
|
31
|
+
let(:pokemon) { create(:pokemon) }
|
|
32
|
+
let(:master) { pokemon.pokemon_master }
|
|
33
|
+
|
|
34
|
+
let(:parameters) do
|
|
35
|
+
{
|
|
36
|
+
pokemon_master_id: master.id,
|
|
37
|
+
id: pokemon.id,
|
|
38
|
+
format: :json,
|
|
39
|
+
pokemon: { name: 'Butterfree' }
|
|
40
|
+
}
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
it 'updates pokemon' do
|
|
44
|
+
expect { post :update, params: parameters }
|
|
45
|
+
.to change { pokemon.reload.name }
|
|
46
|
+
.from('Bulbasaur')
|
|
47
|
+
.to('Butterfree')
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
it 'updates pokemon to be favorite' do
|
|
51
|
+
expect { post :update, params: parameters }
|
|
52
|
+
.to change { pokemon.reload.favorite }
|
|
53
|
+
.from(nil)
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
end
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
class PokemonsController < ApplicationController
|
|
4
|
+
include Azeroth::Resourceable
|
|
5
|
+
|
|
6
|
+
resource_for :pokemon,
|
|
7
|
+
only: %i[create update],
|
|
8
|
+
before_save: :set_favorite
|
|
9
|
+
|
|
10
|
+
private
|
|
11
|
+
|
|
12
|
+
def set_favorite
|
|
13
|
+
pokemon.favorite = true
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def pokemons
|
|
17
|
+
master.pokemons
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def master
|
|
21
|
+
@master ||= PokemonMaster.find(master_id)
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def master_id
|
|
25
|
+
params.require(:pokemon_master_id)
|
|
26
|
+
end
|
|
27
|
+
end
|
data/spec/dummy/config/routes.rb
CHANGED
|
@@ -23,6 +23,89 @@ describe Azeroth::RequestHandler::Create do
|
|
|
23
23
|
.by(1)
|
|
24
24
|
end
|
|
25
25
|
end
|
|
26
|
+
|
|
27
|
+
context 'with before_save block option' do
|
|
28
|
+
it_behaves_like 'a request handler', status: :created do
|
|
29
|
+
let(:block) do
|
|
30
|
+
value = 10
|
|
31
|
+
proc do
|
|
32
|
+
document.reference = "X-MAGIC-#{value}"
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
let(:options_hash) do
|
|
37
|
+
{
|
|
38
|
+
before_save: block
|
|
39
|
+
}
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
let(:extra_params) do
|
|
43
|
+
{
|
|
44
|
+
document: {
|
|
45
|
+
name: 'My Document'
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
let(:expected_json) do
|
|
51
|
+
{
|
|
52
|
+
'name' => 'My Document',
|
|
53
|
+
'reference' => 'X-MAGIC-10'
|
|
54
|
+
}
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
it 'creates entry' do
|
|
58
|
+
expect { handler.process }
|
|
59
|
+
.to change(Document, :count)
|
|
60
|
+
.by(1)
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
it 'changes entry before saving' do
|
|
64
|
+
handler.process
|
|
65
|
+
|
|
66
|
+
expect(Document.last.reference)
|
|
67
|
+
.to eq('X-MAGIC-10')
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
context 'with before_save symbol option' do
|
|
73
|
+
it_behaves_like 'a request handler', status: :created do
|
|
74
|
+
let(:options_hash) do
|
|
75
|
+
{
|
|
76
|
+
before_save: :add_magic_reference
|
|
77
|
+
}
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
let(:extra_params) do
|
|
81
|
+
{
|
|
82
|
+
document: {
|
|
83
|
+
name: 'My Document'
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
let(:expected_json) do
|
|
89
|
+
{
|
|
90
|
+
'name' => 'My Document',
|
|
91
|
+
'reference' => 'X-MAGIC-15'
|
|
92
|
+
}
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
it 'creates entry' do
|
|
96
|
+
expect { handler.process }
|
|
97
|
+
.to change(Document, :count)
|
|
98
|
+
.by(1)
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
it 'changes entry before saving' do
|
|
102
|
+
handler.process
|
|
103
|
+
|
|
104
|
+
expect(Document.last.reference)
|
|
105
|
+
.to eq('X-MAGIC-15')
|
|
106
|
+
end
|
|
107
|
+
end
|
|
108
|
+
end
|
|
26
109
|
end
|
|
27
110
|
|
|
28
111
|
context 'when payload is invalid' do
|
|
@@ -30,6 +30,97 @@ describe Azeroth::RequestHandler::Update do
|
|
|
30
30
|
end
|
|
31
31
|
end
|
|
32
32
|
|
|
33
|
+
context 'with before_save block option' do
|
|
34
|
+
it_behaves_like 'a request handler' do
|
|
35
|
+
let(:block) do
|
|
36
|
+
value = 10
|
|
37
|
+
proc do
|
|
38
|
+
document.reference = "X-MAGIC-#{value}"
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
let(:options_hash) do
|
|
43
|
+
{
|
|
44
|
+
before_save: block
|
|
45
|
+
}
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
let(:expected_resource) { document }
|
|
49
|
+
|
|
50
|
+
let(:extra_params) do
|
|
51
|
+
{
|
|
52
|
+
id: document.id,
|
|
53
|
+
document: {
|
|
54
|
+
name: 'New Name'
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
let(:expected_json) do
|
|
60
|
+
{
|
|
61
|
+
'name' => 'New Name',
|
|
62
|
+
'reference' => 'X-MAGIC-10'
|
|
63
|
+
}
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
it 'updates the values given by request' do
|
|
67
|
+
expect { handler.process }
|
|
68
|
+
.to change { document.reload.name }
|
|
69
|
+
.from(document.name)
|
|
70
|
+
.to('New Name')
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
it 'updates the values done by before_save' do
|
|
74
|
+
expect { handler.process }
|
|
75
|
+
.to change { document.reload.reference }
|
|
76
|
+
.from(nil)
|
|
77
|
+
.to('X-MAGIC-10')
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
context 'with before_save symbol option' do
|
|
83
|
+
it_behaves_like 'a request handler' do
|
|
84
|
+
let(:options_hash) do
|
|
85
|
+
{
|
|
86
|
+
before_save: :add_magic_reference
|
|
87
|
+
}
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
let(:expected_resource) { document }
|
|
91
|
+
|
|
92
|
+
let(:extra_params) do
|
|
93
|
+
{
|
|
94
|
+
id: document.id,
|
|
95
|
+
document: {
|
|
96
|
+
name: 'New Name'
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
let(:expected_json) do
|
|
102
|
+
{
|
|
103
|
+
'name' => 'New Name',
|
|
104
|
+
'reference' => 'X-MAGIC-15'
|
|
105
|
+
}
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
it 'updates the values given by request' do
|
|
109
|
+
expect { handler.process }
|
|
110
|
+
.to change { document.reload.name }
|
|
111
|
+
.from(document.name)
|
|
112
|
+
.to('New Name')
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
it 'updates the values done by before_save' do
|
|
116
|
+
expect { handler.process }
|
|
117
|
+
.to change { document.reload.reference }
|
|
118
|
+
.from(nil)
|
|
119
|
+
.to('X-MAGIC-15')
|
|
120
|
+
end
|
|
121
|
+
end
|
|
122
|
+
end
|
|
123
|
+
|
|
33
124
|
context 'when payload is invalid' do
|
|
34
125
|
it_behaves_like 'a request handler',
|
|
35
126
|
status: :unprocessable_entity do
|
|
@@ -4,7 +4,9 @@ require 'spec_helper'
|
|
|
4
4
|
|
|
5
5
|
describe Azeroth::RequestHandler do
|
|
6
6
|
describe '#process' do
|
|
7
|
-
subject(:handler)
|
|
7
|
+
subject(:handler) do
|
|
8
|
+
handler_class.new(controller, model, options)
|
|
9
|
+
end
|
|
8
10
|
|
|
9
11
|
let(:controller) { controller_class.new }
|
|
10
12
|
let(:params) { ActionController::Parameters.new(parameters) }
|
|
@@ -10,6 +10,10 @@ class RequestHandlerController < ActionController::Base
|
|
|
10
10
|
end
|
|
11
11
|
|
|
12
12
|
def document
|
|
13
|
-
documents.find(params.require(:id))
|
|
13
|
+
@document ||= documents.find(params.require(:id))
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def add_magic_reference
|
|
17
|
+
document.reference = 'X-MAGIC-15'
|
|
14
18
|
end
|
|
15
19
|
end
|
|
@@ -1,12 +1,15 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
shared_examples 'a request handler' do |status: :ok|
|
|
4
|
-
subject(:handler)
|
|
4
|
+
subject(:handler) do
|
|
5
|
+
described_class.new(controller, model, options)
|
|
6
|
+
end
|
|
5
7
|
|
|
6
8
|
let(:controller) { controller_class.new }
|
|
7
9
|
let(:params) { ActionController::Parameters.new(parameters) }
|
|
8
10
|
let(:model) { Azeroth::Model.new(:document, options) }
|
|
9
|
-
let(:options) { Azeroth::Options.new }
|
|
11
|
+
let(:options) { Azeroth::Options.new(options_hash) }
|
|
12
|
+
let(:options_hash) { {} }
|
|
10
13
|
let(:extra_params) { {} }
|
|
11
14
|
|
|
12
15
|
let(:decorator) { Document::Decorator.new(expected_resource) }
|
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.7.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Darthjee
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2020-05-
|
|
11
|
+
date: 2020-05-13 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: activesupport
|
|
@@ -38,6 +38,20 @@ dependencies:
|
|
|
38
38
|
- - ">="
|
|
39
39
|
- !ruby/object:Gem::Version
|
|
40
40
|
version: 1.3.2
|
|
41
|
+
- !ruby/object:Gem::Dependency
|
|
42
|
+
name: jace
|
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
|
44
|
+
requirements:
|
|
45
|
+
- - ">="
|
|
46
|
+
- !ruby/object:Gem::Version
|
|
47
|
+
version: 0.0.3
|
|
48
|
+
type: :runtime
|
|
49
|
+
prerelease: false
|
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
51
|
+
requirements:
|
|
52
|
+
- - ">="
|
|
53
|
+
- !ruby/object:Gem::Version
|
|
54
|
+
version: 0.0.3
|
|
41
55
|
- !ruby/object:Gem::Dependency
|
|
42
56
|
name: sinclair
|
|
43
57
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -435,9 +449,12 @@ files:
|
|
|
435
449
|
- lib/azeroth/resourceable/class_methods.rb
|
|
436
450
|
- lib/azeroth/routes_builder.rb
|
|
437
451
|
- lib/azeroth/version.rb
|
|
452
|
+
- scripts/build.sh
|
|
438
453
|
- spec/controllers/documents_controller_spec.rb
|
|
439
454
|
- spec/controllers/documents_with_error_controller_spec.rb
|
|
440
455
|
- spec/controllers/index_documents_controller_spec.rb
|
|
456
|
+
- spec/controllers/pokemon_masters_controller_spec.rb
|
|
457
|
+
- spec/controllers/pokemons_controller_spec.rb
|
|
441
458
|
- spec/dummy/.ruby-version
|
|
442
459
|
- spec/dummy/Rakefile
|
|
443
460
|
- spec/dummy/app/assets/config/manifest.js
|
|
@@ -454,6 +471,8 @@ files:
|
|
|
454
471
|
- spec/dummy/app/controllers/documents_with_error_controller.rb
|
|
455
472
|
- spec/dummy/app/controllers/games_controller.rb
|
|
456
473
|
- spec/dummy/app/controllers/index_documents_controller.rb
|
|
474
|
+
- spec/dummy/app/controllers/pokemon_masters_controller.rb
|
|
475
|
+
- spec/dummy/app/controllers/pokemons_controller.rb
|
|
457
476
|
- spec/dummy/app/controllers/publishers_controller.rb
|
|
458
477
|
- spec/dummy/app/helpers/application_helper.rb
|
|
459
478
|
- spec/dummy/app/jobs/application_job.rb
|
|
@@ -560,6 +579,7 @@ files:
|
|
|
560
579
|
- spec/support/factories/dummy_model.rb
|
|
561
580
|
- spec/support/factories/factory.rb
|
|
562
581
|
- spec/support/factories/game.rb
|
|
582
|
+
- spec/support/factories/pokemon.rb
|
|
563
583
|
- spec/support/factories/pokemon_master.rb
|
|
564
584
|
- spec/support/factories/product.rb
|
|
565
585
|
- spec/support/factories/publisher.rb
|
|
@@ -594,6 +614,8 @@ test_files:
|
|
|
594
614
|
- spec/controllers/documents_controller_spec.rb
|
|
595
615
|
- spec/controllers/documents_with_error_controller_spec.rb
|
|
596
616
|
- spec/controllers/index_documents_controller_spec.rb
|
|
617
|
+
- spec/controllers/pokemon_masters_controller_spec.rb
|
|
618
|
+
- spec/controllers/pokemons_controller_spec.rb
|
|
597
619
|
- spec/dummy/.ruby-version
|
|
598
620
|
- spec/dummy/Rakefile
|
|
599
621
|
- spec/dummy/app/assets/config/manifest.js
|
|
@@ -610,6 +632,8 @@ test_files:
|
|
|
610
632
|
- spec/dummy/app/controllers/documents_with_error_controller.rb
|
|
611
633
|
- spec/dummy/app/controllers/games_controller.rb
|
|
612
634
|
- spec/dummy/app/controllers/index_documents_controller.rb
|
|
635
|
+
- spec/dummy/app/controllers/pokemon_masters_controller.rb
|
|
636
|
+
- spec/dummy/app/controllers/pokemons_controller.rb
|
|
613
637
|
- spec/dummy/app/controllers/publishers_controller.rb
|
|
614
638
|
- spec/dummy/app/helpers/application_helper.rb
|
|
615
639
|
- spec/dummy/app/jobs/application_job.rb
|
|
@@ -716,6 +740,7 @@ test_files:
|
|
|
716
740
|
- spec/support/factories/dummy_model.rb
|
|
717
741
|
- spec/support/factories/factory.rb
|
|
718
742
|
- spec/support/factories/game.rb
|
|
743
|
+
- spec/support/factories/pokemon.rb
|
|
719
744
|
- spec/support/factories/pokemon_master.rb
|
|
720
745
|
- spec/support/factories/product.rb
|
|
721
746
|
- spec/support/factories/publisher.rb
|