Skip to content

test: prefer id lookups over aggregate find#31

Merged
patrickleet merged 1 commit into
mainfrom
test/use-id-and-readmodel-lookups
May 21, 2026
Merged

test: prefer id lookups over aggregate find#31
patrickleet merged 1 commit into
mainfrom
test/use-id-and-readmodel-lookups

Conversation

@patrickleet
Copy link
Copy Markdown
Collaborator

@patrickleet patrickleet commented May 21, 2026

Summary

  • remove Todo integration tests that demonstrated aggregate predicate find/find_one/exists/count so the Todo example stays a simple event-sourcing flow
  • keep Todo coverage focused on create/commit/get/get_all/outbox/queue behavior
  • update snapshot integration coverage to use get/get_all instead of aggregate predicate find

Verification

  • cargo fmt --check
  • git diff --check
  • cargo test --test todos
  • cargo test --test snapshots
  • cargo test --all-features --test todos
  • cargo test --all-features --test snapshots
  • cargo test --all-features

Note: full all-features test still emits the pre-existing Reservation dead-code warning in tests/sagas/order/inventory.rs.

Summary by CodeRabbit

  • Tests
    • Updated snapshot test to use direct bulk fetch instead of filtering approach.
    • Renamed snapshot test function for clarity.
    • Replaced repository query tests with a new test validating metadata propagation through the system.

Review Change Stack

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 21, 2026

📝 Walkthrough

Walkthrough

Two test modules are refactored: snapshot tests migrate to bulk fetch semantics with simplified assertion patterns, and aggregate repository tests are replaced by an integration test validating metadata propagation through the outbox and publisher pipeline.

Changes

Test Refactoring and Outbox Integration

Layer / File(s) Summary
Snapshot bulk fetch test refactor
tests/snapshots/main.rs
Test function renamed to get_all_with_snapshots and refactored to fetch aggregates directly via repo.get_all() instead of filter-based repo.find(), with assertions validating result count and snapshot fields.
Metadata and outbox publisher integration test
tests/todos/main.rs
Aggregate repository query tests are removed and replaced by metadata_flows_from_entity_through_outbox_to_publisher, which verifies correlation/causation and entity metadata flow through outbox encoding, worker processing, and publisher emission.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Poem

🐰 Snapshots snap with get_all instead of find,
Metadata flows through outbox, carefully aligned,
Tests now whisper secrets through the publisher's ear,
One refactor here, one there—progress crystal clear!

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 66.67% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'test: prefer id lookups over aggregate find' directly and accurately describes the main change: replacing aggregate predicate find operations with id-based lookups in tests.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch test/use-id-and-readmodel-lookups

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (1)
tests/snapshots/main.rs (1)

219-221: ⚡ Quick win

Assert Alice’s fields from get_all results, not a separate get.

These checks currently validate repo.get("t1"), which bypasses the get_all path being tested. Pull t1 from todos and assert on that record to keep this test scoped to bulk-fetch behavior.

Suggested diff
-    let alice = repo.get("t1").unwrap().unwrap();
-    assert_eq!(alice.snapshot().user_id, "alice");
-    assert_eq!(alice.snapshot().task, "Buy milk");
+    let alice = todos
+        .iter()
+        .find(|todo| todo.snapshot().id == "t1")
+        .expect("t1 should be present in get_all result");
+    assert_eq!(alice.snapshot().user_id, "alice");
+    assert_eq!(alice.snapshot().task, "Buy milk");
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/snapshots/main.rs` around lines 219 - 221, The test is asserting
Alice's fields using repo.get("t1") which bypasses the get_all path under test;
instead, locate the record with id "t1" inside the collection returned by
repo.get_all (the todos variable), assign that entry to alice (or a similarly
named variable), and assert on alice.snapshot().user_id and
alice.snapshot().task so the assertions validate the bulk-fetch (get_all)
results rather than a separate repo.get call.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@tests/todos/aggregate.rs`:
- Around line 93-99: The add_todo method currently appends the todo id to
completed_ids or pending_ids without ensuring mutual exclusivity or preventing
duplicates; update add_todo (working with TodoSnapshot) to first remove the
todo.id from both completed_ids and pending_ids (or at least from the opposite
bucket), then push the id into the correct bucket (completed_ids if
todo.completed is true, otherwise pending_ids) so a re-indexed todo never exists
in both lists or duplicated.

---

Nitpick comments:
In `@tests/snapshots/main.rs`:
- Around line 219-221: The test is asserting Alice's fields using repo.get("t1")
which bypasses the get_all path under test; instead, locate the record with id
"t1" inside the collection returned by repo.get_all (the todos variable), assign
that entry to alice (or a similarly named variable), and assert on
alice.snapshot().user_id and alice.snapshot().task so the assertions validate
the bulk-fetch (get_all) results rather than a separate repo.get call.
🪄 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: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 1cf42d9f-1198-4789-ba65-eb840911de66

📥 Commits

