forest_liana 6.1.1 → 6.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 8c38a671d9137793a03aa5081ff0fc5602dd26fd2015f29d5e94205a82562f35
4
- data.tar.gz: 0b38be20c307f00be9645383d4655eec0ccb38cc747e43ed7c7759b8f884284b
3
+ metadata.gz: 9db3ae9b9a24a9f298e24a2b6562e8df12b0123cbbe45f453fab19d8da7a8f10
4
+ data.tar.gz: 4e245a23470730308895296e37e765a711186381820f2bf619e5091966cba6fc
5
5
  SHA512:
6
- metadata.gz: 5ed3dfb92b55a1516db98f6ad2b838a16348d9c4ae01e32ddc53d7f592fb92a883d35759dc33fccf1cb9ce28d597735c1d41b67c1a408c87ffd969fe8396771d
7
- data.tar.gz: 4efa06e606a4e62594b039875e10188658b52a52a9ba4e9bf4855c6746d80fc4efb61ff2acefb366b1b071d74d01b79f12253770b8df29987d7f5ddea003438e
6
+ metadata.gz: 9d87f2aa53059a2c6129bc5cc1d5107009121d6c97f08b2b6e745c55132ac333be420d9ea9f82fe4441c9b59a447eafad3f4111b4a8109650935d958664e6cd2
7
+ data.tar.gz: 9e7300a1819a26f7ca5dd4f8d59fa58abdb009dca12b045c963c0a0fdf10398bdeb403833fc7b021b4c93257ef7799f57210c6e8cda8755b350d3252f548d0e6
@@ -4,5 +4,11 @@ module ForestLiana
4
4
  collection_name = ForestLiana.name_for(active_record_class)
5
5
  ForestLiana.apimap.find { |collection| collection.name.to_s == collection_name }
6
6
  end
7
+
8
+ def self.is_smart_field?(model, field_name)
9
+ collection = self.find_collection_from_model(model)
10
+ field_found = collection.fields.find { |collection_field| collection_field[:field].to_s == field_name } if collection
11
+ field_found && field_found[:is_virtual]
12
+ end
7
13
  end
8
14
  end
@@ -48,6 +48,7 @@ class ForestLiana::Model::Action
48
48
  field[:default_value] = nil unless field.key?(:default_value)
49
49
  field[:enums] = nil unless field.key?(:enums)
50
50
  field[:is_required] = false unless field.key?(:is_required)
51
+ field[:is_read_only] = false unless field.key?(:is_read_only)
51
52
  field[:reference] = nil unless field.key?(:reference)
52
53
  field[:description] = nil unless field.key?(:description)
53
54
  field[:widget] = nil unless field.key?(:widget)
@@ -47,6 +47,7 @@ module ForestLiana
47
47
  'default_value',
48
48
  'enums',
49
49
  'is_required',
50
+ 'is_read_only',
50
51
  'reference',
51
52
  'description',
52
53
  'position',
@@ -47,30 +47,56 @@ module ForestLiana
47
47
  end
48
48
 
49
49
  def parse_condition(condition)
50
- ensure_valid_condition(condition)
50
+ where = parse_condition_without_smart_field(condition)
51
51
 
52
- operator = condition['operator']
53
- value = condition['value']
54
- field = condition['field']
52
+ field_name = condition['field']
55
53
 
56
- if @operator_date_parser.is_date_operator?(operator)
57
- condition = @operator_date_parser.get_date_filter(operator, value)
58
- return "#{parse_field_name(field)} #{condition}"
54
+ if ForestLiana::SchemaHelper.is_smart_field?(@resource, field_name)
55
+ schema = ForestLiana.schema_for_resource(@resource)
56
+ field_schema = schema.fields.find do |field|
57
+ field[:field].to_s == field_name
58
+ end
59
+
60
+ unless field_schema.try(:[], :filter)
61
+ raise ForestLiana::Errors::NotImplementedMethodError.new("method filter on smart field '#{field_name}' not found")
62
+ end
63
+
64
+ return field_schema[:filter].call(condition, where)
59
65
  end
60
66
 
61
- if is_belongs_to(field)
62
- association = field.partition(':').first.to_sym
63
- association_field = field.partition(':').last
67
+ where
68
+ end
69
+
70
+ def get_association_field_and_resource(field_name)
71
+ if is_belongs_to(field_name)
72
+ association = field_name.partition(':').first.to_sym
73
+ association_field = field_name.partition(':').last
64
74
 
65
75
  unless @resource.reflect_on_association(association)
66
76
  raise ForestLiana::Errors::HTTP422Error.new("Association '#{association}' not found")
67
77
  end
68
78
 
69
79
  current_resource = @resource.reflect_on_association(association).klass
80
+
81
+ return association_field, current_resource
70
82
  else
71
- association_field = field
72
- current_resource = @resource
83
+ return field_name, @resource
73
84
  end
85
+ end
86
+
87
+ def parse_condition_without_smart_field(condition)
88
+ ensure_valid_condition(condition)
89
+
90
+ operator = condition['operator']
91
+ value = condition['value']
92
+ field_name = condition['field']
93
+
94
+ if @operator_date_parser.is_date_operator?(operator)
95
+ condition = @operator_date_parser.get_date_filter(operator, value)
96
+ return "#{parse_field_name(field_name)} #{condition}"
97
+ end
98
+
99
+ association_field, current_resource = get_association_field_and_resource(field_name)
74
100
 
75
101
  # NOTICE: Set the integer value instead of a string if "enum" type
76
102
  # NOTICE: Rails 3 do not have a defined_enums method
@@ -78,7 +104,7 @@ module ForestLiana
78
104
  value = current_resource.defined_enums[association_field][value]
79
105
  end
80
106
 
81
- parsed_field = parse_field_name(field)
107
+ parsed_field = parse_field_name(field_name)
82
108
  parsed_operator = parse_operator(operator)
83
109
  parsed_value = parse_value(operator, value)
84
110
  field_and_operator = "#{parsed_field} #{parsed_operator}"
@@ -149,16 +175,16 @@ module ForestLiana
149
175
 
150
176
  association = get_association_name_for_condition(field)
151
177
  quoted_table_name = ActiveRecord::Base.connection.quote_column_name(association)
152
- quoted_field_name = ActiveRecord::Base.connection.quote_column_name(field.split(':')[1])
178
+ field_name = field.split(':')[1]
153
179
  else
154
180
  quoted_table_name = @resource.quoted_table_name
155
- quoted_field_name = ActiveRecord::Base.connection.quote_column_name(field)
156
181
  current_resource = @resource
182
+ field_name = field
157
183
  end
184
+ quoted_field_name = ActiveRecord::Base.connection.quote_column_name(field_name)
158
185
 
