towerops/test/towerops/workers/session_cleanup_worker_test.exs
2026-02-03 11:02:38 -06:00

153 lines
4.8 KiB
Elixir

defmodule Towerops.Workers.SessionCleanupWorkerTest do
use Towerops.DataCase, async: true
import Towerops.AccountsFixtures
alias Towerops.Accounts
alias Towerops.Accounts.BrowserSession
alias Towerops.Workers.SessionCleanupWorker
describe "perform/1" do
test "deletes expired browser sessions" do
user = user_fixture()
{_token, user_token} = Accounts.generate_user_session_token_with_record(user)
# Create an expired session (1 day ago)
expired_session =
insert_browser_session(%{
user_id: user.id,
user_token_id: user_token.id,
expires_at: DateTime.add(DateTime.utc_now(), -1, :day)
})
# Execute the worker
assert {:ok, %{sessions_deleted: 1}} =
SessionCleanupWorker.perform(%Oban.Job{args: %{}})
# Verify expired session was deleted
refute Repo.get(BrowserSession, expired_session.id)
end
test "keeps non-expired browser sessions" do
user = user_fixture()
{_token, user_token} = Accounts.generate_user_session_token_with_record(user)
# Create a valid session (expires in 1 day)
valid_session =
insert_browser_session(%{
user_id: user.id,
user_token_id: user_token.id,
expires_at: DateTime.add(DateTime.utc_now(), 1, :day)
})
# Execute the worker
assert {:ok, %{sessions_deleted: 0}} =
SessionCleanupWorker.perform(%Oban.Job{args: %{}})
# Verify valid session still exists
assert Repo.get(BrowserSession, valid_session.id)
end
test "deletes only expired sessions among mixed sessions" do
user = user_fixture()
{_token1, user_token1} = Accounts.generate_user_session_token_with_record(user)
{_token2, user_token2} = Accounts.generate_user_session_token_with_record(user)
{_token3, user_token3} = Accounts.generate_user_session_token_with_record(user)
# Create 2 expired sessions
expired1 =
insert_browser_session(%{
user_id: user.id,
user_token_id: user_token1.id,
expires_at: DateTime.add(DateTime.utc_now(), -2, :day)
})
expired2 =
insert_browser_session(%{
user_id: user.id,
user_token_id: user_token2.id,
expires_at: DateTime.add(DateTime.utc_now(), -1, :hour)
})
# Create 1 valid session
valid_session =
insert_browser_session(%{
user_id: user.id,
user_token_id: user_token3.id,
expires_at: DateTime.add(DateTime.utc_now(), 7, :day)
})
# Execute the worker
assert {:ok, %{sessions_deleted: 2}} =
SessionCleanupWorker.perform(%Oban.Job{args: %{}})
# Verify expired sessions were deleted
refute Repo.get(BrowserSession, expired1.id)
refute Repo.get(BrowserSession, expired2.id)
# Verify valid session still exists
assert Repo.get(BrowserSession, valid_session.id)
end
test "returns zero count when no expired sessions exist" do
user = user_fixture()
{_token, user_token} = Accounts.generate_user_session_token_with_record(user)
# Create only valid sessions
insert_browser_session(%{
user_id: user.id,
user_token_id: user_token.id,
expires_at: DateTime.add(DateTime.utc_now(), 1, :day)
})
# Execute the worker
assert {:ok, %{sessions_deleted: 0}} =
SessionCleanupWorker.perform(%Oban.Job{args: %{}})
end
test "works when no sessions exist at all" do
# Execute the worker with no sessions in the database
assert {:ok, %{sessions_deleted: 0}} =
SessionCleanupWorker.perform(%Oban.Job{args: %{}})
end
test "handles sessions that expired exactly now" do
user = user_fixture()
{_token, user_token} = Accounts.generate_user_session_token_with_record(user)
now = DateTime.utc_now()
# Create a session that expires exactly now (should be considered expired)
expired_now =
insert_browser_session(%{
user_id: user.id,
user_token_id: user_token.id,
expires_at: now
})
# Execute the worker
assert {:ok, %{sessions_deleted: count}} =
SessionCleanupWorker.perform(%Oban.Job{args: %{}})
# The session should be deleted (expires_at < now, not <=)
# Actually, checking the code: where([bs], bs.expires_at < ^now)
# So expires_at == now should NOT be deleted
assert count == 0
assert Repo.get(BrowserSession, expired_now.id)
end
end
# Helper function to create browser sessions
defp insert_browser_session(attrs) do
default_attrs = %{
ip_address: "192.168.1.1",
last_activity_at: DateTime.utc_now()
}
attrs = Map.merge(default_attrs, attrs)
%BrowserSession{}
|> BrowserSession.create_changeset(attrs)
|> Repo.insert!()
end
end