defmodule OhMyExOhIrcd.ScrobblesTest do
use OhMyExOhIrcd.DataCase, async: true
import OhMyExOhIrcd.AccountsFixtures
alias OhMyExOhIrcd.Channels
alias OhMyExOhIrcd.Scrobbles
setup do
user = user_fixture()
chan = "#scr-#{System.unique_integer([:positive])}"
{:ok, _rec} = Channels.register(chan, user)
{:ok, user: user, chan: chan}
end
describe "config" do
test "ensure_config requires a registered channel" do
assert {:error, :not_registered} = Scrobbles.ensure_config("#nope-#{System.unique_integer()}")
end
test "ensure_config creates an enabled, not-joined config", %{chan: chan} do
assert {:ok, cfg} = Scrobbles.ensure_config(chan)
assert cfg.enabled
refute cfg.joined
assert cfg.format =~ "%who%"
end
test "ensure_config is idempotent", %{chan: chan} do
{:ok, a} = Scrobbles.ensure_config(chan)
{:ok, b} = Scrobbles.ensure_config(chan)
assert a.id == b.id
end
test "update_config + toggles", %{chan: chan} do
{:ok, _} = Scrobbles.set_enabled(chan, false)
{:ok, _} = Scrobbles.set_format(chan, "%who%: %track%")
{:ok, _} = Scrobbles.set_rate_limit(chan, 5)
{:ok, _} = Scrobbles.set_restrict(chan, true)
cfg = Scrobbles.get_config(chan)
refute cfg.enabled
assert cfg.format == "%who%: %track%"
assert cfg.rate_limit_seconds == 5
assert cfg.restrict_to_allowlist
end
test "format strips control chars", %{chan: chan} do
{:ok, cfg} = Scrobbles.set_format(chan, "%who%\r\nPRIVMSG #evil :x")
refute cfg.format =~ "\n"
refute cfg.format =~ "\r"
end
test "allowlist add/remove is downcased and deduped", %{chan: chan} do
{:ok, _} = Scrobbles.add_allow(chan, "GMP")
{:ok, _} = Scrobbles.add_allow(chan, "gmp")
assert Scrobbles.get_config(chan).allowlist == ["gmp"]
{:ok, _} = Scrobbles.remove_allow(chan, "Gmp")
assert Scrobbles.get_config(chan).allowlist == []
end
test "list_joined_channels only returns joined", %{chan: chan} do
{:ok, _} = Scrobbles.ensure_config(chan)
refute chan in Scrobbles.list_joined_channels()
{:ok, _} = Scrobbles.set_joined(chan, true)
assert chan in Scrobbles.list_joined_channels()
end
end
describe "tokens" do
test "mint + verify round-trips channel, who and user", %{chan: chan, user: user} do
assert {:ok, display, token} = Scrobbles.mint_token(chan, user, "gmp", "laptop")
assert is_binary(display)
assert token.label == "laptop"
assert token.who == "gmp"
assert token.user_id == user.id
assert {:ok, %{channel: channel, who: who, user_id: uid}} = Scrobbles.verify_token(display)
assert channel.name == String.downcase(chan)
assert who == "gmp"
assert uid == user.id
end
test "mint requires a non-blank who", %{chan: chan, user: user} do
assert {:error, :blank_who} = Scrobbles.mint_token(chan, user, " ", "x")
end
test "verify bumps last_used_at", %{chan: chan, user: user} do
{:ok, display, token} = Scrobbles.mint_token(chan, user, "gmp", nil)
assert token.last_used_at == nil
{:ok, _} = Scrobbles.verify_token(display)
[refreshed] = Scrobbles.list_tokens(chan)
assert refreshed.last_used_at
end
test "revoked tokens no longer verify", %{chan: chan, user: user} do
{:ok, display, token} = Scrobbles.mint_token(chan, user, "gmp", nil)
:ok = Scrobbles.revoke_token(chan, token.id)
assert :error = Scrobbles.verify_token(display)
assert Scrobbles.list_tokens(chan) == []
end
test "garbage tokens return :error", %{chan: _chan} do
assert :error = Scrobbles.verify_token("not-a-real-token")
assert :error = Scrobbles.verify_token("!!!not base64!!!")
end
end
describe "history" do
test "record + recent newest-first with limit", %{chan: chan} do
%{id: id} = Channels.get(chan)
for n <- 1..5, do: {:ok, _} = Scrobbles.record_scrobble(id, %{who: "w", artist: "a", track: "t#{n}"})
recent = Scrobbles.recent(chan, 3)
assert length(recent) == 3
assert hd(recent).track == "t5"
end
end
describe "request logs" do
test "log + recent newest-first", %{chan: chan} do
%{id: id} = Channels.get(chan)
{:ok, _} = Scrobbles.log_request(id, %{who: "gmp", status: "ok"})
{:ok, _} = Scrobbles.log_request(id, %{who: "gmp", status: "ignored", detail: "rate_limited"})
logs = Scrobbles.recent_logs(chan, 10)
assert length(logs) == 2
assert hd(logs).status == "ignored"
assert hd(logs).detail == "rate_limited"
end
test "prunes beyond retention", %{chan: chan} do
%{id: id} = Channels.get(chan)
for n <- 1..205, do: {:ok, _} = Scrobbles.log_request(id, %{who: "w", status: "ok", detail: "#{n}"})
# Retention caps stored rows at 200.
assert length(Scrobbles.recent_logs(chan, 1000)) == 200
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.9 KiB · text
History
4b6fe3b