3 changed files with 348 additions and 74 deletions
@ -0,0 +1,283 @@
@@ -0,0 +1,283 @@
|
||||
defmodule GcIndexRelayWeb.FilterControllerTest do |
||||
use GcIndexRelayWeb.ConnCase |
||||
|
||||
import GcIndexRelay.NostrFixtures |
||||
|
||||
@moduletag :integration |
||||
|
||||
setup %{conn: conn} do |
||||
conn = |
||||
conn |
||||
|> put_req_header("accept", "application/json") |
||||
|> put_req_header("content-type", "application/json") |
||||
|
||||
{:ok, conn: conn} |
||||
end |
||||
|
||||
describe "GET /api/events (index)" do |
||||
test "returns empty list when no events exist", %{conn: conn} do |
||||
conn = get(conn, ~p"/api/events?since=0&until=9999999999&limit=10") |
||||
|
||||
assert %{"data" => []} = json_response(conn, 200) |
||||
end |
||||
|
||||
test "returns events within time range", %{conn: conn} do |
||||
event_fixture(%{created_at: 1_640_000_100}) |
||||
conn = get(conn, ~p"/api/events?since=0&until=9999999999&limit=10") |
||||
|
||||
assert %{"data" => events} = json_response(conn, 200) |
||||
assert length(events) == 1 |
||||
end |
||||
|
||||
test "filters by authors", %{conn: conn} do |
||||
%{keypair1: keypair1, keypair2: keypair2} = test_keypairs() |
||||
event_fixture(%{keypair: :keypair1}) |
||||
event_fixture(%{keypair: :keypair2}) |
||||
|
||||
conn = |
||||
get( |
||||
conn, |
||||
~p"/api/events?since=0&until=9999999999&limit=10&authors=#{keypair1.public_key_hex}" |
||||
) |
||||
|
||||
assert %{"data" => events} = json_response(conn, 200) |
||||
assert length(events) == 1 |
||||
assert hd(events)["pubkey"] == keypair1.public_key_hex |
||||
assert hd(events)["pubkey"] != keypair2.public_key_hex |
||||
end |
||||
|
||||
test "filters by kinds", %{conn: conn} do |
||||
event_fixture(%{kind: 1}) |
||||
event_fixture(%{kind: 2}) |
||||
conn = get(conn, ~p"/api/events?since=0&until=9999999999&limit=10&kinds=1") |
||||
|
||||
assert %{"data" => events} = json_response(conn, 200) |
||||
assert length(events) == 1 |
||||
assert hd(events)["kind"] == 1 |
||||
end |
||||
|
||||
test "filters by ids", %{conn: conn} do |
||||
event1 = event_fixture(%{kind: 1}) |
||||
_event2 = event_fixture(%{kind: 2, created_at: 1_640_000_001}) |
||||
hex_id1 = Base.encode16(event1.id, case: :lower) |
||||
|
||||
conn = get(conn, ~p"/api/events?since=0&until=9999999999&limit=10&ids=#{hex_id1}") |
||||
|
||||
assert %{"data" => events} = json_response(conn, 200) |
||||
assert length(events) == 1 |
||||
assert hd(events)["id"] == hex_id1 |
||||
end |
||||
|
||||
test "filters by tags", %{conn: conn} do |
||||
tagged_pub_event = valid_pub_event_fixture(%{tags: [["p", "abc123def456"]]}) |
||||
{:ok, _} = GcIndexRelay.Nostr.create_event(tagged_pub_event) |
||||
event_fixture(%{kind: 2, created_at: 1_640_000_001}) |
||||
|
||||
conn = get(conn, ~p"/api/events?since=0&until=9999999999&limit=10&#p=abc123def456") |
||||
|
||||
assert %{"data" => events} = json_response(conn, 200) |
||||
assert length(events) == 1 |
||||
assert hd(events)["id"] == tagged_pub_event.id |
||||
end |
||||
|
||||
test "respects limit parameter", %{conn: conn} do |
||||
event_fixture(%{kind: 1}) |
||||
event_fixture(%{kind: 2, created_at: 1_640_000_001}) |
||||
event_fixture(%{kind: 3, created_at: 1_640_000_002}) |
||||
conn = get(conn, ~p"/api/events?since=0&until=9999999999&limit=2") |
||||
|
||||
assert %{"data" => events} = json_response(conn, 200) |
||||
assert length(events) == 2 |
||||
end |
||||
|
||||
test "returns 400 when since is missing", %{conn: conn} do |
||||
conn = get(conn, ~p"/api/events?until=9999999999&limit=10") |
||||
|
||||
assert json_response(conn, 400) |
||||
end |
||||
|
||||
test "returns 400 when until is missing", %{conn: conn} do |
||||
conn = get(conn, ~p"/api/events?since=0&limit=10") |
||||
|
||||
assert json_response(conn, 400) |
||||
end |
||||
|
||||
test "returns 400 when limit is missing", %{conn: conn} do |
||||
conn = get(conn, ~p"/api/events?since=0&until=9999999999") |
||||
|
||||
assert json_response(conn, 400) |
||||
end |
||||
|
||||
test "returns 400 when limit is too large", %{conn: conn} do |
||||
conn = get(conn, ~p"/api/events?since=0&until=9999999999&limit=101") |
||||
|
||||
assert json_response(conn, 400) |
||||
end |
||||
|
||||
test "returns 400 for unknown query parameter", %{conn: conn} do |
||||
conn = get(conn, ~p"/api/events?since=0&until=9999999999&limit=10&unknown=foo") |
||||
|
||||
assert json_response(conn, 400) |
||||
end |
||||
|
||||
test "returns 400 for invalid (non-integer) limit value", %{conn: conn} do |
||||
conn = get(conn, ~p"/api/events?since=0&until=9999999999&limit=abc") |
||||
|
||||
assert json_response(conn, 400) |
||||
end |
||||
|
||||
test "returns 400 for invalid (non-integer) since value", %{conn: conn} do |
||||
conn = get(conn, ~p"/api/events?since=not_a_number&until=9999999999&limit=10") |
||||
|
||||
assert json_response(conn, 400) |
||||
end |
||||
end |
||||
|
||||
describe "POST /api/events/filter (query)" do |
||||
test "returns empty list when no events exist", %{conn: conn} do |
||||
conn = post(conn, ~p"/api/events/filter", %{"limit" => 10}) |
||||
|
||||
assert %{"data" => []} = json_response(conn, 200) |
||||
end |
||||
|
||||
test "returns events with only limit specified", %{conn: conn} do |
||||
event_fixture() |
||||
conn = post(conn, ~p"/api/events/filter", %{"limit" => 10}) |
||||
|
||||
assert %{"data" => events} = json_response(conn, 200) |
||||
assert length(events) >= 1 |
||||
assert length(events) <= 10 |
||||
end |
||||
|
||||
test "filters by authors", %{conn: conn} do |
||||
%{keypair1: keypair1, keypair2: keypair2} = test_keypairs() |
||||
event_fixture(%{keypair: :keypair1}) |
||||
event_fixture(%{keypair: :keypair2}) |
||||
|
||||
conn = |
||||
post(conn, ~p"/api/events/filter", %{ |
||||
"authors" => [keypair1.public_key_hex], |
||||
"limit" => 10 |
||||
}) |
||||
|
||||
assert %{"data" => events} = json_response(conn, 200) |
||||
assert length(events) == 1 |
||||
assert hd(events)["pubkey"] == keypair1.public_key_hex |
||||
assert hd(events)["pubkey"] != keypair2.public_key_hex |
||||
end |
||||
|
||||
test "filters by kinds", %{conn: conn} do |
||||
event_fixture(%{kind: 1}) |
||||
event_fixture(%{kind: 2, created_at: 1_640_000_001}) |
||||
|
||||
conn = post(conn, ~p"/api/events/filter", %{"kinds" => [1], "limit" => 10}) |
||||
|
||||
assert %{"data" => events} = json_response(conn, 200) |
||||
assert length(events) == 1 |
||||
assert hd(events)["kind"] == 1 |
||||
end |
||||
|
||||
test "filters by ids", %{conn: conn} do |
||||
pub_event = valid_pub_event_fixture() |
||||
event_fixture(%{kind: 2, created_at: 1_640_000_001}) |
||||
{:ok, _} = GcIndexRelay.Nostr.create_event(pub_event) |
||||
|
||||
conn = |
||||
post(conn, ~p"/api/events/filter", %{ |
||||
"ids" => [pub_event.id], |
||||
"limit" => 10 |
||||
}) |
||||
|
||||
assert %{"data" => events} = json_response(conn, 200) |
||||
assert length(events) == 1 |
||||
assert hd(events)["id"] == pub_event.id |
||||
end |
||||
|
||||
test "filters by since timestamp", %{conn: conn} do |
||||
event_fixture(%{created_at: 1_639_999_999}) |
||||
event_fixture(%{kind: 2, created_at: 1_640_000_100}) |
||||
|
||||
conn = |
||||
post(conn, ~p"/api/events/filter", %{ |
||||
"since" => 1_640_000_000, |
||||
"limit" => 10 |
||||
}) |
||||
|
||||
assert %{"data" => events} = json_response(conn, 200) |
||||
assert length(events) == 1 |
||||
assert hd(events)["created_at"] == 1_640_000_100 |
||||
end |
||||
|
||||
test "filters by until timestamp", %{conn: conn} do |
||||
event_fixture(%{created_at: 1_639_999_999}) |
||||
event_fixture(%{kind: 2, created_at: 1_640_000_100}) |
||||
|
||||
conn = |
||||
post(conn, ~p"/api/events/filter", %{ |
||||
"until" => 1_640_000_000, |
||||
"limit" => 10 |
||||
}) |
||||
|
||||
assert %{"data" => events} = json_response(conn, 200) |
||||
assert length(events) == 1 |
||||
assert hd(events)["created_at"] == 1_639_999_999 |
||||
end |
||||
|
||||
test "filters by tags", %{conn: conn} do |
||||
tagged_pub_event = valid_pub_event_fixture(%{tags: [["p", "abc123def456"]]}) |
||||
{:ok, _} = GcIndexRelay.Nostr.create_event(tagged_pub_event) |
||||
event_fixture(%{kind: 2, created_at: 1_640_000_001}) |
||||
|
||||
conn = |
||||
post(conn, ~p"/api/events/filter", %{ |
||||
"#p" => ["abc123def456"], |
||||
"limit" => 10 |
||||
}) |
||||
|
||||
assert %{"data" => events} = json_response(conn, 200) |
||||
assert length(events) == 1 |
||||
assert hd(events)["id"] == tagged_pub_event.id |
||||
end |
||||
|
||||
test "respects limit parameter", %{conn: conn} do |
||||
event_fixture(%{kind: 1}) |
||||
event_fixture(%{kind: 2, created_at: 1_640_000_001}) |
||||
event_fixture(%{kind: 3, created_at: 1_640_000_002}) |
||||
|
||||
conn = post(conn, ~p"/api/events/filter", %{"limit" => 2}) |
||||
|
||||
assert %{"data" => events} = json_response(conn, 200) |
||||
assert length(events) == 2 |
||||
end |
||||
|
||||
test "returns results in descending created_at order", %{conn: conn} do |
||||
event_fixture(%{kind: 1, created_at: 1_640_000_001}) |
||||
event_fixture(%{kind: 2, created_at: 1_640_000_002}) |
||||
event_fixture(%{kind: 3, created_at: 1_640_000_003}) |
||||
|
||||
conn = post(conn, ~p"/api/events/filter", %{"limit" => 10}) |
||||
|
||||
assert %{"data" => events} = json_response(conn, 200) |
||||
created_ats = Enum.map(events, & &1["created_at"]) |
||||
assert created_ats == Enum.sort(created_ats, :desc) |
||||
end |
||||
|
||||
test "returns 400 when limit is missing", %{conn: conn} do |
||||
conn = post(conn, ~p"/api/events/filter", %{"kinds" => [1]}) |
||||
|
||||
assert json_response(conn, 400) |
||||
end |
||||
|
||||
test "returns 400 when limit is 0", %{conn: conn} do |
||||
conn = post(conn, ~p"/api/events/filter", %{"limit" => 0}) |
||||
|
||||
assert json_response(conn, 400) |
||||
end |
||||
|
||||
test "returns 400 when limit exceeds 100", %{conn: conn} do |
||||
conn = post(conn, ~p"/api/events/filter", %{"limit" => 101}) |
||||
|
||||
assert json_response(conn, 400) |
||||
end |
||||
end |
||||
end |
||||
Loading…
Reference in new issue