finch_gleam/test/finch_gleam_test.gleam

173 lines
3.9 KiB
Gleam
Raw Permalink Normal View History

2023-01-28 14:55:39 +00:00
import gleeunit
import gleeunit/should
2023-12-27 21:44:32 +00:00
import mist.{type Connection}
import gleam/bytes_builder
2023-01-28 14:55:39 +00:00
import gleam/http
import gleam/http/request
import gleam/http/response
2023-12-27 21:44:32 +00:00
import gleam/erlang/atom.{type Atom}
2023-01-28 14:55:39 +00:00
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() {
2023-03-01 18:05:36 +00:00
let assert Ok(_) =
2023-12-27 21:44:32 +00:00
fn(req: request.Request(Connection)) {
case req.method, request.path_segments(req) {
http.Get, ["ok"] ->
response.new(200)
|> response.set_body(mist.Bytes(bytes_builder.from_string("OK")))
http.Post, ["post"] -> {
let assert Ok(req) = mist.read_body(req, 4_000_000)
response.new(500)
|> response.set_body(
mist.Bytes(bytes_builder.from_bit_array(req.body)),
)
2023-01-28 14:55:39 +00:00
}
2023-12-27 21:44:32 +00:00
http.Delete, ["headers"] ->
response.new(200)
|> response.set_body(
mist.Bytes(bytes_builder.from_string(string.inspect(req.headers))),
)
|> response.set_header("x-token", "token-x")
_, _ -> panic
}
}
|> mist.new()
|> mist.port(33_100)
|> mist.start_http()
2023-01-28 14:55:39 +00:00
configure_logger([Level(None)])
gleeunit.main()
}
pub fn ok_req_test() {
use <- with_finch()
2023-03-01 18:05:36 +00:00
let assert Ok(url) = uri.parse(ok_url())
let assert Ok(req) = request.from_uri(url)
2023-01-28 14:55:39 +00:00
let finch_req = finch.build(req, [])
2023-03-01 18:05:36 +00:00
let assert Ok(resp) = finch.request(finch_req, server_name())
2023-01-28 14:55:39 +00:00
should.equal(resp.status, 200)
should.equal(resp.body, "OK")
}
pub fn post_data_test() {
let body = "FOOBAR"
use <- with_finch()
2023-03-01 18:05:36 +00:00
let assert Ok(url) = uri.parse(post_url())
let assert Ok(req) = request.from_uri(url)
2023-01-28 14:55:39 +00:00
let req = request.Request(..req, method: http.Post, body: body)
let finch_req = finch.build(req, [])
2023-03-01 18:05:36 +00:00
let assert Ok(resp) = finch.request(finch_req, server_name())
2023-01-28 14:55:39 +00:00
should.equal(resp.status, 500)
should.equal(resp.body, body)
}
pub fn headers_test() {
use <- with_finch()
2023-03-01 18:05:36 +00:00
let assert Ok(url) = uri.parse(headers_url())
let assert Ok(req) = request.from_uri(url)
2023-01-28 14:55:39 +00:00
let req =
request.Request(
..req,
method: http.Delete,
headers: [
#("accept", "multipart/form-data"),
#("content-type", "formipart/mult-data"),
],
)
let finch_req = finch.build(req, [])
2023-03-01 18:05:36 +00:00
let assert Ok(resp) = finch.request(finch_req, server_name())
2023-01-28 14:55:39 +00:00
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"
}
2023-12-27 21:44:32 +00:00
fn with_finch(real_test: fn() -> a) {
2023-01-28 14:55:39 +00:00
let subject: process.Subject(process.Pid) = process.new_subject()
process.start(
fn() {
2023-03-01 18:05:36 +00:00
let assert otp.Ok(child) = start_finch()
2023-01-28 14:55:39 +00:00
process.send(subject, child)
process.sleep_forever()
},
False,
)
2023-03-01 18:05:36 +00:00
let assert Ok(finch_pid) = process.receive(subject, 1000)
2023-01-28 14:55:39 +00:00
let monitor = process.monitor_process(finch_pid)
let selector =
process.new_selector()
|> process.selecting_process_down(monitor, fn(down) { down })
2023-12-27 21:44:32 +00:00
real_test()
2023-01-28 14:55:39 +00:00
process.kill(finch_pid)
2023-03-01 18:05:36 +00:00
let assert Ok(_) = process.select(selector, 1000)
2023-01-28 14:55:39 +00:00
// 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)
2023-07-22 08:20:05 +00:00
@external(erlang, "Elixir.Logger", "configure")
fn configure_logger(a: LoggerOptions) -> Nil