all: add tests

This commit is contained in:
Stanislav Chzhen 2025-09-16 13:15:28 +03:00
parent a871d51341
commit 942c28f4c0
2 changed files with 129 additions and 0 deletions

View File

@ -34,6 +34,7 @@ NOTE: Add new changes BELOW THIS COMMENT.
### Fixed
- Excessive configuration file overwrites when visiting the Web UI and a non-empty `language` is set.
- Lowered the severity of log messages for failed deletion of old filter files ([#7964]).
- Authentication errors in the Web UI when AdGuard Home is behind a proxy that sets Basic Auth headers ([#7987]).
- The HTTP API `GET /control/profile` endpoint failing when no users were configured ([#7985]).

View File

@ -1,7 +1,11 @@
package home
import (
"bytes"
"context"
"encoding/binary"
"encoding/json"
"io"
"net/http"
"net/http/httptest"
"os"
@ -10,6 +14,10 @@ import (
"time"
"github.com/AdguardTeam/AdGuardHome/internal/agh"
"github.com/AdguardTeam/AdGuardHome/internal/aghhttp"
"github.com/AdguardTeam/AdGuardHome/internal/aghtest"
"github.com/AdguardTeam/golibs/errors"
"github.com/AdguardTeam/golibs/httphdr"
"github.com/AdguardTeam/golibs/testutil"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
@ -117,3 +125,123 @@ func TestWeb_HandleGetProfile(t *testing.T) {
assert.Equal(t, http.StatusUnauthorized, w.Code)
}))
}
func TestWeb_HandlePutProfile(t *testing.T) {
storeGlobals(t)
mux := http.NewServeMux()
globalContext.mux = mux
isConfigChanged := false
confModifier := &aghtest.ConfigModifier{
OnApply: func(_ context.Context) { isConfigChanged = true },
}
ctx := testutil.ContextWithTimeout(t, testTimeout)
web, err := initWeb(ctx, options{}, nil, nil, testLogger, nil, nil, confModifier, false)
require.NoError(t, err)
globalContext.web = web
var (
dataValid = errors.Must(json.Marshal(&profileJSON{
Language: "en",
Theme: "auto",
}))
dataInvalidLang = errors.Must(json.Marshal(&profileJSON{
Language: "invalid_lang",
Theme: "auto",
}))
dataInvalidTheme = errors.Must(json.Marshal(&profileJSON{
Language: "en",
Theme: "invalid_theme",
}))
)
testCases := []struct {
req *http.Request
name string
wantBody string
wantCode int
}{{
req: profileUpdateRequest(http.MethodPut, dataValid, true),
name: "basic",
wantBody: "OK\n",
wantCode: http.StatusOK,
}, {
req: profileUpdateRequest(http.MethodGet, dataValid, true),
name: "invalid_method",
wantBody: "only method PUT is allowed\n",
wantCode: http.StatusMethodNotAllowed,
}, {
req: profileUpdateRequest(http.MethodPut, dataValid, false),
name: "invalid_content_type",
wantBody: "only content-type application/json is allowed\n",
wantCode: http.StatusUnsupportedMediaType,
}, {
req: profileUpdateRequest(http.MethodPut, nil, false),
name: "empty_body",
wantBody: "reading req: EOF\n",
wantCode: http.StatusBadRequest,
}, {
req: profileUpdateRequest(http.MethodPut, dataInvalidLang, true),
name: "invalid_language",
wantBody: `unknown language: "invalid_lang"` + "\n",
wantCode: http.StatusBadRequest,
}, {
req: profileUpdateRequest(http.MethodPut, dataInvalidTheme, true),
name: "invalid_theme",
wantBody: `reading req: invalid theme "invalid_theme", ` +
`supported: "auto", "dark", "light"` + "\n",
wantCode: http.StatusBadRequest,
}}
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
w := httptest.NewRecorder()
mux.ServeHTTP(w, tc.req)
assert.Equal(t, tc.wantCode, w.Code)
assert.Equal(t, tc.wantBody, w.Body.String())
})
}
require.True(t, t.Run("single_config_update", func(t *testing.T) {
isConfigChanged = false
config.Language = ""
config.Theme = ""
w := httptest.NewRecorder()
mux.ServeHTTP(w, profileUpdateRequest(http.MethodPut, dataValid, true))
require.Equal(t, http.StatusOK, w.Code)
assert.True(t, isConfigChanged)
isConfigChanged = false
mux.ServeHTTP(w, profileUpdateRequest(http.MethodPut, dataValid, true))
require.Equal(t, http.StatusOK, w.Code)
assert.False(t, isConfigChanged)
}))
}
// profileUpdateRequest builds an *http.Request for the profile update endpoint.
// If body is non-nil, it is used as the request body. If setCT is true, the
// Content-Type header is set to application/json.
func profileUpdateRequest(method string, body []byte, setCT bool) (req *http.Request) {
var r io.Reader
if body != nil {
r = bytes.NewReader(body)
}
req = httptest.NewRequest(method, "/control/profile/update", r)
if setCT {
req.Header.Set(httphdr.ContentType, aghhttp.HdrValApplicationJSON)
}
return req
}