towerops/test/towerops_web/plugs/update_session_activity_test.exs
Graham McIntire 7a3950d1ad chore: add jump_credo_checks ~> 0.4 with all 19 checks enabled
All checks set to exit_status: 0 initially to avoid blocking on
pre-existing violations. Remove exit_status overrides as each
check category is cleaned up incrementally.

Dependency added to dev/test only.
2026-06-12 13:45:59 -05:00

130 lines
4.3 KiB
Elixir

defmodule ToweropsWeb.Plugs.UpdateSessionActivityTest do
use ToweropsWeb.ConnCase, async: false
alias Towerops.Accounts.BrowserSession
alias ToweropsWeb.Plugs.UpdateSessionActivity
describe "init/1" do
test "passes through opts unchanged" do
assert UpdateSessionActivity.init(:some_opts) == :some_opts
end
end
describe "call/2" do
test "passes through when no user_token in session", %{conn: conn} do
conn =
conn
|> init_test_session(%{})
|> UpdateSessionActivity.call(%{})
assert conn.state == :unset
end
test "starts background task when user_token present", %{conn: conn} do
conn =
conn
|> init_test_session(%{user_token: "existing-token"})
|> UpdateSessionActivity.call(%{})
assert conn.state == :unset
end
test "starts background task when user_token and live_socket_id present", %{conn: conn} do
conn =
conn
|> init_test_session(%{
user_token: "existing-token",
live_socket_id: "users_sessions:abc"
})
|> UpdateSessionActivity.call(%{})
assert conn.state == :unset
end
end
describe "session_timed_out?/1" do
test "returns true when session has been inactive for more than 30 minutes" do
old_time = DateTime.add(DateTime.utc_now(), -31, :minute)
session = %{last_activity_at: old_time}
assert UpdateSessionActivity.session_timed_out?(session)
end
test "returns false when session was recently active" do
recent_time = DateTime.add(DateTime.utc_now(), -5, :second)
session = %{last_activity_at: recent_time}
refute UpdateSessionActivity.session_timed_out?(session)
end
test "uses inserted_at when last_activity_at is nil" do
old_time = DateTime.add(DateTime.utc_now(), -31, :minute)
session = %{last_activity_at: nil, inserted_at: old_time}
assert UpdateSessionActivity.session_timed_out?(session)
end
test "returns false for recent inserted_at when last_activity_at is nil" do
recent_time = DateTime.add(DateTime.utc_now(), -5, :second)
session = %{last_activity_at: nil, inserted_at: recent_time}
refute UpdateSessionActivity.session_timed_out?(session)
end
test "returns false at exactly 30 minutes of inactivity" do
borderline_time = DateTime.add(DateTime.utc_now(), -30, :minute)
session = %{last_activity_at: borderline_time}
refute UpdateSessionActivity.session_timed_out?(session)
end
test "returns true just over 30 minutes of inactivity" do
old_time = DateTime.add(DateTime.utc_now(), -30, :minute)
old_time = DateTime.add(old_time, -1, :second)
session = %{last_activity_at: old_time}
assert UpdateSessionActivity.session_timed_out?(session)
end
end
describe "handle_session_activity/2" do
test "returns :ok when no session found for token" do
assert :ok == UpdateSessionActivity.handle_session_activity("nonexistent-token", nil)
end
test "returns :ok when session found and not timed out" do
user = Towerops.AccountsFixtures.user_fixture()
{_token, user_token} = Towerops.Accounts.generate_user_session_token_with_record(user)
%BrowserSession{}
|> BrowserSession.create_changeset(%{
user_id: user.id,
user_token_id: user_token.id,
ip_address: "127.0.0.1",
last_activity_at: DateTime.utc_now(),
expires_at: DateTime.add(DateTime.utc_now(), 7, :day)
})
|> Towerops.Repo.insert!()
assert :ok == UpdateSessionActivity.handle_session_activity(user_token.id, nil)
end
end
describe "revoke_inactive_session/2" do
test "returns nil when no live_socket_id" do
user = Towerops.AccountsFixtures.user_fixture()
token = Towerops.Accounts.generate_user_session_token(user)
assert nil == UpdateSessionActivity.revoke_inactive_session(token, nil)
end
test "broadcasts disconnect when live_socket_id present" do
user = Towerops.AccountsFixtures.user_fixture()
token = Towerops.Accounts.generate_user_session_token(user)
ToweropsWeb.Endpoint.subscribe("users_sessions:test-session")
assert :ok == UpdateSessionActivity.revoke_inactive_session(token, "users_sessions:test-session")
assert_receive %Phoenix.Socket.Broadcast{event: "disconnect", topic: "users_sessions:test-session"}
end
end
end