Reviewing files that changed from the base of the PR and between 59ace53 and 0cbad33.

📒 Files selected for processing (3)
  • tests/snapshots/main.rs
  • tests/todos/aggregate.rs
  • tests/todos/main.rs

Comment thread tests/todos/aggregate.rs Outdated
Comment on lines +93 to +99
pub fn add_todo(&mut self, todo: &TodoSnapshot) {
if todo.completed {
self.completed_ids.push(todo.id.clone());
} else {
self.pending_ids.push(todo.id.clone());
}
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Keep status buckets mutually exclusive when updating an existing todo ID.

Line 93 currently only appends, so a todo that is re-indexed after status changes can end up in both lists (or duplicated), breaking the status partition.

Proposed fix
 pub fn add_todo(&mut self, todo: &TodoSnapshot) {
+    self.completed_ids.retain(|id| id != &todo.id);
+    self.pending_ids.retain(|id| id != &todo.id);
     if todo.completed {
         self.completed_ids.push(todo.id.clone());
     } else {
         self.pending_ids.push(todo.id.clone());
     }
 }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
pub fn add_todo(&mut self, todo: &TodoSnapshot) {
if todo.completed {
self.completed_ids.push(todo.id.clone());
} else {
self.pending_ids.push(todo.id.clone());
}
}
pub fn add_todo(&mut self, todo: &TodoSnapshot) {
self.completed_ids.retain(|id| id != &todo.id);
self.pending_ids.retain(|id| id != &todo.id);
if todo.completed {
self.completed_ids.push(todo.id.clone());
} else {
self.pending_ids.push(todo.id.clone());
}
}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/todos/aggregate.rs` around lines 93 - 99, The add_todo method currently
appends the todo id to completed_ids or pending_ids without ensuring mutual
exclusivity or preventing duplicates; update add_todo (working with
TodoSnapshot) to first remove the todo.id from both completed_ids and
pending_ids (or at least from the opposite bucket), then push the id into the
correct bucket (completed_ids if todo.completed is true, otherwise pending_ids)
so a re-indexed todo never exists in both lists or duplicated.

@patrickleet patrickleet force-pushed the test/use-id-and-readmodel-lookups branch from 0cbad33 to 7f88db3 Compare May 21, 2026 18:44
@patrickleet patrickleet changed the title test: prefer indexed lookups over aggregate find test: prefer id lookups over aggregate find May 21, 2026
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
tests/snapshots/main.rs (1)

215-221: ⚡ Quick win

Assert get_all content directly instead of re-fetching t1.

Line 219 re-queries repo.get("t1"), so the test does not fully validate that get_all returned the expected entity payloads.

Proposed test-focused adjustment
-    let todos = repo.get_all(&["t1", "t2"]).unwrap();
-    assert_eq!(todos.len(), 2);
-    assert!(todos.iter().all(|todo| todo.snapshot().completed));
-
-    let alice = repo.get("t1").unwrap().unwrap();
-    assert_eq!(alice.snapshot().user_id, "alice");
-    assert_eq!(alice.snapshot().task, "Buy milk");
+    let todos = repo.get_all(&["t1", "t2"]).unwrap();
+    assert_eq!(todos.len(), 2);
+    assert!(todos.iter().all(|todo| todo.snapshot().completed));
+    assert!(todos.iter().any(|todo| {
+        let s = todo.snapshot();
+        s.id == "t1" && s.user_id == "alice" && s.task == "Buy milk"
+    }));
+    assert!(todos.iter().any(|todo| todo.snapshot().id == "t2"));
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/snapshots/main.rs` around lines 215 - 221, The test currently
re-fetches repo.get("t1") instead of validating the payload returned by
repo.get_all; change the assertions to inspect the todos variable directly:
locate the returned entity for id "t1" from the Vec returned by repo.get_all
(e.g. find by id or use ordering since get_all was called with ["t1","t2"]),
then assert on that entity's snapshot().user_id and snapshot().task (and
completed) instead of calling repo.get; update references to repo.get_all,
todos, and snapshot() in the test accordingly.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@tests/snapshots/main.rs`:
- Around line 215-221: The test currently re-fetches repo.get("t1") instead of
validating the payload returned by repo.get_all; change the assertions to
inspect the todos variable directly: locate the returned entity for id "t1" from
the Vec returned by repo.get_all (e.g. find by id or use ordering since get_all
was called with ["t1","t2"]), then assert on that entity's snapshot().user_id
and snapshot().task (and completed) instead of calling repo.get; update
references to repo.get_all, todos, and snapshot() in the test accordingly.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 6f1261f1-b8c3-436d-8b05-8bc98b31694d

📥 Commits

Reviewing files that changed from the base of the PR and between 0cbad33 and 7f88db3.

📒 Files selected for processing (2)
  • tests/snapshots/main.rs
  • tests/todos/main.rs
💤 Files with no reviewable changes (1)
  • tests/todos/main.rs

@patrickleet patrickleet merged commit b6c8450 into main May 21, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant