2021-01-16 21:58:04 +01:00
|
|
|
local function rng_markup() return math.random() > 0.5 and "plain" or "imageboard" end
|
|
|
|
local function generate_str(length,characters)
|
|
|
|
return function()
|
|
|
|
local t = {}
|
|
|
|
local rnglength = math.random(2,length)
|
|
|
|
for i = 1,rnglength do
|
|
|
|
local rngpos = math.random(#characters)
|
|
|
|
local rngchar = string.sub(characters,rngpos,rngpos)
|
|
|
|
table.insert(t,rngchar)
|
|
|
|
end
|
|
|
|
local ret = table.concat(t)
|
|
|
|
return ret
|
|
|
|
end
|
|
|
|
end
|
|
|
|
local function characters(mask)
|
|
|
|
local t = {}
|
|
|
|
for i = 1,255 do
|
|
|
|
if string.match(string.char(i), mask) then
|
|
|
|
table.insert(t,string.char(i))
|
|
|
|
end
|
|
|
|
end
|
|
|
|
return table.concat(t)
|
|
|
|
end
|
|
|
|
local function maybe(input,chance)
|
|
|
|
chance = chance or 0.5
|
|
|
|
if math.random() < chance then
|
|
|
|
return input
|
|
|
|
end
|
|
|
|
end
|
2021-02-03 05:30:27 +01:00
|
|
|
local rng_any = generate_str(1024,characters("."))
|
2021-01-16 21:58:04 +01:00
|
|
|
local rng_subdomain = generate_str(30,characters("[0-9a-z]"))
|
|
|
|
local rng_storyname = generate_str(10,"[a-zA-Z0-9$+!*'(),-]")
|
2021-02-03 05:30:27 +01:00
|
|
|
local rng_storyid = function() return tostring(math.random(1,10)) end
|
2021-01-16 21:58:04 +01:00
|
|
|
local rng_tags = function()
|
|
|
|
local tag_gen = generate_str(10,"[%w%d ]")
|
|
|
|
local t = {}
|
|
|
|
for i = 1,10 do
|
|
|
|
table.insert(t,tag_gen())
|
|
|
|
end
|
|
|
|
return table.concat(t,";")
|
|
|
|
end
|
2020-12-21 05:22:22 +01:00
|
|
|
|
|
|
|
local pages = {
|
|
|
|
index = {
|
|
|
|
route = "/",
|
|
|
|
name = "home",
|
|
|
|
methods = {
|
|
|
|
GET={}
|
|
|
|
}
|
|
|
|
},
|
|
|
|
paste = {
|
|
|
|
route = "/_paste",
|
|
|
|
name = "post_story",
|
|
|
|
methods = {
|
|
|
|
GET={},
|
2020-12-23 07:02:02 +01:00
|
|
|
POST={
|
|
|
|
title = rng_any,
|
|
|
|
text = rng_any,
|
|
|
|
pasteas = rng_subdomain,
|
2021-01-16 21:58:04 +01:00
|
|
|
markup = rng_markup,
|
|
|
|
tags = rng_any,
|
2020-12-23 07:02:02 +01:00
|
|
|
}
|
2020-12-21 05:22:22 +01:00
|
|
|
}
|
|
|
|
},
|
|
|
|
edit = {
|
|
|
|
route = "/_edit",
|
|
|
|
name = "edit",
|
|
|
|
methods = {
|
2020-12-23 07:02:02 +01:00
|
|
|
GET={
|
|
|
|
story=rng_storyid
|
|
|
|
},
|
|
|
|
POST={
|
2021-01-16 21:58:04 +01:00
|
|
|
story=rng_storyid,
|
2020-12-23 07:02:02 +01:00
|
|
|
title = rng_any,
|
|
|
|
text = rng_any,
|
|
|
|
pasteas = rng_subdomain,
|
|
|
|
markup = rng_markup,
|
|
|
|
tags = rng_any
|
|
|
|
},
|
2020-12-21 05:22:22 +01:00
|
|
|
}
|
|
|
|
},
|
|
|
|
--TODO:bio
|
|
|
|
login = {
|
|
|
|
route = "/_login",
|
|
|
|
name = "login",
|
|
|
|
methods = {
|
|
|
|
GET={},
|
2020-12-23 07:02:02 +01:00
|
|
|
POST={
|
|
|
|
user = rng_subdomain,
|
|
|
|
pass = rng_any
|
|
|
|
},
|
2020-12-21 05:22:22 +01:00
|
|
|
}
|
|
|
|
},
|
|
|
|
claim = {
|
|
|
|
route = "/_claim",
|
|
|
|
name = "claim",
|
|
|
|
methods = {
|
|
|
|
GET = {},
|
2020-12-23 07:02:02 +01:00
|
|
|
POST = {
|
|
|
|
user = rng_subdomain
|
|
|
|
}
|
2020-12-21 05:22:22 +01:00
|
|
|
}
|
|
|
|
},
|
|
|
|
download = {
|
|
|
|
route = "/_download",
|
|
|
|
name = "download",
|
|
|
|
methods = {
|
2020-12-23 07:02:02 +01:00
|
|
|
GET = {
|
|
|
|
story = rng_storyid
|
|
|
|
},
|
2020-12-21 05:22:22 +01:00
|
|
|
}
|
|
|
|
},
|
|
|
|
preview = {
|
|
|
|
route = "/_preview",
|
|
|
|
name = "preview",
|
|
|
|
methods = {
|
2021-01-16 21:58:04 +01:00
|
|
|
POST = {
|
|
|
|
title = rng_any,
|
|
|
|
text = rng_any,
|
|
|
|
markup = rng_markup,
|
|
|
|
tags = maybe(rng_tags)
|
|
|
|
},
|
2020-12-21 05:22:22 +01:00
|
|
|
}
|
|
|
|
},
|
|
|
|
search = {
|
|
|
|
route = "/_search",
|
|
|
|
name = "search",
|
|
|
|
methods = {
|
|
|
|
GET = {},
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2020-12-23 07:02:02 +01:00
|
|
|
local request_stub_m = {}
|
2020-12-21 05:22:22 +01:00
|
|
|
function http_response(req,errcode,str)
|
2020-12-23 07:02:02 +01:00
|
|
|
req.responded = true
|
|
|
|
req.errcode = errcode
|
|
|
|
req.message = str
|
2020-12-21 05:22:22 +01:00
|
|
|
end
|
|
|
|
function http_request_get_host(reqstub)
|
|
|
|
return "localhost:8888"
|
|
|
|
end
|
|
|
|
function http_request_populate_post(reqstub)
|
|
|
|
reqstub.post_populated = true
|
|
|
|
end
|
|
|
|
|
2020-12-23 07:02:02 +01:00
|
|
|
local function fuzz_endpoint(endpoint, parameters)
|
|
|
|
for i = 1,100 do
|
|
|
|
local req = {}
|
|
|
|
for paramtype, params in pairs(parameters) do
|
|
|
|
|
|
|
|
end
|
|
|
|
end
|
|
|
|
return true
|
|
|
|
end
|
|
|
|
|
2021-01-16 21:58:04 +01:00
|
|
|
local function generate_req(tbl)
|
|
|
|
assert(({GET=true,POST=true})[tbl.method])
|
|
|
|
return tbl
|
|
|
|
end
|
|
|
|
local env = {}
|
|
|
|
local smr_mock_env = {
|
|
|
|
--An empty function that gets called to set up databases and do other
|
|
|
|
--startup-time stuff, runs once for each worker process.
|
|
|
|
configure = spy.new(function(...) end),
|
|
|
|
http_request_get_host = spy.new(function(req) return env.host or "test.host" end),
|
|
|
|
http_request_get_path = spy.new(function(req) return env.path or "/" end),
|
|
|
|
http_request_populate_qs = spy.new(function(req) req.qs_populated = true end),
|
|
|
|
http_request_populate_post = spy.new(function(req) req.post_populated = true end),
|
|
|
|
http_populate_multipart_form = spy.new(function(req) req.post_populated = true end),
|
|
|
|
http_argument_get_string = spy.new(function(req,str)
|
|
|
|
assert(
|
|
|
|
req.method == "GET" and req.qs_populated or
|
|
|
|
req.method == "POST" and req.post_populated,[[
|
|
|
|
http_argument_get_string() can only be called after
|
|
|
|
the appropriate populate method has been called, either
|
|
|
|
http_request_populate_qs(req) or
|
|
|
|
http_request_populate_post(req)]]
|
|
|
|
)
|
|
|
|
return req.args[str]
|
|
|
|
end),
|
|
|
|
http_file_get = spy.new(function(req,filename) return "file data" end),
|
|
|
|
http_response = spy.new(function(req,errcode,html) end),
|
|
|
|
http_response_header = spy.new(function(req,name,value) end),
|
|
|
|
http_method_text = spy.new(function(req) return req.method end),
|
|
|
|
http_populate_cookies = spy.new(function(req) req.cookies_populated = true end),
|
|
|
|
http_request_cookie = spy.new(function(req,cookie_name)
|
|
|
|
|
|
|
|
end),
|
2021-02-03 05:30:27 +01:00
|
|
|
http_response_cookie = spy.new(function(req,name,value) req.cookies = {[name] = value} end),
|
2021-01-16 21:58:04 +01:00
|
|
|
log = spy.new(function(priority, message) end),
|
|
|
|
sha3 = spy.new(function(message) return "digest" end),
|
|
|
|
}
|
|
|
|
local sfmt = string.format
|
|
|
|
local string_fmt_override = {
|
|
|
|
format = spy.new(function(fmt,...)
|
|
|
|
local args = {...}
|
|
|
|
for i = 1,#args do
|
|
|
|
if args[i] == nil then
|
|
|
|
args[i] = "nil"
|
|
|
|
end
|
|
|
|
end
|
|
|
|
table.insert(args,1,fmt)
|
|
|
|
return sfmt(unpack(args))
|
|
|
|
end)
|
|
|
|
}
|
|
|
|
setmetatable(string_fmt_override,{__index = string})
|
|
|
|
local smr_override_env = {
|
|
|
|
--Detour assert so we don't actually perform any checks
|
|
|
|
assert = spy.new(function(bool,msg,level) return bool end),
|
|
|
|
--Allow string.format to accept nil as arguments
|
|
|
|
string = string_fmt_override
|
|
|
|
}
|
|
|
|
local smr_mock_env_m = {
|
2021-02-03 05:30:27 +01:00
|
|
|
__index = smr_mock_env,
|
|
|
|
__newindex = function(self,key,value)
|
|
|
|
local setter = debug.getinfo(2)
|
|
|
|
if setter.source ~= "=[C]" and key ~= "configure" then
|
|
|
|
error(string.format(
|
|
|
|
"Tried to create a global %q with value %s\n%s",
|
|
|
|
key,
|
|
|
|
tostring(value),
|
|
|
|
debug.traceback()
|
|
|
|
),2)
|
|
|
|
else
|
|
|
|
rawset(self,key,value)
|
|
|
|
end
|
|
|
|
end
|
2021-01-16 21:58:04 +01:00
|
|
|
}
|
|
|
|
|
2020-12-21 05:22:22 +01:00
|
|
|
describe("smr",function()
|
|
|
|
for name, obj in pairs(pages) do
|
|
|
|
describe("endpoint " .. name,function()
|
|
|
|
for method,parameters in pairs(obj.methods) do
|
|
|
|
describe("method " .. method,function()
|
|
|
|
local fname = string.format("%s_%s",name,string.lower(method))
|
2021-01-16 21:58:04 +01:00
|
|
|
local olds = {}
|
|
|
|
setup(function()
|
|
|
|
setmetatable(_G,smr_mock_env_m)
|
|
|
|
for k,v in pairs(smr_override_env) do
|
|
|
|
olds[k] = _G[k]
|
|
|
|
_G[k] = v
|
|
|
|
end
|
|
|
|
end)
|
|
|
|
teardown(function()
|
|
|
|
setmetatable(_G,{})
|
|
|
|
for k,v in pairs(olds) do
|
|
|
|
_G[k] = v
|
|
|
|
end
|
|
|
|
end)
|
2020-12-21 05:22:22 +01:00
|
|
|
it("should be named appropriately",function()
|
2020-12-23 07:02:02 +01:00
|
|
|
local f = assert(io.open("endpoints/"..fname .. ".lua","r"))
|
2020-12-21 05:22:22 +01:00
|
|
|
end)
|
|
|
|
it("should run without errors",function()
|
2020-12-23 07:02:02 +01:00
|
|
|
require("endpoints." .. fname)
|
2020-12-21 05:22:22 +01:00
|
|
|
end)
|
2021-01-16 21:58:04 +01:00
|
|
|
it("should configure without errors",function()
|
|
|
|
require("endpoints." .. fname)
|
|
|
|
configure()
|
|
|
|
end)
|
2020-12-21 05:22:22 +01:00
|
|
|
it("should return a function",function()
|
2020-12-23 07:02:02 +01:00
|
|
|
local pagefunc = assert(require("endpoints." .. fname))
|
2020-12-21 05:22:22 +01:00
|
|
|
assert(type(pagefunc) == "function")
|
|
|
|
end)
|
2020-12-23 07:02:02 +01:00
|
|
|
it("should call http_response() at some point",function()
|
|
|
|
local pagefunc = require("endpoints." .. fname)
|
2021-02-03 05:30:27 +01:00
|
|
|
for i = 1,1000 do
|
|
|
|
local req = {}
|
|
|
|
req.method = method
|
|
|
|
req.path = obj.route
|
|
|
|
req.args = {}
|
|
|
|
for param_name,param_rng_func in pairs(parameters) do
|
|
|
|
local param = param_rng_func()
|
|
|
|
req.args[param_name] = param
|
|
|
|
end
|
|
|
|
pagefunc(req)
|
|
|
|
assert.spy(smr_mock_env.http_response).was_called()
|
2021-01-16 21:58:04 +01:00
|
|
|
end
|
2020-12-21 05:22:22 +01:00
|
|
|
end)
|
|
|
|
|
|
|
|
end)
|
|
|
|
end
|
|
|
|
end)
|
|
|
|
end
|
|
|
|
end)
|