159
186
  column_found = current_resource.columns.find { |column| column.name == field.split(':').last }
160
-
161
- if column_found.nil?
187
+ if column_found.nil? && !ForestLiana::SchemaHelper.is_smart_field?(current_resource, field_name)
162
188
  raise ForestLiana::Errors::HTTP422Error.new("Field '#{field}' not found")
163
189
  end
164
190
 
@@ -46,6 +46,12 @@ module ForestLiana
46
46
  end
47
47
  end
48
48
 
49
+ class NotImplementedMethodError < ExpectedError
50
+ def initialize(message = "Method not implemented")
51
+ super(501, :internal_server_error, message, 'MethodNotImplementedError')
52
+ end
53
+ end
54
+
49
55
  class InconsistentSecretAndRenderingError < ExpectedError
50
56
  def initialize(message=ForestLiana::MESSAGES[:SERVER_TRANSACTION][:SECRET_AND_RENDERINGID_INCONSISTENT])
51
57
  super(500, :internal_server_error, message, 'InconsistentSecretAndRenderingError')
@@ -58,6 +58,7 @@ module ForestLiana
58
58
  'default_value',
59
59
  'enums',
60
60
  'is_required',
61
+ 'is_read_only',
61
62
  'reference',
62
63
  'description',
63
64
  'position',
@@ -1,3 +1,3 @@
1
1
  module ForestLiana
2
- VERSION = "6.1.1"
2
+ VERSION = "6.3.0"
3
3
  end
@@ -2,4 +2,5 @@ class Island < ActiveRecord::Base
2
2
  self.table_name = 'isle'
3
3
 
4
4
  has_many :trees
5
+ has_one :location
5
6
  end
@@ -0,0 +1,3 @@
1
+ class Location < ActiveRecord::Base
2
+ belongs_to :island
3
+ end
@@ -0,0 +1,2 @@
1
+ class Reference < ActiveRecord::Base
2
+ end
@@ -0,0 +1,8 @@
1
+ class CreateReferences < ActiveRecord::Migration[6.0]
2
+ def change
3
+ create_table :references do |t|
4
+
5
+ t.timestamps
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,10 @@
1
+ class CreateLocations < ActiveRecord::Migration[6.0]
2
+ def change
3
+ create_table :locations do |t|
4
+ t.string :coordinates
5
+ t.references :island, index: true
6
+
7
+ t.timestamps
8
+ end
9
+ end
10
+ end
@@ -10,7 +10,7 @@
10
10
  #
11
11
  # It's strongly recommended that you check this file into your version control system.
12
12
 
13
- ActiveRecord::Schema.define(version: 2019_07_16_135241) do
13
+ ActiveRecord::Schema.define(version: 2021_03_26_140855) do
14
14
 
15
15
  create_table "isle", force: :cascade do |t|
16
16
  t.string "name"
@@ -19,6 +19,19 @@ ActiveRecord::Schema.define(version: 2019_07_16_135241) do
19
19
  t.datetime "updated_at"
20
20
  end
21
21
 
22
+ create_table "locations", force: :cascade do |t|
23
+ t.string "coordinates"
24
+ t.integer "island_id"
25
+ t.datetime "created_at", precision: 6, null: false
26
+ t.datetime "updated_at", precision: 6, null: false
27
+ t.index ["island_id"], name: "index_locations_on_island_id"
28
+ end
29
+
30
+ create_table "references", force: :cascade do |t|
31
+ t.datetime "created_at", precision: 6, null: false
32
+ t.datetime "updated_at", precision: 6, null: false
33
+ end
34
+
22
35
  create_table "trees", force: :cascade do |t|
23
36
  t.string "name"
24
37
  t.integer "owner_id"
@@ -0,0 +1,10 @@
1
+ class Forest::Location
2
+ include ForestLiana::Collection
3
+
4
+ collection :Location
5
+
6
+ field :alter_coordinates, type: 'String' do
7
+ object.name + 'XYZ'
8
+ end
9
+
10
+ end
@@ -0,0 +1,15 @@
1
+ class Forest::User
2
+ include ForestLiana::Collection
3
+
4
+ collection :User
5
+
6
+ filter_cap_name = lambda do |condition, where|
7
+ capitalize_name = condition['value'].capitalize
8
+ "name IS '#{capitalize_name}'"
9
+ end
10
+
11
+ field :cap_name, type: 'String', filter: filter_cap_name do
12
+ object.name.upcase
13
+ end
14
+
15
+ end
@@ -26,6 +26,7 @@ describe 'Requesting Actions routes', :type => :request do
26
26
  default_value: nil,
27
27
  enums: nil,
28
28
  is_required: false,
29
+ is_read_only: false,
29
30
  reference: nil,
30
31
  description: nil,
31
32
  widget: nil,
