109 lines
3.6 KiB
Go
109 lines
3.6 KiB
Go
package testusers
|
|
|
|
import (
|
|
"bytes"
|
|
"fmt"
|
|
"image"
|
|
"image/png"
|
|
"os"
|
|
"path/filepath"
|
|
"reflect"
|
|
"regexp"
|
|
"strings"
|
|
"testing"
|
|
"time"
|
|
)
|
|
|
|
func TestGenerateBalancedLabelledAdults(t *testing.T) {
|
|
items, err := Generate("https://im.bchongw.com/uploads/")
|
|
if err != nil || len(items) != 100 {
|
|
t.Fatalf("len=%d err=%v", len(items), err)
|
|
}
|
|
ids, names := map[string]bool{}, map[string]bool{}
|
|
locations := map[string]bool{}
|
|
counts := map[int]int{}
|
|
files := map[string]bool{}
|
|
for _, file := range Avatars() {
|
|
files[file] = true
|
|
}
|
|
for _, p := range items {
|
|
if ids[p.PublicID] || names[p.Nickname] || !p.IsTest || p.TestBatch != Batch || p.Label != "测试用户" || !strings.HasPrefix(p.Nickname, "测试·") {
|
|
t.Fatalf("missing label or duplicate identity: %+v", p)
|
|
}
|
|
ids[p.PublicID], names[p.Nickname] = true, true
|
|
counts[p.Gender]++
|
|
birthday, err := time.Parse("2006-01-02", p.Birthday)
|
|
if err != nil || birthday.After(time.Date(2008, 8, 31, 0, 0, 0, 0, time.UTC)) {
|
|
t.Fatalf("invalid adult birthday: %s", p.Birthday)
|
|
}
|
|
if !files[p.AvatarFile] || p.Avatar != "https://im.bchongw.com/uploads/"+p.AvatarFile || !regexp.MustCompile(`^[0-9]+-[0-9]+\.png$`).MatchString(p.AvatarFile) {
|
|
t.Fatalf("avatar incompatible with media route: %s", p.Avatar)
|
|
}
|
|
if !strings.Contains(p.Bio, "非真实交友用户") {
|
|
t.Fatal("missing synthetic identity disclosure")
|
|
}
|
|
if p.Latitude < 18 || p.Latitude > 54 || p.Longitude < 73 || p.Longitude > 135 {
|
|
t.Fatalf("fixture location is outside China: %+v", p)
|
|
}
|
|
location := fmt.Sprintf("%.6f,%.6f", p.Latitude, p.Longitude)
|
|
if locations[location] {
|
|
t.Fatalf("duplicate fixture location: %s", location)
|
|
}
|
|
locations[location] = true
|
|
}
|
|
if counts[1] != 50 || counts[2] != 50 || len(counts) != 2 {
|
|
t.Fatalf("gender distribution: %v", counts)
|
|
}
|
|
again, _ := Generate("https://im.bchongw.com/uploads/")
|
|
if !reflect.DeepEqual(items, again) {
|
|
t.Fatal("fixture generation must be deterministic")
|
|
}
|
|
}
|
|
|
|
func TestRejectUnsafePublicBase(t *testing.T) {
|
|
for _, base := range []string{"", "/uploads", "http://example.com/uploads", "https://user:secret@example.com/uploads", "https://example.com/uploads?x=1", "https://example.com/#bad", "javascript:alert(1)"} {
|
|
if _, err := Generate(base); err == nil {
|
|
t.Errorf("accepted unsafe base %q", base)
|
|
}
|
|
}
|
|
for _, base := range []string{"https://example.com/uploads", "http://127.0.0.1:8888/uploads", "http://localhost:8888/uploads"} {
|
|
if _, err := Generate(base); err != nil {
|
|
t.Errorf("rejected valid base %q: %v", base, err)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestAvatarCopyIsRepeatableAndDoesNotOverwrite(t *testing.T) {
|
|
source, destination := t.TempDir(), t.TempDir()
|
|
var buf bytes.Buffer
|
|
if err := png.Encode(&buf, image.NewRGBA(image.Rect(0, 0, 256, 256))); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
for _, file := range Avatars() {
|
|
if err := os.WriteFile(filepath.Join(source, file), buf.Bytes(), 0600); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
}
|
|
for i := 0; i < 2; i++ {
|
|
if err := CopyAvatars(source, destination); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
}
|
|
conflict := filepath.Join(destination, Avatars()[0])
|
|
if err := os.WriteFile(conflict, []byte("existing user file"), 0600); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if err := CopyAvatars(source, destination); err == nil {
|
|
t.Fatal("overwrote an unrelated file")
|
|
}
|
|
if got, _ := os.ReadFile(conflict); string(got) != "existing user file" {
|
|
t.Fatal("collision changed existing file")
|
|
}
|
|
}
|
|
|
|
func TestBundledAvatarsArePresent(t *testing.T) {
|
|
if err := CopyAvatars(filepath.Join("..", "..", "..", "fixtures", "test-users", "avatars"), t.TempDir()); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
}
|