diff --git a/lib/wild/book_reads.ex b/lib/wild/book_reads.ex
new file mode 100644
index 0000000..aba8b30
--- /dev/null
+++ b/lib/wild/book_reads.ex
@@ -0,0 +1,104 @@
+defmodule Wild.BookReads do
+ @moduledoc """
+ The BookReads context.
+ """
+
+ import Ecto.Query, warn: false
+ alias Wild.Repo
+
+ alias Wild.BookReads.BookRead
+
+ @doc """
+ Returns the list of book_reads.
+
+ ## Examples
+
+ iex> list_book_reads()
+ [%BookRead{}, ...]
+
+ """
+ def list_book_reads do
+ Repo.all(BookRead)
+ end
+
+ @doc """
+ Gets a single book_read.
+
+ Raises `Ecto.NoResultsError` if the Book read does not exist.
+
+ ## Examples
+
+ iex> get_book_read!(123)
+ %BookRead{}
+
+ iex> get_book_read!(456)
+ ** (Ecto.NoResultsError)
+
+ """
+ def get_book_read!(id), do: Repo.get!(BookRead, id)
+
+ @doc """
+ Creates a book_read.
+
+ ## Examples
+
+ iex> create_book_read(%{field: value})
+ {:ok, %BookRead{}}
+
+ iex> create_book_read(%{field: bad_value})
+ {:error, %Ecto.Changeset{}}
+
+ """
+ def create_book_read(attrs \\ %{}) do
+ %BookRead{}
+ |> BookRead.changeset(attrs)
+ |> Repo.insert()
+ end
+
+ @doc """
+ Updates a book_read.
+
+ ## Examples
+
+ iex> update_book_read(book_read, %{field: new_value})
+ {:ok, %BookRead{}}
+
+ iex> update_book_read(book_read, %{field: bad_value})
+ {:error, %Ecto.Changeset{}}
+
+ """
+ def update_book_read(%BookRead{} = book_read, attrs) do
+ book_read
+ |> BookRead.changeset(attrs)
+ |> Repo.update()
+ end
+
+ @doc """
+ Deletes a book_read.
+
+ ## Examples
+
+ iex> delete_book_read(book_read)
+ {:ok, %BookRead{}}
+
+ iex> delete_book_read(book_read)
+ {:error, %Ecto.Changeset{}}
+
+ """
+ def delete_book_read(%BookRead{} = book_read) do
+ Repo.delete(book_read)
+ end
+
+ @doc """
+ Returns an `%Ecto.Changeset{}` for tracking book_read changes.
+
+ ## Examples
+
+ iex> change_book_read(book_read)
+ %Ecto.Changeset{data: %BookRead{}}
+
+ """
+ def change_book_read(%BookRead{} = book_read, attrs \\ %{}) do
+ BookRead.changeset(book_read, attrs)
+ end
+end
diff --git a/lib/wild/book_reads/book_read.ex b/lib/wild/book_reads/book_read.ex
new file mode 100644
index 0000000..6fe07f8
--- /dev/null
+++ b/lib/wild/book_reads/book_read.ex
@@ -0,0 +1,24 @@
+defmodule Wild.BookReads.BookRead do
+ use Ecto.Schema
+ import Ecto.Changeset
+
+ @primary_key false
+ schema "book_reads" do
+ field :progress, :integer
+ field :rating, :integer
+ field :thoughts, :string
+ field :read_start, :utc_datetime
+ field :read_finish, :utc_datetime
+ field :user_id, :id, primary_key: true
+ field :book_id, :id, primary_key: true
+
+ timestamps(type: :utc_datetime)
+ end
+
+ @doc false
+ def changeset(book_read, attrs) do
+ book_read
+ |> cast(attrs, [:rating, :thoughts, :read_start, :read_finish, :progress])
+ |> validate_required([:rating, :thoughts, :read_start, :read_finish, :progress])
+ end
+end
diff --git a/lib/wild/books/author.ex b/lib/wild/books/author.ex
new file mode 100644
index 0000000..f327f85
--- /dev/null
+++ b/lib/wild/books/author.ex
@@ -0,0 +1,21 @@
+defmodule Wild.Books.Author do
+ use Ecto.Schema
+ import Ecto.Changeset
+
+ schema "authors" do
+ field :name, :string
+ field :country, :string
+ field :bio, :string
+ field :year_born, :string
+ field :year_died, :string
+
+ timestamps(type: :utc_datetime)
+ end
+
+ @doc false
+ def changeset(author, attrs) do
+ author
+ |> cast(attrs, [:name, :country, :bio, :year_born, :year_died])
+ |> validate_required([:name, :country, :bio, :year_born, :year_died])
+ end
+end
diff --git a/lib/wild/books/book.ex b/lib/wild/books/book.ex
new file mode 100644
index 0000000..c2ba8fb
--- /dev/null
+++ b/lib/wild/books/book.ex
@@ -0,0 +1,20 @@
+defmodule Wild.Books.Book do
+ use Ecto.Schema
+ import Ecto.Changeset
+
+ schema "books" do
+ field :title, :string
+ field :blurb, :string
+ field :publication_year, :string
+ field :author_id, :id
+
+ timestamps(type: :utc_datetime)
+ end
+
+ @doc false
+ def changeset(book, attrs) do
+ book
+ |> cast(attrs, [:title, :blurb, :publication_year])
+ |> validate_required([:title, :blurb, :publication_year])
+ end
+end
diff --git a/lib/wild_web/live/book_read_live/form_component.ex b/lib/wild_web/live/book_read_live/form_component.ex
new file mode 100644
index 0000000..9d7be8c
--- /dev/null
+++ b/lib/wild_web/live/book_read_live/form_component.ex
@@ -0,0 +1,86 @@
+defmodule WildWeb.BookReadLive.FormComponent do
+ use WildWeb, :live_component
+
+ alias Wild.BookReads
+
+ @impl true
+ def render(assigns) do
+ ~H"""
+
+ <.header>
+ {@title}
+ <:subtitle>Use this form to manage book_read records in your database.
+
+
+ <.simple_form
+ for={@form}
+ id="book_read-form"
+ phx-target={@myself}
+ phx-change="validate"
+ phx-submit="save"
+ >
+ <.input field={@form[:rating]} type="number" label="Rating" />
+ <.input field={@form[:thoughts]} type="text" label="Thoughts" />
+ <.input field={@form[:read_start]} type="datetime-local" label="Read start" />
+ <.input field={@form[:read_finish]} type="datetime-local" label="Read finish" />
+ <.input field={@form[:progress]} type="number" label="Progress" />
+ <:actions>
+ <.button phx-disable-with="Saving...">Save Book read
+
+
+
+ """
+ end
+
+ @impl true
+ def update(%{book_read: book_read} = assigns, socket) do
+ {:ok,
+ socket
+ |> assign(assigns)
+ |> assign_new(:form, fn ->
+ to_form(BookReads.change_book_read(book_read))
+ end)}
+ end
+
+ @impl true
+ def handle_event("validate", %{"book_read" => book_read_params}, socket) do
+ changeset = BookReads.change_book_read(socket.assigns.book_read, book_read_params)
+ {:noreply, assign(socket, form: to_form(changeset, action: :validate))}
+ end
+
+ def handle_event("save", %{"book_read" => book_read_params}, socket) do
+ save_book_read(socket, socket.assigns.action, book_read_params)
+ end
+
+ defp save_book_read(socket, :edit, book_read_params) do
+ case BookReads.update_book_read(socket.assigns.book_read, book_read_params) do
+ {:ok, book_read} ->
+ notify_parent({:saved, book_read})
+
+ {:noreply,
+ socket
+ |> put_flash(:info, "Book read updated successfully")
+ |> push_patch(to: socket.assigns.patch)}
+
+ {:error, %Ecto.Changeset{} = changeset} ->
+ {:noreply, assign(socket, form: to_form(changeset))}
+ end
+ end
+
+ defp save_book_read(socket, :new, book_read_params) do
+ case BookReads.create_book_read(book_read_params) do
+ {:ok, book_read} ->
+ notify_parent({:saved, book_read})
+
+ {:noreply,
+ socket
+ |> put_flash(:info, "Book read created successfully")
+ |> push_patch(to: socket.assigns.patch)}
+
+ {:error, %Ecto.Changeset{} = changeset} ->
+ {:noreply, assign(socket, form: to_form(changeset))}
+ end
+ end
+
+ defp notify_parent(msg), do: send(self(), {__MODULE__, msg})
+end
diff --git a/lib/wild_web/live/book_read_live/index.ex b/lib/wild_web/live/book_read_live/index.ex
new file mode 100644
index 0000000..dccc6d9
--- /dev/null
+++ b/lib/wild_web/live/book_read_live/index.ex
@@ -0,0 +1,47 @@
+defmodule WildWeb.BookReadLive.Index do
+ use WildWeb, :live_view
+
+ alias Wild.BookReads
+ alias Wild.BookReads.BookRead
+
+ @impl true
+ def mount(_params, _session, socket) do
+ {:ok, stream(socket, :book_reads, BookReads.list_book_reads())}
+ end
+
+ @impl true
+ def handle_params(params, _url, socket) do
+ {:noreply, apply_action(socket, socket.assigns.live_action, params)}
+ end
+
+ defp apply_action(socket, :edit, %{"id" => id}) do
+ socket
+ |> assign(:page_title, "Edit Book read")
+ |> assign(:book_read, BookReads.get_book_read!(id))
+ end
+
+ defp apply_action(socket, :new, _params) do
+ socket
+ |> assign(:page_title, "New Book read")
+ |> assign(:book_read, %BookRead{})
+ end
+
+ defp apply_action(socket, :index, _params) do
+ socket
+ |> assign(:page_title, "Listing Book reads")
+ |> assign(:book_read, nil)
+ end
+
+ @impl true
+ def handle_info({WildWeb.BookReadLive.FormComponent, {:saved, book_read}}, socket) do
+ {:noreply, stream_insert(socket, :book_reads, book_read)}
+ end
+
+ @impl true
+ def handle_event("delete", %{"id" => id}, socket) do
+ book_read = BookReads.get_book_read!(id)
+ {:ok, _} = BookReads.delete_book_read(book_read)
+
+ {:noreply, stream_delete(socket, :book_reads, book_read)}
+ end
+end
diff --git a/lib/wild_web/live/book_read_live/index.html.heex b/lib/wild_web/live/book_read_live/index.html.heex
new file mode 100644
index 0000000..6d9c3d5
--- /dev/null
+++ b/lib/wild_web/live/book_read_live/index.html.heex
@@ -0,0 +1,45 @@
+<.header>
+ Listing Book reads
+ <:actions>
+ <.link patch={~p"/book_reads/new"}>
+ <.button>New Book read
+
+
+
+
+<.table
+ id="book_reads"
+ rows={@streams.book_reads}
+ row_click={fn {_id, book_read} -> JS.navigate(~p"/book_reads/#{book_read}") end}
+>
+ <:col :let={{_id, book_read}} label="Rating">{book_read.rating}
+ <:col :let={{_id, book_read}} label="Thoughts">{book_read.thoughts}
+ <:col :let={{_id, book_read}} label="Read start">{book_read.read_start}
+ <:col :let={{_id, book_read}} label="Read finish">{book_read.read_finish}
+ <:col :let={{_id, book_read}} label="Progress">{book_read.progress}
+ <:action :let={{_id, book_read}}>
+
+ <.link navigate={~p"/book_reads/#{book_read}"}>Show
+
+ <.link patch={~p"/book_reads/#{book_read}/edit"}>Edit
+
+ <:action :let={{id, book_read}}>
+ <.link
+ phx-click={JS.push("delete", value: %{id: book_read.id}) |> hide("##{id}")}
+ data-confirm="Are you sure?"
+ >
+ Delete
+
+
+
+
+<.modal :if={@live_action in [:new, :edit]} id="book_read-modal" show on_cancel={JS.patch(~p"/book_reads")}>
+ <.live_component
+ module={WildWeb.BookReadLive.FormComponent}
+ id={@book_read.id || :new}
+ title={@page_title}
+ action={@live_action}
+ book_read={@book_read}
+ patch={~p"/book_reads"}
+ />
+
diff --git a/lib/wild_web/live/book_read_live/show.ex b/lib/wild_web/live/book_read_live/show.ex
new file mode 100644
index 0000000..ed329c8
--- /dev/null
+++ b/lib/wild_web/live/book_read_live/show.ex
@@ -0,0 +1,21 @@
+defmodule WildWeb.BookReadLive.Show do
+ use WildWeb, :live_view
+
+ alias Wild.BookReads
+
+ @impl true
+ def mount(_params, _session, socket) do
+ {:ok, socket}
+ end
+
+ @impl true
+ def handle_params(%{"id" => id}, _, socket) do
+ {:noreply,
+ socket
+ |> assign(:page_title, page_title(socket.assigns.live_action))
+ |> assign(:book_read, BookReads.get_book_read!(id))}
+ end
+
+ defp page_title(:show), do: "Show Book read"
+ defp page_title(:edit), do: "Edit Book read"
+end
diff --git a/lib/wild_web/live/book_read_live/show.html.heex b/lib/wild_web/live/book_read_live/show.html.heex
new file mode 100644
index 0000000..af74354
--- /dev/null
+++ b/lib/wild_web/live/book_read_live/show.html.heex
@@ -0,0 +1,30 @@
+<.header>
+ Book read {@book_read.id}
+ <:subtitle>This is a book_read record from your database.
+ <:actions>
+ <.link patch={~p"/book_reads/#{@book_read}/show/edit"} phx-click={JS.push_focus()}>
+ <.button>Edit book_read
+
+
+
+
+<.list>
+ <:item title="Rating">{@book_read.rating}
+ <:item title="Thoughts">{@book_read.thoughts}
+ <:item title="Read start">{@book_read.read_start}
+ <:item title="Read finish">{@book_read.read_finish}
+ <:item title="Progress">{@book_read.progress}
+
+
+<.back navigate={~p"/book_reads"}>Back to book_reads
+
+<.modal :if={@live_action == :edit} id="book_read-modal" show on_cancel={JS.patch(~p"/book_reads/#{@book_read}")}>
+ <.live_component
+ module={WildWeb.BookReadLive.FormComponent}
+ id={@book_read.id}
+ title={@page_title}
+ action={@live_action}
+ book_read={@book_read}
+ patch={~p"/book_reads/#{@book_read}"}
+ />
+
diff --git a/priv/repo/migrations/20250109091315_create_authors.exs b/priv/repo/migrations/20250109091315_create_authors.exs
new file mode 100644
index 0000000..62bd4bb
--- /dev/null
+++ b/priv/repo/migrations/20250109091315_create_authors.exs
@@ -0,0 +1,15 @@
+defmodule Wild.Repo.Migrations.CreateAuthors do
+ use Ecto.Migration
+
+ def change do
+ create table(:authors) do
+ add :name, :string
+ add :country, :string
+ add :bio, :string
+ add :year_born, :string
+ add :year_died, :string
+
+ timestamps(type: :utc_datetime)
+ end
+ end
+end
diff --git a/priv/repo/migrations/20250109091420_create_books.exs b/priv/repo/migrations/20250109091420_create_books.exs
new file mode 100644
index 0000000..72b3827
--- /dev/null
+++ b/priv/repo/migrations/20250109091420_create_books.exs
@@ -0,0 +1,16 @@
+defmodule Wild.Repo.Migrations.CreateBooks do
+ use Ecto.Migration
+
+ def change do
+ create table(:books) do
+ add :title, :string
+ add :blurb, :string
+ add :publication_year, :string
+ add :author_id, references(:authors, on_delete: :nothing)
+
+ timestamps(type: :utc_datetime)
+ end
+
+ create index(:books, [:author_id])
+ end
+end
diff --git a/priv/repo/migrations/20250109103126_create_book_reads.exs b/priv/repo/migrations/20250109103126_create_book_reads.exs
new file mode 100644
index 0000000..12525f1
--- /dev/null
+++ b/priv/repo/migrations/20250109103126_create_book_reads.exs
@@ -0,0 +1,20 @@
+defmodule Wild.Repo.Migrations.CreateBookReads do
+ use Ecto.Migration
+
+ def change do
+ create table(:book_reads) do
+ add :rating, :integer
+ add :thoughts, :string
+ add :read_start, :utc_datetime
+ add :read_finish, :utc_datetime
+ add :progress, :integer
+ add :user_id, references(:users, on_delete: :nothing)
+ add :book_id, references(:books, on_delete: :nothing)
+
+ timestamps(type: :utc_datetime)
+ end
+
+ create index(:book_reads, [:user_id])
+ create index(:book_reads, [:book_id])
+ end
+end
diff --git a/test/support/fixtures/book_reads_fixtures.ex b/test/support/fixtures/book_reads_fixtures.ex
new file mode 100644
index 0000000..3ea7dc8
--- /dev/null
+++ b/test/support/fixtures/book_reads_fixtures.ex
@@ -0,0 +1,24 @@
+defmodule Wild.BookReadsFixtures do
+ @moduledoc """
+ This module defines test helpers for creating
+ entities via the `Wild.BookReads` context.
+ """
+
+ @doc """
+ Generate a book_read.
+ """
+ def book_read_fixture(attrs \\ %{}) do
+ {:ok, book_read} =
+ attrs
+ |> Enum.into(%{
+ progress: 42,
+ rating: 42,
+ read_finish: ~U[2025-01-08 10:31:00Z],
+ read_start: ~U[2025-01-08 10:31:00Z],
+ thoughts: "some thoughts"
+ })
+ |> Wild.BookReads.create_book_read()
+
+ book_read
+ end
+end
diff --git a/test/wild/book_reads_test.exs b/test/wild/book_reads_test.exs
new file mode 100644
index 0000000..e054aa0
--- /dev/null
+++ b/test/wild/book_reads_test.exs
@@ -0,0 +1,67 @@
+defmodule Wild.BookReadsTest do
+ use Wild.DataCase
+
+ alias Wild.BookReads
+
+ describe "book_reads" do
+ alias Wild.BookReads.BookRead
+
+ import Wild.BookReadsFixtures
+
+ @invalid_attrs %{progress: nil, rating: nil, thoughts: nil, read_start: nil, read_finish: nil}
+
+ test "list_book_reads/0 returns all book_reads" do
+ book_read = book_read_fixture()
+ assert BookReads.list_book_reads() == [book_read]
+ end
+
+ test "get_book_read!/1 returns the book_read with given id" do
+ book_read = book_read_fixture()
+ assert BookReads.get_book_read!(book_read.id) == book_read
+ end
+
+ test "create_book_read/1 with valid data creates a book_read" do
+ valid_attrs = %{progress: 42, rating: 42, thoughts: "some thoughts", read_start: ~U[2025-01-08 10:31:00Z], read_finish: ~U[2025-01-08 10:31:00Z]}
+
+ assert {:ok, %BookRead{} = book_read} = BookReads.create_book_read(valid_attrs)
+ assert book_read.progress == 42
+ assert book_read.rating == 42
+ assert book_read.thoughts == "some thoughts"
+ assert book_read.read_start == ~U[2025-01-08 10:31:00Z]
+ assert book_read.read_finish == ~U[2025-01-08 10:31:00Z]
+ end
+
+ test "create_book_read/1 with invalid data returns error changeset" do
+ assert {:error, %Ecto.Changeset{}} = BookReads.create_book_read(@invalid_attrs)
+ end
+
+ test "update_book_read/2 with valid data updates the book_read" do
+ book_read = book_read_fixture()
+ update_attrs = %{progress: 43, rating: 43, thoughts: "some updated thoughts", read_start: ~U[2025-01-09 10:31:00Z], read_finish: ~U[2025-01-09 10:31:00Z]}
+
+ assert {:ok, %BookRead{} = book_read} = BookReads.update_book_read(book_read, update_attrs)
+ assert book_read.progress == 43
+ assert book_read.rating == 43
+ assert book_read.thoughts == "some updated thoughts"
+ assert book_read.read_start == ~U[2025-01-09 10:31:00Z]
+ assert book_read.read_finish == ~U[2025-01-09 10:31:00Z]
+ end
+
+ test "update_book_read/2 with invalid data returns error changeset" do
+ book_read = book_read_fixture()
+ assert {:error, %Ecto.Changeset{}} = BookReads.update_book_read(book_read, @invalid_attrs)
+ assert book_read == BookReads.get_book_read!(book_read.id)
+ end
+
+ test "delete_book_read/1 deletes the book_read" do
+ book_read = book_read_fixture()
+ assert {:ok, %BookRead{}} = BookReads.delete_book_read(book_read)
+ assert_raise Ecto.NoResultsError, fn -> BookReads.get_book_read!(book_read.id) end
+ end
+
+ test "change_book_read/1 returns a book_read changeset" do
+ book_read = book_read_fixture()
+ assert %Ecto.Changeset{} = BookReads.change_book_read(book_read)
+ end
+ end
+end
diff --git a/test/wild_web/live/book_read_live_test.exs b/test/wild_web/live/book_read_live_test.exs
new file mode 100644
index 0000000..1429447
--- /dev/null
+++ b/test/wild_web/live/book_read_live_test.exs
@@ -0,0 +1,113 @@
+defmodule WildWeb.BookReadLiveTest do
+ use WildWeb.ConnCase
+
+ import Phoenix.LiveViewTest
+ import Wild.BookReadsFixtures
+
+ @create_attrs %{progress: 42, rating: 42, thoughts: "some thoughts", read_start: "2025-01-08T10:31:00Z", read_finish: "2025-01-08T10:31:00Z"}
+ @update_attrs %{progress: 43, rating: 43, thoughts: "some updated thoughts", read_start: "2025-01-09T10:31:00Z", read_finish: "2025-01-09T10:31:00Z"}
+ @invalid_attrs %{progress: nil, rating: nil, thoughts: nil, read_start: nil, read_finish: nil}
+
+ defp create_book_read(_) do
+ book_read = book_read_fixture()
+ %{book_read: book_read}
+ end
+
+ describe "Index" do
+ setup [:create_book_read]
+
+ test "lists all book_reads", %{conn: conn, book_read: book_read} do
+ {:ok, _index_live, html} = live(conn, ~p"/book_reads")
+
+ assert html =~ "Listing Book reads"
+ assert html =~ book_read.thoughts
+ end
+
+ test "saves new book_read", %{conn: conn} do
+ {:ok, index_live, _html} = live(conn, ~p"/book_reads")
+
+ assert index_live |> element("a", "New Book read") |> render_click() =~
+ "New Book read"
+
+ assert_patch(index_live, ~p"/book_reads/new")
+
+ assert index_live
+ |> form("#book_read-form", book_read: @invalid_attrs)
+ |> render_change() =~ "can't be blank"
+
+ assert index_live
+ |> form("#book_read-form", book_read: @create_attrs)
+ |> render_submit()
+
+ assert_patch(index_live, ~p"/book_reads")
+
+ html = render(index_live)
+ assert html =~ "Book read created successfully"
+ assert html =~ "some thoughts"
+ end
+
+ test "updates book_read in listing", %{conn: conn, book_read: book_read} do
+ {:ok, index_live, _html} = live(conn, ~p"/book_reads")
+
+ assert index_live |> element("#book_reads-#{book_read.id} a", "Edit") |> render_click() =~
+ "Edit Book read"
+
+ assert_patch(index_live, ~p"/book_reads/#{book_read}/edit")
+
+ assert index_live
+ |> form("#book_read-form", book_read: @invalid_attrs)
+ |> render_change() =~ "can't be blank"
+
+ assert index_live
+ |> form("#book_read-form", book_read: @update_attrs)
+ |> render_submit()
+
+ assert_patch(index_live, ~p"/book_reads")
+
+ html = render(index_live)
+ assert html =~ "Book read updated successfully"
+ assert html =~ "some updated thoughts"
+ end
+
+ test "deletes book_read in listing", %{conn: conn, book_read: book_read} do
+ {:ok, index_live, _html} = live(conn, ~p"/book_reads")
+
+ assert index_live |> element("#book_reads-#{book_read.id} a", "Delete") |> render_click()
+ refute has_element?(index_live, "#book_reads-#{book_read.id}")
+ end
+ end
+
+ describe "Show" do
+ setup [:create_book_read]
+
+ test "displays book_read", %{conn: conn, book_read: book_read} do
+ {:ok, _show_live, html} = live(conn, ~p"/book_reads/#{book_read}")
+
+ assert html =~ "Show Book read"
+ assert html =~ book_read.thoughts
+ end
+
+ test "updates book_read within modal", %{conn: conn, book_read: book_read} do
+ {:ok, show_live, _html} = live(conn, ~p"/book_reads/#{book_read}")
+
+ assert show_live |> element("a", "Edit") |> render_click() =~
+ "Edit Book read"
+
+ assert_patch(show_live, ~p"/book_reads/#{book_read}/show/edit")
+
+ assert show_live
+ |> form("#book_read-form", book_read: @invalid_attrs)
+ |> render_change() =~ "can't be blank"
+
+ assert show_live
+ |> form("#book_read-form", book_read: @update_attrs)
+ |> render_submit()
+
+ assert_patch(show_live, ~p"/book_reads/#{book_read}")
+
+ html = render(show_live)
+ assert html =~ "Book read updated successfully"
+ assert html =~ "some updated thoughts"
+ end
+ end
+end