defmodule OhMyExOhIrcd.SightingsTest do
use OhMyExOhIrcd.DataCase, async: true
import OhMyExOhIrcd.AccountsFixtures
alias OhMyExOhIrcd.Sightings
alias OhMyExOhIrcd.Sightings.Sighting
defp at(days_ago, now \\ ~U[2026-10-27 12:00:00Z]),
do: DateTime.add(now, -days_ago * 86_400, :second)
defp nick(prefix), do: "#{prefix}#{System.unique_integer([:positive])}"
describe "record/1 keying" do
test "an anonymous nick is one row per downcased nick; first_seen_at is kept" do
n = nick("Anon")
{:ok, first} =
Sightings.record(%{nick: n, host: "a.cloak", real_ip: "10.0.0.1", at: at(3)})
{:ok, second} =
Sightings.record(%{
nick: String.upcase(n),
host: "b.cloak",
real_ip: "10.0.0.2",
at: at(1)
})
assert first.id == second.id
assert second.nick == String.upcase(n)
assert second.nick_key == String.downcase(n)
assert second.first_seen_at == at(3)
assert second.last_seen_at == at(1)
assert second.host == "b.cloak"
assert second.real_ip == "10.0.0.2"
assert is_nil(second.user_id)
end
test "a registered account is one row whatever nick it used" do
user = user_fixture()
{:ok, a} = Sightings.record(%{nick: nick("old"), user_id: user.id, host: "h", at: at(2)})
new_nick = nick("new")
{:ok, b} = Sightings.record(%{nick: new_nick, user_id: user.id, host: "h2", at: at(1)})
assert a.id == b.id
assert b.nick == new_nick
assert b.first_seen_at == at(2)
assert Repo.aggregate(from(s in Sighting, where: s.user_id == ^user.id), :count) == 1
end
test "the same nick, anonymous and registered, is two rows" do
n = nick("shared")
user = user_fixture()
{:ok, anon} = Sightings.record(%{nick: n})
{:ok, reg} = Sightings.record(%{nick: n, user_id: user.id})
refute anon.id == reg.id
assert reg.user_id == user.id
end
test "last_seen_at never moves backwards; a known IP and quit reason are kept" do
n = nick("order")
{:ok, _} = Sightings.record(%{nick: n, real_ip: "10.1.1.1", quit_reason: "bye", at: at(1)})
{:ok, row} = Sightings.record(%{nick: n, at: at(5)})
assert row.last_seen_at == at(1)
assert row.real_ip == "10.1.1.1"
assert row.last_quit_reason == "bye"
end
test "service nicks are skipped" do
assert :skipped = Sightings.record(%{nick: OhMyExOhIrcd.IRC.ChanServ.nick()})
assert :skipped = Sightings.record(%{nick: "imgserv"})
end
end
describe "prune/1" do
test "removes old unregistered rows, keeps recent ones and every registered row" do
now = ~U[2026-10-27 12:00:00Z]
user = user_fixture()
{:ok, old_anon} = Sightings.record(%{nick: nick("stale"), at: at(91, now)})
{:ok, recent_anon} = Sightings.record(%{nick: nick("fresh"), at: at(89, now)})
{:ok, old_reg} =
Sightings.record(%{nick: nick("loyal"), user_id: user.id, at: at(400, now)})
assert Sightings.prune(now) >= 1
refute Repo.get(Sighting, old_anon.id)
assert Repo.get(Sighting, recent_anon.id)
assert Repo.get(Sighting, old_reg.id)
end
end
describe "list_recent/2" do
test "newest first, filtered by type, with the account preloaded" do
user = user_fixture()
{:ok, anon} = Sightings.record(%{nick: nick("la"), at: at(2)})
{:ok, reg} = Sightings.record(%{nick: nick("lr"), user_id: user.id, at: at(1)})
ids = Sightings.list_recent(:all) |> Enum.map(& &1.id)
assert Enum.find_index(ids, &(&1 == reg.id)) < Enum.find_index(ids, &(&1 == anon.id))
[only_reg] = Sightings.list_recent(:registered) |> Enum.filter(&(&1.id == reg.id))
assert only_reg.user.email == user.email
refute Enum.any?(Sightings.list_recent(:registered), &(&1.id == anon.id))
refute Enum.any?(Sightings.list_recent(:unregistered), &(&1.id == reg.id))
assert Enum.any?(Sightings.list_recent(:unregistered), &(&1.id == anon.id))
end
end
end
neiam
/oh-my-ex-oh-ircd
public · Issues · Pulls · Labels · Forks · Compare · Actions success · Badges · Packages
⭐
Log in to mark this repository.
4.0 KiB · text
History
4b6fe3b