Files
gitea/modules/httplib/serve_test.go
T
silverwind 8abda62312 test: consolidate Go tests (#39962)
Consolidate all Go tests. Coverage is identical to before. Go tests are
around 5% faster while being 7% smaller. No non-test code is touched.
2026-10-24 13:48:19 +00:00

102 lines
3.3 KiB
Go

// Copyright 2023 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
package httplib
import (
"net/http"
"net/http/httptest"
"net/url"
"os"
"strconv"
"strings"
"testing"
"gitea.dev/modules/typesniffer"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func TestServeUserContent(t *testing.T) {
data := "0123456789abcdef"
for _, source := range []string{"reader", "file"} {
t.Run(source, func(t *testing.T) {
var tmpFile string
if source == "file" {
tmpFile = t.TempDir() + "/test"
assert.NoError(t, os.WriteFile(tmpFile, []byte(data), 0o644))
}
for _, tc := range []struct {
rangeStr string
expectedStatusCode int
expectedContent string
}{
{"", http.StatusOK, data},
{"0-", http.StatusPartialContent, data},
{"0-15", http.StatusPartialContent, data},
{"1-", http.StatusPartialContent, data[1:]},
{"1-3", http.StatusPartialContent, data[1 : 3+1]},
{"16-", http.StatusRequestedRangeNotSatisfiable, ""},
{"1-99999", http.StatusPartialContent, data[1:]},
} {
t.Run("_range_"+tc.rangeStr, func(t *testing.T) {
r := &http.Request{Header: http.Header{}, Form: url.Values{}}
if tc.rangeStr != "" {
r.Header.Set("Range", "bytes="+tc.rangeStr)
}
w := httptest.NewRecorder()
if source == "file" {
seekReader, err := os.OpenFile(tmpFile, os.O_RDONLY, 0o644)
require.NoError(t, err)
defer seekReader.Close()
ServeUserContentByFile(r, w, seekReader, ServeHeaderOptions{})
} else {
ServeUserContentByReader(r, w, int64(len(data)), strings.NewReader(data), ServeHeaderOptions{})
}
assert.Equal(t, tc.expectedStatusCode, w.Code)
if tc.expectedStatusCode == http.StatusPartialContent || tc.expectedStatusCode == http.StatusOK {
assert.Equal(t, strconv.Itoa(len(tc.expectedContent)), w.Header().Get("Content-Length"))
assert.Equal(t, tc.expectedContent, w.Body.String())
}
})
}
})
}
}
func TestServeSetHeaderContentRelated(t *testing.T) {
cases := []struct {
contentType string
csp string
}{
{"", serveHeaderCspDefault},
{"any", serveHeaderCspDefault},
{"application/pdf", serveHeaderCspPdf},
{"application/pdf; charset=binary", serveHeaderCspPdf},
{"audio/mp4", serveHeaderCspAudioVideo},
{"video/ogg; codecs=theora", serveHeaderCspAudioVideo},
{"video/mp4;,text/html", serveHeaderCspDefault},
{typesniffer.MimeTypeImageSvg, serveHeaderCspDefault},
}
for _, c := range cases {
w := httptest.NewRecorder()
serveSetHeaderContentRelated(w, c.contentType)
csp := w.Header().Get("Content-Security-Policy")
assert.Equal(t, c.csp, csp, "content-type: %s", c.contentType)
assert.Equal(t, "nosniff", w.Header().Get("X-Content-Type-Options")) // it should always be there
}
// make sure sandboxed
require.Contains(t, serveHeaderCspDefault, "sandbox")
require.NotContains(t, serveHeaderCspDefault, "allow-same-origin")
}
func TestServeSetHeaders(t *testing.T) {
w := httptest.NewRecorder()
ServeSetHeaders(w, ServeHeaderOptions{Filename: "foo.zip"})
assert.Equal(t, "attachment; filename=foo.zip", w.Header().Get("Content-Disposition"))
ServeSetHeaders(w, ServeHeaderOptions{Filename: "foo.zip", ContentDisposition: ContentDispositionInline})
assert.Equal(t, "inline; filename=foo.zip", w.Header().Get("Content-Disposition"))
}