@@ -0,0 +1,359 @@
1
+ module ForestLiana
2
+ describe ResourcesGetter do
3
+ let(:resource) { User }
4
+ let(:pageSize) { 10 }
5
+ let(:pageNumber) { 1 }
6
+ let(:sort) { 'id' }
7
+ let(:fields) { }
8
+ let(:filters) { }
9
+
10
+ let(:getter) { described_class.new(resource, {
11
+ page: { size: pageSize, number: pageNumber },
12
+ sort: sort,
13
+ fields: fields,
14
+ filters: filters,
15
+ })}
16
+
17
+ before(:each) do
18
+ 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']
19
+ .map { |name| User.create(name: name) }
20
+
21
+ islands = [
22
+ { :name => 'Skull', :updated_at => Time.now - 1.years },
23
+ { :name => 'Muerta', :updated_at => Time.now - 5.years },
24
+ { :name => 'Treasure', :updated_at => Time.now },
25
+ { :name => 'Birds', :updated_at => Time.now - 7.years },
26
+ { :name => 'Lille', :updated_at => Time.now - 1.years }
27
+ ].map { |island| Island.create(name: island[:name], updated_at: island[:updated_at]) }
28
+
29
+ trees = [
30
+ { :name => 'Lemon Tree', :created_at => Time.now - 7.years, :island => islands[0], :owner => users[0], :cutter => users[0] },
31
+ { :name => 'Ginger Tree', :created_at => Time.now - 7.years, :island => islands[0], :owner => users[1], :cutter => users[0] },
32
+ { :name => 'Apple Tree', :created_at => Time.now - 5.years, :island => islands[1], :owner => users[2], :cutter => users[0] },
33
+ { :name => 'Pear Tree', :created_at => Time.now + 4.hours, :island => islands[3], :owner => users[3], :cutter => users[1] },
34
+ { :name => 'Choco Tree', :created_at => Time.now, :island => islands[3], :owner => users[4], :cutter => users[1] }
35
+ ].map { |tree| Tree.create(name: tree[:name], created_at: tree[:created_at], island: tree[:island], owner: tree[:owner], cutter: tree[:cutter]) }
36
+
37
+ locations = [
38
+ { :coordinates => '12345', :island => islands[0] },
39
+ { :coordinates => '54321', :island => islands[1] },
40
+ { :coordinates => '43215', :island => islands[2] },
41
+ { :coordinates => '21543', :island => islands[3] },
42
+ { :coordinates => '32154', :island => islands[4] }
43
+ ].map { |location| Location.create(coordinates: location[:coordinates], island: location[:island]) }
44
+
45
+ reference = Reference.create()
46
+ end
47
+
48
+ after(:each) do
49
+ User.destroy_all
50
+ Island.destroy_all
51
+ Location.destroy_all
52
+ Tree.destroy_all
53
+ end
54
+
55
+ describe 'when there are more records than the page size' do
56
+ describe 'when asking for the 1st page and 15 records' do
57
+ let(:pageSize) { 15 }
58
+ let(:sort) { '-id' }
59
+
60
+ it 'should get only the expected records' do
61
+ getter.perform
62
+ records = getter.records
63
+ count = getter.count
64
+
65
+ expect(records.count).to eq 15
66
+ expect(count).to eq 30
67
+ expect(records.first.id).to eq 30
68
+ expect(records.last.id).to eq 16
69
+ end
70
+ end
71
+
72
+ describe 'when asking for the 2nd page and 10 records' do
73
+ let(:pageNumber) { 2 }
74
+ let(:sort) { '-id' }
75
+
76
+ it 'should get only the expected records' do
77
+ getter.perform
78
+ records = getter.records
79
+ count = getter.count
80
+
81
+ expect(records.count).to eq 10
82
+ expect(count).to eq 30
83
+ expect(records.first.id).to eq 20
84
+ expect(records.last.id).to eq 11
85
+ end
86
+ end
87
+ end
88
+
89
+ describe 'when on a model having a reserved SQL word as name' do
90
+ let(:resource) { Reference }
91
+
92
+ it 'should get the ressource properly' do
93
+ getter.perform
94
+ records = getter.records
95
+ count = getter.count
96
+
97
+ expect(records.count).to eq 1
98
+ expect(count).to eq 1
99
+ expect(records.first.id).to eq 1
100
+ end
101
+ end
102
+
103
+ describe 'when sorting by a specific field' do
104
+ let(:pageSize) { 5 }
105
+ let(:sort) { '-name' }
106
+
107
+ it 'should get only the expected records' do
108
+ getter.perform
109
+ records = getter.records
110
+ count = getter.count
111
+
112
+ expect(records.count).to eq 5
113
+ expect(count).to eq 30
114
+ expect(records.map(&:name)).to eq ['Xavier', 'Vince', 'Valentin', 'Steve', 'Sandro']
115
+ end
116
+ end
117
+
118
+ describe 'when sorting by a belongs_to association' do
119
+ let(:resource) { Tree }
120
+ let(:sort) { 'owner.name' }
121
+
122
+ it 'should get only the expected records' do
123
+ getter.perform
124
+ records = getter.records
125
+ count = getter.count
126
+
127
+ expect(records.count).to eq 5
128
+ expect(count).to eq 5
129
+ expect(records.map(&:id)).to eq [1, 5, 2, 4, 3]
130
+ end
131
+ end
132
+
133
+ describe 'when sorting by a has_one association' do
134
+ let(:resource) { Island }
135
+ let(:sort) { 'location.coordinates' }
136
+ let(:pageSize) { 5 }
137
+
138
+ it 'should get only the expected records' do
139
+ getter.perform
140
+ records = getter.records
141
+ count = getter.count
142
+
143
+ expect(records.count).to eq 5
144
+ expect(count).to eq 5
145
+ expect(records.map(&:id)).to eq [1, 4, 5, 3, 2]
146
+ end
147
+ end
148
+
149
+ describe 'when filtering on an ambiguous field' do
150
+ let(:resource) { Tree }
151
+ let(:pageSize) { 5 }
152
+ let(:fields) { { 'Tree' => 'id' } }
153
+ let(:filters) { {
154
+ aggregator: 'and',
155
+ conditions: [{
156
+ field: 'created_at',
157
+ operator: 'after',
158
+ value: "#{Time.now - 6.year}",
159
+ }, {
160
+ field: 'cutter:name',
161
+ operator: 'equal',
162
+ value: 'Michel'
163
+ }]
164
+ }.to_json }
165
+
166
+ it 'should get only the expected records' do
167
+ getter.perform
168
+ records = getter.records
169
+ count = getter.count
170
+
171
+ expect(records.count).to eq 1
172
+ expect(count).to eq 1
173
+ expect(records.first.id).to eq 3
174
+ expect(records.first.name).to eq 'Apple Tree'
175
+ expect(records.first.cutter.name).to eq 'Michel'
176
+ end
177
+ end
178
+
179
+ describe 'when filtering on before x hours ago' do
180
+ let(:resource) { Tree }
181
+ let(:fields) { { 'Tree' => 'id' } }
182
+ let(:filters) { {
183
+ field: 'created_at',
184
+ operator: 'before_x_hours_ago',
185
+ value: 3
186
+ }.to_json }
187
+
188
+ it 'should filter as expected' do
189
+ getter.perform
190
+ records = getter.records
191
+ count = getter.count
192
+
193
+ expect(records.count).to eq 3
194
+ expect(count).to eq 3
195
+ expect(records.map(&:name)).to eq ['Lemon Tree', 'Ginger Tree', 'Apple Tree']
196
+ end
197
+ end
198
+
199
+ describe 'when filtering on after x hours ago' do
200
+ let(:resource) { Tree }
201
+ let(:fields) { { 'Tree' => 'id' } }
202
+ let(:filters) { {
203
+ field: 'created_at',
204
+ operator: 'after_x_hours_ago',
205
+ value: 3
206
+ }.to_json }
207
+
208
+ it 'should filter as expected' do
209
+ getter.perform
210
+ records = getter.records
211
+ count = getter.count
212
+
213
+ expect(records.count).to eq 2
214
+ expect(count).to eq 2
215
+ expect(records.map(&:name)).to eq ['Pear Tree', 'Choco Tree']
216
+ end
217
+ end
218
+
219
+ describe 'when sorting on an ambiguous field name with a filter' do
220
+ let(:resource) { Tree }
221
+ let(:sort) { '-name' }
222
+ let(:fields) { { 'Tree' => 'id' } }
223
+ let(:filters) { {
224
+ field: 'cutter:name',
225
+ operator: 'equal',
226
+ value: 'Michel'
227
+ }.to_json }
228
+
229
+ it 'should get only the sorted expected records' do
230
+ getter.perform
231
+ records = getter.records
232
+ count = getter.count
233
+
234
+ expect(records.count).to eq 3
235
+ expect(count).to eq 3
236
+ expect(records.map(&:name)).to eq ['Lemon Tree', 'Ginger Tree', 'Apple Tree']
237
+ end
238
+ end
239
+
240
+ describe 'when filtering on an updated_at field of the main collection' do
241
+ let(:resource) { Island }
242
+ let(:filters) { {
243
+ field: 'updated_at',
244
+ operator: 'previous_year'
245
+ }.to_json }
246
+
247
+ it 'should get only the expected records' do
248
+ getter.perform
249
+ records = getter.records
250
+ count = getter.count
251
+
252
+ expect(records.count).to eq 2
253
+ expect(count).to eq 2
254
+ expect(records.map(&:name)).to eq ['Skull', 'Lille']
255
+ end
256
+ end
257
+
258
+ describe 'when filtering on an updated_at field of an associated collection' do
259
+ let(:resource) { Tree }
260
+ let(:fields) { { 'Tree' => 'id' } }
261
+ let(:filters) { {
262
+ field: 'island:updated_at',
263
+ operator: 'previous_year'
264
+ }.to_json }
265
+
266
+ it 'should get only the expected records' do
267
+ getter.perform
268
+ records = getter.records
269
+ count = getter.count
270
+
271
+ expect(records.count).to eq 2
272
+ expect(count).to eq 2
273
+ expect(records.map(&:name)).to eq ['Lemon Tree', 'Ginger Tree']
274
+ end
275
+ end
276
+
277
+ describe 'when filtering on an exact updated_at field of an associated collection' do
278
+ let(:resource) { Tree }
279
+ let(:fields) { { 'Tree' => 'id' } }
280
+ let(:filters) { {
281
+ field: 'island:updated_at',
282
+ operator: 'equal',
283
+ value: 'Sat Jul 02 2016 11:52:00 GMT-0400 (EDT)',
284
+ }.to_json }
285
+
286
+ it 'should get only the expected records' do
287
+ getter.perform
288
+ records = getter.records
289
+ count = getter.count
290
+
291
+ expect(records.count).to eq 0
292
+ expect(count).to eq 0
293
+ end
294
+ end
295
+
296
+ describe 'when filtering on a field of an associated collection that does not exist' do
297
+ let(:resource) { Tree }
298
+ let(:fields) { { 'Tree' => 'id' } }
299
+ let(:filters) { {
300
+ field: 'leaf:id',
301
+ operator: 'equal',
302
+ value: 1
303
+ }.to_json }
304
+
305
+ it 'should raise the right error' do
306
+ expect { getter }.to raise_error(ForestLiana::Errors::HTTP422Error, "Association 'leaf' not found")
307
+ end
308
+ end
309
+
310
+ describe 'when filtering on a field that does not exists' do
311
+ let(:resource) { Tree }
312
+ let(:fields) { { 'Tree' => 'id' } }
313
+ let(:filters) { {
314
+ field: 'content',
315
+ operator: 'contains',
316
+ value: 'c'
317
+ }.to_json }
318
+
319
+ it 'should raise the right error' do
320
+ expect { getter }.to raise_error(ForestLiana::Errors::HTTP422Error, "Field 'content' not found")
321
+ end
322
+ end
323
+
324
+ describe 'when filtering on a smart field' do
325
+ let(:filters) { {
326
+ field: 'cap_name',
327
+ operator: 'equal',
328
+ value: 'MICHEL',
329
+ }.to_json }
330
+
331
+ it 'should filter as expected' do
332
+ getter.perform
333
+ records = getter.records
334
+ count = getter.count
335
+
336
+ expect(records.count).to eq 1
337
+ expect(count).to eq 1
338
+ expect(records.first.id).to eq 1
339
+ expect(records.first.name).to eq 'Michel'
340
+ end
341
+ end
342
+
343
+ describe 'when filtering on a smart field with no filter method' do
344
+ let(:resource) { Location }
345
+ let(:filters) { {
346
+ field: 'alter_coordinates',
347
+ operator: 'equal',
348
+ value: '12345XYZ',
349
+ }.to_json }
350
+
351
+ it 'should raise the right error' do
352
+ expect { getter }.to raise_error(
353
+ ForestLiana::Errors::NotImplementedMethodError,
354
+ "method filter on smart field 'alter_coordinates' not found"
355
+ )
356
+ end
357
+ end
358
+ end
359
+ end
@@ -8,7 +8,7 @@ module ForestLiana
8
8
  end
