package fritzbox
import (
"context"
"net/http"
"net/http/httptest"
"strings"
"testing"
)
const addonInfos = `
81908
1467861996
1247413843
276345768940
3471580989011
`
const linkProperties = `
Cable
56710000
1150000000
`
const soapFault = `
s:ClientUPnPError
401Invalid Action
`
// fakeIGD answers each action with the given body and status, and fails the
// test on a request the box would reject.
func fakeIGD(t *testing.T, answers map[string]string, status int) *Client {
t.Helper()
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
action := r.Header.Get("SOAPACTION")
if r.Method != http.MethodPost || r.URL.Path != igdControl {
t.Errorf("%s %s", r.Method, r.URL.Path)
}
if !strings.HasPrefix(action, `"`+igdService+"#") || !strings.HasSuffix(action, `"`) {
t.Errorf("SOAPACTION %s is not the quoted service#action", action)
}
name := strings.Trim(action[strings.Index(action, "#")+1:], `"`)
w.WriteHeader(status)
_, _ = w.Write([]byte(answers[name]))
}))
t.Cleanup(srv.Close)
c := New("http://fritz.box", "", "")
c.IGD = srv.URL
return c
}
func TestWANPrefersThe64BitCounters(t *testing.T) {
c := fakeIGD(t, map[string]string{"GetAddonInfos": addonInfos, "GetCommonLinkProperties": linkProperties}, http.StatusOK)
w, err := c.WAN(context.Background())
if err != nil {
t.Fatal(err)
}
want := WAN{ReceivedBytes: 3471580989011, SentBytes: 276345768940, DownstreamBps: 1150000000, UpstreamBps: 56710000}
if w != want {
t.Errorf("got %+v, want %+v", w, want)
}
}
func TestWANFallsBackTo32BitCounters(t *testing.T) {
old := strings.NewReplacer(
"3471580989011", "", "276345768940", "").Replace(addonInfos)
c := fakeIGD(t, map[string]string{"GetAddonInfos": old, "GetCommonLinkProperties": linkProperties}, http.StatusOK)
w, err := c.WAN(context.Background())
if err != nil {
t.Fatal(err)
}
if w.ReceivedBytes != 1247413843 || w.SentBytes != 1467861996 {
t.Errorf("got %+v, want the 32 bit counters", w)
}
}
func TestWANReportsTheFault(t *testing.T) {
c := fakeIGD(t, map[string]string{"GetAddonInfos": soapFault}, http.StatusInternalServerError)
_, err := c.WAN(context.Background())
if err == nil || !strings.Contains(err.Error(), "Invalid Action") {
t.Errorf("err = %v, want the fault's description", err)
}
}
func TestWANNamesTheUPnPSettingWhenOff(t *testing.T) {
c := fakeIGD(t, nil, http.StatusNotFound)
_, err := c.WAN(context.Background())
if err == nil || !strings.Contains(err.Error(), "UPnP") {
t.Errorf("err = %v, want it to name the UPnP setting", err)
}
}
func TestIGDBaseIsTheBoxHostOnPort49000(t *testing.T) {
for in, want := range map[string]string{
"http://fritz.box": "http://fritz.box:49000",
"https://192.168.178.1:443": "http://192.168.178.1:49000",
"": "",
} {
if got := igdBase(in); got != want {
t.Errorf("igdBase(%q) = %q, want %q", in, got, want)
}
}
}