forest_liana 6.3.8 → 7.0.0.beta.2
Sign up to get free protection for your applications and to get access to all the features.
- 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
|