| 1 |
|
| 2 |
|
| 3 |
mod common; |
| 4 |
|
| 5 |
use chrono::NaiveDate; |
| 6 |
use goingson_core::DailyNoteRepository; |
| 7 |
use goingson_db_sqlite::SqliteDailyNoteRepository; |
| 8 |
|
| 9 |
fn date(y: i32, m: u32, d: u32) -> NaiveDate { |
| 10 |
NaiveDate::from_ymd_opt(y, m, d).unwrap() |
| 11 |
} |
| 12 |
|
| 13 |
#[tokio::test] |
| 14 |
async fn upsert_then_get_by_date_roundtrips() { |
| 15 |
let pool = common::setup_test_db().await; |
| 16 |
let user_id = common::create_test_user(&pool).await; |
| 17 |
let repo = SqliteDailyNoteRepository::new(pool.clone()); |
| 18 |
let d = date(2026, 3, 15); |
| 19 |
|
| 20 |
let created = repo |
| 21 |
.upsert( |
| 22 |
user_id, |
| 23 |
d, |
| 24 |
"shipped the audit", |
| 25 |
"less context switching", |
| 26 |
false, |
| 27 |
) |
| 28 |
.await |
| 29 |
.unwrap(); |
| 30 |
assert_eq!(created.note_date, d); |
| 31 |
assert_eq!(created.went_well, "shipped the audit"); |
| 32 |
assert_eq!(created.could_improve, "less context switching"); |
| 33 |
assert!(!created.is_reviewed); |
| 34 |
assert!(created.reviewed_at.is_none()); |
| 35 |
|
| 36 |
let fetched = repo.get_by_date(user_id, d).await.unwrap().unwrap(); |
| 37 |
assert_eq!(fetched.id, created.id); |
| 38 |
assert_eq!(fetched.went_well, "shipped the audit"); |
| 39 |
} |
| 40 |
|
| 41 |
#[tokio::test] |
| 42 |
async fn get_by_date_missing_is_none() { |
| 43 |
let pool = common::setup_test_db().await; |
| 44 |
let user_id = common::create_test_user(&pool).await; |
| 45 |
let repo = SqliteDailyNoteRepository::new(pool.clone()); |
| 46 |
|
| 47 |
assert!( |
| 48 |
repo.get_by_date(user_id, date(2026, 1, 1)) |
| 49 |
.await |
| 50 |
.unwrap() |
| 51 |
.is_none() |
| 52 |
); |
| 53 |
} |
| 54 |
|
| 55 |
#[tokio::test] |
| 56 |
async fn upsert_conflict_updates_in_place_and_preserves_id_and_created_at() { |
| 57 |
let pool = common::setup_test_db().await; |
| 58 |
let user_id = common::create_test_user(&pool).await; |
| 59 |
let repo = SqliteDailyNoteRepository::new(pool.clone()); |
| 60 |
let d = date(2026, 5, 1); |
| 61 |
|
| 62 |
let first = repo.upsert(user_id, d, "a", "b", false).await.unwrap(); |
| 63 |
let second = repo |
| 64 |
.upsert(user_id, d, "updated", "improved", true) |
| 65 |
.await |
| 66 |
.unwrap(); |
| 67 |
|
| 68 |
|
| 69 |
assert_eq!(second.id, first.id, "id preserved on conflict path"); |
| 70 |
assert_eq!(second.created_at, first.created_at, "created_at preserved"); |
| 71 |
assert_eq!(second.went_well, "updated"); |
| 72 |
assert_eq!(second.could_improve, "improved"); |
| 73 |
assert!(second.is_reviewed); |
| 74 |
assert!( |
| 75 |
second.reviewed_at.is_some(), |
| 76 |
"reviewed_at set when is_reviewed" |
| 77 |
); |
| 78 |
|
| 79 |
|
| 80 |
let all = repo.list_all(user_id).await.unwrap(); |
| 81 |
assert_eq!(all.len(), 1); |
| 82 |
} |
| 83 |
|
| 84 |
#[tokio::test] |
| 85 |
async fn list_all_is_ordered_by_note_date_ascending() { |
| 86 |
let pool = common::setup_test_db().await; |
| 87 |
let user_id = common::create_test_user(&pool).await; |
| 88 |
let repo = SqliteDailyNoteRepository::new(pool.clone()); |
| 89 |
|
| 90 |
repo.upsert(user_id, date(2026, 3, 10), "c", "", false) |
| 91 |
.await |
| 92 |
.unwrap(); |
| 93 |
repo.upsert(user_id, date(2026, 3, 1), "a", "", false) |
| 94 |
.await |
| 95 |
.unwrap(); |
| 96 |
repo.upsert(user_id, date(2026, 3, 5), "b", "", false) |
| 97 |
.await |
| 98 |
.unwrap(); |
| 99 |
|
| 100 |
let all = repo.list_all(user_id).await.unwrap(); |
| 101 |
let dates: Vec<NaiveDate> = all.iter().map(|n| n.note_date).collect(); |
| 102 |
assert_eq!( |
| 103 |
dates, |
| 104 |
vec![date(2026, 3, 1), date(2026, 3, 5), date(2026, 3, 10)] |
| 105 |
); |
| 106 |
} |
| 107 |
|
| 108 |
#[tokio::test] |
| 109 |
async fn list_all_is_scoped_per_user() { |
| 110 |
let pool = common::setup_test_db().await; |
| 111 |
let user_a = common::create_test_user(&pool).await; |
| 112 |
let user_b = common::create_test_user(&pool).await; |
| 113 |
let repo = SqliteDailyNoteRepository::new(pool.clone()); |
| 114 |
|
| 115 |
repo.upsert(user_a, date(2026, 2, 1), "a-note", "", false) |
| 116 |
.await |
| 117 |
.unwrap(); |
| 118 |
repo.upsert(user_b, date(2026, 2, 1), "b-note", "", false) |
| 119 |
.await |
| 120 |
.unwrap(); |
| 121 |
|
| 122 |
let a = repo.list_all(user_a).await.unwrap(); |
| 123 |
assert_eq!(a.len(), 1); |
| 124 |
assert_eq!(a[0].went_well, "a-note"); |
| 125 |
|
| 126 |
assert!( |
| 127 |
repo.get_by_date(user_a, date(2026, 2, 1)) |
| 128 |
.await |
| 129 |
.unwrap() |
| 130 |
.is_some() |
| 131 |
); |
| 132 |
} |
| 133 |
|