9
9
 
10
10
  expect(collection.fields.map { |field| field[:field] }).to eq(
11
- ["id", "name", "created_at", "updated_at", "trees"]
11
+ ["id", "name", "created_at", "updated_at", "trees", "location"]
12
12
  )
13
13
  end
14
14
  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: 6.1.1
4
+ version: 6.3.0
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-03-22 00:00:00.000000000 Z
11
+ date: 2021-04-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -325,6 +325,8 @@ files:
325
325
  - spec/dummy/app/controllers/application_controller.rb
326
326
  - spec/dummy/app/helpers/application_helper.rb
327
327
  - spec/dummy/app/models/island.rb
328
+ - spec/dummy/app/models/location.rb
329
+ - spec/dummy/app/models/reference.rb
328
330
  - spec/dummy/app/models/tree.rb
329
331
  - spec/dummy/app/models/user.rb
330
332
  - spec/dummy/app/views/layouts/application.html.erb
@@ -356,7 +358,11 @@ files:
356
358
  - spec/dummy/db/migrate/20190226174951_create_tree.rb
357
359
  - spec/dummy/db/migrate/20190716130830_add_age_to_tree.rb
358
360
  - spec/dummy/db/migrate/20190716135241_add_type_to_user.rb
361
+ - spec/dummy/db/migrate/20210326110524_create_references.rb
362
+ - spec/dummy/db/migrate/20210326140855_create_locations.rb
359
363
  - spec/dummy/db/schema.rb
364
+ - spec/dummy/lib/forest_liana/collections/location.rb
365
+ - spec/dummy/lib/forest_liana/collections/user.rb
360
366
  - spec/helpers/forest_liana/is_same_data_structure_helper_spec.rb
361
367
  - spec/helpers/forest_liana/query_helper_spec.rb
362
368
  - spec/helpers/forest_liana/schema_helper_spec.rb
@@ -373,6 +379,7 @@ files:
373
379
  - spec/services/forest_liana/permissions_checker_live_queries_spec.rb
374
380
  - spec/services/forest_liana/permissions_formatter_spec.rb
375
381
  - spec/services/forest_liana/permissions_getter_spec.rb
