forest_liana 6.1.1 → 6.3.0

Sign up to get free protection for your applications and to get access to all the features.
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