ソースを参照

Add imagedata tests

DarthSim 2 ヶ月 前
コミット
0a50b79111
1 ファイル変更309 行追加0 行削除
  1. 309 0
      imagedata/image_data_test.go

+ 309 - 0
imagedata/image_data_test.go

@@ -0,0 +1,309 @@
+package imagedata
+
+import (
+	"bytes"
+	"compress/gzip"
+	"context"
+	"encoding/base64"
+	"fmt"
+	"io"
+	"log"
+	"net"
+	"net/http"
+	"net/http/httptest"
+	"os"
+	"strconv"
+	"testing"
+
+	"github.com/stretchr/testify/suite"
+
+	"github.com/imgproxy/imgproxy/v3/config"
+	"github.com/imgproxy/imgproxy/v3/ierrors"
+	"github.com/imgproxy/imgproxy/v3/imagetype"
+	"github.com/imgproxy/imgproxy/v3/security"
+)
+
+type ImageDataTestSuite struct {
+	suite.Suite
+
+	server *httptest.Server
+
+	status int
+	data   []byte
+	header http.Header
+	check  func(*http.Request)
+
+	defaultData []byte
+}
+
+func (s *ImageDataTestSuite) SetupSuite() {
+	config.Reset()
+	config.ClientKeepAliveTimeout = 0
+
+	Init()
+
+	f, err := os.Open("../testdata/test1.jpg")
+	s.Require().NoError(err)
+	defer f.Close()
+
+	data, err := io.ReadAll(f)
+	s.Require().NoError(err)
+
+	s.defaultData = data
+
+	s.server = httptest.NewServer(http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) {
+		if s.check != nil {
+			s.check(r)
+		}
+
+		for k, vv := range s.header {
+			for _, v := range vv {
+				rw.Header().Add(k, v)
+			}
+		}
+
+		data := s.data
+		if data == nil {
+			data = s.defaultData
+		}
+
+		rw.Header().Set("Content-Length", strconv.Itoa(len(data)))
+
+		rw.WriteHeader(s.status)
+		rw.Write(data)
+	}))
+}
+
+func (s *ImageDataTestSuite) TearDownSuite() {
+	s.server.Close()
+}
+
+func (s *ImageDataTestSuite) SetupTest() {
+	config.Reset()
+	config.AllowLoopbackSourceAddresses = true
+
+	s.status = http.StatusOK
+	s.data = nil
+	s.check = nil
+
+	s.header = http.Header{}
+	s.header.Set("Content-Type", "image/jpeg")
+}
+
+func (s *ImageDataTestSuite) TestDownloadStatusOK() {
+	imgdata, err := Download(context.Background(), s.server.URL, "Test image", DownloadOptions{}, security.DefaultOptions())
+
+	s.Require().NoError(err)
+	s.Require().NotNil(imgdata)
+	s.Require().Equal(s.defaultData, imgdata.Data)
+	s.Require().Equal(imagetype.JPEG, imgdata.Type)
+}
+
+func (s *ImageDataTestSuite) TestDownloadStatusPartialContent() {
+	s.status = http.StatusPartialContent
+
+	testCases := []struct {
+		name         string
+		contentRange string
+		expectErr    bool
+	}{
+		{
+			name:         "Full Content-Range",
+			contentRange: fmt.Sprintf("bytes 0-%d/%d", len(s.defaultData)-1, len(s.defaultData)),
+			expectErr:    false,
+		},
+		{
+			name:         "Partial Content-Range, early end",
+			contentRange: fmt.Sprintf("bytes 0-%d/%d", len(s.defaultData)-2, len(s.defaultData)),
+			expectErr:    true,
+		},
+		{
+			name:         "Partial Content-Range, late start",
+			contentRange: fmt.Sprintf("bytes 1-%d/%d", len(s.defaultData)-1, len(s.defaultData)),
+			expectErr:    true,
+		},
+		{
+			name:         "Zero Content-Range",
+			contentRange: "bytes 0-0/0",
+			expectErr:    true,
+		},
+		{
+			name:         "Invalid Content-Range",
+			contentRange: "invalid",
+			expectErr:    true,
+		},
+		{
+			name:         "Unknown Content-Range range",
+			contentRange: fmt.Sprintf("bytes */%d", len(s.defaultData)),
+			expectErr:    true,
+		},
+		{
+			name:         "Unknown Content-Range size, full range",
+			contentRange: fmt.Sprintf("bytes 0-%d/*", len(s.defaultData)-1),
+			expectErr:    false,
+		},
+		{
+			name:         "Unknown Content-Range size, early end",
+			contentRange: fmt.Sprintf("bytes 0-%d/*", len(s.defaultData)-2),
+			expectErr:    true,
+		},
+		{
+			name:         "Unknown Content-Range size, late start",
+			contentRange: fmt.Sprintf("bytes 1-%d/*", len(s.defaultData)-1),
+			expectErr:    true,
+		},
+	}
+
+	for _, tc := range testCases {
+		s.Run(tc.name, func() {
+			s.header.Set("Content-Range", tc.contentRange)
+
+			imgdata, err := Download(context.Background(), s.server.URL, "Test image", DownloadOptions{}, security.DefaultOptions())
+
+			if tc.expectErr {
+				s.Require().Error(err)
+				s.Require().Equal(404, ierrors.Wrap(err, 0).StatusCode)
+			} else {
+				s.Require().NoError(err)
+				s.Require().NotNil(imgdata)
+				s.Require().Equal(s.defaultData, imgdata.Data)
+				s.Require().Equal(imagetype.JPEG, imgdata.Type)
+			}
+		})
+	}
+}
+
+func (s *ImageDataTestSuite) TestDownloadStatusNotFound() {
+	s.status = http.StatusNotFound
+	s.data = []byte("Not Found")
+	s.header.Set("Content-Type", "text/plain")
+
+	imgdata, err := Download(context.Background(), s.server.URL, "Test image", DownloadOptions{}, security.DefaultOptions())
+
+	s.Require().Error(err)
+	s.Require().Equal(404, ierrors.Wrap(err, 0).StatusCode)
+	s.Require().Nil(imgdata)
+}
+
+func (s *ImageDataTestSuite) TestDownloadStatusForbidden() {
+	s.status = http.StatusForbidden
+	s.data = []byte("Forbidden")
+	s.header.Set("Content-Type", "text/plain")
+
+	imgdata, err := Download(context.Background(), s.server.URL, "Test image", DownloadOptions{}, security.DefaultOptions())
+
+	s.Require().Error(err)
+	s.Require().Equal(404, ierrors.Wrap(err, 0).StatusCode)
+	s.Require().Nil(imgdata)
+}
+
+func (s *ImageDataTestSuite) TestDownloadStatusInternalServerError() {
+	s.status = http.StatusInternalServerError
+	s.data = []byte("Internal Server Error")
+	s.header.Set("Content-Type", "text/plain")
+
+	imgdata, err := Download(context.Background(), s.server.URL, "Test image", DownloadOptions{}, security.DefaultOptions())
+
+	s.Require().Error(err)
+	s.Require().Equal(500, ierrors.Wrap(err, 0).StatusCode)
+	s.Require().Nil(imgdata)
+}
+
+func (s *ImageDataTestSuite) TestDownloadUnreachable() {
+	l, err := net.Listen("tcp", "127.0.0.1:0")
+	s.Require().NoError(err)
+	l.Close()
+
+	serverURL := fmt.Sprintf("http://%s", l.Addr().String())
+
+	imgdata, err := Download(context.Background(), serverURL, "Test image", DownloadOptions{}, security.DefaultOptions())
+
+	s.Require().Error(err)
+	s.Require().Equal(500, ierrors.Wrap(err, 0).StatusCode)
+	s.Require().Nil(imgdata)
+}
+
+func (s *ImageDataTestSuite) TestDownloadInvalidImage() {
+	s.data = []byte("invalid")
+
+	imgdata, err := Download(context.Background(), s.server.URL, "Test image", DownloadOptions{}, security.DefaultOptions())
+
+	s.Require().Error(err)
+	s.Require().Equal(422, ierrors.Wrap(err, 0).StatusCode)
+	s.Require().Nil(imgdata)
+}
+
+func (s *ImageDataTestSuite) TestDownloadSourceAddressNotAllowed() {
+	log.Printf("Server URL: %s", s.server.URL)
+	config.AllowLoopbackSourceAddresses = false
+
+	imgdata, err := Download(context.Background(), s.server.URL, "Test image", DownloadOptions{}, security.DefaultOptions())
+
+	s.Require().Error(err)
+	s.Require().Equal(404, ierrors.Wrap(err, 0).StatusCode)
+	s.Require().Nil(imgdata)
+}
+
+func (s *ImageDataTestSuite) TestDownloadImageTooLarge() {
+	config.MaxSrcResolution = 1
+
+	imgdata, err := Download(context.Background(), s.server.URL, "Test image", DownloadOptions{}, security.DefaultOptions())
+
+	s.Require().Error(err)
+	s.Require().Equal(422, ierrors.Wrap(err, 0).StatusCode)
+	s.Require().Nil(imgdata)
+}
+
+func (s *ImageDataTestSuite) TestDownloadImageFileTooLarge() {
+	config.MaxSrcFileSize = 1
+
+	imgdata, err := Download(context.Background(), s.server.URL, "Test image", DownloadOptions{}, security.DefaultOptions())
+
+	s.Require().Error(err)
+	s.Require().Equal(422, ierrors.Wrap(err, 0).StatusCode)
+	s.Require().Nil(imgdata)
+}
+
+func (s *ImageDataTestSuite) TestDownloadGzip() {
+	buf := new(bytes.Buffer)
+
+	enc := gzip.NewWriter(buf)
+	_, err := enc.Write(s.defaultData)
+	s.Require().NoError(err)
+	err = enc.Close()
+	s.Require().NoError(err)
+
+	s.data = buf.Bytes()
+	s.header.Set("Content-Encoding", "gzip")
+
+	imgdata, err := Download(context.Background(), s.server.URL, "Test image", DownloadOptions{}, security.DefaultOptions())
+
+	s.Require().NoError(err)
+	s.Require().NotNil(imgdata)
+	s.Require().Equal(s.defaultData, imgdata.Data)
+	s.Require().Equal(imagetype.JPEG, imgdata.Type)
+}
+
+func (s *ImageDataTestSuite) TestFromFile() {
+	imgdata, err := FromFile("../testdata/test1.jpg", "Test image", security.DefaultOptions())
+
+	s.Require().NoError(err)
+	s.Require().NotNil(imgdata)
+	s.Require().Equal(s.defaultData, imgdata.Data)
+	s.Require().Equal(imagetype.JPEG, imgdata.Type)
+}
+
+func (s *ImageDataTestSuite) TestFromBase64() {
+	b64 := base64.StdEncoding.EncodeToString(s.defaultData)
+
+	imgdata, err := FromBase64(b64, "Test image", security.DefaultOptions())
+
+	s.Require().NoError(err)
+	s.Require().NotNil(imgdata)
+	s.Require().Equal(s.defaultData, imgdata.Data)
+	s.Require().Equal(imagetype.JPEG, imgdata.Type)
+}
+
+func TestImageData(t *testing.T) {
+	suite.Run(t, new(ImageDataTestSuite))
+}