forest_liana 7.0.0.beta.4 → 7.0.1

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.
Files changed (45) hide show
  1. checksums.yaml +4 -4
  2. data/app/controllers/forest_liana/actions_controller.rb +2 -2
  3. data/app/controllers/forest_liana/associations_controller.rb +2 -2
  4. data/app/controllers/forest_liana/resources_controller.rb +15 -6
  5. data/app/controllers/forest_liana/scopes_controller.rb +20 -0
  6. data/app/controllers/forest_liana/smart_actions_controller.rb +39 -3
  7. data/app/controllers/forest_liana/stats_controller.rb +5 -5
  8. data/app/services/forest_liana/filters_parser.rb +25 -9
  9. data/app/services/forest_liana/has_many_dissociator.rb +2 -2
  10. data/app/services/forest_liana/has_many_getter.rb +2 -2
  11. data/app/services/forest_liana/leaderboard_stat_getter.rb +20 -14
  12. data/app/services/forest_liana/line_stat_getter.rb +4 -2
  13. data/app/services/forest_liana/permissions_checker.rb +3 -4
  14. data/app/services/forest_liana/permissions_getter.rb +2 -2
  15. data/app/services/forest_liana/pie_stat_getter.rb +6 -3
  16. data/app/services/forest_liana/resource_getter.rb +6 -3
  17. data/app/services/forest_liana/resource_updater.rb +5 -2
  18. data/app/services/forest_liana/resources_getter.rb +6 -5
  19. data/app/services/forest_liana/scope_manager.rb +102 -0
  20. data/app/services/forest_liana/search_query_builder.rb +6 -3
  21. data/app/services/forest_liana/stat_getter.rb +2 -1
  22. data/app/services/forest_liana/value_stat_getter.rb +4 -2
  23. data/config/routes.rb +3 -0
  24. data/lib/forest_liana/version.rb +1 -1
  25. data/spec/dummy/app/controllers/forest/islands_controller.rb +5 -0
  26. data/spec/dummy/config/routes.rb +4 -0
  27. data/spec/dummy/lib/forest_liana/collections/island.rb +7 -0
  28. data/spec/requests/actions_controller_spec.rb +100 -12
  29. data/spec/requests/resources_spec.rb +2 -0
  30. data/spec/services/forest_liana/filters_parser_spec.rb +27 -1
  31. data/spec/services/forest_liana/has_many_getter_spec.rb +116 -0
  32. data/spec/services/forest_liana/line_stat_getter_spec.rb +14 -6
  33. data/spec/services/forest_liana/permissions_checker_acl_disabled_spec.rb +1 -3
  34. data/spec/services/forest_liana/pie_stat_getter_spec.rb +114 -0
  35. data/spec/services/forest_liana/resource_updater_spec.rb +116 -0
  36. data/spec/services/forest_liana/resources_getter_spec.rb +68 -1
  37. data/spec/services/forest_liana/scope_manager_spec.rb +232 -0
  38. data/spec/services/forest_liana/value_stat_getter_spec.rb +96 -0
  39. metadata +20 -15
  40. data/app/services/forest_liana/scope_validator.rb +0 -98
  41. data/test/services/forest_liana/has_many_getter_test.rb +0 -75
  42. data/test/services/forest_liana/pie_stat_getter_test.rb +0 -29
  43. data/test/services/forest_liana/resource_updater_test.rb +0 -86
  44. data/test/services/forest_liana/scope_validator_test.rb +0 -185
  45. data/test/services/forest_liana/value_stat_getter_test.rb +0 -71
@@ -6,13 +6,21 @@ module ForestLiana
6
6
  let(:sort) { 'id' }
7
7
  let(:fields) { }
8
8
  let(:filters) { }
9
+ let(:scopes) { { } }
10
+ let(:rendering_id) { 13 }
11
+ let(:user) { { 'id' => '1', 'rendering_id' => rendering_id } }
9
12
 
