code refactor
Some checks failed
CI / Check / Test (push) Has been cancelled

Reviewed-on: #26
This commit was merged in pull request #26.
This commit is contained in:
2026-10-26 09:36:23 +00:00
parent 2ce7db12c2
commit 017b58d6fa
804 changed files with 33423 additions and 28955 deletions

View File

@@ -1,17 +1,16 @@
[package]
name = "export"
version = "0.1.0"
edition = "2024"
edition.workspace = true
[dependencies]
domain = { workspace = true }
async-trait = { workspace = true }
serde_json = { workspace = true }
chrono = { workspace = true }
futures = { workspace = true }
bytes = { workspace = true }
async-stream = { workspace = true }
[dev-dependencies]
domain = { workspace = true, features = ["test-helpers"] }
uuid = { workspace = true }
tokio = { workspace = true }
tokio = { workspace = true, features = ["rt", "macros"] }

View File

@@ -107,7 +107,3 @@ fn entry_to_json(e: &DiaryEntry) -> serde_json::Value {
"spoilers": e.review().spoilers(),
})
}
#[cfg(test)]
#[path = "tests/lib.rs"]
mod tests;

View File

@@ -1,9 +1,12 @@
use super::ExportAdapter;
use domain::{
models::{DiaryEntry, ExportFormat, Movie, Review},
models::{DiaryEntry, ExportFormat, Movie, ReviewEdit},
ports::DiaryExporter,
value_objects::{ExternalMetadataId, MovieTitle, Rating, ReleaseYear},
testing::{
test_movie_with_director, test_movie_with_external_id, test_movie_with_year, test_review,
},
value_objects::{Comment, ExternalMetadataId, UserId},
};
use export::ExportAdapter;
async fn collect_stream(
stream: futures::stream::BoxStream<'static, Result<bytes::Bytes, domain::errors::DomainError>>,
@@ -26,55 +29,19 @@ fn entry_stream(
Box::pin(futures::stream::iter(entries.into_iter().map(Ok)))
}
fn make_entry(
title: &str,
year: u16,
director: Option<&str>,
rating: u8,
comment: Option<&str>,
) -> DiaryEntry {
make_entry_full(title, year, director, rating, comment, None)
}
fn make_entry_full(
title: &str,
year: u16,
director: Option<&str>,
rating: u8,
comment: Option<&str>,
external_id: Option<&str>,
) -> DiaryEntry {
let movie = Movie::new(
external_id.map(|id| ExternalMetadataId::new(id.to_string()).unwrap()),
MovieTitle::new(title.to_string()).unwrap(),
ReleaseYear::new(year).unwrap(),
director.map(str::to_string),
None,
);
let user_id = domain::value_objects::UserId::from_uuid(uuid::Uuid::new_v4());
let review = Review::new(
movie.id().clone(),
user_id,
Rating::new(rating).unwrap(),
comment.map(|c| domain::value_objects::Comment::new(c.to_string()).unwrap()),
chrono::NaiveDate::from_ymd_opt(2024, 3, 15)
.unwrap()
.and_hms_opt(0, 0, 0)
.unwrap(),
None,
false,
)
.unwrap();
fn entry_for(movie: Movie, rating: u8, comment: Option<&str>) -> DiaryEntry {
let review = test_review(movie.id(), &UserId::generate(), rating).apply_edit(ReviewEdit {
comment: Some(comment.map(|c| Comment::new(c.to_string()).unwrap())),
..Default::default()
});
DiaryEntry::new(movie, review)
}
#[tokio::test]
async fn csv_has_header_and_one_row() {
let adapter = ExportAdapter;
let entry = make_entry(
"Inception",
2010,
Some("Christopher Nolan"),
let entry = entry_for(
test_movie_with_director("Inception", 2010, "Christopher Nolan"),
5,
Some("great"),
);
@@ -95,7 +62,7 @@ async fn csv_has_header_and_one_row() {
#[tokio::test]
async fn csv_escapes_commas_in_title() {
let adapter = ExportAdapter;
let entry = make_entry("Tár, A Film", 2022, None, 4, None);
let entry = entry_for(test_movie_with_year("Tár, A Film", 2022), 4, None);
let bytes =
collect_stream(adapter.stream_entries(entry_stream(vec![entry]), ExportFormat::Csv)).await;
let text = String::from_utf8(bytes).unwrap();
@@ -105,7 +72,11 @@ async fn csv_escapes_commas_in_title() {
#[tokio::test]
async fn json_is_valid_array() {
let adapter = ExportAdapter;
let entry = make_entry("Dune", 2021, Some("Denis Villeneuve"), 5, None);
let entry = entry_for(
test_movie_with_director("Dune", 2021, "Denis Villeneuve"),
5,
None,
);
let bytes =
collect_stream(adapter.stream_entries(entry_stream(vec![entry]), ExportFormat::Json)).await;
let arr: Vec<serde_json::Value> = serde_json::from_slice(&bytes).unwrap();
@@ -120,20 +91,29 @@ async fn json_is_valid_array() {
#[tokio::test]
async fn external_metadata_id_included_when_present() {
let adapter = ExportAdapter;
let entry = make_entry_full("Alien", 1979, None, 5, None, Some("tt0078748"));
let entry = entry_for(
test_movie_with_external_id(
"Alien",
1979,
ExternalMetadataId::new("tt0078748".to_string()).unwrap(),
),
5,
None,
);
let bytes =
collect_stream(adapter.stream_entries(entry_stream(vec![entry]), ExportFormat::Json)).await;
let arr: Vec<serde_json::Value> = serde_json::from_slice(&bytes).unwrap();
assert_eq!(arr[0]["external_metadata_id"], "tt0078748");
let bytes = collect_stream(adapter.stream_entries(
entry_stream(vec![make_entry_full(
"Alien",
1979,
None,
entry_stream(vec![entry_for(
test_movie_with_external_id(
"Alien",
1979,
ExternalMetadataId::new("tt0078748".to_string()).unwrap(),
),
5,
None,
Some("tt0078748"),
)]),
ExportFormat::Csv,
))