diff --git a/services/webdav/pkg/preprocessor/errors.go b/services/webdav/pkg/preprocessor/errors.go index a0db070da5..45baa493ce 100644 --- a/services/webdav/pkg/preprocessor/errors.go +++ b/services/webdav/pkg/preprocessor/errors.go @@ -2,10 +2,4 @@ package preprocessor import "errors" -var ( - ErrNoImageFromAudioFile = errors.New("preprocessor: could not extract image from audio file") - ErrNoConverterForExtractedImageFromGgsFile = errors.New("preprocessor: could not find converter for image extracted from ggs file") - ErrNoConverterForExtractedImageFromAudioFile = errors.New("preprocessor: could not find converter for image extracted from audio file") - ErrNoConverterForExtractedImageFromGgpFile = errors.New("preprocessor: could not find converter for image extracted from ggp file") - ErrNoThumbnail = errors.New("preprocessor: the document has no thumbnail") -) +var ErrNoThumbnail = errors.New("preprocessor: the document has no thumbnail") diff --git a/services/webdav/pkg/preprocessor/preprocessor.go b/services/webdav/pkg/preprocessor/preprocessor.go index c5886ac35d..607ead90e7 100644 --- a/services/webdav/pkg/preprocessor/preprocessor.go +++ b/services/webdav/pkg/preprocessor/preprocessor.go @@ -86,7 +86,7 @@ func (g GgsDecoder) Convert(r io.Reader) (*Image, error) { return &Image{ContentType: "image/png", Data: data}, nil } } - return nil, errors.Errorf("%s not found", g.thumbnailpath) + return nil, ErrNoThumbnail } // AudioDecoder is a converter for the audio file. @@ -111,12 +111,8 @@ func (i AudioDecoder) Convert(r io.Reader) (*Image, error) { } picture := m.Picture() - if picture == nil { - return nil, ErrNoImageFromAudioFile - } - - if !strings.HasPrefix(picture.MIMEType, "image/") { - return nil, ErrNoConverterForExtractedImageFromAudioFile + if picture == nil || !strings.HasPrefix(picture.MIMEType, "image/") { + return nil, ErrNoThumbnail } return &Image{ContentType: picture.MIMEType, Data: picture.Data}, nil @@ -260,7 +256,7 @@ func (j GgpDecoder) Convert(r io.Reader) (*Image, error) { contentType := http.DetectContentType(b) if !strings.HasPrefix(contentType, "image/") { - return nil, ErrNoConverterForExtractedImageFromGgpFile + return nil, ErrNoThumbnail } return &Image{ContentType: contentType, Data: b}, nil @@ -268,12 +264,12 @@ func (j GgpDecoder) Convert(r io.Reader) (*Image, error) { func extractBase64ImageFromGGP(ggp *GGPStruct) (string, error) { if len(ggp.Sections) < 1 || len(ggp.Sections[0].Cards) < 1 { - return "", errors.New("cant find thumbnail in ggp file") + return "", ErrNoThumbnail } raw := strings.Split(ggp.Sections[0].Cards[0].Element.Image.Base64Image, "base64,") if len(raw) < 2 { - return "", errors.New("cant decode ggp thumbnail") + return "", ErrNoThumbnail } return raw[1], nil diff --git a/services/webdav/pkg/preprocessor/preprocessor_test.go b/services/webdav/pkg/preprocessor/preprocessor_test.go index 08cffabb77..d2aaf151c9 100644 --- a/services/webdav/pkg/preprocessor/preprocessor_test.go +++ b/services/webdav/pkg/preprocessor/preprocessor_test.go @@ -3,15 +3,17 @@ package preprocessor import ( "archive/zip" "bytes" + "encoding/base64" "encoding/binary" "io" "os" + "strings" "testing" "golang.org/x/image/font" "golang.org/x/image/font/opentype" - . "github.com/onsi/ginkgo" + . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" ) @@ -77,6 +79,19 @@ var _ = Describe("preprocessor", func() { Expect(img).To(BeNil()) }) + It("reports a ggs without a thumbnail as having none", func() { + var buf bytes.Buffer + w := zip.NewWriter(&buf) + _, err := w.Create("geogebra.xml") + Expect(err).ToNot(HaveOccurred()) + Expect(w.Close()).To(Succeed()) + + decoder := GgsDecoder{thumbnailpath: ggsThumbnailPath, maxSize: defaultMaxExtractedSize} + img, err := decoder.Convert(bytes.NewReader(buf.Bytes())) + Expect(err).To(MatchError(ErrNoThumbnail)) + Expect(img).To(BeNil()) + }) + It("refuses an entry that expands past the limit", func() { decoder := GgsDecoder{thumbnailpath: ggsThumbnailPath, maxSize: 1 << 20} @@ -109,7 +124,7 @@ var _ = Describe("preprocessor", func() { Expect(img.ContentType).To(HavePrefix("image/")) Expect(img.Data).ToNot(BeEmpty()) }) - It("should decode an audio", func() { + It("reports an audio without cover art as having none", func() { fileContent, err := os.ReadFile("test_assets/empty_no_image.mp3") if err != nil { panic(err) @@ -117,13 +132,46 @@ var _ = Describe("preprocessor", func() { fileReader = bytes.NewReader(fileContent) decoder := AudioDecoder{} img, err := decoder.Convert(fileReader) - Expect(err).To(HaveOccurred()) + Expect(err).To(MatchError(ErrNoThumbnail)) Expect(img).To(BeNil()) }) It("should return an error if the audio is invalid", func() { decoder := AudioDecoder{} img, err := decoder.Convert(bytes.NewReader([]byte("not an audio"))) Expect(err).To(HaveOccurred()) + Expect(err).ToNot(MatchError(ErrNoThumbnail)) + Expect(img).To(BeNil()) + }) + }) + + Describe("GgpDecoder", func() { + It("hands on the embedded thumbnail", func() { + data, err := os.ReadFile("test_assets/noise.png") + Expect(err).ToNot(HaveOccurred()) + ggp := `{"sections":[{"cards":[{"element":{"image":{"base64Image":"data:image/png;base64,` + base64.StdEncoding.EncodeToString(data) + `"}}}]}]}` + + img, err := GgpDecoder{}.Convert(strings.NewReader(ggp)) + Expect(err).ToNot(HaveOccurred()) + Expect(img.ContentType).To(Equal("image/png")) + Expect(img.Data).To(Equal(data)) + }) + + DescribeTable("reports a ggp without a thumbnail as having none", + func(ggp string) { + img, err := GgpDecoder{}.Convert(strings.NewReader(ggp)) + Expect(err).To(MatchError(ErrNoThumbnail)) + Expect(img).To(BeNil()) + }, + Entry("no sections", `{}`), + Entry("no cards", `{"sections":[{"cards":[]}]}`), + Entry("no base64 image", `{"sections":[{"cards":[{"element":{"image":{"base64Image":""}}}]}]}`), + Entry("not an image", `{"sections":[{"cards":[{"element":{"image":{"base64Image":"data:text/plain;base64,aGVsbG8="}}}]}]}`), + ) + + It("should return an error if the ggp is invalid", func() { + img, err := GgpDecoder{}.Convert(strings.NewReader("not a ggp")) + Expect(err).To(HaveOccurred()) + Expect(err).ToNot(MatchError(ErrNoThumbnail)) Expect(img).To(BeNil()) }) }) diff --git a/services/webdav/pkg/preprocessor/tika_test.go b/services/webdav/pkg/preprocessor/tika_test.go index fee3aaa6e4..3636ff4595 100644 --- a/services/webdav/pkg/preprocessor/tika_test.go +++ b/services/webdav/pkg/preprocessor/tika_test.go @@ -9,7 +9,7 @@ import ( "net/http" "net/http/httptest" - . "github.com/onsi/ginkgo" + . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" "github.com/onsi/gomega/types"