10
13
  let(:getter) { described_class.new(resource, {
11
14
  page: { size: pageSize, number: pageNumber },
12
15
  sort: sort,
13
16
  fields: fields,
14
17
  filters: filters,
15
- })}
18
+ }, user) }
19
+
20
+ def init_scopes
21
+ ForestLiana::ScopeManager.invalidate_scope_cache(rendering_id)
22
+ allow(ForestLiana::ScopeManager).to receive(:fetch_scopes).and_return(scopes)
23
+ end
16
24
 
17
25
  before(:each) do
18
26
  users = ['Michel', 'Robert', 'Vince', 'Sandro', 'Olesya', 'Romain', 'Valentin', 'Jason', 'Arnaud', 'Jeff', 'Steve', 'Marc', 'Xavier', 'Paul', 'Mickael', 'Mike', 'Maxime', 'Gertrude', 'Monique', 'Mia', 'Rachid', 'Edouard', 'Sacha', 'Caro', 'Amand', 'Nathan', 'Noémie', 'Robin', 'Gaelle', 'Isabelle']
@@ -43,6 +51,7 @@ module ForestLiana
43
51
  ].map { |location| Location.create(coordinates: location[:coordinates], island: location[:island]) }
44
52
 
45
53
  reference = Reference.create()
54
+ init_scopes
46
55
  end
47
56
 
48
57
  after(:each) do
@@ -355,5 +364,63 @@ module ForestLiana
355
364
  )
356
365
  end
357
366
  end
367
+
368
+ describe 'when scopes are defined' do
369
+ let(:resource) { Island }
370
+ let(:pageSize) { 15 }
371
+ let(:fields) { }
372
+ let(:filters) { }
373
+ let(:scopes) {
374
+ {
375
+ 'Island' => {
376
+ 'scope'=> {
377
+ 'filter'=> {
378
+ 'aggregator' => 'and',
379
+ 'conditions' => [
380
+ { 'field' => 'name', 'operator' => 'contains', 'value' => 'u' }
381
+ ]
382
+ },
383
+ 'dynamicScopesValues' => { }
384
+ }
385
+ }
386
+ }
387
+ }
388
+
389
+ describe 'when there are NO filters already defined' do
390
+ it 'should get only the records matching the scope' do
391
+ getter.perform
392
+ records = getter.records
393
+ count = getter.count
394
+
395
+ expect(records.count).to eq 3
396
+ expect(count).to eq 3
397
+ expect(records.first.name).to eq 'Skull'
398
+ expect(records.second.name).to eq 'Muerta'
399
+ expect(records.third.name).to eq 'Treasure'
400
+ end
401
+ end
402
+
403
+ describe 'when there are filters already defined' do
404
+ let(:filters) { {
405
+ aggregator: 'and',
406
+ conditions: [{
407
+ field: 'name',
408
+ operator: 'contains',
409
+ value: 'a',
410
+ }]
411
+ }.to_json }
412
+
413
+ it 'should get only the records matching the scope' do
414
+ getter.perform
415
+ records = getter.records
416
+ count = getter.count
417
+
418
+ expect(records.count).to eq 2
419
+ expect(count).to eq 2
420
+ expect(records.first.name).to eq 'Muerta'
421
+ expect(records.second.name).to eq 'Treasure'
422
+ end
423
+ end
424
+ end
358
425
  end
359
426
  end
