馃 A practical web framework for Gleam
1import app
2import app/router
3import app/web.{type Context, Context}
4import app/web/people.{Person}
5import gleam/json
6import gleeunit
7import gleeunit/should
8import tiny_database
9import wisp/testing
10
11pub fn main() {
12 gleeunit.main()
13}
14
15fn with_context(testcase: fn(Context) -> t) -> t {
16 // Create a new database connection for this test
17 use db <- tiny_database.with_connection(app.data_directory)
18
19 // Truncate the database so there is no prexisting data from previous tests
20 let assert Ok(_) = tiny_database.truncate(db)
21 let context = Context(db: db)
22
23 // Run the test with the context
24 testcase(context)
25}
26
27pub fn get_unknown_test() {
28 use ctx <- with_context
29 let request = testing.get("/", [])
30 let response = router.handle_request(request, ctx)
31
32 response.status
33 |> should.equal(404)
34}
35
36pub fn list_people_test() {
37 use ctx <- with_context
38
39 let response = router.handle_request(testing.get("/people", []), ctx)
40 response.status
41 |> should.equal(200)
42 response.headers
43 |> should.equal([#("content-type", "application/json; charset=utf-8")])
44
45 // Initially there are no people in the database
46 response
47 |> testing.string_body
48 |> should.equal("{\"people\":[]}")
49
50 // Create a new person
51 let assert Ok(id) = people.save_to_database(ctx.db, Person("Jane", "Red"))
52
53 // The id of the new person is listed by the API
54 let response = router.handle_request(testing.get("/people", []), ctx)
55 response
56 |> testing.string_body
57 |> should.equal("{\"people\":[{\"id\":\"" <> id <> "\"}]}")
58}
59
60pub fn create_person_test() {
61 use ctx <- with_context
62 let json =
63 json.object([
64 #("name", json.string("Lucy")),
65 #("favourite-colour", json.string("Pink")),
66 ])
67 let request = testing.post_json("/people", [], json)
68 let response = router.handle_request(request, ctx)
69
70 response.status
71 |> should.equal(201)
72
73 // The request created a new person in the database
74 let assert Ok([id]) = tiny_database.list(ctx.db)
75
76 response
77 |> testing.string_body
78 |> should.equal("{\"id\":\"" <> id <> "\"}")
79}
80
81pub fn create_person_missing_parameters_test() {
82 use ctx <- with_context
83 let json = json.object([#("name", json.string("Lucy"))])
84 let request = testing.post_json("/people", [], json)
85 let response = router.handle_request(request, ctx)
86
87 response.status
88 |> should.equal(422)
89
90 // Nothing was created in the database
91 let assert Ok([]) = tiny_database.list(ctx.db)
92}
93
94pub fn read_person_test() {
95 use ctx <- with_context
96 let assert Ok(id) = people.save_to_database(ctx.db, Person("Jane", "Red"))
97 let request = testing.get("/people/" <> id, [])
98 let response = router.handle_request(request, ctx)
99
100 response.status
101 |> should.equal(200)
102
103 response
104 |> testing.string_body
105 |> should.equal(
106 "{\"id\":\"" <> id <> "\",\"name\":\"Jane\",\"favourite-colour\":\"Red\"}",
107 )
108}