81 lines
3.3 KiB
Go
81 lines
3.3 KiB
Go
package companion
|
|
|
|
import (
|
|
"context"
|
|
"testing"
|
|
"time"
|
|
)
|
|
|
|
type trajectorySourceFixture struct {
|
|
positions []map[string]any
|
|
vehicles []map[string]any
|
|
limits []int
|
|
}
|
|
|
|
func (source *trajectorySourceFixture) ReadPositionRows(_ context.Context, limit int) ([]map[string]any, error) {
|
|
source.limits = append(source.limits, limit)
|
|
return source.positions, nil
|
|
}
|
|
|
|
func (source *trajectorySourceFixture) ReadVehicleRows(_ context.Context, limit int) ([]map[string]any, error) {
|
|
source.limits = append(source.limits, limit)
|
|
return source.vehicles, nil
|
|
}
|
|
|
|
type trajectoryStoreFixture struct {
|
|
ensureCalls int
|
|
samples []TrajectorySample
|
|
}
|
|
|
|
func (store *trajectoryStoreFixture) EnsureSchema(context.Context) error {
|
|
store.ensureCalls++
|
|
return nil
|
|
}
|
|
|
|
func (store *trajectoryStoreFixture) StorePositionRows(_ context.Context, serverInstanceID string, rows []map[string]any, sampledAt time.Time) (int, error) {
|
|
samples, err := TrajectorySamplesFromPositionRows(serverInstanceID, rows, sampledAt)
|
|
if err != nil {
|
|
return 0, err
|
|
}
|
|
store.samples = append(store.samples, samples...)
|
|
return len(samples), nil
|
|
}
|
|
|
|
func (store *trajectoryStoreFixture) StoreVehicleRows(_ context.Context, serverInstanceID string, rows []map[string]any, sampledAt time.Time) (int, error) {
|
|
samples, err := TrajectorySamplesFromVehicleRows(serverInstanceID, rows, sampledAt)
|
|
if err != nil {
|
|
return 0, err
|
|
}
|
|
store.samples = append(store.samples, samples...)
|
|
return len(samples), nil
|
|
}
|
|
|
|
func TestTrajectoryCollectorStoresRawSCUMWorldCoordinates(t *testing.T) {
|
|
sampledAt := time.Date(2026, 8, 31, 3, 30, 0, 0, time.UTC)
|
|
source := &trajectorySourceFixture{
|
|
positions: []map[string]any{{"subjectType": "player", "subjectId": "76561198000000001", "gamePlayerId": "player-1", "x": 123.25, "y": -456.5, "z": 7.75, "observedAt": "2026-08-31T03:29:59Z"}},
|
|
vehicles: []map[string]any{{"vehicleId": "vehicle-1", "entityId": "entity-1", "className": "BPC_Laika_C", "label": "Laika", "x": -10.5, "y": 20.25, "z": 0}},
|
|
}
|
|
store := &trajectoryStoreFixture{}
|
|
collector := &TrajectoryCollector{Source: source, Store: store, ServerInstanceID: "server-1", MaxRows: 777, Now: func() time.Time { return sampledAt }}
|
|
report, err := collector.CollectOnce(context.Background())
|
|
if err != nil {
|
|
t.Fatalf("collect trajectories: %v", err)
|
|
}
|
|
if report.PositionRows != 1 || report.VehicleRows != 1 || report.StoredSamples != 2 || report.Reason != "raw world coordinates stored" {
|
|
t.Fatalf("unexpected collection report: %+v", report)
|
|
}
|
|
if store.ensureCalls != 1 || len(source.limits) != 2 || source.limits[0] != 777 || source.limits[1] != 777 {
|
|
t.Fatalf("collector did not use bounded source/store once: ensure=%d limits=%v", store.ensureCalls, source.limits)
|
|
}
|
|
if len(store.samples) != 2 {
|
|
t.Fatalf("expected two trajectory samples, got %+v", store.samples)
|
|
}
|
|
if store.samples[0].WorldX != 123.25 || store.samples[0].WorldY != -456.5 || store.samples[0].WorldZ == nil || *store.samples[0].WorldZ != 7.75 {
|
|
t.Fatalf("player coordinates were changed before storage: %+v", store.samples[0])
|
|
}
|
|
if store.samples[1].SubjectType != "vehicle" || store.samples[1].WorldX != -10.5 || store.samples[1].WorldY != 20.25 || store.samples[1].Source != "plugin.sql.scum.vehicles" {
|
|
t.Fatalf("vehicle coordinates were changed before storage: %+v", store.samples[1])
|
|
}
|
|
}
|