1package imageutil
2
3import (
4 "bytes"
5 "image"
6 "image/color"
7 "image/jpeg"
8 "image/png"
9 "testing"
10)
11
12func createTestPNG(t *testing.T, width, height int) []byte {
13 img := image.NewRGBA(image.Rect(0, 0, width, height))
14 for y := 0; y < height; y++ {
15 for x := 0; x < width; x++ {
16 img.Set(x, y, color.RGBA{R: 100, G: 150, B: 200, A: 255})
17 }
18 }
19 var buf bytes.Buffer
20 if err := png.Encode(&buf, img); err != nil {
21 t.Fatalf("Failed to create test image: %v", err)
22 }
23 return buf.Bytes()
24}
25
26func TestResizeImage(t *testing.T) {
27 tests := []struct {
28 name string
29 width int
30 height int
31 maxDim int
32 wantResize bool
33 wantMaxDim int
34 }{
35 {"small image", 800, 600, 2000, false, 800},
36 {"at limit", 2000, 2000, 2000, false, 2000},
37 {"width exceeds", 3000, 1000, 2000, true, 2000},
38 {"height exceeds", 1000, 3000, 2000, true, 2000},
39 {"both exceed", 3000, 3000, 2000, true, 2000},
40 }
41
42 for _, tt := range tests {
43 t.Run(tt.name, func(t *testing.T) {
44 data := createTestPNG(t, tt.width, tt.height)
45 resized, format, didResize, err := ResizeImage(data, tt.maxDim)
46 if err != nil {
47 t.Fatalf("ResizeImage() error = %v", err)
48 }
49 if didResize != tt.wantResize {
50 t.Errorf("ResizeImage() didResize = %v, want %v", didResize, tt.wantResize)
51 }
52 if format != "png" {
53 t.Errorf("ResizeImage() format = %v, want png", format)
54 }
55 if didResize {
56 // Verify the resized image dimensions
57 config, _, err := image.DecodeConfig(bytes.NewReader(resized))
58 if err != nil {
59 t.Fatalf("Failed to decode resized image: %v", err)
60 }
61 if config.Width > tt.maxDim || config.Height > tt.maxDim {
62 t.Errorf("Resized image %dx%d still exceeds max %d", config.Width, config.Height, tt.maxDim)
63 }
64 } else {
65 if !bytes.Equal(resized, data) {
66 t.Error("Expected original data when no resize needed")
67 }
68 }
69 })
70 }
71}
72
73func TestResizeImageJPEG(t *testing.T) {
74 // Create a test JPEG image
75 img := image.NewRGBA(image.Rect(0, 0, 3000, 1000))
76 for y := 0; y < 1000; y++ {
77 for x := 0; x < 3000; x++ {
78 img.Set(x, y, color.RGBA{R: 100, G: 150, B: 200, A: 255})
79 }
80 }
81 var buf bytes.Buffer
82 if err := jpeg.Encode(&buf, img, &jpeg.Options{Quality: 85}); err != nil {
83 t.Fatalf("Failed to create test JPEG image: %v", err)
84 }
85 data := buf.Bytes()
86
87 resized, format, didResize, err := ResizeImage(data, 2000)
88 if err != nil {
89 t.Fatalf("ResizeImage() error = %v", err)
90 }
91 if !didResize {
92 t.Error("Expected resize for large JPEG image")
93 }
94 if format != "jpeg" {
95 t.Errorf("ResizeImage() format = %v, want jpeg", format)
96 }
97
98 // Verify the resized image dimensions
99 config, _, err := image.DecodeConfig(bytes.NewReader(resized))
100 if err != nil {
101 t.Fatalf("Failed to decode resized image: %v", err)
102 }
103 if config.Width > 2000 || config.Height > 2000 {
104 t.Errorf("Resized image %dx%d still exceeds max 2000", config.Width, config.Height)
105 }
106}
107
108func TestResizeImageErrors(t *testing.T) {
109 tests := []struct {
110 name string
111 data []byte
112 maxDim int
113 wantErr bool
114 }{
115 {
116 name: "empty data",
117 data: []byte{},
118 maxDim: 2000,
119 wantErr: true,
120 },
121 }
122
123 for _, tt := range tests {
124 t.Run(tt.name, func(t *testing.T) {
125 _, _, _, err := ResizeImage(tt.data, tt.maxDim)
126 if (err != nil) != tt.wantErr {
127 t.Errorf("ResizeImage() error = %v, wantErr %v", err, tt.wantErr)
128 }
129 })
130 }
131}
132
133func TestResizeImageNoResizeNeeded(t *testing.T) {
134 data := createTestPNG(t, 800, 600)
135 resized, format, didResize, err := ResizeImage(data, 2000)
136 if err != nil {
137 t.Fatalf("ResizeImage() error = %v", err)
138 }
139 if didResize {
140 t.Error("Expected no resize for small image")
141 }
142 if format != "png" {
143 t.Errorf("ResizeImage() format = %v, want png", format)
144 }
145 if !bytes.Equal(resized, data) {
146 t.Error("Expected original data when no resize needed")
147 }
148}