mirror of
https://github.com/tahoe-lafs/tahoe-lafs.git
synced 2025-04-27 06:20:25 +00:00
webapi 'move'-button cleanups
test_web.py: use shouldFail2(), safer than old shouldFail() directory.py: forbid slashes in from_name=, return BAD_REQUEST instead of GONE when trying to move into a non-directory
This commit is contained in:
parent
e89bce21a5
commit
a92385b54b
src/allmydata
@ -3286,13 +3286,12 @@ class Web(WebMixin, WebErrorMixin, testutil.StallMixin, testutil.ReallyEqualMixi
|
||||
return d
|
||||
|
||||
def test_POST_move_file_no_replace(self):
|
||||
d = self.POST(self.public_url + "/foo", t="move", replace="false",
|
||||
from_name="bar.txt", to_name="baz.txt", to_dir="sub")
|
||||
d.addBoth(self.shouldFail, error.Error,
|
||||
"POST_move_file_no_replace",
|
||||
"409 Conflict",
|
||||
"There was already a child by that name, and you asked me "
|
||||
"to not replace it")
|
||||
d = self.shouldFail2(error.Error, "POST_move_file_no_replace",
|
||||
"409 Conflict",
|
||||
"There was already a child by that name, and you asked me to not replace it",
|
||||
self.POST, self.public_url + "/foo", t="move",
|
||||
replace="false", from_name="bar.txt",
|
||||
to_name="baz.txt", to_dir="sub")
|
||||
d.addCallback(lambda res: self.GET(self.public_url + "/foo/bar.txt"))
|
||||
d.addCallback(self.failUnlessIsBarDotTxt)
|
||||
d.addCallback(lambda res: self.GET(self.public_url + "/foo/bar.txt?t=json"))
|
||||
@ -3302,26 +3301,33 @@ class Web(WebMixin, WebErrorMixin, testutil.StallMixin, testutil.ReallyEqualMixi
|
||||
return d
|
||||
|
||||
def test_POST_move_file_slash_fail(self):
|
||||
d = self.POST(self.public_url + "/foo", t="move",
|
||||
from_name="bar.txt", to_name="slash/fail.txt", to_dir="sub")
|
||||
d.addBoth(self.shouldFail, error.Error,
|
||||
"test_POST_rename_file_slash_fail",
|
||||
"400 Bad Request",
|
||||
"to_name= may not contain a slash",
|
||||
)
|
||||
d = self.shouldFail2(error.Error, "test_POST_rename_file_slash_fail",
|
||||
"400 Bad Request",
|
||||
"to_name= may not contain a slash",
|
||||
self.POST, self.public_url + "/foo", t="move",
|
||||
from_name="bar.txt",
|
||||
to_name="slash/fail.txt", to_dir="sub")
|
||||
d.addCallback(lambda res:
|
||||
self.failUnlessNodeHasChild(self._foo_node, u"bar.txt"))
|
||||
d.addCallback(lambda res:
|
||||
self.failIfNodeHasChild(self._sub_node, u"slash/fail.txt"))
|
||||
d.addCallback(lambda ign:
|
||||
self.shouldFail2(error.Error,
|
||||
"test_POST_rename_file_slash_fail2",
|
||||
"400 Bad Request",
|
||||
"from_name= may not contain a slash",
|
||||
self.POST, self.public_url + "/foo",
|
||||
t="move",
|
||||
from_name="nope/bar.txt",
|
||||
to_name="fail.txt", to_dir="sub"))
|
||||
return d
|
||||
|
||||
def test_POST_move_file_no_target(self):
|
||||
d = self.POST(self.public_url + "/foo", t="move",
|
||||
from_name="bar.txt", to_name="baz.txt")
|
||||
d.addBoth(self.shouldFail, error.Error,
|
||||
"POST_move_file_no_target",
|
||||
"400 Bad Request",
|
||||
"move requires from_name and to_dir")
|
||||
d = self.shouldFail2(error.Error, "POST_move_file_no_target",
|
||||
"400 Bad Request",
|
||||
"move requires from_name and to_dir",
|
||||
self.POST, self.public_url + "/foo", t="move",
|
||||
from_name="bar.txt", to_name="baz.txt")
|
||||
d.addCallback(lambda res: self.GET(self.public_url + "/foo/bar.txt"))
|
||||
d.addCallback(self.failUnlessIsBarDotTxt)
|
||||
d.addCallback(lambda res: self.GET(self.public_url + "/foo/bar.txt?t=json"))
|
||||
@ -3331,13 +3337,12 @@ class Web(WebMixin, WebErrorMixin, testutil.StallMixin, testutil.ReallyEqualMixi
|
||||
return d
|
||||
|
||||
def test_POST_move_file_bad_target_type(self):
|
||||
d = self.POST(self.public_url + "/foo", t="move", target_type="*D",
|
||||
from_name="bar.txt", to_dir="sub")
|
||||
d.addBoth(self.shouldFail, error.Error,
|
||||
"test_POST_rename_file_slash_fail",
|
||||
"400 Bad Request",
|
||||
"invalid target_type parameter",
|
||||
)
|
||||
d = self.shouldFail2(error.Error, "test_POST_move_file_bad_target_type",
|
||||
"400 Bad Request", "invalid target_type parameter",
|
||||
self.POST,
|
||||
self.public_url + "/foo", t="move",
|
||||
target_type="*D", from_name="bar.txt",
|
||||
to_dir="sub")
|
||||
return d
|
||||
|
||||
def test_POST_move_file_multi_level(self):
|
||||
@ -3364,21 +3369,17 @@ class Web(WebMixin, WebErrorMixin, testutil.StallMixin, testutil.ReallyEqualMixi
|
||||
return d
|
||||
|
||||
def test_POST_move_file_to_nonexist_dir(self):
|
||||
d = self.POST(self.public_url + "/foo", t="move",
|
||||
from_name="bar.txt", to_dir="notchucktesta")
|
||||
d.addBoth(self.shouldFail, error.Error,
|
||||
"POST_move_file_to_nonexist_dir",
|
||||
"404 Not Found",
|
||||
"No such child: notchucktesta")
|
||||
d = self.shouldFail2(error.Error, "POST_move_file_to_nonexist_dir",
|
||||
"404 Not Found", "No such child: nopechucktesta",
|
||||
self.POST, self.public_url + "/foo", t="move",
|
||||
from_name="bar.txt", to_dir="nopechucktesta")
|
||||
return d
|
||||
|
||||
def test_POST_move_file_into_file(self):
|
||||
d = self.POST(self.public_url + "/foo", t="move",
|
||||
from_name="bar.txt", to_dir="baz.txt")
|
||||
d.addBoth(self.shouldFail, error.Error,
|
||||
"POST_move_file_into_file",
|
||||
"410 Gone",
|
||||
"to_dir is not a usable directory")
|
||||
d = self.shouldFail2(error.Error, "POST_move_file_into_file",
|
||||
"400 Bad Request", "to_dir is not a directory",
|
||||
self.POST, self.public_url + "/foo", t="move",
|
||||
from_name="bar.txt", to_dir="baz.txt")
|
||||
d.addCallback(lambda res: self.GET(self.public_url + "/foo/baz.txt"))
|
||||
d.addCallback(self.failUnlessIsBazDotTxt)
|
||||
d.addCallback(lambda res: self.GET(self.public_url + "/foo/bar.txt"))
|
||||
@ -3388,13 +3389,11 @@ class Web(WebMixin, WebErrorMixin, testutil.StallMixin, testutil.ReallyEqualMixi
|
||||
return d
|
||||
|
||||
def test_POST_move_file_to_bad_uri(self):
|
||||
d = self.POST(self.public_url + "/foo", t="move",
|
||||
from_name="bar.txt", target_type="uri",
|
||||
to_dir="URI:DIR2:mn5jlyjnrjeuydyswlzyui72i:rmneifcj6k6sycjljjhj3f6majsq2zqffydnnul5hfa4j577arma")
|
||||
d.addBoth(self.shouldFail, error.Error,
|
||||
"POST_move_file_to_bad_uri",
|
||||
"410 Gone",
|
||||
"to_dir is not a usable directory")
|
||||
d = self.shouldFail2(error.Error, "POST_move_file_to_bad_uri",
|
||||
"400 Bad Request", "to_dir is not a directory",
|
||||
self.POST, self.public_url + "/foo", t="move",
|
||||
from_name="bar.txt", target_type="uri",
|
||||
to_dir="URI:DIR2:mn5jlyjnrjeuydyswlzyui72i:rmneifcj6k6sycjljjhj3f6majsq2zqffydnnul5hfa4j577arma")
|
||||
d.addCallback(lambda res: self.GET(self.public_url + "/foo/bar.txt"))
|
||||
d.addCallback(self.failUnlessIsBarDotTxt)
|
||||
d.addCallback(lambda res: self.GET(self.public_url + "/foo/bar.txt?t=json"))
|
||||
|
@ -444,34 +444,33 @@ class DirectoryNodeHandler(RenderMixin, rend.Page, ReplaceMeMixin):
|
||||
if not from_name or not to_dir:
|
||||
raise WebError("move requires from_name and to_dir")
|
||||
replace = boolean_of_arg(get_arg(req, "replace", "true"))
|
||||
target_type = get_arg(req, "target_type", "name")
|
||||
if not target_type in ["name", "uri"]:
|
||||
raise WebError("invalid target_type parameter",
|
||||
http.BAD_REQUEST)
|
||||
|
||||
# allow from_name to contain slashes, so they can fix names that
|
||||
# were accidentally created with them. But disallow them in to_name
|
||||
# (if it's specified), to discourage the practice.
|
||||
if to_name and "/" in to_name:
|
||||
# Disallow slashes in both from_name and to_name, that would only
|
||||
# cause confusion. t=move is only for moving things from the
|
||||
# *current* directory into a second directory named by to_dir=
|
||||
if "/" in from_name:
|
||||
raise WebError("from_name= may not contain a slash",
|
||||
http.BAD_REQUEST)
|
||||
if "/" in to_name:
|
||||
raise WebError("to_name= may not contain a slash",
|
||||
http.BAD_REQUEST)
|
||||
|
||||
d = defer.Deferred()
|
||||
def get_target_node(target_type):
|
||||
if target_type == "name":
|
||||
return self.node.get_child_at_path(to_dir)
|
||||
elif target_type == "uri":
|
||||
return self.client.create_node_from_uri(str(to_dir))
|
||||
d.addCallback(get_target_node)
|
||||
d.callback(target_type)
|
||||
target_type = get_arg(req, "target_type", "name")
|
||||
if target_type == "name":
|
||||
d = self.node.get_child_at_path(to_dir)
|
||||
elif target_type == "uri":
|
||||
d = defer.succeed(self.client.create_node_from_uri(str(to_dir)))
|
||||
else:
|
||||
raise WebError("invalid target_type parameter", http.BAD_REQUEST)
|
||||
|
||||
def is_target_node_usable(target_node):
|
||||
if not IDirectoryNode.providedBy(target_node):
|
||||
raise WebError("to_dir is not a usable directory",
|
||||
http.GONE)
|
||||
raise WebError("to_dir is not a directory", http.BAD_REQUEST)
|
||||
return target_node
|
||||
d.addCallback(is_target_node_usable)
|
||||
d.addCallback(lambda new_parent: self.node.move_child_to(
|
||||
from_name, new_parent, to_name, replace))
|
||||
d.addCallback(lambda new_parent:
|
||||
self.node.move_child_to(from_name, new_parent,
|
||||
to_name, replace))
|
||||
d.addCallback(lambda res: "thing moved")
|
||||
return d
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user