forest_liana 8.0.17 → 8.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/app/deserializers/forest_liana/resource_deserializer.rb +6 -1
- data/app/helpers/forest_liana/query_helper.rb +22 -5
- data/app/serializers/forest_liana/serializer_factory.rb +17 -1
- data/app/services/forest_liana/apimap_sorter.rb +1 -0
- data/app/services/forest_liana/base_getter.rb +13 -6
- data/app/services/forest_liana/belongs_to_updater.rb +10 -1
- data/app/services/forest_liana/has_many_getter.rb +14 -8
- data/app/services/forest_liana/schema_adapter.rb +37 -1
- data/app/services/forest_liana/schema_utils.rb +26 -3
- data/lib/forest_liana/bootstrapper.rb +6 -1
- data/lib/forest_liana/schema_file_updater.rb +1 -0
- data/lib/forest_liana/version.rb +1 -1
- data/lib/tasks/send_apimap.rake +1 -1
- data/spec/dummy/app/models/address.rb +5 -0
- data/spec/dummy/app/models/user.rb +1 -0
- data/spec/dummy/db/migrate/20231117084236_create_addresses.rb +12 -0
- data/spec/dummy/db/schema.rb +12 -1
- data/spec/helpers/forest_liana/query_helper_spec.rb +25 -1
- data/spec/lib/forest_liana/bootstrapper_spec.rb +1 -0
- data/spec/lib/forest_liana/schema_file_updater_spec.rb +35 -0
- data/spec/requests/resources_spec.rb +84 -0
- data/spec/services/forest_liana/schema_adapter_spec.rb +58 -0
- data/spec/spec_helper.rb +2 -0
- metadata +6 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e051d1446dd0f16749a9d078bb0caee6ff1b93c37557b5fdc0571fca710137f8
|
4
|
+
data.tar.gz: 90db1924c8d20ef02b3525eb84bba26ed03025fe042b4c6405d83ebaf3ac2e23
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 87d40012a5f767ebc6faf75c5cb9826d50afc536837daad7f578f85ecf8b6e4c82f20d2c4eb246a4a3197e7e8d0ef6ad294362dccd5100b1194ce3897fda8044
|
7
|
+
data.tar.gz: 3d24e8527ae65ec0945ebd309a4958257ee4b12792d78f41e72427baea073333f4630756dc48254fef347ad467976a5bddeddf85d823432c94f34a4f8e465eb5
|
@@ -63,7 +63,12 @@ module ForestLiana
|
|
63
63
|
# ActionController::Parameters do not inherit from Hash anymore
|
64
64
|
# since Rails 5.
|
65
65
|
if (data.is_a?(Hash) || data.is_a?(ActionController::Parameters)) && data[:id]
|
66
|
-
|
66
|
+
if (SchemaUtils.polymorphic?(association))
|
67
|
+
@attributes[association.foreign_key] = data[:id]
|
68
|
+
@attributes[association.foreign_type] = data[:type]
|
69
|
+
else
|
70
|
+
@attributes[name] = association.klass.find(data[:id])
|
71
|
+
end
|
67
72
|
elsif data.blank?
|
68
73
|
@attributes[name] = nil
|
69
74
|
end
|
@@ -1,8 +1,16 @@
|
|
1
1
|
module ForestLiana
|
2
2
|
module QueryHelper
|
3
3
|
def self.get_one_associations(resource)
|
4
|
-
SchemaUtils.one_associations(resource)
|
5
|
-
.select
|
4
|
+
associations = SchemaUtils.one_associations(resource)
|
5
|
+
.select do |association|
|
6
|
+
if SchemaUtils.polymorphic?(association)
|
7
|
+
SchemaUtils.polymorphic_models(association).all? { |model| SchemaUtils.model_included?(model) }
|
8
|
+
else
|
9
|
+
SchemaUtils.model_included?(association.klass)
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
associations
|
6
14
|
end
|
7
15
|
|
8
16
|
def self.get_one_association_names_symbol(resource)
|
@@ -18,10 +26,19 @@ module ForestLiana
|
|
18
26
|
associations_has_one = self.get_one_associations(resource)
|
19
27
|
|
20
28
|
associations_has_one.each do |association|
|
21
|
-
if
|
22
|
-
|
29
|
+
if SchemaUtils.polymorphic?(association)
|
30
|
+
SchemaUtils.polymorphic_models(association).each do |model|
|
31
|
+
if tables_associated_to_relations_name[model.table_name].nil?
|
32
|
+
tables_associated_to_relations_name[model.table_name] = []
|
33
|
+
end
|
34
|
+
tables_associated_to_relations_name[model.table_name] << association.name
|
35
|
+
end
|
36
|
+
else
|
37
|
+
if tables_associated_to_relations_name[association.try(:table_name)].nil?
|
38
|
+
tables_associated_to_relations_name[association.table_name] = []
|
39
|
+
end
|
40
|
+
tables_associated_to_relations_name[association.table_name] << association.name
|
23
41
|
end
|
24
|
-
tables_associated_to_relations_name[association.table_name] << association.name
|
25
42
|
end
|
26
43
|
|
27
44
|
tables_associated_to_relations_name
|
@@ -265,7 +265,19 @@ module ForestLiana
|
|
265
265
|
|
266
266
|
SchemaUtils.associations(active_record_class).each do |a|
|
267
267
|
begin
|
268
|
-
if SchemaUtils.
|
268
|
+
if SchemaUtils.polymorphic?(a)
|
269
|
+
serializer.send(serializer_association(a), a.name) {
|
270
|
+
if [:has_one, :belongs_to].include?(a.macro)
|
271
|
+
begin
|
272
|
+
object.send(a.name)
|
273
|
+
rescue ActiveRecord::RecordNotFound
|
274
|
+
nil
|
275
|
+
end
|
276
|
+
else
|
277
|
+
[]
|
278
|
+
end
|
279
|
+
}
|
280
|
+
elsif SchemaUtils.model_included?(a.klass)
|
269
281
|
serializer.send(serializer_association(a), a.name) {
|
270
282
|
if [:has_one, :belongs_to].include?(a.macro)
|
271
283
|
begin
|
@@ -369,6 +381,7 @@ module ForestLiana
|
|
369
381
|
|
370
382
|
def attributes(active_record_class)
|
371
383
|
return [] if @is_smart_collection
|
384
|
+
|
372
385
|
active_record_class.column_names.select do |column_name|
|
373
386
|
!association?(active_record_class, column_name)
|
374
387
|
end
|
@@ -410,6 +423,9 @@ module ForestLiana
|
|
410
423
|
def foreign_keys(active_record_class)
|
411
424
|
begin
|
412
425
|
SchemaUtils.belongs_to_associations(active_record_class).map(&:foreign_key)
|
426
|
+
SchemaUtils.belongs_to_associations(active_record_class)
|
427
|
+
.select { |association| !SchemaUtils.polymorphic?(association) }
|
428
|
+
.map(&:foreign_key)
|
413
429
|
rescue => err
|
414
430
|
# Association foreign_key triggers an error. Put the stacktrace and
|
415
431
|
# returns no foreign keys.
|
@@ -33,16 +33,23 @@ module ForestLiana
|
|
33
33
|
def optimize_record_loading(resource, records)
|
34
34
|
instance_dependent_associations = instance_dependent_associations(resource)
|
35
35
|
|
36
|
+
polymorphic = []
|
36
37
|
preload_loads = @includes.select do |name|
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
38
|
+
association = resource.reflect_on_association(name)
|
39
|
+
if SchemaUtils.polymorphic?(association)
|
40
|
+
polymorphic << association.name
|
41
|
+
false
|
42
|
+
else
|
43
|
+
targetModelConnection = association.klass.connection
|
44
|
+
targetModelDatabase = targetModelConnection.current_database if targetModelConnection.respond_to? :current_database
|
45
|
+
resourceConnection = resource.connection
|
46
|
+
resourceDatabase = resourceConnection.current_database if resourceConnection.respond_to? :current_database
|
41
47
|
|
42
|
-
|
48
|
+
targetModelDatabase != resourceDatabase
|
49
|
+
end
|
43
50
|
end + instance_dependent_associations
|
44
51
|
|
45
|
-
result = records.eager_load(@includes - preload_loads)
|
52
|
+
result = records.eager_load(@includes - preload_loads - polymorphic)
|
46
53
|
|
47
54
|
# Rails 7 can mix `eager_load` and `preload` in the same scope
|
48
55
|
# Rails 6 cannot mix `eager_load` and `preload` in the same scope
|
@@ -13,7 +13,16 @@ module ForestLiana
|
|
13
13
|
def perform
|
14
14
|
begin
|
15
15
|
@record = @resource.find(@params[:id])
|
16
|
-
|
16
|
+
if (SchemaUtils.polymorphic?(@association))
|
17
|
+
if @data.nil?
|
18
|
+
new_value = nil
|
19
|
+
else
|
20
|
+
association_klass = SchemaUtils.polymorphic_models(@association).select { |a| a.name.downcase == @data[:type] }.first
|
21
|
+
new_value = association_klass.find(@data[:id]) if @data && @data[:id]
|
22
|
+
end
|
23
|
+
else
|
24
|
+
new_value = @association.klass.find(@data[:id]) if @data && @data[:id]
|
25
|
+
end
|
17
26
|
@record.send("#{@association.name}=", new_value)
|
18
27
|
|
19
28
|
@record.save
|
@@ -40,17 +40,23 @@ module ForestLiana
|
|
40
40
|
@includes = @association.klass
|
41
41
|
.reflect_on_all_associations
|
42
42
|
.select do |association|
|
43
|
-
inclusion = !association.options[:polymorphic] &&
|
44
|
-
SchemaUtils.model_included?(association.klass) &&
|
45
|
-
[:belongs_to, :has_and_belongs_to_many].include?(association.macro)
|
46
43
|
|
47
|
-
if
|
48
|
-
inclusion
|
44
|
+
if SchemaUtils.polymorphic?(association)
|
45
|
+
inclusion = SchemaUtils.polymorphic_models(association)
|
46
|
+
.all? { |model| SchemaUtils.model_included?(model) } &&
|
47
|
+
[:belongs_to, :has_and_belongs_to_many].include?(association.macro)
|
49
48
|
else
|
50
|
-
inclusion
|
49
|
+
inclusion = SchemaUtils.model_included?(association.klass) &&
|
50
|
+
[:belongs_to, :has_and_belongs_to_many].include?(association.macro)
|
51
51
|
end
|
52
|
-
|
53
|
-
|
52
|
+
|
53
|
+
if @field_names_requested
|
54
|
+
inclusion && @field_names_requested.include?(association.name)
|
55
|
+
else
|
56
|
+
inclusion
|
57
|
+
end
|
58
|
+
end
|
59
|
+
.map { |association| association.name }
|
54
60
|
end
|
55
61
|
|
56
62
|
def field_names_requested
|
@@ -241,8 +241,33 @@ module ForestLiana
|
|
241
241
|
def add_associations
|
242
242
|
SchemaUtils.associations(@model).each do |association|
|
243
243
|
begin
|
244
|
+
if SchemaUtils.polymorphic?(association) &&
|
245
|
+
(ENV['ENABLE_SUPPORT_POLYMORPHISM'].present? && ENV['ENABLE_SUPPORT_POLYMORPHISM'].downcase == 'true')
|
246
|
+
|
247
|
+
collection.fields << {
|
248
|
+
field: association.name.to_s,
|
249
|
+
type: get_type_for_association(association),
|
250
|
+
relationship: get_relationship_type(association),
|
251
|
+
reference: "#{association.name.to_s}.id",
|
252
|
+
inverse_of: @model.name.demodulize.underscore,
|
253
|
+
is_filterable: false,
|
254
|
+
is_sortable: true,
|
255
|
+
is_read_only: false,
|
256
|
+
is_required: false,
|
257
|
+
is_virtual: false,
|
258
|
+
default_value: nil,
|
259
|
+
integration: nil,
|
260
|
+
relationships: nil,
|
261
|
+
widget: nil,
|
262
|
+
validations: [],
|
263
|
+
polymorphic_referenced_models: get_polymorphic_types(association)
|
264
|
+
}
|
265
|
+
|
266
|
+
collection.fields = collection.fields.reject do |field|
|
267
|
+
field[:field] == association.foreign_key || field[:field] == association.foreign_type
|
268
|
+
end
|
244
269
|
# NOTICE: Delete the association if the targeted model is excluded.
|
245
|
-
|
270
|
+
elsif !SchemaUtils.model_included?(association.klass)
|
246
271
|
field = collection.fields.find do |x|
|
247
272
|
x[:field] == association.foreign_key
|
248
273
|
end
|
@@ -275,6 +300,17 @@ module ForestLiana
|
|
275
300
|
automatic_inverse_of(association)
|
276
301
|
end
|
277
302
|
|
303
|
+
def get_polymorphic_types(relation)
|
304
|
+
types = []
|
305
|
+
ForestLiana.models.each do |model|
|
306
|
+
unless model.reflect_on_all_associations.select { |association| association.options[:as] == relation.name.to_sym }.empty?
|
307
|
+
types << model.name
|
308
|
+
end
|
309
|
+
end
|
310
|
+
|
311
|
+
types
|
312
|
+
end
|
313
|
+
|
278
314
|
def automatic_inverse_of(association)
|
279
315
|
name = association.active_record.name.demodulize.underscore
|
280
316
|
|
@@ -4,7 +4,12 @@ module ForestLiana
|
|
4
4
|
def self.associations(active_record_class)
|
5
5
|
active_record_class.reflect_on_all_associations.select do |association|
|
6
6
|
begin
|
7
|
-
|
7
|
+
if (ENV['ENABLE_SUPPORT_POLYMORPHISM'].present? && ENV['ENABLE_SUPPORT_POLYMORPHISM'].downcase == 'true')
|
8
|
+
polymorphic?(association) ? true : !is_active_type?(association.klass)
|
9
|
+
else
|
10
|
+
!polymorphic?(association) && !is_active_type?(association.klass)
|
11
|
+
end
|
12
|
+
|
8
13
|
rescue
|
9
14
|
FOREST_LOGGER.warn "Unknown association #{association.name} on class #{active_record_class.name}"
|
10
15
|
false
|
@@ -53,12 +58,30 @@ module ForestLiana
|
|
53
58
|
ActiveRecord::Base.connection.tables
|
54
59
|
end
|
55
60
|
|
56
|
-
private
|
57
|
-
|
58
61
|
def self.polymorphic?(association)
|
59
62
|
association.options[:polymorphic]
|
60
63
|
end
|
61
64
|
|
65
|
+
def self.klass(association)
|
66
|
+
return association.klass unless polymorphic?(association)
|
67
|
+
|
68
|
+
|
69
|
+
end
|
70
|
+
|
71
|
+
def self.polymorphic_models(relation)
|
72
|
+
models = []
|
73
|
+
ForestLiana.models.each do |model|
|
74
|
+
unless model.reflect_on_all_associations.select { |association| association.options[:as] == relation.name.to_sym }.empty?
|
75
|
+
models << model
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
models
|
80
|
+
end
|
81
|
+
|
82
|
+
|
83
|
+
private
|
84
|
+
|
62
85
|
def self.find_model_from_abstract_class(abstract_class, collection_name)
|
63
86
|
abstract_class.subclasses.find do |subclass|
|
64
87
|
if subclass.abstract_class?
|
@@ -5,7 +5,12 @@ module ForestLiana
|
|
5
5
|
class Bootstrapper
|
6
6
|
SCHEMA_FILENAME = File.join(Dir.pwd, '.forestadmin-schema.json')
|
7
7
|
|
8
|
-
def initialize
|
8
|
+
def initialize(reset_api_map = false)
|
9
|
+
if reset_api_map
|
10
|
+
ForestLiana.apimap = []
|
11
|
+
ForestLiana.models = []
|
12
|
+
end
|
13
|
+
|
9
14
|
@integration_stripe_valid = false
|
10
15
|
@integration_intercom_valid = false
|
11
16
|
|
data/lib/forest_liana/version.rb
CHANGED
data/lib/tasks/send_apimap.rake
CHANGED
@@ -3,7 +3,7 @@ namespace :forest do
|
|
3
3
|
task(:send_apimap).clear
|
4
4
|
task send_apimap: :environment do
|
5
5
|
if ForestLiana.env_secret
|
6
|
-
bootstrapper = ForestLiana::Bootstrapper.new
|
6
|
+
bootstrapper = ForestLiana::Bootstrapper.new(true)
|
7
7
|
bootstrapper.synchronize(true)
|
8
8
|
else
|
9
9
|
puts 'Cannot send the Apimap, Forest cannot find your env_secret'
|
data/spec/dummy/db/schema.rb
CHANGED
@@ -10,7 +10,18 @@
|
|
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: 2023_11_17_084236) do
|
14
|
+
|
15
|
+
create_table "addresses", force: :cascade do |t|
|
16
|
+
t.string "line1"
|
17
|
+
t.string "city"
|
18
|
+
t.string "zipcode"
|
19
|
+
t.string "addressable_type", null: false
|
20
|
+
t.integer "addressable_id", null: false
|
21
|
+
t.datetime "created_at", precision: 6, null: false
|
22
|
+
t.datetime "updated_at", precision: 6, null: false
|
23
|
+
t.index ["addressable_type", "addressable_id"], name: "index_addresses_on_addressable_type_and_addressable_id"
|
24
|
+
end
|
14
25
|
|
15
26
|
create_table "isle", force: :cascade do |t|
|
16
27
|
t.string "name"
|
@@ -3,6 +3,7 @@ module ForestLiana
|
|
3
3
|
before(:all) do
|
4
4
|
Tree.connection
|
5
5
|
User.connection
|
6
|
+
Address.connection
|
6
7
|
Island.connection
|
7
8
|
end
|
8
9
|
|
@@ -14,6 +15,21 @@ module ForestLiana
|
|
14
15
|
end
|
15
16
|
end
|
16
17
|
|
18
|
+
context 'on a model having 1 polymorphic association' do
|
19
|
+
it 'should return the association' do
|
20
|
+
associations = QueryHelper.get_one_associations(Address)
|
21
|
+
expect(associations).to eq(Address.reflect_on_all_associations(:belongs_to))
|
22
|
+
end
|
23
|
+
|
24
|
+
it 'should return 0 association when one of referenced model was excluded' do
|
25
|
+
allow(ForestLiana).to receive(:excluded_models).and_return(['User'])
|
26
|
+
associations = QueryHelper.get_one_associations(Address)
|
27
|
+
|
28
|
+
expect(associations.length).to eq(0)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
|
17
33
|
context 'on a model having some belongsTo associations' do
|
18
34
|
let(:expected_association_attributes) do
|
19
35
|
[
|
@@ -75,7 +91,15 @@ module ForestLiana
|
|
75
91
|
expect(tables_associated_to_relations_name['isle'].second).to eq(:eponymous_island)
|
76
92
|
end
|
77
93
|
end
|
78
|
-
end
|
79
94
|
|
95
|
+
context 'on a model having polymorphic association' do
|
96
|
+
tables_associated_to_relations_name =
|
97
|
+
QueryHelper.get_tables_associated_to_relations_name(Address)
|
98
|
+
|
99
|
+
it 'should return the one-one associations' do
|
100
|
+
expect(tables_associated_to_relations_name.keys.length).to eq(1)
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
80
104
|
end
|
81
105
|
end
|
@@ -10,6 +10,41 @@ module ForestLiana
|
|
10
10
|
end
|
11
11
|
|
12
12
|
describe "with a given collection" do
|
13
|
+
describe "when the collection has a polymorphic relation" do
|
14
|
+
it "should save the relation" do
|
15
|
+
collections = [
|
16
|
+
{
|
17
|
+
"name" => "Address",
|
18
|
+
"fields" => [
|
19
|
+
{
|
20
|
+
"field" => "addressable",
|
21
|
+
"type" => "Number",
|
22
|
+
"relationship" => "BelongsTo",
|
23
|
+
"reference" => "addressable.id",
|
24
|
+
"inverse_of" => "address",
|
25
|
+
"is_filterable" => false,
|
26
|
+
"is_sortable" => true,
|
27
|
+
"is_read_only" => false,
|
28
|
+
"is_required" => false,
|
29
|
+
"is_virtual" => false,
|
30
|
+
"default_value" => nil,
|
31
|
+
"integration" => nil,
|
32
|
+
"relationships" => nil,
|
33
|
+
"widget" => nil,
|
34
|
+
"validations" => [],
|
35
|
+
"polymorphic_referenced_models" => ["User"]
|
36
|
+
},
|
37
|
+
],
|
38
|
+
"actions" => [],
|
39
|
+
"segments" => []
|
40
|
+
}
|
41
|
+
]
|
42
|
+
schema_file_updater = ForestLiana::SchemaFileUpdater.new("test.txt", collections, {})
|
43
|
+
expect(schema_file_updater.instance_variable_get(:@collections))
|
44
|
+
.to eq(collections)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
13
48
|
describe "when the collection has a smart action action" do
|
14
49
|
it "should save the smart action" do
|
15
50
|
collections = [{
|
@@ -154,3 +154,87 @@ describe 'Requesting Tree resources', :type => :request do
|
|
154
154
|
end
|
155
155
|
end
|
156
156
|
end
|
157
|
+
|
158
|
+
describe 'Requesting Address resources', :type => :request do
|
159
|
+
|
160
|
+
before do
|
161
|
+
user = User.create(name: 'Michel')
|
162
|
+
address = Address.create(line1: '10 Downing Street', city: 'London', zipcode: '2AB', addressable: user)
|
163
|
+
|
164
|
+
Rails.cache.write('forest.users', {'1' => { 'id' => 1, 'roleId' => 1, 'rendering_id' => '1' }})
|
165
|
+
Rails.cache.write('forest.has_permission', true)
|
166
|
+
Rails.cache.write(
|
167
|
+
'forest.collections',
|
168
|
+
{
|
169
|
+
'Address' => {
|
170
|
+
'browse' => [1],
|
171
|
+
'read' => [1],
|
172
|
+
'edit' => [1],
|
173
|
+
'add' => [1],
|
174
|
+
'delete' => [1],
|
175
|
+
'export' => [1],
|
176
|
+
'actions' => {}
|
177
|
+
}
|
178
|
+
}
|
179
|
+
)
|
180
|
+
|
181
|
+
allow(ForestLiana::IpWhitelist).to receive(:retrieve) { true }
|
182
|
+
allow(ForestLiana::IpWhitelist).to receive(:is_ip_whitelist_retrieved) { true }
|
183
|
+
allow(ForestLiana::IpWhitelist).to receive(:is_ip_valid) { true }
|
184
|
+
allow(ForestLiana::ScopeManager).to receive(:fetch_scopes).and_return({})
|
185
|
+
end
|
186
|
+
|
187
|
+
after do
|
188
|
+
User.destroy_all
|
189
|
+
Address.destroy_all
|
190
|
+
end
|
191
|
+
|
192
|
+
token = JWT.encode({
|
193
|
+
id: 1,
|
194
|
+
email: 'michael.kelso@that70.show',
|
195
|
+
first_name: 'Michael',
|
196
|
+
last_name: 'Kelso',
|
197
|
+
team: 'Operations',
|
198
|
+
rendering_id: 16,
|
199
|
+
exp: Time.now.to_i + 2.weeks.to_i,
|
200
|
+
permission_level: 'admin'
|
201
|
+
}, ForestLiana.auth_secret, 'HS256')
|
202
|
+
|
203
|
+
headers = {
|
204
|
+
'Accept' => 'application/json',
|
205
|
+
'Content-Type' => 'application/json',
|
206
|
+
'Authorization' => "Bearer #{token}"
|
207
|
+
}
|
208
|
+
|
209
|
+
describe 'index' do
|
210
|
+
params = {
|
211
|
+
fields: { 'Address' => 'id,line1,city,zip_code,addressable' },
|
212
|
+
page: { 'number' => '1', 'size' => '10' },
|
213
|
+
searchExtended: '0',
|
214
|
+
sort: '-id',
|
215
|
+
timezone: 'Europe/Paris'
|
216
|
+
}
|
217
|
+
|
218
|
+
it 'should respond the address data' do
|
219
|
+
get '/forest/Address', params: params, headers: headers
|
220
|
+
|
221
|
+
expect(JSON.parse(response.body)).to include(
|
222
|
+
"data" => [
|
223
|
+
{
|
224
|
+
"type" => "Address",
|
225
|
+
"id" => "1",
|
226
|
+
"attributes" => {
|
227
|
+
"id" => 1,
|
228
|
+
"line1" => "10 Downing Street",
|
229
|
+
"city" => "London"
|
230
|
+
},
|
231
|
+
"links" => { "self" => "/forest/address/1" },
|
232
|
+
"relationships" => {
|
233
|
+
"addressable" => { "links" => { "related" => {} }, "data" => { "type" => "User", "id" => "1" } }
|
234
|
+
}
|
235
|
+
}
|
236
|
+
]
|
237
|
+
)
|
238
|
+
end
|
239
|
+
end
|
240
|
+
end
|
@@ -1,6 +1,64 @@
|
|
1
1
|
module ForestLiana
|
2
2
|
describe SchemaAdapter do
|
3
3
|
describe 'perform' do
|
4
|
+
context 'with polymorphic association' do
|
5
|
+
it 'should define the association with the referenced models' do
|
6
|
+
collection = ForestLiana.apimap.find do |object|
|
7
|
+
object.name.to_s == ForestLiana.name_for(Address)
|
8
|
+
end
|
9
|
+
field = collection.fields.find { |field| field[:field] == 'addressable' }
|
10
|
+
|
11
|
+
expect(field).to eq(
|
12
|
+
{
|
13
|
+
field: "addressable",
|
14
|
+
type: "Number",
|
15
|
+
relationship: "BelongsTo",
|
16
|
+
reference: "addressable.id",
|
17
|
+
inverse_of: "address",
|
18
|
+
is_filterable: false,
|
19
|
+
is_sortable: true,
|
20
|
+
is_read_only: false,
|
21
|
+
is_required: false,
|
22
|
+
is_virtual: false,
|
23
|
+
default_value: nil,
|
24
|
+
integration: nil,
|
25
|
+
relationships: nil,
|
26
|
+
widget: nil,
|
27
|
+
validations: [],
|
28
|
+
polymorphic_referenced_models: ['User']
|
29
|
+
}
|
30
|
+
)
|
31
|
+
end
|
32
|
+
|
33
|
+
it 'should remove the polymorphic attributes(_id and _type)' do
|
34
|
+
collection = ForestLiana.apimap.find do |object|
|
35
|
+
object.name.to_s == ForestLiana.name_for(Address)
|
36
|
+
end
|
37
|
+
removed_fields = collection.fields.select do
|
38
|
+
|field| field[:field] == 'addressable_id' || field[:field] == 'addressable_type'
|
39
|
+
end
|
40
|
+
|
41
|
+
expect(removed_fields).to be_empty
|
42
|
+
end
|
43
|
+
|
44
|
+
context 'when the polymorphic support was disabled' do
|
45
|
+
it 'should not define the association' do
|
46
|
+
ENV['ENABLE_SUPPORT_POLYMORPHISM'] = 'false'
|
47
|
+
Bootstrapper.new(true)
|
48
|
+
collection = ForestLiana.apimap.find do |object|
|
49
|
+
object.name.to_s == ForestLiana.name_for(Address)
|
50
|
+
end
|
51
|
+
association = collection.fields.find { |field| field[:field] == 'addressable' }
|
52
|
+
fields = collection.fields.select do |field|
|
53
|
+
field[:field] == 'addressable_id' || field[:field] == 'addressable_type'
|
54
|
+
end
|
55
|
+
|
56
|
+
expect(association).to be_nil
|
57
|
+
expect(fields.size).to eq(2)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
4
62
|
context 'with an "unhandled" column types (binary, postgis geography, ...)' do
|
5
63
|
it 'should not define theses column in the schema' do
|
6
64
|
collection = ForestLiana.apimap.find do |object|
|
data/spec/spec_helper.rb
CHANGED
@@ -19,6 +19,8 @@ SimpleCov.add_filter ['app/services/forest_liana/ability/fetch.rb', 'lib/forest_
|
|
19
19
|
# See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
|
20
20
|
RSpec.configure do |config|
|
21
21
|
ENV['RAILS_ENV'] = 'test'
|
22
|
+
ENV['ENABLE_SUPPORT_POLYMORPHISM'] = 'true'
|
23
|
+
|
22
24
|
require File.expand_path('../dummy/config/environment', __FILE__)
|
23
25
|
|
24
26
|
# rspec-expectations config goes here. You can use an alternate
|
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: 8.0
|
4
|
+
version: 8.1.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:
|
11
|
+
date: 2024-01-18 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|
@@ -350,6 +350,7 @@ files:
|
|
350
350
|
- spec/dummy/app/controllers/application_controller.rb
|
351
351
|
- spec/dummy/app/controllers/forest/islands_controller.rb
|
352
352
|
- spec/dummy/app/helpers/application_helper.rb
|
353
|
+
- spec/dummy/app/models/address.rb
|
353
354
|
- spec/dummy/app/models/application_record.rb
|
354
355
|
- spec/dummy/app/models/car.rb
|
355
356
|
- spec/dummy/app/models/driver.rb
|
@@ -403,6 +404,7 @@ files:
|
|
403
404
|
- spec/dummy/db/migrate/20220719094450_create_drivers.rb
|
404
405
|
- spec/dummy/db/migrate/20220727114450_create_manufacturers.rb
|
405
406
|
- spec/dummy/db/migrate/20220727114930_add_columns_to_products.rb
|
407
|
+
- spec/dummy/db/migrate/20231117084236_create_addresses.rb
|
406
408
|
- spec/dummy/db/schema.rb
|
407
409
|
- spec/dummy/lib/forest_liana/collections/island.rb
|
408
410
|
- spec/dummy/lib/forest_liana/collections/location.rb
|
@@ -646,6 +648,7 @@ test_files:
|
|
646
648
|
- spec/dummy/app/controllers/application_controller.rb
|
647
649
|
- spec/dummy/app/controllers/forest/islands_controller.rb
|
648
650
|
- spec/dummy/app/helpers/application_helper.rb
|
651
|
+
- spec/dummy/app/models/address.rb
|
649
652
|
- spec/dummy/app/models/application_record.rb
|
650
653
|
- spec/dummy/app/models/car.rb
|
651
654
|
- spec/dummy/app/models/driver.rb
|
@@ -699,6 +702,7 @@ test_files:
|
|
699
702
|
- spec/dummy/db/migrate/20220719094450_create_drivers.rb
|
700
703
|
- spec/dummy/db/migrate/20220727114450_create_manufacturers.rb
|
701
704
|
- spec/dummy/db/migrate/20220727114930_add_columns_to_products.rb
|
705
|
+
- spec/dummy/db/migrate/20231117084236_create_addresses.rb
|
702
706
|
- spec/dummy/db/schema.rb
|
703
707
|
- spec/dummy/lib/forest_liana/collections/island.rb
|
704
708
|
- spec/dummy/lib/forest_liana/collections/location.rb
|