File size: 2,878 Bytes
c9c49ab
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
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