forest_liana 9.11.3 → 9.15.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.
@@ -121,7 +121,7 @@ module ForestLiana
121
121
 
122
122
  # NOTICE: Sort keys
123
123
  @collections = @collections.map do |collection|
124
- collection['fields'].sort do |field1, field2|
124
+ collection['fields'].sort! do |field1, field2|
125
125
  [field1['field'], field1['type'].inspect] <=> [field2['field'], field2['type'].inspect]
126
126
  end
127
127
 
@@ -1,3 +1,3 @@
1
1
  module ForestLiana
2
- VERSION = "9.11.3"
2
+ VERSION = "9.15.1"
3
3
  end
@@ -1,10 +1,12 @@
1
1
  class Tree < ActiveRecord::Base
2
2
  belongs_to :owner, class_name: 'User', inverse_of: :trees_owned
3
3
  belongs_to :cutter, class_name: 'User', inverse_of: :trees_cut
4
- belongs_to :island
4
+ belongs_to :island, optional: true
5
5
  belongs_to :eponymous_island,
6
6
  ->(record) { where(name: record.name) },
7
7
  class_name: 'Island',
8
8
  inverse_of: :eponymous_tree,
9
9
  optional: true
10
+
11
+ has_one :location, through: :island
10
12
  end
@@ -37,6 +37,7 @@ module ForestLiana
37
37
  { name: :cutter, klass: User },
38
38
  { name: :island, klass: Island },
39
39
  { name: :eponymous_island, klass: Island },
40
+ { name: :location, klass: Location },
40
41
  ]
41
42
  end
42
43
 
@@ -52,13 +53,17 @@ module ForestLiana
52
53
 
53
54
  describe 'get_one_association_names_symbol' do
54
55
  it 'should return the one-one associations names as symbols' do
55
- expect(QueryHelper.get_one_association_names_symbol(Tree)).to eq([:owner, :cutter, :island, :eponymous_island])
56
+ expect(QueryHelper.get_one_association_names_symbol(Tree)).to eq(
57
+ [:owner, :cutter, :island, :eponymous_island, :location]
58
+ )
56
59
  end
57
60
  end
58
61
 
59
62
  describe 'get_one_association_names_string' do
60
63
  it 'should return the one-one associations names as strings' do
61
- expect(QueryHelper.get_one_association_names_string(Tree)).to eq(['owner', 'cutter', 'island', 'eponymous_island'])
64
+ expect(QueryHelper.get_one_association_names_string(Tree)).to eq(
65
+ ['owner', 'cutter', 'island', 'eponymous_island', 'location']
66
+ )
62
67
  end
63
68
  end
64
69
 
@@ -71,12 +76,12 @@ module ForestLiana
71
76
  end
72
77
  end
73
78
 
74
- context 'on a model having 2 belongsTo associations' do
79
+ context 'on a model having 3 belongsTo/hasOne associations' do
75
80
  tables_associated_to_relations_name =
76
81
  QueryHelper.get_tables_associated_to_relations_name(Tree)
77
82
 
78
83
  it 'should return the one-one associations' do
79
- expect(tables_associated_to_relations_name.keys.length).to eq(2)
84
+ expect(tables_associated_to_relations_name.keys.length).to eq(3)
80
85
  end
81
86
 
82
87
  it 'should return relationships having a name different than the targeted model' do
@@ -4,7 +4,9 @@ describe 'Requesting Tree resources', :type => :request do
4
4
  let(:scope_filters) { {'scopes' => {}, 'team' => {'id' => '1', 'name' => 'Operations'}} }
5
5
  before do
6
6
  user = User.create(name: 'Michel')
7
- Tree.create(name: 'Lemon Tree', owner: user, cutter: user)
7
+ tree = Tree.create(name: 'Lemon Tree', owner: user, cutter: user)
8
+ island = Island.create(name: 'Lemon Island', trees: [tree])
9
+ Location.create(coordinates: '1,2', island: island)
8
10
 
9
11
  Rails.cache.write('forest.users', {'1' => { 'id' => 1, 'roleId' => 1, 'rendering_id' => '1' }})
10
12
  Rails.cache.write('forest.has_permission', true)
@@ -32,6 +34,8 @@ describe 'Requesting Tree resources', :type => :request do
32
34
  after do
33
35
  User.destroy_all
34
36
  Tree.destroy_all
