strip session-added comments
This commit is contained in:
@@ -90,7 +90,6 @@ async fn registration_refuses_a_retired_username() {
|
||||
.unwrap()
|
||||
.unwrap();
|
||||
users.mark_deleted(old.id(), &[]).await.unwrap();
|
||||
// The purge removes the row; only the retired name keeps the username taken.
|
||||
users.delete_user(old.id());
|
||||
|
||||
let err = register::execute(&deps, register_command("new@example.com", "Ghost"))
|
||||
|
||||
@@ -78,7 +78,6 @@ async fn edit_other_users_review_returns_forbidden() {
|
||||
assert!(matches!(err, domain::errors::DomainError::Forbidden(_)));
|
||||
}
|
||||
|
||||
/// Loads from the store but refuses every write.
|
||||
pub(crate) struct WriteRefusingReviews(pub(crate) Arc<InMemoryStore>);
|
||||
|
||||
#[async_trait::async_trait]
|
||||
|
||||
@@ -1,6 +1,3 @@
|
||||
//! Every event handler may run twice for the same event (lease takeover after
|
||||
//! a crash mid-handler). Running it twice must leave the world as if it ran once.
|
||||
|
||||
use std::collections::HashMap;
|
||||
use std::sync::{
|
||||
Arc, Mutex,
|
||||
@@ -36,7 +33,6 @@ use application::person::event_handler::PersonEnrichmentHandler;
|
||||
|
||||
// ── fakes ───────────────────────────────────────────────────────────────────
|
||||
|
||||
/// Search index keyed like a real one: indexing the same id twice is one doc.
|
||||
#[derive(Default)]
|
||||
struct RecordingSearch {
|
||||
docs: Mutex<HashMap<(String, String), u32>>,
|
||||
@@ -79,7 +75,6 @@ impl SearchCommand for RecordingSearch {
|
||||
}
|
||||
}
|
||||
|
||||
/// Fails the first `index` call, succeeds afterwards.
|
||||
struct FlakySearch {
|
||||
inner: Arc<RecordingSearch>,
|
||||
failed_once: AtomicUsize,
|
||||
@@ -103,7 +98,6 @@ fn person(tmdb: u64, name: &str) -> Person {
|
||||
Person::basic(PersonId::from_external(&ext), ext, name.into(), None, None)
|
||||
}
|
||||
|
||||
/// One person whose `enriched_at` is set by `update_enrichment`, like the real store.
|
||||
struct FakePersons {
|
||||
person: Mutex<Person>,
|
||||
enrich_writes: AtomicUsize,
|
||||
@@ -239,7 +233,6 @@ impl domain::ports::ImageFetcher for NoImages {
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the key it was given, like the real adapter.
|
||||
struct KeyStorage;
|
||||
|
||||
#[async_trait]
|
||||
@@ -371,8 +364,6 @@ async fn a_movie_enrichment_that_failed_midway_is_redone_on_redelivery() {
|
||||
};
|
||||
|
||||
assert!(handler.handle(&event).await.is_err());
|
||||
// The profile row is the "enrichment done" marker: it must not exist yet,
|
||||
// or the redelivery below would skip and the search index would stay empty.
|
||||
assert!(store.get_by_movie_id(movie.id()).await.unwrap().is_none());
|
||||
|
||||
handler.handle(&event).await.unwrap();
|
||||
@@ -517,13 +508,11 @@ async fn poster_sync_skips_converted_poster_keys_but_not_lookalike_paths() {
|
||||
external_metadata_id: ext,
|
||||
};
|
||||
|
||||
// The converter's output is the canonical synced key: skipped.
|
||||
movie.update_poster(PosterPath::new(format!("{id}.webp")).unwrap());
|
||||
store.upsert_movie(&movie, &[]).await.unwrap();
|
||||
handler.handle(&event).await.unwrap();
|
||||
assert!(publisher.published().is_empty());
|
||||
|
||||
// A foreign path that merely contains the id is not a synced poster.
|
||||
movie.update_poster(PosterPath::new(format!("https://cdn.example/{id}/p.jpg")).unwrap());
|
||||
store.upsert_movie(&movie, &[]).await.unwrap();
|
||||
handler.handle(&event).await.unwrap();
|
||||
|
||||
@@ -1,7 +1,3 @@
|
||||
//! Command builders for tests. Each builder returns a command with sensible
|
||||
//! defaults; tests override individual fields with struct-update syntax:
|
||||
//! `LogReviewCommand { rating: 6, ..log_review_command(user, movie) }`.
|
||||
|
||||
use chrono::NaiveDate;
|
||||
use uuid::Uuid;
|
||||
|
||||
@@ -66,7 +62,6 @@ pub fn log_review_command_manual(user_id: Uuid, title: &str, year: u16) -> LogRe
|
||||
}
|
||||
}
|
||||
|
||||
/// Edits only the rating; `review_id` and `requesting_user_id` are random.
|
||||
pub fn edit_review_command(rating: u8) -> EditReviewCommand {
|
||||
EditReviewCommand {
|
||||
review_id: Uuid::new_v4(),
|
||||
@@ -115,7 +110,6 @@ pub fn update_goal_command(year: u16, target_count: u32) -> UpdateGoalCommand {
|
||||
}
|
||||
}
|
||||
|
||||
/// Confirms indices `[0]`.
|
||||
pub fn execute_import_command(user_id: Uuid, session_id: Uuid) -> ExecuteImportCommand {
|
||||
ExecuteImportCommand {
|
||||
user_id,
|
||||
@@ -132,7 +126,6 @@ pub fn create_import_session_command(user_id: Uuid, csv: &[u8]) -> CreateImportS
|
||||
}
|
||||
}
|
||||
|
||||
/// No field mappings.
|
||||
pub fn apply_import_mapping_command(user_id: Uuid, session_id: Uuid) -> ApplyImportMappingCommand {
|
||||
ApplyImportMappingCommand {
|
||||
user_id,
|
||||
@@ -153,7 +146,6 @@ pub fn apply_import_profile_command(
|
||||
}
|
||||
}
|
||||
|
||||
/// One confirmation, rating as given, no comment.
|
||||
pub fn confirm_watch_events_command(
|
||||
user_id: Uuid,
|
||||
watch_event_id: Uuid,
|
||||
@@ -176,7 +168,6 @@ pub fn dismiss_watch_events_command(
|
||||
DismissWatchEventsCommand { user_id, event_ids }
|
||||
}
|
||||
|
||||
/// Jellyfin provider, no label.
|
||||
pub fn generate_webhook_token_command(user_id: Uuid) -> GenerateWebhookTokenCommand {
|
||||
GenerateWebhookTokenCommand {
|
||||
user_id,
|
||||
@@ -185,7 +176,6 @@ pub fn generate_webhook_token_command(user_id: Uuid) -> GenerateWebhookTokenComm
|
||||
}
|
||||
}
|
||||
|
||||
/// Every field unset; override what the test cares about.
|
||||
pub fn update_profile_command(user_id: Uuid) -> UpdateProfileCommand {
|
||||
UpdateProfileCommand {
|
||||
user_id,
|
||||
@@ -199,7 +189,6 @@ pub fn update_profile_command(user_id: Uuid) -> UpdateProfileCommand {
|
||||
}
|
||||
}
|
||||
|
||||
/// All federation toggles on.
|
||||
pub fn update_user_settings_command(user_id: Uuid) -> UpdateUserSettingsCommand {
|
||||
UpdateUserSettingsCommand {
|
||||
user_id,
|
||||
@@ -216,7 +205,6 @@ pub fn add_to_watchlist_command(user_id: Uuid, movie_id: Uuid) -> AddToWatchlist
|
||||
}
|
||||
}
|
||||
|
||||
/// Window is 1 Jan of `year` to 1 Jan of `year + 1`.
|
||||
pub fn request_wrap_up_command(user_id: Option<Uuid>, year: i32) -> RequestWrapUpCommand {
|
||||
RequestWrapUpCommand {
|
||||
user_id,
|
||||
|
||||
@@ -1,6 +1,3 @@
|
||||
//! Shared fakes and builders for the application integration tests.
|
||||
//! Included via `mod support;` from each `tests/<module>.rs`; not every
|
||||
//! binary uses every helper.
|
||||
#![allow(dead_code, unused_imports)]
|
||||
|
||||
mod commands;
|
||||
|
||||
@@ -139,7 +139,6 @@ fn entries(log: &Log) -> Vec<String> {
|
||||
|
||||
#[test]
|
||||
fn the_handler_name_is_stable() {
|
||||
// The name keys the processed-event ledger; renaming re-runs events.
|
||||
let f = tokio::runtime::Runtime::new()
|
||||
.unwrap()
|
||||
.block_on(fixture(false, true));
|
||||
@@ -255,9 +254,6 @@ async fn a_redelivered_event_is_skipped_by_the_ledger() {
|
||||
assert_eq!(purges, 1);
|
||||
}
|
||||
|
||||
/// The rows were committed but the worker died before deleting the image
|
||||
/// objects: the redelivery finds the account purged, still sees the image
|
||||
/// references, deletes the objects and clears the references.
|
||||
#[tokio::test]
|
||||
async fn a_rerun_after_a_crash_following_the_commit_deletes_the_images() {
|
||||
let f = fixture(false, true).await;
|
||||
|
||||
@@ -21,8 +21,6 @@ use domain::models::{User, UserSummary};
|
||||
use domain::ports::UserRepository as UserRepositoryPort;
|
||||
use domain::value_objects::Username;
|
||||
|
||||
/// Delegates to a store but reports a stale admin count, as a concurrent
|
||||
/// deletion would leave the use case's pre-check.
|
||||
struct StaleAdminCount(Arc<InMemoryStore>);
|
||||
|
||||
#[async_trait]
|
||||
|
||||
@@ -273,7 +273,6 @@ async fn changing_also_known_as_records_the_move_with_the_update() {
|
||||
assert!(matches!(recorded[1], DomainEvent::UserAccountMoved { .. }));
|
||||
}
|
||||
|
||||
/// Loads from the store but refuses the profile write.
|
||||
struct ProfileWriteRefusingUsers(Arc<InMemoryStore>);
|
||||
|
||||
#[async_trait::async_trait]
|
||||
|
||||
@@ -377,7 +377,6 @@ impl EventHandler for CountingHandler {
|
||||
}
|
||||
}
|
||||
|
||||
/// Delivers the same event (same id) `times` times, recording ack/nack per delivery.
|
||||
struct RedeliveringConsumer {
|
||||
id: Option<domain::events::EventId>,
|
||||
event: DomainEvent,
|
||||
@@ -416,8 +415,6 @@ impl EventConsumer for RedeliveringConsumer {
|
||||
Box::new(CountNack(Arc::clone(&nacks), Arc::clone(&defers))),
|
||||
);
|
||||
async move {
|
||||
// Let the previous delivery's handlers finish first: a real
|
||||
// broker redelivers only after the nack.
|
||||
tokio::time::sleep(std::time::Duration::from_millis(50)).await;
|
||||
Ok(envelope)
|
||||
}
|
||||
@@ -498,7 +495,6 @@ async fn a_handler_already_running_elsewhere_is_not_run_concurrently() {
|
||||
let (handler, calls) = CountingHandler::new("slow", 0);
|
||||
let store = InMemoryStore::new();
|
||||
let id = domain::events::EventId::new();
|
||||
// Another delivery holds a live claim on this (event, handler).
|
||||
assert!(matches!(
|
||||
store.begin(&id, "slow").await.unwrap(),
|
||||
Begin::Run(_)
|
||||
@@ -560,7 +556,6 @@ async fn a_delivery_blocked_by_a_live_claim_is_deferred_without_consuming_an_att
|
||||
assert_eq!(*nacks.lock().unwrap(), 0, "a nack would consume an attempt");
|
||||
let defers = defers.lock().unwrap();
|
||||
assert_eq!(defers.len(), 1);
|
||||
// Retried only once the claim's lease has run out (plus a margin).
|
||||
let lease = std::time::Duration::from_secs(HANDLER_LEASE_SECONDS as u64);
|
||||
assert!(
|
||||
defers[0] > lease - std::time::Duration::from_secs(5),
|
||||
@@ -588,7 +583,6 @@ async fn a_lapsed_owner_cannot_release_a_claim_taken_over_by_another() {
|
||||
let Begin::Run(lapsed) = store.begin(&id, "h").await.unwrap() else {
|
||||
panic!("stale claim should be taken over");
|
||||
};
|
||||
// Simulate: the original owner's token is from before the takeover.
|
||||
let original = domain::ports::ClaimToken::new("2020-01-01T00:00:00.000Z".into());
|
||||
assert_ne!(original, lapsed);
|
||||
|
||||
@@ -652,7 +646,6 @@ async fn a_failed_handler_releases_its_claim_so_redelivery_retries() {
|
||||
.run(tokio::sync::watch::channel(false).1)
|
||||
.await;
|
||||
|
||||
// Delivery 1 fails and releases; 2 succeeds; 3 is skipped as done.
|
||||
assert_eq!(*calls.lock().unwrap(), 2);
|
||||
assert_eq!(*nacks.lock().unwrap(), 1);
|
||||
}
|
||||
|
||||
@@ -82,7 +82,6 @@ async fn generates_wrapup_and_marks_complete() {
|
||||
assert_eq!(final_rec.status, WrapUpStatus::Ready);
|
||||
assert!(final_rec.report.is_some());
|
||||
|
||||
// The completion event is recorded together with the completed row.
|
||||
let recorded = repo.recorded_events();
|
||||
assert_eq!(recorded.len(), 1);
|
||||
assert!(matches!(
|
||||
@@ -93,8 +92,6 @@ async fn generates_wrapup_and_marks_complete() {
|
||||
|
||||
#[tokio::test]
|
||||
async fn a_wrapup_left_generating_is_completed_on_redelivery() {
|
||||
// A crash after `Generating` was written (or a failed `set_complete`) leaves
|
||||
// the record stuck; the redelivered event must finish it, not skip it.
|
||||
let repo = InMemoryWrapUpRepository::new();
|
||||
let wrapup_id = WrapUpId::generate();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user