test: shared factories and command builders

This commit is contained in:
2026-10-25 22:08:17 +01:00
parent 2ac1d4e0cf
commit 51d92e08a7
58 changed files with 784 additions and 1344 deletions

View File

@@ -1,23 +1,21 @@
use crate::test_support::{apply_import_mapping_command, create_import_session_command};
use domain::testing::{test_movie_with_external_id, test_movie_with_year};
use std::sync::Arc;
use uuid::Uuid;
use domain::{
models::{
AnnotatedRow, Movie,
AnnotatedRow,
import::{ImportRow, ParsedFile, RowResult},
},
ports::{DocumentParser, MovieCommand},
testing::{InMemoryImportSessionRepository, InMemoryMovieRepository},
value_objects::{ExternalMetadataId, MovieTitle, ReleaseYear},
value_objects::ExternalMetadataId,
};
use crate::import::deps::{ApplyMappingDeps, CreateSessionDeps};
use crate::import::{
apply_mapping,
commands::{ApplyImportMappingCommand, CreateImportSessionCommand},
create_session,
};
use crate::import::{apply_mapping, create_session};
use crate::test_helpers::TestContextBuilder;
#[tokio::test]
@@ -33,11 +31,7 @@ async fn applies_mapping_to_session() {
let session = create_session::execute(
&create_deps,
CreateImportSessionCommand {
user_id,
bytes: b"title\nTest".to_vec(),
format: domain::models::FileFormat::Csv,
},
create_import_session_command(user_id, b"title\nTest"),
)
.await
.unwrap();
@@ -50,11 +44,7 @@ async fn applies_mapping_to_session() {
let rows = apply_mapping::execute(
&mapping_deps,
ApplyImportMappingCommand {
user_id,
session_id: session.session_id.value(),
mappings: vec![],
},
apply_import_mapping_command(user_id, session.session_id.value()),
)
.await
.unwrap();
@@ -75,11 +65,7 @@ async fn fails_when_session_not_found() {
let result = apply_mapping::execute(
&deps,
ApplyImportMappingCommand {
user_id: Uuid::new_v4(),
session_id: Uuid::new_v4(),
mappings: vec![],
},
apply_import_mapping_command(Uuid::new_v4(), Uuid::new_v4()),
)
.await;
@@ -123,13 +109,7 @@ async fn marks_duplicate_by_external_id() {
let sessions = InMemoryImportSessionRepository::new();
let ext_id = ExternalMetadataId::new("tt1234567".into()).unwrap();
let movie = Movie::new(
Some(ext_id),
MovieTitle::new("Known Movie".into()).unwrap(),
ReleaseYear::new(2020).unwrap(),
None,
None,
);
let movie = test_movie_with_external_id("Known Movie", 2020, ext_id);
movies.upsert_movie(&movie).await.unwrap();
let parser = Arc::new(DuplicateTestParser {
@@ -150,11 +130,7 @@ async fn marks_duplicate_by_external_id() {
let session = create_session::execute(
&create_deps,
CreateImportSessionCommand {
user_id,
bytes: b"title\nKnown Movie".to_vec(),
format: domain::models::FileFormat::Csv,
},
create_import_session_command(user_id, b"title\nKnown Movie"),
)
.await
.unwrap();
@@ -167,11 +143,7 @@ async fn marks_duplicate_by_external_id() {
let rows = apply_mapping::execute(
&mapping_deps,
ApplyImportMappingCommand {
user_id,
session_id: session.session_id.value(),
mappings: vec![],
},
apply_import_mapping_command(user_id, session.session_id.value()),
)
.await
.unwrap();
@@ -185,13 +157,7 @@ async fn marks_duplicate_by_title_and_year() {
let movies = InMemoryMovieRepository::new();
let sessions = InMemoryImportSessionRepository::new();
let movie = Movie::new(
None,
MovieTitle::new("Duplicate Film".into()).unwrap(),
ReleaseYear::new(2022).unwrap(),
None,
None,
);
let movie = test_movie_with_year("Duplicate Film", 2022);
movies.upsert_movie(&movie).await.unwrap();
let parser = Arc::new(DuplicateTestParser {
@@ -211,11 +177,7 @@ async fn marks_duplicate_by_title_and_year() {
let session = create_session::execute(
&create_deps,
CreateImportSessionCommand {
user_id,
bytes: b"title\nDuplicate Film".to_vec(),
format: domain::models::FileFormat::Csv,
},
create_import_session_command(user_id, b"title\nDuplicate Film"),
)
.await
.unwrap();
@@ -228,11 +190,7 @@ async fn marks_duplicate_by_title_and_year() {
let rows = apply_mapping::execute(
&mapping_deps,
ApplyImportMappingCommand {
user_id,
session_id: session.session_id.value(),
mappings: vec![],
},
apply_import_mapping_command(user_id, session.session_id.value()),
)
.await
.unwrap();

View File

@@ -1,3 +1,4 @@
use crate::test_support::apply_import_profile_command;
use std::sync::Arc;
use chrono::Utc;
@@ -7,8 +8,8 @@ use domain::testing::{InMemoryImportProfileRepository, InMemoryImportSessionRepo
use domain::value_objects::{ImportProfileId, UserId};
use uuid::Uuid;
use crate::import::apply_profile;
use crate::import::deps::ApplyProfileDeps;
use crate::import::{apply_profile, commands::ApplyImportProfileCommand};
#[tokio::test]
async fn fails_when_profile_not_found() {
@@ -22,11 +23,7 @@ async fn fails_when_profile_not_found() {
let result = apply_profile::execute(
&deps,
ApplyImportProfileCommand {
user_id: Uuid::new_v4(),
session_id: Uuid::new_v4(),
profile_id: Uuid::new_v4(),
},
apply_import_profile_command(Uuid::new_v4(), Uuid::new_v4(), Uuid::new_v4()),
)
.await;
@@ -56,11 +53,7 @@ async fn fails_when_session_not_found() {
let result = apply_profile::execute(
&deps,
ApplyImportProfileCommand {
user_id,
session_id: Uuid::new_v4(),
profile_id: profile_id.value(),
},
apply_import_profile_command(user_id, Uuid::new_v4(), profile_id.value()),
)
.await;
@@ -98,11 +91,7 @@ async fn applies_profile_mappings_to_session() {
apply_profile::execute(
&deps,
ApplyImportProfileCommand {
user_id,
session_id: session_id.value(),
profile_id: profile_id.value(),
},
apply_import_profile_command(user_id, session_id.value(), profile_id.value()),
)
.await
.unwrap();

View File

@@ -1,19 +1,17 @@
use crate::test_support::create_import_session_command;
use std::sync::Arc;
use chrono::Utc;
use uuid::Uuid;
use domain::models::import::{DomainField, Transform};
use domain::models::{FieldMapping, FileFormat, ImportProfile};
use domain::models::{FieldMapping, ImportProfile};
use domain::ports::{ImportProfileRepository, ImportSessionRepository};
use domain::testing::{InMemoryImportProfileRepository, InMemoryImportSessionRepository};
use domain::value_objects::{ImportProfileId, UserId};
use crate::import::deps::{ApplyProfileAndMapDeps, CreateSessionDeps};
use crate::import::{
apply_profile_and_map, commands::ApplyProfileAndMapCommand,
commands::CreateImportSessionCommand, create_session,
};
use crate::import::{apply_profile_and_map, commands::ApplyProfileAndMapCommand, create_session};
use crate::test_helpers::TestContextBuilder;
#[tokio::test]
@@ -69,11 +67,7 @@ async fn applies_profile_then_regenerates_mapping() {
};
let created = create_session::execute(
&create_deps,
CreateImportSessionCommand {
user_id,
bytes: b"title\nTest".to_vec(),
format: FileFormat::Csv,
},
create_import_session_command(user_id, b"title\nTest"),
)
.await
.unwrap();

View File

@@ -1,11 +1,12 @@
use crate::test_support::create_import_session_command;
use std::sync::Arc;
use uuid::Uuid;
use domain::testing::InMemoryImportSessionRepository;
use crate::import::create_session;
use crate::import::deps::CreateSessionDeps;
use crate::import::{commands::CreateImportSessionCommand, create_session};
use crate::test_helpers::TestContextBuilder;
#[tokio::test]
@@ -20,11 +21,7 @@ async fn creates_session_with_parsed_file() {
let result = create_session::execute(
&deps,
CreateImportSessionCommand {
user_id: Uuid::new_v4(),
bytes: b"col1\nval1".to_vec(),
format: domain::models::FileFormat::Csv,
},
create_import_session_command(Uuid::new_v4(), b"col1\nval1"),
)
.await
.unwrap();

View File

@@ -1,3 +1,4 @@
use crate::test_support::execute_import_command;
use std::sync::Arc;
use domain::models::{AnnotatedRow, ImportSession, import::RowResult};
@@ -59,9 +60,8 @@ async fn imports_confirmed_rows() {
let result = execute::execute(
&deps,
ExecuteImportCommand {
user_id: uid,
session_id: sid.value(),
confirmed_indices: vec![0, 1],
..execute_import_command(uid, sid.value())
},
)
.await
@@ -86,16 +86,9 @@ async fn skips_unconfirmed_rows() {
review_logger: Arc::new(NoopReviewLogger),
};
let result = execute::execute(
&deps,
ExecuteImportCommand {
user_id: uid,
session_id: sid.value(),
confirmed_indices: vec![0],
},
)
.await
.unwrap();
let result = execute::execute(&deps, execute_import_command(uid, sid.value()))
.await
.unwrap();
assert_eq!(result.imported, 1);
assert_eq!(result.skipped_duplicates, 1);
@@ -113,9 +106,8 @@ async fn fails_when_session_not_found() {
let result = execute::execute(
&deps,
ExecuteImportCommand {
user_id: Uuid::new_v4(),
session_id: Uuid::new_v4(),
confirmed_indices: vec![],
..execute_import_command(Uuid::new_v4(), Uuid::new_v4())
},
)
.await;
@@ -149,16 +141,9 @@ async fn handles_datetime_format() {
review_logger: Arc::new(NoopReviewLogger),
};
let result = execute::execute(
&deps,
ExecuteImportCommand {
user_id: uid,
session_id: sid.value(),
confirmed_indices: vec![0],
},
)
.await
.unwrap();
let result = execute::execute(&deps, execute_import_command(uid, sid.value()))
.await
.unwrap();
assert_eq!(result.imported, 1);
assert!(result.failed.is_empty());
@@ -190,16 +175,9 @@ async fn fails_on_invalid_rating() {
review_logger: Arc::new(NoopReviewLogger),
};
let result = execute::execute(
&deps,
ExecuteImportCommand {
user_id: uid,
session_id: sid.value(),
confirmed_indices: vec![0],
},
)
.await
.unwrap();
let result = execute::execute(&deps, execute_import_command(uid, sid.value()))
.await
.unwrap();
assert_eq!(result.imported, 0);
assert_eq!(result.failed.len(), 1);
@@ -231,16 +209,9 @@ async fn fails_on_missing_watched_at() {
review_logger: Arc::new(NoopReviewLogger),
};
let result = execute::execute(
&deps,
ExecuteImportCommand {
user_id: uid,
session_id: sid.value(),
confirmed_indices: vec![0],
},
)
.await
.unwrap();
let result = execute::execute(&deps, execute_import_command(uid, sid.value()))
.await
.unwrap();
assert_eq!(result.imported, 0);
assert_eq!(result.failed.len(), 1);
@@ -272,16 +243,9 @@ async fn imports_row_with_external_metadata_id() {
review_logger: Arc::new(NoopReviewLogger),
};
let result = execute::execute(
&deps,
ExecuteImportCommand {
user_id: uid,
session_id: sid.value(),
confirmed_indices: vec![0],
},
)
.await
.unwrap();
let result = execute::execute(&deps, execute_import_command(uid, sid.value()))
.await
.unwrap();
assert_eq!(result.imported, 1);
assert!(result.failed.is_empty());
@@ -313,16 +277,9 @@ async fn imports_row_with_director_and_comment() {
review_logger: Arc::new(NoopReviewLogger),
};
let result = execute::execute(
&deps,
ExecuteImportCommand {
user_id: uid,
session_id: sid.value(),
confirmed_indices: vec![0],
},
)
.await
.unwrap();
let result = execute::execute(&deps, execute_import_command(uid, sid.value()))
.await
.unwrap();
assert_eq!(result.imported, 1);
assert!(result.failed.is_empty());
@@ -354,16 +311,9 @@ async fn handles_space_separated_datetime_format() {
review_logger: Arc::new(NoopReviewLogger),
};
let result = execute::execute(
&deps,
ExecuteImportCommand {
user_id: uid,
session_id: sid.value(),
confirmed_indices: vec![0],
},
)
.await
.unwrap();
let result = execute::execute(&deps, execute_import_command(uid, sid.value()))
.await
.unwrap();
assert_eq!(result.imported, 1);
assert!(result.failed.is_empty());
@@ -390,16 +340,9 @@ async fn reports_invalid_row_result_errors() {
review_logger: Arc::new(NoopReviewLogger),
};
let result = execute::execute(
&deps,
ExecuteImportCommand {
user_id: uid,
session_id: sid.value(),
confirmed_indices: vec![0],
},
)
.await
.unwrap();
let result = execute::execute(&deps, execute_import_command(uid, sid.value()))
.await
.unwrap();
assert_eq!(result.imported, 0);
assert_eq!(result.failed.len(), 1);
@@ -433,16 +376,9 @@ async fn fails_on_missing_rating() {
review_logger: Arc::new(NoopReviewLogger),
};
let result = execute::execute(
&deps,
ExecuteImportCommand {
user_id: uid,
session_id: sid.value(),
confirmed_indices: vec![0],
},
)
.await
.unwrap();
let result = execute::execute(&deps, execute_import_command(uid, sid.value()))
.await
.unwrap();
assert_eq!(result.imported, 0);
assert_eq!(result.failed.len(), 1);
@@ -475,16 +411,9 @@ async fn fails_on_unparseable_date() {
review_logger: Arc::new(NoopReviewLogger),
};
let result = execute::execute(
&deps,
ExecuteImportCommand {
user_id: uid,
session_id: sid.value(),
confirmed_indices: vec![0],
},
)
.await
.unwrap();
let result = execute::execute(&deps, execute_import_command(uid, sid.value()))
.await
.unwrap();
assert_eq!(result.imported, 0);
assert_eq!(result.failed.len(), 1);
@@ -517,16 +446,9 @@ async fn imports_row_without_release_year() {
review_logger: Arc::new(NoopReviewLogger),
};
let result = execute::execute(
&deps,
ExecuteImportCommand {
user_id: uid,
session_id: sid.value(),
confirmed_indices: vec![0],
},
)
.await
.unwrap();
let result = execute::execute(&deps, execute_import_command(uid, sid.value()))
.await
.unwrap();
assert_eq!(result.imported, 1);
assert!(result.failed.is_empty());
@@ -547,16 +469,9 @@ async fn deletes_session_after_import() {
review_logger: Arc::new(NoopReviewLogger),
};
execute::execute(
&deps,
ExecuteImportCommand {
user_id: uid,
session_id: sid.value(),
confirmed_indices: vec![0],
},
)
.await
.unwrap();
execute::execute(&deps, execute_import_command(uid, sid.value()))
.await
.unwrap();
assert_eq!(
sessions.count(),
@@ -599,9 +514,8 @@ async fn imports_more_rows_than_concurrency_limit() {
let result = execute::execute(
&deps,
ExecuteImportCommand {
user_id: uid,
session_id: sid.value(),
confirmed_indices,
..execute_import_command(uid, sid.value())
},
)
.await