37
+ Island.destroy_all
38
+ Location.destroy_all
35
39
  end
36
40
 
37
41
  token = JWT.encode({
@@ -54,7 +58,7 @@ describe 'Requesting Tree resources', :type => :request do
54
58
  describe 'index' do
55
59
  describe 'without any filter' do
56
60
  params = {
57
- fields: { 'Tree' => 'id,name' },
61
+ fields: { 'Tree' => 'id,name,location' },
58
62
  page: { 'number' => '1', 'size' => '10' },
59
63
  searchExtended: '0',
60
64
  sort: '-id',
@@ -98,7 +102,8 @@ describe 'Requesting Tree resources', :type => :request do
98
102
 
99
103
  it 'should respond the tree data' do
100
104
  get '/forest/Tree', params: params, headers: headers
101
- expect(JSON.parse(response.body)).to eq({
105
+
106
+ expect(JSON.parse(response.body)).to include({
102
107
  "data" => [{
103
108
  "type" => "Tree",
104
109
  "id" => "1",
@@ -108,9 +113,30 @@ describe 'Requesting Tree resources', :type => :request do
108
113
  },
109
114
  "links" => {
110
115
  "self" => "/forest/tree/1"
116
+ },
117
+ "relationships" => {
118
+ "location" => {
119
+ "data" => { "id" => "1", "type" => "Location" },
120
+ "links" => { "related" => {} }
121
+ }
111
122
  }
112
123
  }],
113
- "included" => []
124
+ "included" => [{
125
+ "type" => "Location",
126
+ "id" => "1",
127
+ "attributes" => include(
128
+ "id" => 1,
129
+ "created_at" => nil,
130
+ "updated_at" => nil,
131
+ "coordinates" => nil
132
+ ),
133
+ "links" => { "self" => "/forest/location/1" },
134
+ "relationships" => {
135
+ "island" => {
136
+ "links" => { "related" => {} }
137
+ }
138
+ }
139
+ }]
114
140
  })
115
141
  end
116
142
  end
@@ -133,5 +133,187 @@ module ForestLiana
133
133
  end
134
134
  end
135
135
  end
136
+
137
+ describe 'aggregation methods behavior' do
138
+ let(:scopes) { {'scopes' => {}, 'team' => {'id' => '1', 'name' => 'Operations'}} }
139
+ let(:model) { Tree }
140
+ let(:collection) { 'trees' }
141
+ let(:groupByFieldName) { 'age' }
142
+
143
+ describe 'aggregation_sql method' do
144
+ subject { PieStatGetter.new(model, params, user) }
145
+
146
+ context 'with COUNT aggregator' do
147
+ let(:params) {
148
+ {
149
+ type: 'Pie',
150
+ sourceCollectionName: collection,
151
+ timezone: 'Europe/Paris',
152
+ aggregator: 'Count',
153
+ groupByFieldName: groupByFieldName
154
+ }
155
+ }
156
+
157
+ it 'should generate correct COUNT SQL' do
158
+ sql = subject.send(:aggregation_sql, 'count', nil)
159
+ expect(sql).to eq 'COUNT(DISTINCT trees.id)'
160
+ end
161
+
162
+ it 'should generate correct COUNT SQL with specific field' do
163
+ sql = subject.send(:aggregation_sql, 'count', 'age')
164
+ expect(sql).to eq 'COUNT(DISTINCT trees.age)'
165
+ end
166
+ end
167
+
168
+ context 'with SUM aggregator' do
169
+ let(:params) {
170
+ {
171
+ type: 'Pie',
172
+ sourceCollectionName: collection,
173
+ timezone: 'Europe/Paris',
174
+ aggregator: 'Sum',
175
+ aggregateFieldName: 'age',
176
+ groupByFieldName: groupByFieldName
177
+ }
178
+ }
179
+
180
+ it 'should generate correct SUM SQL' do
181
+ sql = subject.send(:aggregation_sql, 'sum', 'age')
182
+ expect(sql).to eq 'SUM(trees.age)'
183
+ end
184
+ end
185
+
186
+ context 'with association field' do
187
+ let(:params) {
188
+ {
189
+ type: 'Pie',
190
+ sourceCollectionName: collection,
191
+ timezone: 'Europe/Paris',
192
+ aggregator: 'Count',
193
+ groupByFieldName: 'owner:name'
194
+ }
195
+ }
196
+
197
+ it 'should handle association fields correctly' do
198
+ # Assuming Tree belongs_to :owner
199
+ allow(model).to receive(:reflect_on_association).with(:owner).and_return(
200
+ double(table_name: 'owners')
201
+ )
202
+
203
+ sql = subject.send(:aggregation_sql, 'count', 'owner:id')
204
+ expect(sql).to eq 'COUNT(DISTINCT owners.id)'
205
+ end
206
+ end
207
+
208
+ context 'with unsupported aggregator' do
209
+ let(:params) {
210
+ {
211
+ type: 'Pie',
212
+ sourceCollectionName: collection,
213
+ timezone: 'Europe/Paris',
214
+ aggregator: 'Invalid',
215
+ groupByFieldName: groupByFieldName
216
+ }
217
+ }
218
+
219
+ it 'should raise an error for unsupported aggregator' do
220
+ expect {
221
+ subject.send(:aggregation_sql, 'invalid', 'age')
222
+ }.to raise_error(ForestLiana::Errors::HTTP422Error)
223
+ end
224
+ end
225
+ end
226
+
227
+ describe 'aggregation_alias method' do
228
+ subject { PieStatGetter.new(model, params, user) }
229
+
230
+ context 'with COUNT aggregator' do
231
+ let(:params) {
232
+ {
233
+ type: 'Pie',
234
+ sourceCollectionName: collection,
235
+ timezone: 'Europe/Paris',
236
+ aggregator: 'Count',
237
+ groupByFieldName: groupByFieldName
238
+ }
239
+ }
240
+
241
+ it 'should return correct alias for count' do
242
+ alias_name = subject.send(:aggregation_alias, 'count', nil)
243
+ expect(alias_name).to eq 'count_id'
244
+ end
245
+ end
246
+
247
+ context 'with SUM aggregator' do
248
+ let(:params) {
249
+ {
250
+ type: 'Pie',
251
+ sourceCollectionName: collection,
252
+ timezone: 'Europe/Paris',
253
+ aggregator: 'Sum',
254
+ aggregateFieldName: 'age',
255
+ groupByFieldName: groupByFieldName
256
+ }
257
+ }
258
+
259
+ it 'should return correct alias for sum' do
260
+ alias_name = subject.send(:aggregation_alias, 'sum', 'age')
261
+ expect(alias_name).to eq 'sum_age'
262
+ end
263
+
264
+ it 'should handle field names with mixed case' do
265
+ alias_name = subject.send(:aggregation_alias, 'sum', 'TreeAge')
266
+ expect(alias_name).to eq 'sum_treeage'
267
+ end
268
+ end
269
+ end
270
+
271
+ describe 'results ordering' do
272
+ subject { PieStatGetter.new(model, params, user) }
273
+
274
+ context 'with COUNT aggregator' do
275
+ let(:params) {
276
+ {
277
+ type: 'Pie',
278
+ sourceCollectionName: collection,
279
+ timezone: 'Europe/Paris',
280
+ aggregator: 'Count',
281
+ groupByFieldName: groupByFieldName
282
+ }
283
+ }
284
+
285
+ it 'should return results ordered by count descending' do
286
+ subject.perform
287
+
288
+ expect(subject.record.value).to eq [
289
+ { :key => 3, :value => 5},
290
+ { :key => 15, :value => 4 }
291
+ ]
292
+ end
293
+ end
294
+
295
+ context 'with SUM aggregator' do
296
+ let(:params) {
297
+ {
298
+ type: 'Pie',
299
+ sourceCollectionName: collection,
300
+ timezone: 'Europe/Paris',
301
+ aggregator: 'Sum',
302
+ aggregateFieldName: 'age',
303
+ groupByFieldName: groupByFieldName
304
+ }
305
+ }
306
+
307
+ it 'should return results ordered by sum descending' do
308
+ subject.perform
309
+
310
+ expect(subject.record.value).to eq [
311
+ { :key => 15, :value => 60 },
312
+ { :key => 3, :value => 15 }
313
+ ]
314
+ end
315
+ end
316
+ end
317
+ end
136
318
  end
137
319
  end
@@ -4,7 +4,7 @@ module ForestLiana
4
4
  let(:pageSize) { 10 }
5
5
  let(:pageNumber) { 1 }
6
6
  let(:sort) { 'id' }
7
- let(:fields) {}
7
+ let(:fields) { { resource.name => 'id' } }
8
8
  let(:filters) {}
9
9
  let(:scopes) { {'scopes' => {}, 'team' => {'id' => '1', 'name' => 'Operations'}} }
10
10
  let(:rendering_id) { 13 }
@@ -38,7 +38,7 @@ module ForestLiana
38
38
  clean_database
39
39
 
40
40
  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']
41
- .map { |name| User.create(name: name) }
41
+ .map { |name| User.create(name: name) }
42
42
 
43
43
  islands = [
44
44
  { :name => 'Skull', :updated_at => Time.now - 1.years },
@@ -190,6 +190,7 @@ module ForestLiana
190
190
 
191
191
  describe 'when on a model having a reserved SQL word as name' do
192
192
  let(:resource) { Reference }
193
+ let(:fields) { { resource.name => 'id' } }
193
194
 
194
195
  it 'should get the ressource properly' do
195
196
  getter.perform
@@ -219,6 +220,7 @@ module ForestLiana
219
220
 
220
221
  describe 'when sorting by a belongs_to association' do
221
222
  let(:resource) { Tree }
223
+ let(:fields) { { resource.name => 'id' } }
222
224
  let(:sort) { 'owner.name' }
223
225
 
224
226
  it 'should get only the expected records' do
@@ -288,21 +290,37 @@ module ForestLiana
288
290
  end
289
291
  end
290
292
 
293
+ describe 'when getting a has_one through association' do
294
+ let(:resource) { Tree }
295
+ let(:fields) { { 'Tree' => 'id,location' } }
296
+
297
+ it 'should get the expected records, including the foreign_key for the direct association' do
298
+ getter.perform
299
+ records = getter.records
300
+ count = getter.count
301
+
302
+ expect(records.count).to eq Tree.count
303
+ expect(count).to eq Tree.count
304
+ expect(records.map(&:id)).to match_array(Tree.pluck(:id))
305
+ expect(records.map(&:island_id)).to match_array(Tree.pluck(:island_id))
306
+ end
307
+ end
308
+
291
309
  describe 'when filtering on an ambiguous field' do
292
310
  let(:resource) { Tree }
293
311
  let(:pageSize) { 5 }
294
- let(:fields) { { 'Tree' => 'id' } }
312
+ let(:fields) { { 'Tree' => 'id,name', 'cutter' => 'id' } }
295
313
  let(:filters) { {
296
314
  aggregator: 'and',
297
315
  conditions: [{
298
- field: 'created_at',
299
- operator: 'after',
300
- value: "#{Time.now - 6.year}",
301
- }, {
302
- field: 'cutter:name',
303
- operator: 'equal',
304
- value: 'Michel'
305
- }]
316
+ field: 'created_at',
317
+ operator: 'after',
318
+ value: "#{Time.now - 6.year}",
319
+ }, {
320
+ field: 'cutter:name',
321
+ operator: 'equal',
322
+ value: 'Michel'
323
+ }]
306
324
  }.to_json }
307
325
 
308
326
  it 'should get only the expected records' do
@@ -314,7 +332,6 @@ module ForestLiana
314
332
  expect(count).to eq 1
315
333
  expect(records.first.id).to eq 3
316
334
  expect(records.first.name).to eq 'Apple Tree'
317
- expect(records.first.cutter.name).to eq 'Michel'
318
335
  end
319
336
  end
320
337
 
@@ -361,7 +378,7 @@ module ForestLiana
361
378
  describe 'when sorting on an ambiguous field name with a filter' do
362
379
  let(:resource) { Tree }
363
380
  let(:sort) { '-name' }
364
- let(:fields) { { 'Tree' => 'id' } }
381
+ let(:fields) { { 'Tree' => 'id,name' } }
365
382
  let(:filters) { {
366
383
  field: 'cutter:name',
367
384
  operator: 'equal',
@@ -399,7 +416,7 @@ module ForestLiana
399
416
 
400
417
  describe 'when filtering on an updated_at field of an associated collection' do
401
418
  let(:resource) { Tree }
402
- let(:fields) { { 'Tree' => 'id' } }
419
+ let(:fields) { { 'Tree' => 'id,name' } }
403
420
  let(:filters) { {
404
421
  field: 'island:updated_at',
405
422
  operator: 'previous_year'
@@ -492,16 +509,16 @@ module ForestLiana
492
509
 
493
510
  it 'should raise the right error' do
494
511
  expect { getter }.to raise_error(
495
- ForestLiana::Errors::NotImplementedMethodError,
496
- "method filter on smart field 'alter_coordinates' not found"
497
- )
512
+ ForestLiana::Errors::NotImplementedMethodError,
513
+ "method filter on smart field 'alter_coordinates' not found"
514
+ )
498
515
  end
499
516
  end
500
517
 
501
518
  describe 'when scopes are defined' do
502
519
  let(:resource) { Island }
503
520
  let(:pageSize) { 15 }
504
- let(:fields) { }
521
+ let(:fields) { { resource.name => 'id' } }
505
522
  let(:filters) { }
506
523
  let(:scopes) {
507
524
  {
@@ -537,10 +554,10 @@ module ForestLiana
537
554
  let(:filters) { {
538
555
  aggregator: 'and',
539
556
  conditions: [{
540
- field: 'name',
541
- operator: 'contains',
542
- value: 'a',
543
- }]
557
+ field: 'name',
558
+ operator: 'contains',
559
+ value: 'a',
560
+ }]
544
561
  }.to_json }
545
562
 
546
563
  it 'should get only the records matching the scope' do
@@ -554,6 +571,84 @@ module ForestLiana
554
571
  expect(records.second.name).to eq 'Treasure'
555
572
  end
556
573
  end
574
+
575
+ describe '#perform' do
576
+ let(:resource) { User }
577
+ let(:fields) { nil }
578
+ let(:sort) { nil }
579
+ let(:filters) { nil }
580
+
581
+ it 'does not raise an error when params[:fields] is nil' do
582
+ expect {
583
+ getter.perform
584
+ }.not_to raise_error
585
+
586
+ records = getter.records
587
+ count = getter.count
588
+
589
+ expect(records).to all(be_a(User))
590
+ expect(count).to eq User.count
591
+ end
592
+ end
593
+
594
+ describe '#extract_associations_from_filter' do
595
+ let(:resource) { Tree }
596
+
597
+ before { init_scopes }
598
+
599
+ context 'with a single filter as JSON string' do
600
+ let(:filters) {
601
+ {
602
+ field: 'island:updated_at',
603
+ operator: 'equal',
604
+ value: '2024-01-01'
605
+ }.to_json
606
+ }
607
+
608
+ it 'extracts the correct association' do
609
+ expect(getter.send(:extract_associations_from_filter)).to eq [:island]
610
+ end
611
+ end
612
+
613
+ context 'with grouped conditions as JSON string' do
614
+ let(:filters) {
615
+ {
616
+ aggregator: 'and',
617
+ conditions: [
618
+ { field: 'island:updated_at', operator: 'equal', value: '2024-01-01' },
619
+ { field: 'owner:name', operator: 'equal', value: 'Michel' },
620
+ { field: 'id', operator: 'present', value: nil }
621
+ ]
622
+ }.to_json
623
+ }
624
+
625
+ it 'extracts all unique associations' do
626
+ expect(getter.send(:extract_associations_from_filter)).to match_array [:island, :owner]
627
+ end
628
+ end
629
+
630
+ context 'when filters has no association field' do
631
+ let(:filters) {
632
+ {
633
+ field: 'id',
634
+ operator: 'equal',
635
+ value: 1
636
+ }.to_json
637
+ }
638
+
639
+ it 'returns an empty array' do
640
+ expect(getter.send(:extract_associations_from_filter)).to eq []
641
+ end
642
+ end
643
+
644
+ context 'when filters is nil' do
645
+ let(:filters) { nil }
646
+
647
+ it 'returns an empty array' do
648
+ expect(getter.send(:extract_associations_from_filter)).to eq []
649
+ end
650
+ end
651
+ end
557
652
  end
558
653
  end
559
- end
654
+ end
@@ -61,7 +61,18 @@ module ForestLiana
61
61
  end
62
62
 
63
63
  expect(collection.fields.map { |field| field[:field].to_s}).to eq(
64
- ["age", "created_at", "cutter", "eponymous_island", "id", "island", "name", "owner", "updated_at"]
64
+ [
65
+ "age",
66
+ "created_at",
67
+ "cutter",
68
+ "eponymous_island",
69
+ "id",
70
+ "island",
71
+ "location",
72
+ "name",
73
+ "owner",
74
+ "updated_at"
75
+ ]
65
76
  )
66
77
  end
67
78
  end
@@ -0,0 +1,53 @@
1
+ module ForestLiana
2
+ describe SerializerFactory do
3
+ describe '#serializer_for has_one_relationships patch' do
4
+ let(:user) { User.create!(name: 'PatchTest') }
5
+ let(:island) { Island.create!(name: 'TestIsland') }
6
+ let(:tree) { Tree.create!(name: 'TestTree', island: island, owner: user) }
7
+
8
+ it 'simulates has_one relation with only primary key' do
9
+ factory = described_class.new
10
+ serializer_class = factory.serializer_for(Tree)
11
+
12
+ serializer_class.send(:has_one, :island) { }
13
+
14
+ instance = serializer_class.new(tree, fields: {
15
+ 'Island' => [:id],
16
+ 'Tree' => [:island]
17
+ })
18
+
19
+ relationships = instance.send(:has_one_relationships)
20
+ expect(relationships).to have_key(:island)
21
+ relation_data = relationships[:island]
22
+ expect(relation_data[:attr_or_block]).to be_a(Proc)
23
+ model = relation_data[:attr_or_block].call
24
+
25
+ expect(model).to be_a(Island)
26
+ expect(model.id).to eq(island.id)
27
+ end
28
+
29
+ it 'returns nil if foreign key is nil' do
30
+ tree_without_island = Tree.create!(name: 'NoIslandTree', island_id: nil, owner: user)
31
+
32
+ factory = described_class.new
33
+ serializer_class = factory.serializer_for(Tree)
34
+
35
+ serializer_class.send(:has_one, :island) { }
36
+
37
+ instance = serializer_class.new(tree_without_island, fields: {
38
+ 'Island' => [:id],
39
+ 'Tree' => [:island]
40
+ })
41
+
42
+ relationships = instance.send(:has_one_relationships)
43
+ expect(relationships).to have_key(:island)
44
+ relation_data = relationships[:island]
45
+ expect(relation_data[:attr_or_block]).to be_a(Proc)
46
+ model = relation_data[:attr_or_block].call
47
+
48
+ expect(model).to be_nil
49
+ end
50
+
51
+ end
52
+ end
53
+ 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: 9.11.3
4
+ version: 9.15.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: 2025-04-09 00:00:00.000000000 Z
11
+ date: 2025-07-23 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -254,6 +254,7 @@ files:
254
254
  - app/services/forest_liana/ability/permission.rb
255
255
  - app/services/forest_liana/ability/permission/request_permission.rb
256
256
  - app/services/forest_liana/ability/permission/smart_action_checker.rb
257
+ - app/services/forest_liana/aggregation_helper.rb
257
258
  - app/services/forest_liana/apimap_sorter.rb
258
259
  - app/services/forest_liana/authentication.rb
259
260
  - app/services/forest_liana/authorization_getter.rb
@@ -317,6 +318,7 @@ files:
317
318
  - config/routes.rb
318
319
  - config/routes/actions.rb
319
320
  - lib/forest_liana.rb
321
+ - lib/forest_liana/active_record_override.rb
320
322
  - lib/forest_liana/base64_string_io.rb
321
323
  - lib/forest_liana/bootstrapper.rb
322
324
  - lib/forest_liana/collection.rb
@@ -430,6 +432,7 @@ files:
430
432
  - spec/services/forest_liana/resources_getter_spec.rb
431
433
  - spec/services/forest_liana/schema_adapter_spec.rb
432
434
  - spec/services/forest_liana/scope_manager_spec.rb
435
+ - spec/services/forest_liana/serializer_factory_spec.rb
433
436
  - spec/services/forest_liana/smart_action_field_validator_spec.rb
434
437
  - spec/services/forest_liana/smart_action_form_parser_spec.rb
435
438
  - spec/services/forest_liana/utils/context_variables_injector_spec.rb
@@ -735,6 +738,7 @@ test_files:
735
738
  - spec/services/forest_liana/resources_getter_spec.rb
736
739
  - spec/services/forest_liana/schema_adapter_spec.rb
737
740
  - spec/services/forest_liana/scope_manager_spec.rb
741
+ - spec/services/forest_liana/serializer_factory_spec.rb
738
742
  - spec/services/forest_liana/smart_action_field_validator_spec.rb
739
743
  - spec/services/forest_liana/smart_action_form_parser_spec.rb
740
744
  - spec/services/forest_liana/utils/context_variables_injector_spec.rb