Skip to content

Commit 76adab6

Browse files
committed
Data Flow fixing from web ui
1 parent 834b92c commit 76adab6

4 files changed

Lines changed: 88 additions & 6 deletions

File tree

lib/asrfacet_rb/web/server.rb

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
# and conditions defined in the LICENSE file.
1313

1414
require "json"
15+
require "uri"
1516
require "webrick"
1617

1718
module ASRFacet
@@ -122,7 +123,7 @@ def handle_sessions(req, res)
122123
end
123124

124125
def handle_session_lookup(req, res)
125-
session = @session_store.fetch(req.query["id"].to_s)
126+
session = @session_store.fetch(request_param(req, "id").to_s)
126127
session ? respond_json(res, { session: session }) : respond_json(res, { error: "not_found" }, status: 404)
127128
rescue StandardError
128129
respond_json(res, { error: "lookup_failed" }, status: 500)
@@ -131,7 +132,7 @@ def handle_session_lookup(req, res)
131132
def handle_run(req, res)
132133
return respond_json(res, { error: "method_not_allowed" }, status: 405) unless req.request_method == "POST"
133134

134-
session_id = req.query["id"].to_s
135+
session_id = request_param(req, "id").to_s
135136
return respond_json(res, { error: "not_found" }, status: 404) if @session_store.fetch(session_id).nil?
136137

137138
if @session_runner.start(session_id)
@@ -276,6 +277,24 @@ def parse_json(req)
276277
{}
277278
end
278279

280+
def request_param(req, key)
281+
key_name = key.to_s
282+
from_query = req.query[key_name].to_s
283+
return from_query unless from_query.empty?
284+
285+
query_string = req.query_string.to_s
286+
if query_string.empty?
287+
request_uri = req.request_uri
288+
query_string = request_uri.query.to_s if request_uri.respond_to?(:query)
289+
query_string = request_uri.to_s.split("?", 2).last.to_s if query_string.empty? && request_uri.to_s.include?("?")
290+
end
291+
return nil if query_string.empty?
292+
293+
URI.decode_www_form(query_string).to_h[key_name]
294+
rescue StandardError
295+
nil
296+
end
297+
279298
def respond_json(res, payload, status: 200)
280299
res.status = status
281300
res["Content-Type"] = "application/json; charset=utf-8"

lib/asrfacet_rb/web/session_store.rb

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -244,7 +244,7 @@ def path_for(id)
244244
def load_file(path)
245245
return nil unless File.file?(path)
246246

247-
symbolize(JSON.parse(File.read(path)))
247+
hydrate_session(symbolize(JSON.parse(File.read(path))))
248248
rescue StandardError
249249
nil
250250
end
@@ -270,12 +270,14 @@ def deep_merge(base, extra)
270270
end
271271

272272
def normalize(value)
273-
if value.respond_to?(:to_h) && !value.is_a?(Hash)
274-
normalize(value.to_h)
275-
elsif value.is_a?(Hash)
273+
if value.is_a?(Hash)
276274
value.each_with_object({}) { |(key, nested), memo| memo[key.to_sym] = normalize(nested) }
277275
elsif value.is_a?(Array)
278276
value.map { |entry| normalize(entry) }
277+
elsif value.nil?
278+
nil
279+
elsif value.respond_to?(:to_h) && !value.is_a?(Hash)
280+
normalize(value.to_h)
279281
else
280282
value
281283
end
@@ -347,6 +349,16 @@ def normalize_failure(message)
347349
recommendation: "Review the session activity log and rerun with a healthier framework or target configuration."
348350
}
349351
end
352+
353+
def hydrate_session(session)
354+
item = symbolize(session)
355+
item[:events] = [] if item[:events].is_a?(Hash) && item[:events].empty?
356+
item[:error] = nil if item[:error].is_a?(Hash) && item[:error].empty?
357+
item[:last_heartbeat_at] = nil if item[:last_heartbeat_at].is_a?(Hash) && item[:last_heartbeat_at].empty?
358+
item
359+
rescue StandardError
360+
session
361+
end
350362
end
351363
end
352364
end

spec/web/server_spec.rb

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
# and conditions defined in the LICENSE file.
1313

1414
require "spec_helper"
15+
require "json"
1516

1617
RSpec.describe ASRFacet::Web::Server do
1718
it "renders the branded dashboard shell with external assets and workspace views" do
@@ -26,4 +27,42 @@
2627
expect(html).to include("About ASRFacet-Rb")
2728
expect(html).to include("Documentation")
2829
end
30+
31+
it "starts a saved session when the run id is passed in the POST query string" do
32+
session_store = instance_double(ASRFacet::Web::SessionStore)
33+
session_runner = instance_double(ASRFacet::Web::SessionRunner)
34+
response_class = Class.new do
35+
attr_accessor :status, :body
36+
37+
def initialize
38+
@headers = {}
39+
end
40+
41+
def []=(key, value)
42+
@headers[key] = value
43+
end
44+
45+
def [](key)
46+
@headers[key]
47+
end
48+
end
49+
request = Struct.new(:request_method, :query, :query_string, :request_uri, :body).new(
50+
"POST",
51+
{},
52+
"id=session-123",
53+
URI("http://127.0.0.1/api/run?id=session-123"),
54+
""
55+
)
56+
response = response_class.new
57+
58+
allow(session_store).to receive(:fetch).with("session-123").and_return({ id: "session-123" })
59+
allow(session_store).to receive(:append_event)
60+
allow(session_runner).to receive(:start).with("session-123").and_return(true)
61+
62+
described_class.new(session_store: session_store, session_runner: session_runner).send(:handle_run, request, response)
63+
64+
expect(response.status).to eq(200)
65+
expect(JSON.parse(response.body)).to include("ok" => true, "session_id" => "session-123")
66+
expect(session_store).to have_received(:append_event).with("session-123", hash_including(type: "system"))
67+
end
2968
end

spec/web/session_store_spec.rb

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,4 +79,16 @@
7979
)
8080
end
8181
end
82+
83+
it "preserves array and nil session fields when persisting to disk" do
84+
Dir.mktmpdir do |dir|
85+
store = described_class.new(root: dir)
86+
session = store.create_or_update(name: "Shape check", config: { target: "example.com" })
87+
recovered = store.fetch(session[:id])
88+
89+
expect(recovered[:events]).to eq([])
90+
expect(recovered[:error]).to be_nil
91+
expect(recovered[:last_heartbeat_at]).to be_nil
92+
end
93+
end
8294
end

0 commit comments

Comments
 (0)