defmodule Akkoma.Collections.FetcherTest do use Pleroma.DataCase use Oban.Testing, repo: Pleroma.Repo alias Akkoma.Collections.Fetcher import Tesla.Mock setup do mock(fn env -> apply(HttpRequestMock, :request, [env]) end) :ok end test "it should extract items from an embedded array in a Collection" do ap_id = "https://example.com/collection/ordered_array" unordered_collection = "test/fixtures/collections/unordered_array.json" |> File.read!() |> Jason.decode!() |> Map.put("id", ap_id) |> Jason.encode!(pretty: true) Tesla.Mock.mock(fn %{ method: :get, url: ^ap_id } -> %Tesla.Env{ status: 200, body: unordered_collection, headers: [{"content-type", "application/activity+json"}] } end) {:ok, objects} = Fetcher.fetch_collection(ap_id) assert [%{"type" => "Create"}, %{"type" => "Like"}] = objects end test "it should extract items from an embedded array in an OrderedCollection" do ordered_collection = "test/fixtures/collections/ordered_array.json" |> File.read!() ap_id = "https://example.com/collection/ordered_array" Tesla.Mock.mock(fn %{ method: :get, url: ^ap_id } -> %Tesla.Env{ status: 200, body: ordered_collection, headers: [{"content-type", "application/activity+json"}] } end) {:ok, objects} = Fetcher.fetch_collection(ap_id) assert [%{"type" => "Create"}, %{"type" => "Like"}] = objects end test "it should extract items from an referenced first page in a Collection" do unordered_collection = "test/fixtures/collections/unordered_page_reference.json" |> File.read!() first_page = "test/fixtures/collections/unordered_page_first.json" |> File.read!() second_page = "test/fixtures/collections/unordered_page_second.json" |> File.read!() ap_id = "https://example.com/collection/unordered_page_reference" first_page_id = "https://example.com/collection/unordered_page_reference?page=1" second_page_id = "https://example.com/collection/unordered_page_reference?page=2" Tesla.Mock.mock(fn %{ method: :get, url: ^ap_id } -> %Tesla.Env{ status: 200, body: unordered_collection, headers: [{"content-type", "application/activity+json"}] } %{ method: :get, url: ^first_page_id } -> %Tesla.Env{ status: 200, body: first_page, headers: [{"content-type", "application/activity+json"}] } %{ method: :get, url: ^second_page_id } -> %Tesla.Env{ status: 200, body: second_page, headers: [{"content-type", "application/activity+json"}] } end) {:ok, objects} = Fetcher.fetch_collection(ap_id) assert [%{"type" => "Create"}, %{"type" => "Like"}] = objects end test "it should stop fetching when we hit :max_collection_objects" do clear_config([:activitypub, :max_collection_objects], 1) unordered_collection = "test/fixtures/collections/unordered_page_reference.json" |> File.read!() first_page = "test/fixtures/collections/unordered_page_first.json" |> File.read!() second_page = "test/fixtures/collections/unordered_page_second.json" |> File.read!() ap_id = "https://example.com/collection/unordered_page_reference" first_page_id = "https://example.com/collection/unordered_page_reference?page=1" second_page_id = "https://example.com/collection/unordered_page_reference?page=2" Tesla.Mock.mock(fn %{ method: :get, url: ^ap_id } -> %Tesla.Env{ status: 200, body: unordered_collection, headers: [{"content-type", "application/activity+json"}] } %{ method: :get, url: ^first_page_id } -> %Tesla.Env{ status: 200, body: first_page, headers: [{"content-type", "application/activity+json"}] } %{ method: :get, url: ^second_page_id } -> %Tesla.Env{ status: 200, body: second_page, headers: [{"content-type", "application/activity+json"}] } end) {:ok, objects} = Fetcher.fetch_collection(ap_id) assert [%{"type" => "Create"}] = objects end test "it should stop fetching when we hit a 404" do clear_config([:activitypub, :max_collection_objects], 1) unordered_collection = "test/fixtures/collections/unordered_page_reference.json" |> File.read!() first_page = "test/fixtures/collections/unordered_page_first.json" |> File.read!() ap_id = "https://example.com/collection/unordered_page_reference" first_page_id = "https://example.com/collection/unordered_page_reference?page=1" second_page_id = "https://example.com/collection/unordered_page_reference?page=2" Tesla.Mock.mock(fn %{ method: :get, url: ^ap_id } -> %Tesla.Env{ status: 200, body: unordered_collection, headers: [{"content-type", "application/activity+json"}] } %{ method: :get, url: ^first_page_id } -> %Tesla.Env{ status: 200, body: first_page, headers: [{"content-type", "application/activity+json"}] } %{ method: :get, url: ^second_page_id } -> %Tesla.Env{ status: 404, body: nil, headers: [{"content-type", "application/activity+json"}] } end) {:ok, objects} = Fetcher.fetch_collection(ap_id) assert [%{"type" => "Create"}] = objects end end