avatar_test.go
⎇
Raw
1package avatar
2
3import (
4 "bytes"
5 "encoding/hex"
6 "image"
7 "image/color"
8 "image/jpeg"
9 "os"
10 "path/filepath"
11 "testing"
12)
13
14// Reference values from the previous implementation. They pin the identicon
15// algorithm, so existing users keep the same picture.
16func TestIdenticonMatchesReference(t *testing.T) {
17 tests := []struct {
18 name string
19 bytes string
20 rgb [3]uint8
21 }{
22 {"alice", "a554a5a173394418a17c66ae57445638", [3]uint8{156, 178, 31}},
23 {"admin", "7c212d2be8af0b70a0dd6542c4f55b32", [3]uint8{166, 33, 186}},
24 {"bob-42", "07c21f2cb96afe78a3f481297d2f9406", [3]uint8{197, 27, 53}},
25 {"ünïcode", "6f73f4fe71b1d1c57b611ae2556e8766", [3]uint8{219, 140, 57}},
26 }
27 for _, tt := range tests {
28 b := hashBytes(tt.name, 16)
29 if got := hex.EncodeToString(b); got != tt.bytes {
30 t.Errorf("hashBytes(%q) = %s, want %s", tt.name, got, tt.bytes)
31 }
32 r, g, bl := hslToRGB(float64((int(b[0])|int(b[1])<<8)%360), float64(int(b[2])%20+65), float64(int(b[3])%20+40))
33 if [3]uint8{r, g, bl} != tt.rgb {
34 t.Errorf("color(%q) = %v, want %v", tt.name, [3]uint8{r, g, bl}, tt.rgb)
35 }
36 }
37}
38
39func TestIdenticonPixels(t *testing.T) {
40 img := Identicon("alice")
41 if img.Bounds() != image.Rect(0, 0, 128, 128) {
42 t.Fatalf("bounds = %v", img.Bounds())
43 }
44 // The padding area is always background.
45 if got := img.NRGBAAt(0, 0); got != (color.NRGBA{240, 240, 240, 255}) {
46 t.Errorf("corner = %v", got)
47 }
48 // Column 0 and column 4 mirror each other.
49 for y := 24; y < 104; y++ {
50 if img.NRGBAAt(24, y) != img.NRGBAAt(127-24, y) {
51 t.Fatalf("identicon not symmetric at y=%d", y)
52 }
53 }
54}
55
56func TestSaveResizesAndRejectsNonImages(t *testing.T) {
57 dir := t.TempDir()
58
59 src := image.NewRGBA(image.Rect(0, 0, 400, 200))
60 var buf bytes.Buffer
61 if err := jpeg.Encode(&buf, src, nil); err != nil {
62 t.Fatal(err)
63 }
64 if err := Save(dir, 7, buf.Bytes()); err != nil {
65 t.Fatal(err)
66 }
67 f, err := os.Open(filepath.Join(dir, "7.png"))
68 if err != nil {
69 t.Fatal(err)
70 }
71 defer f.Close()
72 cfg, format, err := image.DecodeConfig(f)
73 if err != nil {
74 t.Fatal(err)
75 }
76 if format != "png" || cfg.Width != 128 || cfg.Height != 128 {
77 t.Errorf("stored %s %dx%d", format, cfg.Width, cfg.Height)
78 }
79
80 if err := Save(dir, 8, []byte("not an image at all")); err == nil {
81 t.Error("expected an error for a non-image upload")
82 }
83}
84
85func TestPath(t *testing.T) {
86 if got := Path("/data/avatars", 42); got != "/data/avatars/42.png" {
87 t.Errorf("Path = %q", got)
88 }
89}
90