summaryrefslogtreecommitdiffstats
path: root/modules/avatar/avatar_test.go
blob: 824a38e15bd2438487744b5adc3c773293246737 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
// Copyright 2016 The Gogs Authors. All rights reserved.
// SPDX-License-Identifier: MIT

package avatar

import (
	"bytes"
	"image"
	"image/png"
	"os"
	"testing"

	"code.gitea.io/gitea/modules/setting"

	"github.com/stretchr/testify/assert"
	"github.com/stretchr/testify/require"
)

func Test_RandomImageSize(t *testing.T) {
	_, err := RandomImageSize(0, []byte("gitea@local"))
	require.Error(t, err)

	_, err = RandomImageSize(64, []byte("gitea@local"))
	require.NoError(t, err)
}

func Test_RandomImage(t *testing.T) {
	_, err := RandomImage([]byte("gitea@local"))
	require.NoError(t, err)
}

func Test_ProcessAvatarPNG(t *testing.T) {
	setting.Avatar.MaxWidth = 4096
	setting.Avatar.MaxHeight = 4096

	data, err := os.ReadFile("testdata/avatar.png")
	require.NoError(t, err)

	_, err = processAvatarImage(data, 262144)
	require.NoError(t, err)
}

func Test_ProcessAvatarJPEG(t *testing.T) {
	setting.Avatar.MaxWidth = 4096
	setting.Avatar.MaxHeight = 4096

	data, err := os.ReadFile("testdata/avatar.jpeg")
	require.NoError(t, err)

	_, err = processAvatarImage(data, 262144)
	require.NoError(t, err)
}

func Test_ProcessAvatarInvalidData(t *testing.T) {
	setting.Avatar.MaxWidth = 5
	setting.Avatar.MaxHeight = 5

	_, err := processAvatarImage([]byte{}, 12800)
	assert.EqualError(t, err, "image.DecodeConfig: image: unknown format")
}

func Test_ProcessAvatarInvalidImageSize(t *testing.T) {
	setting.Avatar.MaxWidth = 5
	setting.Avatar.MaxHeight = 5

	data, err := os.ReadFile("testdata/avatar.png")
	require.NoError(t, err)

	_, err = processAvatarImage(data, 12800)
	assert.EqualError(t, err, "image width is too large: 10 > 5")
}

func Test_ProcessAvatarImage(t *testing.T) {
	setting.Avatar.MaxWidth = 4096
	setting.Avatar.MaxHeight = 4096
	scaledSize := DefaultAvatarSize * setting.Avatar.RenderedSizeFactor

	newImgData := func(size int, optHeight ...int) []byte {
		width := size
		height := size
		if len(optHeight) == 1 {
			height = optHeight[0]
		}
		img := image.NewRGBA(image.Rect(0, 0, width, height))
		bs := bytes.Buffer{}
		err := png.Encode(&bs, img)
		require.NoError(t, err)
		return bs.Bytes()
	}

	// if origin image canvas is too large, crop and resize it
	origin := newImgData(500, 600)
	result, err := processAvatarImage(origin, 0)
	require.NoError(t, err)
	assert.NotEqual(t, origin, result)
	decoded, err := png.Decode(bytes.NewReader(result))
	require.NoError(t, err)
	assert.EqualValues(t, scaledSize, decoded.Bounds().Max.X)
	assert.EqualValues(t, scaledSize, decoded.Bounds().Max.Y)

	// if origin image is smaller than the default size, use the origin image
	origin = newImgData(1)
	result, err = processAvatarImage(origin, 0)
	require.NoError(t, err)
	assert.Equal(t, origin, result)

	// use the origin image if the origin is smaller
	origin = newImgData(scaledSize + 100)
	result, err = processAvatarImage(origin, 0)
	require.NoError(t, err)
	assert.Less(t, len(result), len(origin))

	// still use the origin image if the origin doesn't exceed the max-origin-size
	origin = newImgData(scaledSize + 100)
	result, err = processAvatarImage(origin, 262144)
	require.NoError(t, err)
	assert.Equal(t, origin, result)

	// allow to use known image format (eg: webp) if it is small enough
	origin, err = os.ReadFile("testdata/animated.webp")
	require.NoError(t, err)
	result, err = processAvatarImage(origin, 262144)
	require.NoError(t, err)
	assert.Equal(t, origin, result)

	// do not support unknown image formats, eg: SVG may contain embedded JS
	origin = []byte("<svg></svg>")
	_, err = processAvatarImage(origin, 262144)
	require.ErrorContains(t, err, "image: unknown format")

	// make sure the canvas size limit works
	setting.Avatar.MaxWidth = 5
	setting.Avatar.MaxHeight = 5
	origin = newImgData(10)
	_, err = processAvatarImage(origin, 262144)
	require.ErrorContains(t, err, "image width is too large: 10 > 5")
}