- ErrorHTML: explicit 400 path + 401/403/999 delegation.
- Layouts.body_class/1 returns the expected light/dark theme classes.
- MapLive.Components: map_container + slideover_panel exercising all
connection_status variants, loading state, tracked_callsign clear
button, and view-mode radios.
- CoreComponents: icon (found + fallback), button, label, error,
flash (info + error + close=false), checkbox input, JS composers.
- Accounts: get_user_by_email{_and_password}, get_user!, register_user
happy-path + error paths, change_* changesets, session-token
round-trip.
Refactor: DeviceIdentification.maybe_refresh_devices splits its nested
logic into fetch_most_recent_device/0, to_datetime/1, and
refresh_if_stale/2 — each a multi-clause function matching on shape.
Coverage 68.28 → 69.56%.
111 lines
3.4 KiB
Elixir
111 lines
3.4 KiB
Elixir
defmodule Aprsme.AccountsTest do
|
|
use Aprsme.DataCase, async: true
|
|
|
|
import Aprsme.AccountsFixtures
|
|
|
|
alias Aprsme.Accounts
|
|
alias Aprsme.Accounts.User
|
|
|
|
describe "get_user_by_email/1" do
|
|
test "returns the user when email matches" do
|
|
user = user_fixture()
|
|
assert Accounts.get_user_by_email(user.email).id == user.id
|
|
end
|
|
|
|
test "returns nil for unknown email" do
|
|
assert Accounts.get_user_by_email("nobody@example.com") == nil
|
|
end
|
|
end
|
|
|
|
describe "get_user_by_email_and_password/2" do
|
|
test "returns the user for the right password" do
|
|
user = user_fixture()
|
|
assert Accounts.get_user_by_email_and_password(user.email, valid_user_password()).id == user.id
|
|
end
|
|
|
|
test "returns nil for wrong password" do
|
|
user = user_fixture()
|
|
assert Accounts.get_user_by_email_and_password(user.email, "wrong-password-123") == nil
|
|
end
|
|
|
|
test "returns nil when user doesn't exist" do
|
|
assert Accounts.get_user_by_email_and_password("nobody@example.com", "whatever") == nil
|
|
end
|
|
end
|
|
|
|
describe "get_user!/1" do
|
|
test "returns the user by id" do
|
|
user = user_fixture()
|
|
assert Accounts.get_user!(user.id).id == user.id
|
|
end
|
|
|
|
test "raises for unknown id" do
|
|
assert_raise Ecto.NoResultsError, fn ->
|
|
Accounts.get_user!(-1)
|
|
end
|
|
end
|
|
end
|
|
|
|
describe "register_user/1" do
|
|
test "inserts a new user with valid attrs" do
|
|
attrs = valid_user_attributes()
|
|
assert {:ok, %User{} = user} = Accounts.register_user(attrs)
|
|
assert user.email == attrs.email
|
|
end
|
|
|
|
test "returns an error changeset for invalid attrs" do
|
|
assert {:error, %Ecto.Changeset{}} = Accounts.register_user(%{})
|
|
end
|
|
|
|
test "returns an error for duplicate email" do
|
|
user = user_fixture()
|
|
assert {:error, changeset} = Accounts.register_user(valid_user_attributes(%{email: user.email}))
|
|
assert "has already been taken" in errors_on(changeset).email
|
|
end
|
|
end
|
|
|
|
describe "change_user_registration/2" do
|
|
test "returns a changeset with casted attrs" do
|
|
changeset = Accounts.change_user_registration(%User{}, valid_user_attributes())
|
|
assert %Ecto.Changeset{valid?: true} = changeset
|
|
end
|
|
end
|
|
|
|
describe "change_user_email/2" do
|
|
test "returns an email-focused changeset" do
|
|
user = user_fixture()
|
|
changeset = Accounts.change_user_email(user, %{"email" => "new@example.com"})
|
|
assert %Ecto.Changeset{} = changeset
|
|
end
|
|
end
|
|
|
|
describe "change_user_password/2" do
|
|
test "returns a password-focused changeset" do
|
|
user = user_fixture()
|
|
changeset = Accounts.change_user_password(user, %{"password" => "new valid password"})
|
|
assert %Ecto.Changeset{} = changeset
|
|
end
|
|
end
|
|
|
|
describe "change_user_callsign/2" do
|
|
test "returns a callsign-focused changeset" do
|
|
user = user_fixture()
|
|
changeset = Accounts.change_user_callsign(user, %{"callsign" => "K5XYZ"})
|
|
assert %Ecto.Changeset{} = changeset
|
|
end
|
|
end
|
|
|
|
describe "session tokens" do
|
|
test "generate + get + delete round-trip" do
|
|
user = user_fixture()
|
|
token = Accounts.generate_user_session_token(user)
|
|
assert is_binary(token)
|
|
|
|
fetched = Accounts.get_user_by_session_token(token)
|
|
assert fetched.id == user.id
|
|
|
|
assert :ok = Accounts.delete_user_session_token(token)
|
|
assert Accounts.get_user_by_session_token(token) == nil
|
|
end
|
|
end
|
|
end
|