@@ -0,0 +1,232 @@
1
+ module ForestLiana
2
+ describe ScopeManager do
3
+ let(:rendering_id) { 13 }
4
+ let(:user) { { 'id' => '1', 'rendering_id' => rendering_id } }
5
+ let(:collection_name) { 'Users' }
6
+ let(:first_collection_scope) {
7
+ {
8
+ 'scope'=> {
9
+ 'filter'=> {
10
+ 'aggregator' => 'and',
11
+ 'conditions' => [
12
+ { 'field' => 'description', 'operator' => 'contains', 'value' => 'check' }
13
+ ]
14
+ },
15
+ 'dynamicScopesValues' => { }
16
+ }
17
+ }
18
+ }
19
+ let(:second_collection_scope) {
20
+ {
21
+ 'scope'=> {
22
+ 'filter'=> {
23
+ 'aggregator' => 'and',
24
+ 'conditions' => [
25
+ { 'field' => 'description', 'operator' => 'contains', 'value' => 'toto' }
26
+ ]
27
+ },
28
+ 'dynamicScopesValues' => { }
29
+ }
30
+ }
31
+ }
32
+ let(:first_json_scopes) { JSON.generate({ collection_name => first_collection_scope }) }
33
+ let(:second_json_scopes) { JSON.generate({ collection_name => second_collection_scope }) }
34
+ let(:first_scopes_api_call_response) { Net::HTTPOK.new({}, 200, first_json_scopes) }
35
+ let(:second_scopes_api_call_response) { Net::HTTPOK.new({}, 200, second_json_scopes) }
36
+
37
+ before do
38
+ described_class.invalidate_scope_cache(rendering_id)
39
+ allow(ForestLiana::ForestApiRequester).to receive(:get).and_return(first_scopes_api_call_response, second_scopes_api_call_response)
40
+ allow(first_scopes_api_call_response).to receive(:body).and_return(first_json_scopes)
41
+ allow(second_scopes_api_call_response).to receive(:body).and_return(second_json_scopes)
42
+ end
43
+
44
+ describe '#get_scope_for_user' do
45
+ describe 'with invalid inputs' do
46
+ it 'should raise an error on missing rendering_id' do
47
+ expect {
48
+ described_class.get_scope_for_user({}, collection_name)
49
+ }.to raise_error 'Missing required rendering_id'
50
+ end
51
+
52
+ it 'should raise an error on missing collection_name' do
53
+ expect {
54
+ described_class.get_scope_for_user(user, nil)
55
+ }.to raise_error 'Missing required collection_name'
56
+ end
57
+ end
58
+
59
+ describe 'when the backend return an errored response' do
60
+ let(:first_scopes_api_call_response) { Net::HTTPNotFound.new({}, 404, nil) }
61
+
62
+ it 'should raise an error' do
63
+ expect {
64
+ described_class.get_scope_for_user(user, collection_name)
65
+ }.to raise_error 'Unable to fetch scopes'
66
+ end
67
+ end
68
+
69
+ describe 'when retrieving scopes once with no cached value' do
70
+ let(:scope) { described_class.get_scope_for_user(user, collection_name) }
71
+
72
+ it 'should fetch the relevant scope and return it' do
73
+ expect(scope).to eq first_collection_scope['scope']['filter']
74
+ expect(ForestLiana::ForestApiRequester).to have_received(:get).once
75
+ expect(ForestLiana::ForestApiRequester).to have_received(:get).with('/liana/scopes', query: { 'renderingId' => rendering_id })
76
+ end
77
+ end
78
+
79
+ describe 'when retrieving scopes twice before the refresh cache delta' do
80
+ let(:scope_first_fetch) { described_class.get_scope_for_user(user, collection_name) }
81
+ let(:scope_second_fetch) { described_class.get_scope_for_user(user, collection_name) }
82
+
83
+ it 'should return the same value twice and have fetch the scopes from the backend only once' do
84
+ expect(scope_first_fetch).to eq first_collection_scope['scope']['filter']
85
+ expect(scope_second_fetch).to eq first_collection_scope['scope']['filter']
86
+ expect(ForestLiana::ForestApiRequester).to have_received(:get).once.with('/liana/scopes', query: { 'renderingId' => rendering_id })
87
+ end
88
+ end
89
+
90
+ describe 'when retrieving scopes twice after the refresh cache delta' do
91
+ let(:scope_first_fetch) { described_class.get_scope_for_user(user, collection_name) }
92
+ let(:scope_second_fetch) { described_class.get_scope_for_user(user, collection_name) }
93
+
94
+ it 'should return same value but trigger a fetch twice' do
95
+ expect(scope_first_fetch).to eq first_collection_scope['scope']['filter']
96
+ allow(Time).to receive(:now).and_return(Time.now + 20.minutes)
97
+ expect(scope_second_fetch).to eq first_collection_scope['scope']['filter']
98
+ # sleep to wait for the Thread to trigger the call to the `ForestApiRequester`
99
+ sleep(0.001)
100
+ expect(ForestLiana::ForestApiRequester).to have_received(:get).twice.with('/liana/scopes', query: { 'renderingId' => rendering_id })
101
+ end
102
+ end
103
+
104
+ describe 'when retrieving scopes three times after the refresh cache delta' do
105
+ let(:scope_first_fetch) { described_class.get_scope_for_user(user, collection_name) }
106
+ let(:scope_second_fetch) { described_class.get_scope_for_user(user, collection_name) }
107
+ let(:scope_third_fetch) { described_class.get_scope_for_user(user, collection_name) }
108
+
109
+ it 'should return a new value on third call and have fetch the scopes from the backend only twice' do
110
+ expect(scope_first_fetch).to eq first_collection_scope['scope']['filter']
111
+ allow(Time).to receive(:now).and_return(Time.now + 20.minutes)
112
+ expect(scope_second_fetch).to eq first_collection_scope['scope']['filter']
113
+ # sleep to wait for the Thread to update the cache
114
+ sleep(0.001)
115
+ expect(scope_third_fetch).to eq second_collection_scope['scope']['filter']
116
+ expect(ForestLiana::ForestApiRequester).to have_received(:get).twice.with('/liana/scopes', query: { 'renderingId' => rendering_id })
117
+ end
118
+ end
119
+
120
+ describe 'when scope contains dynamic values' do
121
+ let(:first_collection_scope) {
122
+ {
123
+ 'scope' => {
124
+ 'filter'=> {
125
+ 'aggregator' => 'and',
126
+ 'conditions' => [
127
+ { 'field' => 'description', 'operator' => 'contains', 'value' => '$currentUser.firstName' }
128
+ ]
129
+ },
130
+ 'dynamicScopesValues' => {
131
+ 'users' => { '1' => { '$currentUser.firstName' => 'Valentin' } }
132
+ }
133
+ }
134
+ }
135
+ }
136
+ let(:scope_filter) { described_class.get_scope_for_user(user, collection_name) }
137
+ let(:expected_filter) {
138
+ {
139
+ 'aggregator' => 'and',
140
+ 'conditions' => [
141
+ { 'field' => 'description', 'operator' => 'contains', 'value' => 'Valentin' }
142
+ ]
143
+ }
144
+ }
145
+
146
+ it 'should replace the dynamic values properly' do
147
+ expect(scope_filter).to eq expected_filter
148
+ expect(ForestLiana::ForestApiRequester).to have_received(:get).once
149
+ expect(ForestLiana::ForestApiRequester).to have_received(:get).with('/liana/scopes', query: { 'renderingId' => rendering_id })
150
+ end
151
+ end
152
+
153
+ describe 'when target collection has no scopes' do
154
+ let(:first_collection_scope) { { } }
155
+ let(:scope_filter) { described_class.get_scope_for_user(user, collection_name) }
156
+
157
+ it 'should return nil' do
158
+ expect(scope_filter).to eq nil
159
+ expect(ForestLiana::ForestApiRequester).to have_received(:get).once
160
+ expect(ForestLiana::ForestApiRequester).to have_received(:get).with('/liana/scopes', query: { 'renderingId' => rendering_id })
161
+ end
162
+ end
163
+
164
+ describe 'when target collection has no scopes' do
165
+ let(:first_collection_scope) { { } }
166
+ let(:scope_filter) { described_class.get_scope_for_user(user, collection_name) }
167
+
168
+ it 'should return nil' do
169
+ expect(scope_filter).to eq nil
170
+ expect(ForestLiana::ForestApiRequester).to have_received(:get).once
171
+ expect(ForestLiana::ForestApiRequester).to have_received(:get).with('/liana/scopes', query: { 'renderingId' => rendering_id })
172
+ end
173
+ end
174
+
175
+ describe 'when asking for filters as string' do
176
+ let(:scope) { described_class.get_scope_for_user(user, collection_name, as_string: true) }
177
+ let(:expected_filters) { "{\"aggregator\":\"and\",\"conditions\":[{\"field\":\"description\",\"operator\":\"contains\",\"value\":\"check\"}]}" }
178
+
179
+ it 'should fetch the relevant scope and return it as a string' do
180
+ expect(scope).to eq expected_filters
181
+ expect(ForestLiana::ForestApiRequester).to have_received(:get).once
182
+ expect(ForestLiana::ForestApiRequester).to have_received(:get).with('/liana/scopes', query: { 'renderingId' => rendering_id })
183
+ end
184
+ end
185
+ end
186
+
187
+ describe '#append_scope_for_user' do
188
+ let(:existing_filter) { "{\"aggregator\":\"and\",\"conditions\":[{\"field\":\"shipping_status\",\"operator\":\"equal\",\"value\":\"Shipped\"}]}" }
189
+ let(:first_collection_scope_filter_as_string) { "{\"aggregator\":\"and\",\"conditions\":[{\"field\":\"description\",\"operator\":\"contains\",\"value\":\"check\"}]}" }
190
+
191
+ describe 'when the target collection has NO scopes defined' do
192
+ let(:first_collection_scope) { { } }
193
+
194
+ describe 'when providing NO existing filters' do
195
+ let(:existing_filter) { nil }
196
+ let(:filters) { described_class.append_scope_for_user(existing_filter, user, collection_name) }
197
+
198
+ it 'should return nil' do
199
+ expect(filters).to eq nil
200
+ end
201
+ end
202
+
203
+ describe 'when providing existing filters' do
204
+ let(:filters) { described_class.append_scope_for_user(existing_filter, user, collection_name) }
205
+
206
+ it 'should return only the exisitng filters' do
207
+ expect(filters).to eq existing_filter
208
+ end
209
+ end
210
+ end
211
+
212
+ describe 'when the target collection has scopes defined' do
213
+ describe 'when providing NO existing filters' do
214
+ let(:existing_filter) { nil }
215
+ let(:filters) { described_class.append_scope_for_user(existing_filter, user, collection_name) }
216
+
217
+ it 'should return only the scope filters' do
218
+ expect(filters).to eq first_collection_scope_filter_as_string
219
+ end
220
+ end
221
+
222
+ describe 'when providing existing filters' do
223
+ let(:filters) { described_class.append_scope_for_user(existing_filter, user, collection_name) }
224
+
225
+ it 'should return the aggregation between the exisitng filters and the scope filters' do
226
+ expect(filters).to eq "{\"aggregator\":\"and\",\"conditions\":[#{existing_filter},#{first_collection_scope_filter_as_string}]}"
227
+ end
228
+ end
229
+ end
230
+ end
231
+ end
232
+ end
@@ -0,0 +1,96 @@
1
+ module ForestLiana
2
+ describe ValueStatGetter do
3
+ let(:rendering_id) { 13 }
4
+ let(:user) { { 'id' => '1', 'rendering_id' => rendering_id } }
5
+
6
+ before(:each) do
7
+ ForestLiana::ScopeManager.invalidate_scope_cache(rendering_id)
8
+ allow(ForestLiana::ScopeManager).to receive(:fetch_scopes).and_return(scopes)
9
+
10
+ island = Island.create!(name: 'Númenor')
11
+ king = User.create!(title: :king, name: 'Aragorn')
12
+ villager = User.create!(title: :villager)
13
+ Tree.create!(name: 'Tree n1', age: 1, island: island, owner: king)
14
+ Tree.create!(name: 'Tree n2', age: 3, island: island, created_at: 3.day.ago, owner: villager)
15
+ Tree.create!(name: 'Tree n3', age: 4, island: island, owner: king, cutter: villager)
16
+ end
17
+
18
+ let(:params) {
19
+ {
20
+ type: "Value",
21
+ collection: collection,
22
+ timezone: "Europe/Paris",
23
+ aggregate: "Count",
24
+ filters: filters
25
+ }
26
+ }
27
+
28
+ subject { ValueStatGetter.new(model, params, user) }
29
+
30
+ describe 'with empty scopes' do
31
+ let(:scopes) { { } }
32
+
33
+ describe 'with a simple filter matching no entries' do
34
+ let(:model) { User }
35
+ let(:collection) { 'users' }
36
+ let(:filters) { { field: 'name', operator: 'in', value: ['Merry', 'Pippin'] }.to_json }
37
+
38
+ it 'should have a countCurrent of 0' do
39
+ subject.perform
40
+ expect(subject.record.value[:countCurrent]).to eq 0
41
+ end
42
+ end
43
+
44
+ describe 'with a filter on a belongs_to string field' do
45
+ let(:model) { Tree }
46
+ let(:collection) { 'trees' }
47
+ let(:filters) { { field: 'owner:name', operator: 'equal', value: 'Aragorn' }.to_json }
48
+
49
+ it 'should have a countCurrent of 2' do
50
+ subject.perform
51
+ expect(subject.record.value[:countCurrent]).to eq 2
52
+ end
53
+ end
54
+
55
+ describe 'with a filter on a belongs_to enum field' do
56
+ let(:model) { Tree }
57
+ let(:collection) { 'trees' }
58
+ let(:filters) { { field: 'owner:title', operator: 'equal', value: 'villager' }.to_json }
59
+
60
+ it 'should have a countCurrent of 1' do
61
+ subject.perform
62
+ expect(subject.record.value[:countCurrent]).to eq 1
63
+ end
64
+ end
65
+ end
66
+
67
+ describe 'with scopes' do
68
+ let(:scopes) {
69
+ {
70
+ 'User' => {
71
+ 'scope'=> {
72
+ 'filter'=> {
73
+ 'aggregator' => 'and',
74
+ 'conditions' => [
75
+ { 'field' => 'title', 'operator' => 'not_equal', 'value' => 'villager' }
76
+ ]
77
+ },
78
+ 'dynamicScopesValues' => { }
79
+ }
80
+ }
81
+ }
82
+ }
83
+
84
+ describe 'with a filter on a belongs_to enum field' do
85
+ let(:model) { User }
86
+ let(:collection) { 'users' }
87
+ let(:filters) { { field: 'title', operator: 'equal', value: 'villager' }.to_json }
88
+
89
+ it 'should have a countCurrent of 0' do
90
+ subject.perform
91
+ expect(subject.record.value[:countCurrent]).to eq 0
92
+ end
93
+ end
94
+ end
95
+ end
96
+ 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: 7.0.0.beta.4
4
+ version: 7.0.1
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-07-06 00:00:00.000000000 Z
11
+ date: 2021-07-23 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -218,6 +218,7 @@ files:
218
218
  - app/controllers/forest_liana/mixpanel_controller.rb
