Files
Cyrene_v2/internal/services/backthink/state_test.go
T

86 lines
2.4 KiB
Go

package backthink
import (
"context"
"errors"
"testing"
"git.yeij.top/AskaEth/Cyrene_v2/internal/config"
"git.yeij.top/AskaEth/Cyrene_v2/internal/iot"
)
// stateMockProvider is a tiny iot.Provider that returns a heart-rate watch, a
// sleep band and a working-calendar device, to exercise the state decoding.
type stateMockProvider struct{}
func (stateMockProvider) Name() string { return "state-mock" }
func (stateMockProvider) List(context.Context) ([]iot.Device, error) {
return []iot.Device{
{ID: "watch.heart", Name: "心率手表", Type: "sensor", State: map[string]any{"bpm": 62}},
{ID: "band.sleep", Name: "睡眠手环", Type: "sensor", State: map[string]any{"sleeping": true}},
{ID: "cal.schedule", Name: "日程", State: map[string]any{"working": true}},
}, nil
}
func (stateMockProvider) Control(context.Context, string, string, map[string]any) (*iot.Device, error) {
return nil, iot.ErrUnsupported
}
func (stateMockProvider) Status(context.Context, string) (*iot.Device, error) {
return nil, iot.ErrDeviceNotFound
}
func TestIoTStateProvider_Current(t *testing.T) {
t.Parallel()
mgr, err := iot.New(config.IoTConfig{Provider: "none"}, nil)
if err != nil {
t.Fatalf("iot.New: %v", err)
}
if err := mgr.Register(stateMockProvider{}); err != nil {
t.Fatalf("Register: %v", err)
}
p := NewIoTStateProvider(mgr, nil)
st, err := p.Current(context.Background())
if err != nil {
t.Fatalf("Current: %v", err)
}
if st.HeartRateBPM != 62 {
t.Fatalf("HeartRateBPM = %d, want 62", st.HeartRateBPM)
}
if !st.Sleeping {
t.Fatalf("Sleeping = false, want true")
}
if !st.Working {
t.Fatalf("Working = false, want true")
}
}
func TestIoTStateProvider_NilManager(t *testing.T) {
t.Parallel()
p := NewIoTStateProvider(nil, nil)
_, err := p.Current(context.Background())
if !errors.Is(err, iot.ErrProviderNotRegistered) {
t.Fatalf("err = %v, want ErrProviderNotRegistered", err)
}
}
func TestIoTStateProvider_EmptyNeutral(t *testing.T) {
t.Parallel()
mgr, err := iot.New(config.IoTConfig{Provider: "mock"}, nil)
if err != nil {
t.Fatalf("iot.New: %v", err)
}
p := NewIoTStateProvider(mgr, nil)
// The mock provider has no heart-rate/sleep/working device, so it must yield
// a zero state instead of an error, keeping the service operable.
st, err := p.Current(context.Background())
if err != nil {
t.Fatalf("Current: %v", err)
}
if st != (UserState{}) {
t.Fatalf("state = %+v, want zero UserState", st)
}
}