smr/spec/login_spec.lua

225 lines
6.1 KiB
Lua

_G.spy = spy
local mock_env = require("spec.env_mock")
local rng = require("spec.fuzzgen")
describe("smr login",function()
setup(mock_env.setup)
teardown(mock_env.teardown)
it("should allow someone to claim an account",function()
mock_env.mockdb()
local claim_post = require("endpoints.claim_post")
configure()
claim_req = {
method = "POST",
host = "test.host",
path = "/_claim",
args = {
user = "user"
}
}
claim_post(claim_req)
assert(
claim_req.responsecode == 200,
"Login did not respond with a 200 code"
)
assert(
claim_req.response_headers,
"Login did not have response headers."
)
assert(
claim_req.response_headers["Content-Disposition"],
"Login did not have a Content Disposition header to set filename"
)
assert(
string.find(claim_req.response_headers["Content-Disposition"],"attachment"),
"Login did not mark passfile as an attachment"
)
assert(
claim_req.response_headers["Content-Disposition"]:find(".passfile"),
"Login did not name the returned file with the .passfile extension."
)
assert(
claim_req.response_headers["Content-Type"],
"Login did not respond with a Content-Type"
)
assert(
claim_req.response_headers["Content-Type"] == "application/octet-stream",
"Login did not mark Content-Type correctly (application/octet-stream)"
)
assert(
claim_req.response,
"Login did not return a passfile"
)
end)
it("should give a session cookie when logging in with a user",function()
local claim_post = require("endpoints.claim_post")
local login_post = require("endpoints.login_post")
local config = require("config")
local db = require("db")
local session = require("session")
configure()
local username = rng.subdomain()
local claim_req = {
method = "POST",
host = "test.host",
path = "/_claim",
args = {
user = username
}
}
claim_post(claim_req)
login_req = {
method = "POST",
host = "test.host",
path = "/_login",
args = {
user = username
},
file = {
pass = claim_req.response
}
}
sessionspy = spy.on(session,"start")
login_post(login_req)
assert.spy(sessionspy).was.called()
local code = login_req.responsecode
assert(
code >= 300 and code <= 400,
"Sucessful login should redirect the user, code:" .. tostring(code)
)
assert(
login_req.response_headers,
"Sucessful login should have response headers"
)
assert(
login_req.response_headers["set-cookie"],
"Sucessful login should set a cookie on the client"
)
local cookie = login_req.response_headers["set-cookie"]
local domain_noport = string.match(config.domain,"(.-):?%d*$")
assert(
string.find(cookie,"session="),
"Sucessful login should set a cookie named 'session'"
)
assert(
string.find(cookie,"Domain="..domain_noport),
"Cookies should only be set for the configured domain"
)
assert(
string.find(cookie,"HttpOnly"),
"Cookies should have the HttpOnly flag set"
)
assert(
string.find(cookie,"Secure"),
"Cookies should have the secure flag set"
)
assert(
login_req.response_headers["Location"],
"Sucessful login should redirect to a location"
)
assert(
login_req.response_headers["Location"] == "https://" .. username .. "." .. config.domain,
"Login redirect should get domain from config file"
)
end)
it("should allow logged in users the option of posting under their username",function()
local claim_post = require("endpoints.claim_post")
local login_post = require("endpoints.login_post")
local paste_get = require("endpoints.paste_get")
local paste_post = require("endpoints.paste_post")
local read_get = require("endpoints.read_get")
local db = require("db")
local config = require("config")
config.domain = "test.host"
configure()
local username = rng.subdomain()
local claim_req = {
method = "POST",
host = "test.host",
path = "/_claim",
args = {
user = username
}
}
claim_post(claim_req)
login_req = {
method = "POST",
host = "test.host",
path = "/_login",
args = {
user = username
},
file = {
pass = claim_req.response
}
}
login_post(login_req)
local cookie = login_req.response_headers["set-cookie"]
local sessionid = cookie:match("session=([^;]+)")
local paste_req_get = {
method = "GET",
host = username .. ".test.host",
path = "/_paste",
cookies = {
session = sessionid
}
}
paste_get(paste_req_get)
local option = '<option value="' .. username .. '">' .. username .. '</option>'
assert(
paste_req_get.response:find(option),
"After logging in the user should have an option to "..
"make posts as themselves. Looking for " .. option ..
" but didn't find it in " .. paste_req_get.response
)
local paste_req_post = {
method = "POST",
host = username .. ".test.host",
path = "/_paste",
cookies = {
session = sessionid
},
args = {
title = "post title",
text = "post text",
markup = "plain",
tags = "",
}
}
paste_post(paste_req_post)
for row in db.conn:rows("SELECT COUNT(*) FROM posts") do
assert(row[1] == 1, "Expected exactly 1 post in sample db")
end
local code = paste_req_post.responsecode
assert(code >= 300 and code <= 400, "Should receive a redirect after posting, got:" .. tostring(code))
assert(paste_req_post.response_headers, "Should have received some response headers")
assert(paste_req_post.response_headers.Location, "Should have received a location in response headers")
local redirect = paste_req_post.response_headers.Location:match("(/[^/]*)$")
local read_req_get = {
method = "GET",
host = username .. ".test.host",
path = redirect,
cookies = {
session = sessionid
},
args = {}
}
read_get(read_req_get)
local response = read_req_get.response
assert(
response:find([[post title]]),
"Failed to find post title in response."
)
assert(
response:find('By <a href="https://' .. username .. '.test.host">' .. username .. '</a>'),
"Failed to find the author name after a paste."
)
assert(
response:find([[post text]]),
"Failed to find post text in response."
)
end)
end)