219
219
  - app/controllers/forest_liana/resources_controller.rb
220
220
  - app/controllers/forest_liana/router.rb
221
+ - app/controllers/forest_liana/scopes_controller.rb
221
222
  - app/controllers/forest_liana/smart_actions_controller.rb
222
223
  - app/controllers/forest_liana/stats_controller.rb
223
224
  - app/controllers/forest_liana/stripe_controller.rb
@@ -280,7 +281,7 @@ files:
280
281
  - app/services/forest_liana/resources_getter.rb
281
282
  - app/services/forest_liana/schema_adapter.rb
282
283
  - app/services/forest_liana/schema_utils.rb
283
- - app/services/forest_liana/scope_validator.rb
284
+ - app/services/forest_liana/scope_manager.rb
284
285
  - app/services/forest_liana/search_query_builder.rb
285
286
  - app/services/forest_liana/smart_action_field_validator.rb
286
287
  - app/services/forest_liana/stat_getter.rb
@@ -324,6 +325,7 @@ files:
324
325
  - spec/dummy/app/assets/stylesheets/application.css
325
326
  - spec/dummy/app/config/routes.rb
326
327
  - spec/dummy/app/controllers/application_controller.rb
328
+ - spec/dummy/app/controllers/forest/islands_controller.rb
327
329
  - spec/dummy/app/helpers/application_helper.rb
