Skip to content

Commit 1c1b1b4

Browse files
Jérôme Guyonjosevalim
authored andcommitted
Add Plug.Test.init_test_session/2 for initializing a session (#469)
1 parent cc5c502 commit 1c1b1b4

File tree

3 files changed

+75
-1
lines changed

3 files changed

+75
-1
lines changed

lib/plug/session.ex

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,10 @@ defmodule Plug.Session do
5555
end
5656

5757
def call(conn, config) do
58-
Conn.put_private(conn, :plug_session_fetch, fetch_session(config))
58+
conn
59+
|> Conn.put_private(:plug_session_init, conn.private[:plug_session] || %{})
60+
|> Conn.put_private(:plug_session, nil)
61+
|> Conn.put_private(:plug_session_fetch, fetch_session(config))
5962
end
6063

6164
defp convert_store(store) do
@@ -76,6 +79,8 @@ defmodule Plug.Session do
7679
{nil, %{}}
7780
end
7881

82+
session = Map.merge(session, conn.private.plug_session_init)
83+
7984
conn
8085
|> Conn.put_private(:plug_session, session)
8186
|> Conn.put_private(:plug_session_fetch, :done)

lib/plug/test.ex

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,4 +123,26 @@ defmodule Plug.Test do
123123
{key, value}, acc -> put_req_cookie(acc, to_string(key), value)
124124
end
125125
end
126+
127+
@doc """
128+
Initializes the session with the given contents.
129+
130+
If the session has already been initialized, the new contents will be merged
131+
with the previous ones.
132+
"""
133+
@spec init_test_session(Conn.t, %{(String.t | atom) => any}) :: Conn.t
134+
def init_test_session(conn, session) do
135+
conn =
136+
if conn.private[:plug_session_fetch] do
137+
Conn.fetch_session(conn)
138+
else
139+
conn
140+
|> Conn.put_private(:plug_session, %{})
141+
|> Conn.put_private(:plug_session_fetch, :done)
142+
end
143+
144+
Enum.reduce(session, conn, fn {key, value}, conn ->
145+
Conn.put_session(conn, key, value)
146+
end)
147+
end
126148
end

test/plug/session_test.exs

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,4 +127,51 @@ defmodule Plug.SessionTest do
127127
opts = Plug.Session.init(store: :ets, key: "foobar", table: :some_table)
128128
assert opts.store == Plug.Session.ETS
129129
end
130+
131+
test "init_test_session/2" do
132+
conn = conn(:get, "/") |> init_test_session(foo: "bar")
133+
assert get_session(conn, :foo) == "bar"
134+
135+
conn = fetch_session(conn)
136+
assert get_session(conn, :foo) == "bar"
137+
138+
conn = put_session(conn, :bar, "foo")
139+
assert get_session(conn, :bar) == "foo"
140+
141+
conn = delete_session(conn, :bar)
142+
refute get_session(conn, :bar)
143+
144+
conn = clear_session(conn)
145+
refute get_session(conn, :foo)
146+
end
147+
148+
test "init_test_session/2 merges values when called after Plug.Session" do
149+
conn = conn(:get, "/") |> fetch_cookies
150+
151+
opts = Plug.Session.init(store: ProcessStore, key: "foobar")
152+
conn = Plug.Session.call(conn, opts) |> fetch_session
153+
conn = conn |> put_session(:foo, "bar") |> put_session(:bar, "foo")
154+
conn = init_test_session(conn, bar: "bar", other: "other")
155+
156+
assert get_session(conn, :foo) == "bar"
157+
assert get_session(conn, :other) == "other"
158+
assert get_session(conn, :bar) == "bar"
159+
end
160+
161+
test "init_test_session/2 merges values when called before Plug.Session" do
162+
opts = Plug.Session.init(store: ProcessStore, key: "foobar")
163+
164+
conn = conn(:get, "/") |> fetch_cookies
165+
conn = Plug.Session.call(conn, opts) |> fetch_session
166+
conn = conn |> put_session(:foo, "bar") |> put_session(:bar, "foo")
167+
conn = send_resp(conn, 200, "")
168+
169+
conn = conn(:get, "/") |> recycle_cookies(conn)
170+
conn = init_test_session(conn, bar: "bar", other: "other")
171+
conn = Plug.Session.call(conn, opts) |> fetch_session
172+
173+
assert get_session(conn, :foo) == "bar"
174+
assert get_session(conn, :other) == "other"
175+
assert get_session(conn, :bar) == "bar"
176+
end
130177
end

0 commit comments

Comments
 (0)