Skip to main content

qualia_client_core/wellfair/
companion_tests.rs

1//! Companion ingest path — phone bundle → journal (§8.1 step 4, Phase 2 closeout).
2
3#[cfg(test)]
4mod tests {
5    use std::path::PathBuf;
6
7    use ed25519_dalek::SigningKey;
8    use wellfare_core::companion_sync::{CompanionCsvFile, CompanionHealthBundle};
9
10    use crate::wellfair::api::WebizenHostApi;
11    use crate::wellfair::policy::PolicyDecisionService;
12    use crate::wellfair::vault::VaultService;
13
14    const WEIGHT_CSV: &str = "uuid,start_time,end_time,time_offset,weight,body_fat,muscle_mass,body_water,skeletal_muscle,bmi\n\
15a2000001-0000-4000-8000-000000000002,1777632000000,1777632060000,60,71.5,18.0,31.8,55.0,30.2,22.9\n";
16
17    fn host(dir: &tempfile::TempDir) -> WebizenHostApi {
18        let wal = dir.path().join("companion.wal");
19        let vault = VaultService::open(&wal, dir.path(), 0xCAFE).unwrap();
20        let policy = PolicyDecisionService::new();
21        let signing_key = SigningKey::from_bytes(&[22u8; 32]);
22        WebizenHostApi::new(
23            vault,
24            policy,
25            signing_key,
26            "did:wf:owner".into(),
27            "did:wf:owner".into(),
28            PathBuf::from(dir.path()),
29        )
30    }
31
32    #[test]
33    fn companion_bundle_ingest_commits_weight_records() {
34        let dir = tempfile::tempdir().unwrap();
35        let mut host = host(&dir);
36        let bundle = CompanionHealthBundle::new(
37            "phone-closeout-1",
38            1_700_000_100,
39            vec![CompanionCsvFile {
40                filename: "weight.csv".into(),
41                csv_content: WEIGHT_CSV.into(),
42            }],
43        );
44        let report = host.ingest_companion_health_bundle(&bundle);
45        assert!(
46            report.records_committed > 0,
47            "expected commits, got {:?}",
48            report
49        );
50        let journal = host.list_health_records(32).unwrap();
51        assert!(
52            journal.iter().any(|e| e.kind == "weight"),
53            "journal should contain companion-derived rows: {:?}",
54            journal
55        );
56    }
57
58    #[test]
59    fn companion_bundle_survives_checkpoint_reopen() {
60        let dir = tempfile::tempdir().unwrap();
61        let mut host = host(&dir);
62        let bundle = CompanionHealthBundle::new(
63            "phone-closeout-2",
64            1_700_000_200,
65            vec![CompanionCsvFile {
66                filename: "weight.csv".into(),
67                csv_content: WEIGHT_CSV.into(),
68            }],
69        );
70        host.ingest_companion_health_bundle(&bundle);
71        host.finalize_batch().unwrap();
72
73        let wal = dir.path().join("companion.wal");
74        let vault2 = VaultService::open(&wal, dir.path(), 0xCAFE).unwrap();
75        let policy = PolicyDecisionService::new();
76        let signing_key = SigningKey::from_bytes(&[22u8; 32]);
77        let host2 = WebizenHostApi::new(
78            vault2,
79            policy,
80            signing_key,
81            "did:wf:owner".into(),
82            "did:wf:owner".into(),
83            PathBuf::from(dir.path()),
84        );
85        let count = host2.list_health_records(64).unwrap().len();
86        assert!(count > 0, "records should persist after checkpoint reopen");
87    }
88}