168 lines
3.6 KiB
Gleam
168 lines
3.6 KiB
Gleam
|
import gleeunit
|
||
|
import gleeunit/should
|
||
|
import mist
|
||
|
import gleam/bit_builder
|
||
|
import gleam/http
|
||
|
import gleam/http/request
|
||
|
import gleam/http/response
|
||
|
import gleam/erlang/atom.{Atom}
|
||
|
import gleam/erlang/process
|
||
|
import gleam/uri
|
||
|
import gleam/string
|
||
|
import gleam/list
|
||
|
import finch
|
||
|
import finch/otp
|
||
|
|
||
|
const base_url = "http://localhost:33100"
|
||
|
|
||
|
pub fn main() {
|
||
|
assert Ok(_) =
|
||
|
mist.run_service(
|
||
|
33_100,
|
||
|
fn(req) {
|
||
|
case req.method, request.path_segments(req) {
|
||
|
http.Get, ["ok"] ->
|
||
|
response.new(200)
|
||
|
|> response.set_body(bit_builder.from_string("OK"))
|
||
|
|
||
|
http.Post, ["post"] ->
|
||
|
response.new(500)
|
||
|
|> response.set_body(bit_builder.from_bit_string(req.body))
|
||
|
|
||
|
http.Delete, ["headers"] ->
|
||
|
response.new(200)
|
||
|
|> response.set_body(bit_builder.from_string(string.inspect(
|
||
|
req.headers,
|
||
|
)))
|
||
|
|> response.set_header("x-token", "token-x")
|
||
|
}
|
||
|
},
|
||
|
max_body_limit: 4_000_000,
|
||
|
)
|
||
|
|
||
|
configure_logger([Level(None)])
|
||
|
|
||
|
gleeunit.main()
|
||
|
}
|
||
|
|
||
|
pub fn ok_req_test() {
|
||
|
use <- with_finch()
|
||
|
|
||
|
assert Ok(url) = uri.parse(ok_url())
|
||
|
assert Ok(req) = request.from_uri(url)
|
||
|
let finch_req = finch.build(req, [])
|
||
|
assert Ok(resp) = finch.request(finch_req, server_name())
|
||
|
|
||
|
should.equal(resp.status, 200)
|
||
|
should.equal(resp.body, "OK")
|
||
|
}
|
||
|
|
||
|
pub fn post_data_test() {
|
||
|
let body = "FOOBAR"
|
||
|
|
||
|
use <- with_finch()
|
||
|
|
||
|
assert Ok(url) = uri.parse(post_url())
|
||
|
assert Ok(req) = request.from_uri(url)
|
||
|
let req = request.Request(..req, method: http.Post, body: body)
|
||
|
let finch_req = finch.build(req, [])
|
||
|
assert Ok(resp) = finch.request(finch_req, server_name())
|
||
|
|
||
|
should.equal(resp.status, 500)
|
||
|
should.equal(resp.body, body)
|
||
|
}
|
||
|
|
||
|
pub fn headers_test() {
|
||
|
use <- with_finch()
|
||
|
|
||
|
assert Ok(url) = uri.parse(headers_url())
|
||
|
assert Ok(req) = request.from_uri(url)
|
||
|
let req =
|
||
|
request.Request(
|
||
|
..req,
|
||
|
method: http.Delete,
|
||
|
headers: [
|
||
|
#("accept", "multipart/form-data"),
|
||
|
#("content-type", "formipart/mult-data"),
|
||
|
],
|
||
|
)
|
||
|
let finch_req = finch.build(req, [])
|
||
|
assert Ok(resp) = finch.request(finch_req, server_name())
|
||
|
|
||
|
should.equal(resp.status, 200)
|
||
|
should.be_true(string.contains(
|
||
|
resp.body,
|
||
|
"#(\"accept\", \"multipart/form-data\")",
|
||
|
))
|
||
|
should.be_true(string.contains(
|
||
|
resp.body,
|
||
|
"#(\"content-type\", \"formipart/mult-data\")",
|
||
|
))
|
||
|
should.be_true(list.contains(resp.headers, #("x-token", "token-x")))
|
||
|
}
|
||
|
|
||
|
fn ok_url() {
|
||
|
base_url <> "/ok"
|
||
|
}
|
||
|
|
||
|
fn post_url() {
|
||
|
base_url <> "/post"
|
||
|
}
|
||
|
|
||
|
fn headers_url() {
|
||
|
base_url <> "/headers"
|
||
|
}
|
||
|
|
||
|
fn with_finch(test: fn() -> a) {
|
||
|
let subject: process.Subject(process.Pid) = process.new_subject()
|
||
|
|
||
|
process.start(
|
||
|
fn() {
|
||
|
assert otp.Ok(child) = start_finch()
|
||
|
process.send(subject, child)
|
||
|
process.sleep_forever()
|
||
|
},
|
||
|
False,
|
||
|
)
|
||
|
|
||
|
assert Ok(finch_pid) = process.receive(subject, 1000)
|
||
|
|
||
|
let monitor = process.monitor_process(finch_pid)
|
||
|
let selector =
|
||
|
process.new_selector()
|
||
|
|> process.selecting_process_down(monitor, fn(down) { down })
|
||
|
|
||
|
test()
|
||
|
|
||
|
process.kill(finch_pid)
|
||
|
assert Ok(_) = process.select(selector, 1000)
|
||
|
|
||
|
// We need to wait for all the Finch processes to close, sadly didn't find a
|
||
|
// better way to do this :/
|
||
|
process.sleep(200)
|
||
|
}
|
||
|
|
||
|
fn start_finch() -> otp.OnStart {
|
||
|
let name = server_name()
|
||
|
|
||
|
finch.start_link([otp.Name(name)])
|
||
|
}
|
||
|
|
||
|
fn server_name() -> Atom {
|
||
|
atom.create_from_string("finch_test_server")
|
||
|
}
|
||
|
|
||
|
type LogLevel {
|
||
|
None
|
||
|
}
|
||
|
|
||
|
type LoggerOption {
|
||
|
Level(LogLevel)
|
||
|
}
|
||
|
|
||
|
type LoggerOptions =
|
||
|
List(LoggerOption)
|
||
|
|
||
|
external fn configure_logger(LoggerOptions) -> Nil =
|
||
|
"Elixir.Logger" "configure"
|