forest_liana 6.6.0 → 7.0.0.beta.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (35) hide show
  1. checksums.yaml +4 -4
  2. data/app/controllers/forest_liana/actions_controller.rb +44 -29
  3. data/app/controllers/forest_liana/application_controller.rb +2 -2
  4. data/app/controllers/forest_liana/associations_controller.rb +1 -1
  5. data/app/controllers/forest_liana/base_controller.rb +1 -1
  6. data/app/controllers/forest_liana/resources_controller.rb +7 -6
  7. data/app/serializers/forest_liana/intercom_attribute_serializer.rb +1 -1
  8. data/app/serializers/forest_liana/intercom_conversation_serializer.rb +1 -1
  9. data/app/serializers/forest_liana/mixpanel_event_serializer.rb +1 -1
  10. data/app/serializers/forest_liana/serializer_factory.rb +1 -1
  11. data/app/serializers/forest_liana/stat_serializer.rb +1 -1
  12. data/app/serializers/forest_liana/stripe_bank_account_serializer.rb +1 -1
  13. data/app/serializers/forest_liana/stripe_card_serializer.rb +1 -1
  14. data/app/serializers/forest_liana/stripe_invoice_serializer.rb +1 -1
  15. data/app/serializers/forest_liana/stripe_payment_serializer.rb +1 -1
  16. data/app/serializers/forest_liana/stripe_subscription_serializer.rb +1 -1
  17. data/app/services/forest_liana/apimap_sorter.rb +1 -0
  18. data/app/services/forest_liana/permissions_checker.rb +40 -34
  19. data/app/services/forest_liana/permissions_formatter.rb +1 -1
  20. data/app/services/forest_liana/permissions_getter.rb +1 -4
  21. data/app/services/forest_liana/smart_action_field_validator.rb +49 -0
  22. data/config/initializers/errors.rb +17 -0
  23. data/lib/forest_liana/bootstrapper.rb +2 -2
  24. data/lib/forest_liana/schema_file_updater.rb +8 -0
  25. data/lib/forest_liana/version.rb +1 -1
  26. data/spec/lib/forest_liana/schema_file_updater_spec.rb +94 -0
  27. data/spec/requests/actions_controller_spec.rb +22 -20
  28. data/spec/services/forest_liana/permissions_checker_acl_disabled_spec.rb +45 -69
  29. data/spec/services/forest_liana/permissions_checker_acl_enabled_spec.rb +39 -63
  30. data/spec/services/forest_liana/permissions_checker_live_queries_spec.rb +3 -3
  31. data/spec/services/forest_liana/permissions_formatter_spec.rb +11 -11
  32. data/spec/services/forest_liana/smart_action_field_validator_spec.rb +70 -0
  33. metadata +119 -117
  34. data/app/helpers/forest_liana/is_same_data_structure_helper.rb +0 -44
  35. data/spec/helpers/forest_liana/is_same_data_structure_helper_spec.rb +0 -87
@@ -13,7 +13,7 @@ module ForestLiana
13
13
  'actions' => convert_actions_permissions_to_new_format(permissions[collection_name]['actions'])
14
14
  }
15
15
 
16
- permissions_new_format['renderings'][rendering_id][collection_name] = { 'scope' => permissions[collection_name]['scope'] }
16
+ permissions_new_format['renderings'][rendering_id][collection_name] = { 'segments' => permissions[collection_name]['segments'] }
17
17
  }
18
18
 
19
19
  permissions_new_format
@@ -26,10 +26,7 @@ module ForestLiana
26
26
  # rederings => {
27
27
  # {rendering_id} => {
28
28
  # {collection_id} => {
29
- # scope => {
30
- # dynamicScopesValues => {},
31
- # filter => {}
32
- # }
29
+ # segments => ['query1', 'query2']
33
30
  # }
34
31
  # }
35
32
  # }
@@ -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
 
@@ -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'] = {:load => load, :change => change}
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
@@ -1,3 +1,3 @@
1
1
  module ForestLiana
2
- VERSION = "6.6.0"
2
+ VERSION = "7.0.0.beta.3"
3
3
  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