382
+ - spec/services/forest_liana/resources_getter_spec.rb
376
383
  - spec/services/forest_liana/schema_adapter_spec.rb
377
384
  - spec/spec_helper.rb
378
385
  - test/dummy/README.rdoc
@@ -462,7 +469,6 @@ files:
462
469
  - test/services/forest_liana/has_many_getter_test.rb
463
470
  - test/services/forest_liana/pie_stat_getter_test.rb
464
471
  - test/services/forest_liana/resource_updater_test.rb
465
- - test/services/forest_liana/resources_getter_test.rb
466
472
  - test/services/forest_liana/schema_adapter_test.rb
467
473
  - test/services/forest_liana/scope_validator_test.rb
468
474
  - test/services/forest_liana/value_stat_getter_test.rb
@@ -491,154 +497,160 @@ signing_key:
491
497
  specification_version: 4
492
498
  summary: Official Rails Liana for Forest
493
499
  test_files:
494
- - test/dummy/config/application.rb
495
- - test/dummy/config/database.yml
496
- - test/dummy/config/environment.rb
497
- - test/dummy/config/locales/en.yml
498
- - test/dummy/config/secrets.yml
499
- - test/dummy/config/environments/development.rb
500
- - test/dummy/config/environments/test.rb
501
- - test/dummy/config/environments/production.rb
502
- - test/dummy/config/boot.rb
503
- - test/dummy/config/initializers/session_store.rb
504
- - test/dummy/config/initializers/mime_types.rb
505
- - test/dummy/config/initializers/cookies_serializer.rb
506
- - test/dummy/config/initializers/wrap_parameters.rb
507
- - test/dummy/config/initializers/inflections.rb
508
- - test/dummy/config/initializers/filter_parameter_logging.rb
509
- - test/dummy/config/initializers/assets.rb
510
- - test/dummy/config/initializers/backtrace_silencers.rb
511
- - test/dummy/config/routes.rb
512
- - test/dummy/app/assets/config/manifest.js
513
- - test/dummy/app/assets/stylesheets/application.css
514
- - test/dummy/app/assets/javascripts/application.js
515
- - test/dummy/app/views/layouts/application.html.erb
500
+ - test/dummy/db/migrate/20150608133044_create_has_one_field.rb
501
+ - test/dummy/db/migrate/20150608132159_create_boolean_field.rb
502
+ - test/dummy/db/migrate/20160627172810_create_owner.rb
503
+ - test/dummy/db/migrate/20150608131603_create_decimal_field.rb
504
+ - test/dummy/db/migrate/20150608133038_create_belongs_to_field.rb
505
+ - test/dummy/db/migrate/20150814081918_create_has_many_through_field.rb
506
+ - test/dummy/db/migrate/20160627172951_create_tree.rb
507
+ - test/dummy/db/migrate/20150608131610_create_float_field.rb
508
+ - test/dummy/db/migrate/20150608150016_create_has_many_field.rb
509
+ - test/dummy/db/migrate/20150608131430_create_integer_field.rb
510
+ - test/dummy/db/migrate/20181111162121_create_references_table.rb
511
+ - test/dummy/db/migrate/20150612112520_create_has_and_belongs_to_many_field.rb
512
+ - test/dummy/db/migrate/20150608132621_create_string_field.rb
513
+ - test/dummy/db/migrate/20170614141921_create_serialize_field.rb
514
+ - test/dummy/db/migrate/20150608130516_create_date_field.rb
515
+ - test/dummy/db/migrate/20150616150629_create_polymorphic_field.rb
516
+ - test/dummy/db/migrate/20150609114636_create_belongs_to_class_name_field.rb
517
+ - test/dummy/db/migrate/20160628173505_add_timestamps.rb
518
+ - test/dummy/db/migrate/20150623115554_create_has_many_class_name_field.rb
519
+ - test/dummy/db/schema.rb
520
+ - test/dummy/public/404.html
521
+ - test/dummy/public/500.html
522
+ - test/dummy/public/422.html
523
+ - test/dummy/public/favicon.ico
524
+ - test/dummy/Rakefile
516
525
  - test/dummy/app/controllers/application_controller.rb
517
- - test/dummy/app/models/tree.rb
518
- - test/dummy/app/models/reference.rb
519
- - test/dummy/app/models/belongs_to_field.rb
520
- - test/dummy/app/models/string_field.rb
521
- - test/dummy/app/models/has_many_through_field.rb
522
- - test/dummy/app/models/has_many_class_name_field.rb
523
- - test/dummy/app/models/date_field.rb
526
+ - test/dummy/app/models/has_and_belongs_to_many_field.rb
524
527
  - test/dummy/app/models/polymorphic_field.rb
528
+ - test/dummy/app/models/has_many_field.rb
529
+ - test/dummy/app/models/float_field.rb
530
+ - test/dummy/app/models/string_field.rb
531
+ - test/dummy/app/models/has_one_field.rb
532
+ - test/dummy/app/models/reference.rb
533
+ - test/dummy/app/models/serialize_field.rb
525
534
  - test/dummy/app/models/boolean_field.rb
535
+ - test/dummy/app/models/has_many_through_field.rb
526
536
  - test/dummy/app/models/belongs_to_class_name_field.rb
527
- - test/dummy/app/models/has_one_field.rb
528
- - test/dummy/app/models/has_many_field.rb
529
- - test/dummy/app/models/has_and_belongs_to_many_field.rb
530
537
  - test/dummy/app/models/decimal_field.rb
531
- - test/dummy/app/models/owner.rb
532
- - test/dummy/app/models/serialize_field.rb
533
538
  - test/dummy/app/models/integer_field.rb
534
- - test/dummy/app/models/float_field.rb
539
+ - test/dummy/app/models/tree.rb
540
+ - test/dummy/app/models/date_field.rb
541
+ - test/dummy/app/models/belongs_to_field.rb
542
+ - test/dummy/app/models/has_many_class_name_field.rb
543
+ - test/dummy/app/models/owner.rb
544
+ - test/dummy/app/assets/stylesheets/application.css
545
+ - test/dummy/app/assets/javascripts/application.js
546
+ - test/dummy/app/assets/config/manifest.js
535
547
  - test/dummy/app/helpers/application_helper.rb
536
- - test/dummy/Rakefile
537
- - test/dummy/config.ru
548
+ - test/dummy/app/views/layouts/application.html.erb
538
549
  - test/dummy/README.rdoc
