72de690894
Chatbot functionality * baseline working * missing test file * more tests
105 lines
3.5 KiB
Go
105 lines
3.5 KiB
Go
// Milestone 2 service-layer tests for the chatbot session preview
|
|
// turn-limit math (plan §3, §10 M2, §11).
|
|
//
|
|
// Two contracts are locked in here:
|
|
//
|
|
// 1. Turn-limit derivation: the service caller hands the repository
|
|
// turn_limit = min(request.limit, cfg.RecentTurns) per plan §3.
|
|
// This test exercises the boundary set so a future refactor cannot
|
|
// silently drop the cap.
|
|
// 2. Config validation: a service constructed with a config whose
|
|
// RecentTurns is out of [1, 5] must not be accepted. The
|
|
// authoritative validator lives in
|
|
// internal/serviceconfig/chatbot.ChatbotConfig.Validate; this test
|
|
// proves that path catches the boundaries plan §8 mandates.
|
|
//
|
|
// Compile contract: this file references bot.Service.New plus the
|
|
// bot.SessionListInput / bot.MinTurnLimit symbols that backend-eng
|
|
// emits during M2. Until then the file fails to compile — the failing
|
|
// state the team-lead M2 dispatch endorsed.
|
|
package bot_test
|
|
|
|
import (
|
|
"testing"
|
|
|
|
"queryorchestration/internal/bot"
|
|
"queryorchestration/internal/serviceconfig/chatbot"
|
|
|
|
"github.com/stretchr/testify/require"
|
|
)
|
|
|
|
// TestSessionList_TurnLimitMin proves min(request.limit, cfg.RecentTurns)
|
|
// at the service layer. The bot package exports MinTurnLimit (or
|
|
// equivalently named helper) so the service and any other caller agree
|
|
// on the cap arithmetic.
|
|
//
|
|
// With cfg.RecentTurns=5, the brief lists these (request.limit, want)
|
|
// pairs: (2, 2), (3, 3), (5, 5), (7, 5), (10, 5).
|
|
func TestSessionList_TurnLimitMin(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
const recentTurns = 5
|
|
|
|
cases := []struct {
|
|
name string
|
|
requestLimit int
|
|
want int
|
|
}{
|
|
{name: "below_cap_two", requestLimit: 2, want: 2},
|
|
{name: "below_cap_three", requestLimit: 3, want: 3},
|
|
{name: "at_cap_five", requestLimit: 5, want: 5},
|
|
{name: "above_cap_seven", requestLimit: 7, want: 5},
|
|
{name: "above_cap_ten", requestLimit: 10, want: 5},
|
|
}
|
|
|
|
for _, c := range cases {
|
|
t.Run(c.name, func(t *testing.T) {
|
|
got := bot.MinTurnLimit(c.requestLimit, recentTurns)
|
|
require.Equal(t, c.want, got,
|
|
"plan §3: turn_limit = min(request.limit, cfg.RecentTurns); "+
|
|
"min(%d, %d) expected %d, got %d",
|
|
c.requestLimit, recentTurns, c.want, got)
|
|
})
|
|
}
|
|
}
|
|
|
|
// TestSessionList_RejectsConfigOutOfRange proves that the chatbot
|
|
// config validator catches the same boundaries plan §8 lists, and
|
|
// that bot.New refuses a config whose Validate fails. Two layers,
|
|
// one assertion each — keeps the test focused on the service-level
|
|
// contract.
|
|
func TestSessionList_RejectsConfigOutOfRange(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
cases := []struct {
|
|
name string
|
|
recentTurns int
|
|
}{
|
|
{name: "zero_rejected", recentTurns: 0},
|
|
{name: "six_rejected", recentTurns: 6},
|
|
{name: "negative_rejected", recentTurns: -1},
|
|
}
|
|
|
|
for _, c := range cases {
|
|
t.Run(c.name, func(t *testing.T) {
|
|
cfg := chatbot.ChatbotConfig{
|
|
ServiceURL: "http://chatbot.local:8000",
|
|
APIKey: "k",
|
|
RequestTimeoutSeconds: 60,
|
|
MaxTurnChars: 2000,
|
|
RecentTurns: c.recentTurns,
|
|
}
|
|
require.Error(t, cfg.Validate(),
|
|
"plan §8: ChatbotConfig.Validate must reject RecentTurns=%d", c.recentTurns)
|
|
|
|
// bot.New must refuse the same invalid config so the
|
|
// service can never be constructed with an out-of-range
|
|
// turn-limit cap. The exact error type is not asserted
|
|
// here — only that construction fails.
|
|
_, err := bot.New(cfg, nil)
|
|
require.Errorf(t, err,
|
|
"bot.New must refuse a config with RecentTurns=%d", c.recentTurns)
|
|
})
|
|
}
|
|
}
|