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 +4 -4
- data/app/helpers/forest_liana/schema_helper.rb +6 -0
- data/app/models/forest_liana/model/action.rb +1 -0
- data/app/services/forest_liana/apimap_sorter.rb +1 -0
- data/app/services/forest_liana/filters_parser.rb +43 -17
- data/config/initializers/errors.rb +6 -0
- data/lib/forest_liana/schema_file_updater.rb +1 -0
- data/lib/forest_liana/version.rb +1 -1
- data/spec/dummy/app/models/island.rb +1 -0
- data/spec/dummy/app/models/location.rb +3 -0
- data/spec/dummy/app/models/reference.rb +2 -0
- data/spec/dummy/db/migrate/20210326110524_create_references.rb +8 -0
- data/spec/dummy/db/migrate/20210326140855_create_locations.rb +10 -0
- data/spec/dummy/db/schema.rb +14 -1
- data/spec/dummy/lib/forest_liana/collections/location.rb +10 -0
- data/spec/dummy/lib/forest_liana/collections/user.rb +15 -0
- data/spec/requests/actions_controller_spec.rb +1 -0
- data/spec/services/forest_liana/resources_getter_spec.rb +359 -0
- data/spec/services/forest_liana/schema_adapter_spec.rb +1 -1
- metadata +133 -121
- data/test/services/forest_liana/resources_getter_test.rb +0 -284
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9db3ae9b9a24a9f298e24a2b6562e8df12b0123cbbe45f453fab19d8da7a8f10
|
4
|
+
data.tar.gz: 4e245a23470730308895296e37e765a711186381820f2bf619e5091966cba6fc
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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,30 +47,56 @@ module ForestLiana
|
|
47
47
|
end
|
48
48
|
|
49
49
|
def parse_condition(condition)
|
50
|
-
|
50
|
+
where = parse_condition_without_smart_field(condition)
|
51
51
|
|
52
|
-
|
53
|
-
value = condition['value']
|
54
|
-
field = condition['field']
|
52
|
+
field_name = condition['field']
|
55
53
|
|
56
|
-
if
|
57
|
-
|
58
|
-
|
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
|
-
|
62
|
-
|
63
|
-
|
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
|
-
|
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(
|
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
|
-
|
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')
|
data/lib/forest_liana/version.rb
CHANGED
data/spec/dummy/db/schema.rb
CHANGED
@@ -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:
|
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,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
|
@@ -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
|
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.
|
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-
|
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/
|
495
|
-
- test/dummy/
|
496
|
-
- test/dummy/
|
497
|
-
- test/dummy/
|
498
|
-
- test/dummy/
|
499
|
-
- test/dummy/
|
500
|
-
- test/dummy/
|
501
|
-
- test/dummy/
|
502
|
-
- test/dummy/
|
503
|
-
- test/dummy/
|
504
|
-
- test/dummy/
|
505
|
-
- test/dummy/
|
506
|
-
- test/dummy/
|
507
|
-
- test/dummy/
|
508
|
-
- test/dummy/
|
509
|
-
- test/dummy/
|
510
|
-
- test/dummy/
|
511
|
-
- test/dummy/
|
512
|
-
- test/dummy/
|
513
|
-
- test/dummy/
|
514
|
-
- test/dummy/
|
515
|
-
- test/dummy/
|
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/
|
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/
|
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/
|
537
|
-
- test/dummy/config.ru
|
548
|
+
- test/dummy/app/views/layouts/application.html.erb
|
538
549
|
- test/dummy/README.rdoc
|
539
|
-
- test/dummy/
|
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/
|
544
|
-
- test/
|
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
|
-
-
|
585
|
-
-
|
586
|
-
- spec/dummy/
|
587
|
-
- spec/dummy/
|
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/
|
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/
|
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/
|
604
|
-
- spec/dummy/
|
605
|
-
- spec/dummy/
|
606
|
-
- spec/dummy/
|
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/
|
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/
|
647
|
+
- spec/services/forest_liana/filters_parser_spec.rb
|
641
648
|
- spec/rails_helper.rb
|
642
|
-
- spec/
|
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
|