2.6 KiB · text History 4b6fe3b
defmodule OhMyExOhIrcd.LinksTest do
  use OhMyExOhIrcd.DataCase, async: true

  alias OhMyExOhIrcd.Links

  describe "create_link/1" do
    test "creates with a downcased slug" do
      assert {:ok, link} =
               Links.create_link(%{"slug" => "ScroppleApp", "url" => "https://example.com/a.apk"})

      assert link.slug == "scroppleapp"
    end

    test "rejects an invalid slug" do
      assert {:error, changeset} =
               Links.create_link(%{"slug" => "bad slug!", "url" => "https://x.test"})

      refute changeset.valid?
      assert errors_on(changeset)[:slug]
    end

    test "rejects a non-http(s) url" do
      assert {:error, changeset} = Links.create_link(%{"slug" => "ok", "url" => "ftp://x.test"})
      assert errors_on(changeset)[:url]
    end

    test "enforces unique slugs" do
      assert {:ok, _} = Links.create_link(%{"slug" => "dup", "url" => "https://a.test"})

      assert {:error, changeset} =
               Links.create_link(%{"slug" => "dup", "url" => "https://b.test"})

      assert "has already been taken" in errors_on(changeset).slug
    end
  end

  describe "get_by_slug/1" do
    test "is case-insensitive and trims" do
      {:ok, _} = Links.create_link(%{"slug" => "casecheck", "url" => "https://a.test"})
      assert Links.get_by_slug("  CaseCheck ").slug == "casecheck"
      assert Links.get_by_slug("missing") == nil
    end
  end

  describe "record_click/2 and metrics/1" do
    test "increments counters and aggregates metrics" do
      {:ok, link} = Links.create_link(%{"slug" => "metricz", "url" => "https://example.com"})

      :ok = Links.record_click(link, %{referer: "https://t.co/x", user_agent: "UA/1"})
      :ok = Links.record_click(link, %{referer: nil, user_agent: "UA/1"})

      link = Links.get_by_slug("metricz")
      assert link.click_count == 2
      assert link.last_clicked_at

      m = Links.metrics(link)
      assert m.total == 2
      assert m.last_24h == 2
      assert m.last_7d == 2
      assert Enum.any?(m.top_user_agents, &(&1.value == "UA/1" and &1.count == 2))
      assert Enum.any?(m.top_referrers, &(&1.value == "(direct)"))
      assert length(m.recent) == 2
    end
  end

  describe "delete_link/1" do
    test "deletes a link and its clicks" do
      {:ok, link} = Links.create_link(%{"slug" => "doomed", "url" => "https://a.test"})
      :ok = Links.record_click(link, %{referer: nil, user_agent: "UA"})

      assert {:ok, _} = Links.delete_link(link.id)
      assert Links.get_by_slug("doomed") == nil
    end

    test "returns {:error, :not_found} for a missing id" do
      assert {:error, :not_found} = Links.delete_link(-1)
    end
  end
end