Files
maptool/test/test_kiwix.rb
T
randy 2b49eda7cb
CI / check (push) Successful in 40s
CI / deploy (push) Successful in 12s
Fix kiwix proxy 502ing on article links with non-ASCII titles
Sinatra decodes a route's splat before handing it to the block, so an
article link like /kiwix/content/wikipedia/Dlhé_diely arrived as raw
UTF-8, not percent-encoded. URI#path= rejects that outright
(URI::InvalidComponentError) rather than escaping it, which .proxy's
rescue turned into a silent nil -> every article link 502'd, while the
search results page linking to them worked fine (its own path,
/kiwix/search, is plain ASCII).
2026-09-09 15:55:48 +02:00

74 lines
2.9 KiB
Ruby

require_relative "test_helper"
require "maptool/kiwix"
# No real network calls — a blank URL and a guaranteed-local connection
# refusal are both fully offline/deterministic; simulating a genuine
# reachable kiwix-serve would need spinning up a real HTTP server for what
# is, at heart, a two-line Net::HTTP wrapper — not worth it, same
# restraint LiveTrackClientTest already applies to its own network path.
class KiwixTest < Minitest::Test
def test_reachable_is_false_for_a_blank_url
refute Maptool::Kiwix.reachable?("")
refute Maptool::Kiwix.reachable?(nil)
end
def test_reachable_is_false_when_nothing_is_listening
refute Maptool::Kiwix.reachable?("http://127.0.0.1:1", open_timeout: 1)
end
# A bare TCPServer stub (not WEBrick — not a project dependency, and this
# only needs to echo back what request line it received) confirms .proxy
# actually builds the target URL from path + query_string correctly, not
# just that it can complete *a* request (already covered by nothing here
# exercising a wrong path/query, unlike .reachable? which only ever hits
# "/").
def test_proxy_forwards_path_and_query_and_returns_the_response
server = TCPServer.new("127.0.0.1", 0)
port = server.addr[1]
request_line = nil
thread = Thread.new do
client = server.accept
request_line = client.gets
client.print("HTTP/1.1 200 OK\r\nContent-Type: text/plain\r\nContent-Length: 2\r\n\r\nhi")
client.close
end
response = Maptool::Kiwix.proxy("http://127.0.0.1:#{port}", "/kiwix/search", "pattern=&latitude=1")
thread.join
server.close
assert_equal "GET /kiwix/search?pattern=&latitude=1 HTTP/1.1\r\n", request_line
assert_equal "200", response.code
assert_equal "hi", response.body
end
def test_proxy_returns_nil_when_nothing_is_listening
assert_nil Maptool::Kiwix.proxy("http://127.0.0.1:1", "/kiwix/search", "", open_timeout: 1)
end
# A path with non-ASCII characters, e.g. an article title like
# "/kiwix/content/wikipedia/Dlhé_diely" — exactly what Sinatra's splat
# hands .proxy for a real article link, already URL-*decoded*. Used to
# raise URI::InvalidComponentError (caught, so this returned nil — every
# article link 502'd) since URI#path= rejects raw UTF-8 bytes outright
# instead of escaping them.
def test_proxy_escapes_non_ascii_characters_in_the_path
server = TCPServer.new("127.0.0.1", 0)
port = server.addr[1]
request_line = nil
thread = Thread.new do
client = server.accept
request_line = client.gets
client.print("HTTP/1.1 200 OK\r\nContent-Type: text/html\r\nContent-Length: 0\r\n\r\n")
client.close
end
response = Maptool::Kiwix.proxy("http://127.0.0.1:#{port}", "/kiwix/content/wikipedia/Dlhé_diely", "")
thread.join
server.close
assert_equal "GET /kiwix/content/wikipedia/Dlh%C3%A9_diely HTTP/1.1\r\n", request_line
assert_equal "200", response.code
end
end