Skip to content

Commit 2fd11a9

Browse files
committed
Control request flow in tests
1 parent 781c6fd commit 2fd11a9

File tree

3 files changed

+119
-20
lines changed

3 files changed

+119
-20
lines changed

test/extensions/persistent_session/plug/cookie_test.exs

Lines changed: 58 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -45,15 +45,52 @@ defmodule PowPersistentSession.Plug.CookieTest do
4545
assert PersistentSessionCache.get([backend: ets], new_id) == {[id: 1], []}
4646
end
4747

48-
test "call/2 assigns user from cookie and doesn't expire with simultanous request", %{conn: conn, ets: ets} do
49-
user = %User{id: 1}
50-
id = "test"
51-
conn = store_persistent(conn, ets, id, {[id: user.id], []})
48+
defmodule PersistentSessionCacheWaitDelete do
49+
alias PowPersistentSession.Store.PersistentSessionCache
50+
51+
@timeout :timer.seconds(5)
52+
53+
defdelegate put(config, session_id, record_or_records), to: PersistentSessionCache
54+
55+
defdelegate get(config, session_id), to: PersistentSessionCache
56+
57+
def delete(config, session_id)do
58+
send(self(), {__MODULE__, :wait})
59+
60+
receive do
61+
{__MODULE__, :commit} -> :ok
62+
after
63+
@timeout -> raise "Timeout reached"
64+
end
65+
66+
PersistentSessionCache.delete(config, session_id)
67+
end
68+
end
5269

53-
task_1 = Task.async(fn -> run_plug(conn) end)
54-
task_2 = Task.async(fn -> run_plug(conn) end)
55-
conn_1 = Task.await(task_1)
56-
conn_2 = Task.await(task_2)
70+
test "call/2 assigns user from cookie and doesn't expire with simultanous request", %{conn: conn, ets: ets} do
71+
:ets.delete(EtsCacheMock)
72+
:ets.new(EtsCacheMock, [:ordered_set, :public, :named_table])
73+
74+
user = %User{id: 1}
75+
id = "test"
76+
conn = store_persistent(conn, ets, id, {[id: user.id], []})
77+
config = [persistent_session_store: {PersistentSessionCacheWaitDelete, ttl: :timer.hours(24) * 30, namespace: "persistent_session"}]
78+
79+
task_1 =
80+
fn -> run_plug(conn, config) end
81+
|> Task.async()
82+
|> wait_till_ready()
83+
84+
conn_2 =
85+
fn -> run_plug(conn, config) end
86+
|> Task.async()
87+
|> continue_work()
88+
|> Task.await()
89+
90+
conn_1 =
91+
task_1
92+
|> continue_work()
93+
|> Task.await()
5794

5895
assert Plug.current_user(conn_1) == user
5996
assert %{value: _id, max_age: @max_age, path: "/"} = conn_1.resp_cookies[@cookie_key]
@@ -62,6 +99,19 @@ defmodule PowPersistentSession.Plug.CookieTest do
6299
refute conn_2.resp_cookies[@cookie_key]
63100
end
64101

102+
defp wait_till_ready(%{pid: tracking_pid} = task) do
103+
:erlang.trace(tracking_pid, true, [:receive])
104+
assert_receive {:trace, ^tracking_pid, :receive, {PersistentSessionCacheWaitDelete, :wait}}
105+
106+
task
107+
end
108+
109+
defp continue_work(%{pid: tracking_pid} = task) do
110+
send(tracking_pid, {PersistentSessionCacheWaitDelete, :commit})
111+
112+
task
113+
end
114+
65115
test "call/2 assigns user from cookie passing fingerprint to the session metadata", %{conn: conn, ets: ets} do
66116
user = %User{id: 1}
67117
id = "test"

test/pow/plug/session_test.exs

Lines changed: 60 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -112,10 +112,35 @@ defmodule Pow.Plug.SessionTest do
112112
assert conn.private[:pow_session_metadata][:fingerprint] == "fingerprint"
113113
end
114114

