|
|
|
|
@ -5348,6 +5348,8 @@ func TestDisplayMessages(t *testing.T) { |
|
|
|
|
ht.SetIPNState("NeedsLogin", true) |
|
|
|
|
ht.GotStreamedMapResponse() |
|
|
|
|
|
|
|
|
|
b.mu.Lock() |
|
|
|
|
defer b.mu.Unlock() |
|
|
|
|
b.setNetMapLocked(&netmap.NetworkMap{ |
|
|
|
|
DisplayMessages: map[tailcfg.DisplayMessageID]tailcfg.DisplayMessage{ |
|
|
|
|
"test-message": { |
|
|
|
|
@ -5374,7 +5376,8 @@ func TestDisplayMessagesURLFilter(t *testing.T) { |
|
|
|
|
ht.SetIPNState("NeedsLogin", true) |
|
|
|
|
ht.GotStreamedMapResponse() |
|
|
|
|
|
|
|
|
|
defer b.lockAndGetUnlock()() |
|
|
|
|
b.mu.Lock() |
|
|
|
|
defer b.mu.Unlock() |
|
|
|
|
b.setNetMapLocked(&netmap.NetworkMap{ |
|
|
|
|
DisplayMessages: map[tailcfg.DisplayMessageID]tailcfg.DisplayMessage{ |
|
|
|
|
"test-message": { |
|
|
|
|
@ -5405,3 +5408,104 @@ func TestDisplayMessagesURLFilter(t *testing.T) { |
|
|
|
|
t.Errorf("Unexpected message content (-want/+got):\n%s", diff) |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// TestDisplayMessageIPNBus checks that we send health messages appropriately
|
|
|
|
|
// based on whether the watcher has sent the [ipn.NotifyHealthActions] watch
|
|
|
|
|
// option or not.
|
|
|
|
|
func TestDisplayMessageIPNBus(t *testing.T) { |
|
|
|
|
type test struct { |
|
|
|
|
name string |
|
|
|
|
mask ipn.NotifyWatchOpt |
|
|
|
|
wantWarning health.UnhealthyState |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
msgs := map[tailcfg.DisplayMessageID]tailcfg.DisplayMessage{ |
|
|
|
|
"test-message": { |
|
|
|
|
Title: "Message title", |
|
|
|
|
Text: "Message text.", |
|
|
|
|
Severity: tailcfg.SeverityMedium, |
|
|
|
|
PrimaryAction: &tailcfg.DisplayMessageAction{ |
|
|
|
|
URL: "https://example.com", |
|
|
|
|
Label: "Learn more", |
|
|
|
|
}, |
|
|
|
|
}, |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
for _, tt := range []test{ |
|
|
|
|
{ |
|
|
|
|
name: "older-client-no-actions", |
|
|
|
|
mask: 0, |
|
|
|
|
wantWarning: health.UnhealthyState{ |
|
|
|
|
WarnableCode: "test-message", |
|
|
|
|
Severity: health.SeverityMedium, |
|
|
|
|
Title: "Message title", |
|
|
|
|
Text: "Message text. Learn more: https://example.com", // PrimaryAction appended to text
|
|
|
|
|
PrimaryAction: nil, // PrimaryAction not included
|
|
|
|
|
}, |
|
|
|
|
}, |
|
|
|
|
{ |
|
|
|
|
name: "new-client-with-actions", |
|
|
|
|
mask: ipn.NotifyHealthActions, |
|
|
|
|
wantWarning: health.UnhealthyState{ |
|
|
|
|
WarnableCode: "test-message", |
|
|
|
|
Severity: health.SeverityMedium, |
|
|
|
|
Title: "Message title", |
|
|
|
|
Text: "Message text.", |
|
|
|
|
PrimaryAction: &health.UnhealthyStateAction{ |
|
|
|
|
URL: "https://example.com", |
|
|
|
|
Label: "Learn more", |
|
|
|
|
}, |
|
|
|
|
}, |
|
|
|
|
}, |
|
|
|
|
} { |
|
|
|
|
t.Run(tt.name, func(t *testing.T) { |
|
|
|
|
t.Parallel() |
|
|
|
|
|
|
|
|
|
lb := newLocalBackendWithTestControl(t, false, func(tb testing.TB, opts controlclient.Options) controlclient.Client { |
|
|
|
|
return newClient(tb, opts) |
|
|
|
|
}) |
|
|
|
|
|
|
|
|
|
ipnWatcher := newNotificationWatcher(t, lb, nil) |
|
|
|
|
ipnWatcher.watch(tt.mask, []wantedNotification{{ |
|
|
|
|
name: "test", |
|
|
|
|
cond: func(_ testing.TB, _ ipnauth.Actor, n *ipn.Notify) bool { |
|
|
|
|
if n.Health == nil { |
|
|
|
|
return false |
|
|
|
|
} |
|
|
|
|
got, ok := n.Health.Warnings["test-message"] |
|
|
|
|
if ok { |
|
|
|
|
if diff := cmp.Diff(tt.wantWarning, got); diff != "" { |
|
|
|
|
t.Errorf("unexpected warning details (-want/+got):\n%s", diff) |
|
|
|
|
return true // we failed the test so tell the watcher we've seen what we need to to stop it waiting
|
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
return ok |
|
|
|
|
}, |
|
|
|
|
}}) |
|
|
|
|
|
|
|
|
|
lb.SetPrefsForTest(&ipn.Prefs{ |
|
|
|
|
ControlURL: "https://localhost:1/", |
|
|
|
|
WantRunning: true, |
|
|
|
|
LoggedOut: false, |
|
|
|
|
}) |
|
|
|
|
if err := lb.Start(ipn.Options{}); err != nil { |
|
|
|
|
t.Fatalf("(*LocalBackend).Start(): %v", err) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
cc := lb.cc.(*mockControl) |
|
|
|
|
|
|
|
|
|
// Assert that we are logged in and authorized, and also send our DisplayMessages
|
|
|
|
|
cc.send(nil, "", true, &netmap.NetworkMap{ |
|
|
|
|
SelfNode: (&tailcfg.Node{MachineAuthorized: true}).View(), |
|
|
|
|
DisplayMessages: msgs, |
|
|
|
|
}) |
|
|
|
|
|
|
|
|
|
// Tell the health tracker that we are in a map poll because
|
|
|
|
|
// mockControl doesn't tell it
|
|
|
|
|
lb.HealthTracker().GotStreamedMapResponse() |
|
|
|
|
|
|
|
|
|
// Assert that we got the expected notification
|
|
|
|
|
ipnWatcher.check() |
|
|
|
|
}) |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|