Skip to content

Commit

Permalink
Add link options and callback method for provider_links method
Browse files Browse the repository at this point in the history
  • Loading branch information
danschultzer committed May 24, 2020
1 parent 3a704b9 commit cb791f3
Show file tree
Hide file tree
Showing 3 changed files with 76 additions and 16 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

* [`PowAssent.Phoenix.ViewHelpers`] `PowAssent.Phoenix.ViewHelpers.authorization_link/3` now accepts block argument
* [`PowAssent.Phoenix.ViewHelpers`] `PowAssent.Phoenix.ViewHelpers.deauthorization_link/3` now accepts block argument
* [`PowAssent.Phoenix.ViewHelpers`] `PowAssent.Phoenix.ViewHelpers.authorization_links/2` now accepts link options or callback method as second argument

## v0.4.8 (2020-05-18)

Expand Down
47 changes: 36 additions & 11 deletions lib/pow_assent/phoenix/views/view_helpers.ex
Original file line number Diff line number Diff line change
Expand Up @@ -16,18 +16,43 @@ defmodule PowAssent.Phoenix.ViewHelpers do
If a user is assigned to the conn, the authorized providers for a user will
be looked up with `PowAssent.Plug.providers_for_current_user/1`.
`deauthorization_link/2` will be used for any already authorized providers.
The second argument may be link options passed on to `authorization_link/2`
or `deauthorization_link/2` respectively. It may also be a method that
handles render callback as seen in the example below.
## Example
ViewHelpers.provider_links @conn, fn provider, providers_for_user ->
if provider in providers_for_user do
ViewHelpers.deauthorization_link @conn, provider do
Tag.content_tag(:span, "Remove \#{provider}", class: provider)
end
else
ViewHelpers.authorization_link @conn, provider do
Tag.content_tag(:span, "Sign in with \#{provider}", class: provider)
end
end
end
"""
@spec provider_links(Conn.t(), keyword()) :: [HTML.safe()]
def provider_links(conn, link_opts \\ []) do
available_providers = Plug.available_providers(conn)
providers_for_user = Plug.providers_for_current_user(conn)

available_providers
|> Enum.map(&{&1, &1 in providers_for_user})
|> Enum.map(fn
{provider, true} -> deauthorization_link(conn, provider, link_opts)
{provider, false} -> authorization_link(conn, provider, link_opts)
end)
@spec provider_links(Conn.t(), keyword() | ({atom(), boolean()} -> Phoenix.HTML.unsafe())) :: [HTML.safe()]
def provider_links(conn, link_opts_or_callback \\ []) do
providers_for_user = Plug.providers_for_current_user(conn)
callback = render_callback(link_opts_or_callback, conn)

conn
|> Plug.available_providers()
|> Enum.map(&callback.(&1, providers_for_user))
end

defp render_callback(callback, _conn) when is_function(callback), do: callback
defp render_callback(link_opts, conn) do
fn provider, providers_for_user ->
case provider in providers_for_user do
true -> deauthorization_link(conn, provider, link_opts)
false -> authorization_link(conn, provider, link_opts)
end
end
end

@doc """
Expand Down
44 changes: 39 additions & 5 deletions test/pow_assent/phoenix/views/view_helpers_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ defmodule PowAssent.Phoenix.ViewHelpersTest do
use PowAssent.Test.Phoenix.ConnCase

alias Plug.Conn
alias Phoenix.HTML.Link
alias Phoenix.HTML.{Link, Tag}
alias PowAssent.Phoenix.ViewHelpers
alias PowAssent.Test.{Phoenix.Router, Ecto.Users.User, RepoMock}

Expand All @@ -26,7 +26,7 @@ defmodule PowAssent.Phoenix.ViewHelpersTest do
{:ok, conn: conn}
end

test "provider_links/1", %{conn: conn} do
test "provider_links/2", %{conn: conn} do
[safe: iodata] = ViewHelpers.provider_links(conn)
assert {:safe, iodata} == Link.link("Sign in with Test provider", to: "/auth/test_provider/new")

Expand All @@ -36,13 +36,13 @@ defmodule PowAssent.Phoenix.ViewHelpersTest do
assert {:safe, iodata} == Link.link("Remove Test provider authentication", to: "/auth/test_provider", method: "delete")
end

test "provider_links/1 with link opts", %{conn: conn} do
test "provider_links/2 with link opts", %{conn: conn} do
[safe: iodata] = ViewHelpers.provider_links(conn, class: "example")

assert {:safe, iodata} == Link.link("Sign in with Test provider", to: "/auth/test_provider/new", class: "example")
end

test "provider_links/1 with request_path", %{conn: conn} do
test "provider_links/2 with request_path", %{conn: conn} do
[safe: iodata] =
conn
|> Conn.assign(:request_path, "/custom-url")
Expand All @@ -51,13 +51,47 @@ defmodule PowAssent.Phoenix.ViewHelpersTest do
assert {:safe, iodata} == Link.link("Sign in with Test provider", to: "/auth/test_provider/new?request_path=%2Fcustom-url")
end

test "provider_links/1 with invited_user", %{conn: conn} do
test "provider_links/2 with invited_user", %{conn: conn} do
conn = Conn.assign(conn, :invited_user, %PowAssent.Test.Invitation.Users.User{invitation_token: "token"})

[safe: iodata] = ViewHelpers.provider_links(conn)
assert {:safe, iodata} == Link.link("Sign in with Test provider", to: "/auth/test_provider/new?invitation_token=token")
end

test "provider_links/2 with callback", %{conn: conn} do
callback =
fn provider, providers_for_user ->
case provider in providers_for_user do
true ->
ViewHelpers.deauthorization_link(conn, :test_provider, class: "remove") do
Tag.content_tag(:span, "Provider remove", class: "test_provider")
end

false ->
ViewHelpers.authorization_link(conn, :test_provider, class: "auth") do
Tag.content_tag(:span, "Provider auth", class: "test_provider")
end
end
end

[safe: iodata] = ViewHelpers.provider_links(conn, callback)

assert {:safe, iodata} ==
(Link.link to: "/auth/test_provider/new", class: "auth" do
Tag.content_tag(:span, "Provider auth", class: "test_provider")
end)

[safe: iodata] =
conn
|> Pow.Plug.assign_current_user(%User{id: 1}, [])
|> ViewHelpers.provider_links(callback)

assert {:safe, iodata} ==
(Link.link to: "/auth/test_provider", class: "remove", method: "delete" do
Tag.content_tag(:span, "Provider remove", class: "test_provider")
end)
end

test "authorization_link/4 accepts blocks", %{conn: conn} do
{:safe, iodata} = ViewHelpers.authorization_link(conn, :test_provider) do
"Provider auth"
Expand Down

0 comments on commit cb791f3

Please sign in to comment.