From a1719e9fcf1c8d91bccfae0b92a54247ae5ccae8 Mon Sep 17 00:00:00 2001 From: Gabriel Sagula Date: Mon, 16 Mar 2020 21:50:29 -0700 Subject: [PATCH] MM-22707: improved image upload tests and logging (#14018) * improved image upload tests and error logging message Signed-off-by: Gabriel Linden Sagula * removed unecessary logging message Signed-off-by: Gabriel Linden Sagula * fixed null ptr issue Signed-off-by: Gabriel Linden Sagula * rolled back pointer to the client Signed-off-by: Gabriel Linden Sagula * added hexdump of the previewer file Signed-off-by: Gabriel Linden Sagula * fixed tests that use the renamed files Signed-off-by: Gabriel Linden Sagula * addressed reviewer notes Signed-off-by: Gabriel Linden Sagula * addressed reviewer concerns Signed-off-by: Gabriel Linden Sagula Co-authored-by: mattermod --- api4/file_test.go | 34 +++++++++++++----- app/post_metadata_test.go | 2 +- .../{test.tiff => test_compressed_tiff.tiff} | Bin ...w.tiff => test_expected_tiff_preview.jpeg} | Bin ...umb.tiff => test_expected_tiff_thumb.jpeg} | Bin tests/test_raw_tiff.tiff | Bin 0 -> 22028 bytes 6 files changed, 27 insertions(+), 9 deletions(-) rename tests/{test.tiff => test_compressed_tiff.tiff} (100%) rename tests/{test_expected_preview.tiff => test_expected_tiff_preview.jpeg} (100%) rename tests/{test_expected_thumb.tiff => test_expected_tiff_thumb.jpeg} (100%) create mode 100644 tests/test_raw_tiff.tiff diff --git a/api4/file_test.go b/api4/file_test.go index 70e32820c5..d955dca1ef 100644 --- a/api4/file_test.go +++ b/api4/file_test.go @@ -5,6 +5,7 @@ package api4 import ( "bytes" + "encoding/hex" "fmt" "io" "io/ioutil" @@ -221,13 +222,13 @@ func TestUploadFiles(t *testing.T) { // Upload a bunch of files, mixed images and non-images { title: "Happy", - names: []string{"test.png", "testgif.gif", "testplugin.tar.gz", "test-search.md", "test.tiff"}, + names: []string{"test.png", "testgif.gif", "testplugin.tar.gz", "test-search.md", "test_compressed_tiff.tiff"}, expectedCreatorId: th.BasicUser.Id, }, // Upload a bunch of files, with clientIds { title: "Happy client_ids", - names: []string{"test.png", "testgif.gif", "testplugin.tar.gz", "test-search.md", "test.tiff"}, + names: []string{"test.png", "testgif.gif", "testplugin.tar.gz", "test-search.md", "test_compressed_tiff.tiff"}, clientIds: []string{"1", "2", "3", "4", "5"}, expectedCreatorId: th.BasicUser.Id, }, @@ -356,9 +357,20 @@ func TestUploadFiles(t *testing.T) { // TIFF preview test { title: "Happy image thumbnail/preview 9", - names: []string{"test.tiff"}, - expectedImageThumbnailNames: []string{"test_expected_thumb.tiff"}, - expectedImagePreviewNames: []string{"test_expected_preview.tiff"}, + names: []string{"test_compressed_tiff.tiff"}, + expectedImageThumbnailNames: []string{"test_expected_tiff_thumb.jpeg"}, + expectedImagePreviewNames: []string{"test_expected_tiff_preview.jpeg"}, + expectImage: true, + expectedImageWidths: []int{701}, + expectedImageHeights: []int{701}, + expectedImageHasPreview: []bool{true}, + expectedCreatorId: th.BasicUser.Id, + }, + { + title: "Happy image thumbnail/preview 10", + names: []string{"test_raw_tiff.tiff"}, + expectedImageThumbnailNames: []string{"test_expected_tiff_thumb.jpeg"}, + expectedImagePreviewNames: []string{"test_expected_tiff_preview.jpeg"}, expectImage: true, expectedImageWidths: []int{701}, expectedImageHeights: []int{701}, @@ -609,10 +621,16 @@ func TestUploadFiles(t *testing.T) { require.Nil(t, err) if !bytes.Equal(data, expected) { tf, err := ioutil.TempFile("", fmt.Sprintf("test_%v_*_%s", i, name)) + defer tf.Close() require.Nil(t, err) - _, _ = io.Copy(tf, bytes.NewReader(data)) - tf.Close() - t.Errorf("Actual data mismatched %s, written to %q", name, tf.Name()) + _, err = io.Copy(tf, bytes.NewReader(data)) + require.Nil(t, err) + if strings.Contains(name, "test_expected_tiff") { + // TODO: remove this once MM-22056 is fixed. + t.Errorf("Actual data mismatched %s, written to %q - expected %d bytes, got %d. Previewer Image: \n\n%s\n", name, tf.Name(), len(expected), len(data), hex.Dump(data)) + } else { + t.Errorf("Actual data mismatched %s, written to %q - expected %d bytes, got %d.", name, tf.Name(), len(expected), len(data)) + } } } if len(tc.expectedPayloadNames) == 0 { diff --git a/app/post_metadata_test.go b/app/post_metadata_test.go index f65ab845ff..24bda46ac9 100644 --- a/app/post_metadata_test.go +++ b/app/post_metadata_test.go @@ -2181,7 +2181,7 @@ func TestParseImages(t *testing.T) { }, }, "tiff": { - FileName: "test.tiff", + FileName: "test_compressed_tiff.tiff", Expected: (*model.PostImage)(nil), }, "not an image": { diff --git a/tests/test.tiff b/tests/test_compressed_tiff.tiff similarity index 100% rename from tests/test.tiff rename to tests/test_compressed_tiff.tiff diff --git a/tests/test_expected_preview.tiff b/tests/test_expected_tiff_preview.jpeg similarity index 100% rename from tests/test_expected_preview.tiff rename to tests/test_expected_tiff_preview.jpeg diff --git a/tests/test_expected_thumb.tiff b/tests/test_expected_tiff_thumb.jpeg similarity index 100% rename from tests/test_expected_thumb.tiff rename to tests/test_expected_tiff_thumb.jpeg diff --git a/tests/test_raw_tiff.tiff b/tests/test_raw_tiff.tiff new file mode 100644 index 0000000000000000000000000000000000000000..5d5ec68f6792eeb701c56ea39cb1d7b0ce26cf9c GIT binary patch literal 22028 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 literal 0 HcmV?d00001