114 lines
3.5 KiB
Rust
114 lines
3.5 KiB
Rust
use whispassist_lib::models::{AttendeeInfo, CalendarEvent, ImportedEvent};
|
|
use whispassist_lib::storage::{SqliteStore, Store};
|
|
|
|
fn event(uid: &str, subject: &str) -> ImportedEvent {
|
|
ImportedEvent {
|
|
event: CalendarEvent {
|
|
id: uuid::Uuid::new_v4().to_string(),
|
|
source: "pst".to_string(),
|
|
subject: Some(subject.to_string()),
|
|
organizer: Some("Jordan Lee".to_string()),
|
|
starts_at: Some(1_782_896_400),
|
|
ends_at: Some(1_782_900_000),
|
|
description: Some("Agenda".to_string()),
|
|
raw_uid: Some(uid.to_string()),
|
|
},
|
|
attendees: vec![
|
|
AttendeeInfo {
|
|
name: "Alex Kim".to_string(),
|
|
email: Some("alex@example.com".to_string()),
|
|
role: Some("required".to_string()),
|
|
},
|
|
AttendeeInfo {
|
|
name: "No Email Person".to_string(),
|
|
email: None,
|
|
role: None,
|
|
},
|
|
],
|
|
}
|
|
}
|
|
|
|
#[tokio::test]
|
|
async fn import_calendar_events_dedups_by_source_and_raw_uid() {
|
|
std::env::set_var(
|
|
"LOCALAPPDATA",
|
|
std::env::temp_dir().join(format!("wa-caltest-{}", uuid::Uuid::new_v4())),
|
|
);
|
|
let store = SqliteStore::connect().await.unwrap();
|
|
|
|
let n1 = store
|
|
.import_calendar_events(vec![event("uid-1", "Sprint planning")])
|
|
.await
|
|
.unwrap();
|
|
assert_eq!(n1, 1);
|
|
|
|
let n2 = store
|
|
.import_calendar_events(vec![
|
|
event("uid-1", "Sprint planning (rescheduled)"),
|
|
event("uid-2", "Retro"),
|
|
])
|
|
.await
|
|
.unwrap();
|
|
assert_eq!(n2, 2);
|
|
|
|
let n3 = store
|
|
.import_calendar_events(vec![event("uid-1", "Sprint planning (rescheduled)")])
|
|
.await
|
|
.unwrap();
|
|
assert_eq!(n3, 1);
|
|
|
|
// Verify actual row-level dedup, not just the returned counts.
|
|
let pool = sqlx::sqlite::SqlitePool::connect(&format!(
|
|
"sqlite:{}",
|
|
whispassist_lib::paths::db_path().display()
|
|
))
|
|
.await
|
|
.unwrap();
|
|
|
|
let event_count: i64 =
|
|
sqlx::query_scalar("SELECT COUNT(*) FROM calendar_events WHERE raw_uid = 'uid-1'")
|
|
.fetch_one(&pool)
|
|
.await
|
|
.unwrap();
|
|
assert_eq!(
|
|
event_count, 1,
|
|
"re-importing uid-1 must update in place, not duplicate"
|
|
);
|
|
|
|
let subject: String =
|
|
sqlx::query_scalar("SELECT subject FROM calendar_events WHERE raw_uid = 'uid-1'")
|
|
.fetch_one(&pool)
|
|
.await
|
|
.unwrap();
|
|
assert_eq!(subject, "Sprint planning (rescheduled)");
|
|
|
|
let total_events: i64 = sqlx::query_scalar("SELECT COUNT(*) FROM calendar_events")
|
|
.fetch_one(&pool)
|
|
.await
|
|
.unwrap();
|
|
assert_eq!(total_events, 2, "uid-1 and uid-2 only");
|
|
|
|
let no_email_rows: i64 =
|
|
sqlx::query_scalar("SELECT COUNT(*) FROM participants WHERE name = 'No Email Person'")
|
|
.fetch_one(&pool)
|
|
.await
|
|
.unwrap();
|
|
assert_eq!(
|
|
no_email_rows, 1,
|
|
"repeat no-email attendee must not duplicate the participant row"
|
|
);
|
|
|
|
let alex_rows: i64 =
|
|
sqlx::query_scalar("SELECT COUNT(*) FROM participants WHERE email = 'alex@example.com'")
|
|
.fetch_one(&pool)
|
|
.await
|
|
.unwrap();
|
|
assert_eq!(alex_rows, 1);
|
|
|
|
let links: i64 = sqlx::query_scalar("SELECT COUNT(*) FROM calendar_event_participants")
|
|
.fetch_one(&pool)
|
|
.await
|
|
.unwrap();
|
|
assert_eq!(links, 4, "2 events x 2 attendees each");
|
|
}
|