328
330
  - spec/dummy/app/models/island.rb
329
331
  - spec/dummy/app/models/location.rb
@@ -366,6 +368,7 @@ files:
366
368
  - spec/dummy/db/migrate/20210511141752_create_owners.rb
367
369
  - spec/dummy/db/migrate/20210526084712_create_products.rb
368
370
  - spec/dummy/db/schema.rb
371
+ - spec/dummy/lib/forest_liana/collections/island.rb
369
372
  - spec/dummy/lib/forest_liana/collections/location.rb
370
373
  - spec/dummy/lib/forest_liana/collections/user.rb
371
374
  - spec/helpers/forest_liana/query_helper_spec.rb
@@ -379,6 +382,7 @@ files:
379
382
  - spec/requests/stats_spec.rb
380
383
  - spec/services/forest_liana/apimap_sorter_spec.rb
381
384
  - spec/services/forest_liana/filters_parser_spec.rb
385
+ - spec/services/forest_liana/has_many_getter_spec.rb
382
386
  - spec/services/forest_liana/ip_whitelist_checker_spec.rb
383
387
  - spec/services/forest_liana/line_stat_getter_spec.rb
384
388
  - spec/services/forest_liana/permissions_checker_acl_disabled_spec.rb
@@ -386,9 +390,13 @@ files:
386
390
  - spec/services/forest_liana/permissions_checker_live_queries_spec.rb
