func TestStatJob(t *testing.T) {
	conn, err := dbus.SessionBus()
	if err != nil {
		t.Error("get session bus failed")
		t.FailNow()
	}

	backendProxy, err := NewDBusProxy(conn, _Dest, _Path, _Iface, 0)
	if err != nil {
		t.Error("create dbus proxy:", err)
		t.FailNow()
	}
	var dest string
	var objPath dbus.ObjectPath
	var iface string
	err = backendProxy.Call("NewStatJob", "/tmp").Store(&dest, &objPath, &iface)
	if err != nil {
		t.Error("create StatJob:", err)
		t.FailNow()
	}

	statProxy, err := NewDBusProxy(conn, dest, string(objPath), iface, 0)
	if err != nil {
		t.Error("create dbus proxy for stat job:", err)
		t.FailNow()
	}

	err = statProxy.Call("Execute").Store()
	if err != nil {
		t.Error("execute stat job:", err)
		t.FailNow()
	}
}
func showModule(module string) {
	go func() {
		conn, err := dbus.SessionBus()
		if err != nil {
			return
		}

		obj := conn.Object("com.deepin.dde.ControlCenter", "/com/deepin/dde/ControlCenter")
		if obj != nil {
			obj.Call("com.deepin.dde.ControlCenter.ShowModule", 0, module).Store()
		}
	}()
}
func (app *Application) emitRequestPaste(dest string) error {
	conn, err := dbus.SessionBus()
	if err != nil {
		return err
	}

	obj := conn.Object("com.deepin.filemanager.Backend.Clipboard", "/com/deepin/filemanager/Backend/Clipboard")
	if obj != nil {
		return obj.Call("com.deepin.filemanager.Backend.Clipboard.EmitPaste", 0, dest).Store()
	}

	return nil
}
func TestProxy(t *testing.T) {
	Convey("DBusProxy", t, func() {
		Convey("should handle nil connection", func() {
			proxy, err := NewDBusProxy(nil,
				"org.freedesktop.DBus",
				"/",
				"org.freedesktop.DBus",
				0,
			)
			So(proxy, ShouldBeNil)
			So(err, ShouldNotBeNil)
			So(err, ShouldEqual, ErrorProxyNilConnection)
		})

		Convey("should handle empty destination", func() {
			conn, err := dbus.SessionBus()
			So(err, ShouldBeNil)
			proxy, err := NewDBusProxy(conn,
				"",
				"/",
				"org.freedesktop.DBus",
				0,
			)
			So(proxy, ShouldBeNil)
			So(err, ShouldNotBeNil)
			So(err, ShouldEqual, ErrorProxyEmptyDestination)
		})

		Convey("should handle empty object path", func() {
			conn, err := dbus.SessionBus()
			So(err, ShouldBeNil)

			proxy, err := NewDBusProxy(conn,
				"org.freedesktop.DBus",
				"",
				"org.freedesktop.DBus",
				0,
			)
			So(proxy, ShouldBeNil)
			So(err, ShouldNotBeNil)
			So(err, ShouldEqual, ErrorProxyEmptyObjectPath)
		})

		Convey("should handle empty interface path", func() {
			conn, err := dbus.SessionBus()
			So(err, ShouldBeNil)

			proxy, err := NewDBusProxy(conn,
				"org.freedesktop.DBus",
				"/",
				"",
				0,
			)
			So(proxy, ShouldBeNil)
			So(err, ShouldNotBeNil)
			So(err, ShouldEqual, ErrorProxyEmptyInterface)
		})

		Convey("should handle invalid object path", func() {
			conn, err := dbus.SessionBus()
			So(err, ShouldBeNil)

			proxy, err := NewDBusProxy(conn,
				"org.freedesktop.DBus",
				"1",
				"org.freedesktop.DBus",
				0,
			)
			So(proxy, ShouldBeNil)
			So(err, ShouldNotBeNil)
			So(err, ShouldEqual, ErrorProxyInvalidObjectPath)
		})

		Convey("call method", func() {
			conn, err := dbus.SessionBus()
			So(err, ShouldBeNil)
			proxy, err := NewDBusProxy(conn,
				"org.freedesktop.DBus",
				"/",
				"org.freedesktop.DBus",
				0,
			)

			So(err, ShouldBeNil)
			var x string
			err = proxy.Call("GetId").Store(&x)
			So(err, ShouldBeNil)
			So(x, ShouldNotEqual, "")
		})

		Convey("call a not existed method", func() {
			conn, err := dbus.SessionBus()
			So(err, ShouldBeNil)
			proxy, err := NewDBusProxy(conn,
				"org.freedesktop.DBus",
				"/",
				"org.freedesktop.DBus",
				0,
			)

			So(err, ShouldBeNil)
			err = proxy.Call("GetXXX").Store()
			So(err, ShouldNotBeNil)
		})
	})
}
func TestNewDeleteJob(t *testing.T) {
	conn, err := dbus.SessionBus()
	if err != nil {
		t.Error("get session bus failed")
		t.FailNow()
	}

	backendProxy, err := NewDBusProxy(conn, _Dest, _Path, _Iface, 0)
	if err != nil {
		t.Error(err)
		t.FailNow()
	}
	x := func(t *testing.T, fn func() (string, error)) func() {
		return func() {
			target, err := fn()
			if err != nil {
				t.Error(err)
			}

			f := gio.FileNewForCommandlineArg(target)
			So(f.QueryExists(nil), ShouldBeTrue)
			f.Unref()

			var destName string
			var objPath dbus.ObjectPath
			var iface string
			err = backendProxy.Call("NewDeleteJob", []string{target}, false, "", "", "").Store(&destName, &objPath, &iface)
			if err != nil {
				t.Error(err)
				t.FailNow()
			}

			deleteProxy, err := NewDBusProxy(conn, destName, string(objPath), iface, 0)
			err = deleteProxy.Call("Execute").Store()
			if err != nil {
				t.Error(err.Error())
			}

			f = gio.FileNewForCommandlineArg(target)
			// TODO: this test result is not stable, add a timer to check.
			So(f.QueryExists(nil), ShouldBeFalse)
			f.Unref()
		}
	}

	Convey("should remove a file correctly", t, x(t, func() (string, error) {
		target, err := filepath.Abs("./testdata/todelete.txt")
		if err != nil {
			return "", err
		}

		err = exec.Command("touch", target).Run()
		return target, err
	}))

	// TODO: backup deleted things
	SkipConvey("should delete a empty directory correctly", t, x(t, func() (string, error) {
		target, err := filepath.Abs("./testdata/todelete.dir")
		if err != nil {
			return target, err
		}
		err = exec.Command("mkdir", target).Run()
		return target, err
	}))

	SkipConvey("should delete a non-empty directory correctly", t, x(t, func() (string, error) {
		target, err := filepath.Abs("./testdata/todelete.dir")
		if err != nil {
			return target, err
		}
		err = exec.Command("mkdir", target).Run()
		err = exec.Command("touch", target+"/a").Run()
		return target, nil
	}))
}
	"path/filepath"
	"pkg.deepin.io/lib/dbus"
	d "pkg.deepin.io/service/file-manager-backend/delegator"
	. "pkg.deepin.io/service/file-manager-backend/log"
	"pkg.deepin.io/service/file-manager-backend/operations"
	"strings"
	"sync"
)

var getConn = (func() func() *dbus.Conn {
	var conn *dbus.Conn
	var once sync.Once
	return func() *dbus.Conn {
		once.Do(func() {
			var err error
			conn, err = dbus.SessionBus()
			if err != nil {
				Log.Fatal("Connect to Session Bus failed:", err)
			}
		})
		return conn
	}
}())

// OperationBackend is the backend to create dbus operations for front end.
type OperationBackend struct {
}

// NewOperationBackend creates a new backend for operations.
func NewOperationBackend() *OperationBackend {
	op := &OperationBackend{}