ituoke/internal/device/input_test.go

95 lines
3.0 KiB
Go

package device
import (
"math"
"os"
"path/filepath"
"runtime"
"strings"
"testing"
)
func inputFixture(t *testing.T) (*Service, string) {
t.Helper()
if runtime.GOOS == "windows" {
t.Skip("fake adb uses a POSIX shell")
}
dir := t.TempDir()
calls := filepath.Join(dir, "calls")
t.Setenv("INPUT_CALLS", calls)
path := filepath.Join(dir, "adb")
script := `#!/bin/sh
printf '%s\n' "$*" >> "$INPUT_CALLS"
if [ "$1" != -P ] || [ "$2" != 17891 ]; then exit 42; fi
if [ "$REJECT_INPUT" = 1 ]; then echo 'java.lang.SecurityException: requires INJECT_EVENTS permission' >&2; exit 1; fi
`
if err := os.WriteFile(path, []byte(script), 0700); err != nil {
t.Fatal(err)
}
previous := adbPathOverride
SetAdbPath(path)
t.Cleanup(func() { SetAdbPath(previous) })
return &Service{devices: map[string]DeviceInfo{"phone": {ID: "phone", Online: true, Width: 1080, Height: 2400}}}, calls
}
func TestPhoneInputCommands(t *testing.T) {
s, calls := inputFixture(t)
if err := s.Tap(TapRequest{DeviceID: "phone", X: 540, Y: 1200}); err != nil {
t.Fatal(err)
}
if err := s.Swipe(SwipeRequest{DeviceID: "phone", X1: 500, Y1: 1800, X2: 500, Y2: 600, DurationMs: 350}); err != nil {
t.Fatal(err)
}
if err := s.Swipe(SwipeRequest{DeviceID: "phone", X1: 1500, Y1: 500, X2: 500, Y2: 500, DurationMs: 400}); err != nil {
t.Fatal(err)
}
output, err := os.ReadFile(calls)
if err != nil {
t.Fatal(err)
}
for _, want := range []string{
"-P 17891 -s phone shell input tap 540 1200\n",
"-P 17891 -s phone shell input swipe 500 1800 500 600 350\n",
"-P 17891 -s phone shell input swipe 1500 500 500 500 400\n",
} {
if !strings.Contains(string(output), want) {
t.Fatalf("wrong phone input: %s", output)
}
}
}
func TestInvalidPhoneInputDoesNotExecuteADB(t *testing.T) {
s, calls := inputFixture(t)
for _, req := range []TapRequest{
{DeviceID: "missing", X: 1, Y: 1}, {DeviceID: "phone", X: math.NaN(), Y: 1},
{DeviceID: "phone", X: 1, Y: math.Inf(1)}, {DeviceID: "phone", X: -1, Y: 1},
{DeviceID: "phone", X: 3000, Y: 1}, {DeviceID: "phone", X: 1500, Y: 1500},
} {
if err := s.Tap(req); err == nil {
t.Fatalf("accepted invalid tap: %+v", req)
}
}
if err := s.Swipe(SwipeRequest{DeviceID: "phone", DurationMs: 0}); err == nil {
t.Fatal("accepted zero swipe duration")
}
if err := s.Swipe(SwipeRequest{DeviceID: "phone", DurationMs: 1501}); err == nil {
t.Fatal("accepted excessive swipe duration")
}
s.devices["phone"] = DeviceInfo{ID: "phone", Online: false, Width: 1080, Height: 2400}
if err := s.Tap(TapRequest{DeviceID: "phone", X: 1, Y: 1}); err == nil {
t.Fatal("accepted offline input")
}
if _, err := os.Stat(calls); !os.IsNotExist(err) {
t.Fatalf("invalid input executed adb: %v", err)
}
}
func TestPhoneInputPermissionError(t *testing.T) {
s, _ := inputFixture(t)
t.Setenv("REJECT_INPUT", "1")
err := s.Tap(TapRequest{DeviceID: "phone", X: 1, Y: 1})
if err == nil || !strings.Contains(err.Error(), "USB 调试(安全设置)") {
t.Fatalf("missing actionable permission error: %v", err)
}
}