- 'foo' => -> (context) {
54
- fields = context[:fields]
55
- fields['foo'][:value] = 'baz'
56
- return fields
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
- 'foo' => -> (context) {
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
- context[:fields]['baz'] = foo.clone.update({field: 'baz'})
81
- context[:fields]
81
+ {}
82
82
  },
83
83
  :change => {
84
- 'foo' => -> (context) {
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
- 'foo' => -> (context) {
96
+ 'on_foo_changed' => -> (context) {
97
97
  fields = context[:fields]
98
- fields['enum'][:enums] = %w[c d e]
99
- return fields
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
- 'foo' => -> (context) {
111
+ 'on_foo_changed' => -> (context) {
111
112
  fields = context[:fields]
112
- fields['multipleEnum'][:enums] = %w[c d z]
113
- return fields
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
- end
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
@@ -75,7 +75,7 @@ module ForestLiana
75
75
  "users" => nil
76
76
  },
77
77
  },
78
- "scope" => nil
78
+ "segments" => nil
79
79
  },
80
80
  "no_rights_collection" => {
81
81
  "collection" => {
@@ -93,7 +93,7 @@ module ForestLiana
93
93
  "users" => nil
94
94
  }
95
95
  },
96
- "scope" => nil
96
+ "segments" => nil
97
97
  },
98
98
  },
99
99
  "meta" => {
@@ -146,6 +146,8 @@ module ForestLiana
146
146
 
147
147
  context 'with permissions coming from 2 different renderings' do
148
148
  let(:collection_name) { 'custom' }
149
+
150
+ let(:segments_permissions) { nil }
149
151
  let(:api_permissions_rendering_1) {
150
152
  {
151
153
  "data" => {
@@ -160,7 +162,7 @@ module ForestLiana
160
162
  "searchToEdit" => true
161
163
  },
162
164
  "actions" => { },
163
- "scope" => nil
165
+ "segments" => segments_permissions
164
166
  },
165
167
  },
166
168
  "meta" => {
@@ -190,11 +192,11 @@ module ForestLiana
190
192
  end
191
193
 
192
194
 
193
- context 'scopes cache' do
195
+ context 'renderings cache' do
194
196
  let(:fake_ressource) { collection_name }
195
197
  let(:rendering_id) { 1 }
196
198
  let(:collection_name) { 'custom' }
197
- let(:scope_permissions) { { rendering_id => { 'custom' => nil } } }
199
+ let(:segments_permissions) { { rendering_id => { 'custom' => nil } } }
198
200
  let(:api_permissions) {
199
201
  {
200
202
  "data" => {
@@ -209,7 +211,7 @@ module ForestLiana
209
211
  "searchToEdit" => true
210
212
  },
211
213
  "actions" => { },
212
- "scope" => nil
214
+ "segments" => nil
213
215
  },
214
216
  },
215
217
  "meta" => {
@@ -217,11 +219,11 @@ module ForestLiana
217
219
  }
218
220
  }
219
221
  }
220
- let(:api_permissions_scope_only) {
222
+ let(:api_permissions_rendering_only) {
221
223
  {
222
224
  "data" => {
223
225
  'collections' => { },
224
- 'renderings' => scope_permissions
226
+ 'renderings' => segments_permissions
225
227
  },
226
228
  "meta" => {
227
229
  "rolesACLActivated" => false
@@ -233,13 +235,13 @@ module ForestLiana
233
235
  # clones is called to duplicate the returned value and not use to same (which results in an error
234
236
  # as the permissions is edited through the formatter)
235
237
  allow(ForestLiana::PermissionsGetter).to receive(:get_permissions_for_rendering).with(rendering_id) { api_permissions.clone }
236
- allow(ForestLiana::PermissionsGetter).to receive(:get_permissions_for_rendering).with(rendering_id, rendering_specific_only: true).and_return(api_permissions_scope_only)
238
+ allow(ForestLiana::PermissionsGetter).to receive(:get_permissions_for_rendering).with(rendering_id, rendering_specific_only: true).and_return(api_permissions_rendering_only)
237
239
  end
238
240
 
239
241
  context 'when checking once for authorization' do
240
242
  context 'when checking browseEnabled' do
241
243
  context 'when expiration value is set to its default' do
242
- it 'should not call the API to refresh the scopes cache' do
244
+ it 'should not call the API to refresh the renderings cache' do
243
245
  described_class.new(fake_ressource, 'browseEnabled', rendering_id, user_id: user_id).is_authorized?
244
246
 
245
247
  expect(ForestLiana::PermissionsGetter).to have_received(:get_permissions_for_rendering).with(rendering_id).once
@@ -254,7 +256,7 @@ module ForestLiana
254
256
  described_class.empty_cache
255
257
  end
256
258
 
257
- it 'should call the API to refresh the scopes cache' do
259
+ it 'should call the API to refresh the renderings cache' do
258
260
  described_class.new(fake_ressource, 'browseEnabled', rendering_id, user_id: user_id).is_authorized?
259
261
 
260
262
  expect(ForestLiana::PermissionsGetter).to have_received(:get_permissions_for_rendering).with(rendering_id).once
@@ -263,7 +265,7 @@ module ForestLiana
263
265
  end
264
266
  end
265
267
 
266
- # Only browse permission requires scopes
268
+ # Only browse permission requires segments
267
269
  context 'when checking exportEnabled' do
268
270
  context 'when expiration value is set in the past' do
269
271
  before do
@@ -273,7 +275,7 @@ module ForestLiana
273
275
  end
274
276
  end
275
277
 
276
- it 'should NOT call the API to refresh the scopes cache' do
278
+ it 'should NOT call the API to refresh the renderings cache' do
277
279
  described_class.new(fake_ressource, 'exportEnabled', rendering_id, user_id: user_id).is_authorized?
278
280
 
279
281
  expect(ForestLiana::PermissionsGetter).to have_received(:get_permissions_for_rendering).with(rendering_id).once
@@ -284,8 +286,8 @@ module ForestLiana
284
286
 
285
287
  context 'when checking twice for authorization' do
286
288
  context 'on the same rendering' do
287
- context 'when scopes permission has NOT expired' do
288
- it 'should NOT call the API to refresh the scopes permissions' do
289
+ context 'when renderings permission has NOT expired' do
290
+ it 'should NOT call the API to refresh the renderings permissions' do
289
291
  described_class.new(fake_ressource, 'browseEnabled', rendering_id, user_id: user_id).is_authorized?
290
292
  described_class.new(fake_ressource, 'browseEnabled', rendering_id, user_id: user_id).is_authorized?
291
293
 
@@ -294,14 +296,14 @@ module ForestLiana
294
296
  end
295
297
  end
296
298
 
297
- context 'when scopes permission has expired' do
299
+ context 'when renderings permission has expired' do
298
300
  before do
299
301
  allow(ENV).to receive(:[]).with('FOREST_PERMISSIONS_EXPIRATION_IN_SECONDS').and_return('-1')
300
302
  # Needed to enforce ENV stub
301
303
  described_class.empty_cache
302
304
  end
303
305
 
304
- it 'should call the API to refresh the scopes permissions' do
306
+ it 'should call the API to refresh the renderings permissions' do
305
307
  described_class.new(fake_ressource, 'browseEnabled', rendering_id, user_id: user_id).is_authorized?
306
308
  described_class.new(fake_ressource, 'browseEnabled', rendering_id, user_id: user_id).is_authorized?
307
309
 
@@ -313,7 +315,7 @@ module ForestLiana
313
315
 
314
316
  context 'on two different renderings' do
315
317
  let(:other_rendering_id) { 2 }
316
- let(:api_permissions_scope_only) {
318
+ let(:api_permissions_rendering_only) {
317
319
  {
318
320
  "data" => {
319
321
  'collections' => { },
@@ -330,10 +332,10 @@ module ForestLiana
330
332
 
331
333
  before do
332
334
  allow(ForestLiana::PermissionsGetter).to receive(:get_permissions_for_rendering).with(other_rendering_id).and_return(api_permissions_copy)
333
- allow(ForestLiana::PermissionsGetter).to receive(:get_permissions_for_rendering).with(other_rendering_id, rendering_specific_only: true).and_return(api_permissions_scope_only)
335
+ allow(ForestLiana::PermissionsGetter).to receive(:get_permissions_for_rendering).with(other_rendering_id, rendering_specific_only: true).and_return(api_permissions_rendering_only)
334
336
  end
335
337
 
336
- it 'should not call the API to refresh the scopes permissions' do
338
+ it 'should not call the API to refresh the rederings permissions' do
337
339
  described_class.new(fake_ressource, 'browseEnabled', rendering_id, user_id: user_id).is_authorized?
338
340
  described_class.new(fake_ressource, 'browseEnabled', other_rendering_id, user_id: user_id).is_authorized?
339
341
 
@@ -350,7 +352,7 @@ module ForestLiana
350
352
  # Resource is only used to retrieve the collection name as it's stubbed it does not
351
353
  # need to be defined
352
354
  let(:fake_ressource) { collection_name }
353
- let(:default_rendering_id) { nil }
355
+ let(:default_rendering_id) { 1 }
354
356
  let(:api_permissions) { default_api_permissions }
355
357
  let(:collection_name) { 'all_rights_collection' }
356
358
 
@@ -380,14 +382,14 @@ module ForestLiana
380
382
  describe 'browseEnabled permission' do
381
383
  let(:collection_name) { 'custom' }
382
384
  subject { described_class.new(fake_ressource, 'browseEnabled', default_rendering_id, user_id: user_id) }
383
- let(:scope_permissions) { nil }
385
+ let(:segments_permissions) { nil }
384
386
  let(:default_api_permissions) {
385
387
  {
386
388
  "data" => {
387
389
  "custom" => {
388
390
  "collection" => collection_permissions,
389
391
  "actions" => { },
390
- "scope" => scope_permissions
392
+ "segments" => segments_permissions
391
393
  },
392
394
  },
393
395
  "meta" => {
@@ -480,6 +482,26 @@ module ForestLiana
480
482
  end
481
483
  end
482
484
 
485
+ context 'when segments are defined' do
486
+ let(:segments_permissions) { ['SELECT * FROM products;', 'SELECT * FROM sellers;'] }
487
+ let(:collection_list_parameters) { { :user_id => "1", :segmentQuery => segmentQuery } }
488
+
489
+ context 'when segments are passing validation' do
490
+ let(:segmentQuery) { 'SELECT * FROM products;' }
491
+ it 'should return true' do
492
+ expect(subject.is_authorized?).to be true
493
+ end
494
+ end
495
+
496
+ context 'when segments are NOT passing validation' do
497
+ let(:segmentQuery) { 'SELECT * FROM rockets WHERE name = "Starship";' }
498
+ it 'should return false' do
499
+ expect(subject.is_authorized?).to be false
500
+ end
501
+ end
502
+
503
+ end
504
+
483
505
  context 'when user has not the required permission' do
484
506
  let(:collection_permissions) {
485
507
  {
@@ -498,52 +520,6 @@ module ForestLiana
498
520
  end
499
521
  end
500
522
 
501
- context 'when scopes are defined' do
502
- let(:scope_permissions) { { 'dynamicScopesValues' => {}, 'filter' => { 'aggregator' => 'and', 'conditions' => [condition] } }}
503
- let(:collection_list_parameters) { { :user_id => "1", :filters => JSON.generate(condition) } }
504
-
505
- context 'when scopes are passing validation' do
506
- context 'when scope value is a string' do
507
- let(:condition) { { 'field' => 'field_1', 'operator' => 'equal', 'value' => true } }
508
-
509
- it 'should return true' do
510
- expect(subject.is_authorized?).to be true
511
- end
512
- end
513
-
514
- context 'when scope value is a boolean' do
515
- let(:condition) { { 'field' => 'field_1', 'operator' => 'equal', 'value' => 'true' } }
516
-
517
- it 'should return true' do
518
- expect(subject.is_authorized?).to be true
519
- end
520
- end
521
- end
522
-
523
- context 'when scopes are NOT passing validation' do
524
- let(:condition) { { 'field' => 'field_1', 'operator' => 'equal', 'value' => true } }
525
- let(:other_condition) {
526
- {
527
- aggregator: 'and',
528
- conditions: [
529
- { field: 'name', value: 'john', operator: 'equal' },
530
- { field: 'price', value: '2500', operator: 'equal' }
531
- ]
532
- }
533
- }
534
- let(:collection_list_parameters) {
535
- {
536
- :user_id => "1",
537
- :filters => JSON.generate(other_condition)
538
- }
539
- }
540
-
541
-
542
- it 'should return false' do
543
- expect(subject.is_authorized?).to be false
544
- end
545
- end
546
- end
547
523
  end
548
524
  end
549
525