finch_gleam/test/finch_gleam_test.gleam

168 lines
3.6 KiB
Gleam
Raw Normal View History

2023-01-28 14:55:39 +00:00
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"