package aceboot::bodyparser
import std.unittest.*
import std.unittest.testmacro.*
import std.collection.*
import aceboot::web.*
@Test
func test_urlencoded_form() {
let h = HashMap<String, String>()
h.add("content-type", "application/x-www-form-urlencoded")
let ctx = Context("POST", "/login", h)
ctx.setRawBody("user=alice&pass=p%40ss+word&empty=")
let app = App().use(bodyParser())
app.handle(ctx)
@Expect(formValue(ctx, "user").getOrThrow(), "alice")
@Expect(formValue(ctx, "pass").getOrThrow(), "p@ss word")
@Expect(formValue(ctx, "empty").getOrThrow(), "")
@Expect(formValue(ctx, "missing").isNone(), true)
}
@Test
func test_charset_suffix_still_parses() {
let h = HashMap<String, String>()
h.add("content-type", "application/x-www-form-urlencoded; charset=utf-8")
let ctx = Context("POST", "/", h)
ctx.setRawBody("a=1&b=2")
App().use(bodyParser()).handle(ctx)
@Expect(formValue(ctx, "a").getOrThrow(), "1")
@Expect(formValue(ctx, "b").getOrThrow(), "2")
}
@Test
func test_streaming_request_rejects_body_parser() {
let h = HashMap<String, String>()
h.add("content-type", "application/x-www-form-urlencoded")
let ctx = Context("POST", "/upload", h)
ctx.setRequestBodyStream(RequestBodyStream({_: Array<UInt8> => 0}))
App().use(bodyParser()).handle(ctx)
@Expect(ctx.status, 500u16)
@Expect(formValue(ctx, "x").isNone(), true)
}
@Test
func test_no_content_type_skips() {
let ctx = Context.of("GET", "/")
App().use(bodyParser()).handle(ctx)
@Expect(formValue(ctx, "x").isNone(), true)
}
@Test
func test_multipart_form() {
let b = "----TestBoundary"
let body = "--${b}\r\nContent-Disposition: form-data; name=\"user\"\r\n\r\nalice\r\n--${b}\r\nContent-Disposition: form-data; name=\"role\"\r\n\r\nadmin\r\n--${b}--\r\n"
let h = HashMap<String, String>()
h.add("content-type", "multipart/form-data; boundary=${b}")
let ctx = Context("POST", "/upload", h)
ctx.setRawBody(body)
App().use(bodyParser()).handle(ctx)
@Expect(formValue(ctx, "user").getOrThrow(), "alice")
@Expect(formValue(ctx, "role").getOrThrow(), "admin")
@Expect(formValue(ctx, "missing").isNone(), true)
}