Files
wehub-resource-sync f99010fae1
CI / lint (push) Failing after 1s
CI / frontend (push) Failing after 1s
CI / scripts (push) Failing after 1s
CI / Go Test (ubuntu-latest) (push) Failing after 0s
CI / frontend-node-25 (push) Failing after 1s
CI / docs (push) Failing after 0s
CI / coverage (push) Failing after 0s
CI / e2e (push) Failing after 0s
Docker / build-and-push (push) Failing after 1s
CI / integration (push) Failing after 4m43s
CI / Go Test (windows-latest) (push) Has been cancelled
CI / Desktop Unit Tests (Windows) (push) Has been cancelled
Desktop Artifacts / Desktop Build (Linux (arm64)) (push) Has been cancelled
Desktop Artifacts / Desktop Build (Linux) (push) Has been cancelled
Desktop Artifacts / Desktop Build (Windows) (push) Has been cancelled
Desktop Artifacts (macOS) / Desktop Build (macOS (aarch64)) (push) Has been cancelled
Desktop Artifacts (macOS) / Desktop Build (macOS (x86_64)) (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 12:30:36 +08:00

158 lines
4.6 KiB
Go

package db
import (
"context"
"testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
// windowMsgSpec describes one seeded message's role, keyed by ordinal.
type windowMsgSpec struct {
ordinal int
role string
}
// seedWindowMessages seeds a session with 12 messages (ordinals 0..11) with a
// mix of user/assistant/system roles, used across the GetMessagesWindow
// tests. Layout:
//
// 0 user, 1 assistant, 2 user, 3 assistant, 4 system, 5 user,
// 6 assistant, 7 user, 8 assistant, 9 system, 10 user, 11 assistant
func seedWindowMessages(t *testing.T, d *DB, sessionID string) {
t.Helper()
insertSession(t, d, sessionID, "proj")
specs := []windowMsgSpec{
{0, "user"}, {1, "assistant"}, {2, "user"}, {3, "assistant"},
{4, "system"}, {5, "user"}, {6, "assistant"}, {7, "user"},
{8, "assistant"}, {9, "system"}, {10, "user"}, {11, "assistant"},
}
msgs := make([]Message, 0, len(specs))
for _, sp := range specs {
content := "msg"
msgs = append(msgs, Message{
SessionID: sessionID,
Ordinal: sp.ordinal,
Role: sp.role,
Content: content,
ContentLength: len(content),
IsSystem: sp.role == "system",
})
}
insertMessages(t, d, msgs...)
}
func ordinalsOf(msgs []Message) []int {
out := make([]int, len(msgs))
for i, m := range msgs {
out[i] = m.Ordinal
}
return out
}
func TestGetMessagesWindow_AroundMidSession(t *testing.T) {
d := testDB(t)
ctx := context.Background()
seedWindowMessages(t, d, "sMid")
anchor := 6
msgs, err := d.GetMessagesWindow(ctx, "sMid", MessageWindow{
Around: &anchor, Before: 2, After: 2,
})
require.NoError(t, err)
assert.Equal(t, []int{4, 5, 6, 7, 8}, ordinalsOf(msgs),
"unfiltered window should return anchor +/- 2 ordinals ascending")
}
func TestGetMessagesWindow_RoleFilterCountsFilteredMessages(t *testing.T) {
d := testDB(t)
ctx := context.Background()
seedWindowMessages(t, d, "sRoleCount")
anchor := 6
msgs, err := d.GetMessagesWindow(ctx, "sRoleCount", MessageWindow{
Around: &anchor, Before: 2, After: 2,
Roles: []string{"user", "assistant"},
})
require.NoError(t, err)
// Ordinal 4 (system) sits between 3 and 5, so the 2 role-filtered
// messages before the anchor are ordinals 3 and 5, not 4 and 5.
assert.Equal(t, []int{3, 5, 6, 7, 8}, ordinalsOf(msgs),
"before/after counts should count role-filtered messages, not raw ordinals")
}
func TestGetMessagesWindow_AnchorIncludedEvenWhenRoleFiltered(t *testing.T) {
d := testDB(t)
ctx := context.Background()
seedWindowMessages(t, d, "sAnchorFiltered")
anchor := 4 // role "system", excluded by the role filter
msgs, err := d.GetMessagesWindow(ctx, "sAnchorFiltered", MessageWindow{
Around: &anchor, Before: 1, After: 1,
Roles: []string{"user", "assistant"},
})
require.NoError(t, err)
require.Equal(t, []int{3, 4, 5}, ordinalsOf(msgs),
"anchor must be included even though its own role is filtered out")
assert.Equal(t, "system", msgs[1].Role)
}
func TestGetMessagesWindow_AroundOrdinalZeroHasNoBefore(t *testing.T) {
d := testDB(t)
ctx := context.Background()
seedWindowMessages(t, d, "sFirst")
anchor := 0
msgs, err := d.GetMessagesWindow(ctx, "sFirst", MessageWindow{
Around: &anchor, Before: 2, After: 2,
})
require.NoError(t, err)
assert.Equal(t, []int{0, 1, 2}, ordinalsOf(msgs),
"no before rows exist above the first ordinal")
}
func TestGetMessagesWindow_AroundLastOrdinalHasNoAfter(t *testing.T) {
d := testDB(t)
ctx := context.Background()
seedWindowMessages(t, d, "sLast")
anchor := 11
msgs, err := d.GetMessagesWindow(ctx, "sLast", MessageWindow{
Around: &anchor, Before: 2, After: 2,
})
require.NoError(t, err)
assert.Equal(t, []int{9, 10, 11}, ordinalsOf(msgs),
"no after rows exist below the last ordinal")
}
func TestGetMessagesWindow_LinearModeWithRoles(t *testing.T) {
d := testDB(t)
ctx := context.Background()
seedWindowMessages(t, d, "sLinearRoles")
msgs, err := d.GetMessagesWindow(ctx, "sLinearRoles", MessageWindow{
Limit: 100, Asc: true, Roles: []string{"user"},
})
require.NoError(t, err)
assert.Equal(t, []int{0, 2, 5, 7, 10}, ordinalsOf(msgs),
"linear mode should apply the role filter like the around mode")
}
func TestGetMessagesWindow_EmptyRolesEquivalentToGetMessages(t *testing.T) {
d := testDB(t)
ctx := context.Background()
seedWindowMessages(t, d, "sEquiv")
direct, err := d.GetMessages(ctx, "sEquiv", 3, 5, true)
require.NoError(t, err)
from := 3
windowed, err := d.GetMessagesWindow(ctx, "sEquiv", MessageWindow{
From: &from, Limit: 5, Asc: true,
})
require.NoError(t, err)
assert.Equal(t, direct, windowed,
"empty Roles should behave identically to GetMessages")
}