172 lines
3.9 KiB
Gleam
172 lines
3.9 KiB
Gleam
import gleeunit
|
|
import gleeunit/should
|
|
import mist.{type Connection}
|
|
import gleam/bytes_builder
|
|
import gleam/http
|
|
import gleam/http/request
|
|
import gleam/http/response
|
|
import gleam/erlang/atom.{type 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() {
|
|
let assert Ok(_) =
|
|
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)),
|
|
)
|
|
}
|
|
|
|
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()
|
|
|
|
configure_logger([Level(None)])
|
|
|
|
gleeunit.main()
|
|
}
|
|
|
|
pub fn ok_req_test() {
|
|
use <- with_finch()
|
|
|
|
let assert Ok(url) = uri.parse(ok_url())
|
|
let assert Ok(req) = request.from_uri(url)
|
|
let finch_req = finch.build(req, [])
|
|
let 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()
|
|
|
|
let assert Ok(url) = uri.parse(post_url())
|
|
let assert Ok(req) = request.from_uri(url)
|
|
let req = request.Request(..req, method: http.Post, body: body)
|
|
let finch_req = finch.build(req, [])
|
|
let 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()
|
|
|
|
let assert Ok(url) = uri.parse(headers_url())
|
|
let 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, [])
|
|
let 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(real_test: fn() -> a) {
|
|
let subject: process.Subject(process.Pid) = process.new_subject()
|
|
|
|
process.start(
|
|
fn() {
|
|
let assert otp.Ok(child) = start_finch()
|
|
process.send(subject, child)
|
|
process.sleep_forever()
|
|
},
|
|
False,
|
|
)
|
|
|
|
let 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 })
|
|
|
|
real_test()
|
|
|
|
process.kill(finch_pid)
|
|
let 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(erlang, "Elixir.Logger", "configure")
|
|
fn configure_logger(a: LoggerOptions) -> Nil
|