test: add alignment_db unit tests (RFC 0051)
12 tests covering: - Dialogue ID generation with collision handling - Display ID format (P0001, T0105, R0215) - Display ID parsing - Dialogue creation and retrieval - Expert registration and scoring - Perspective, tension, recommendation registration - Tension lifecycle (open → addressed → resolved) - Cross-reference registration - Verdict registration with dialogue status update - Full workflow integration test Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
parent
401a6b1a45
commit
4b043c12d0
1 changed files with 646 additions and 0 deletions
|
|
@ -1447,3 +1447,649 @@ pub fn get_verdicts(
|
|||
|
||||
Ok(verdicts)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use rusqlite::Connection;
|
||||
|
||||
/// Create an in-memory database with the alignment schema
|
||||
fn setup_test_db() -> Connection {
|
||||
let conn = Connection::open_in_memory().unwrap();
|
||||
|
||||
// Create all alignment tables
|
||||
conn.execute_batch(
|
||||
r#"
|
||||
CREATE TABLE alignment_dialogues (
|
||||
dialogue_id TEXT PRIMARY KEY,
|
||||
title TEXT NOT NULL,
|
||||
question TEXT,
|
||||
status TEXT NOT NULL DEFAULT 'open',
|
||||
created_at TEXT NOT NULL,
|
||||
converged_at TEXT,
|
||||
total_rounds INTEGER DEFAULT 0,
|
||||
total_alignment INTEGER DEFAULT 0,
|
||||
output_dir TEXT,
|
||||
calibrated INTEGER DEFAULT 0,
|
||||
domain_id TEXT,
|
||||
ethos_id TEXT,
|
||||
background TEXT
|
||||
);
|
||||
|
||||
CREATE TABLE alignment_experts (
|
||||
dialogue_id TEXT NOT NULL,
|
||||
expert_slug TEXT NOT NULL,
|
||||
role TEXT NOT NULL,
|
||||
description TEXT,
|
||||
focus TEXT,
|
||||
tier TEXT NOT NULL,
|
||||
source TEXT NOT NULL,
|
||||
relevance REAL,
|
||||
creation_reason TEXT,
|
||||
color TEXT,
|
||||
scores TEXT DEFAULT '{}',
|
||||
raw_content TEXT,
|
||||
total_score INTEGER DEFAULT 0,
|
||||
first_round INTEGER,
|
||||
created_at TEXT NOT NULL,
|
||||
PRIMARY KEY (dialogue_id, expert_slug)
|
||||
);
|
||||
|
||||
CREATE TABLE alignment_rounds (
|
||||
dialogue_id TEXT NOT NULL,
|
||||
round INTEGER NOT NULL,
|
||||
title TEXT,
|
||||
score INTEGER NOT NULL,
|
||||
summary TEXT,
|
||||
status TEXT NOT NULL DEFAULT 'open',
|
||||
created_at TEXT NOT NULL,
|
||||
completed_at TEXT,
|
||||
PRIMARY KEY (dialogue_id, round)
|
||||
);
|
||||
|
||||
CREATE TABLE alignment_perspectives (
|
||||
dialogue_id TEXT NOT NULL,
|
||||
round INTEGER NOT NULL,
|
||||
seq INTEGER NOT NULL,
|
||||
label TEXT NOT NULL,
|
||||
content TEXT NOT NULL,
|
||||
contributors TEXT NOT NULL,
|
||||
status TEXT NOT NULL DEFAULT 'open',
|
||||
refs TEXT,
|
||||
created_at TEXT NOT NULL,
|
||||
PRIMARY KEY (dialogue_id, round, seq)
|
||||
);
|
||||
|
||||
CREATE TABLE alignment_perspective_events (
|
||||
dialogue_id TEXT NOT NULL,
|
||||
perspective_round INTEGER NOT NULL,
|
||||
perspective_seq INTEGER NOT NULL,
|
||||
event_type TEXT NOT NULL,
|
||||
event_round INTEGER NOT NULL,
|
||||
actors TEXT NOT NULL,
|
||||
result_id TEXT,
|
||||
created_at TEXT NOT NULL,
|
||||
PRIMARY KEY (dialogue_id, perspective_round, perspective_seq, created_at)
|
||||
);
|
||||
|
||||
CREATE TABLE alignment_tensions (
|
||||
dialogue_id TEXT NOT NULL,
|
||||
round INTEGER NOT NULL,
|
||||
seq INTEGER NOT NULL,
|
||||
label TEXT NOT NULL,
|
||||
description TEXT NOT NULL,
|
||||
contributors TEXT NOT NULL,
|
||||
status TEXT NOT NULL DEFAULT 'open',
|
||||
refs TEXT,
|
||||
created_at TEXT NOT NULL,
|
||||
PRIMARY KEY (dialogue_id, round, seq)
|
||||
);
|
||||
|
||||
CREATE TABLE alignment_tension_events (
|
||||
dialogue_id TEXT NOT NULL,
|
||||
tension_round INTEGER NOT NULL,
|
||||
tension_seq INTEGER NOT NULL,
|
||||
event_type TEXT NOT NULL,
|
||||
event_round INTEGER NOT NULL,
|
||||
actors TEXT NOT NULL,
|
||||
reason TEXT,
|
||||
reference TEXT,
|
||||
created_at TEXT NOT NULL,
|
||||
PRIMARY KEY (dialogue_id, tension_round, tension_seq, created_at)
|
||||
);
|
||||
|
||||
CREATE TABLE alignment_recommendations (
|
||||
dialogue_id TEXT NOT NULL,
|
||||
round INTEGER NOT NULL,
|
||||
seq INTEGER NOT NULL,
|
||||
label TEXT NOT NULL,
|
||||
content TEXT NOT NULL,
|
||||
contributors TEXT NOT NULL,
|
||||
parameters TEXT,
|
||||
status TEXT NOT NULL DEFAULT 'proposed',
|
||||
refs TEXT,
|
||||
adopted_in_verdict TEXT,
|
||||
created_at TEXT NOT NULL,
|
||||
PRIMARY KEY (dialogue_id, round, seq)
|
||||
);
|
||||
|
||||
CREATE TABLE alignment_recommendation_events (
|
||||
dialogue_id TEXT NOT NULL,
|
||||
rec_round INTEGER NOT NULL,
|
||||
rec_seq INTEGER NOT NULL,
|
||||
event_type TEXT NOT NULL,
|
||||
event_round INTEGER NOT NULL,
|
||||
actors TEXT NOT NULL,
|
||||
result_id TEXT,
|
||||
created_at TEXT NOT NULL,
|
||||
PRIMARY KEY (dialogue_id, rec_round, rec_seq, created_at)
|
||||
);
|
||||
|
||||
CREATE TABLE alignment_evidence (
|
||||
dialogue_id TEXT NOT NULL,
|
||||
round INTEGER NOT NULL,
|
||||
seq INTEGER NOT NULL,
|
||||
label TEXT NOT NULL,
|
||||
content TEXT NOT NULL,
|
||||
contributors TEXT NOT NULL,
|
||||
status TEXT NOT NULL DEFAULT 'cited',
|
||||
refs TEXT,
|
||||
created_at TEXT NOT NULL,
|
||||
PRIMARY KEY (dialogue_id, round, seq)
|
||||
);
|
||||
|
||||
CREATE TABLE alignment_claims (
|
||||
dialogue_id TEXT NOT NULL,
|
||||
round INTEGER NOT NULL,
|
||||
seq INTEGER NOT NULL,
|
||||
label TEXT NOT NULL,
|
||||
content TEXT NOT NULL,
|
||||
contributors TEXT NOT NULL,
|
||||
status TEXT NOT NULL DEFAULT 'asserted',
|
||||
refs TEXT,
|
||||
created_at TEXT NOT NULL,
|
||||
PRIMARY KEY (dialogue_id, round, seq)
|
||||
);
|
||||
|
||||
CREATE TABLE alignment_refs (
|
||||
dialogue_id TEXT NOT NULL,
|
||||
source_type TEXT NOT NULL,
|
||||
source_id TEXT NOT NULL,
|
||||
ref_type TEXT NOT NULL,
|
||||
target_type TEXT NOT NULL,
|
||||
target_id TEXT NOT NULL,
|
||||
created_at TEXT NOT NULL,
|
||||
PRIMARY KEY (dialogue_id, source_id, ref_type, target_id)
|
||||
);
|
||||
|
||||
CREATE TABLE alignment_verdicts (
|
||||
dialogue_id TEXT NOT NULL,
|
||||
verdict_id TEXT NOT NULL,
|
||||
verdict_type TEXT NOT NULL,
|
||||
round INTEGER NOT NULL,
|
||||
author_expert TEXT,
|
||||
recommendation TEXT NOT NULL,
|
||||
description TEXT NOT NULL,
|
||||
conditions TEXT,
|
||||
vote TEXT,
|
||||
confidence TEXT,
|
||||
tensions_resolved TEXT,
|
||||
tensions_accepted TEXT,
|
||||
recommendations_adopted TEXT,
|
||||
key_evidence TEXT,
|
||||
key_claims TEXT,
|
||||
supporting_experts TEXT,
|
||||
ethos_compliance TEXT,
|
||||
created_at TEXT NOT NULL,
|
||||
PRIMARY KEY (dialogue_id, verdict_id)
|
||||
);
|
||||
"#,
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
conn
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_generate_dialogue_id() {
|
||||
let conn = setup_test_db();
|
||||
|
||||
let id1 = generate_dialogue_id(&conn, "Test Dialogue").unwrap();
|
||||
assert_eq!(id1, "test-dialogue");
|
||||
|
||||
// Create the first dialogue
|
||||
create_dialogue(&conn, "Test Dialogue", None, None, None).unwrap();
|
||||
|
||||
// Second dialogue with same title should get suffix
|
||||
let id2 = generate_dialogue_id(&conn, "Test Dialogue").unwrap();
|
||||
assert_eq!(id2, "test-dialogue-2");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_display_id_format() {
|
||||
assert_eq!(display_id(EntityType::Perspective, 0, 1), "P0001");
|
||||
assert_eq!(display_id(EntityType::Tension, 1, 5), "T0105");
|
||||
assert_eq!(display_id(EntityType::Recommendation, 2, 15), "R0215");
|
||||
assert_eq!(display_id(EntityType::Evidence, 0, 99), "E0099");
|
||||
assert_eq!(display_id(EntityType::Claim, 3, 1), "C0301");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse_display_id() {
|
||||
let (entity, round, seq) = parse_display_id("P0001").unwrap();
|
||||
assert_eq!(entity, EntityType::Perspective);
|
||||
assert_eq!(round, 0);
|
||||
assert_eq!(seq, 1);
|
||||
|
||||
let (entity, round, seq) = parse_display_id("T0105").unwrap();
|
||||
assert_eq!(entity, EntityType::Tension);
|
||||
assert_eq!(round, 1);
|
||||
assert_eq!(seq, 5);
|
||||
|
||||
let (entity, round, seq) = parse_display_id("R0215").unwrap();
|
||||
assert_eq!(entity, EntityType::Recommendation);
|
||||
assert_eq!(round, 2);
|
||||
assert_eq!(seq, 15);
|
||||
|
||||
// Invalid IDs
|
||||
assert!(parse_display_id("X0001").is_none()); // Invalid type
|
||||
assert!(parse_display_id("P001").is_none()); // Too short
|
||||
assert!(parse_display_id("P00001").is_none()); // Too long
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_create_and_get_dialogue() {
|
||||
let conn = setup_test_db();
|
||||
|
||||
let id = create_dialogue(
|
||||
&conn,
|
||||
"NVIDIA Investment Analysis",
|
||||
Some("Should Acme Trust swap NVAI for NVDA?"),
|
||||
Some("/tmp/blue-dialogue/nvidia"),
|
||||
None,
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
assert_eq!(id, "nvidia-investment-analysis");
|
||||
|
||||
let dialogue = get_dialogue(&conn, &id).unwrap();
|
||||
assert_eq!(dialogue.title, "NVIDIA Investment Analysis");
|
||||
assert_eq!(
|
||||
dialogue.question,
|
||||
Some("Should Acme Trust swap NVAI for NVDA?".to_string())
|
||||
);
|
||||
assert_eq!(dialogue.status, DialogueStatus::Open);
|
||||
assert_eq!(dialogue.total_rounds, 0);
|
||||
assert_eq!(dialogue.total_alignment, 0);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_register_expert() {
|
||||
let conn = setup_test_db();
|
||||
create_dialogue(&conn, "Test", None, None, None).unwrap();
|
||||
|
||||
register_expert(
|
||||
&conn,
|
||||
"test",
|
||||
"muffin",
|
||||
"Value Analyst",
|
||||
ExpertTier::Core,
|
||||
ExpertSource::Pool,
|
||||
Some("Evaluates intrinsic value"),
|
||||
Some("Margin of safety"),
|
||||
Some(0.95),
|
||||
None,
|
||||
Some("#ff6b6b"),
|
||||
Some(0),
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
let experts = get_experts(&conn, "test").unwrap();
|
||||
assert_eq!(experts.len(), 1);
|
||||
assert_eq!(experts[0].expert_slug, "muffin");
|
||||
assert_eq!(experts[0].role, "Value Analyst");
|
||||
assert_eq!(experts[0].tier, ExpertTier::Core);
|
||||
assert_eq!(experts[0].source, ExpertSource::Pool);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_register_perspective() {
|
||||
let conn = setup_test_db();
|
||||
create_dialogue(&conn, "Test", None, None, None).unwrap();
|
||||
|
||||
let id = register_perspective(
|
||||
&conn,
|
||||
"test",
|
||||
0,
|
||||
"Income mandate mismatch",
|
||||
"NVIDIA's zero dividend conflicts with the trust's 4% income requirement.",
|
||||
&["muffin".to_string()],
|
||||
None,
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
assert_eq!(id, "P0001");
|
||||
|
||||
// Register another perspective
|
||||
let id2 = register_perspective(
|
||||
&conn,
|
||||
"test",
|
||||
0,
|
||||
"Concentration risk",
|
||||
"Adding NVDA increases semiconductor exposure.",
|
||||
&["cupcake".to_string()],
|
||||
None,
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
assert_eq!(id2, "P0002");
|
||||
|
||||
let perspectives = get_perspectives(&conn, "test").unwrap();
|
||||
assert_eq!(perspectives.len(), 2);
|
||||
assert_eq!(perspectives[0].label, "Income mandate mismatch");
|
||||
assert_eq!(perspectives[1].label, "Concentration risk");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_register_tension() {
|
||||
let conn = setup_test_db();
|
||||
create_dialogue(&conn, "Test", None, None, None).unwrap();
|
||||
|
||||
let id = register_tension(
|
||||
&conn,
|
||||
"test",
|
||||
0,
|
||||
"Growth vs income",
|
||||
"NVIDIA's zero dividend conflicts with 4% income mandate",
|
||||
&["muffin".to_string(), "cupcake".to_string()],
|
||||
None,
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
assert_eq!(id, "T0001");
|
||||
|
||||
let tensions = get_tensions(&conn, "test").unwrap();
|
||||
assert_eq!(tensions.len(), 1);
|
||||
assert_eq!(tensions[0].status, TensionStatus::Open);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_tension_lifecycle() {
|
||||
let conn = setup_test_db();
|
||||
create_dialogue(&conn, "Test", None, None, None).unwrap();
|
||||
|
||||
register_tension(
|
||||
&conn,
|
||||
"test",
|
||||
0,
|
||||
"Growth vs income",
|
||||
"Income mandate conflict",
|
||||
&["muffin".to_string()],
|
||||
None,
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
// Address the tension
|
||||
update_tension_status(
|
||||
&conn,
|
||||
"test",
|
||||
"T0001",
|
||||
TensionStatus::Addressed,
|
||||
&["donut".to_string()],
|
||||
Some("R0001"),
|
||||
1,
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
let tensions = get_tensions(&conn, "test").unwrap();
|
||||
assert_eq!(tensions[0].status, TensionStatus::Addressed);
|
||||
|
||||
// Resolve the tension
|
||||
update_tension_status(
|
||||
&conn,
|
||||
"test",
|
||||
"T0001",
|
||||
TensionStatus::Resolved,
|
||||
&["muffin".to_string()],
|
||||
Some("P0101"),
|
||||
2,
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
let tensions = get_tensions(&conn, "test").unwrap();
|
||||
assert_eq!(tensions[0].status, TensionStatus::Resolved);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_expert_scores() {
|
||||
let conn = setup_test_db();
|
||||
create_dialogue(&conn, "Test", None, None, None).unwrap();
|
||||
|
||||
register_expert(
|
||||
&conn,
|
||||
"test",
|
||||
"muffin",
|
||||
"Value Analyst",
|
||||
ExpertTier::Core,
|
||||
ExpertSource::Pool,
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
Some(0),
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
// Update score for round 0
|
||||
update_expert_score(&conn, "test", "muffin", 0, 12).unwrap();
|
||||
|
||||
let experts = get_experts(&conn, "test").unwrap();
|
||||
assert_eq!(experts[0].total_score, 12);
|
||||
assert_eq!(experts[0].scores["0"], 12);
|
||||
|
||||
// Update score for round 1
|
||||
update_expert_score(&conn, "test", "muffin", 1, 8).unwrap();
|
||||
|
||||
let experts = get_experts(&conn, "test").unwrap();
|
||||
assert_eq!(experts[0].total_score, 20);
|
||||
assert_eq!(experts[0].scores["1"], 8);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_cross_references() {
|
||||
let conn = setup_test_db();
|
||||
create_dialogue(&conn, "Test", None, None, None).unwrap();
|
||||
|
||||
register_ref(
|
||||
&conn,
|
||||
"test",
|
||||
EntityType::Perspective,
|
||||
"P0101",
|
||||
RefType::Refine,
|
||||
EntityType::Perspective,
|
||||
"P0001",
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
register_ref(
|
||||
&conn,
|
||||
"test",
|
||||
EntityType::Recommendation,
|
||||
"R0001",
|
||||
RefType::Address,
|
||||
EntityType::Tension,
|
||||
"T0001",
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
// Verify refs are stored (we'd need a get_refs function to fully test)
|
||||
// For now, just verify no errors
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_verdict_registration() {
|
||||
let conn = setup_test_db();
|
||||
create_dialogue(&conn, "Test", None, None, None).unwrap();
|
||||
|
||||
let verdict = Verdict {
|
||||
dialogue_id: "test".to_string(),
|
||||
verdict_id: "final".to_string(),
|
||||
verdict_type: VerdictType::Final,
|
||||
round: 3,
|
||||
author_expert: None,
|
||||
recommendation: "APPROVE conditional partial trim".to_string(),
|
||||
description: "The panel approved the strategy with conditions.".to_string(),
|
||||
conditions: Some(vec![
|
||||
"Execute 60-90 days post-refinancing".to_string(),
|
||||
"Implement 30-delta covered calls".to_string(),
|
||||
]),
|
||||
vote: Some("12-0".to_string()),
|
||||
confidence: Some("unanimous".to_string()),
|
||||
tensions_resolved: Some(vec!["T0001".to_string(), "T0002".to_string()]),
|
||||
tensions_accepted: None,
|
||||
recommendations_adopted: Some(vec!["R0001".to_string()]),
|
||||
key_evidence: None,
|
||||
key_claims: None,
|
||||
supporting_experts: None,
|
||||
ethos_compliance: None,
|
||||
created_at: Utc::now(),
|
||||
};
|
||||
|
||||
register_verdict(&conn, &verdict).unwrap();
|
||||
|
||||
// Verify dialogue status updated to converged
|
||||
let dialogue = get_dialogue(&conn, "test").unwrap();
|
||||
assert_eq!(dialogue.status, DialogueStatus::Converged);
|
||||
|
||||
let verdicts = get_verdicts(&conn, "test").unwrap();
|
||||
assert_eq!(verdicts.len(), 1);
|
||||
assert_eq!(verdicts[0].verdict_type, VerdictType::Final);
|
||||
assert_eq!(verdicts[0].vote, Some("12-0".to_string()));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_full_dialogue_workflow() {
|
||||
let conn = setup_test_db();
|
||||
|
||||
// Create dialogue
|
||||
let id = create_dialogue(
|
||||
&conn,
|
||||
"NVIDIA Investment",
|
||||
Some("Should we swap NVAI for NVDA?"),
|
||||
None,
|
||||
None,
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
// Register experts
|
||||
register_expert(
|
||||
&conn,
|
||||
&id,
|
||||
"muffin",
|
||||
"Value Analyst",
|
||||
ExpertTier::Core,
|
||||
ExpertSource::Pool,
|
||||
None,
|
||||
None,
|
||||
Some(0.95),
|
||||
None,
|
||||
None,
|
||||
Some(0),
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
register_expert(
|
||||
&conn,
|
||||
&id,
|
||||
"donut",
|
||||
"Options Strategist",
|
||||
ExpertTier::Adjacent,
|
||||
ExpertSource::Pool,
|
||||
None,
|
||||
None,
|
||||
Some(0.70),
|
||||
None,
|
||||
None,
|
||||
Some(0),
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
// Create round 0
|
||||
create_round(&conn, &id, 0, Some("Opening Arguments"), 0).unwrap();
|
||||
|
||||
// Register perspectives
|
||||
let p1 = register_perspective(
|
||||
&conn,
|
||||
&id,
|
||||
0,
|
||||
"Income mandate mismatch",
|
||||
"Zero dividend conflicts with 4% requirement",
|
||||
&["muffin".to_string()],
|
||||
None,
|
||||
)
|
||||
.unwrap();
|
||||
assert_eq!(p1, "P0001");
|
||||
|
||||
let p2 = register_perspective(
|
||||
&conn,
|
||||
&id,
|
||||
0,
|
||||
"Options overlay opportunity",
|
||||
"Covered calls can generate income",
|
||||
&["donut".to_string()],
|
||||
None,
|
||||
)
|
||||
.unwrap();
|
||||
assert_eq!(p2, "P0002");
|
||||
|
||||
// Register tension
|
||||
let t1 = register_tension(
|
||||
&conn,
|
||||
&id,
|
||||
0,
|
||||
"Growth vs income",
|
||||
"Fundamental conflict",
|
||||
&["muffin".to_string()],
|
||||
None,
|
||||
)
|
||||
.unwrap();
|
||||
assert_eq!(t1, "T0001");
|
||||
|
||||
// Register recommendation
|
||||
let r1 = register_recommendation(
|
||||
&conn,
|
||||
&id,
|
||||
0,
|
||||
"Income Collar Structure",
|
||||
"Use 30-delta covered calls",
|
||||
&["donut".to_string()],
|
||||
Some(&serde_json::json!({"delta": "0.30", "dte": "45"})),
|
||||
None,
|
||||
)
|
||||
.unwrap();
|
||||
assert_eq!(r1, "R0001");
|
||||
|
||||
// Update scores
|
||||
update_expert_score(&conn, &id, "muffin", 0, 12).unwrap();
|
||||
update_expert_score(&conn, &id, "donut", 0, 15).unwrap();
|
||||
|
||||
// Verify state
|
||||
let dialogue = get_dialogue(&conn, &id).unwrap();
|
||||
assert_eq!(dialogue.total_rounds, 1);
|
||||
|
||||
let perspectives = get_perspectives(&conn, &id).unwrap();
|
||||
assert_eq!(perspectives.len(), 2);
|
||||
|
||||
let tensions = get_tensions(&conn, &id).unwrap();
|
||||
assert_eq!(tensions.len(), 1);
|
||||
|
||||
let recommendations = get_recommendations(&conn, &id).unwrap();
|
||||
assert_eq!(recommendations.len(), 1);
|
||||
assert!(recommendations[0].parameters.is_some());
|
||||
|
||||
let experts = get_experts(&conn, &id).unwrap();
|
||||
let total_score: i32 = experts.iter().map(|e| e.total_score).sum();
|
||||
assert_eq!(total_score, 27);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue