From 6dbd3b1079a259128d3c59fb8aeedc54a658c73c Mon Sep 17 00:00:00 2001 From: "kacaii.dev" Date: Mon, 8 Jun 2026 22:40:54 -0300 Subject: [PATCH] login: use the `simulate` module to test the login page --- src/client/page/login.gleam | 2 + test/client_test.gleam | 7 ++ test/client_test/dummy.gleam | 9 +++ test/client_test/page_test/login_test.gleam | 89 +++++++++++---------- 4 files changed, 66 insertions(+), 41 deletions(-) diff --git a/src/client/page/login.gleam b/src/client/page/login.gleam index 39a07b4..98aeb1d 100644 --- a/src/client/page/login.gleam +++ b/src/client/page/login.gleam @@ -158,6 +158,7 @@ pub fn view(model: Model, lang: lang.Language) -> Element(Message) { html.input([ event.on_input(UserTypedEmail), attr.required(True), + attr.id("input-email"), attr.type_("email"), attr.value(model.email), attr.placeholder({ @@ -189,6 +190,7 @@ pub fn view(model: Model, lang: lang.Language) -> Element(Message) { html.input([ event.on_input(UserTypedPassword), attr.required(True), + attr.id("input-password"), attr.type_("password"), attr.value(model.password), attr.placeholder("********"), diff --git a/test/client_test.gleam b/test/client_test.gleam index ecd12ad..bec103a 100644 --- a/test/client_test.gleam +++ b/test/client_test.gleam @@ -1,5 +1,12 @@ +import client.{type Message, type Model} import gleeunit +import lustre/dev/simulate pub fn main() { gleeunit.main() } + +pub fn simulation(init: client.Init) -> simulate.Simulation(Model, Message) { + simulate.application(client.init, client.update, client.view) + |> simulate.start(init) +} diff --git a/test/client_test/dummy.gleam b/test/client_test/dummy.gleam index 5078906..392aef5 100644 --- a/test/client_test/dummy.gleam +++ b/test/client_test/dummy.gleam @@ -7,6 +7,7 @@ import client/session/token import client/user.{type User, User} import client/user/role import gleam/json +import gleam/uri import lustre/effect.{type Effect} pub fn user(role: role.Role) -> User { @@ -41,3 +42,11 @@ pub fn model( let #(page, effect) = page.init(route) #(client.Model(session:, route:, page:, lang: lang.English), effect) } + +pub fn init(initial_route: route.Route) -> client.Init { + let assert Ok(uri) = uri.parse("https://localhost:1234") + let path = route.path(initial_route) + + uri.Uri(..uri, path:) + |> client.Init +} diff --git a/test/client_test/page_test/login_test.gleam b/test/client_test/page_test/login_test.gleam index 5200872..1de0176 100644 --- a/test/client_test/page_test/login_test.gleam +++ b/test/client_test/page_test/login_test.gleam @@ -1,51 +1,58 @@ -import client/language as lang +import client +import client/page import client/page/login +import client/route import client/session import client/user/role +import client_test as testing import client_test/dummy -import gleam/list import lustre/dev/query -import lustre/effect +import lustre/dev/simulate import rsvp -pub fn disable_button_test() -> Nil { - let model = login.empty - let html = login.view(model, lang.English) - - let button = query.id("submit") - let disabled = query.attribute("disabled", "") - - assert query.has(in: html, matching: query.and(button, disabled)) - - Nil -} - -pub fn submit_test() -> Nil { - let model = login.empty - let email = "bfd@email.dev" - let password = "root" - - let sequence = [ - login.UserTypedEmail(email), - login.UserTypedPassword(password), - login.UserClickedSubmit, - ] - - let #(model, _) = { - use acc, msg <- list.fold(over: sequence, from: #(model, effect.none())) - let assert login.Continue(model, _) = login.update(acc.0, msg) - - #(model, effect.none()) - } - - assert model.email == email - assert model.password == password - assert model.loading == True - - let html = login.view(model, lang.English) - let button = query.id("submit") - let busy = query.aria("busy", "true") - assert query.has(in: html, matching: query.and(button, busy)) +pub fn form_submit_test() -> Nil { + let simulation = + route.Login + |> dummy.init + |> testing.simulation + + // values + let email_value = "bfd@email.dev" + let password_value = "root" + let message = + Error(rsvp.NetworkError) + |> client.UserRestoredSession + + // queries + let email = query.id("input-email") |> query.and(query.tag("input")) + let password = query.id("input-password") |> query.and(query.tag("input")) + let submit = query.id("submit") |> query.and(query.tag("button")) + let spinner = query.and(submit, query.aria("busy", "true")) + let disabled = query.and(submit, query.attribute("disabled", "")) + + // simulation + let simulation = + simulate.message(simulation, message) + |> simulate.input(query.element(email), email_value) + |> simulate.input(query.element(password), password_value) + |> simulate.click(query.element(submit)) + + // assert + let model = simulate.model(simulation) + let assert page.Login(page) = model.page + + assert page.email == email_value + assert page.password == password_value + assert page.loading as "page is loading" + assert model.session == session.Guest + + assert simulate.view(simulation) + |> query.has(spinner) + as "spinner is rendered" + + assert simulate.view(simulation) + |> query.has(disabled) + as "submit button is disabled" Nil } -- 2.51.2