forest_liana 8.0.9 → 8.0.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 7da02ba115c9316d358a95b7e7001b92dd50b61e3799aa59d44fe552f62bdd0b
4
- data.tar.gz: 43d99d7f3067815e9dd3af8bf26f153e2ff33b5910e892ca3ada77fc00246284
3
+ metadata.gz: 46e0bf016cde7afdf3a6cc2fc021d2984d649af245e62c3e56262c68b16a00cf
4
+ data.tar.gz: 22769b1933fd3f95169e33a7f13cec97b463f2e28784691772e817213d29fdc1
5
5
  SHA512:
6
- metadata.gz: 46ecb0aa4cd2257f62cff46564061b181e41dfac8407f10dec94883a351c5a5ade2372c0dfd6fb92a90e01c3b22e38f4b3a4ad7b67c2364255bdc937c82e326d
7
- data.tar.gz: 17c836f951cc37a5a9ab6fe5bd39e78b444451938ab65eedf654274e1c3965cf66b151796d5317481b9267d658badbf19e3ae417d906109914547834dbe10aaf
6
+ metadata.gz: 41e4b81c03def8ae2cfd17455133ba66e552805a85604b8daf057d468b6d0b96f407ac50f55c01ae2c8de2bc047894084f2357792de2d7cf343ad7f12d51f166
7
+ data.tar.gz: 7748c16eae78df865130cfdcaec6db0a7605d8e3253167c8d6fd4b6da511930ace227cb4581c1da5021de0b91149bb9c2dc96182757a0e365f9a654f3abfb784
@@ -0,0 +1,12 @@
1
+ ForestLiana.apimap.each do |collection|
2
+ if !collection.actions.empty?
3
+ collection.actions.each do |action|
4
+ if action.hooks && action.hooks[:load].present?
5
+ post action.endpoint.sub('forest', '') + '/hooks/load' => 'actions#load', action_name: ActiveSupport::Inflector.parameterize(action.name)
6
+ end
7
+ if action.hooks && action.hooks[:change].present?
8
+ post action.endpoint.sub('forest', '') + '/hooks/change' => 'actions#change', action_name: ActiveSupport::Inflector.parameterize(action.name)
9
+ end
10
+ end
11
+ end
12
+ end
data/config/routes.rb CHANGED
@@ -59,7 +59,6 @@ ForestLiana::Engine.routes.draw do
59
59
  delete ':collection/:id', to: router
60
60
  delete ':collection', to: router
61
61
 
62
- # Smart Actions forms value
63
- post 'actions/:action_name/hooks/load' => 'actions#load'
64
- post 'actions/:action_name/hooks/change' => 'actions#change'
62
+ draw(:actions)
63
+
65
64
  end
@@ -1,3 +1,3 @@
1
1
  module ForestLiana
2
- VERSION = "8.0.9"
2
+ VERSION = "8.0.10"
3
3
  end
@@ -3,5 +3,106 @@ class Forest::Island
3
3
 
4
4
  collection :Island
5
5
 
