JavaScriptを有効にしてください

【Elixir】Phoenix Liveview のファイルアップロードのテスト方法

 ·  ☕ 2 分で読めます

【Elixir】Phoenix Liveview のファイルアップロードのテスト方法

Elixir Phoenix の Liveview のファイルアップロードのテスト方法

環境

  • Elixir 1.14.2
  • Phoenix 1.6.3

対象のコード

テストをする対象のコードはこちらになります。

Elixirファイル

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
defmodule DemoWeb.FileUploadLive.Index do
  use DemoWeb, :live_view

  @impl true
  def mount(_params, _session, socket) do
    {
      :ok,
      socket
      # アップロード設定
      |> allow_upload(:image, accept: ~w(.jpg .jpeg .png))
    }
  end

  @impl true
  def handle_event("validate", _params, socket) do
    {:noreply, socket}
  end

  @impl true
  def handle_event("cancel-entry", %{"ref" => ref}, socket) do
    # アップロードキャンセル
    {:noreply, cancel_upload(socket, :image, ref)}
  end

  @impl true
  def handle_event("save", _params, socket) do
    uploaded_file =
      consume_uploaded_entries(socket, :image, fn %{path: path}, entry ->
        # ファイルアップロード処理
        # path はファイルがアップロードされた場所
        # entry はアップされたファイル情報
        File.cp!(path, entry.client_name)
        entry.client_name
      end)

    {:noreply,
     socket
     |> put_flash(:info, "ファイルアップロード完了")
     |> redirect(to: "/")}
  end
end

テンプレートファイル

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
<form id="post-form" phx-change="validate" phx-submit="save">
    <!-- アップロードされたらファイルアップ箇所は非表示 -->
    <div class="columns is-centered" style={ if @uploads.image.entries != [], do: "display:none" }>
    <!-- ファイルをドラッグ & ドロップでもアップロードすることが可能 -->
      <div class="file is-boxed" phx-drop-target={ @uploads.image.ref }>
        <label class="file-label">
          <%= live_file_input @uploads.image, class: "file-input" %>
          <span class="file-cta">
            <span class="file-label p-6">
              Choose a file…
            </span>
          </span>
        </label>
      </div>
    </div>
    <%=
    # アップロードされたら表示
    for entry <- @uploads.image.entries do %>
      <figure>
        <%= live_img_preview entry %>
        <figcaption><%= entry.client_name %></figcaption>
      </figure>
      <%=
      # アップロードキャンセルボタン
      submit gettext("Cancel"), type: "button", phx_click: "cancel-entry", phx_value_ref: entry.ref %>

      <%=
      # エラー表示
      for err <- upload_errors(@uploads.image, entry) do %>
        <p class="alert alert-danger"><%= err %></p>
      <% end %>
    <% end %>
    <%= submit gettext("Save"), phx_disable_with: gettext("Saving...") %>
</form>

テスト

実際のテスト処理を書きます。

前準備

テストの前にファイルアップロードに使用する画像を用意します。

ファイルアップロード用のディレクトリの作成とフェニックスのロゴをコピーします

1
2
$ mkdir test/support/upload_files
$ cp priv/static/images/phoenix.png test/support/upload_files/phoenix.png

テストファイル

実際にテストを書くとこうなります

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
defmodule DemoWeb.Live.FileUploadTest do
  use DemoWeb.ConnCase

  import Phoenix.LiveViewTest

  test "FileUpload", %{conn: conn} do
    # ファイルアップロード処理
    assert index_live
            # ファイルアップロードのターゲット
            |> file_input("#post-form", :image, [
            # アップロードするファイルの情報
            %{
                # 名前
                name: "phoenix.png",
                # 種別
                type: "image/png",
                # 実ファイル
                content: File.read!("test/support/upload_files/phoenix.png")
            }
            ])
            # ファイルのアップロード処理
            |> render_upload("phoenix.png") =~ "phoenix.png"
  end
end

参考

まとめ

今までPHPのFWのバージョンアップなど経験をしてきましたが、Phoenix はまだまだ新機能が作られたりするので破壊的なバージョンアップが続きそうなので注意が必要です。

共有

こぴぺたん
著者
こぴぺたん
Copy & Paste Engineer