package learnermemory import ( "testing" "tutor/internal/workflows" ) func TestApplyCandidateIgnoresUpdatesWithoutEvidence(t *testing.T) { service := NewService(NewMemoryStore()) if _, err := service.EnsureProfile(ProfileInput{ UserID: "user-1", TargetRole: "junior backend developer", Stack: []string{"go"}, }); err != nil { t.Fatalf("EnsureProfile error: %v", err) } err := service.ApplyCandidate(workflows.MemoryUpdateCandidate{ UserID: "user-1", Updates: []workflows.MemoryUpdate{ { Kind: workflows.MemoryConceptMastery, Concept: workflows.ConceptRef{ID: "http-idempotency", Label: "HTTP idempotency"}, ProposedState: workflows.ReadinessImproving, Summary: "No evidence should not persist.", }, }, }) if err != nil { t.Fatalf("ApplyCandidate error: %v", err) } snapshot, err := service.Snapshot("user-1") if err != nil { t.Fatalf("Snapshot error: %v", err) } if len(snapshot.Mastery) != 0 { t.Fatalf("mastery entries = %d, want 0", len(snapshot.Mastery)) } } func TestApplyCandidateStoresEvidenceBackedMemory(t *testing.T) { service := NewService(NewMemoryStore()) if _, err := service.EnsureProfile(ProfileInput{ UserID: "user-1", TargetRole: "junior backend developer", Stack: []string{"go"}, }); err != nil { t.Fatalf("EnsureProfile error: %v", err) } evidence := []workflows.EvidenceRef{{Kind: workflows.EvidenceAnswer, ID: "answer-1", Confidence: 1}} err := service.ApplyCandidate(workflows.MemoryUpdateCandidate{ UserID: "user-1", Updates: []workflows.MemoryUpdate{ { Kind: workflows.MemoryConceptMastery, Concept: workflows.ConceptRef{ID: "http-idempotency", Label: "HTTP idempotency"}, ProposedState: workflows.ReadinessInterviewReady, Summary: "Evidence-backed concept mastery.", Evidence: evidence, Confidence: 0.8, }, { Kind: workflows.MemoryReviewSchedule, Concept: workflows.ConceptRef{ID: "http-idempotency", Label: "HTTP idempotency"}, Summary: "Review later.", Evidence: evidence, Confidence: 0.7, }, }, }) if err != nil { t.Fatalf("ApplyCandidate error: %v", err) } snapshot, err := service.Snapshot("user-1") if err != nil { t.Fatalf("Snapshot error: %v", err) } if len(snapshot.Mastery) != 1 { t.Fatalf("mastery entries = %d, want 1", len(snapshot.Mastery)) } if len(snapshot.ReviewSchedule) != 1 { t.Fatalf("review entries = %d, want 1", len(snapshot.ReviewSchedule)) } if len(snapshot.Mastery[0].Evidence) != 1 { t.Fatal("expected mastery evidence") } }