387
391
  - spec/services/forest_liana/permissions_formatter_spec.rb
388
392
  - spec/services/forest_liana/permissions_getter_spec.rb
393
+ - spec/services/forest_liana/pie_stat_getter_spec.rb
394
+ - spec/services/forest_liana/resource_updater_spec.rb
389
395
  - spec/services/forest_liana/resources_getter_spec.rb
390
396
  - spec/services/forest_liana/schema_adapter_spec.rb
397
+ - spec/services/forest_liana/scope_manager_spec.rb
391
398
  - spec/services/forest_liana/smart_action_field_validator_spec.rb
399
+ - spec/services/forest_liana/value_stat_getter_spec.rb
392
400
  - spec/spec_helper.rb
393
401
  - test/dummy/README.rdoc
394
402
  - test/dummy/Rakefile
@@ -474,13 +482,8 @@ files:
474
482
  - test/fixtures/tree.yml
475
483
  - test/forest_liana_test.rb
476
484
  - test/routing/route_test.rb
477
- - test/services/forest_liana/has_many_getter_test.rb
478
485
  - test/services/forest_liana/operator_date_interval_parser_test.rb
479
- - test/services/forest_liana/pie_stat_getter_test.rb
480
- - test/services/forest_liana/resource_updater_test.rb
481
486
  - test/services/forest_liana/schema_adapter_test.rb
