diff --git a/Sense/server/app/sense/media/service_test.go b/Sense/server/app/sense/media/service_test.go index 5f536d3..dc55b3b 100644 --- a/Sense/server/app/sense/media/service_test.go +++ b/Sense/server/app/sense/media/service_test.go @@ -3,9 +3,11 @@ package media import ( "context" "errors" + "strings" "testing" "yovision.local/sense/app/sense/adapters/mediamtx" + "yovision.local/sense/app/sense/adapters/rtsp" "yovision.local/sense/app/sense/admission" "yovision.local/sense/app/sense/device" "yovision.local/sense/app/sense/identity" @@ -108,3 +110,37 @@ func TestReconcileRecordsFailureStates(t *testing.T) { t.Fatalf("result=%#v err=%v", result, err) } } + +func TestConfigureProfilesIsIdempotentAndReportsMediaState(t *testing.T) { + process := &fakeProcess{startErr: errors.New("binary missing")} + service := NewService(NewMemoryStore(), process, fakeController{}) + service.profile = func(_ string, token string) (admission.Profile, error) { + return admission.Profile{Token: token, StreamURI: "rtsp://camera.invalid/" + token}, nil + } + service.credential = func(context.Context, string) (device.Credential, error) { + return device.Credential{Username: "fixture", Password: "fixture"}, nil + } + result := admission.Result{DeviceID: "device", Profiles: []admission.Profile{{Token: "main", Verification: rtspReady()}, {Token: "sub", Verification: rtspReady()}}} + outcome := service.ConfigureProfiles(context.Background(), identity.Principal{}, result) + if outcome.Status != "needs_attention" { + t.Fatalf("outcome=%#v", outcome) + } + outcome = service.ConfigureProfiles(context.Background(), identity.Principal{}, result) + items, err := service.List(context.Background()) + if err != nil || len(items) != 2 || outcome.Status != "needs_attention" { + t.Fatalf("items=%#v outcome=%#v err=%v", items, outcome, err) + } + for _, item := range items { + if item.Actual != "process_failed" || strings.Contains(item.Detail, "binary missing") { + t.Fatalf("unsafe route detail=%#v", item) + } + } + process.startErr = nil + outcome = service.ConfigureProfiles(context.Background(), identity.Principal{}, result) + if outcome.Status != "ready" { + t.Fatalf("ready outcome=%#v", outcome) + } +} + +func rtspReady() rtsp.Result { return rtsp.Result{Status: "ready"} } +