115+
defmodule CredentialsCacheWaitDelete do
116+
alias Pow.Store.CredentialsCache
117+
118+
@timeout :timer.seconds(5)
119+
120+
defdelegate put(config, session_id, record_or_records), to: CredentialsCache
121+
122+
defdelegate get(config, session_id), to: CredentialsCache
123+
124+
def delete(config, session_id)do
125+
send(self(), {__MODULE__, :wait})
126+
127+
receive do
128+
{__MODULE__, :commit} -> :ok
129+
after
130+
@timeout -> raise "Timeout reached"
131+
end
132+
133+
CredentialsCache.delete(config, session_id)
134+
end
135+
end
136+
115137
test "call/2 creates new session when :session_renewal_ttl reached and doesn't delete with simultanous request", %{conn: conn} do
138+
:ets.delete(EtsCacheMock)
139+
:ets.new(EtsCacheMock, [:ordered_set, :public, :named_table])
140+
116141
ttl = 100
117142
session_id = "token"
118-
config = Keyword.put(@default_opts, :session_ttl_renewal, ttl)
143+
config = Keyword.merge(@default_opts, session_ttl_renewal: ttl, credentials_cache_store: {CredentialsCacheWaitDelete, [ttl: :timer.minutes(30), namespace: "credentials"]})
119144
stale_timestamp = :os.system_time(:millisecond) - ttl - 1
120145

121146
conn =
@@ -130,16 +155,27 @@ defmodule Pow.Plug.SessionTest do
130155

131156
CredentialsCache.put(@store_config, session_id, {@user, inserted_at: stale_timestamp})
132157

133-
task_1 = Task.async(fn ->
134-
Process.put({:session, sid}, session_data)
135-
run_plug(conn, config)
136-
end)
137-
task_2 = Task.async(fn ->
138-
Process.put({:session, sid}, session_data)
139-
run_plug(conn, config)
140-
end)
141-
conn_1 = Task.await(task_1)
142-
conn_2 = Task.await(task_2)
158+
task_1 =
159+
fn ->
160+
Process.put({:session, sid}, session_data)
161+
run_plug(conn, config)
162+
end
163+
|> Task.async()
164+
|> wait_till_ready()
165+
166+
conn_2 =
167+
fn ->
168+
Process.put({:session, sid}, session_data)
169+
run_plug(conn, config)
170+
end
171+
|> Task.async()
172+
|> continue_work()
173+
|> Task.await()
174+
175+
conn_1 =
176+
task_1
177+
|> continue_work()
178+
|> Task.await()
143179

144180
assert Plug.current_user(conn_1) == @user
145181
assert conn_1.resp_cookies["foobar"]
@@ -152,6 +188,19 @@ defmodule Pow.Plug.SessionTest do
152188
assert CredentialsCache.get(@store_config, get_session_id(conn_2)) == :not_found
153189
end
154190

191+
defp wait_till_ready(%{pid: tracking_pid} = task) do
192+
:erlang.trace(tracking_pid, true, [:receive])
193+
assert_receive {:trace, ^tracking_pid, :receive, {CredentialsCacheWaitDelete, :wait}}
194+
195+
task
196+
end
197+
198+
defp continue_work(%{pid: tracking_pid} = task) do
199+
send(tracking_pid, {CredentialsCacheWaitDelete, :commit})
200+
201+
task
202+
end
203+
155204
test "call/2 with prepended `:otp_app` session key", %{conn: conn} do
156205
CredentialsCache.put(@store_config, "token", {@user, inserted_at: :os.system_time(:millisecond)})
157206

test/support/ets_cache_mock.ex

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ defmodule Pow.Test.EtsCacheMock do
22
@moduledoc false
33
@tab __MODULE__
44

5-
def init, do: :ets.new(@tab, [:ordered_set, :public, :named_table])
5+
def init, do: :ets.new(@tab, [:ordered_set, :protected, :named_table])
66

77
def get(config, key) do
88
ets_key = ets_key(config, key)

0 commit comments

Comments
 (0)