"409 Conflict",
"There was already a child by that name, and you asked me "
"to not replace it")
+ def _check(res):
+ self.failUnless("sub" in self._foo_node.children)
+ newdir_uri = self._foo_node.children["sub"]
+ newdir_node = self.nodes[newdir_uri]
+ self.failUnlessEqual(newdir_node.children.keys(), ["baz.txt"])
+ d.addCallback(_check)
return d
def test_PUT_NEWDIRURL_mkdirs(self):
d.addCallback(_check)
return d
+ def test_POST_upload_replace(self):
+ d = self.POST("/vdrive/global/foo", t="upload",
+ file=("bar.txt", self.NEWFILE_CONTENTS))
+ def _check(res):
+ self.failUnless("bar.txt" in self._foo_node.children)
+ new_uri = self._foo_node.children["bar.txt"]
+ new_contents = self.files[new_uri]
+ self.failUnlessEqual(new_contents, self.NEWFILE_CONTENTS)
+ self.failUnlessEqual(res.strip(), new_uri)
+ d.addCallback(_check)
+ return d
+
+ def test_POST_upload_no_replace_queryarg(self):
+ d = self.POST("/vdrive/global/foo?replace=false", t="upload",
+ file=("bar.txt", self.NEWFILE_CONTENTS))
+ d.addBoth(self.shouldFail, error.Error,
+ "POST_upload_no_replace_queryarg",
+ "409 Conflict",
+ "There was already a child by that name, and you asked me "
+ "to not replace it")
+ d.addCallback(lambda res: self.GET("/vdrive/global/foo/bar.txt"))
+ d.addCallback(self.failUnlessIsBarDotTxt)
+ return d
+
+ def test_POST_upload_no_replace_field(self):
+ d = self.POST("/vdrive/global/foo", t="upload", replace="false",
+ file=("bar.txt", self.NEWFILE_CONTENTS))
+ d.addBoth(self.shouldFail, error.Error, "POST_upload_no_replace_field",
+ "409 Conflict",
+ "There was already a child by that name, and you asked me "
+ "to not replace it")
+ d.addCallback(lambda res: self.GET("/vdrive/global/foo/bar.txt"))
+ d.addCallback(self.failUnlessIsBarDotTxt)
+ return d
+
def test_POST_upload_whendone(self):
d = self.POST("/vdrive/global/foo", t="upload", when_done="/THERE",
file=("new.txt", self.NEWFILE_CONTENTS))
d.addCallback(_check)
return d
+ def test_POST_mkdir_replace(self): # return value?
+ d = self.POST("/vdrive/global/foo", t="mkdir", name="sub")
+ def _check(res):
+ self.failUnless("sub" in self._foo_node.children)
+ newdir_uri = self._foo_node.children["sub"]
+ newdir_node = self.nodes[newdir_uri]
+ self.failIf(newdir_node.children)
+ d.addCallback(_check)
+ return d
+
+ def test_POST_mkdir_no_replace_queryarg(self): # return value?
+ d = self.POST("/vdrive/global/foo?replace=false", t="mkdir", name="sub")
+ d.addBoth(self.shouldFail, error.Error,
+ "POST_mkdir_no_replace_queryarg",
+ "409 Conflict",
+ "There was already a child by that name, and you asked me "
+ "to not replace it")
+ def _check(res):
+ self.failUnless("sub" in self._foo_node.children)
+ newdir_uri = self._foo_node.children["sub"]
+ newdir_node = self.nodes[newdir_uri]
+ self.failUnlessEqual(newdir_node.children.keys(), ["baz.txt"])
+ d.addCallback(_check)
+ return d
+
+ def test_POST_mkdir_no_replace_field(self): # return value?
+ d = self.POST("/vdrive/global/foo", t="mkdir", name="sub",
+ replace="false")
+ d.addBoth(self.shouldFail, error.Error, "POST_mkdir_no_replace_field",
+ "409 Conflict",
+ "There was already a child by that name, and you asked me "
+ "to not replace it")
+ def _check(res):
+ self.failUnless("sub" in self._foo_node.children)
+ newdir_uri = self._foo_node.children["sub"]
+ newdir_node = self.nodes[newdir_uri]
+ self.failUnlessEqual(newdir_node.children.keys(), ["baz.txt"])
+ d.addCallback(_check)
+ return d
+
def test_POST_mkdir_whendone_field(self):
d = self.POST("/vdrive/global/foo",
t="mkdir", name="newdir", when_done="/THERE")
d.addCallback(_check)
return d
+ def test_POST_put_uri_replace(self):
+ newuri = self.makefile(8)
+ contents = self.files[newuri]
+ d = self.POST("/vdrive/global/foo", t="uri", name="bar.txt", uri=newuri)
+ def _check(res):
+ self.failUnless("bar.txt" in self._foo_node.children)
+ new_uri = self._foo_node.children["bar.txt"]
+ new_contents = self.files[new_uri]
+ self.failUnlessEqual(new_contents, contents)
+ self.failUnlessEqual(res.strip(), new_uri)
+ d.addCallback(_check)
+ return d
+
+ def test_POST_put_uri_no_replace_queryarg(self):
+ newuri = self.makefile(8)
+ contents = self.files[newuri]
+ d = self.POST("/vdrive/global/foo?replace=false", t="uri",
+ name="bar.txt", uri=newuri)
+ d.addBoth(self.shouldFail, error.Error,
+ "POST_put_uri_no_replace_queryarg",
+ "409 Conflict",
+ "There was already a child by that name, and you asked me "
+ "to not replace it")
+ d.addCallback(lambda res: self.GET("/vdrive/global/foo/bar.txt"))
+ d.addCallback(self.failUnlessIsBarDotTxt)
+ return d
+
+ def test_POST_put_uri_no_replace_field(self):
+ newuri = self.makefile(8)
+ contents = self.files[newuri]
+ d = self.POST("/vdrive/global/foo", t="uri", replace="false",
+ name="bar.txt", uri=newuri)
+ d.addBoth(self.shouldFail, error.Error,
+ "POST_put_uri_no_replace_field",
+ "409 Conflict",
+ "There was already a child by that name, and you asked me "
+ "to not replace it")
+ d.addCallback(lambda res: self.GET("/vdrive/global/foo/bar.txt"))
+ d.addCallback(self.failUnlessIsBarDotTxt)
+ return d
+
def test_POST_delete(self):
d = self.POST("/vdrive/global/foo", t="delete", name="bar.txt")
def _check(res):
d.addCallback(self.failUnlessIsBarJSON)
return d
+ def test_POST_rename_file_replace(self):
+ # rename a file and replace a directory with it
+ d = self.POST("/vdrive/global/foo", t="rename",
+ from_name="bar.txt", to_name='empty')
+ def _check(res):
+ self.failIf("bar.txt" in self._foo_node.children)
+ self.failUnless("empty" in self._foo_node.children)
+ d.addCallback(_check)
+ d.addCallback(lambda res: self.GET("/vdrive/global/foo/empty"))
+ d.addCallback(self.failUnlessIsBarDotTxt)
+ d.addCallback(lambda res: self.GET("/vdrive/global/foo/empty?t=json"))
+ d.addCallback(self.failUnlessIsBarJSON)
+ return d
+
+ def test_POST_rename_file_no_replace_queryarg(self):
+ # rename a file and replace a directory with it
+ d = self.POST("/vdrive/global/foo?replace=false", t="rename",
+ from_name="bar.txt", to_name='empty')
+ d.addBoth(self.shouldFail, error.Error,
+ "POST_rename_file_no_replace_queryarg",
+ "409 Conflict",
+ "There was already a child by that name, and you asked me "
+ "to not replace it")
+ d.addCallback(lambda res: self.GET("/vdrive/global/foo/empty?t=json"))
+ d.addCallback(self.failUnlessIsEmptyJSON)
+ return d
+
+ def test_POST_rename_file_no_replace_field(self):
+ # rename a file and replace a directory with it
+ d = self.POST("/vdrive/global/foo", t="rename", replace="false",
+ from_name="bar.txt", to_name='empty')
+ d.addBoth(self.shouldFail, error.Error,
+ "POST_rename_file_no_replace_field",
+ "409 Conflict",
+ "There was already a child by that name, and you asked me "
+ "to not replace it")
+ d.addCallback(lambda res: self.GET("/vdrive/global/foo/empty?t=json"))
+ d.addCallback(self.failUnlessIsEmptyJSON)
+ return d
+
+ def failUnlessIsEmptyJSON(self, res):
+ data = self.worlds_cheapest_json_decoder(res)
+ self.failUnlessEqual(data[0], "dirnode")
+ self.failUnlessEqual(len(data[1]["children"]), 0)
+
def test_POST_rename_file_slash_fail(self):
d = self.POST("/vdrive/global/foo", t="rename",
from_name="bar.txt", to_name='kirk/spock.txt')
self._node = node
self._replace = replace
+ def _check_replacement(self, name):
+ if self._replace:
+ return defer.succeed(None)
+ d = self._node.has_child(name)
+ def _got(present):
+ if present:
+ raise NoReplacementError("There was already a child by that "
+ "name, and you asked me to not "
+ "replace it.")
+ return None
+ d.addCallback(_got)
+ return d
+
def renderHTTP(self, ctx):
req = inevow.IRequest(ctx)
if "when_done" in req.fields:
when_done = req.fields["when_done"].value
+ if "replace" in req.fields:
+ if req.fields["replace"].value.lower() in ("false", "0"):
+ self._replace = False
+
if t == "mkdir":
if not name:
raise RuntimeError("mkdir requires a name")
- d = self._node.create_empty_directory(name)
+ d = self._check_replacement(name)
+ d.addCallback(lambda res: self._node.create_empty_directory(name))
def _done(res):
return "directory created"
d.addCallback(_done)
newuri = req.args["uri"][0]
else:
newuri = req.fields["uri"].value
- d = self._node.set_uri(name, newuri)
+ d = self._check_replacement(name)
+ d.addCallback(lambda res: self._node.set_uri(name, newuri))
def _done(res):
return newuri
d.addCallback(_done)
req.setResponseCode(http.BAD_REQUEST)
req.setHeader("content-type", "text/plain")
return "%s= may not contain a slash" % (k,)
- d = self._node.get(from_name)
+ d = self._check_replacement(to_name)
+ d.addCallback(lambda res: self._node.get(from_name))
def add_dest(child):
uri = child.get_uri()
# now actually do the rename
contents = req.fields["file"]
name = name or contents.filename
uploadable = upload.FileHandle(contents.file)
- d = self._node.add_file(name, uploadable)
+ d = self._check_replacement(name)
+ d.addCallback(lambda res: self._node.add_file(name, uploadable))
def _done(newnode):
return newnode.get_uri()
d.addCallback(_done)
return "BAD t=%s" % t
if when_done:
d.addCallback(lambda res: url.URL.fromString(when_done))
+ def _check_replacement(f):
+ # TODO: make this more human-friendly: maybe send them to the
+ # when_done page but with an extra query-arg that will display
+ # the error message in a big box at the top of the page. The
+ # directory page that when_done= usually points to accepts a
+ # result= argument.. use that.
+ f.trap(NoReplacementError)
+ req.setResponseCode(http.CONFLICT)
+ req.setHeader("content-type", "text/plain")
+ return str(f.value)
+ d.addErrback(_check_replacement)
return d
class DELETEHandler(rend.Page):
# TODO: think about clobbering/revealing config files and node secrets
replace = True
-# if "replace" in req.fields:
-# if req.fields["replace"].value.lower() in ("false", "0"):
-# replace = False
if "replace" in req.args:
if req.args["replace"][0].lower() in ("false", "0"):
replace = False