smr/spec/pages_sanity_spec.lua

287 lines
6.9 KiB
Lua

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
local rng_any = generate_str(1024,characters("."))
local rng_subdomain = generate_str(30,characters("[0-9a-z]"))
local rng_storyname = generate_str(10,"[a-zA-Z0-9$+!*'(),-]")
local rng_storyid = function() return tostring(math.random(1,10)) end
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
local pages = {
index = {
route = "/",
name = "home",
methods = {
GET={}
}
},
paste = {
route = "/_paste",
name = "post_story",
methods = {
GET={},
POST={
title = rng_any,
text = rng_any,
pasteas = rng_subdomain,
markup = rng_markup,
tags = rng_any,
}
}
},
edit = {
route = "/_edit",
name = "edit",
methods = {
GET={
story=rng_storyid
},
POST={
story=rng_storyid,
title = rng_any,
text = rng_any,
pasteas = rng_subdomain,
markup = rng_markup,
tags = rng_any
},
}
},
--TODO:bio
login = {
route = "/_login",
name = "login",
methods = {
GET={},
POST={
user = rng_subdomain,
pass = rng_any
},
}
},
claim = {
route = "/_claim",
name = "claim",
methods = {
GET = {},
POST = {
user = rng_subdomain
}
}
},
download = {
route = "/_download",
name = "download",
methods = {
GET = {
story = rng_storyid
},
}
},
preview = {
route = "/_preview",
name = "preview",
methods = {
POST = {
title = rng_any,
text = rng_any,
markup = rng_markup,
tags = maybe(rng_tags)
},
}
},
search = {
route = "/_search",
name = "search",
methods = {
GET = {},
}
}
}
local request_stub_m = {}
function http_response(req,errcode,str)
req.responded = true
req.errcode = errcode
req.message = str
end
function http_request_get_host(reqstub)
return "localhost:8888"
end
function http_request_populate_post(reqstub)
reqstub.post_populated = true
end
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
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),
http_response_cookie = spy.new(function(req,name,value) req.cookies = {[name] = value} end),
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 = {
__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
}
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))
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)
it("should be named appropriately",function()
local f = assert(io.open("endpoints/"..fname .. ".lua","r"))
end)
it("should run without errors",function()
require("endpoints." .. fname)
end)
it("should configure without errors",function()
require("endpoints." .. fname)
configure()
end)
it("should return a function",function()
local pagefunc = assert(require("endpoints." .. fname))
assert(type(pagefunc) == "function")
end)
it("should call http_response() at some point #slow",function()
local pagefunc = require("endpoints." .. fname)
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()
end
end)
end)
end
end)
end
end)