package app import ( "bytes" "context" "image" "image/color" "image/png" "testing" "github.com/geo-platform/tenant-api/internal/shared/config" ) func newTestChallengePNG(t *testing.T) []byte { t.Helper() img := image.NewRGBA(image.Rect(0, 0, 50, 25)) orange := color.RGBA{R: 240, G: 130, B: 40, A: 255} // Four orange blocks emulate the four-digit captcha; digitocr only needs to // segment and match them, so exact glyphs are not required for this test. for d := 0; d < 4; d++ { x0 := 5 + d*10 for y := 5; y < 21; y++ { for x := x0; x < x0+8; x++ { img.Set(x, y, orange) } } } var buf bytes.Buffer if err := png.Encode(&buf, img); err != nil { t.Fatalf("encode png: %v", err) } return buf.Bytes() } func TestDigitOCRChallengeResolverDecodesImage(t *testing.T) { resolver := DigitOCRMeijiequanChallengeCodeResolver{} code, err := resolver.ResolveCode(context.Background(), MeijiequanChallenge{ Image: newTestChallengePNG(t), ContentType: "image/png", }) if err != nil { t.Fatalf("resolve code: %v", err) } if len(code) != meijiequanChallengeDigits { t.Fatalf("expected %d digit code, got %q", meijiequanChallengeDigits, code) } for _, r := range code { if r < '0' || r > '9' { t.Fatalf("expected numeric code, got %q", code) } } } func TestDigitOCRChallengeResolverRejectsEmptyImage(t *testing.T) { resolver := DigitOCRMeijiequanChallengeCodeResolver{} if _, err := resolver.ResolveCode(context.Background(), MeijiequanChallenge{}); err == nil { t.Fatal("expected error for empty challenge image") } } func TestNewMeijiequanClientDefaultsToDigitOCRResolver(t *testing.T) { client := NewMeijiequanClient(nil, config.MeijiequanConfig{}) if _, ok := client.challengeResolver().(DigitOCRMeijiequanChallengeCodeResolver); !ok { t.Fatalf("expected digitocr resolver by default, got %T", client.challengeResolver()) } }