539
- - test/dummy/bin/rails
550
+ - test/dummy/config.ru
551
+ - test/dummy/config/environment.rb
552
+ - test/dummy/config/secrets.yml
553
+ - test/dummy/config/boot.rb
554
+ - test/dummy/config/database.yml
555
+ - test/dummy/config/routes.rb
556
+ - test/dummy/config/application.rb
557
+ - test/dummy/config/initializers/filter_parameter_logging.rb
558
+ - test/dummy/config/initializers/mime_types.rb
559
+ - test/dummy/config/initializers/session_store.rb
560
+ - test/dummy/config/initializers/inflections.rb
561
+ - test/dummy/config/initializers/assets.rb
562
+ - test/dummy/config/initializers/wrap_parameters.rb
563
+ - test/dummy/config/initializers/backtrace_silencers.rb
564
+ - test/dummy/config/initializers/cookies_serializer.rb
565
+ - test/dummy/config/environments/test.rb
566
+ - test/dummy/config/environments/production.rb
567
+ - test/dummy/config/environments/development.rb
568
+ - test/dummy/config/locales/en.yml
540
569
  - test/dummy/bin/rake
541
570
  - test/dummy/bin/bundle
571
+ - test/dummy/bin/rails
542
572
  - test/dummy/bin/setup
543
- - test/dummy/public/favicon.ico
544
- - test/dummy/public/422.html
545
- - test/dummy/public/404.html
546
- - test/dummy/public/500.html
547
- - test/dummy/db/schema.rb
548
- - test/dummy/db/migrate/20150608131430_create_integer_field.rb
549
- - test/dummy/db/migrate/20181111162121_create_references_table.rb
550
- - test/dummy/db/migrate/20150608130516_create_date_field.rb
551
- - test/dummy/db/migrate/20160627172810_create_owner.rb
552
- - test/dummy/db/migrate/20150609114636_create_belongs_to_class_name_field.rb
553
- - test/dummy/db/migrate/20170614141921_create_serialize_field.rb
554
- - test/dummy/db/migrate/20150608132159_create_boolean_field.rb
555
- - test/dummy/db/migrate/20150616150629_create_polymorphic_field.rb
556
- - test/dummy/db/migrate/20160627172951_create_tree.rb
557
- - test/dummy/db/migrate/20150608132621_create_string_field.rb
558
- - test/dummy/db/migrate/20150608150016_create_has_many_field.rb
559
- - test/dummy/db/migrate/20150612112520_create_has_and_belongs_to_many_field.rb
560
- - test/dummy/db/migrate/20150814081918_create_has_many_through_field.rb
561
- - test/dummy/db/migrate/20150608133038_create_belongs_to_field.rb
562
- - test/dummy/db/migrate/20150623115554_create_has_many_class_name_field.rb
563
- - test/dummy/db/migrate/20160628173505_add_timestamps.rb
564
- - test/dummy/db/migrate/20150608133044_create_has_one_field.rb
565
- - test/dummy/db/migrate/20150608131610_create_float_field.rb
566
- - test/dummy/db/migrate/20150608131603_create_decimal_field.rb
567
- - test/fixtures/tree.yml
568
- - test/fixtures/has_many_through_field.yml
569
- - test/fixtures/owner.yml
570
- - test/fixtures/has_many_field.yml
571
- - test/fixtures/string_field.yml
572
- - test/fixtures/serialize_field.yml
573
- - test/fixtures/has_one_field.yml
574
- - test/fixtures/reference.yml
575
- - test/fixtures/belongs_to_field.yml
576
- - test/services/forest_liana/value_stat_getter_test.rb
577
- - test/services/forest_liana/resources_getter_test.rb
573
+ - test/test_helper.rb
574
+ - test/forest_liana_test.rb
578
575
  - test/services/forest_liana/has_many_getter_test.rb
579
576
  - test/services/forest_liana/resource_updater_test.rb
580
- - test/services/forest_liana/pie_stat_getter_test.rb
581
577
  - test/services/forest_liana/schema_adapter_test.rb
582
578
  - test/services/forest_liana/scope_validator_test.rb
579
+ - test/services/forest_liana/value_stat_getter_test.rb
580
+ - test/services/forest_liana/pie_stat_getter_test.rb
581
+ - test/fixtures/owner.yml
582
+ - test/fixtures/has_many_through_field.yml
583
+ - test/fixtures/reference.yml
584
+ - test/fixtures/has_many_field.yml
585
+ - test/fixtures/has_one_field.yml
586
+ - test/fixtures/belongs_to_field.yml
587
+ - test/fixtures/string_field.yml
588
+ - test/fixtures/serialize_field.yml
589
+ - test/fixtures/tree.yml
583
590
  - test/routing/route_test.rb
584
- - test/forest_liana_test.rb
585
- - test/test_helper.rb
586
- - spec/dummy/config/application.rb
587
- - spec/dummy/config/database.yml
591
+ - spec/dummy/db/migrate/20190716135241_add_type_to_user.rb
592
+ - spec/dummy/db/migrate/20210326110524_create_references.rb
593
+ - spec/dummy/db/migrate/20190226173051_create_isle.rb
594
+ - spec/dummy/db/migrate/20190226174951_create_tree.rb
595
+ - spec/dummy/db/migrate/20190716130830_add_age_to_tree.rb
596
+ - spec/dummy/db/migrate/20190226172951_create_user.rb
597
+ - spec/dummy/db/migrate/20210326140855_create_locations.rb
598
+ - spec/dummy/db/schema.rb
599
+ - spec/dummy/lib/forest_liana/collections/location.rb
600
+ - spec/dummy/lib/forest_liana/collections/user.rb
601
+ - spec/dummy/Rakefile
602
+ - spec/dummy/app/controllers/application_controller.rb
603
+ - spec/dummy/app/models/island.rb
604
+ - spec/dummy/app/models/reference.rb
605
+ - spec/dummy/app/models/location.rb
606
+ - spec/dummy/app/models/tree.rb
607
+ - spec/dummy/app/models/user.rb
608
+ - spec/dummy/app/assets/stylesheets/application.css
609
+ - spec/dummy/app/assets/javascripts/application.js
610
+ - spec/dummy/app/assets/config/manifest.js
611
+ - spec/dummy/app/config/routes.rb
612
+ - spec/dummy/app/helpers/application_helper.rb
613
+ - spec/dummy/app/views/layouts/application.html.erb
614
+ - spec/dummy/README.rdoc
615
+ - spec/dummy/config.ru
588
616
  - spec/dummy/config/environment.rb
589
617
  - spec/dummy/config/secrets.yml
590
- - spec/dummy/config/environments/development.rb
591
- - spec/dummy/config/environments/test.rb
592
- - spec/dummy/config/environments/production.rb
593
618
  - spec/dummy/config/boot.rb
594
- - spec/dummy/config/initializers/session_store.rb
619
+ - spec/dummy/config/database.yml
620
+ - spec/dummy/config/routes.rb
621
+ - spec/dummy/config/application.rb
622
+ - spec/dummy/config/initializers/filter_parameter_logging.rb
623
+ - spec/dummy/config/initializers/forest_liana.rb
595
624
  - spec/dummy/config/initializers/mime_types.rb
