defmodule Plausible.Plugins.API.TokensTest do use Plausible.DataCase, async: true alias Plausible.Plugins.API.Token alias Plausible.Plugins.API.Tokens alias Plausible.Repo describe "create/2" do test "generates and stores the token" do site = insert(:site) assert {:ok, %Token{} = token, raw} = Tokens.create(site, "My test token") from_db = Repo.get(Token, token.id) assert from_db.token_hash == token.token_hash assert from_db.description == "My test token" assert from_db.site_id == site.id hint = from_db.hint assert is_binary(hint) and byte_size(hint) == 4 assert String.ends_with?(raw, hint) end test "fails to store on input errors" do site = insert(:site) assert {:error, %Ecto.Changeset{}} = Tokens.create(site, nil) end end describe "find/2" do test "finds the right token" do site = insert(:site) assert {:ok, _, raw} = Tokens.create(site, "My test token") assert {:ok, found} = Tokens.find(raw) assert found.id == found.id assert found.site_id == site.id end test "fails to find the token" do assert {:error, :not_found} = Tokens.find("non-existing") end end describe "any?/2" do test "returns if a site has any tokens" do site1 = insert(:site, domain: "foo1.example.com") site2 = insert(:site, domain: "foo2.example.com") assert Tokens.any?(site1) == false assert Tokens.any?(site2) == false assert {:ok, _, _} = Tokens.create(site1, "My test token") assert Tokens.any?(site1) == true assert Tokens.any?(site2) == false end end describe "delete/2" do test "deletes a token" do site1 = insert(:site, domain: "foo1.example.com") site2 = insert(:site, domain: "foo2.example.com") assert {:ok, t1, _} = Tokens.create(site1, "My test token") assert {:ok, t2, _} = Tokens.create(site1, "My test token") assert {:ok, _, _} = Tokens.create(site2, "My test token") :ok = Tokens.delete(site1, t1.id) # idempotent :ok = Tokens.delete(site1, t1.id) assert Tokens.any?(site1) :ok = Tokens.delete(site1, t2.id) refute Tokens.any?(site1) assert Tokens.any?(site2) end end describe "update_last_seen/1" do test "updates in 5m window" do site = insert(:site) assert {:ok, token0, _} = Tokens.create(site, "My test token") now = NaiveDateTime.utc_now() {:ok, token1} = Tokens.update_last_seen(token0, now) {:ok, token2} = Tokens.update_last_seen(token1, NaiveDateTime.shift(now, minute: 2)) assert token1.last_used_at == token2.last_used_at {:ok, token3} = Tokens.update_last_seen(token2, NaiveDateTime.shift(now, minute: 6)) assert NaiveDateTime.compare(token3.last_used_at, token2.last_used_at) == :gt end end end