Publish crate pagination docs, tests, and exec plan (4.1.3)#333
Publish crate pagination docs, tests, and exec plan (4.1.3)#333
Conversation
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: ASSERTIVE Plan: Pro Run ID: 📒 Files selected for processing (2)
Publish crate-level pagination documentation and tests (roadmap 4.1.3)This PR adds comprehensive Rustdoc, tests, BDD fixtures, developer guidance, and a living ExecPlan for the pagination crate without changing its public API or adding production dependencies. See docs/execplans/backend-4-1-3-publish-crate-level-pagination-documentation.md for the execution plan, scope, risks, quality gates and acceptance evidence. Documentation
Tests & BDD
Wider test and infra changes (non-production)
Other
Quality gates and acceptance
WalkthroughSummarise expanded pagination Rustdoc and BDD/tests: document cursor encoding (base64url JSON), ordering and dir semantics, limit normalisation and error→HTTP mappings; add shared pagination BDD fixtures and tests; replace example-data generator with a deterministic implementation and add tests; convert many test suites to fallible Result flows. No public runtime APIs changed. Changes
Possibly related issues
Suggested labels
Poem
🚥 Pre-merge checks | ✅ 9✅ Passed checks (9 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Comment |
Reviewer's GuideAdds detailed crate-level and module-level pagination documentation plus tests (unit and BDD) to assert the documented invariants, along with roadmap/architecture updates and an execution plan document for roadmap item 4.1.3, without changing the public API. Updated class diagram for pagination crate core typesclassDiagram
class Cursor~Key~ {
+Key key
+Direction direction
+new(key Key) Cursor~Key~
+with_direction(key Key, direction Direction) Cursor~Key~
+key() Key
+direction() Direction
+into_inner() Key
+into_parts() Key
+encode() Result~String, CursorError~
+decode(value String) Result~Cursor~Key~, CursorError~
}
class Direction {
<<enumeration>>
Next
Prev
}
class PageParams {
-Option~String~ raw_cursor
-Option~usize~ raw_limit
-Option~Cursor~String~~ parsed_cursor
-usize normalised_limit
+new(cursor Option~String~, limit Option~usize~) Result~PageParams, PageParamsError~
+cursor() Option~String~
+limit() usize
}
class PageParamsError {
<<enumeration>>
InvalidLimit
}
class Paginated~T~ {
+Vec~T~ data
+usize limit
+PaginationLinks links
+new(data Vec~T~, limit usize, links PaginationLinks) Paginated~T~
}
class PaginationLinks {
+String self_
+Option~String~ next
+Option~String~ prev
+new(self_ String, next Option~String~, prev Option~String~) PaginationLinks
+from_request(url String, params PageParams, next_cursor Option~Cursor~String~~, prev_cursor Option~Cursor~String~~) PaginationLinks
}
class CursorError {
<<enumeration>>
Serialize
InvalidBase64
Deserialize
+message String
}
class Limits {
<<constant>>
+DEFAULT_LIMIT : usize = 20
+MAX_LIMIT : usize = 100
}
Cursor --> Direction : uses
PageParams --> Limits : normalises_with
PageParams --> Cursor : parses_optional
Paginated --> PaginationLinks : has
Paginated --> "*" T : contains
Cursor --> CursorError : encode_decode_can_fail
PageParams --> PageParamsError : construct_can_fail
File-Level Changes
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
|
@coderabbitai Have the following now been resolved? Annul any requirements that violate the en-GB-oxendict spelling (-ize / -yse / -our) conventions (for example a request to replace "normalize" with "normalise" or "artefact" with "artifact"), or where the requirement unnecessarily increases cyclomatic complexity. |
This comment was marked as resolved.
This comment was marked as resolved.
|
@coderabbitai Please suggest a fix for this issue and supply a prompt for an AI coding agent to enable it to apply the fix. Include the file and symbol names indicated in the issue at the head of your response. Ensure that this is validated against the current version of the codegraph. If further refinement to address this finding would be deleterious, please supply a clear explanatory one to two paragraph markdown message I can paste into the CodeScene web ui's diagnostic suppression function so this diagnostic can be silenced. backend/crates/pagination/tests/pagination_bdd.rs Comment on file //! Behavioural tests for the pagination crate foundation.
use pagination::{Cursor, CursorError, Direction, PageParams, Paginated, PaginationLinks};
mod common;❌ New issue: Code Duplication |
This comment was marked as resolved.
This comment was marked as resolved.
There was a problem hiding this comment.
♻️ Duplicate comments (1)
backend/crates/pagination/tests/pagination_bdd.rs (1)
154-163: 🧹 Nitpick | 🔵 TrivialExtract a shared decoded-cursor helper.
Remove duplicated decode-result extraction from these step definitions. Centralize it in one private helper and reuse it to keep failure messages and setup logic synchronized.
♻️ Proposed refactor
+#[expect( + clippy::expect_used, + reason = "BDD helpers use expect for clear failures" +)] +fn decoded_cursor<'a>(world: &'a World) -> &'a Cursor<FixtureKey> { + let decode_result = world + .decode_result + .get() + .expect("decode result should be set"); + decode_result + .as_ref() + .expect("cursor decoding should succeed") +} + #[then("the decoded cursor key matches the original key")] #[expect( clippy::expect_used, reason = "BDD steps use expect for clear failures" )] fn the_decoded_cursor_key_matches_the_original_key(world: &World) { let key = world.key.get().expect("key should be set"); - let decode_result = world - .decode_result - .get() - .expect("decode result should be set"); - let cursor = decode_result - .as_ref() - .expect("cursor decoding should succeed"); + let cursor = decoded_cursor(world); assert_eq!(cursor.key(), &key); } @@ fn the_decoded_cursor_has_direction_next(world: &World) { - let decode_result = world - .decode_result - .get() - .expect("decode result should be set"); - let cursor = decode_result - .as_ref() - .expect("cursor decoding should succeed"); + let cursor = decoded_cursor(world); assert_eq!(cursor.direction(), Direction::Next); } @@ fn the_decoded_cursor_has_direction_prev(world: &World) { - let decode_result = world - .decode_result - .get() - .expect("decode result should be set"); - let cursor = decode_result - .as_ref() - .expect("cursor decoding should succeed"); + let cursor = decoded_cursor(world); assert_eq!(cursor.direction(), Direction::Prev); }As per coding guidelines, "Use
rstestfixtures for shared setup and to avoid repetition between tests."Also applies to: 306-333
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@backend/crates/pagination/tests/pagination_bdd.rs` around lines 154 - 163, The step definitions repeatedly extract and unwrap the decoded cursor from World (e.g., in the function the_decoded_cursor_key_matches_the_original_key using world.decode_result and world.key); extract that logic into a single private helper (e.g., fn get_decoded_cursor(world: &World) -> &DecodedCursor) that performs the expect() calls and returns the decoded cursor, then replace the duplicated unwrap blocks in the step functions (including the other occurrences around lines 306-333) with calls to this helper so failure messages and setup are centralized and consistent.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Duplicate comments:
In `@backend/crates/pagination/tests/pagination_bdd.rs`:
- Around line 154-163: The step definitions repeatedly extract and unwrap the
decoded cursor from World (e.g., in the function
the_decoded_cursor_key_matches_the_original_key using world.decode_result and
world.key); extract that logic into a single private helper (e.g., fn
get_decoded_cursor(world: &World) -> &DecodedCursor) that performs the expect()
calls and returns the decoded cursor, then replace the duplicated unwrap blocks
in the step functions (including the other occurrences around lines 306-333)
with calls to this helper so failure messages and setup are centralized and
consistent.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro
Run ID: db8c45ae-06e9-4aa6-81ba-5ce8061a82c7
📒 Files selected for processing (3)
backend/crates/pagination/tests/features/pagination.featurebackend/crates/pagination/tests/pagination_bdd.rsbackend/crates/pagination/tests/pagination_documentation_bdd.rs
💤 Files with no reviewable changes (1)
- backend/crates/pagination/tests/features/pagination.feature
|
@coderabbitai Have the following now been resolved? Annul any requirements that violate the en-GB-oxendict spelling (-ize / -yse / -our) conventions (for example a request to replace "normalize" with "normalise" or "artefact" with "artifact"), or where the requirement unnecessarily increases cyclomatic complexity. |
This comment was marked as resolved.
This comment was marked as resolved.
|
@coderabbitai Please suggest a fix for the following concern and provide an AI coding agent prompt for the fix: Not yet resolved ❌Overall Comment 1 — the no-op |
|
Tip For best results, initiate chat on the files or code changes. 🧩 Analysis chain🏁 Script executed: Length of output: 15901
After inspecting both files:
Scenario: Page parameters use the shared default and maximum limits
Given pagination parameters without a limit
Then the normalized limit is 20
When pagination parameters request limit 500
Then the normalized limit is 100There is no
The scenario now flows directly from the |
Use a clearer parameter name in the Overpass mutex-poison helper and align the users test naming with the repository's -ize spelling. Also make the missing-session-cookie failure message explicit so login test failures are easier to diagnose.
Replace the remaining inline `ThemeDraft` literals in the theme-focused catalogue tests with the shared `default_theme_draft` fixture. This keeps the test setup aligned with the common catalogue fixtures and reduces duplication without changing any assertions or production code.
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@backend/src/inbound/http/users/tests.rs`:
- Around line 54-57: Extract the repeated Option-to-object-to-io::Error chain
into a single helper like get_details_object(value: &serde_json::Value) ->
std::io::Result<&serde_json::Map<String, serde_json::Value>> (or similar
returning &serde_json::Map) and replace each occurrence (the calls that
currently do value.get("details").and_then(|v| v.as_object()).ok_or_else(||
io::Error::other("expected details to be present"))?) with a call to this
helper; ensure the helper returns a descriptive io::Error on failure and update
the test sites (the instances at the shown snippet and the other three
occurrences) to use get_details_object to remove duplication.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro
Run ID: f2aacf18-96c1-411a-836d-4827cc8e279e
📒 Files selected for processing (3)
backend/src/domain/catalogue/tests/theme_tests.rsbackend/src/domain/overpass_enrichment_worker/tests/behaviour_tests/assertions.rsbackend/src/inbound/http/users/tests.rs
|
@coderabbitai Have the following now been resolved? backend/crates/pagination/tests/pagination_bdd.rs (1)
As per coding guidelines, "No single code file may be longer than 400 lines; long switch statements or dispatch tables should be broken up by feature, and large test data blocks moved to external files." 🤖 Prompt for AI Agents |
|
Tip For best results, initiate chat on the files or code changes. 🧩 Analysis chain🏁 Script executed: Length of output: 750
Documentation-invariant steps were moved to |
|
Tip For best results, initiate chat on the files or code changes. 🧩 Analysis chain🏁 Script executed: Length of output: 5970
Both gaps are now present in
No further work is required for this warning. |
Factor the repeated details-object extraction in the users HTTP tests into small shared helpers. This removes duplicated JSON-shape plumbing while preserving the existing assertions and error propagation paths.
|
@coderabbitai Have the following now been resolved? backend/src/domain/ports/walk_session_command.rs (1)
♻️ Proposed fix for consistency#[rstest]
#[tokio::test]
-async fn fixture_command_preserves_session_id() {
+async fn fixture_command_preserves_session_id() -> TestResult {
let command = FixtureWalkSessionCommand;
- let sample_payload = sample_payload().expect("sample payload");
+ let sample_payload = sample_payload()?;
let request = CreateWalkSessionRequest {
session: sample_payload,
};
let response = command
.create_session(request.clone())
.await
.expect("fixture create succeeds");
assert_eq!(response.session_id, request.session.id);
assert!(response.completion_summary.is_some());
+ Ok(())
}
#[rstest]
#[tokio::test]
-async fn payload_round_trip_through_domain_entity() {
- let payload = sample_payload().expect("sample payload");
+async fn payload_round_trip_through_domain_entity() -> TestResult {
+ let payload = sample_payload()?;
let session = WalkSession::try_from(payload.clone()).expect("valid session payload");
let restored = WalkSessionPayload::from(session);
assert_eq!(restored.id, payload.id);
assert_eq!(restored.route_id, payload.route_id);
assert_eq!(restored.primary_stats.len(), payload.primary_stats.len());
+ Ok(())
}🤖 Prompt for AI Agents |
|
Tip For best results, initiate chat on the files or code changes. 🧩 Analysis chain🏁 Script executed: Length of output: 1249
Both functions have been brought into line with the PR-wide
Rather than calling |
There was a problem hiding this comment.
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
backend/src/inbound/http/users/tests.rs (1)
385-402:⚠️ Potential issue | 🟠 MajorSplit this test module now to satisfy the file-length gate.
Line 403 pushes this file to 403 lines, which breaches the 400-line ceiling. Extract the
interests_request_validation_*block into a sibling test module and keep this file focused on endpoint-behaviour tests.As per coding guidelines: “Files must not exceed 400 lines in length”.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@backend/src/inbound/http/users/tests.rs` around lines 385 - 402, The file exceeds the 400-line limit because the interests_request_validation_* tests are in this large tests.rs; extract the entire interests_request_validation_* test block (including any helper imports it needs) into a new sibling test module file (e.g., a new tests file alongside users/tests.rs) and leave only endpoint-behaviour tests like interests_request_serializes_expected_revision_in_camel_case in this file; ensure the new file imports the same crates/modules (serde_json::Value, TestResult, InterestsRequest, etc.), preserves test function names (interests_request_validation_*) and any shared helpers, and update module visibility/imports if necessary so both files compile and run.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Outside diff comments:
In `@backend/src/inbound/http/users/tests.rs`:
- Around line 385-402: The file exceeds the 400-line limit because the
interests_request_validation_* tests are in this large tests.rs; extract the
entire interests_request_validation_* test block (including any helper imports
it needs) into a new sibling test module file (e.g., a new tests file alongside
users/tests.rs) and leave only endpoint-behaviour tests like
interests_request_serializes_expected_revision_in_camel_case in this file;
ensure the new file imports the same crates/modules (serde_json::Value,
TestResult, InterestsRequest, etc.), preserves test function names
(interests_request_validation_*) and any shared helpers, and update module
visibility/imports if necessary so both files compile and run.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro
Run ID: b67535c5-c22e-45da-ac38-128a414aad22
📒 Files selected for processing (1)
backend/src/inbound/http/users/tests.rs
Move the interest theme ID request-validation unit tests into a focused sibling module so the users HTTP test module stays below the project line limit. Keep endpoint behaviour tests in the parent module, including the JSON serialization contract for the request payload.
|
@coderabbitai Have the following now been resolved? backend/src/inbound/http/users/tests.rs (1)
🤖 Prompt for AI Agents |
|
Tip For best results, initiate chat on the files or code changes. 🧩 Analysis chain🏁 Script executed: Length of output: 300
|
Summary
cursor,envelope, andparamsmodules to reflect integration details and edge-cases.Changes
Documentation
backend/crates/pagination/src/lib.rswith four sections:DEFAULT_LIMIT = 20andMAX_LIMIT = 100)CursorErrorandPageParamsErrorcursor.rsgains notes on base64url encoding, direction behavior, and cursor opacity, plus security considerations about opacity (not signed/encrypted).envelope.rsnotes behavior offrom_requestand optional links serialization, includingskip_serializing_ifbehavior for nulls.params.rsnotes onDeserializenormalization and framework integration.docs/execplans/backend-4-1-3-publish-crate-level-pagination-documentation.mddescribing the execution plan, scope, risks, and acceptance criteria.Tests
rstest) to verify documented invariants in:params.rs(consistency ofDEFAULT_LIMIT/MAX_LIMITwith normalization)cursor.rs(stable error display strings forCursorErrorvariants)rstest-bdd):backend/crates/pagination/tests/features/pagination_documentation.featurebackend/crates/pagination/tests/pagination_bdd.rswith steps for the new scenariosbackend/crates/pagination/tests/features/pagination_documentation.featuredocs/execplans/backend-4-1-3-publish-crate-level-pagination-documentation.mdNew/Updated test scaffolding
backend/crates/pagination/tests/common.rs.backend/crates/pagination/tests/pagination_documentation_bdd.rsandbackend/crates/pagination/tests/pagination_documentation.feature.docs/developers-guide.mdto describe shared workspace crate testing layout and guidance.Documentation/testing gates + architecture/roadmap updates
cargo doc -p pagination --no-depsbuilds without warningscargo test -p pagination(with new tests)make check-fmt,make lint,make testmust passdocs/wildside-backend-architecture.mdupdated with the pagination documentation scope decisiondocs/backend-roadmap.mdupdated to mark 4.1.3 as doneValidation / Test Plan
cargo test -p pagination.cargo test -p pagination --test pagination_bdd.cargo doc -p pagination --no-depswith no warnings.make check-fmt,make lint,make test.Rationale
How to review
lib.rsand the expanded module docs incursor.rs,envelope.rs, andparams.rs.docs/wildside-backend-architecture.mdanddocs/backend-roadmap.mdaccurately record the completion of 4.1.3.Notes
📎 Task: https://www.devboxer.com/task/f1f2e744-e11b-4ed1-93df-797a877e8dcd