-
Notifications
You must be signed in to change notification settings - Fork 2.9k
/
forward_test.exs
174 lines (141 loc) · 4.89 KB
/
forward_test.exs
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
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
defmodule Phoenix.Test.HealthController do
use Phoenix.Controller
def health(conn, _params), do: text(conn, "health")
end
defmodule Phoenix.Router.ForwardTest do
use ExUnit.Case, async: true
use RouterHelper
defmodule Controller do
use Phoenix.Controller
plug :assign_fwd_script
def index(conn, _params), do: text(conn, "admin index")
def stats(conn, _params), do: text(conn, "stats")
def params(conn, params), do: text(conn, inspect(params))
def api_users(conn, _params), do: text(conn, "api users")
def api_root(conn, _params), do: text(conn, "api root")
defp assign_fwd_script(conn, _), do: assign(conn, :fwd_script, conn.script_name)
end
defmodule ApiRouter do
use Phoenix.Router
get "/", Controller, :api_root
get "/users", Controller, :api_users
scope "/health", Phoenix.Test do
forward "/", HealthController, :health
end
end
defmodule AdminDashboard do
use Phoenix.Router
get "/", Controller, :index, as: :page
get "/stats", Controller, :stats, as: :page
forward "/api-admin", ApiRouter
end
defmodule InitPlug do
def init(_), do: %{non: :literal}
def call(conn, %{non: :literal} = opts), do: assign(conn, :opts, opts)
end
defmodule AssignOptsPlug do
def init(opts), do: opts
def call(conn, opts), do: assign(conn, :opts, opts)
end
defmodule Router do
use Phoenix.Router
scope "/" do
get "/stats", Controller, :stats
forward "/admin", AdminDashboard
forward "/init", InitPlug
forward "/assign/opts", AssignOptsPlug, %{foo: "bar"}
scope "/params/:param" do
forward "/", Controller, :params
end
end
end
setup do
Logger.disable(self())
:ok
end
test "forwards path to plug" do
conn = call(Router, :get, "admin")
assert conn.script_name == []
assert conn.assigns[:fwd_script] == ["admin"]
assert conn.status == 200
assert conn.resp_body == "admin index"
end
test "forwards any request starting with forward path" do
conn = call(Router, :get, "admin/stats")
assert conn.script_name == []
assert conn.assigns[:fwd_script] == ["admin"]
assert conn.status == 200
assert conn.resp_body == "stats"
end
test "forward with dynamic segments raises" do
router = quote do
defmodule BadRouter do
use Phoenix.Router
forward "/api/:version", ApiRouter
end
end
assert_raise ArgumentError, ~r{dynamic segment "/api/:version" not allowed}, fn ->
Code.eval_quoted(router)
end
end
test "forward with non-unique plugs raises" do
router = quote do
defmodule BadRouter do
use Phoenix.Router
forward "/api/v1", ApiRouter
forward "/api/v2", ApiRouter
end
end
assert_raise ArgumentError, ~r{Phoenix.Router.ForwardTest.ApiRouter has already been forwarded}, fn ->
Code.eval_quoted(router)
end
end
test "accumulates phoenix_forwards" do
conn = call(Router, :get, "admin")
assert conn.private[Router] == {[], %{
Phoenix.Router.ForwardTest.AdminDashboard => ["admin"],
Phoenix.Router.ForwardTest.InitPlug => ["init"],
Phoenix.Router.ForwardTest.AssignOptsPlug => ["assign", "opts"],
Phoenix.Router.ForwardTest.Controller => []
}}
assert conn.private[AdminDashboard] ==
{["admin"], %{Phoenix.Router.ForwardTest.ApiRouter => ["api-admin"]}}
end
test "helpers cascade script name across forwards based on main router" do
import AdminDashboard.Helpers
assert page_path(%Plug.Conn{}, :stats) == "/stats"
conn = call(Router, :get, "stats")
assert page_path(conn, :stats) == "/admin/stats"
conn = call(Router, :get, "stats", _params = nil, ["phx"])
assert page_path(conn, :stats) == "/phx/admin/stats"
conn = call(Router, :get, "admin/stats")
assert page_path(conn, :stats) == "/admin/stats"
conn = call(Router, :get, "admin/stats", _params = nil, ["phx"])
assert page_path(conn, :stats) == "/phx/admin/stats"
end
test "forward can handle plugs with non-literal init returns" do
assert call(Router, :get, "init").assigns.opts == %{non: :literal}
end
test "forward can handle plugs with custom options" do
assert call(Router, :get, "assign/opts").assigns.opts == %{foo: "bar"}
end
test "forward can handle params" do
assert call(Router, :get, "params/hello_world").resp_body =~ ~s["param" => "hello_world"]
end
test "forward with scoped alias" do
conn = call(ApiRouter, :get, "health")
assert conn.resp_body == "health"
assert conn.private[ApiRouter] == {[], %{Phoenix.Test.HealthController => []}}
end
test "forwards raises if using the plug to arguments" do
error_message = ~r/expects a module/
assert_raise(ArgumentError, error_message, fn ->
defmodule BrokenRouter do
use Phoenix.Router
scope "/" do
forward "/health", to: HealthController
end
end
end)
end
end