6
- action 'my_action'
6
+ foo = {
7
+ field: 'foo',
8
+ type: 'String',
9
+ default_value: nil,
10
+ enums: nil,
11
+ is_required: false,
12
+ is_read_only: false,
13
+ reference: nil,
14
+ description: nil,
15
+ widget: nil,
16
+ hook: 'on_foo_changed'
17
+ }
18
+ enum = {
19
+ field: 'enum',
20
+ type: 'Enum',
21
+ enums: %w[a b c],
22
+ }
23
+ multiple_enum = {
24
+ field: 'multipleEnum',
25
+ type: ['Enum'],
26
+ enums: %w[a b c],
27
+ }
28
+
29
+ action 'my_action',
30
+ fields: [foo],
31
+ hooks: {
32
+ :load => -> (context) {
33
+ context[:fields]
34
+ },
35
+ :change => {
36
+ 'on_foo_changed' => -> (context) {
37
+ foo = context[:fields].find{|field| field[:field] == 'foo'}
38
+ foo[:value] = 'baz'
39
+ context[:fields]
40
+ }
41
+ }
42
+ }
43
+
44
+ action 'fail_action',
45
+ fields: [foo],
46
+ hooks: {
47
+ :load => -> (context) {
48
+ 1
49
+ },
50
+ :change => {
51
+ 'on_foo_changed' => -> (context) {
52
+ 1
53
+ }
54
+ }
55
+ }
56
+
57
+ action 'cheat_action',
58
+ fields: [foo],
59
+ hooks: {
60
+ :load => -> (context) {
61
+ {}
62
+ },
63
+ :change => {
64
+ 'on_foo_changed' => -> (context) {
65
+ context[:fields]['baz'] = foo.clone.update({field: 'baz'})
66
+ context[:fields]
67
+ }
68
+ }
69
+ }
70
+
71
+ action 'enums_action',
72
+ endpoint: 'forest/custom/islands/enums_action',
73
+ fields: [foo, enum],
74
+ hooks: {
75
+ :change => {
76
+ 'on_foo_changed' => -> (context) {
77
+ fields = context[:fields]
78
+ enum_field = fields.find{|field| field[:field] == 'enum'}
79
+ enum_field[:enums] = %w[c d e]
80
+ fields
81
+ }
82
+ }
83
+ }
84
+
85
+ action 'multiple_enums_action',
86
+ fields: [foo, multiple_enum],
87
+ hooks: {
88
+ :change => {
89
+ 'on_foo_changed' => -> (context) {
90
+ fields = context[:fields]
91
+ enum_field = fields.find{|field| field[:field] == 'multipleEnum'}
92
+ enum_field[:enums] = %w[c d z]
93
+ fields
94
+ }
95
+ }
96
+ }
97
+
98
+ action 'use_user_context',
99
+ fields: [foo],
100
+ hooks: {
101
+ :load => -> (context) {
102
+ foo = context[:fields].find{|field| field[:field] == 'foo'}
103
+ foo[:value] = context[:user]['first_name']
104
+ context[:fields]
105
+ }
106
+ }
107
+
7
108
  end
@@ -39,124 +39,7 @@ describe 'Requesting Actions routes', :type => :request do
39
39
  }
40
40
 
41
41
  describe 'hooks' do
42
- foo = {
43
- field: 'foo',
44
- type: 'String',
45
- default_value: nil,
46
- enums: nil,
47
- is_required: false,
48
- is_read_only: false,
49
- reference: nil,
50
- description: nil,
51
- widget: nil,
52
- hook: 'on_foo_changed'
53
- }
54
- enum = {
55
- field: 'enum',
56
- type: 'Enum',
57
- enums: %w[a b c],
58
- }
59
- multiple_enum = {
60
- field: 'multipleEnum',
61
- type: ['Enum'],
62
- enums: %w[a b c],
63
- }
64
-
65
- action_definition = {
66
- name: 'my_action',
67
- fields: [foo],
68
- hooks: {
69
- :load => -> (context) {
70
- context[:fields]
71
- },
72
- :change => {
73
- 'on_foo_changed' => -> (context) {
74
- foo = context[:fields].find{|field| field[:field] == 'foo'}
75
- foo[:value] = 'baz'
76
- context[:fields]
77
- }
78
- }
79
- }
80
- }
81
- fail_action_definition = {
82
- name: 'fail_action',
83
- fields: [foo],
84
- hooks: {
85
- :load => -> (context) {
86
- 1
87
- },
88
- :change => {
89
- 'on_foo_changed' => -> (context) {
90
- 1
91
- }
92
- }
93
- }
94
- }
95
- cheat_action_definition = {
96
- name: 'cheat_action',
97
- fields: [foo],
98
- hooks: {
99
- :load => -> (context) {
100
- {}
101
- },
102
- :change => {
103
- 'on_foo_changed' => -> (context) {
104
- context[:fields]['baz'] = foo.clone.update({field: 'baz'})
105
- context[:fields]
106
- }
107
- }
108
- }
109
- }
110
- enums_action_definition = {
111
- name: 'enums_action',
112
- fields: [foo, enum],
113
- hooks: {
114
- :change => {
115
- 'on_foo_changed' => -> (context) {
116
- fields = context[:fields]
117
- enum_field = fields.find{|field| field[:field] == 'enum'}
118
- enum_field[:enums] = %w[c d e]
119
- fields
120
- }
121
- }
122
- }
123
- }
124
-
125
- multiple_enums_action_definition = {
126
- name: 'multiple_enums_action',
127
- fields: [foo, multiple_enum],
128
- hooks: {
129
- :change => {
130
- 'on_foo_changed' => -> (context) {
131
- fields = context[:fields]
132
- enum_field = fields.find{|field| field[:field] == 'multipleEnum'}
133
- enum_field[:enums] = %w[c d z]
134
- fields
135
- }
136
- }
137
- }
138
- }
139
-
140
- use_user_context_action_definition = {
141
- name: 'use_user_context',
142
- fields: [foo],
143
- hooks: {
144
- :load => -> (context) {
145
- foo = context[:fields].find{|field| field[:field] == 'foo'}
146
- foo[:value] = context[:user]['first_name']
147
- context[:fields]
148
- }
149
- }
150
- }
151
-
152
- action = ForestLiana::Model::Action.new(action_definition)
153
- fail_action = ForestLiana::Model::Action.new(fail_action_definition)
154
- cheat_action = ForestLiana::Model::Action.new(cheat_action_definition)
155
- enums_action = ForestLiana::Model::Action.new(enums_action_definition)
156
- multiple_enums_action = ForestLiana::Model::Action.new(multiple_enums_action_definition)
157
- use_user_context_action = ForestLiana::Model::Action.new(use_user_context_action_definition)
158
42
  island = ForestLiana.apimap.find {|collection| collection.name.to_s == ForestLiana.name_for(Island)}
