strawboss/src/test/nim/tserver.nim
2017-05-08 12:41:46 -05:00

154 lines
5.2 KiB
Nim

import asyncdispatch, httpclient, json, os, osproc, sequtils, strutils,
tempfile, times, unittest
from langutils import sameContents
import ../../main/nim/strawbosspkg/configuration
import ../../main/nim/strawbosspkg/server
import ../../main/nim/strawbosspkg/private/util
# test helpers
proc newAuthenticatedHttpClient(apiBase, uname, pwd: string): HttpClient =
result = newHttpClient()
let authResp = result.post(apiBase & "/auth-token", $(%*{"username": uname, "password": pwd}))
assert authResp.status.startsWith("200")
result.headers = newHttpHeaders({"Authorization": "Bearer " & parseJson(authResp.body).getStr})
let apiBase = "http://localhost:8180/api"
let cfgFilePath = "src/test/json/strawboss.config.json"
let cfg = loadStrawBossConfig(cfgFilePath)
let testuser = UserRef( # note: needs to correspond to an actual user
name: "bob@builder.com",
hashedPwd: "$2a$11$lVZ9U4optQMhzPh0E9A7Yu6XndXblUF3gCa.zmEvJy4F.4C4718b.")
suite "strawboss server":
# suite setup code
let serverProcess = startProcess("./strawboss", ".",
@["serve", "-c", cfgFilePath], loadEnv(), {poUsePath})
let http = newHttpClient()
# give the server time to spin up
sleep(100)
## UNIT TESTS
test "validate hashed pwd":
check validatePwd(testuser, "password")
test "detect invalid pwds":
check(not validatePwd(testuser, "Password"))
test "make and extract a JWT token from a session":
let session = newSession(testuser)
let tok = toJWT(cfg, session)
check fromJWT(cfg, tok) == session
test "ping":
let resp = http.get(apiBase & "/ping")
check:
resp.status.startsWith("200")
resp.body == "\"pong\""
test "fail auth":
let resp = http.post(apiBase & "/auth-token",
$(%*{"username": "bob@builder.com", "password": "notpassword"}))
check resp.status.startsWith("401")
test "auth":
let resp = http.post(apiBase & "/auth-token",
$(%*{"username": "bob@builder.com", "password": "password"}))
check resp.status.startsWith("200")
test "verify valid auth token":
let authHttp = newAuthenticatedHttpClient(apiBase, "bob@builder.com", "password")
let resp = authHttp.get(apiBase & "/verify-auth")
check resp.status.startsWith("200")
test "verify fails when no auth token is given":
let resp = http.get(apiBase & "/verify-auth")
check resp.status.startsWith("401")
test "verify fails when invalid auth token is given":
let http1 = newHttpClient()
http1.headers = newHttpHeaders({"Authorization": "Bearer nope"})
let resp = http1.get(apiBase & "/verify-auth")
check resp.status.startsWith("401")
test "fail to get projects when not authenticated":
let resp = http.get(apiBase & "/projects")
check resp.status.startsWith("401")
test "get projects":
let authHttp = newAuthenticatedHttpClient(apiBase, "bob@builder.com", "password")
let resp = authHttp.get(apiBase & "/projects")
check resp.status.startsWith("200")
let projects: seq[ProjectDef] = parseJson(resp.body).getElems.mapIt(parseProjectDef(it))
check sameContents(projects, cfg.projects)
# suite tear-down
# give the server time to spin down but kill it after that
discard newAsyncHttpClient().post(apiBase & "/service/debug/stop")
sleep(100)
if serverProcess.running: kill(serverProcess)
suite "strawboss server continued":
setup:
let tmpArtifactsDir = mkdtemp()
let (_, tmpCfgPath) = mkstemp()
var newCfg = cfg
newCfg.artifactsRepo = tmpArtifactsDir
writeFile(tmpCfgPath, $newCfg)
let serverProcess = startProcess("./strawboss", ".",
@["serve", "-c", tmpCfgPath], loadEnv(), {poUsePath})
# give the server time to spin up
sleep(100)
teardown:
discard newAsyncHttpClient().post(apiBase & "/service/debug/stop")
removeDir(tmpArtifactsDir)
removeFile(tmpCfgPath)
# give the server time to spin down but kill it after that
sleep(100)
if serverProcess.running: kill(serverProcess)
test "handle missing project configuration":
let http = newAuthenticatedHttpClient(apibase, "bob@builder.com", "password")
let resp = http.get(apiBase & "/projects/" & cfg.projects[0].name)
check resp.status.startsWith("404")
test "gives 404 when no versions built":
let http = newAuthenticatedHttpClient(apibase, "bob@builder.com", "password")
let resp = http.get(apiBase & "/projects/" & cfg.projects[0].name & "/versions")
check resp.status.startsWith("404")
test "GET /api/project/@projectName/versions":
let projArtifactsDir = tmpArtifactsDir & "/" & cfg.projects[0].name
let expectedVersions = @["alpha", "beta", "1.0.0", "1.0.1"]
# Touch configuration files
createDir(projArtifactsDir)
for v in expectedVersions:
var f: File
check open(f, projArtifactsDir & "/configuration." & v & ".json", fmWrite)
close(f)
let http = newAuthenticatedHttpClient(apibase, "bob@builder.com", "password")
let resp = http.get(apiBase & "/project/" & cfg.projects[0].name & "/versions")
let returnedVersions = parseJson(resp.body).getElems.mapIt(it.getStr)
check sameContents(expectedVersions, returnedVersions)
# Last-chance catch to kill the server in case some test err'ed and didn't
# reach it's teardown handler
discard newAsyncHttpClient().post(apiBase & "/service/debug/stop")