defmodule BerrypodWeb.Auth.SettingsTest do
  use BerrypodWeb.ConnCase

  alias Berrypod.Accounts
  import Phoenix.LiveViewTest
  import Berrypod.AccountsFixtures

  describe "settings redirect" do
    test "redirects to admin settings when logged in", %{conn: conn} do
      conn = log_in_user(conn, user_fixture())
      assert {:error, {:redirect, %{to: "/admin/settings"}}} = live(conn, ~p"/users/settings")
    end

    test "redirects to login when not logged in", %{conn: conn} do
      assert {:error, redirect} = live(conn, ~p"/users/settings")
      assert {:redirect, %{to: path, flash: flash}} = redirect
      assert path == ~p"/users/log-in"
      assert %{"error" => "You must log in to access this page."} = flash
    end
  end

  describe "confirm email" do
    setup %{conn: conn} do
      user = user_fixture()
      email = unique_user_email()

      token =
        extract_user_token(fn url ->
          Accounts.deliver_user_update_email_instructions(%{user | email: email}, user.email, url)
        end)

      %{conn: log_in_user(conn, user), token: token, email: email, user: user}
    end

    test "updates the user email once", %{conn: conn, user: user, token: token, email: email} do
      {:error, redirect} = live(conn, ~p"/users/settings/confirm-email/#{token}")

      assert {:redirect, %{to: "/admin/settings", flash: flash}} = redirect
      assert %{"info" => "Email changed successfully."} = flash
      refute Accounts.get_user_by_email(user.email)
      assert Accounts.get_user_by_email(email)

      # use confirm token again
      {:error, redirect} = live(conn, ~p"/users/settings/confirm-email/#{token}")

      assert {:redirect, %{to: "/admin/settings", flash: flash}} = redirect
      assert %{"error" => "Email change link is invalid or it has expired."} = flash
    end

    test "does not update email with invalid token", %{conn: conn, user: user} do
      {:error, redirect} = live(conn, ~p"/users/settings/confirm-email/oops")

      assert {:redirect, %{to: "/admin/settings", flash: flash}} = redirect
      assert %{"error" => "Email change link is invalid or it has expired."} = flash
      assert Accounts.get_user_by_email(user.email)
    end

    test "redirects if user is not logged in", %{token: token} do
      conn = build_conn()
      {:error, redirect} = live(conn, ~p"/users/settings/confirm-email/#{token}")

      assert {:redirect, %{to: path, flash: flash}} = redirect
      assert path == ~p"/users/log-in"
      assert %{"error" => message} = flash
      assert message == "You must log in to access this page."
    end
  end
end
