| defmodule Plausible.Shields.HostnameTest do |
| use Plausible.DataCase |
| import Plausible.Shields |
|
|
| setup do |
| site = insert(:site) |
| {:ok, %{site: site}} |
| end |
|
|
| describe "add_hostname_rule/2" do |
| test "no input", %{site: site} do |
| assert {:error, changeset} = add_hostname_rule(site, %{}) |
| assert changeset.errors == [hostname: {"can't be blank", [validation: :required]}] |
| refute changeset.valid? |
| end |
|
|
| test "lengthy", %{site: site} do |
| long = "/" <> :binary.copy("a", 251) |
| assert {:error, changeset} = add_hostname_rule(site, %{"hostname" => long}) |
| assert [hostname: {"should be at most %{count} character(s)", _}] = changeset.errors |
| refute changeset.valid? |
| end |
|
|
| test "double insert", %{site: site} do |
| assert {:ok, _} = add_hostname_rule(site, %{"hostname" => "/test"}) |
| assert {:error, changeset} = add_hostname_rule(site, %{"hostname" => "/test"}) |
| refute changeset.valid? |
|
|
| assert changeset.errors == [ |
| hostname: |
| {"rule already exists", |
| [ |
| {:constraint, :unique}, |
| {:constraint_name, "shield_rules_hostname_site_id_hostname_pattern_index"} |
| ]} |
| ] |
| end |
|
|
| test "equivalent rules are counted as dupes", %{site: site} do |
| assert {:ok, _} = add_hostname_rule(site, %{"hostname" => "test*"}) |
| assert {:error, changeset} = add_hostname_rule(site, %{"hostname" => "test**"}) |
|
|
| assert changeset.errors == [ |
| hostname: |
| {"rule already exists", |
| [ |
| {:constraint, :unique}, |
| {:constraint_name, "shield_rules_hostname_site_id_hostname_pattern_index"} |
| ]} |
| ] |
| end |
|
|
| test "regex storage: wildcard", %{site: site} do |
| assert {:ok, rule} = add_hostname_rule(site, %{"hostname" => "*test"}) |
| assert rule.hostname_pattern == "^.*test$" |
| end |
|
|
| test "regex storage: no wildcard", %{site: site} do |
| assert {:ok, rule} = add_hostname_rule(site, %{"hostname" => "test"}) |
| assert rule.hostname_pattern == "^test$" |
| end |
|
|
| test "regex storage: escaping", %{site: site} do |
| assert {:ok, rule} = add_hostname_rule(site, %{"hostname" => "test.*.**.|+[0-9]"}) |
| assert rule.hostname_pattern == "^test\\..*\\..*\\.\\|\\+\\[0\\-9\\]$" |
| end |
|
|
| test "over limit", %{site: site} do |
| for i <- 1..maximum_hostname_rules() do |
| assert {:ok, _} = |
| add_hostname_rule(site, %{"hostname" => "test-#{i}"}) |
| end |
|
|
| assert count_hostname_rules(site) == maximum_hostname_rules() |
|
|
| assert {:error, changeset} = |
| add_hostname_rule(site, %{"hostname" => "test.limit"}) |
|
|
| refute changeset.valid? |
| assert changeset.errors == [hostname: {"maximum reached", []}] |
| end |
|
|
| test "with added_by", %{site: site} do |
| assert {:ok, rule} = |
| add_hostname_rule(site, %{"hostname" => "test.example.com"}, |
| added_by: build(:user, name: "Joe", email: "joe@example.com") |
| ) |
|
|
| assert rule.added_by == "Joe <joe@example.com>" |
| end |
|
|
| test "ignores site_id supplied in params", %{site: site} do |
| victim = insert(:site) |
|
|
| assert {:ok, rule} = |
| add_hostname_rule(site, %{"hostname" => "example.com", "site_id" => victim.id}) |
|
|
| assert rule.site_id == site.id |
| assert count_hostname_rules(victim) == 0 |
| end |
| end |
|
|
| describe "hostname pattern matching" do |
| test "no wildcard", %{site: site} do |
| assert {:ok, _} = add_hostname_rule(site, %{"hostname" => "test.example.com"}) |
| assert hostname_allowed?(site, "test.example.com") |
| refute hostname_allowed?(site, "subdmoain.example.com") |
| refute hostname_allowed?(site, "test") |
| end |
|
|
| test "wildcard - subdomains", %{site: site} do |
| assert {:ok, _} = add_hostname_rule(site, %{"hostname" => "*.example.com"}) |
| refute hostname_allowed?(site, "example.com") |
| refute hostname_allowed?(site, "example.com.pl") |
| assert hostname_allowed?(site, "subdomain.example.com") |
| end |
|
|
| test "wildcard - any prefix", %{site: site} do |
| assert {:ok, _} = add_hostname_rule(site, %{"hostname" => "*example.com"}) |
| assert hostname_allowed?(site, "example.com") |
| refute hostname_allowed?(site, "example.com.pl") |
| assert hostname_allowed?(site, "subdomain.example.com") |
| end |
| end |
|
|
| describe "remove_hostname_rule/2" do |
| test "is idempontent", %{site: site} do |
| {:ok, rule} = add_hostname_rule(site, %{"hostname" => "test"}) |
| assert remove_hostname_rule(site, rule.id) == :ok |
| refute Repo.get(Plausible.Shield.HostnameRule, rule.id) |
| assert remove_hostname_rule(site, rule.id) == :ok |
| end |
| end |
|
|
| describe "list_hostname_rules/1" do |
| test "empty", %{site: site} do |
| assert(list_hostname_rules(site) == []) |
| end |
|
|
| @tag :slow |
| test "many", %{site: site} do |
| {:ok, %{id: id1}} = add_hostname_rule(site, %{"hostname" => "test1.example.com"}) |
| :timer.sleep(1000) |
| {:ok, %{id: id2}} = add_hostname_rule(site, %{"hostname" => "test2.example.com"}) |
| assert [%{id: ^id2}, %{id: ^id1}] = list_hostname_rules(site) |
| end |
| end |
|
|
| describe "count_hostname_rules/1" do |
| test "counts", %{site: site} do |
| assert count_hostname_rules(site) == 0 |
| {:ok, _} = add_hostname_rule(site, %{"hostname" => "test1"}) |
| assert count_hostname_rules(site) == 1 |
| {:ok, _} = add_hostname_rule(site, %{"hostname" => "test2"}) |
| assert count_hostname_rules(site) == 2 |
| end |
| end |
|
|
| describe "allowed_hostname_patterns/1" do |
| test "returns a list of regular expressions when rules are defined", %{site: site} do |
| {:ok, _} = add_hostname_rule(site, %{"hostname" => "example.com"}) |
| {:ok, _} = add_hostname_rule(site, %{"hostname" => "another.example.com"}) |
| {:ok, _} = add_hostname_rule(site, %{"hostname" => "app.*"}) |
|
|
| allowed = allowed_hostname_patterns(site.domain) |
|
|
| assert length(allowed) == 3 |
| assert "^example\\.com$" in allowed |
| assert "^another\\.example\\.com$" in allowed |
| assert "^app\\..*$" in allowed |
| end |
| end |
|
|
| describe "Hostname Rules" do |
| test "end to end", %{site: site} do |
| site2 = insert(:site) |
|
|
| assert count_hostname_rules(site.id) == 0 |
| assert list_hostname_rules(site.id) == [] |
|
|
| assert {:ok, rule} = |
| add_hostname_rule(site.id, %{ |
| "hostname" => "blog.example.com" |
| }) |
|
|
| add_hostname_rule(site2, %{"hostname" => "portral.example.com"}) |
|
|
| assert count_hostname_rules(site) == 1 |
| assert [%{id: rule_id}] = list_hostname_rules(site) |
| assert rule.id == rule_id |
| assert rule.hostname == "blog.example.com" |
| assert rule.action == :allow |
| refute rule.from_cache? |
| assert hostname_allowed?(site, "blog.example.com") |
| refute hostname_allowed?(site, "portal.example.com") |
| end |
| end |
| end |
|
|