482
- - test/services/forest_liana/scope_validator_test.rb
483
- - test/services/forest_liana/value_stat_getter_test.rb
484
487
  - test/test_helper.rb
485
488
  homepage: https://github.com/ForestAdmin/forest-rails
486
489
  licenses:
@@ -497,9 +500,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
497
500
  version: '0'
498
501
  required_rubygems_version: !ruby/object:Gem::Requirement
499
502
  requirements:
500
- - - ">"
503
+ - - ">="
501
504
  - !ruby/object:Gem::Version
502
- version: 1.3.1
505
+ version: '0'
503
506
  requirements: []
504
507
  rubygems_version: 3.1.2
505
508
  signing_key:
@@ -509,12 +512,7 @@ test_files:
509
512
  - test/routing/route_test.rb
510
513
  - test/forest_liana_test.rb
511
514
  - test/services/forest_liana/schema_adapter_test.rb
512
- - test/services/forest_liana/resource_updater_test.rb
513
- - test/services/forest_liana/scope_validator_test.rb
514
515
  - test/services/forest_liana/operator_date_interval_parser_test.rb
515
- - test/services/forest_liana/value_stat_getter_test.rb
516
- - test/services/forest_liana/has_many_getter_test.rb
517
- - test/services/forest_liana/pie_stat_getter_test.rb
518
516
  - test/fixtures/string_field.yml
