import Foundation
import Testing
@testable import IrdAPI
@Suite struct PaginatorTests {
@Test func cursorFollowsNextCursorUntilNil() async throws {
let (client, http) = captureClient(script: [
json(200, #"{"registrations":[{"id":"r1"}],"next_cursor":"c2"}"#),
json(200, #"{"registrations":[{"id":"r2"}],"next_cursor":null}"#),
])
let rows: [JSONValue] = try await Paginator.cursor(
fetch: { (cursor: String?) in
var q = [QueryItem("limit", "100")]
if let cursor { q.append(QueryItem("cursor", cursor)) }
return try await client.raw.request(method: .get, path: "/domains/registrations", query: q)
},
items: { $0["registrations"]?.arrayValue ?? [] },
next: { $0["next_cursor"]?.stringValue })
#expect(rows.map { $0["id"]?.stringValue } == ["r1", "r2"])
#expect(http.trail == ["GET /domains/registrations?limit=100", "GET /domains/registrations?limit=100&cursor=c2"])
}
@Test func offsetWalksPagesUntilAShortOne() async throws {
let (client, http) = captureClient(script: [
json(200, #"{"pins":[{"id":"p1"},{"id":"p2"}],"total":3}"#),
json(200, #"{"pins":[{"id":"p3"}],"total":3}"#),
])
let rows: [JSONValue] = try await Paginator.offset(limit: 2,
fetch: { limit, offset in
try await client.raw.request(method: .get, path: "/ipfs/pins",
query: [QueryItem("status", "pinned"), QueryItem("limit", String(limit)), QueryItem("offset", String(offset))])
},
items: { $0["pins"]?.arrayValue ?? [] })
#expect(rows.count == 3)
#expect(http.trail == ["GET /ipfs/pins?status=pinned&limit=2&offset=0", "GET /ipfs/pins?status=pinned&limit=2&offset=2"])
}
@Test func exactlyFullLastPageCostsOneEmptyRequest() async throws {
let (client, http) = captureClient(script: [
json(200, #"{"pins":[{"id":"p1"},{"id":"p2"}]}"#),
json(200, #"{"pins":[]}"#),
])
let rows: [JSONValue] = try await Paginator.offset(limit: 2,
fetch: { limit, offset in
try await client.raw.request(method: .get, path: "/ipfs/pins", query: [QueryItem("limit", String(limit)), QueryItem("offset", String(offset))])
},
items: { $0["pins"]?.arrayValue ?? [] })
#expect(rows.count == 2)
#expect(http.count == 2)
}
@Test func offsetDefaultsTo100And0() async throws {
let (client, http) = captureClient(script: [json(200, #"{"pins":[]}"#)])
let rows: [JSONValue] = try await Paginator.offset(
fetch: { limit, offset in
try await client.raw.request(method: .get, path: "/ipfs/pins", query: [QueryItem("limit", String(limit)), QueryItem("offset", String(offset))])
},
items: { $0["pins"]?.arrayValue ?? [] })
#expect(rows.isEmpty)
#expect(http.trail == ["GET /ipfs/pins?limit=100&offset=0"])
}
}