phoenixframework / phoenix_live_view

Rich, real-time user experiences with server-rendered HTML
https://hex.pm/packages/phoenix_live_view
MIT License
6.12k stars 917 forks source link

Phoenix.LiveViewTest.render_upload/3 crashes when upload process redirects #2047

Closed mogest closed 8 months ago

mogest commented 2 years ago

Environment

Actual behavior

Using render_upload when the upload function returns {:noreply, push_redirect(socket, to: some_url)} causes the following error:

     ** (FunctionClauseError) no function clause matching in Floki.RawHTML.build_raw_html/4

     The following arguments were given to Floki.RawHTML.build_raw_html/4:

         # 1
         [error: {:live_redirect, %{kind: :push, to: "/url"}}]

         # 2
         []

         # 3
         &HtmlEntities.encode/1

         # 4
         :noop

It's because this line in Phoenix.LiveViewTest.render_chunk/3 calls render/1 and that doesn't work with a redirect.

Makes sense—the function is called render_upload after all—but there's no way to to perform an upload otherwise as private functions are used.

Expected behavior

I don't think we should change the functionality of render_upload, but I propose a new function perform_upload that does the same without rendering; instead it can return :ok | {:error, atom()}.

Then render_upload can be refactored to use the new perform_upload function and render the view in the :ok case.

I'm happy to code this up as a PR but wanted to check in that that was a sensible path to take first.

mcrumm commented 2 years ago

Hi @mogest – I think this issue is a duplicate of #1620. Are you consuming the entry in the progress callback?

mogest commented 2 years ago

Yes:

  defp handle_progress(_name, entry, socket) do
    if entry.done? do
      consume_uploads(socket)
    else
      {:noreply, socket}
    end
  end

Is that OK to do that? I found the same workaround as in #1620, but get intermittent failures on test runs so swapped that out with a reimplementation that doesn't render.

chrismccord commented 8 months ago

Closed via eeafb2a5834645d812264a3032192639c4473777

cbh123 commented 3 months ago

Environment

Actual behavior

Hmm, I'm still seeing this even after updating to :phoenix_live_view, "~> 1.0.0-rc.0" (with your commit).

I'm running the same logic as @mogest where I redirect after uploading an image, and I get this error when I try and test it.

Test:

      {:ok, view, _html} = live(conn, "/dashboard")

      assert render(view) =~ "free plan"

      # Upload an image file
      image = view |> file_input("#upload-form", :image, [image_fixture()])

      render_upload(image, image_fixture().name) 

Result:

     ** (FunctionClauseError) no function clause matching in Floki.RawHTML.build_raw_html/5

     The following arguments were given to Floki.RawHTML.build_raw_html/5:

         # 1
         [error: {:live_redirect, %{kind: :push, to: "/uploads/275a4e57-2503-40a1-b6f1-b5acee055383"}}]

I've tried rm -rf _build a couple times to make sure it's actually running the new code, and I've confirmed that my channel.ex uses the https://github.com/phoenixframework/phoenix_live_view/commit/eeafb2a5834645d812264a3032192639c4473777 commit from @chrismccord.