AdGuardHome/internal/filtering/http_test.go

308 lines
7.1 KiB
Go
Raw Normal View History

2022-11-02 13:18:02 +00:00
package filtering
import (
"bytes"
"encoding/json"
"net/http"
"net/http/httptest"
"testing"
"time"
2023-06-07 18:04:01 +01:00
"github.com/AdguardTeam/golibs/testutil"
2022-11-02 13:18:02 +00:00
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func TestDNSFilter_handleFilteringSetURL(t *testing.T) {
filtersDir := t.TempDir()
var goodRulesEndpoint, anotherGoodRulesEndpoint, badRulesEndpoint string
for _, rulesSource := range []struct {
endpoint *string
content []byte
}{{
endpoint: &goodRulesEndpoint,
content: []byte(`||example.org^`),
}, {
endpoint: &anotherGoodRulesEndpoint,
content: []byte(`||example.com^`),
}, {
endpoint: &badRulesEndpoint,
content: []byte(`<html></html>`),
}} {
2023-01-19 12:04:46 +00:00
*rulesSource.endpoint = serveFiltersLocally(t, rulesSource.content)
2022-11-02 13:18:02 +00:00
}
testCases := []struct {
name string
wantBody string
oldURL string
newName string
newURL string
initial []FilterYAML
}{{
name: "success",
wantBody: "",
oldURL: goodRulesEndpoint,
newName: "default_one",
newURL: anotherGoodRulesEndpoint,
initial: []FilterYAML{{
Enabled: true,
URL: goodRulesEndpoint,
Name: "default_one",
white: false,
}},
}, {
name: "non-existing",
wantBody: "url doesn't exist\n",
oldURL: anotherGoodRulesEndpoint,
newName: "default_one",
newURL: goodRulesEndpoint,
initial: []FilterYAML{{
Enabled: true,
URL: goodRulesEndpoint,
Name: "default_one",
white: false,
}},
}, {
name: "existing",
wantBody: "url already exists\n",
oldURL: goodRulesEndpoint,
newName: "default_one",
newURL: anotherGoodRulesEndpoint,
initial: []FilterYAML{{
Enabled: true,
URL: goodRulesEndpoint,
Name: "default_one",
white: false,
}, {
Enabled: true,
URL: anotherGoodRulesEndpoint,
Name: "another_default_one",
white: false,
}},
}, {
name: "bad_rules",
wantBody: "data is HTML, not plain text\n",
oldURL: goodRulesEndpoint,
newName: "default_one",
newURL: badRulesEndpoint,
initial: []FilterYAML{{
Enabled: true,
URL: goodRulesEndpoint,
Name: "default_one",
white: false,
}},
}}
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
confModifiedCalled := false
d, err := New(&Config{
FilteringEnabled: true,
Filters: tc.initial,
HTTPClient: &http.Client{
Timeout: 5 * time.Second,
},
ConfigModified: func() { confModifiedCalled = true },
DataDir: filtersDir,
}, nil)
require.NoError(t, err)
t.Cleanup(d.Close)
d.Start()
reqData := &filterURLReq{
Data: &filterURLReqData{
// Leave the name of an existing list.
Name: tc.newName,
URL: tc.newURL,
Enabled: true,
},
URL: tc.oldURL,
Whitelist: false,
}
data, err := json.Marshal(reqData)
require.NoError(t, err)
r := httptest.NewRequest(http.MethodPost, "http://example.org", bytes.NewReader(data))
w := httptest.NewRecorder()
d.handleFilteringSetURL(w, r)
assert.Equal(t, tc.wantBody, w.Body.String())
// For the moment the non-empty response body only contains occurred
// error, so the configuration shouldn't be written.
assert.Equal(t, tc.wantBody == "", confModifiedCalled)
})
}
}
2023-06-07 18:04:01 +01:00
func TestDNSFilter_handleSafeBrowsingStatus(t *testing.T) {
const (
testTimeout = time.Second
statusURL = "/control/safebrowsing/status"
)
confModCh := make(chan struct{})
filtersDir := t.TempDir()
testCases := []struct {
name string
url string
enabled bool
wantStatus assert.BoolAssertionFunc
}{{
name: "enable_off",
url: "/control/safebrowsing/enable",
enabled: false,
wantStatus: assert.True,
}, {
name: "enable_on",
url: "/control/safebrowsing/enable",
enabled: true,
wantStatus: assert.True,
}, {
name: "disable_on",
url: "/control/safebrowsing/disable",
enabled: true,
wantStatus: assert.False,
}, {
name: "disable_off",
url: "/control/safebrowsing/disable",
enabled: false,
wantStatus: assert.False,
}}
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
handlers := make(map[string]http.Handler)
d, err := New(&Config{
ConfigModified: func() {
testutil.RequireSend(testutil.PanicT{}, confModCh, struct{}{}, testTimeout)
},
DataDir: filtersDir,
HTTPRegister: func(_, url string, handler http.HandlerFunc) {
handlers[url] = handler
},
SafeBrowsingEnabled: tc.enabled,
}, nil)
require.NoError(t, err)
t.Cleanup(d.Close)
d.RegisterFilteringHandlers()
require.NotEmpty(t, handlers)
require.Contains(t, handlers, statusURL)
r := httptest.NewRequest(http.MethodPost, tc.url, nil)
w := httptest.NewRecorder()
go handlers[tc.url].ServeHTTP(w, r)
testutil.RequireReceive(t, confModCh, testTimeout)
r = httptest.NewRequest(http.MethodGet, statusURL, nil)
w = httptest.NewRecorder()
handlers[statusURL].ServeHTTP(w, r)
require.Equal(t, http.StatusOK, w.Code)
status := struct {
Enabled bool `json:"enabled"`
}{
Enabled: false,
}
err = json.NewDecoder(w.Body).Decode(&status)
require.NoError(t, err)
tc.wantStatus(t, status.Enabled)
})
}
}
func TestDNSFilter_handleParentalStatus(t *testing.T) {
const (
testTimeout = time.Second
statusURL = "/control/parental/status"
)
confModCh := make(chan struct{})
filtersDir := t.TempDir()
testCases := []struct {
name string
url string
enabled bool
wantStatus assert.BoolAssertionFunc
}{{
name: "enable_off",
url: "/control/parental/enable",
enabled: false,
wantStatus: assert.True,
}, {
name: "enable_on",
url: "/control/parental/enable",
enabled: true,
wantStatus: assert.True,
}, {
name: "disable_on",
url: "/control/parental/disable",
enabled: true,
wantStatus: assert.False,
}, {
name: "disable_off",
url: "/control/parental/disable",
enabled: false,
wantStatus: assert.False,
}}
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
handlers := make(map[string]http.Handler)
d, err := New(&Config{
ConfigModified: func() {
testutil.RequireSend(testutil.PanicT{}, confModCh, struct{}{}, testTimeout)
},
DataDir: filtersDir,
HTTPRegister: func(_, url string, handler http.HandlerFunc) {
handlers[url] = handler
},
ParentalEnabled: tc.enabled,
}, nil)
require.NoError(t, err)
t.Cleanup(d.Close)
d.RegisterFilteringHandlers()
require.NotEmpty(t, handlers)
require.Contains(t, handlers, statusURL)
r := httptest.NewRequest(http.MethodPost, tc.url, nil)
w := httptest.NewRecorder()
go handlers[tc.url].ServeHTTP(w, r)
testutil.RequireReceive(t, confModCh, testTimeout)
r = httptest.NewRequest(http.MethodGet, statusURL, nil)
w = httptest.NewRecorder()
handlers[statusURL].ServeHTTP(w, r)
require.Equal(t, http.StatusOK, w.Code)
status := struct {
Enabled bool `json:"enabled"`
}{
Enabled: false,
}
err = json.NewDecoder(w.Body).Decode(&status)
require.NoError(t, err)
tc.wantStatus(t, status.Enabled)
})
}
}