Home Posts Post Search Tag Search

LiveView 28 - Chapter 10: Your Turn
Published on: 2026-02-12 Tags: elixir, Blog, Testing, LiveView, Html/CSS, Phoenix

Your Turn

Okay you now know how to do testing for various parts of the liveview. We now want you to test more of the code.

Take care of these next steps • Build a unit test that calls render_component/3 directly. Test that the stateless RatingLive.Index renders the product rating form when no product rating exists. • Write another test to verify that the component renders the correct rating details when ratings do exist. • Test the stateful DemographicLive.Form by writing a test for the parent live view. Ensure that submitting a new demographic form updates the page to display the saved demographic details.

defmodule SurveyLiveTest do
  use PentoWeb.ConnCase
  import Phoenix.LiveViewTest
  import PentoWeb.RatingLive.Index
  import Pento.{CatalogFixtures, AccountsFixtures, SurveyFixtures}
  alias Pento.{Accounts, Survey, Catalog}

  describe "Ratings" do
    setup [:create_user, :create_scope, :create_product, :get_products_with_rating]

    test "rating form no rating", %{products: products, scope: scope} do
      html =
        render_component(&product_list/1, %{
          products: products,
          current_scope: scope
        })

      assert html =~ "rating-form-"
    end

    test "rating form with rating", %{user: user, product: product, scope: scope} do
      create_rating(scope, product)
      products = Catalog.list_products_with_user_rating(user)

      html =
        render_component(&product_list/1, %{
          products: products,
          current_scope: scope
        })

      assert html =~ "★ ★ ★ ★ ☆"
    end
  end

  describe "Demographic" do
    setup [:register_and_log_in_user, :create_scope, :create_product]

    test "demographic form no demographic", %{conn: conn} do
      {:ok, _view, html} = live(conn, "/survey")
      assert html =~ "Please fill out the survey."
    end

    test "demographic form with demographic", %{conn: conn, scope: scope} do
      demographic_fixture(scope)
      {:ok, _view, html} = live(conn, "/survey")
      assert html =~ "1990"
      assert html =~ "male"
      assert html =~ "high school"
    end

    test "demographic form with demographic and ratings", %{
      conn: conn,
      product: product,
      scope: scope
    } do
      demographic_fixture(scope)
      create_rating(scope, product)
      {:ok, _view, html} = live(conn, "/survey")
      assert html =~ "1990"
      assert html =~ "male"
      assert html =~ "high school"
      assert html =~ "★ ★ ★ ★ ☆"
    end
  end

  defp get_products_with_rating(%{user: user}) do
    products = Catalog.list_products_with_user_rating(user)
    %{products: products}
  end

  defp create_rating(scope, product) do
    attrs =
      Enum.into(%{}, %{
        stars: 4,
        product_id: product.id
      })

    Survey.create_rating(scope, attrs)
  end

  defp create_product(%{scope: scope}) do
    product = product_fixture(scope)
    %{product: product}
  end

  defp create_user(_) do
    user = user_fixture()
    %{user: user}
  end

  defp create_scope(%{user: user}) do
    scope = Accounts.get_scope_for_user(user)
    %{scope: scope}
  end
end