596
- - spec/dummy/config/initializers/cookies_serializer.rb
597
- - spec/dummy/config/initializers/wrap_parameters.rb
625
+ - spec/dummy/config/initializers/session_store.rb
598
626
  - spec/dummy/config/initializers/inflections.rb
599
- - spec/dummy/config/initializers/forest_liana.rb
600
- - spec/dummy/config/initializers/filter_parameter_logging.rb
601
627
  - spec/dummy/config/initializers/assets.rb
628
+ - spec/dummy/config/initializers/wrap_parameters.rb
602
629
  - spec/dummy/config/initializers/backtrace_silencers.rb
603
- - spec/dummy/config/routes.rb
604
- - spec/dummy/app/config/routes.rb
605
- - spec/dummy/app/assets/config/manifest.js
606
- - spec/dummy/app/assets/stylesheets/application.css
607
- - spec/dummy/app/assets/javascripts/application.js
608
- - spec/dummy/app/views/layouts/application.html.erb
609
- - spec/dummy/app/controllers/application_controller.rb
610
- - spec/dummy/app/models/tree.rb
611
- - spec/dummy/app/models/user.rb
612
- - spec/dummy/app/models/island.rb
613
- - spec/dummy/app/helpers/application_helper.rb
614
- - spec/dummy/Rakefile
615
- - spec/dummy/config.ru
616
- - spec/dummy/README.rdoc
617
- - spec/dummy/bin/rails
630
+ - spec/dummy/config/initializers/cookies_serializer.rb
631
+ - spec/dummy/config/environments/test.rb
632
+ - spec/dummy/config/environments/production.rb
633
+ - spec/dummy/config/environments/development.rb
618
634
  - spec/dummy/bin/rake
619
635
  - spec/dummy/bin/bundle
636
+ - spec/dummy/bin/rails
620
637
  - spec/dummy/bin/setup
621
- - spec/dummy/db/schema.rb
622
- - spec/dummy/db/migrate/20190226173051_create_isle.rb
623
- - spec/dummy/db/migrate/20190226174951_create_tree.rb
624
- - spec/dummy/db/migrate/20190226172951_create_user.rb
625
- - spec/dummy/db/migrate/20190716135241_add_type_to_user.rb
626
- - spec/dummy/db/migrate/20190716130830_add_age_to_tree.rb
627
- - spec/requests/resources_spec.rb
628
- - spec/requests/authentications_spec.rb
629
- - spec/requests/actions_controller_spec.rb
630
- - spec/requests/stats_spec.rb
631
- - spec/spec_helper.rb
632
- - spec/services/forest_liana/filters_parser_spec.rb
633
- - spec/services/forest_liana/permissions_checker_live_queries_spec.rb
634
638
  - spec/services/forest_liana/permissions_checker_acl_disabled_spec.rb
639
+ - spec/services/forest_liana/resources_getter_spec.rb
640
+ - spec/services/forest_liana/permissions_formatter_spec.rb
641
+ - spec/services/forest_liana/permissions_checker_live_queries_spec.rb
642
+ - spec/services/forest_liana/permissions_getter_spec.rb
635
643
  - spec/services/forest_liana/schema_adapter_spec.rb
636
- - spec/services/forest_liana/permissions_checker_acl_enabled_spec.rb
637
644
  - spec/services/forest_liana/apimap_sorter_spec.rb
638
- - spec/services/forest_liana/permissions_getter_spec.rb
645
+ - spec/services/forest_liana/permissions_checker_acl_enabled_spec.rb
639
646
  - spec/services/forest_liana/ip_whitelist_checker_spec.rb
640
- - spec/services/forest_liana/permissions_formatter_spec.rb
647
+ - spec/services/forest_liana/filters_parser_spec.rb
641
648
  - spec/rails_helper.rb
642
- - spec/helpers/forest_liana/schema_helper_spec.rb
649
+ - spec/requests/resources_spec.rb
650
+ - spec/requests/authentications_spec.rb
651
+ - spec/requests/actions_controller_spec.rb
652
+ - spec/requests/stats_spec.rb
643
653
  - spec/helpers/forest_liana/is_same_data_structure_helper_spec.rb
654
+ - spec/helpers/forest_liana/schema_helper_spec.rb
644
655
  - spec/helpers/forest_liana/query_helper_spec.rb
