mirror of
https://github.com/bryanthaboi/gen1recomp.git
synced 2026-08-19 20:20:19 +02:00
skin studio updates, save sync CLOSES #1533
This commit is contained in:
@@ -0,0 +1,125 @@
|
||||
package.path = "./?.lua;./?/init.lua;" .. package.path
|
||||
|
||||
local T = require("tests.harness")
|
||||
local check, eq = T.check, T.eq
|
||||
love = love or require("tests.love_stub")
|
||||
|
||||
local HostShell = require("src.core.HostShell")
|
||||
|
||||
local TOKEN = "0123456789abcdef0123456789abcdef"
|
||||
local BODY = '{"blob":"return {}"}'
|
||||
|
||||
HostShell.haveCurl = function() return false end
|
||||
love.system.getOS = function() return "Android" end
|
||||
|
||||
local calls = {}
|
||||
local reply = "STATUS 200\n" .. '{"ok":true}'
|
||||
|
||||
love.system.httpRequest = function(url, method, headers, body, userAgent)
|
||||
calls[#calls + 1] = { url = url, method = method, headers = headers,
|
||||
body = body, userAgent = userAgent }
|
||||
if type(reply) == "function" then return reply() end
|
||||
return reply
|
||||
end
|
||||
|
||||
check(HostShell.canHttpRequest(),
|
||||
"the bridge counts as a request transport where curl does not exist")
|
||||
|
||||
local body, err, code = HostShell.httpRequest("https://sync.example/sync/save", {
|
||||
method = "PUT",
|
||||
body = BODY,
|
||||
headers = {
|
||||
["x-sync-account"] = "aa11bb22cc33dd44",
|
||||
["x-sync-token"] = TOKEN,
|
||||
["Content-Type"] = "application/json",
|
||||
},
|
||||
})
|
||||
|
||||
eq(code, 200, "a bridge request completes: " .. tostring(err))
|
||||
eq(body, '{"ok":true}', "and the body arrives with the status line stripped")
|
||||
eq(err, nil, "with no error alongside it")
|
||||
|
||||
eq(#calls, 1, "the bridge is called once")
|
||||
local sent = calls[1]
|
||||
eq(sent.url, "https://sync.example/sync/save", "the url goes through untouched")
|
||||
eq(sent.method, "PUT", "and so does the method curl would have taken with -X")
|
||||
eq(sent.body, BODY, "the save blob rides the body argument, not the url")
|
||||
eq(sent.userAgent, "gen1recomp", "with the default user agent")
|
||||
|
||||
local seen = {}
|
||||
for i = 1, #sent.headers, 2 do seen[sent.headers[i]] = sent.headers[i + 1] end
|
||||
eq(seen["x-sync-token"], TOKEN, "auth headers arrive as flat name, value pairs")
|
||||
eq(seen["x-sync-account"], "aa11bb22cc33dd44", "for the account id too")
|
||||
eq(seen["Content-Type"], "application/json", "and for the content type")
|
||||
eq(seen["User-Agent"], nil,
|
||||
"the user agent stays its own argument rather than a duplicate header")
|
||||
|
||||
calls = {}
|
||||
reply = "STATUS 409\n" .. '{"error":"the save moved on"}'
|
||||
body, err, code = HostShell.httpRequest("https://sync.example/sync/save", {
|
||||
method = "PUT", body = BODY, headers = { ["Accept"] = "application/json" },
|
||||
})
|
||||
eq(code, 409, "a conflict comes back as a status, not as a transport failure")
|
||||
eq(body, '{"error":"the save moved on"}',
|
||||
"and its body survives, which is the whole point of the request arm")
|
||||
eq(err, nil, "a 4xx is the caller's to interpret")
|
||||
|
||||
calls = {}
|
||||
reply = "ERROR the reply was too large\n"
|
||||
body, err, code = HostShell.httpRequest("https://sync.example/sync/state", {
|
||||
method = "GET",
|
||||
})
|
||||
eq(code, nil, "an ERROR envelope has no status")
|
||||
eq(body, nil, "and no body")
|
||||
check(err and err:find("the reply was too large", 1, true) ~= nil,
|
||||
"the bridge's own complaint reaches the caller: " .. tostring(err))
|
||||
check(err and err:find("https://sync.example/sync/state", 1, true) ~= nil,
|
||||
"named with the url that failed")
|
||||
|
||||
calls = {}
|
||||
reply = "STATUS 200\n" .. '{"ok":true}'
|
||||
body, err, code = HostShell.httpRequest("https://sync.example/sync/save", {
|
||||
method = "PUT", body = BODY,
|
||||
headers = { ["x-sync-token"] = TOKEN .. "\r\nx-sync-account: stolen" },
|
||||
})
|
||||
eq(code, nil, "a header value carrying CRLF is refused")
|
||||
eq(err, "bad request header", "with the same complaint the curl branch gives")
|
||||
eq(#calls, 0, "and the bridge is never reached")
|
||||
|
||||
calls = {}
|
||||
body, err, code = HostShell.httpRequest("https://sync.example/sync/save", {
|
||||
method = "PATCH", body = BODY,
|
||||
})
|
||||
eq(code, nil, "a method the bridge cannot express is refused")
|
||||
check(err and err:find("PATCH", 1, true) ~= nil,
|
||||
"naming the method: " .. tostring(err))
|
||||
eq(#calls, 0, "without calling the bridge")
|
||||
|
||||
calls = {}
|
||||
reply = function() return nil end
|
||||
body, err, code = HostShell.httpRequest("https://sync.example/sync/save", {
|
||||
method = "PUT", body = BODY,
|
||||
})
|
||||
eq(code, nil, "an old app under a newer engine returns nothing")
|
||||
check(err and err:find("update the app", 1, true) ~= nil,
|
||||
"and degrades to an update notice rather than a crash: " .. tostring(err))
|
||||
|
||||
love.system.httpRequest = nil
|
||||
love.system.httpDownload = function() return false end
|
||||
check(not HostShell.canHttpRequest(),
|
||||
"a build with only the download bridge cannot make signed requests")
|
||||
body, err, code = HostShell.httpRequest("https://sync.example/sync/save", {
|
||||
method = "PUT", body = BODY,
|
||||
})
|
||||
eq(code, nil, "so the request does not go out")
|
||||
check(err and err:find("update the app", 1, true) ~= nil,
|
||||
"and says what to do about it: " .. tostring(err))
|
||||
|
||||
love.system.httpDownload = nil
|
||||
body, err, code = HostShell.httpRequest("https://sync.example/sync/save", {
|
||||
method = "PUT", body = BODY,
|
||||
})
|
||||
eq(err, "no request transport on this platform",
|
||||
"a platform with no bridge at all keeps its old answer")
|
||||
|
||||
T.finish("host shell bridge request")
|
||||
Reference in New Issue
Block a user