99 lines
3.0 KiB
Markdown
99 lines
3.0 KiB
Markdown
# QA Plan: Retroactive Signal Purge
|
|
|
|
## Test Strategy
|
|
|
|
Unit tests in the relevant modules validate individual components. Integration tests in `tidal/tests/m9_retroactive_purge.rs` validate the end-to-end purge flow via the public `TidalDb` API.
|
|
|
|
## Unit Test Cases
|
|
|
|
### QA-U1: Contribution log push and drain
|
|
|
|
- Push 3 records for user A (cohort "x") and 2 for user B (cohort "x").
|
|
- `drain_for(user_A, "x")` returns 3 records and leaves 2 for user B.
|
|
- After drain, log has 2 entries.
|
|
|
|
### QA-U2: Contribution log eviction
|
|
|
|
- Create log with cap=3.
|
|
- Push 5 records.
|
|
- `eviction_count()` == 2.
|
|
- Log length == 3 (last 3 entries).
|
|
|
|
### QA-U3: PurgeCoordinator drains and retracts
|
|
|
|
- Seed cohort ledger with 2 view signals for entity 10.
|
|
- Push matching contribution records.
|
|
- `request_purge(user, "cohort")` → score decreases, manifest has 2 entries.
|
|
|
|
### QA-U4: Second purge is no-op on ledger
|
|
|
|
- After first purge, contribution log is empty.
|
|
- Second `request_purge` returns manifest with 0 entries.
|
|
- Ledger score unchanged from first purge.
|
|
|
|
### QA-U5: Manifest JSON roundtrip
|
|
|
|
- Build a `PurgeManifest` with known fields.
|
|
- `to_json()` → `from_json()` restores all fields.
|
|
|
|
### QA-U6: Malformed JSON returns None
|
|
|
|
- `PurgeManifest::from_json(b"")` == `None`.
|
|
- `PurgeManifest::from_json(b"not json")` == `None`.
|
|
|
|
## Integration Test Cases
|
|
|
|
### QA-I1: `basic_purge_retracts_score`
|
|
|
|
- Define cohort "en_users" (locale=en).
|
|
- User 1 (en), signals item 100 twice.
|
|
- `request_community_purge(1, "en_users")` → score decreases, manifest non-empty.
|
|
|
|
### QA-I2: `second_purge_is_idempotent`
|
|
|
|
- User 2 signals item 200 once.
|
|
- First purge: score decreases, manifest has 1 entry.
|
|
- Second purge: manifest has 0 entries, score unchanged from after first purge.
|
|
|
|
### QA-I3: `purge_does_not_affect_other_users`
|
|
|
|
- Users 3 and 4 both signal item 300.
|
|
- Purge user 3 only.
|
|
- Score still positive (user 4's contribution intact).
|
|
|
|
### QA-I4: `manifest_persisted_and_listable`
|
|
|
|
- User 5 signals item 500, then purged.
|
|
- `list_purge_manifests(5)` returns 1 manifest with correct purge_id.
|
|
- Second purge creates second manifest; list returns 2.
|
|
|
|
### QA-I5: `purge_unknown_cohort_is_noop`
|
|
|
|
- User 6 exists, no cohort defined.
|
|
- `request_community_purge(6, "nonexistent")` succeeds with 0-entry manifest.
|
|
|
|
### QA-I6: `score_never_goes_negative`
|
|
|
|
- User 7 signals once; purge applied.
|
|
- `read_decay_score(...)` >= 0.0.
|
|
|
|
### QA-I7: `multiple_items_purged_together`
|
|
|
|
- User 8 signals items 801 and 802.
|
|
- `request_community_purge(8, "en_users")` → manifest has 2 entries; both scores decrease.
|
|
|
|
### QA-I8: `non_cohort_member_purge_is_noop`
|
|
|
|
- User 9 (en) and user 10 (fr) signal item 900.
|
|
- Only user 9 lands in cohort "en_users".
|
|
- Purge user 10 from "en_users" → 0-entry manifest, score unchanged.
|
|
|
|
## Coverage Requirements
|
|
|
|
- All 8 integration tests must pass.
|
|
- All 6 unit tests in `cohort::purge::tests` must pass.
|
|
- All contribution log unit tests in `cohort::contribution::tests` must pass.
|
|
- `cargo test --lib` 1299+ tests passing.
|
|
- `cargo fmt -- --check` clean.
|
|
- `cargo build` clean (no errors, no relevant warnings).
|