656
+ - spec/spec_helper.rb
@@ -1,284 +0,0 @@
1
- module ForestLiana
2
- class ResourcesGetterTest < ActiveSupport::TestCase
3
-
4
- test 'StringField page 1 size 15' do
5
- getter = ResourcesGetter.new(StringField, {
6
- page: { size: 15, number: 1 },
7
- sort: '-id',
8
- timezone: 'America/Nome'
9
- })
10
- getter.perform
11
- records = getter.records
12
- count = getter.count
13
-
14
- assert records.count == 15
15
- assert count = 30
16
- assert records.first.id == 30
17
- assert records.last.id == 16
18
- end
19
-
20
- test 'on a model having a reserved name' do
21
- getter = ResourcesGetter.new(Reference, {
22
- page: { size: 10, number: 1 },
23
- sort: '-id',
24
- timezone: 'America/Nome'
25
- })
26
- getter.perform
27
- records = getter.records
28
- count = getter.count
29
-
30
- assert records.count == 1
31
- assert count = 1
32
- assert records.first.id == 1
33
- end
34
-
35
- test 'StringField page 2 size 10' do
36
- getter = ResourcesGetter.new(StringField, {
37
- page: { size: 10, number: 2 },
38
- sort: '-id',
39
- timezone: 'America/Nome'
40
- })
41
- getter.perform
42
- records = getter.records
43
- count = getter.count
44
-
45
- assert records.count == 10
46
- assert count = 30
47
- assert records.first.id == 20
48
- assert records.last.id == 11
49
- end
50
-
51
- test 'StringField sort by field' do
52
- getter = ResourcesGetter.new(StringField, {
53
- page: { size: 10, number: 1 },
54
- sort: '-field',
55
- timezone: 'America/Nome'
56
- })
57
- getter.perform
58
- records = getter.records
59
- count = getter.count
60
-
61
- assert records.count == 10
62
- assert count = 30
63
- assert records.map(&:field) == ['Test 9', 'Test 8', 'Test 7', 'Test 6',
64
- 'Test 5', 'Test 4', 'Test 30', 'Test 3',
65
- 'Test 29', 'Test 28']
66
- end
67
-
68
- test 'Sort by a belongs_to association' do
69
- getter = ResourcesGetter.new(BelongsToField, {
70
- page: { size: 10, number: 1 },
71
- sort: 'has_one_field.id',
72
- timezone: 'America/Nome'
73
- })
74
- getter.perform
75
- records = getter.records
76
- count = getter.count
77
-
78
- assert records.count == 10
79
- assert count = 30
80
- assert records.first.has_one_field_id == 1
81
- assert records.last.has_one_field_id == 10
82
- end
83
-
84
- test 'Sort by a has_one association' do
85
- getter = ResourcesGetter.new(HasOneField, {
86
- page: { size: 10, number: 1 },
87
- sort: '-belongs_to_field.id',
88
- timezone: 'America/Nome'
89
- })
90
- getter.perform
91
- records = getter.records
92
- count = getter.count
93
-
94
- assert records.count == 10
95
- assert count = 30
96
- assert records.first.belongs_to_field.id == 30
97
- assert records.last.belongs_to_field.id == 21
98
- end
99
-
100
- test 'Filter on ambiguous field' do
101
- getter = ResourcesGetter.new(Tree, {
102
- fields: { 'Tree' => 'id' },
103
- page: { size: 10, number: 1 },
104
- filters: {
105
- aggregator: 'and',
106
- conditions: [{
107
- field: 'created_at',
108
- operator: 'after',
109
- value: "#{Time.now.year - 5}-06-18 08:00:00",
110
- }, {
111
- field: 'owner:name',
112
- operator: 'equal',
113
- value: 'Arnaud Besnier'
114
- }]
115
- }.to_json,
116
- timezone: 'America/Nome'
117
- })
118
- getter.perform
119
- records = getter.records
120
- count = getter.count
121
-
122
- assert records.count == 1
123
- assert count = 1
124
- assert records.first.id == 4
125
- assert records.first.name == 'Oak'
126
- assert records.first.owner.name == 'Arnaud Besnier'
127
- end
128
-
129
- test 'Filter before x hours' do
130
- getter = ResourcesGetter.new(Tree, {
131
- fields: { 'Tree' => 'id' },
132
- page: { size: 10, number: 1 },
133
- filters: {
134
- field: 'created_at',
135
- operator: 'before_x_hours_ago',
136
- value: 3
137
- }.to_json,
138
- timezone: 'America/Nome'
139
- })
140
- getter.perform
141
- records = getter.records
142
- count = getter.count
143
-
144
- assert records.count == 5
145
- assert count = 5
146
- assert records.first.id == 4
147
- assert records.first.name == 'Oak'
148
- assert records.first.owner.name == 'Arnaud Besnier'
149
- end
150
-
151
- test 'Filter after x hours' do
152
- getter = ResourcesGetter.new(Tree, {
153
- fields: { 'Tree' => 'id' },
154
- page: { size: 10, number: 1 },
155
- filters: {
156
- field: 'created_at',
157
- operator: 'after_x_hours_ago',
158
- value: 3
159
- }.to_json,
160
- timezone: 'America/Nome'
161
- })
162
- getter.perform
163
- records = getter.records
164
- count = getter.count
165
-
166
- assert records.count == 3
167
- assert count = 3
168
- end
169
-
170
- test 'Sort on an ambiguous field name with a filter' do
171
- getter = ResourcesGetter.new(Tree, {
172
- fields: { 'Tree' => 'id' },
173
- page: { size: 10, number: 1 },
174
- sort: '-name',
175
- filters: {
176
- field: 'owner:name',
177
- operator: 'equal',
178
- value: 'Arnaud Besnier'
179
- }.to_json,
180
- timezone: 'America/Nome'
181
- })
182
- getter.perform
183
- records = getter.records
184
- count = getter.count
185
-
186
- assert records.count == 3
187
- assert count = 3
188
- assert records.first.name == 'Oak'
189
- assert records.last.name == 'Mapple'
190
- end
191
-
192
- test 'Filter on an updated_at field of the main collection' do
193
- getter = ResourcesGetter.new(Owner, {
194
- page: { size: 10, number: 1 },
195
- filters: {
196
- field: 'updated_at',
197
- operator: 'previous_year'
198
- }.to_json,
199
- timezone: 'America/Nome'
200
- })
201
- getter.perform
202
- records = getter.records
203
- count = getter.count
204
-
205
- assert records.count == 1
206
- assert count = 1
207
- assert records.first.id == 3
208
- end
209
-
210
- test 'Filter on an updated_at field of an associated collection' do
211
- getter = ResourcesGetter.new(Tree, {
212
- fields: { 'Tree' => 'id' },
213
- page: { size: 10, number: 1 },
214
- filters: {
215
- field: 'owner:updated_at',
216
- operator: 'previous_year'
217
- }.to_json,
218
- timezone: 'America/Nome'
219
- })
220
- getter.perform
221
- records = getter.records
222
- count = getter.count
223
-
224
- assert records.count == 2
225
- assert count = 2
226
- assert records.first.id == 6
227
- end
228
-
229
- test 'Filter equal on an updated_at field of an associated collection' do
230
- getter = ResourcesGetter.new(Tree, {
231
- fields: { 'Tree' => 'id' },
232
- page: { size: 10, number: 1 },
233
- filters: {
234
- field: 'owner:updated_at',
235
- operator: 'equal',
236
- value: 'Sat Jul 02 2016 11:52:00 GMT-0400 (EDT)',
237
- }.to_json,
238
- timezone: 'America/Nome'
239
- })
240
- getter.perform
241
- records = getter.records
242
- count = getter.count
243
-
244
- assert records.count == 0
245
- assert count = 0
246
- end
247
-
248
- test 'Filter on a field of an associated collection that does not exist' do
249
- exception = assert_raises(ForestLiana::Errors::HTTP422Error) {
250
- ForestLiana::ResourcesGetter.new(Tree, {
251
- fields: { 'Tree' => 'id'},
252
- searchExtended: '0',
253
- timezone: 'Europe/Paris',
254
- filters: {
255
- field: 'leaf:id',
256
- operator: 'equal',
257
- value: 1
258
- }.to_json,
259
- collection: 'Tree'
260
- })
261
- }
262
- assert_equal("Association 'leaf' not found", exception.message)
263
- end
264
-
265
- test 'Filter on a field that does not exists' do
266
- exception = assert_raises(ForestLiana::Errors::HTTP422Error) {
267
- ForestLiana::ResourcesGetter.new(Tree, {
268
- fields: { 'Tree' => 'id'},
269
- searchExtended: '0',
270
- timezone: 'Europe/Paris',
271
- filters: {
272
- field: 'content',
273
- operator: 'contains',
274
- value: 'c'
275
- }.to_json,
276
- collection: 'Article'
277
- })
278
- }
279
-
280
- assert_equal("Field 'content' not found", exception.message)
281
- end
282
-
283
- end
284
- end