159
- island.actions = [action, fail_action, cheat_action, enums_action, multiple_enums_action, use_user_context_action]
160
43
 
161
44
  describe 'call /load' do
162
45
  params = {
@@ -167,6 +50,8 @@ describe 'Requesting Actions routes', :type => :request do
167
50
 
168
51
  it 'should respond 200' do
169
52
  post '/forest/actions/my_action/hooks/load', params: JSON.dump(params), headers: headers
53
+ action = island.actions.select { |action| action.name == 'my_action' }.first
54
+ foo = action.fields.select { |field| field[:field] == 'foo' }.first
170
55
  expect(response.status).to eq(200)
171
56
  expect(JSON.parse(response.body)).to eq({'fields' => [foo.merge({:value => nil}).transform_keys { |key| key.to_s.camelize(:lower) }.stringify_keys]})
172
57
  end
@@ -190,26 +75,30 @@ describe 'Requesting Actions routes', :type => :request do
190
75
 
191
76
  it 'should return the first_name of the user who call the action' do
192
77
  post '/forest/actions/use_user_context/hooks/load', params: JSON.dump(params), headers: headers
78
+ action = island.actions.select { |action| action.name == 'use_user_context' }.first
79
+ foo = action.fields.select { |field| field[:field] == 'foo' }.first
193
80
  expect(response.status).to eq(200)
194
81
  expect(JSON.parse(response.body)).to eq({'fields' => [foo.merge({:value => 'Michael'}).transform_keys { |key| key.to_s.camelize(:lower) }.stringify_keys]})
195
82
  end
196
83
  end
197
84
 
198
85
  describe 'call /change' do
199
- updated_foo = foo.clone.merge({:previousValue => nil, :value => 'bar'})
200
- params = {
201
- data: {
202
- attributes: {
203
- ids: [1],
204
- fields: [updated_foo],
205
- collection_name: 'Island',
206
- changed_field: 'foo',
207
- is_read_only: true
86
+ it 'should respond 200' do
87
+ action = island.actions.select { |action| action.name == 'my_action' }.first
88
+ foo = action.fields.select { |field| field[:field] == 'foo' }.first
89
+ updated_foo = foo.clone.merge({:previousValue => nil, :value => 'bar'})
90
+ params = {
91
+ data: {
92
+ attributes: {
93
+ ids: [1],
94
+ fields: [updated_foo],
95
+ collection_name: 'Island',
96
+ changed_field: 'foo',
97
+ is_read_only: true
98
+ }
208
99
  }
209
100
  }
210
- }
211
101
 
212
- it 'should respond 200' do
213
102
  post '/forest/actions/my_action/hooks/change', params: JSON.dump(params), headers: headers
214
103
  expect(response.status).to eq(200)
215
104
  expected = updated_foo.clone.merge({:value => 'baz'})
@@ -226,12 +115,31 @@ describe 'Requesting Actions routes', :type => :request do
226
115
  end
227
116
 
228
117
  it 'should respond 500 with bad hook result type' do
118
+ action = island.actions.select { |action| action.name == 'fail_action' }.first
119
+ foo = action.fields.select { |field| field[:field] == 'foo' }.first
120
+ updated_foo = foo.clone.merge({:previousValue => nil, :value => 'bar'})
121
+ params = {
122
+ data: {
123
+ attributes: {
124
+ ids: [1],
125
+ fields: [updated_foo],
126
+ collection_name: 'Island',
127
+ changed_field: 'foo',
128
+ is_read_only: true
129
+ }
130
+ }
131
+ }
132
+
229
133
  post '/forest/actions/fail_action/hooks/change', params: JSON.dump(params), headers: headers
230
134
  expect(response.status).to eq(500)
231
135
  expect(JSON.parse(response.body)).to eq({'error' => 'Error in smart action load hook: hook must return an array of fields'})
232
136
  end
233
137
 
234
138
  it 'should reset value when enums has changed' do
139
+ action = island.actions.select { |action| action.name == 'enums_action' }.first
140
+ foo = action.fields.select { |field| field[:field] == 'foo' }.first
141
+ enum = action.fields.select { |field| field[:field] == 'enum' }.first
142
+ updated_foo = foo.clone.merge({:previousValue => nil, :value => 'bar'})
235
143
  updated_enum = enum.clone.merge({:previousValue => nil, :value => 'a'}) # set value to a
236
144
  p = {
237
145
  data: {
@@ -243,7 +151,8 @@ describe 'Requesting Actions routes', :type => :request do
243
151
  }
244
152
  }
245
153
  }
246
- post '/forest/actions/enums_action/hooks/change', params: JSON.dump(p), headers: headers
154
+
155
+ post '/forest/custom/islands/enums_action/hooks/change', params: JSON.dump(p), headers: headers
247
156
  expect(response.status).to eq(200)
248
157
 
249
158
  expected_enum = updated_enum.clone.merge({ :enums => %w[c d e], :value => nil, :widgetEdit => nil})
@@ -258,6 +167,9 @@ describe 'Requesting Actions routes', :type => :request do
258
167
  end
259
168
 
260
169
  it 'should not reset value when every enum values are in the enums definition' do
170
+ action = island.actions.select { |action| action.name == 'multiple_enums_action' }.first
171
+ foo = action.fields.select { |field| field[:field] == 'foo' }.first
172
+ multiple_enum = action.fields.select { |field| field[:field] == 'multipleEnum' }.first
261
173
  updated_multiple_enum = multiple_enum.clone.merge({:previousValue => nil, :value => %w[c]})
262
174
  p = {
263
175
  data: {
@@ -284,6 +196,9 @@ describe 'Requesting Actions routes', :type => :request do
284
196
  end
285
197
 
286
198
  it 'should reset value when one of the enum values is not in the enums definition' do
199
+ action = island.actions.select { |action| action.name == 'multiple_enums_action' }.first
200
+ foo = action.fields.select { |field| field[:field] == 'foo' }.first
201
+ multiple_enum = action.fields.select { |field| field[:field] == 'multipleEnum' }.first
287
202
  wrongly_updated_multiple_enum = multiple_enum.clone.merge({:previousValue => nil, :value => %w[a b]})
288
203
  p = {
289
204
  data: {
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.9
4
+ version: 8.0.10
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sandro Munda
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-06-13 00:00:00.000000000 Z
11
+ date: 2023-06-19 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -326,6 +326,7 @@ files:
326
326
  - config/initializers/logger.rb
327
327
  - config/initializers/time_formats.rb
328
328
  - config/routes.rb
329
+ - config/routes/actions.rb
329
330
  - lib/forest_liana.rb
330
331
  - lib/forest_liana/base64_string_io.rb
331
332
  - lib/forest_liana/bootstrapper.rb