Full Mattermost server source with integrated Community Enterprise features. Includes vendor directory for offline/air-gapped builds. Structure: - enterprise-impl/: Enterprise feature implementations - enterprise-community/: Init files that register implementations - enterprise/: Bridge imports (community_imports.go) - vendor/: All dependencies for offline builds Build (online): go build ./cmd/mattermost Build (offline/air-gapped): go build -mod=vendor ./cmd/mattermost 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
350 lines
7.6 KiB
Go
350 lines
7.6 KiB
Go
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
|
// See LICENSE.txt for license information.
|
|
|
|
package imaging
|
|
|
|
import (
|
|
"bytes"
|
|
"image"
|
|
"image/color"
|
|
"os"
|
|
"testing"
|
|
|
|
"github.com/mattermost/mattermost/server/v8/channels/utils/fileutils"
|
|
|
|
"github.com/stretchr/testify/require"
|
|
)
|
|
|
|
func TestFillImageTransparency(t *testing.T) {
|
|
tcs := []struct {
|
|
name string
|
|
inputName string
|
|
outputName string
|
|
fillColor color.Color
|
|
}{
|
|
{
|
|
"8-bit Palette",
|
|
"fill_test_8bit_palette.png",
|
|
"fill_test_8bit_palette_out.png",
|
|
color.RGBA{0, 255, 0, 255},
|
|
},
|
|
{
|
|
"8-bit RGB",
|
|
"fill_test_8bit_rgb.png",
|
|
"fill_test_8bit_rgb_out.png",
|
|
color.RGBA{0, 255, 0, 255},
|
|
},
|
|
{
|
|
"8-bit RGBA",
|
|
"fill_test_8bit_rgba.png",
|
|
"fill_test_8bit_rgba_out.png",
|
|
color.RGBA{0, 255, 0, 255},
|
|
},
|
|
{
|
|
"16-bit RGB",
|
|
"fill_test_16bit_rgb.png",
|
|
"fill_test_16bit_rgb_out.png",
|
|
color.RGBA{0, 255, 0, 255},
|
|
},
|
|
{
|
|
"16-bit RGBA",
|
|
"fill_test_16bit_rgba.png",
|
|
"fill_test_16bit_rgba_out.png",
|
|
color.RGBA{0, 255, 0, 255},
|
|
},
|
|
}
|
|
|
|
imgDir, ok := fileutils.FindDir("tests")
|
|
require.True(t, ok)
|
|
|
|
e, err := NewEncoder(EncoderOptions{})
|
|
require.NotNil(t, e)
|
|
require.NoError(t, err)
|
|
|
|
d, err := NewDecoder(DecoderOptions{})
|
|
require.NotNil(t, d)
|
|
require.NoError(t, err)
|
|
|
|
for _, tc := range tcs {
|
|
t.Run(tc.name, func(t *testing.T) {
|
|
inputFile, err := os.Open(imgDir + "/" + tc.inputName)
|
|
require.NoError(t, err)
|
|
require.NotNil(t, inputFile)
|
|
defer func() {
|
|
require.NoError(t, inputFile.Close())
|
|
}()
|
|
|
|
inputImg, format, err := d.Decode(inputFile)
|
|
require.NoError(t, err)
|
|
require.NotNil(t, inputImg)
|
|
require.Equal(t, "png", format)
|
|
|
|
expectedBytes, err := os.ReadFile(imgDir + "/" + tc.outputName)
|
|
require.NoError(t, err)
|
|
|
|
FillImageTransparency(inputImg, tc.fillColor)
|
|
|
|
var b bytes.Buffer
|
|
err = e.EncodePNG(&b, inputImg)
|
|
require.NoError(t, err)
|
|
require.Equal(t, expectedBytes, b.Bytes())
|
|
})
|
|
}
|
|
|
|
t.Run("Opaque image", func(t *testing.T) {
|
|
inputFile, err := os.Open(imgDir + "/fill_test_opaque.png")
|
|
require.NoError(t, err)
|
|
require.NotNil(t, inputFile)
|
|
defer func() {
|
|
require.NoError(t, inputFile.Close())
|
|
}()
|
|
|
|
inputImg, format, err := d.Decode(inputFile)
|
|
require.NoError(t, err)
|
|
require.NotNil(t, inputImg)
|
|
require.Equal(t, "png", format)
|
|
|
|
_, err = inputFile.Seek(0, 0)
|
|
require.NoError(t, err)
|
|
|
|
expectedImg, format, err := d.Decode(inputFile)
|
|
require.NoError(t, err)
|
|
require.NotNil(t, expectedImg)
|
|
require.Equal(t, "png", format)
|
|
|
|
FillImageTransparency(inputImg, color.RGBA{0, 255, 0, 255})
|
|
require.Equal(t, expectedImg, inputImg)
|
|
})
|
|
}
|
|
|
|
func TestCropCenter(t *testing.T) {
|
|
imgDir, ok := fileutils.FindDir("tests")
|
|
require.True(t, ok)
|
|
|
|
d, err := NewDecoder(DecoderOptions{})
|
|
require.NotNil(t, d)
|
|
require.NoError(t, err)
|
|
|
|
for _, tc := range []struct {
|
|
name string
|
|
inputName string
|
|
outputName string
|
|
width int
|
|
height int
|
|
}{
|
|
{
|
|
"Crop to center 100x100",
|
|
"crop_test_input.png",
|
|
"crop_test_output_100x100.png",
|
|
100,
|
|
100,
|
|
},
|
|
{
|
|
"Crop to center 45x45",
|
|
"crop_test_input.png",
|
|
"crop_test_output_45x45.png",
|
|
45,
|
|
45,
|
|
},
|
|
{
|
|
"Crop to center 100x45",
|
|
"crop_test_input.png",
|
|
"crop_test_output_100x45.png",
|
|
100,
|
|
45,
|
|
},
|
|
{
|
|
"Crop to center 45x100",
|
|
"crop_test_input.png",
|
|
"crop_test_output_45x100.png",
|
|
45,
|
|
100,
|
|
},
|
|
} {
|
|
t.Run(tc.name, func(t *testing.T) {
|
|
inputFile, err := os.Open(imgDir + "/" + tc.inputName)
|
|
require.NoError(t, err)
|
|
require.NotNil(t, inputFile)
|
|
defer func() {
|
|
require.NoError(t, inputFile.Close())
|
|
}()
|
|
|
|
inputImg, format, err := d.Decode(inputFile)
|
|
require.NoError(t, err)
|
|
require.NotNil(t, inputImg)
|
|
require.Equal(t, "png", format)
|
|
|
|
expectedFile, err := os.Open(imgDir + "/" + tc.outputName)
|
|
require.NoError(t, err)
|
|
require.NotNil(t, expectedFile)
|
|
defer func() {
|
|
require.NoError(t, expectedFile.Close())
|
|
}()
|
|
|
|
expectedImg, format, err := d.Decode(expectedFile)
|
|
require.NoError(t, err)
|
|
require.NotNil(t, expectedImg)
|
|
require.Equal(t, "png", format)
|
|
|
|
croppedImg := CropCenter(inputImg, tc.width, tc.height)
|
|
require.Equal(t, expectedImg.Bounds().Dx(), croppedImg.Bounds().Dx())
|
|
require.Equal(t, expectedImg.Bounds().Dy(), croppedImg.Bounds().Dy())
|
|
require.Equal(t, expectedImg.(*image.RGBA).Pix, croppedImg.(*image.RGBA).Pix)
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestFit(t *testing.T) {
|
|
imgDir, ok := fileutils.FindDir("tests")
|
|
require.True(t, ok)
|
|
|
|
d, err := NewDecoder(DecoderOptions{})
|
|
require.NotNil(t, d)
|
|
require.NoError(t, err)
|
|
|
|
for _, tc := range []struct {
|
|
name string
|
|
inputName string
|
|
outputName string
|
|
width int
|
|
height int
|
|
}{
|
|
{
|
|
"Fit to 100x100",
|
|
"fit_test_input.png",
|
|
"fit_test_output_100x100.png",
|
|
100,
|
|
100,
|
|
},
|
|
{
|
|
"Fit to 45x45",
|
|
"fit_test_input.png",
|
|
"fit_test_output_45x45.png",
|
|
45,
|
|
45,
|
|
},
|
|
{
|
|
"Fit to 100x45",
|
|
"fit_test_input.png",
|
|
"fit_test_output_100x45.png",
|
|
100,
|
|
45,
|
|
},
|
|
{
|
|
"Fit to 45x100",
|
|
"fit_test_input.png",
|
|
"fit_test_output_45x100.png",
|
|
45,
|
|
100,
|
|
},
|
|
} {
|
|
t.Run(tc.name, func(t *testing.T) {
|
|
inputFile, err := os.Open(imgDir + "/" + tc.inputName)
|
|
require.NoError(t, err)
|
|
require.NotNil(t, inputFile)
|
|
defer func() {
|
|
require.NoError(t, inputFile.Close())
|
|
}()
|
|
|
|
inputImg, format, err := d.Decode(inputFile)
|
|
require.NoError(t, err)
|
|
require.NotNil(t, inputImg)
|
|
require.Equal(t, "png", format)
|
|
|
|
expectedFile, err := os.Open(imgDir + "/" + tc.outputName)
|
|
require.NoError(t, err)
|
|
require.NotNil(t, expectedFile)
|
|
defer func() {
|
|
require.NoError(t, expectedFile.Close())
|
|
}()
|
|
|
|
expectedImg, format, err := d.Decode(expectedFile)
|
|
require.NoError(t, err)
|
|
require.NotNil(t, expectedImg)
|
|
require.Equal(t, "png", format)
|
|
|
|
fittedImg := Fit(inputImg, tc.width, tc.height)
|
|
require.Equal(t, expectedImg, fittedImg)
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestFillCenter(t *testing.T) {
|
|
imgDir, ok := fileutils.FindDir("tests")
|
|
require.True(t, ok)
|
|
|
|
d, err := NewDecoder(DecoderOptions{})
|
|
require.NotNil(t, d)
|
|
require.NoError(t, err)
|
|
|
|
tcs := []struct {
|
|
name string
|
|
inputName string
|
|
outputName string
|
|
width int
|
|
height int
|
|
}{
|
|
{
|
|
"Fill center 100x100",
|
|
"fill_test_input.png",
|
|
"fill_test_output_100x100.png",
|
|
100,
|
|
100,
|
|
},
|
|
{
|
|
"Fill center 45x45",
|
|
"fill_test_input.png",
|
|
"fill_test_output_45x45.png",
|
|
45,
|
|
45,
|
|
},
|
|
{
|
|
"Fill center 100x45",
|
|
"fill_test_input.png",
|
|
"fill_test_output_100x45.png",
|
|
100,
|
|
45,
|
|
},
|
|
{
|
|
"Fill center 45x100",
|
|
"fill_test_input.png",
|
|
"fill_test_output_45x100.png",
|
|
45,
|
|
100,
|
|
},
|
|
}
|
|
|
|
for _, tc := range tcs {
|
|
t.Run(tc.name, func(t *testing.T) {
|
|
inputFile, err := os.Open(imgDir + "/" + tc.inputName)
|
|
require.NoError(t, err)
|
|
require.NotNil(t, inputFile)
|
|
defer func() {
|
|
require.NoError(t, inputFile.Close())
|
|
}()
|
|
|
|
inputImg, format, err := d.Decode(inputFile)
|
|
require.NoError(t, err)
|
|
require.NotNil(t, inputImg)
|
|
require.Equal(t, "png", format)
|
|
|
|
expectedFile, err := os.Open(imgDir + "/" + tc.outputName)
|
|
require.NoError(t, err)
|
|
require.NotNil(t, expectedFile)
|
|
defer func() {
|
|
require.NoError(t, expectedFile.Close())
|
|
}()
|
|
|
|
expectedImg, format, err := d.Decode(expectedFile)
|
|
require.NoError(t, err)
|
|
require.NotNil(t, expectedImg)
|
|
require.Equal(t, "png", format)
|
|
|
|
filledImg := FillCenter(inputImg, tc.width, tc.height)
|
|
require.Equal(t, expectedImg.Bounds().Dx(), filledImg.Bounds().Dx())
|
|
require.Equal(t, expectedImg.Bounds().Dy(), filledImg.Bounds().Dy())
|
|
require.Equal(t, expectedImg.(*image.RGBA).Pix, filledImg.(*image.RGBA).Pix)
|
|
})
|
|
}
|
|
}
|