519
517
  - test/fixtures/reference.yml
520
518
  - test/fixtures/has_one_field.yml
@@ -600,17 +598,22 @@ test_files:
600
598
  - test/test_helper.rb
601
599
  - spec/helpers/forest_liana/schema_helper_spec.rb
602
600
  - spec/helpers/forest_liana/query_helper_spec.rb
601
+ - spec/services/forest_liana/scope_manager_spec.rb
602
+ - spec/services/forest_liana/resource_updater_spec.rb
603
+ - spec/services/forest_liana/pie_stat_getter_spec.rb
603
604
  - spec/services/forest_liana/permissions_checker_live_queries_spec.rb
604
605
  - spec/services/forest_liana/ip_whitelist_checker_spec.rb
605
606
  - spec/services/forest_liana/line_stat_getter_spec.rb
606
607
  - spec/services/forest_liana/schema_adapter_spec.rb
607
608
  - spec/services/forest_liana/resources_getter_spec.rb
608
609
  - spec/services/forest_liana/smart_action_field_validator_spec.rb
610
+ - spec/services/forest_liana/has_many_getter_spec.rb
609
611
  - spec/services/forest_liana/apimap_sorter_spec.rb
610
612
  - spec/services/forest_liana/filters_parser_spec.rb
611
613
  - spec/services/forest_liana/permissions_checker_acl_enabled_spec.rb
612
614
  - spec/services/forest_liana/permissions_formatter_spec.rb
613
615
  - spec/services/forest_liana/permissions_getter_spec.rb
616
+ - spec/services/forest_liana/value_stat_getter_spec.rb
614
617
  - spec/services/forest_liana/permissions_checker_acl_disabled_spec.rb
615
618
  - spec/spec_helper.rb
616
619
  - spec/config/initializers/logger_spec.rb
@@ -652,6 +655,7 @@ test_files:
652
655
  - spec/dummy/config/initializers/forest_liana.rb
653
656
  - spec/dummy/config/routes.rb
654
657
  - spec/dummy/lib/forest_liana/collections/location.rb
658
+ - spec/dummy/lib/forest_liana/collections/island.rb
655
659
  - spec/dummy/lib/forest_liana/collections/user.rb
656
660
  - spec/dummy/app/models/location.rb
657
661
  - spec/dummy/app/models/island.rb
@@ -667,6 +671,7 @@ test_files:
667
671
  - spec/dummy/app/assets/stylesheets/application.css
668
672
  - spec/dummy/app/assets/config/manifest.js
669
673
  - spec/dummy/app/controllers/application_controller.rb
674
+ - spec/dummy/app/controllers/forest/islands_controller.rb
670
675
  - spec/dummy/bin/setup
671
676
  - spec/dummy/bin/bundle
672
677
  - spec/dummy/bin/rake