forest_liana 6.3.8 → 7.0.0.beta.2
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 +44 -29
- data/app/controllers/forest_liana/application_controller.rb +2 -2
- data/app/controllers/forest_liana/associations_controller.rb +1 -1
- data/app/controllers/forest_liana/base_controller.rb +1 -1
- data/app/controllers/forest_liana/resources_controller.rb +6 -6
- data/app/serializers/forest_liana/intercom_attribute_serializer.rb +1 -1
- data/app/serializers/forest_liana/intercom_conversation_serializer.rb +1 -1
- data/app/serializers/forest_liana/mixpanel_event_serializer.rb +1 -1
- data/app/serializers/forest_liana/serializer_factory.rb +1 -1
- data/app/serializers/forest_liana/stat_serializer.rb +1 -1
- data/app/serializers/forest_liana/stripe_bank_account_serializer.rb +1 -1
- data/app/serializers/forest_liana/stripe_card_serializer.rb +1 -1
- data/app/serializers/forest_liana/stripe_invoice_serializer.rb +1 -1
- data/app/serializers/forest_liana/stripe_payment_serializer.rb +1 -1
- data/app/serializers/forest_liana/stripe_subscription_serializer.rb +1 -1
- data/app/services/forest_liana/apimap_sorter.rb +1 -0
- data/app/services/forest_liana/smart_action_field_validator.rb +49 -0
- data/config/initializers/errors.rb +17 -0
- data/config/initializers/logger.rb +16 -13
- data/lib/forest_liana.rb +2 -0
- data/lib/forest_liana/bootstrapper.rb +2 -2
- data/lib/forest_liana/schema_file_updater.rb +8 -0
- data/lib/forest_liana/version.rb +1 -1
- data/spec/config/initializers/logger_spec.rb +30 -0
- data/spec/lib/forest_liana/schema_file_updater_spec.rb +94 -0
- data/spec/requests/actions_controller_spec.rb +22 -20
- data/spec/services/forest_liana/smart_action_field_validator_spec.rb +70 -0
- metadata +12 -8
- data/app/helpers/forest_liana/is_same_data_structure_helper.rb +0 -44
- data/spec/helpers/forest_liana/is_same_data_structure_helper_spec.rb +0 -87
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6be4888e921b11142c5bc7774e6a0c9ce9a91b7e0b8ceb8a812cff8e297b540a
|
4
|
+
data.tar.gz: '043584e75c96d49b34a4ab6ec0e0f0315700eb86a7d061fb03de66c095840b1c'
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: bfc23dfba08023225f17e44860caf95dc2fe041bcf81a1d61651ee96cea59563aa2c97ee6a1bcdc2e38e2e56a0f9c7c5e144b64583286af70864ec4d636a5795
|
7
|
+
data.tar.gz: 2cc2bf17cc1a235264db9981e33e99b22c23468514bf136e3379523020ca1efd906b792b46c45b6893f0edb279d8845c79e2e14ee8821ee47db6fc87d4992692
|
@@ -27,34 +27,45 @@ module ForestLiana
|
|
27
27
|
end
|
28
28
|
|
29
29
|
def get_smart_action_load_ctx(fields)
|
30
|
-
fields = fields.
|
31
|
-
ForestLiana::WidgetsHelper.set_field_widget(
|
32
|
-
|
30
|
+
fields = fields.map do |field|
|
31
|
+
ForestLiana::WidgetsHelper.set_field_widget(field)
|
32
|
+
field[:value] = nil unless field[:value]
|
33
|
+
field
|
33
34
|
end
|
34
35
|
{:record => get_record, :fields => fields}
|
35
36
|
end
|
36
37
|
|
37
|
-
def get_smart_action_change_ctx(fields)
|
38
|
-
|
39
|
-
|
38
|
+
def get_smart_action_change_ctx(fields, field_changed)
|
39
|
+
found_field_changed = fields.find{|field| field[:field] == field_changed}
|
40
|
+
fields = fields.map do |field|
|
41
|
+
field = field.permit!.to_h.symbolize_keys
|
40
42
|
ForestLiana::WidgetsHelper.set_field_widget(field)
|
41
|
-
|
43
|
+
field
|
42
44
|
end
|
43
|
-
{:record => get_record, :fields => fields}
|
45
|
+
{:record => get_record, :field_changed => found_field_changed, :fields => fields}
|
44
46
|
end
|
45
47
|
|
46
|
-
def handle_result(result,
|
47
|
-
if result.nil? || !result.is_a?(
|
48
|
-
return render status: 500, json: { error: 'Error in smart action load hook: hook must return an
|
48
|
+
def handle_result(result, action)
|
49
|
+
if result.nil? || !result.is_a?(Array)
|
50
|
+
return render status: 500, json: { error: 'Error in smart action load hook: hook must return an array of fields' }
|
49
51
|
end
|
50
|
-
|
51
|
-
|
52
|
-
|
52
|
+
|
53
|
+
# Validate that the fields are well formed.
|
54
|
+
begin
|
55
|
+
# action.hooks[:change] is a hashmap here
|
56
|
+
# to do the validation, only the hook names are require
|
57
|
+
change_hooks_name = action.hooks[:change].nil? ? nil : action.hooks[:change].keys
|
58
|
+
ForestLiana::SmartActionFieldValidator.validate_smart_action_fields(result, action.name, change_hooks_name)
|
59
|
+
rescue ForestLiana::Errors::SmartActionInvalidFieldError => invalid_field_error
|
60
|
+
FOREST_LOGGER.warn invalid_field_error.message
|
61
|
+
rescue ForestLiana::Errors::SmartActionInvalidFieldHookError => invalid_hook_error
|
62
|
+
FOREST_LOGGER.error invalid_hook_error.message
|
63
|
+
return render status: 500, json: { error: invalid_hook_error.message }
|
53
64
|
end
|
54
65
|
|
55
66
|
# Apply result on fields (transform the object back to an array), preserve order.
|
56
|
-
fields =
|
57
|
-
updated_field = result[field[:field]
|
67
|
+
fields = result.map do |field|
|
68
|
+
updated_field = result.find{|f| f[:field] == field[:field]}
|
58
69
|
|
59
70
|
# Reset `value` when not present in `enums` (which means `enums` has changed).
|
60
71
|
if updated_field[:enums].is_a?(Array)
|
@@ -72,7 +83,7 @@ module ForestLiana
|
|
72
83
|
updated_field
|
73
84
|
end
|
74
85
|
|
75
|
-
render serializer: nil, json: { fields: fields}, status: :ok
|
86
|
+
render serializer: nil, json: { fields: fields }, status: :ok
|
76
87
|
end
|
77
88
|
|
78
89
|
def load
|
@@ -81,14 +92,13 @@ module ForestLiana
|
|
81
92
|
if !action
|
82
93
|
render status: 500, json: {error: 'Error in smart action load hook: cannot retrieve action from collection'}
|
83
94
|
else
|
84
|
-
#
|
95
|
+
# Get the smart action hook load context
|
85
96
|
context = get_smart_action_load_ctx(action.fields)
|
86
|
-
formatted_fields = context[:fields].clone # clone for following test on is_same_data_structure
|
87
97
|
|
88
98
|
# Call the user-defined load hook.
|
89
99
|
result = action.hooks[:load].(context)
|
90
100
|
|
91
|
-
handle_result(result,
|
101
|
+
handle_result(result, action)
|
92
102
|
end
|
93
103
|
end
|
94
104
|
|
@@ -96,17 +106,22 @@ module ForestLiana
|
|
96
106
|
action = get_action(params[:collectionName])
|
97
107
|
|
98
108
|
if !action
|
99
|
-
render status: 500, json: {error: 'Error in smart action change hook: cannot retrieve action from collection'}
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
109
|
+
return render status: 500, json: {error: 'Error in smart action change hook: cannot retrieve action from collection'}
|
110
|
+
elsif params[:fields].nil?
|
111
|
+
return render status: 500, json: {error: 'Error in smart action change hook: fields params is mandatory'}
|
112
|
+
elsif !params[:fields].is_a?(Array)
|
113
|
+
return render status: 500, json: {error: 'Error in smart action change hook: fields params must be an array'}
|
114
|
+
end
|
104
115
|
|
105
|
-
|
106
|
-
|
116
|
+
# Get the smart action hook change context
|
117
|
+
context = get_smart_action_change_ctx(params[:fields], params[:changedField])
|
107
118
|
|
108
|
-
|
109
|
-
|
119
|
+
field_changed_hook = context[:field_changed][:hook]
|
120
|
+
|
121
|
+
# Call the user-defined change hook.
|
122
|
+
result = action.hooks[:change][field_changed_hook].(context)
|
123
|
+
|
124
|
+
handle_result(result, action)
|
110
125
|
end
|
111
126
|
end
|
112
127
|
end
|
@@ -34,14 +34,14 @@ module ForestLiana
|
|
34
34
|
|
35
35
|
def serialize_model(record, options = {})
|
36
36
|
options[:is_collection] = false
|
37
|
-
json = JSONAPI::Serializer.serialize(record, options)
|
37
|
+
json = ForestAdmin::JSONAPI::Serializer.serialize(record, options)
|
38
38
|
|
39
39
|
force_utf8_encoding(json)
|
40
40
|
end
|
41
41
|
|
42
42
|
def serialize_models(records, options = {}, fields_searched = [])
|
43
43
|
options[:is_collection] = true
|
44
|
-
json = JSONAPI::Serializer.serialize(records, options)
|
44
|
+
json = ForestAdmin::JSONAPI::Serializer.serialize(records, options)
|
45
45
|
|
46
46
|
if options[:params] && options[:params][:search]
|
47
47
|
# NOTICE: Add the Smart Fields with a 'String' type.
|
@@ -41,7 +41,7 @@ module ForestLiana
|
|
41
41
|
updater.perform
|
42
42
|
|
43
43
|
if updater.errors
|
44
|
-
render serializer: nil, json: JSONAPI::Serializer.serialize_errors(
|
44
|
+
render serializer: nil, json: ForestAdmin::JSONAPI::Serializer.serialize_errors(
|
45
45
|
updater.errors), status: 422
|
46
46
|
else
|
47
47
|
head :no_content
|
@@ -24,7 +24,7 @@ module ForestLiana
|
|
24
24
|
end
|
25
25
|
end
|
26
26
|
rescue ForestLiana::Errors::ExpectedError => exception
|
27
|
-
error_data = JSONAPI::Serializer.serialize_errors([{
|
27
|
+
error_data = ForestAdmin::JSONAPI::Serializer.serialize_errors([{
|
28
28
|
status: exception.error_code,
|
29
29
|
detail: exception.message
|
30
30
|
}])
|
@@ -41,7 +41,7 @@ module ForestLiana
|
|
41
41
|
status: :unprocessable_entity, serializer: nil
|
42
42
|
rescue ForestLiana::Errors::ExpectedError => error
|
43
43
|
error.display_error
|
44
|
-
error_data = JSONAPI::Serializer.serialize_errors([{
|
44
|
+
error_data = ForestAdmin::JSONAPI::Serializer.serialize_errors([{
|
45
45
|
status: error.error_code,
|
46
46
|
detail: error.message
|
47
47
|
}])
|
@@ -73,7 +73,7 @@ module ForestLiana
|
|
73
73
|
status: :unprocessable_entity, serializer: nil
|
74
74
|
rescue ForestLiana::Errors::ExpectedError => error
|
75
75
|
error.display_error
|
76
|
-
error_data = JSONAPI::Serializer.serialize_errors([{
|
76
|
+
error_data = ForestAdmin::JSONAPI::Serializer.serialize_errors([{
|
77
77
|
status: error.error_code,
|
78
78
|
detail: error.message
|
79
79
|
}])
|
@@ -108,12 +108,12 @@ module ForestLiana
|
|
108
108
|
creator.perform
|
109
109
|
|
110
110
|
if creator.errors
|
111
|
-
render serializer: nil, json: JSONAPI::Serializer.serialize_errors(
|
111
|
+
render serializer: nil, json: ForestAdmin::JSONAPI::Serializer.serialize_errors(
|
112
112
|
creator.errors), status: 400
|
113
113
|
elsif creator.record.valid?
|
114
114
|
render serializer: nil, json: render_record_jsonapi(creator.record)
|
115
115
|
else
|
116
|
-
render serializer: nil, json: JSONAPI::Serializer.serialize_errors(
|
116
|
+
render serializer: nil, json: ForestAdmin::JSONAPI::Serializer.serialize_errors(
|
117
117
|
creator.record.errors), status: 400
|
118
118
|
end
|
119
119
|
rescue => error
|
@@ -131,12 +131,12 @@ module ForestLiana
|
|
131
131
|
updater.perform
|
132
132
|
|
133
133
|
if updater.errors
|
134
|
-
render serializer: nil, json: JSONAPI::Serializer.serialize_errors(
|
134
|
+
render serializer: nil, json: ForestAdmin::JSONAPI::Serializer.serialize_errors(
|
135
135
|
updater.errors), status: 400
|
136
136
|
elsif updater.record.valid?
|
137
137
|
render serializer: nil, json: render_record_jsonapi(updater.record)
|
138
138
|
else
|
139
|
-
render serializer: nil, json: JSONAPI::Serializer.serialize_errors(
|
139
|
+
render serializer: nil, json: ForestAdmin::JSONAPI::Serializer.serialize_errors(
|
140
140
|
updater.record.errors), status: 400
|
141
141
|
end
|
142
142
|
rescue => error
|
@@ -0,0 +1,49 @@
|
|
1
|
+
module ForestLiana
|
2
|
+
class SmartActionFieldValidator
|
3
|
+
|
4
|
+
@@accepted_primitive_field_type = [
|
5
|
+
'String',
|
6
|
+
'Number',
|
7
|
+
'Date',
|
8
|
+
'Boolean',
|
9
|
+
'File',
|
10
|
+
'Enum',
|
11
|
+
'Json',
|
12
|
+
'Dateonly',
|
13
|
+
]
|
14
|
+
|
15
|
+
@@accepted_array_field_type = [
|
16
|
+
'String',
|
17
|
+
'Number',
|
18
|
+
'Date',
|
19
|
+
'boolean',
|
20
|
+
'File',
|
21
|
+
'Enum',
|
22
|
+
]
|
23
|
+
|
24
|
+
def self.validate_field(field, action_name)
|
25
|
+
raise ForestLiana::Errors::SmartActionInvalidFieldError.new(action_name, nil, "The field attribute must be defined") if !field || field[:field].nil?
|
26
|
+
raise ForestLiana::Errors::SmartActionInvalidFieldError.new(action_name, nil, "The field attribute must be a string.") if !field[:field].is_a?(String)
|
27
|
+
raise ForestLiana::Errors::SmartActionInvalidFieldError.new(action_name, field[:field], "The description attribute must be a string.") if field[:description] && !field[:description].is_a?(String)
|
28
|
+
raise ForestLiana::Errors::SmartActionInvalidFieldError.new(action_name, field[:field], "The enums attribute must be an array.") if field[:enums] && !field[:enums].is_a?(Array)
|
29
|
+
raise ForestLiana::Errors::SmartActionInvalidFieldError.new(action_name, field[:field], "The reference attribute must be a string.") if field[:reference] && !field[:reference].is_a?(String)
|
30
|
+
|
31
|
+
is_type_valid = field[:type].is_a?(Array) ?
|
32
|
+
@@accepted_array_field_type.include?(field[:type][0]) :
|
33
|
+
@@accepted_primitive_field_type.include?(field[:type])
|
34
|
+
|
35
|
+
raise ForestLiana::Errors::SmartActionInvalidFieldError.new(action_name, field[:field], "The type attribute must be a valid type. See the documentation for more information. https://docs.forestadmin.com/documentation/reference-guide/fields/create-and-manage-smart-fields#available-field-options.") if !is_type_valid
|
36
|
+
end
|
37
|
+
|
38
|
+
def self.validate_field_change_hook(field, action_name, hooks)
|
39
|
+
raise ForestLiana::Errors::SmartActionInvalidFieldHookError.new(action_name, field[:field], field[:hook]) if field[:hook] && !hooks.find{|hook| hook == field[:hook]}
|
40
|
+
end
|
41
|
+
|
42
|
+
def self.validate_smart_action_fields(fields, action_name, change_hooks)
|
43
|
+
fields.map{|field|
|
44
|
+
self.validate_field(field.symbolize_keys, action_name)
|
45
|
+
self.validate_field_change_hook(field.symbolize_keys, action_name, change_hooks) if change_hooks
|
46
|
+
}
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -13,6 +13,23 @@ module ForestLiana
|
|
13
13
|
end
|
14
14
|
end
|
15
15
|
|
16
|
+
class SmartActionInvalidFieldError < StandardError
|
17
|
+
def initialize(action_name=nil, field_name=nil, message=nil)
|
18
|
+
error_message = ""
|
19
|
+
error_message << "Error while parsing action \"#{action_name}\"" if !action_name.nil?
|
20
|
+
error_message << " on field \"#{field_name}\"" if !field_name.nil?
|
21
|
+
error_message << ": " if !field_name.nil? || !action_name.nil?
|
22
|
+
error_message << message if !message.nil?
|
23
|
+
super(error_message)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
class SmartActionInvalidFieldHookError < StandardError
|
28
|
+
def initialize(action_name=nil, field_name=nil, hook_name=nil)
|
29
|
+
super("The hook \"#{hook_name}\" of \"#{field_name}\" field on the smart action \"#{action_name}\" is not defined.")
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
16
33
|
class ExpectedError < StandardError
|
17
34
|
attr_reader :error_code, :status, :message, :name
|
18
35
|
|
@@ -3,21 +3,24 @@ module ForestLiana
|
|
3
3
|
class Logger
|
4
4
|
class << self
|
5
5
|
def log
|
6
|
-
logger
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
6
|
+
if ForestLiana.logger != nil
|
7
|
+
logger = ForestLiana.logger
|
8
|
+
else
|
9
|
+
logger = ::Logger.new(STDOUT)
|
10
|
+
logger_colors = {
|
11
|
+
DEBUG: 34,
|
12
|
+
WARN: 33,
|
13
|
+
ERROR: 31,
|
14
|
+
INFO: 37
|
15
|
+
}
|
13
16
|
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
17
|
+
logger.formatter = proc do |severity, datetime, progname, message|
|
18
|
+
displayed_message = "[#{datetime.to_s(:db)}] Forest 🌳🌳🌳 " \
|
19
|
+
"#{message}\n"
|
20
|
+
"\e[#{logger_colors[severity.to_sym]}m#{displayed_message}\033[0m"
|
21
|
+
end
|
22
|
+
logger
|
18
23
|
end
|
19
|
-
|
20
|
-
logger
|
21
24
|
end
|
22
25
|
end
|
23
26
|
end
|
data/lib/forest_liana.rb
CHANGED
@@ -27,6 +27,7 @@ module ForestLiana
|
|
27
27
|
mattr_accessor :user_class_name
|
28
28
|
mattr_accessor :names_overriden
|
29
29
|
mattr_accessor :meta
|
30
|
+
mattr_accessor :logger
|
30
31
|
# TODO: Remove once lianas prior to 2.0.0 are not supported anymore.
|
31
32
|
mattr_accessor :names_old_overriden
|
32
33
|
|
@@ -38,6 +39,7 @@ module ForestLiana
|
|
38
39
|
self.user_class_name = nil
|
39
40
|
self.names_overriden = {}
|
40
41
|
self.meta = {}
|
42
|
+
self.logger = nil
|
41
43
|
|
42
44
|
@config_dir = 'lib/forest_liana/**/*.rb'
|
43
45
|
|
@@ -60,7 +60,7 @@ module ForestLiana
|
|
60
60
|
a = get_action(c, action['name'])
|
61
61
|
load = !a.hooks.nil? && a.hooks.key?(:load) && a.hooks[:load].is_a?(Proc)
|
62
62
|
change = !a.hooks.nil? && a.hooks.key?(:change) && a.hooks[:change].is_a?(Hash) ? a.hooks[:change].keys : []
|
63
|
-
action['hooks'] = {
|
63
|
+
action['hooks'] = {'load' => load, 'change' => change}
|
64
64
|
end
|
65
65
|
end
|
66
66
|
end
|
@@ -139,7 +139,7 @@ module ForestLiana
|
|
139
139
|
|
140
140
|
# Monkey patch the find_serializer_class_name method to specify the
|
141
141
|
# good serializer to use.
|
142
|
-
::JSONAPI::Serializer.class_eval do
|
142
|
+
::ForestAdmin::JSONAPI::Serializer.class_eval do
|
143
143
|
def self.find_serializer_class_name(record, options)
|
144
144
|
if record.respond_to?(:jsonapi_serializer_class_name)
|
145
145
|
record.jsonapi_serializer_class_name.to_s
|
@@ -63,6 +63,7 @@ module ForestLiana
|
|
63
63
|
'description',
|
64
64
|
'position',
|
65
65
|
'widget',
|
66
|
+
'hook',
|
66
67
|
]
|
67
68
|
KEYS_SEGMENT = ['name']
|
68
69
|
|
@@ -96,6 +97,13 @@ module ForestLiana
|
|
96
97
|
end
|
97
98
|
|
98
99
|
collection['actions'] = collection['actions'].map do |action|
|
100
|
+
begin
|
101
|
+
SmartActionFieldValidator.validate_smart_action_fields(action['fields'], action['name'], action['hooks']['change'])
|
102
|
+
rescue ForestLiana::Errors::SmartActionInvalidFieldError => invalid_field_error
|
103
|
+
FOREST_LOGGER.warn invalid_field_error.message
|
104
|
+
rescue ForestLiana::Errors::SmartActionInvalidFieldHookError => invalid_hook_error
|
105
|
+
FOREST_LOGGER.error invalid_hook_error.message
|
106
|
+
end
|
99
107
|
action['fields'] = action['fields'].map { |field| field.slice(*KEYS_ACTION_FIELD) }
|
100
108
|
action.slice(*KEYS_ACTION)
|
101
109
|
end
|
data/lib/forest_liana/version.rb
CHANGED
@@ -0,0 +1,30 @@
|
|
1
|
+
module ForestLiana
|
2
|
+
describe Logger do
|
3
|
+
describe 'self.log' do
|
4
|
+
describe 'with a logger overload' do
|
5
|
+
it 'should return the given logger' do
|
6
|
+
logger = ActiveSupport::Logger.new($stdout)
|
7
|
+
logger.formatter = proc do |severity, datetime, progname, msg|
|
8
|
+
{:message => msg}.to_json
|
9
|
+
end
|
10
|
+
ForestLiana.logger = logger
|
11
|
+
|
12
|
+
expect(Logger.log.is_a?(ActiveSupport::Logger)).to be_truthy
|
13
|
+
expect { Logger.log.error "[error] override logger" }.to output({:message => "[error] override logger"}.to_json).to_stdout_from_any_process
|
14
|
+
expect { Logger.log.info "[info] override logger" }.to output({:message => "[info] override logger"}.to_json).to_stdout_from_any_process
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
describe 'with no logger overload' do
|
19
|
+
it 'should return an instance of ::Logger' do
|
20
|
+
ForestLiana.logger = nil
|
21
|
+
|
22
|
+
expect(Logger.log.is_a?(::Logger)).to be_truthy
|
23
|
+
# RegExp is used to check for the forestadmin logger format
|
24
|
+
expect { Logger.log.error "[error] default logger" }.to output(/\[\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}\] Forest .* \[error\]/).to_stdout_from_any_process
|
25
|
+
expect { Logger.log.info "[info] default logger" }.to output(/\[\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}\] Forest .* \[info\]/).to_stdout_from_any_process
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,94 @@
|
|
1
|
+
module ForestLiana
|
2
|
+
describe SchemaFileUpdater do
|
3
|
+
describe "initialize" do
|
4
|
+
describe "without any collections nor meta" do
|
5
|
+
it "should set collections as an empty array and meta as an empty object" do
|
6
|
+
schema_file_updater = ForestLiana::SchemaFileUpdater.new("test.txt", [], {})
|
7
|
+
expect(schema_file_updater.instance_variable_get(:@collections)).to eq([])
|
8
|
+
expect(schema_file_updater.instance_variable_get(:@meta)).to eq({})
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
describe "with a given collection" do
|
13
|
+
describe "when the collection has a smart action action" do
|
14
|
+
it "should save the smart action" do
|
15
|
+
collections = [{
|
16
|
+
"fields" => [],
|
17
|
+
"actions" => [{
|
18
|
+
"fields" => [],
|
19
|
+
"name" => "test",
|
20
|
+
"hooks" => {
|
21
|
+
"change" => []
|
22
|
+
}
|
23
|
+
}],
|
24
|
+
"segments" => []
|
25
|
+
}]
|
26
|
+
schema_file_updater = ForestLiana::SchemaFileUpdater.new("test.txt", collections, {})
|
27
|
+
expect(schema_file_updater.instance_variable_get(:@collections))
|
28
|
+
.to eq(collections)
|
29
|
+
end
|
30
|
+
|
31
|
+
describe "when a smart action field is malformed" do
|
32
|
+
it "should display a warning message" do
|
33
|
+
collections = [{
|
34
|
+
"fields" => [],
|
35
|
+
"actions" => [{
|
36
|
+
"fields" => [{}],
|
37
|
+
"name" => "test",
|
38
|
+
"hooks" => {
|
39
|
+
"change" => []
|
40
|
+
}
|
41
|
+
}],
|
42
|
+
"segments" => []
|
43
|
+
}]
|
44
|
+
allow(FOREST_LOGGER).to receive(:warn)
|
45
|
+
schema_file_updater = ForestLiana::SchemaFileUpdater.new("test.txt", collections, {})
|
46
|
+
expect(FOREST_LOGGER).to have_received(:warn).with('Error while parsing action "test": The field attribute must be defined')
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
describe "when a smart action change field hook does not exist" do
|
51
|
+
it "should display an error message" do
|
52
|
+
collections = [{
|
53
|
+
"fields" => [],
|
54
|
+
"actions" => [{
|
55
|
+
"fields" => [{
|
56
|
+
"field" => "testField",
|
57
|
+
"hook" => "undefinedHook",
|
58
|
+
"type" => "String",
|
59
|
+
}],
|
60
|
+
"name" => "test",
|
61
|
+
"hooks" => {
|
62
|
+
"change" => []
|
63
|
+
}
|
64
|
+
}],
|
65
|
+
"segments" => []
|
66
|
+
}]
|
67
|
+
|
68
|
+
allow(FOREST_LOGGER).to receive(:error)
|
69
|
+
schema_file_updater = ForestLiana::SchemaFileUpdater.new("test.txt", collections, {})
|
70
|
+
expect(FOREST_LOGGER).to have_received(:error).with('The hook "undefinedHook" of "testField" field on the smart action "test" is not defined.')
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
describe "perform" do
|
78
|
+
it "should call file puts with pretty printed data" do
|
79
|
+
file = instance_double(File, read: "stubbed read")
|
80
|
+
|
81
|
+
allow(File).to receive(:open).with("test.txt", "w") { |&block| block.call(file) }
|
82
|
+
|
83
|
+
schema_file_updater = ForestLiana::SchemaFileUpdater.new("test.txt", [], {})
|
84
|
+
expected_result = schema_file_updater.pretty_print({
|
85
|
+
"collections" => [],
|
86
|
+
"meta" => {}
|
87
|
+
})
|
88
|
+
|
89
|
+
expect(file).to receive(:puts).with(expected_result)
|
90
|
+
schema_file_updater.perform
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
@@ -30,6 +30,7 @@ describe 'Requesting Actions routes', :type => :request do
|
|
30
30
|
reference: nil,
|
31
31
|
description: nil,
|
32
32
|
widget: nil,
|
33
|
+
hook: 'on_foo_changed'
|
33
34
|
}
|
34
35
|
enum = {
|
35
36
|
field: 'enum',
|
@@ -50,10 +51,10 @@ describe 'Requesting Actions routes', :type => :request do
|
|
50
51
|
context[:fields]
|
51
52
|
},
|
52
53
|
:change => {
|
53
|
-
'
|
54
|
-
|
55
|
-
|
56
|
-
|
54
|
+
'on_foo_changed' => -> (context) {
|
55
|
+
foo = context[:fields].find{|field| field[:field] == 'foo'}
|
56
|
+
foo[:value] = 'baz'
|
57
|
+
context[:fields]
|
57
58
|
}
|
58
59
|
}
|
59
60
|
}
|
@@ -66,7 +67,7 @@ describe 'Requesting Actions routes', :type => :request do
|
|
66
67
|
1
|
67
68
|
},
|
68
69
|
:change => {
|
69
|
-
'
|
70
|
+
'on_foo_changed' => -> (context) {
|
70
71
|
1
|
71
72
|
}
|
72
73
|
}
|
@@ -77,11 +78,10 @@ describe 'Requesting Actions routes', :type => :request do
|
|
77
78
|
fields: [foo],
|
78
79
|
hooks: {
|
79
80
|
:load => -> (context) {
|
80
|
-
|
81
|
-
context[:fields]
|
81
|
+
{}
|
82
82
|
},
|
83
83
|
:change => {
|
84
|
-
'
|
84
|
+
'on_foo_changed' => -> (context) {
|
85
85
|
context[:fields]['baz'] = foo.clone.update({field: 'baz'})
|
86
86
|
context[:fields]
|
87
87
|
}
|
@@ -93,10 +93,11 @@ describe 'Requesting Actions routes', :type => :request do
|
|
93
93
|
fields: [foo, enum],
|
94
94
|
hooks: {
|
95
95
|
:change => {
|
96
|
-
'
|
96
|
+
'on_foo_changed' => -> (context) {
|
97
97
|
fields = context[:fields]
|
98
|
-
fields[
|
99
|
-
|
98
|
+
enum_field = fields.find{|field| field[:field] == 'enum'}
|
99
|
+
enum_field[:enums] = %w[c d e]
|
100
|
+
fields
|
100
101
|
}
|
101
102
|
}
|
102
103
|
}
|
@@ -107,10 +108,11 @@ describe 'Requesting Actions routes', :type => :request do
|
|
107
108
|
fields: [foo, multiple_enum],
|
108
109
|
hooks: {
|
109
110
|
:change => {
|
110
|
-
'
|
111
|
+
'on_foo_changed' => -> (context) {
|
111
112
|
fields = context[:fields]
|
112
|
-
fields[
|
113
|
-
|
113
|
+
enum_field = fields.find{|field| field[:field] == 'multipleEnum'}
|
114
|
+
enum_field[:enums] = %w[c d z]
|
115
|
+
fields
|
114
116
|
}
|
115
117
|
}
|
116
118
|
}
|
@@ -136,16 +138,19 @@ describe 'Requesting Actions routes', :type => :request do
|
|
136
138
|
it 'should respond 500 with bad params' do
|
137
139
|
post '/forest/actions/my_action/hooks/load', params: {}
|
138
140
|
expect(response.status).to eq(500)
|
141
|
+
expect(JSON.parse(response.body)).to eq({'error' => 'Error in smart action load hook: cannot retrieve action from collection'})
|
139
142
|
end
|
140
143
|
|
141
144
|
it 'should respond 500 with bad hook result type' do
|
142
145
|
post '/forest/actions/fail_action/hooks/load', params: JSON.dump(params), headers: { 'CONTENT_TYPE' => 'application/json' }
|
143
146
|
expect(response.status).to eq(500)
|
147
|
+
expect(JSON.parse(response.body)).to eq({'error' => 'Error in smart action load hook: hook must return an array of fields'})
|
144
148
|
end
|
145
149
|
|
146
150
|
it 'should respond 500 with bad hook result data structure' do
|
147
151
|
post '/forest/actions/cheat_action/hooks/load', params: JSON.dump(params), headers: { 'CONTENT_TYPE' => 'application/json' }
|
148
152
|
expect(response.status).to eq(500)
|
153
|
+
expect(JSON.parse(response.body)).to eq({'error' => 'Error in smart action load hook: hook must return an array of fields'})
|
149
154
|
end
|
150
155
|
end
|
151
156
|
|
@@ -163,18 +168,15 @@ describe 'Requesting Actions routes', :type => :request do
|
|
163
168
|
end
|
164
169
|
|
165
170
|
it 'should respond 500 with bad params' do
|
166
|
-
post '/forest/actions/my_action/hooks/change', params: {}
|
171
|
+
post '/forest/actions/my_action/hooks/change', params: JSON.dump({collectionName: 'Island'}), headers: { 'CONTENT_TYPE' => 'application/json' }
|
167
172
|
expect(response.status).to eq(500)
|
173
|
+
expect(JSON.parse(response.body)).to eq({'error' => 'Error in smart action change hook: fields params is mandatory'})
|
168
174
|
end
|
169
175
|
|
170
176
|
it 'should respond 500 with bad hook result type' do
|
171
177
|
post '/forest/actions/fail_action/hooks/change', params: JSON.dump(params), headers: { 'CONTENT_TYPE' => 'application/json' }
|
172
178
|
expect(response.status).to eq(500)
|
173
|
-
|
174
|
-
|
175
|
-
it 'should respond 500 with bad hook result data structure' do
|
176
|
-
post '/forest/actions/cheat_action/hooks/change', params: JSON.dump(params), headers: { 'CONTENT_TYPE' => 'application/json' }
|
177
|
-
expect(response.status).to eq(500)
|
179
|
+
expect(JSON.parse(response.body)).to eq({'error' => 'Error in smart action load hook: hook must return an array of fields'})
|
178
180
|
end
|
179
181
|
|
180
182
|
it 'should reset value when enums has changed' do
|
@@ -0,0 +1,70 @@
|
|
1
|
+
module ForestLiana
|
2
|
+
describe SmartActionFieldValidator do
|
3
|
+
describe "self.validate_field" do
|
4
|
+
it "should raise an SmartActionInvalidFieldError with nil field" do
|
5
|
+
expect { SmartActionFieldValidator.validate_field(nil, "actionName") }.to raise_error(ForestLiana::Errors::SmartActionInvalidFieldError, 'Error while parsing action "actionName": The field attribute must be defined')
|
6
|
+
end
|
7
|
+
|
8
|
+
it "should raise an SmartActionInvalidFieldError with a field that is not a string" do
|
9
|
+
expect { SmartActionFieldValidator.validate_field({
|
10
|
+
:field => 5
|
11
|
+
}, "actionName") }.to raise_error(ForestLiana::Errors::SmartActionInvalidFieldError, 'Error while parsing action "actionName": The field attribute must be a string.')
|
12
|
+
end
|
13
|
+
|
14
|
+
it "should raise an SmartActionInvalidFieldError with description that is not a string" do
|
15
|
+
expect { SmartActionFieldValidator.validate_field({
|
16
|
+
:field => "field",
|
17
|
+
:description => 5
|
18
|
+
}, "actionName") }.to raise_error(ForestLiana::Errors::SmartActionInvalidFieldError, 'Error while parsing action "actionName" on field "field": The description attribute must be a string.')
|
19
|
+
end
|
20
|
+
|
21
|
+
it "should raise an SmartActionInvalidFieldError with an enums that is not an array" do
|
22
|
+
expect { SmartActionFieldValidator.validate_field({
|
23
|
+
:field => "field",
|
24
|
+
:enums => "NotAnArray"
|
25
|
+
}, "actionName") }.to raise_error(ForestLiana::Errors::SmartActionInvalidFieldError, 'Error while parsing action "actionName" on field "field": The enums attribute must be an array.')
|
26
|
+
end
|
27
|
+
|
28
|
+
it "should raise an SmartActionInvalidFieldError with a reference that is not a string" do
|
29
|
+
expect { SmartActionFieldValidator.validate_field({
|
30
|
+
:field => "field",
|
31
|
+
:type => "String",
|
32
|
+
:reference => 5
|
33
|
+
}, "actionName") }.to raise_error(ForestLiana::Errors::SmartActionInvalidFieldError, 'Error while parsing action "actionName" on field "field": The reference attribute must be a string.')
|
34
|
+
end
|
35
|
+
|
36
|
+
it "should raise an SmartActionInvalidFieldError with an invalid type" do
|
37
|
+
expect { SmartActionFieldValidator.validate_field({
|
38
|
+
:field => "field",
|
39
|
+
:type => "AbsolutelyNotAValidType"
|
40
|
+
}, "actionName") }.to raise_error(ForestLiana::Errors::SmartActionInvalidFieldError, 'Error while parsing action "actionName" on field "field": The type attribute must be a valid type. See the documentation for more information. https://docs.forestadmin.com/documentation/reference-guide/fields/create-and-manage-smart-fields#available-field-options.')
|
41
|
+
end
|
42
|
+
|
43
|
+
it "should not raise any error when everything is configured correctly" do
|
44
|
+
expect { SmartActionFieldValidator.validate_field({
|
45
|
+
:field => "field",
|
46
|
+
:type => "String",
|
47
|
+
:description => "field description"
|
48
|
+
}, "actionName") }.not_to raise_error
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
describe "self.validate_field_change_hook" do
|
53
|
+
it "should raise an SmartActionInvalidFieldHookError with an invalid type" do
|
54
|
+
expect { SmartActionFieldValidator.validate_field_change_hook({
|
55
|
+
:field => "field",
|
56
|
+
:type => "AbsolutelyNotAValidType",
|
57
|
+
:hook => "hookThatDoesNotExist"
|
58
|
+
}, "actionName", []) }.to raise_error(ForestLiana::Errors::SmartActionInvalidFieldHookError)
|
59
|
+
end
|
60
|
+
|
61
|
+
it "should not raise any error when everything is configured correctly" do
|
62
|
+
expect { SmartActionFieldValidator.validate_field_change_hook({
|
63
|
+
:field => "field",
|
64
|
+
:type => "AbsolutelyNotAValidType",
|
65
|
+
:hook => "on_field_changed"
|
66
|
+
}, "actionName", ["on_field_changed"]) }.not_to raise_error
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
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:
|
4
|
+
version: 7.0.0.beta.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Sandro Munda
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-
|
11
|
+
date: 2021-06-07 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|
@@ -25,7 +25,7 @@ dependencies:
|
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: '4.0'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
|
-
name: jsonapi-serializers
|
28
|
+
name: forestadmin-jsonapi-serializers
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
31
|
- - ">="
|
@@ -225,7 +225,6 @@ files:
|
|
225
225
|
- app/helpers/forest_liana/adapter_helper.rb
|
226
226
|
- app/helpers/forest_liana/application_helper.rb
|
227
227
|
- app/helpers/forest_liana/decoration_helper.rb
|
228
|
-
- app/helpers/forest_liana/is_same_data_structure_helper.rb
|
229
228
|
- app/helpers/forest_liana/query_helper.rb
|
230
229
|
- app/helpers/forest_liana/schema_helper.rb
|
231
230
|
- app/helpers/forest_liana/widgets_helper.rb
|
@@ -283,6 +282,7 @@ files:
|
|
283
282
|
- app/services/forest_liana/schema_utils.rb
|
284
283
|
- app/services/forest_liana/scope_validator.rb
|
285
284
|
- app/services/forest_liana/search_query_builder.rb
|
285
|
+
- app/services/forest_liana/smart_action_field_validator.rb
|
286
286
|
- app/services/forest_liana/stat_getter.rb
|
287
287
|
- app/services/forest_liana/stripe_base_getter.rb
|
288
288
|
- app/services/forest_liana/stripe_invoice_getter.rb
|
@@ -316,6 +316,7 @@ files:
|
|
316
316
|
- lib/generators/forest_liana/install_generator.rb
|
317
317
|
- lib/tasks/display_apimap.rake
|
318
318
|
- lib/tasks/send_apimap.rake
|
319
|
+
- spec/config/initializers/logger_spec.rb
|
319
320
|
- spec/dummy/README.rdoc
|
320
321
|
- spec/dummy/Rakefile
|
321
322
|
- spec/dummy/app/assets/config/manifest.js
|
@@ -367,9 +368,9 @@ files:
|
|
367
368
|
- spec/dummy/db/schema.rb
|
368
369
|
- spec/dummy/lib/forest_liana/collections/location.rb
|
369
370
|
- spec/dummy/lib/forest_liana/collections/user.rb
|
370
|
-
- spec/helpers/forest_liana/is_same_data_structure_helper_spec.rb
|
371
371
|
- spec/helpers/forest_liana/query_helper_spec.rb
|
372
372
|
- spec/helpers/forest_liana/schema_helper_spec.rb
|
373
|
+
- spec/lib/forest_liana/schema_file_updater_spec.rb
|
373
374
|
- spec/rails_helper.rb
|
374
375
|
- spec/requests/actions_controller_spec.rb
|
375
376
|
- spec/requests/authentications_spec.rb
|
@@ -386,6 +387,7 @@ files:
|
|
386
387
|
- spec/services/forest_liana/permissions_getter_spec.rb
|
387
388
|
- spec/services/forest_liana/resources_getter_spec.rb
|
388
389
|
- spec/services/forest_liana/schema_adapter_spec.rb
|
390
|
+
- spec/services/forest_liana/smart_action_field_validator_spec.rb
|
389
391
|
- spec/spec_helper.rb
|
390
392
|
- test/dummy/README.rdoc
|
391
393
|
- test/dummy/Rakefile
|
@@ -494,9 +496,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
494
496
|
version: '0'
|
495
497
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
496
498
|
requirements:
|
497
|
-
- - "
|
499
|
+
- - ">"
|
498
500
|
- !ruby/object:Gem::Version
|
499
|
-
version:
|
501
|
+
version: 1.3.1
|
500
502
|
requirements: []
|
501
503
|
rubygems_version: 3.1.2
|
502
504
|
signing_key:
|
@@ -602,12 +604,13 @@ test_files:
|
|
602
604
|
- spec/services/forest_liana/permissions_checker_acl_enabled_spec.rb
|
603
605
|
- spec/services/forest_liana/filters_parser_spec.rb
|
604
606
|
- spec/services/forest_liana/schema_adapter_spec.rb
|
607
|
+
- spec/services/forest_liana/smart_action_field_validator_spec.rb
|
605
608
|
- spec/services/forest_liana/line_stat_getter_spec.rb
|
606
609
|
- spec/services/forest_liana/permissions_formatter_spec.rb
|
607
610
|
- spec/services/forest_liana/permissions_checker_live_queries_spec.rb
|
608
611
|
- spec/services/forest_liana/apimap_sorter_spec.rb
|
609
612
|
- spec/services/forest_liana/permissions_checker_acl_disabled_spec.rb
|
610
|
-
- spec/
|
613
|
+
- spec/config/initializers/logger_spec.rb
|
611
614
|
- spec/helpers/forest_liana/schema_helper_spec.rb
|
612
615
|
- spec/helpers/forest_liana/query_helper_spec.rb
|
613
616
|
- spec/dummy/db/schema.rb
|
@@ -661,6 +664,7 @@ test_files:
|
|
661
664
|
- spec/dummy/app/models/location.rb
|
662
665
|
- spec/dummy/app/models/island.rb
|
663
666
|
- spec/dummy/app/models/reference.rb
|
667
|
+
- spec/lib/forest_liana/schema_file_updater_spec.rb
|
664
668
|
- spec/rails_helper.rb
|
665
669
|
- spec/requests/stats_spec.rb
|
666
670
|
- spec/requests/resources_spec.rb
|
@@ -1,44 +0,0 @@
|
|
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
|
-
|
@@ -1,87 +0,0 @@
|
|
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
|