90 lines
3.0 KiB
Rust
90 lines
3.0 KiB
Rust
//! Integration test: importer trait progress events fire in expected order.
|
|
//!
|
|
//! Drives a full `ChatGptImporter::import` against a fixture and asserts on
|
|
//! the `ImportProgressEvent` sequence observed on the paired receiver.
|
|
|
|
use std::sync::Arc;
|
|
use tempfile::TempDir;
|
|
|
|
use dirigent_archivist::{
|
|
backends::JsonlBackend,
|
|
coordinator::Archivist,
|
|
import::{
|
|
ImportConfig, ImportProgressEvent, ImportProgressSink, ImportTarget, ImporterRegistry,
|
|
},
|
|
};
|
|
|
|
#[tokio::test]
|
|
async fn progress_event_sequence_is_well_formed() {
|
|
// 1. Setup an in-memory archivist (JsonlBackend in tempdir).
|
|
let dir = TempDir::new().unwrap();
|
|
let backend = Arc::new(JsonlBackend::new(dir.path().to_path_buf()).await.unwrap());
|
|
let archivist = Archivist::from_single_backend("main".into(), backend)
|
|
.await
|
|
.unwrap();
|
|
let archivist = Arc::new(archivist);
|
|
|
|
// 2. Use the chatgpt fixture — a minimal conversations.json with a
|
|
// user + assistant message pair.
|
|
let fixture = std::path::PathBuf::from(env!("CARGO_MANIFEST_DIR"))
|
|
.join("../dirigent_chatgpt/tests/fixtures/minimal.json");
|
|
assert!(
|
|
fixture.exists(),
|
|
"chatgpt fixture missing at {}",
|
|
fixture.display()
|
|
);
|
|
|
|
let cfg = ImportConfig {
|
|
source: "chatgpt".into(),
|
|
params: {
|
|
let mut m = std::collections::BTreeMap::new();
|
|
m.insert("path".into(), serde_json::json!(fixture.display().to_string()));
|
|
m
|
|
},
|
|
};
|
|
|
|
// 3. Run the import with a channel sink.
|
|
let registry = ImporterRegistry::default();
|
|
let importer = registry.get("chatgpt").expect("chatgpt registered");
|
|
let (sink, mut rx) = ImportProgressSink::channel();
|
|
|
|
let archivist_for_job = archivist.clone();
|
|
let job = tokio::spawn(async move {
|
|
importer
|
|
.import(&cfg, &*archivist_for_job, ImportTarget::default(), sink)
|
|
.await
|
|
});
|
|
|
|
// 4. Collect all events until the sender side is dropped.
|
|
let mut events = Vec::new();
|
|
while let Some(evt) = rx.recv().await {
|
|
events.push(evt);
|
|
}
|
|
let stats = job.await.unwrap().expect("import");
|
|
|
|
// 5. Assertions on the event sequence.
|
|
// Must contain at least one SessionStarted before any SessionFinished.
|
|
let started_idx = events
|
|
.iter()
|
|
.position(|e| matches!(e, ImportProgressEvent::SessionStarted { .. }));
|
|
let finished_idx = events
|
|
.iter()
|
|
.position(|e| matches!(e, ImportProgressEvent::SessionFinished { .. }));
|
|
|
|
assert!(started_idx.is_some(), "expected a SessionStarted event");
|
|
assert!(finished_idx.is_some(), "expected a SessionFinished event");
|
|
assert!(
|
|
started_idx.unwrap() < finished_idx.unwrap(),
|
|
"SessionStarted must precede SessionFinished"
|
|
);
|
|
|
|
// Stats shows at least 2 messages written (chatgpt fixture has a user
|
|
// + assistant pair).
|
|
assert!(
|
|
stats.messages_written >= 2,
|
|
"expected messages to be written, got stats {:?}",
|
|
stats
|
|
);
|
|
assert_eq!(stats.sessions_imported, 1);
|
|
}
|