symbolboxer

symbolboxer

From Ruby to Elixir: Broken test for MessageController (182)

Hi! I believe I’ve found an erratum.

tl;dr: MessageController/create does not add changeset validation errors to the flash, which breaks one of its tests.

On page 182 we write this test:

test "invalid params is rejected", %{conn: conn} do
  conn = post(conn, ~p"/messages/new", %{}) assert html_response(conn, 200) =~
             Plug.HTML.html_escape("can't be blank")
end

Which resulted in this error when I ran it:

1) test POST /messages/new invalid params is rejected (PhoneAppWeb.MessageControllerTest)
     test/phone_app_web/controllers/message_controller_test.exs:34
     Assertion with =~ failed
     code:  assert html_response(conn, 200) =~ Plug.HTML.html_escape("can't be blank")
     left:  "<!DOCTYPE html>\n<html lang=\"en\" class=\"[scrollbar-gutter:stable]\">\n  <head>
     [rest of page truncated]
     right: "can&#39;t be blank"

After some valuable Elixir debugging practice, I believe I have the cause. The test in this case is looking for a “can’t be blank” error somewhere on the page. In MessageController/create, there is code that takes errors and puts them into the flash on line 48. However, that code is never reached because changeset validation happens on line 43 and the error shoots us down to line 55. That error handler doesn’t do anything specifically with the error. It passes the changeset to the view to render, but I don’t see where in the view it would display the error. Thus, the validation error doesn’t appear on the rendered view, and the test can’t find it.

Thanks, and just let me know if I’ve gotten something wrong.

Marked As Solved

sb8244

sb8244

Author of From Ruby to Elixir and Real-Time Phoenix

Thanks for sharing that. I took a look at CoreComponents.input and found the definition was slightly varied. I changed this line:

    # used to be:
    # errors =  if Phoenix.Component.used_input?(field), do: field.errors, else: []
    errors = field.errors

and the test passes. This was a change in the latest implementation of CoreComponents, hence the difference.

Now, to get this test passing without modifying the above line, I had to tweak the test to pass in blank inputs:

    test "invalid params is rejected", %{conn: conn} do
      params = %{message: %{to: "", body: ""}}
      conn = post(conn, ~p"/messages/new", params)

      assert html_response(conn, 200) =~
               Plug.HTML.html_escape("can't be blank")
    end

We can look through the implementation of used_input? to see why this works. By passing in the data, the form.params field contains the input field, so it counts as “used”

Where Next?

Popular Pragmatic Bookshelf topics Top

belgoros
Following the steps described in Chapter 6 of the book, I’m stuck with running the migration as described on page 84: bundle exec sequel...
New
jeffmcompsci
Title: Design and Build Great Web APIs - typo “https://company-atk.herokuapp.com/2258ie4t68jv” (page 19, third bullet in URL list) Typo:...
New
mikecargal
Title: Hands-On Rust (Chap 8 (Adding a Heads Up Display) It looks like ​.with_simple_console_no_bg​(SCREEN_WIDTH*2, SCREEN_HEIGHT*2...
New
joepstender
The generated iex result below should list products instead of product for the metadata. (page 67) iex&gt; product = %Product{} %Pento....
New
New
jgchristopher
“The ProductLive.Index template calls a helper function, live_component/3, that in turn calls on the modal component. ” Excerpt From: Br...
New
digitalbias
Title: Build a Weather Station with Elixir and Nerves: Problem connecting to Postgres with Grafana on (page 64) If you follow the defau...
New
brunogirin
When running tox for the first time, I got the following error: ERROR: InterpreterNotFound: python3.10 I realised that I was running ...
New
New
dsmith42
Hey there, I’m enjoying this book and have learned a few things alredayd. However, in Chapter 4 I believe we are meant to see the “&gt;...
New

Other popular topics Top

PragmaticBookshelf
Ruby, Io, Prolog, Scala, Erlang, Clojure, Haskell. With Seven Languages in Seven Weeks, by Bruce A. Tate, you’ll go beyond the syntax—and...
New
siddhant3030
I’m thinking of buying a monitor that I can rotate to use as a vertical monitor? Also, I want to know if someone is using it for program...
New
PragmaticBookshelf
From finance to artificial intelligence, genetic algorithms are a powerful tool with a wide array of applications. But you don't need an ...
New
AstonJ
If you get Can't find emacs in your PATH when trying to install Doom Emacs on your Mac you… just… need to install Emacs first! :lol: bre...
New
New
PragmaticBookshelf
Build modern server-driven web applications using htmx. Whatever programming language you use, you’ll write less (and cleaner) code. ...
New
AnfaengerAlex
Hello, I’m a beginner in Android development and I’m facing an issue with my project setup. In my build.gradle.kts file, I have the foll...
New
AstonJ
This is a very quick guide, you just need to: Download LM Studio: https://lmstudio.ai/ Click on search Type DeepSeek, then select the o...
New
PragmaticBookshelf
Use advanced functional programming principles, practical Domain-Driven Design techniques, and production-ready Elixir code to build scal...
New
PragmaticBookshelf
Quickly turn complex problems into simple, working solutions using functional programming, safe concurrency, and the expressive tools of ...
New

Sub Categories: