analytics/test/plausible/segments/segment_test.exs

122 lines
3.9 KiB
Elixir

defmodule Plausible.Segments.SegmentTest do
use ExUnit.Case
alias Plausible.Segments.Segment
doctest Segment, import: true
setup do
segment = %Segment{
name: "any name",
type: :personal,
segment_data: %{"filters" => ["is", "visit:page", ["/blog"]]},
owner_id: 1,
site_id: 100
}
{:ok, segment: segment}
end
test "changeset has required fields" do
assert Segment.changeset(%Segment{}, %{}).errors == [
segment_data: {"property \"filters\" must be an array with at least one member", []},
name: {"can't be blank", [validation: :required]},
segment_data: {"can't be blank", [validation: :required]},
site_id: {"can't be blank", [validation: :required]},
type: {"can't be blank", [validation: :required]},
owner_id: {"can't be blank", [validation: :required]}
]
end
test "changeset does not allow setting owner_id to nil (setting to nil happens with database triggers)",
%{segment: valid_segment} do
assert Segment.changeset(
valid_segment,
%{
owner_id: nil
}
).errors == [
owner_id: {"can't be blank", [validation: :required]}
]
end
test "changeset forbids too long name", %{segment: valid_segment} do
assert Segment.changeset(
valid_segment,
%{
name: String.duplicate("a", 256)
}
).errors == [
name:
{"should be at most %{count} byte(s)",
[{:count, 255}, {:validation, :length}, {:kind, :max}, {:type, :binary}]}
]
end
test "changeset forbids too large segment_data", %{segment: valid_segment} do
assert Segment.changeset(
valid_segment,
%{
segment_data:
Jason.decode!(
~s({"filters": ["is", "visit:exit_page", [#{Enum.map_join(1..(5 * 1024), ",", fn i -> "#{i}" end)}]]})
)
}
).errors == [
segment_data: {"should be at most %{count} byte(s)", [{:count, 5120}]}
]
end
test "changeset allows setting nil owner_id to a user id (to be able to recover dangling site segments)",
%{segment: valid_segment = %Segment{}} do
assert Segment.changeset(
%Segment{
valid_segment
| owner_id: nil
},
%{
owner_id: 100_100
}
).valid? == true
end
test "changeset requires segment_data to be structured as expected", %{segment: valid_segment} do
assert Segment.changeset(
valid_segment,
%{
segment_data: %{"filters" => 1, "labels" => true, "other" => []}
}
).errors == [
{:segment_data, {"property \"labels\" must be map or nil", []}},
{:segment_data,
{"property \"filters\" must be an array with at least one member", []}},
{:segment_data,
{"must not contain any other property except \"filters\" and \"labels\"", []}}
]
end
test "changeset forbids empty filters list", %{segment: valid_segment} do
assert Segment.changeset(
valid_segment,
%{
segment_data: %{
"filters" => []
}
}
).errors == [
{:segment_data,
{"property \"filters\" must be an array with at least one member", []}}
]
end
test "changeset permits well-structured segment data", %{segment: valid_segment} do
assert Segment.changeset(
valid_segment,
%{
segment_data: %{
"filters" => [["is", "visit:country", ["DE"]]],
"labels" => %{"DE" => "Germany"}
}
}
).valid? == true
end
end