mirror of
https://github.com/netbirdio/netbird.git
synced 2026-07-20 15:31:30 +02:00
fix(ui): tray exit-node toggle no longer disables other routes
The tray Selected an exit node with append=false, which the RouteSelector treats as "drop the whole current selection" (default-on semantics), so enabling an exit node also turned off every non-exit routed network the user had on. Send append=true instead and let the daemon's SelectNetworks handler deselect only the sibling exit nodes — matching the frontend's toggleExitNode, which already used append=true. Add a RouteSelector regression test covering the handler sequence.
This commit is contained in:
@@ -825,3 +825,31 @@ func TestRouteSelector_ComplexScenarios(t *testing.T) {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// TestRouteSelector_EnableExitNodeKeepsOtherRoutes is a regression test for the
|
||||
// tray exit-node toggle disabling every non-exit routed network. The tray used
|
||||
// to Select an exit node with append=false, which the RouteSelector treats as
|
||||
// "drop the whole current selection" (default-on semantics) — so enabling an
|
||||
// exit node also turned off every LAN/route the user had on. The fix sends
|
||||
// append=true and lets the daemon's SelectNetworks handler deselect only the
|
||||
// sibling exit nodes. This test models that handler sequence against the
|
||||
// selector: SelectRoutes(exit, append=true) followed by DeselectRoutes(other
|
||||
// exit nodes) must leave non-exit routes untouched.
|
||||
func TestRouteSelector_EnableExitNodeKeepsOtherRoutes(t *testing.T) {
|
||||
rs := routeselector.NewRouteSelector()
|
||||
all := []route.NetID{"exitA", "exitB", "lan1", "lan2"}
|
||||
|
||||
// User has two LAN routes on (default-on: nothing deselected => all selected).
|
||||
require.True(t, rs.IsSelected("lan1"))
|
||||
require.True(t, rs.IsSelected("lan2"))
|
||||
|
||||
// Tray enables exitA: SelectNetworks handler does SelectRoutes(append=true)
|
||||
// then deselects sibling exit nodes (exitB), never the LAN routes.
|
||||
require.NoError(t, rs.SelectRoutes([]route.NetID{"exitA"}, true, all))
|
||||
require.NoError(t, rs.DeselectRoutes([]route.NetID{"exitB"}, all))
|
||||
|
||||
assert.True(t, rs.IsSelected("exitA"), "selected exit node stays on")
|
||||
assert.False(t, rs.IsSelected("exitB"), "sibling exit node is deselected")
|
||||
assert.True(t, rs.IsSelected("lan1"), "non-exit route must stay selected")
|
||||
assert.True(t, rs.IsSelected("lan2"), "non-exit route must stay selected")
|
||||
}
|
||||
|
||||
@@ -97,17 +97,19 @@ func (t *Tray) refreshExitNodes() {
|
||||
}
|
||||
|
||||
// toggleExitNode activates or deactivates one exit node by NetID. Exit nodes
|
||||
// are mutually exclusive, so Select uses append=false to clear any other
|
||||
// active node before turning this one on; deselecting an active node turns
|
||||
// routing off entirely. Mirrors the frontend's toggleExitNode semantics. Runs
|
||||
// the RPC off the menu-click goroutine and re-fetches so the ✓ moves to the
|
||||
// new selection.
|
||||
// are mutually exclusive, but enforcement of that lives daemon-side: the
|
||||
// SelectNetworks handler deselects every other exit node when this Select
|
||||
// activates one. So Select uses append=true — append=false would tell the
|
||||
// RouteSelector to drop the whole current selection (default-on semantics),
|
||||
// which also turns off every non-exit routed network the user had enabled.
|
||||
// Mirrors the frontend's toggleExitNode semantics. Runs the RPC off the
|
||||
// menu-click goroutine and re-fetches so the ✓ moves to the new selection.
|
||||
func (t *Tray) toggleExitNode(id string, selected bool) {
|
||||
go func() {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
|
||||
defer cancel()
|
||||
|
||||
params := services.SelectNetworksParams{NetworkIDs: []string{id}, Append: false, All: false}
|
||||
params := services.SelectNetworksParams{NetworkIDs: []string{id}, Append: true, All: false}
|
||||
var err error
|
||||
if selected {
|
||||
err = t.svc.Networks.Deselect(ctx, params)
|
||||
|
||||
Reference in New Issue
Block a user