Cthulhu is no longer a fork. Now it is a screen reader written in Golang.
This commit is contained in:
1 parent
a998fe67de
commit
069fc674dc
708 files changed
+112482
-532
No files matched your search
@@ -0,0 +1,121 @@
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
package remote
|
||||
|
||||
import (
|
||||
"context"
|
||||
"git.stormux.org/storm/cthulhu/internal/atspi"
|
||||
"git.stormux.org/storm/cthulhu/internal/wine"
|
||||
"github.com/godbus/dbus/v5"
|
||||
"os"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
type reviewRecordingHandler struct {
|
||||
*recordingHandler
|
||||
registry *wine.ReviewRegistry
|
||||
}
|
||||
|
||||
func (h reviewRecordingHandler) RegisterProvider(sender string, path dbus.ObjectPath, version uint32) bool {
|
||||
return h.registry.RegisterProvider(sender, path, version)
|
||||
}
|
||||
func (h reviewRecordingHandler) PresentFocus(sender string, notice wine.ReviewFocusNotice) bool {
|
||||
return h.registry.PresentFocus(sender, notice)
|
||||
}
|
||||
func (h reviewRecordingHandler) BindWineReviewConnection(conn *dbus.Conn) {
|
||||
h.registry.BindWineReviewConnection(conn)
|
||||
}
|
||||
func TestWineReviewAuthorizationAndOptionalHandler(t *testing.T) {
|
||||
r := wine.NewReviewRegistry(nil)
|
||||
endpoint := newEndpoint(nil, reviewRecordingHandler{&recordingHandler{}, r}, func(dbus.Sender) bool { return false })
|
||||
endpoint.startAccepting()
|
||||
if accepted, err := endpoint.RegisterWineReviewProvider(":1.2", wine.ReviewObjectPath, 1); accepted || err == nil || err.Name != "org.freedesktop.DBus.Error.AccessDenied" {
|
||||
t.Fatal("unauthorized registration accepted")
|
||||
}
|
||||
optional := newEndpoint(nil, &recordingHandler{}, func(dbus.Sender) bool { return true })
|
||||
optional.startAccepting()
|
||||
if accepted, err := optional.RegisterWineReviewProvider(":1.2", wine.ReviewObjectPath, 1); accepted || err != nil {
|
||||
t.Fatal("older handler compatibility broken")
|
||||
}
|
||||
}
|
||||
|
||||
type nativeReviewEndpoint struct {
|
||||
conn *dbus.Conn
|
||||
calls chan struct{}
|
||||
bounds atspi.Rectangle
|
||||
}
|
||||
|
||||
func (f *nativeReviewEndpoint) CaptureWindow(sender dbus.Sender, window, focus string, revision uint64) (map[string]dbus.Variant, *dbus.Error) {
|
||||
var owner string
|
||||
if err := f.conn.BusObject().Call("org.freedesktop.DBus.GetNameOwner", 0, BusName).Store(&owner); err != nil || owner != string(sender) {
|
||||
return nil, dbus.NewError("org.freedesktop.DBus.Error.AccessDenied", nil)
|
||||
}
|
||||
select {
|
||||
case f.calls <- struct{}{}:
|
||||
default:
|
||||
}
|
||||
node := map[string]dbus.Variant{"id": dbus.MakeVariant(window), "parent": dbus.MakeVariant(""), "role": dbus.MakeVariant("window"), "name": dbus.MakeVariant("native fixture"), "protected": dbus.MakeVariant(false), "visible": dbus.MakeVariant(true), "bounds": dbus.MakeVariant(f.bounds), "text_known": dbus.MakeVariant(false), "caret_known": dbus.MakeVariant(false), "caret": dbus.MakeVariant(uint64(0)), "caret_utf16": dbus.MakeVariant(uint64(0)), "ranges": dbus.MakeVariant([]wine.ReviewRange{})}
|
||||
return map[string]dbus.Variant{"version": dbus.MakeVariant(uint32(1)), "instance": dbus.MakeVariant("instance"), "window": dbus.MakeVariant(window), "focus": dbus.MakeVariant(focus), "revision": dbus.MakeVariant(revision), "status": dbus.MakeVariant("ok"), "bounds": dbus.MakeVariant(f.bounds), "nodes": dbus.MakeVariant([]map[string]dbus.Variant{node})}, nil
|
||||
}
|
||||
func TestNativeSessionBusWineReview(t *testing.T) {
|
||||
if os.Getenv("CTHULHU_NATIVE_DBUS_TEST") != "1" {
|
||||
t.Skip("requires private session bus")
|
||||
}
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
|
||||
defer cancel()
|
||||
registry := wine.NewReviewRegistry(nil)
|
||||
if err := registry.Start(ctx); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer registry.Stop(context.Background())
|
||||
service := New(nil, reviewRecordingHandler{&recordingHandler{}, registry})
|
||||
if err := service.Start(ctx); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer service.Stop(context.Background())
|
||||
provider, err := dbus.ConnectSessionBus()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer provider.Close()
|
||||
fixture := &nativeReviewEndpoint{conn: provider, calls: make(chan struct{}, 1), bounds: atspi.Rectangle{X: -10, Y: 20, Width: 400, Height: 300}}
|
||||
if err = provider.Export(fixture, wine.ReviewObjectPath, wine.ReviewInterface); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
remote := provider.Object(BusName, ObjectPath)
|
||||
var accepted bool
|
||||
if err = remote.CallWithContext(ctx, InterfaceName+".RegisterWineReviewProvider", 0, wine.ReviewObjectPath, uint32(1)).Store(&accepted); err != nil || !accepted {
|
||||
t.Fatalf("registration: %v %v", accepted, err)
|
||||
}
|
||||
if err = remote.CallWithContext(ctx, InterfaceName+".PresentWineReviewFocus", 0, "instance", "window", "window", uint64(1), "same title", "window", false, fixture.bounds).Store(&accepted); err != nil || !accepted {
|
||||
t.Fatalf("focus: %v %v", accepted, err)
|
||||
}
|
||||
notices := registry.Focuses()
|
||||
if len(notices) != 1 {
|
||||
t.Fatalf("focus mailbox: %+v", notices)
|
||||
}
|
||||
id := notices[0].ID()
|
||||
tree, err := registry.Capture(ctx, id)
|
||||
if err != nil || tree == nil {
|
||||
t.Fatalf("actual owner capture: %v", err)
|
||||
}
|
||||
wrong, err := dbus.ConnectSessionBus()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer wrong.Close()
|
||||
if err = wrong.Object(id.BusName, wine.ReviewObjectPath).CallWithContext(ctx, wine.ReviewInterface+".CaptureWindow", 0, "window", "window", uint64(1)).Err; err == nil {
|
||||
t.Fatal("different unique connection accepted")
|
||||
}
|
||||
provider.Close()
|
||||
for registry.Current(id) {
|
||||
select {
|
||||
case <-registry.Changes():
|
||||
case <-ctx.Done():
|
||||
t.Fatal("dead provider remained current")
|
||||
}
|
||||
}
|
||||
if len(registry.Focuses()) != 0 {
|
||||
t.Fatal("dead focus retained")
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user