Files
ai-customer-service/internal/domain/session/session_test.go
Your Name 06eeb5776b
Some checks failed
CI / verify (push) Failing after 24s
style(go): apply gofmt to repository
2026-05-06 12:22:41 +08:00

191 lines
4.6 KiB
Go

package session
import (
"testing"
"time"
)
func TestSession_ID(t *testing.T) {
sess := Session{
ID: "channel:openid-123",
}
if sess.ID != "channel:openid-123" {
t.Errorf("expected ID 'channel:openid-123', got %q", sess.ID)
}
}
func TestSession_Channel(t *testing.T) {
sess := Session{
Channel: "wechat",
}
if sess.Channel != "wechat" {
t.Errorf("expected Channel 'wechat', got %q", sess.Channel)
}
}
func TestSession_OpenID(t *testing.T) {
sess := Session{
OpenID: "ou_abc123",
}
if sess.OpenID != "ou_abc123" {
t.Errorf("expected OpenID 'ou_abc123', got %q", sess.OpenID)
}
}
func TestSession_StatusConstants(t *testing.T) {
if StatusIdle != "idle" {
t.Errorf("StatusIdle: expected 'idle', got %q", StatusIdle)
}
if StatusProcessing != "processing" {
t.Errorf("StatusProcessing: expected 'processing', got %q", StatusProcessing)
}
if StatusHandoff != "handoff" {
t.Errorf("StatusHandoff: expected 'handoff', got %q", StatusHandoff)
}
if StatusClosed != "closed" {
t.Errorf("StatusClosed: expected 'closed', got %q", StatusClosed)
}
}
func TestSession_StatusTransitions(t *testing.T) {
tests := []struct {
name string
initial Status
transition Status
}{
{"idle to processing", StatusIdle, StatusProcessing},
{"processing to handoff", StatusProcessing, StatusHandoff},
{"handoff to closed", StatusHandoff, StatusClosed},
{"idle directly to closed", StatusIdle, StatusClosed},
}
for _, tt := range tests {
sess := Session{Status: tt.initial}
if sess.Status != tt.initial {
t.Errorf("%s: expected status %q, got %q", tt.name, tt.initial, sess.Status)
}
sess.Status = tt.transition
if sess.Status != tt.transition {
t.Errorf("%s: expected transitioned status %q, got %q", tt.name, tt.transition, sess.Status)
}
}
}
func TestSession_TurnCount(t *testing.T) {
sess := Session{TurnCount: 0}
if sess.TurnCount != 0 {
t.Errorf("expected TurnCount 0, got %d", sess.TurnCount)
}
sess.TurnCount = 5
if sess.TurnCount != 5 {
t.Errorf("expected TurnCount 5, got %d", sess.TurnCount)
}
}
func TestSession_LastMessageAt(t *testing.T) {
now := time.Now()
sess := Session{LastMessageAt: now}
if !sess.LastMessageAt.Equal(now) {
t.Errorf("LastMessageAt: expected %v, got %v", now, sess.LastMessageAt)
}
}
func TestSession_Context(t *testing.T) {
now := time.Now()
sess := Session{
Context: []MessageContext{
{Direction: "inbound", Content: "hello", Timestamp: now},
{Direction: "outbound", Content: "hi there", Timestamp: now},
},
}
if len(sess.Context) != 2 {
t.Errorf("expected 2 context entries, got %d", len(sess.Context))
}
if sess.Context[0].Content != "hello" {
t.Errorf("expected first content 'hello', got %q", sess.Context[0].Content)
}
if sess.Context[1].Direction != "outbound" {
t.Errorf("expected second direction 'outbound', got %q", sess.Context[1].Direction)
}
}
func TestSession_EmptyContext(t *testing.T) {
sess := Session{Context: []MessageContext{}}
if len(sess.Context) != 0 {
t.Errorf("expected empty context, got %d entries", len(sess.Context))
}
}
func TestSession_UserID(t *testing.T) {
sess := Session{UserID: "user-456"}
if sess.UserID != "user-456" {
t.Errorf("expected UserID 'user-456', got %q", sess.UserID)
}
// UserID can be empty
sess2 := Session{}
if sess2.UserID != "" {
t.Errorf("expected empty UserID, got %q", sess2.UserID)
}
}
func TestMessageContext(t *testing.T) {
now := time.Now()
msg := MessageContext{
Direction: "inbound",
Content: "test message",
Timestamp: now,
}
if msg.Direction != "inbound" {
t.Errorf("Direction: expected 'inbound', got %q", msg.Direction)
}
if msg.Content != "test message" {
t.Errorf("Content: expected 'test message', got %q", msg.Content)
}
if !msg.Timestamp.Equal(now) {
t.Errorf("Timestamp: expected %v, got %v", now, msg.Timestamp)
}
}
func TestSession_FullLifecycle(t *testing.T) {
now := time.Now()
sess := Session{
ID: "wechat:ou_abc",
Channel: "wechat",
OpenID: "ou_abc",
Status: StatusIdle,
TurnCount: 0,
LastMessageAt: now,
Context: []MessageContext{},
}
// Idle -> Processing
sess.Status = StatusProcessing
sess.TurnCount++
if sess.Status != StatusProcessing {
t.Error("failed to transition to Processing")
}
// Add message
sess.Context = append(sess.Context, MessageContext{
Direction: "inbound",
Content: "I need help",
Timestamp: now,
})
// Processing -> Handoff
sess.Status = StatusHandoff
if sess.Status != StatusHandoff {
t.Error("failed to transition to Handoff")
}
// Handoff -> Closed
sess.Status = StatusClosed
if sess.Status != StatusClosed {
t.Error("failed to transition to Closed")
}
}