forest_liana 5.2.3 → 5.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/app/controllers/forest_liana/actions_controller.rb +82 -0
- data/app/helpers/forest_liana/is_same_data_structure_helper.rb +44 -0
- data/app/models/forest_liana/model/action.rb +2 -1
- data/app/services/forest_liana/apimap_sorter.rb +1 -0
- data/app/services/forest_liana/resources_getter.rb +3 -3
- data/config/routes.rb +2 -0
- data/lib/forest_liana/bootstrapper.rb +19 -0
- data/lib/forest_liana/schema_file_updater.rb +1 -0
- data/lib/forest_liana/version.rb +1 -1
- data/spec/helpers/forest_liana/is_same_data_structure_helper_spec.rb +87 -0
- data/spec/requests/actions_controller_spec.rb +136 -0
- data/spec/services/forest_liana/apimap_sorter_spec.rb +6 -4
- data/spec/services/forest_liana/schema_adapter_spec.rb +1 -1
- metadata +7 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: e035848d2e7346973187338d78579301dcf062b2b6192ba383cd1f50dcccf584
|
|
4
|
+
data.tar.gz: 5f8a3ecdea7a8f4643922c27626397bfa3d497c14302f77f377153a22f064b0f
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: a30b760625155ae65acf9c8d6941e1e8ddd408b98cd377fdd6f6385c943ceef74e72cf3318d1373f966f8eda48dd9c35c4198bdaeecba2c9c6ffd52f2285e465
|
|
7
|
+
data.tar.gz: 52b468bfea30b0c115c318ab60eefd2caf382c94df171ea53ec0e203d6869d823f0deb23b20f66939f2560a8611d55b2c6b64f1dcb0b5ffb3d461de3471db8a5
|
|
@@ -1,7 +1,89 @@
|
|
|
1
1
|
module ForestLiana
|
|
2
2
|
class ActionsController < ForestLiana::BaseController
|
|
3
|
+
|
|
3
4
|
def values
|
|
4
5
|
render serializer: nil, json: {}, status: :ok
|
|
5
6
|
end
|
|
7
|
+
|
|
8
|
+
def get_collection(collection_name)
|
|
9
|
+
ForestLiana.apimap.find { |collection| collection.name.to_s == collection_name }
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def get_action(collection_name)
|
|
13
|
+
collection = get_collection(collection_name)
|
|
14
|
+
begin
|
|
15
|
+
collection.actions.find {|action| ActiveSupport::Inflector.parameterize(action.name) == params[:action_name]}
|
|
16
|
+
rescue => error
|
|
17
|
+
FOREST_LOGGER.error "Smart Action get action retrieval error: #{error}"
|
|
18
|
+
nil
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def get_record
|
|
23
|
+
model = ForestLiana::SchemaUtils.find_model_from_collection_name(params[:collectionName])
|
|
24
|
+
redord_getter = ForestLiana::ResourceGetter.new(model, {:id => params[:recordIds][0]})
|
|
25
|
+
redord_getter.perform
|
|
26
|
+
redord_getter.record
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def get_smart_action_load_ctx(fields)
|
|
30
|
+
fields = fields.reduce({}) {|p, c| p.update(c[:field] => c.merge!(value: nil))}
|
|
31
|
+
{:record => get_record, :fields => fields}
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def get_smart_action_change_ctx(fields)
|
|
35
|
+
fields = fields.reduce({}) {|p, c| p.update(c[:field] => c.permit!.to_h)}
|
|
36
|
+
{:record => get_record, :fields => fields}
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def handle_result(result, formatted_fields, action)
|
|
40
|
+
if result.nil? || !result.is_a?(Hash)
|
|
41
|
+
return render status: 500, json: { error: 'Error in smart action load hook: hook must return an object' }
|
|
42
|
+
end
|
|
43
|
+
is_same_data_structure = ForestLiana::IsSameDataStructureHelper::Analyser.new(formatted_fields, result, 1)
|
|
44
|
+
unless is_same_data_structure.perform
|
|
45
|
+
return render status: 500, json: { error: 'Error in smart action hook: fields must be unchanged (no addition nor deletion allowed)' }
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
# Apply result on fields (transform the object back to an array), preserve order.
|
|
49
|
+
fields = action.fields.map { |field| result[field[:field]] }
|
|
50
|
+
|
|
51
|
+
render serializer: nil, json: { fields: fields}, status: :ok
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def load
|
|
55
|
+
action = get_action(params[:collectionName])
|
|
56
|
+
|
|
57
|
+
if !action
|
|
58
|
+
render status: 500, json: {error: 'Error in smart action load hook: cannot retrieve action from collection'}
|
|
59
|
+
else
|
|
60
|
+
# Transform fields from array to an object to ease usage in hook, adds null value.
|
|
61
|
+
context = get_smart_action_load_ctx(action.fields)
|
|
62
|
+
formatted_fields = context[:fields].clone # clone for following test on is_same_data_structure
|
|
63
|
+
|
|
64
|
+
# Call the user-defined load hook.
|
|
65
|
+
result = action.hooks[:load].(context)
|
|
66
|
+
|
|
67
|
+
handle_result(result, formatted_fields, action)
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
def change
|
|
72
|
+
action = get_action(params[:collectionName])
|
|
73
|
+
|
|
74
|
+
if !action
|
|
75
|
+
render status: 500, json: {error: 'Error in smart action change hook: cannot retrieve action from collection'}
|
|
76
|
+
else
|
|
77
|
+
# Transform fields from array to an object to ease usage in hook.
|
|
78
|
+
context = get_smart_action_change_ctx(params[:fields])
|
|
79
|
+
formatted_fields = context[:fields].clone # clone for following test on is_same_data_structure
|
|
80
|
+
|
|
81
|
+
# Call the user-defined change hook.
|
|
82
|
+
field_name = params[:fields].select { |field| field[:value] != field[:previousValue] }[0][:field]
|
|
83
|
+
result = action.hooks[:change][field_name].(context)
|
|
84
|
+
|
|
85
|
+
handle_result(result, formatted_fields, action)
|
|
86
|
+
end
|
|
87
|
+
end
|
|
6
88
|
end
|
|
7
89
|
end
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
require 'set'
|
|
2
|
+
|
|
3
|
+
module ForestLiana
|
|
4
|
+
module IsSameDataStructureHelper
|
|
5
|
+
class Analyser
|
|
6
|
+
def initialize(object, other, deep = 0)
|
|
7
|
+
@object = object
|
|
8
|
+
@other = other
|
|
9
|
+
@deep = deep
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def are_objects(object, other)
|
|
13
|
+
object && other && object.is_a?(Hash) && other.is_a?(Hash)
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def check_keys(object, other, step = 0)
|
|
17
|
+
unless are_objects(object, other)
|
|
18
|
+
return false
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
object_keys = object.keys
|
|
22
|
+
other_keys = other.keys
|
|
23
|
+
|
|
24
|
+
if object_keys.length != other_keys.length
|
|
25
|
+
return false
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
object_keys_set = object_keys.to_set
|
|
29
|
+
other_keys.each { |key|
|
|
30
|
+
if !object_keys_set.member?(key) || (step + 1 <= @deep && !check_keys(object[key], other[key], step + 1))
|
|
31
|
+
return false
|
|
32
|
+
end
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
return true
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def perform
|
|
39
|
+
check_keys(@object, @other)
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
|
|
@@ -5,7 +5,7 @@ class ForestLiana::Model::Action
|
|
|
5
5
|
extend ActiveModel::Naming
|
|
6
6
|
|
|
7
7
|
attr_accessor :id, :name, :base_url, :endpoint, :http_method, :fields, :redirect,
|
|
8
|
-
:type, :download
|
|
8
|
+
:type, :download, :hooks
|
|
9
9
|
|
|
10
10
|
def initialize(attributes = {})
|
|
11
11
|
if attributes.key?(:global)
|
|
@@ -66,6 +66,7 @@ class ForestLiana::Model::Action
|
|
|
66
66
|
@base_url ||= nil
|
|
67
67
|
@type ||= "bulk"
|
|
68
68
|
@download ||= false
|
|
69
|
+
@hooks = !@hooks.nil? ? @hooks.symbolize_keys : nil
|
|
69
70
|
end
|
|
70
71
|
|
|
71
72
|
def persisted?
|
|
@@ -12,11 +12,11 @@ module ForestLiana
|
|
|
12
12
|
@collection = get_collection(@collection_name)
|
|
13
13
|
@fields_to_serialize = get_fields_to_serialize
|
|
14
14
|
@field_names_requested = field_names_requested
|
|
15
|
-
get_segment
|
|
16
|
-
compute_includes
|
|
15
|
+
get_segment
|
|
16
|
+
compute_includes
|
|
17
17
|
@search_query_builder = SearchQueryBuilder.new(@params, @includes, @collection)
|
|
18
18
|
|
|
19
|
-
prepare_query
|
|
19
|
+
prepare_query
|
|
20
20
|
end
|
|
21
21
|
|
|
22
22
|
def self.get_ids_from_request(params)
|
data/config/routes.rb
CHANGED
|
@@ -38,6 +38,14 @@ module ForestLiana
|
|
|
38
38
|
|
|
39
39
|
private
|
|
40
40
|
|
|
41
|
+
def get_collection(collection_name)
|
|
42
|
+
ForestLiana.apimap.find { |collection| collection.name.to_s == collection_name }
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def get_action(collection, action_name)
|
|
46
|
+
collection.actions.find {|action| action.name == action_name}
|
|
47
|
+
end
|
|
48
|
+
|
|
41
49
|
def generate_apimap
|
|
42
50
|
create_apimap
|
|
43
51
|
require_lib_forest_liana
|
|
@@ -45,6 +53,17 @@ module ForestLiana
|
|
|
45
53
|
|
|
46
54
|
if Rails.env.development?
|
|
47
55
|
@collections_sent = ForestLiana.apimap.as_json
|
|
56
|
+
|
|
57
|
+
@collections_sent.each do |collection|
|
|
58
|
+
collection['actions'].each do |action|
|
|
59
|
+
c = get_collection(collection['name'])
|
|
60
|
+
a = get_action(c, action['name'])
|
|
61
|
+
load = !a.hooks.nil? && a.hooks.key?(:load) && a.hooks[:load].is_a?(Proc)
|
|
62
|
+
change = !a.hooks.nil? && a.hooks.key?(:change) && a.hooks[:change].is_a?(Hash) ? a.hooks[:change].keys : []
|
|
63
|
+
action['hooks'] = {:load => load, :change => change}
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
|
|
48
67
|
@meta_sent = ForestLiana.meta
|
|
49
68
|
SchemaFileUpdater.new(SCHEMA_FILENAME, @collections_sent, @meta_sent).perform()
|
|
50
69
|
else
|
data/lib/forest_liana/version.rb
CHANGED
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
module ForestLiana
|
|
2
|
+
context 'IsSameDataStructure class' do
|
|
3
|
+
it 'should: be valid with simple data' do
|
|
4
|
+
object = {:a => 'a', :b => 'b'}
|
|
5
|
+
other = {:a => 'a', :b => 'b'}
|
|
6
|
+
result = IsSameDataStructureHelper::Analyser.new(object, other).perform
|
|
7
|
+
expect(result).to be true
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
it 'should: be invalid with simple data' do
|
|
11
|
+
object = {:a => 'a', :b => 'b'}
|
|
12
|
+
other = {:a => 'a', :c => 'c'}
|
|
13
|
+
result = IsSameDataStructureHelper::Analyser.new(object, other).perform
|
|
14
|
+
expect(result).to be false
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
it 'should: be invalid with not same hash' do
|
|
18
|
+
object = {:a => 'a', :b => 'b'}
|
|
19
|
+
other = {:a => 'a', :b => 'b', :c => 'c'}
|
|
20
|
+
result = IsSameDataStructureHelper::Analyser.new(object, other).perform
|
|
21
|
+
expect(result).to be false
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
it 'should: be invalid with nil' do
|
|
25
|
+
object = nil
|
|
26
|
+
other = {:a => 'a', :b => 'b', :c => 'c'}
|
|
27
|
+
result = IsSameDataStructureHelper::Analyser.new(object, other).perform
|
|
28
|
+
expect(result).to be false
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
it 'should: be invalid with not hash' do
|
|
32
|
+
object = nil
|
|
33
|
+
other = {:a => 'a', :b => 'b', :c => 'c'}
|
|
34
|
+
result = IsSameDataStructureHelper::Analyser.new(object, other).perform
|
|
35
|
+
expect(result).to be false
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
it 'should: be invalid with integer' do
|
|
39
|
+
object = 1
|
|
40
|
+
other = {:a => 'a', :b => 'b', :c => 'c'}
|
|
41
|
+
result = IsSameDataStructureHelper::Analyser.new(object, other).perform
|
|
42
|
+
expect(result).to be false
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
it 'should: be invalid with string' do
|
|
46
|
+
object = 'a'
|
|
47
|
+
other = {:a => 'a', :b => 'b', :c => 'c'}
|
|
48
|
+
result = IsSameDataStructureHelper::Analyser.new(object, other).perform
|
|
49
|
+
expect(result).to be false
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
it 'should: be valid with depth 1' do
|
|
53
|
+
object = {:a => {:c => 'c'}, :b => {:d => 'd'}}
|
|
54
|
+
other = {:a => {:c => 'c'}, :b => {:d => 'd'}}
|
|
55
|
+
result = IsSameDataStructureHelper::Analyser.new(object, other, 1).perform
|
|
56
|
+
expect(result).to be true
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
it 'should: be invalid with depth 1' do
|
|
60
|
+
object = {:a => {:c => 'c'}, :b => {:d => 'd'}}
|
|
61
|
+
other = {:a => {:c => 'c'}, :b => {:e => 'e'}}
|
|
62
|
+
result = IsSameDataStructureHelper::Analyser.new(object, other, 1).perform
|
|
63
|
+
expect(result).to be false
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
it 'should: be invalid with depth 1 and nil' do
|
|
67
|
+
object = {:a => {:c => 'c'}, :b => {:d => 'd'}}
|
|
68
|
+
other = {:a => {:c => 'c'}, :b => nil}
|
|
69
|
+
result = IsSameDataStructureHelper::Analyser.new(object, other, 1).perform
|
|
70
|
+
expect(result).to be false
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
it 'should: be invalid with depth 1 and integer' do
|
|
74
|
+
object = {:a => {:c => 'c'}, :b => {:d => 'd'}}
|
|
75
|
+
other = {:a => {:c => 'c'}, :b => 1}
|
|
76
|
+
result = IsSameDataStructureHelper::Analyser.new(object, other, 1).perform
|
|
77
|
+
expect(result).to be false
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
it 'should: be invalid with depth 1 and string' do
|
|
81
|
+
object = {:a => {:c => 'c'}, :b => {:d => 'd'}}
|
|
82
|
+
other = {:a => {:c => 'c'}, :b => 'b'}
|
|
83
|
+
result = IsSameDataStructureHelper::Analyser.new(object, other, 1).perform
|
|
84
|
+
expect(result).to be false
|
|
85
|
+
end
|
|
86
|
+
end
|
|
87
|
+
end
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
require 'rails_helper'
|
|
2
|
+
|
|
3
|
+
describe 'Requesting Actions routes', :type => :request do
|
|
4
|
+
before(:each) do
|
|
5
|
+
allow(ForestLiana::IpWhitelist).to receive(:is_ip_whitelist_retrieved) { true }
|
|
6
|
+
allow(ForestLiana::IpWhitelist).to receive(:is_ip_valid) { true }
|
|
7
|
+
Island.create(name: 'Corsica')
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
after(:each) do
|
|
11
|
+
Island.destroy_all
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
describe 'call /values' do
|
|
15
|
+
it 'should respond 200' do
|
|
16
|
+
post '/forest/actions/foo/values', {}
|
|
17
|
+
expect(response.status).to eq(200)
|
|
18
|
+
expect(response.body).to be {}
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
describe 'hooks' do
|
|
23
|
+
foo = {
|
|
24
|
+
field: 'foo',
|
|
25
|
+
type: 'String',
|
|
26
|
+
default_value: nil,
|
|
27
|
+
enums: nil,
|
|
28
|
+
is_required: false,
|
|
29
|
+
reference: nil,
|
|
30
|
+
description: nil,
|
|
31
|
+
widget: nil,
|
|
32
|
+
}
|
|
33
|
+
action_definition = {
|
|
34
|
+
name: 'my_action',
|
|
35
|
+
fields: [foo],
|
|
36
|
+
hooks: {
|
|
37
|
+
:load => -> (context) {
|
|
38
|
+
context[:fields]
|
|
39
|
+
},
|
|
40
|
+
:change => {
|
|
41
|
+
'foo' => -> (context) {
|
|
42
|
+
fields = context[:fields]
|
|
43
|
+
fields['foo'][:value] = 'baz'
|
|
44
|
+
return fields
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
fail_action_definition = {
|
|
50
|
+
name: 'fail_action',
|
|
51
|
+
fields: [foo],
|
|
52
|
+
hooks: {
|
|
53
|
+
:load => -> (context) {
|
|
54
|
+
1
|
|
55
|
+
},
|
|
56
|
+
:change => {
|
|
57
|
+
'foo' => -> (context) {
|
|
58
|
+
1
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
cheat_action_definition = {
|
|
64
|
+
name: 'cheat_action',
|
|
65
|
+
fields: [foo],
|
|
66
|
+
hooks: {
|
|
67
|
+
:load => -> (context) {
|
|
68
|
+
context[:fields]['baz'] = foo.clone.update({field: 'baz'})
|
|
69
|
+
context[:fields]
|
|
70
|
+
},
|
|
71
|
+
:change => {
|
|
72
|
+
'foo' => -> (context) {
|
|
73
|
+
context[:fields]['baz'] = foo.clone.update({field: 'baz'})
|
|
74
|
+
context[:fields]
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
action = ForestLiana::Model::Action.new(action_definition)
|
|
80
|
+
fail_action = ForestLiana::Model::Action.new(fail_action_definition)
|
|
81
|
+
cheat_action = ForestLiana::Model::Action.new(cheat_action_definition)
|
|
82
|
+
island = ForestLiana.apimap.find {|collection| collection.name.to_s == ForestLiana.name_for(Island)}
|
|
83
|
+
island.actions = [action, fail_action, cheat_action]
|
|
84
|
+
|
|
85
|
+
describe 'call /load' do
|
|
86
|
+
params = {recordIds: [1], collectionName: 'Island'}
|
|
87
|
+
|
|
88
|
+
it 'should respond 200' do
|
|
89
|
+
post '/forest/actions/my_action/hooks/load', JSON.dump(params), 'CONTENT_TYPE' => 'application/json'
|
|
90
|
+
expect(response.status).to eq(200)
|
|
91
|
+
expect(JSON.parse(response.body)).to eq({'fields' => [foo.merge({:value => nil}).stringify_keys]})
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
it 'should respond 500 with bad params' do
|
|
95
|
+
post '/forest/actions/my_action/hooks/load', {}
|
|
96
|
+
expect(response.status).to eq(500)
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
it 'should respond 500 with bad hook result type' do
|
|
100
|
+
post '/forest/actions/fail_action/hooks/load', JSON.dump(params), 'CONTENT_TYPE' => 'application/json'
|
|
101
|
+
expect(response.status).to eq(500)
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
it 'should respond 500 with bad hook result data structure' do
|
|
105
|
+
post '/forest/actions/cheat_action/hooks/load', JSON.dump(params), 'CONTENT_TYPE' => 'application/json'
|
|
106
|
+
expect(response.status).to eq(500)
|
|
107
|
+
end
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
describe 'call /change' do
|
|
111
|
+
updated_foo = foo.clone.merge({:previousValue => nil, :value => 'bar'})
|
|
112
|
+
params = {recordIds: [1], fields: [updated_foo], collectionName: 'Island'}
|
|
113
|
+
|
|
114
|
+
it 'should respond 200' do
|
|
115
|
+
post '/forest/actions/my_action/hooks/change', JSON.dump(params), 'CONTENT_TYPE' => 'application/json'
|
|
116
|
+
expect(response.status).to eq(200)
|
|
117
|
+
expect(JSON.parse(response.body)).to eq({'fields' => [updated_foo.merge({:value => 'baz'}).stringify_keys]})
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
it 'should respond 500 with bad params' do
|
|
121
|
+
post '/forest/actions/my_action/hooks/change', {}
|
|
122
|
+
expect(response.status).to eq(500)
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
it 'should respond 500 with bad hook result type' do
|
|
126
|
+
post '/forest/actions/fail_action/hooks/change', JSON.dump(params), 'CONTENT_TYPE' => 'application/json'
|
|
127
|
+
expect(response.status).to eq(500)
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
it 'should respond 500 with bad hook result data structure' do
|
|
131
|
+
post '/forest/actions/cheat_action/hooks/change', JSON.dump(params), 'CONTENT_TYPE' => 'application/json'
|
|
132
|
+
expect(response.status).to eq(500)
|
|
133
|
+
end
|
|
134
|
+
end
|
|
135
|
+
end
|
|
136
|
+
end
|
|
@@ -75,7 +75,8 @@ module ForestLiana
|
|
|
75
75
|
type: 'File',
|
|
76
76
|
field: 'File'
|
|
77
77
|
}],
|
|
78
|
-
http_method: nil
|
|
78
|
+
http_method: nil,
|
|
79
|
+
hooks: nil,
|
|
79
80
|
}
|
|
80
81
|
}, {
|
|
81
82
|
attributes: {
|
|
@@ -95,7 +96,8 @@ module ForestLiana
|
|
|
95
96
|
download: nil,
|
|
96
97
|
endpoint: nil,
|
|
97
98
|
redirect: nil,
|
|
98
|
-
'http_method': nil
|
|
99
|
+
'http_method': nil,
|
|
100
|
+
hooks: nil,
|
|
99
101
|
}
|
|
100
102
|
}]
|
|
101
103
|
}
|
|
@@ -148,8 +150,8 @@ module ForestLiana
|
|
|
148
150
|
end
|
|
149
151
|
|
|
150
152
|
it 'should sort the included actions and segments objects attributes values' do
|
|
151
|
-
expect(apimap_sorted['included'][0]['attributes'].keys).to eq(['name', 'endpoint', 'http_method', 'redirect', 'download'])
|
|
152
|
-
expect(apimap_sorted['included'][1]['attributes'].keys).to eq(['name', 'http_method', 'fields'])
|
|
153
|
+
expect(apimap_sorted['included'][0]['attributes'].keys).to eq(['name', 'endpoint', 'http_method', 'redirect', 'download', 'hooks'])
|
|
154
|
+
expect(apimap_sorted['included'][1]['attributes'].keys).to eq(['name', 'http_method', 'fields', 'hooks'])
|
|
153
155
|
expect(apimap_sorted['included'][2]['attributes'].keys).to eq(['name'])
|
|
154
156
|
expect(apimap_sorted['included'][3]['attributes'].keys).to eq(['name'])
|
|
155
157
|
end
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: forest_liana
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 5.
|
|
4
|
+
version: 5.3.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Sandro Munda
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2020-12-
|
|
11
|
+
date: 2020-12-07 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: rails
|
|
@@ -211,6 +211,7 @@ files:
|
|
|
211
211
|
- app/helpers/forest_liana/adapter_helper.rb
|
|
212
212
|
- app/helpers/forest_liana/application_helper.rb
|
|
213
213
|
- app/helpers/forest_liana/decoration_helper.rb
|
|
214
|
+
- app/helpers/forest_liana/is_same_data_structure_helper.rb
|
|
214
215
|
- app/helpers/forest_liana/query_helper.rb
|
|
215
216
|
- app/helpers/forest_liana/schema_helper.rb
|
|
216
217
|
- app/models/forest_liana/model/action.rb
|
|
@@ -336,9 +337,11 @@ files:
|
|
|
336
337
|
- spec/dummy/db/migrate/20190716130830_add_age_to_tree.rb
|
|
337
338
|
- spec/dummy/db/migrate/20190716135241_add_type_to_user.rb
|
|
338
339
|
- spec/dummy/db/schema.rb
|
|
340
|
+
- spec/helpers/forest_liana/is_same_data_structure_helper_spec.rb
|
|
339
341
|
- spec/helpers/forest_liana/query_helper_spec.rb
|
|
340
342
|
- spec/helpers/forest_liana/schema_helper_spec.rb
|
|
341
343
|
- spec/rails_helper.rb
|
|
344
|
+
- spec/requests/actions_controller_spec.rb
|
|
342
345
|
- spec/requests/resources_spec.rb
|
|
343
346
|
- spec/services/forest_liana/apimap_sorter_spec.rb
|
|
344
347
|
- spec/services/forest_liana/filters_parser_spec.rb
|
|
@@ -556,6 +559,7 @@ test_files:
|
|
|
556
559
|
- spec/services/forest_liana/apimap_sorter_spec.rb
|
|
557
560
|
- spec/services/forest_liana/filters_parser_spec.rb
|
|
558
561
|
- spec/spec_helper.rb
|
|
562
|
+
- spec/requests/actions_controller_spec.rb
|
|
559
563
|
- spec/requests/resources_spec.rb
|
|
560
564
|
- spec/dummy/README.rdoc
|
|
561
565
|
- spec/dummy/app/views/layouts/application.html.erb
|
|
@@ -598,5 +602,6 @@ test_files:
|
|
|
598
602
|
- spec/dummy/config/initializers/backtrace_silencers.rb
|
|
599
603
|
- spec/dummy/config/database.yml
|
|
600
604
|
- spec/helpers/forest_liana/schema_helper_spec.rb
|
|
605
|
+
- spec/helpers/forest_liana/is_same_data_structure_helper_spec.rb
|
|
601
606
|
- spec/helpers/forest_liana/query_helper_spec.rb
|
|
602
607
|
- spec/rails_helper.rb
|