forest_liana 9.20.0 → 9.20.1
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/controllers/forest_liana/actions_controller.rb +9 -4
- data/config/routes/actions.rb +2 -3
- data/lib/forest_liana/version.rb +1 -1
- data/spec/dummy/lib/forest_liana/collections/island.rb +13 -0
- data/spec/requests/actions_controller_spec.rb +19 -0
- data/spec/requests/workflow_executions_spec.rb +50 -0
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 7e6590ae4597f44757af9a98c3f4d8ba9e83652eedd857f45aeb1fe365e8a8ae
|
|
4
|
+
data.tar.gz: 5aa5f3150171dd65dac411007c311b9cb5409c9eb97d1a415d31e908001b0d34
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 6d848b970f6f68edd2a162f40e546740878c6fc7e2b298a3c494f6641fce908b41e2412a9e3457d13edef7d6433ce9f5704b77604851b2fd7aeca5eb60cfe691
|
|
7
|
+
data.tar.gz: 2828ff99f57028970cc2ec4e1662b70203d0d077ca0bbb45350dd4d29d09bffaffd1ef907b923e666cfc28704f97db62358bdf6709cf4b7c16bac822cd1afa15
|
|
@@ -58,7 +58,7 @@ module ForestLiana
|
|
|
58
58
|
begin
|
|
59
59
|
# action.hooks[:change] is a hashmap here
|
|
60
60
|
# to do the validation, only the hook names are require
|
|
61
|
-
change_hooks_name = action.hooks[:change]
|
|
61
|
+
change_hooks_name = action.hooks && action.hooks[:change] ? action.hooks[:change].keys : nil
|
|
62
62
|
ForestLiana::SmartActionFieldValidator.validate_smart_action_fields(result[:fields], action.name, change_hooks_name)
|
|
63
63
|
rescue ForestLiana::Errors::SmartActionInvalidFieldError => invalid_field_error
|
|
64
64
|
FOREST_LOGGER.warn invalid_field_error.message
|
|
@@ -107,10 +107,15 @@ module ForestLiana
|
|
|
107
107
|
# Get the smart action hook load context
|
|
108
108
|
context = get_smart_action_load_ctx(action.fields)
|
|
109
109
|
|
|
110
|
-
|
|
111
|
-
|
|
110
|
+
if action.hooks && action.hooks[:load].present?
|
|
111
|
+
# Call the user-defined load hook.
|
|
112
|
+
result = action.hooks[:load].(context)
|
|
112
113
|
|
|
113
|
-
|
|
114
|
+
handle_result(result, action)
|
|
115
|
+
else
|
|
116
|
+
# No load hook declared: answer the static form (Node agent parity) instead of a 404.
|
|
117
|
+
handle_result(context[:fields], action)
|
|
118
|
+
end
|
|
114
119
|
end
|
|
115
120
|
end
|
|
116
121
|
|
data/config/routes/actions.rb
CHANGED
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
ForestLiana.apimap.each do |collection|
|
|
2
2
|
if !collection.actions.empty?
|
|
3
3
|
collection.actions.each do |action|
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
end
|
|
4
|
+
# Unconditional: clients probe /hooks/load even when no load hook is declared.
|
|
5
|
+
post action.endpoint.sub('forest', '') + '/hooks/load' => 'actions#load', action_name: ActiveSupport::Inflector.parameterize(action.name)
|
|
7
6
|
if action.hooks && action.hooks[:change].present?
|
|
8
7
|
post action.endpoint.sub('forest', '') + '/hooks/change' => 'actions#change', action_name: ActiveSupport::Inflector.parameterize(action.name)
|
|
9
8
|
end
|
data/lib/forest_liana/version.rb
CHANGED
|
@@ -28,6 +28,19 @@ class Forest::Island
|
|
|
28
28
|
|
|
29
29
|
action 'test'
|
|
30
30
|
|
|
31
|
+
action 'static_form_action',
|
|
32
|
+
fields: [{
|
|
33
|
+
field: 'static_field',
|
|
34
|
+
type: 'String',
|
|
35
|
+
default_value: nil,
|
|
36
|
+
enums: nil,
|
|
37
|
+
is_required: false,
|
|
38
|
+
is_read_only: false,
|
|
39
|
+
reference: nil,
|
|
40
|
+
description: nil,
|
|
41
|
+
widget: nil
|
|
42
|
+
}]
|
|
43
|
+
|
|
31
44
|
action 'my_action',
|
|
32
45
|
fields: [foo],
|
|
33
46
|
hooks: {
|
|
@@ -130,6 +130,25 @@ describe 'Requesting Actions routes', :type => :request do
|
|
|
130
130
|
expect(response.status).to eq(422)
|
|
131
131
|
end
|
|
132
132
|
|
|
133
|
+
it 'should respond 200 with the static form when the action has no load hook' do
|
|
134
|
+
post '/forest/actions/static_form_action/hooks/load', params: JSON.dump(params), headers: headers
|
|
135
|
+
action = island.actions.select { |action| action.name == 'static_form_action' }.first
|
|
136
|
+
static_field = action.fields.select { |field| field[:field] == 'static_field' }.first
|
|
137
|
+
expect(response.status).to eq(200)
|
|
138
|
+
expect(JSON.parse(response.body)).to eq({'fields' => [static_field.merge({:value => nil}).transform_keys { |key| key.to_s.camelize(:lower) }.stringify_keys]})
|
|
139
|
+
|
|
140
|
+
first_body = response.body
|
|
141
|
+
post '/forest/actions/static_form_action/hooks/load', params: JSON.dump(params), headers: headers
|
|
142
|
+
expect(response.status).to eq(200)
|
|
143
|
+
expect(response.body).to eq(first_body)
|
|
144
|
+
end
|
|
145
|
+
|
|
146
|
+
it 'should respond 200 with empty fields when the action has no form at all' do
|
|
147
|
+
post '/forest/actions/test/hooks/load', params: JSON.dump(params), headers: headers
|
|
148
|
+
expect(response.status).to eq(200)
|
|
149
|
+
expect(JSON.parse(response.body)).to eq({'fields' => []})
|
|
150
|
+
end
|
|
151
|
+
|
|
133
152
|
it 'should respond 500 with bad hook result type' do
|
|
134
153
|
post '/forest/actions/fail_action/hooks/load', params: JSON.dump(params), headers: headers
|
|
135
154
|
expect(response.status).to eq(500)
|
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
require 'rails_helper'
|
|
2
|
+
require 'zlib'
|
|
3
|
+
require 'stringio'
|
|
4
|
+
require 'socket'
|
|
2
5
|
|
|
3
6
|
describe 'Workflow executor proxy', type: :request do
|
|
4
7
|
let(:run_id) { 'run_abc123' }
|
|
@@ -207,6 +210,53 @@ describe 'Workflow executor proxy', type: :request do
|
|
|
207
210
|
end
|
|
208
211
|
end
|
|
209
212
|
|
|
213
|
+
# Real local server + real HTTParty (no stub) to exercise actual gzip decompression.
|
|
214
|
+
describe 'when the executor gzip-compresses the response (nginx in front)' do
|
|
215
|
+
let(:gz_body) do
|
|
216
|
+
io = StringIO.new
|
|
217
|
+
writer = Zlib::GzipWriter.new(io)
|
|
218
|
+
writer.write({ 'id' => run_id, 'state' => 'pending' }.to_json)
|
|
219
|
+
writer.close
|
|
220
|
+
io.string
|
|
221
|
+
end
|
|
222
|
+
|
|
223
|
+
around do |example|
|
|
224
|
+
server = TCPServer.new('127.0.0.1', 0)
|
|
225
|
+
port = server.addr[1]
|
|
226
|
+
thread = Thread.new do
|
|
227
|
+
client = server.accept
|
|
228
|
+
client.readpartial(4096)
|
|
229
|
+
client.write(
|
|
230
|
+
"HTTP/1.1 200 OK\r\nContent-Type: application/json\r\n" \
|
|
231
|
+
"Content-Encoding: gzip\r\nContent-Length: #{gz_body.bytesize}\r\n" \
|
|
232
|
+
"Connection: close\r\n\r\n"
|
|
233
|
+
)
|
|
234
|
+
client.write(gz_body)
|
|
235
|
+
client.close
|
|
236
|
+
rescue IOError, Errno::ECONNRESET, Errno::EPIPE
|
|
237
|
+
nil
|
|
238
|
+
end
|
|
239
|
+
|
|
240
|
+
original = ForestLiana.workflow_executor_url
|
|
241
|
+
ForestLiana.workflow_executor_url = "http://127.0.0.1:#{port}"
|
|
242
|
+
example.run
|
|
243
|
+
ensure
|
|
244
|
+
ForestLiana.workflow_executor_url = original
|
|
245
|
+
thread&.kill
|
|
246
|
+
server&.close
|
|
247
|
+
end
|
|
248
|
+
|
|
249
|
+
before { allow(HTTParty).to receive(:get).and_call_original }
|
|
250
|
+
|
|
251
|
+
it 'decompresses the body and drops the stale content-encoding' do
|
|
252
|
+
get "/forest/_internal/executor/runs/#{run_id}", headers: auth_headers
|
|
253
|
+
|
|
254
|
+
expect(response.status).to eq(200)
|
|
255
|
+
expect(JSON.parse(response.body)).to eq('id' => run_id, 'state' => 'pending')
|
|
256
|
+
expect(response.headers['content-encoding']).to be_nil
|
|
257
|
+
end
|
|
258
|
+
end
|
|
259
|
+
|
|
210
260
|
describe 'when ForestLiana.workflow_executor_url is blank' do
|
|
211
261
|
around do |example|
|
|
212
262
|
original = ForestLiana.workflow_executor_url
|
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: 9.20.
|
|
4
|
+
version: 9.20.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Sandro Munda
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2026-
|
|
11
|
+
date: 2026-07-23 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: rails
|