package xray import ( "testing" ) // TestRemoveUserGuardsNilHandlerClient pins that mutation calls on an // uninitialized client fail instead of panicking. In this build they fail // unconditionally — hot-apply is unavailable without xray-core — and every // caller treats that as "fall back to a core restart". func TestRemoveUserGuardsNilHandlerClient(t *testing.T) { err := (&XrayAPI{}).RemoveUser("in-443-tcp", "user@example.com") if err == nil { t.Fatal("RemoveUser with an uninitialized client must return an error") } } func TestHotApplyMutationsAreUnavailable(t *testing.T) { api := &XrayAPI{} calls := map[string]func() error{ "AddInbound": func() error { return api.AddInbound([]byte("{}")) }, "DelInbound": func() error { return api.DelInbound("in-443-tcp") }, "AddOutbound": func() error { return api.AddOutbound([]byte("{}")) }, "DelOutbound": func() error { return api.DelOutbound("direct") }, "ApplyRoutingConfig": func() error { return api.ApplyRoutingConfig([]byte("{}")) }, "AddUser": func() error { return api.AddUser("vless", "in-443-tcp", map[string]any{"email": "a@b.c"}) }, "RemoveUser": func() error { return api.RemoveUser("in-443-tcp", "a@b.c") }, "SetBalancerTarget": func() error { return api.SetBalancerTarget("lb", "direct") }, } for name, call := range calls { if err := call(); err != ErrHotApplyUnavailable { t.Fatalf("%s = %v, want ErrHotApplyUnavailable", name, err) } } if _, err := api.GetBalancerInfo("lb"); err != ErrHotApplyUnavailable { t.Fatalf("GetBalancerInfo = %v, want ErrHotApplyUnavailable", err) } if _, err := api.TestRoute(RouteTestRequest{}); err != ErrHotApplyUnavailable { t.Fatalf("TestRoute = %v, want ErrHotApplyUnavailable", err) } }