Skip to content

Commit a1b1253

Browse files
committed
test: split custom param-name pagination assertion into its own test
The URL-encoding test also asserted the custom page_token query-param path, so a single case guarded two independent properties. Split the param-name assertion into a dedicated test and narrow the encoding test to the default cursor param. Move the token-style guidance out of the package-map table cells into surrounding prose in the README and architecture docs.
1 parent 432fb50 commit a1b1253

3 files changed

Lines changed: 36 additions & 6 deletions

File tree

README.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -255,7 +255,7 @@ See [docs/pipelines.md](docs/pipelines.md) for the step-author walkthrough.
255255
| `http.auth` | `Credential` sealed hierarchy (`KeyCredential`, `NamedKeyCredential`, `BearerToken`), `BearerTokenProvider`, `AuthScheme`, `AuthMetadata`, RFC 7235 challenge parser, `BasicChallengeHandler`, `DigestChallengeHandler`, `CompositeChallengeHandler`. |
256256
| `http.sse` | `ServerSentEventReader` (WHATWG spec), `ServerSentEvent`, `ServerSentEventListener`, `BufferedSource.readServerSentEvents()`. |
257257
| `http.paging` | `PagedIterable<T>`, `PagedResponse<T>`, `PagingOptions` with `byPage()` and `stream()` accessors. |
258-
| `pagination` | `Paginator<T>` (with a `maxPages` safety cap) over cursor / page-number / link-header `PaginationStrategy` implementations, plus `Page<T>` / `SimplePage<T>`. Token-style APIs use `CursorPaginationStrategy` with the query-param name set (e.g. `"page_token"`). |
258+
| `pagination` | `Paginator<T>` (with a `maxPages` safety cap) over cursor / page-number / link-header `PaginationStrategy` implementations, plus `Page<T>` / `SimplePage<T>`. |
259259
| `pipeline` | Recovery-aware primitives: `RequestPipeline`, `ResponsePipeline`, `ExecutionPipeline` over a sealed `ResponseOutcome`, with steps (`pipeline.step`, `pipeline.step.retry`) like `RetryStep`, `ResponseRecoveryStep`, `IdempotencyKeyStep`, `ClientIdentityStep`. |
260260
| `serde` | `Serde`, `Serializer`, `Deserializer` abstractions and `Tristate<T>` (absent / null / present). |
261261
| `io` | `Source`, `Sink`, `Buffer`, `BufferedSource`, `BufferedSink`, `IoProvider`, `Io`, `TeeSink`. |
@@ -265,6 +265,9 @@ See [docs/pipelines.md](docs/pipelines.md) for the step-author walkthrough.
265265
| `util` | `Clock`, `Uuids` (non-blocking v4), `DateTimeRfc1123`, `RetryUtils`, `ProxyOptions`, `Futures`. |
266266
| `generics` | `Builder<T>` — the generic builder interface every SDK builder implements. |
267267

268+
Token-style APIs (`next_page_token`, `pageToken`, …) are served by `CursorPaginationStrategy`:
269+
construct it with the desired query-param name, e.g. `CursorPaginationStrategy(items, extractor, "page_token")`.
270+
268271
## Building
269272

270273
```bash

docs/architecture.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -346,9 +346,12 @@ Two complementary surfaces for walking multi-page responses.
346346
|-----------------------------------------------------------------|-----------------------------------------------------------------------|
347347
| `Paginator<T>` | Lazily iterates pages by re-issuing requests through an `HttpClient`; carries a `maxPages` safety cap |
348348
| `PaginationStrategy<T>` | Computes the next-page request (or stops) from the current page |
349-
| `CursorPaginationStrategy` / `PageNumberPaginationStrategy` / `LinkHeaderPaginationStrategy` | The shipped strategies. Token-style APIs use `CursorPaginationStrategy` with the query-param name set (e.g. `"page_token"`). |
349+
| `CursorPaginationStrategy` / `PageNumberPaginationStrategy` / `LinkHeaderPaginationStrategy` | The shipped strategies |
350350
| `PagedIterable<T>` | First/next-page fetcher abstraction over `PagedResponse`, with its own `maxPages` cap |
351351

352+
Token-style APIs (`next_page_token`, `pageToken`, …) are handled by `CursorPaginationStrategy`
353+
constructed with the query-param name set (e.g. `"page_token"`), so no separate token strategy is needed.
354+
352355
### Serialization
353356

354357
**Package**: `org.dexpace.sdk.core.serde`

sdk-core/src/test/kotlin/org/dexpace/sdk/core/pagination/CursorPaginationTest.kt

Lines changed: 28 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -149,15 +149,39 @@ class CursorPaginationTest {
149149
@Test
150150
fun `cursor with special characters is URL encoded in next request`() {
151151
// Opaque cursors may contain `=` `+` `/` characters (base64) — the rebuilder must
152-
// URL-encode them so the server sees the original value unmangled. A custom query
153-
// param name (e.g. `page_token`) covers token-style APIs that reuse this strategy.
152+
// URL-encode them so the server sees the original value unmangled.
154153
val rawCursor = "a+b/c="
155154
val encoded = "a%2Bb%2Fc%3D"
156155
val client = StubHttpClient()
157156
client.on("https://api.example.com/items") { req ->
158157
textResponse(req, "items=one\ncursor=$rawCursor")
159158
}
160-
client.on("https://api.example.com/items?page_token=$encoded") { req ->
159+
client.on("https://api.example.com/items?cursor=$encoded") { req ->
160+
textResponse(req, "items=two\ncursor=")
161+
}
162+
163+
val (items, cursor) = buildCachedExtractors()
164+
val strategy = CursorPaginationStrategy(items, cursor)
165+
val paginator = Paginator(client, initialRequest(), strategy)
166+
assertEquals(listOf("one", "two"), paginator.iterateAll().toList())
167+
assertEquals(
168+
listOf(
169+
"https://api.example.com/items",
170+
"https://api.example.com/items?cursor=$encoded",
171+
),
172+
client.receivedUrls,
173+
)
174+
}
175+
176+
@Test
177+
fun `custom query-param name is used for the next-page cursor`() {
178+
// Token-style APIs (next_page_token, pageToken, …) are served by setting
179+
// cursorQueryParam; the next request must carry the cursor under that name.
180+
val client = StubHttpClient()
181+
client.on("https://api.example.com/items") { req ->
182+
textResponse(req, "items=one\ncursor=tok1")
183+
}
184+
client.on("https://api.example.com/items?page_token=tok1") { req ->
161185
textResponse(req, "items=two\ncursor=")
162186
}
163187

@@ -168,7 +192,7 @@ class CursorPaginationTest {
168192
assertEquals(
169193
listOf(
170194
"https://api.example.com/items",
171-
"https://api.example.com/items?page_token=$encoded",
195+
"https://api.example.com/items?page_token=tok1",
172196
),
173197
client.receivedUrls,
174198
)

0 commit comments

Comments
 (0)