phoenixframework / phoenix_live_view

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

Testing direct-to-s3 uploads using preflight_upload #3374

Open Munksgaard opened 3 months ago

Munksgaard commented 3 months ago

It is unclear from the documentation how to test direct-to-s3 uploads. Looking through LiveViewTest, I found preflight_upload/1 and this example, which I tried to adopt to my test.

For reference, I was using regular file uploads before and my tests were working, so I just wanted to update them to work with direct-to-s3 uploads. I therefore added a preflight_upload assertion to my test, as follows:

@@ -49,24 +49,26 @@ defmodule FooWeb.FileLiveTest do

       pdf =
         file_input(index_live, "#file-form", :file, [
           %{
             last_modified: 1_594_171_879_000,
             name: name,
             content: <<1, 2, 3, 4>>,
             size: 4,
             type: "application/pdf"
           }
         ])

+      assert {:ok, %{ref: _ref, config: %{chunk_size: _}}} = preflight_upload(pdf)
+
       render_upload(pdf, name)

       refute index_live |> element("button:disabled") |> has_element?()

       assert index_live
              |> form("#file-form", file: @create_attrs)
              |> render_submit()

Upon running the test, I got the following error:

     ** (EXIT from #PID<0.555.0>) an exception was raised:
         ** (ArgumentError) cannot consume uploaded files when entries are still in progress
             (phoenix_live_view 0.20.17) lib/phoenix_live_view/upload.ex:248: Phoenix.LiveView.Upload.consume_uploaded_entries/3
             (leaf 0.1.0) lib/foo/live/file_live/form_component.ex:122: FooWeb.FileLive.FormComponent.save_file/3
             (phoenix_live_view 0.20.17) lib/phoenix_live_view/channel.ex:735: anonymous fn/4 in Phoenix.LiveView.Channel.inner_component_handle_event/4
             (telemetry 1.2.1) /home/munksgaard/src/foo/deps/telemetry/src/telemetry.erl:321: :telemetry.span/3
             (phoenix_live_view 0.20.17) lib/phoenix_live_view/diff.ex:209: Phoenix.LiveView.Diff.write_component/4
             (phoenix_live_view 0.20.17) lib/phoenix_live_view/channel.ex:662: Phoenix.LiveView.Channel.component_handle/4
             (stdlib 4.3.1.4) gen_server.erl:1123: :gen_server.try_dispatch/4
             (stdlib 4.3.1.4) gen_server.erl:1200: :gen_server.handle_msg/6
             (stdlib 4.3.1.4) proc_lib.erl:240: :proc_lib.init_p_do_apply/3

After a bit of debugging, it turns out that the cause of this error was the call to render_submit/1 further down in the code. For some reason, preflight_upload/1 makes render_submit/1 raise. So I am curious, what is the suggested way to test that direct-to-s3 uploads work as expected? I know that LiveView does not test the javascript portion of the code, but it should be possible to test everything else, right?

With the help of @LostKobrakai, I also found out that render_upload/2 is returning {:error, :not_allowed}, but it is unclear from the documentation why. @LostKobrakai pointed out that maybe it is not allowed to call both render_upload/2 and preflight_upload/1, but if so, that should probably be clear from the documentation.

lessless commented 1 month ago

@germsvel is this covered in your course by any chance?