Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions lib/phoenix/presence.ex
Original file line number Diff line number Diff line change
Expand Up @@ -312,12 +312,12 @@ defmodule Phoenix.Presence do
devices, could return:

iex> MyPresence.get_by_key("room:1", "user1")
[%{name: "User 1", metas: [%{device: "Desktop"}, %{device: "Mobile"}]}]
%{name: "User 1", metas: [%{device: "Desktop"}, %{device: "Mobile"}]}

Like `c:list/1`, the presence metadata is passed to the `fetch`
callback of your presence module to fetch any additional information.
"""
@callback get_by_key(Phoenix.Socket.t() | topic, key :: String.t()) :: [presence]
@callback get_by_key(Phoenix.Socket.t() | topic, key :: String.t()) :: map() | []

@doc """
Extend presence information with additional data.
Expand Down
15 changes: 12 additions & 3 deletions lib/phoenix/router/scope.ex
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@ defmodule Phoenix.Router.Scope do
private: %{},
assigns: %{},
log: :debug,
trailing_slash?: false
trailing_slash?: false,
route_defined?: false

@doc """
Initializes the scope.
Expand Down Expand Up @@ -61,6 +62,8 @@ defmodule Phoenix.Router.Scope do
metadata
end

put_top(module, %{top | route_defined?: true})

Phoenix.Router.Route.build(
line,
kind,
Expand Down Expand Up @@ -120,7 +123,12 @@ defmodule Phoenix.Router.Scope do
"""
def pipe_through(module, new_pipes) do
new_pipes = List.wrap(new_pipes)
%{pipes: pipes} = top = get_top(module)
%{pipes: pipes, route_defined?: route_defined?} = top = get_top(module)

if route_defined? do
raise ArgumentError,
"pipe_through must be placed before any routes or scopes in the current scope"
end

if pipe = Enum.find(new_pipes, &(&1 in pipes)) do
raise ArgumentError,
Expand Down Expand Up @@ -160,7 +168,8 @@ defmodule Phoenix.Router.Scope do
private = Keyword.get(opts, :private, %{})
assigns = Keyword.get(opts, :assigns, %{})

update_stack(module, fn stack -> [top | stack] end)
put_top(module, %{top | route_defined?: true})
update_stack(module, fn stack -> [%{top | route_defined?: true} | stack] end)

put_top(module, %Scope{
path: top.path ++ path,
Expand Down
31 changes: 31 additions & 0 deletions test/phoenix/router/pipeline_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,37 @@ defmodule Phoenix.Router.PipelineTest do
end
end

test "pipe_through after route or scope raises" do
assert_raise ArgumentError, ~r{pipe_through must be placed before any routes or scopes in the current scope}, fn ->
defmodule PipeThroughAfterRouteRouter do
use Phoenix.Router, otp_app: :phoenix

pipeline :browser do
end

scope "/" do
get "/foo", Phoenix.Router.PipelineTest.SampleController, :index
pipe_through :browser
end
end
end

assert_raise ArgumentError, ~r{pipe_through must be placed before any routes or scopes in the current scope}, fn ->
defmodule PipeThroughAfterScopeRouter do
use Phoenix.Router, otp_app: :phoenix

pipeline :browser do
end

scope "/" do
scope "/foo" do
end
pipe_through :browser
end
end
end
end

test "pipeline raises on conflict" do
assert_raise ArgumentError, ~r{there is an import from Kernel with the same name}, fn ->
defmodule ConflictingPipeline do
Expand Down
6 changes: 4 additions & 2 deletions test/phoenix/router/routing_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -63,8 +63,10 @@ defmodule Phoenix.Router.RoutingTest do
pipe_through :noop
get "/plug", SomePlug, []
get "/users/:id/raise", UserController, :raise
pipe_through :halt
get "/info", UserController, :raise
scope "/" do
pipe_through :halt
get "/info", UserController, :raise
end
end

get "/no_log", SomePlug, [], log: false
Expand Down