def test_resource_op_acls(self):
        from girder.plugins.virtual_resources.rest import VirtualObject

        root_path = pathlib.Path(self.public_folder["fsPath"])
        nested_dir = root_path / "level0"
        nested_dir.mkdir(parents=True)

        file1 = root_path / "some_file.txt"
        file1_contents = b"Blah Blah Blah"
        with file1.open(mode="wb") as fp:
            fp.write(file1_contents)

        sallys_root_path = pathlib.Path(self.private_folder["fsPath"])
        # MOVE
        move_target_dir = sallys_root_path / "moved"
        move_target_dir.mkdir()
        resources = {
            "item": [
                VirtualObject.generate_id(file1.as_posix(),
                                          self.public_folder["_id"])
            ],
            "folder": [
                VirtualObject.generate_id(nested_dir.as_posix(),
                                          self.public_folder["_id"])
            ],
        }
        parentId = VirtualObject.generate_id(move_target_dir.as_posix(),
                                             self.private_folder["_id"])
        resp = self.request(
            path="/resource/move",
            method="PUT",
            user=self.users["sally"],
            params={
                "parentType": "folder",
                "parentId": parentId,
                "resources": json.dumps(resources),
            },
        )
        self.assertStatusOk(resp)
        self.assertTrue(nested_dir.exists())
        self.assertTrue(file1.exists())
        self.assertEqual(len(list(move_target_dir.iterdir())), 0)

        # COPY cors
        resp = self.request(
            path="/resource/copy",
            method="POST",
            user=self.users["sally"],
            params={
                "parentType": "folder",
                "parentId": parentId,
                "resources": json.dumps(resources),
            },
        )
        self.assertStatusOk(resp)
        self.assertTrue((move_target_dir / nested_dir.name).is_dir())
        self.assertTrue((move_target_dir / file1.name).is_file())
    def test_path(self):
        from girder.plugins.virtual_resources.rest import VirtualObject

        root_path = pathlib.Path(self.private_folder["fsPath"])
        nested_dir = root_path / "directory"
        nested_dir.mkdir(parents=True)
        file1 = nested_dir / "file.txt"
        file1_contents = b"Blah Blah Blah"
        with file1.open(mode="wb") as fp:
            fp.write(file1_contents)

        item_id = VirtualObject.generate_id(file1.as_posix(),
                                            self.private_folder["_id"])
        folder_id = VirtualObject.generate_id(nested_dir.as_posix(),
                                              self.private_folder["_id"])

        resp = self.request(
            path="/resource/{}/path".format(item_id),
            method="GET",
            user=self.users["admin"],
            params={"type": "item"},
        )
        self.assertStatusOk(resp)
        self.assertEqual(
            resp.json,
            "/collection/Virtual Resources/private/directory/file.txt")

        resp = self.request(
            path="/resource/{}/path".format(folder_id),
            method="GET",
            user=self.users["admin"],
            params={"type": "folder"},
        )
        self.assertStatusOk(resp)
        self.assertEqual(resp.json,
                         "/collection/Virtual Resources/private/directory")

        for res_id, res_type in (
            (item_id, "folder"),
            (folder_id, "item"),
            (item_id, "collection"),
        ):
            resp = self.request(
                path="/resource/{}/path".format(res_id),
                method="GET",
                user=self.users["admin"],
                params={"type": res_type},
                exception=True,
            )
            self.assertStatus(resp, 400)
            self.assertEqual(resp.json["message"], "Invalid resource id.")

        file1.unlink()
        nested_dir.rmdir()
    def test_move_acls(self):
        from girder.plugins.virtual_resources.rest import VirtualObject

        root_path = pathlib.Path(self.private_folder["fsPath"])
        dir1 = root_path / "some_dir"
        dir1.mkdir()

        folder_id = VirtualObject.generate_id(dir1, self.private_folder["_id"])

        resp = self.request(
            path="/folder/{}".format(folder_id),
            method="PUT",
            user=self.users["joel"],
            params={
                "parentId": self.private_folder2["_id"],
                "parentType": "folder"
            },
        )
        self.assertStatus(resp, 403)

        resp = self.request(
            path="/folder/{}".format(folder_id),
            method="PUT",
            user=self.users["sally"],
            params={
                "parentId": self.private_folder2["_id"],
                "parentType": "folder"
            },
        )
        self.assertStatusOk(resp)

        self.assertFalse(dir1.exists())
        root_path = pathlib.Path(self.private_folder2["fsPath"])
        dir1 = root_path / "some_dir"
        self.assertTrue(dir1.exists())
        folder_id = VirtualObject.generate_id(dir1,
                                              self.private_folder2["_id"])

        resp = self.request(
            path="/folder/{}".format(folder_id),
            method="PUT",
            user=self.users["joel"],
            params={
                "parentId": self.private_folder["_id"],
                "parentType": "folder"
            },
        )
        self.assertStatus(resp, 403)

        dir1.rmdir()
    def test_folder_move(self):
        from girder.plugins.virtual_resources.rest import VirtualObject

        root_path = pathlib.Path(self.public_folder["fsPath"])
        dir1 = root_path / "some_dir"
        dir1.mkdir()
        file1 = dir1 / "some_file"
        with file1.open(mode="wb") as fp:
            fp.write(b"\n")

        folder_id = VirtualObject.generate_id(dir1, self.public_folder["_id"])

        resp = self.request(
            path="/folder/{}".format(folder_id),
            method="PUT",
            user=self.users["admin"],
            params={"name": dir1.name},
            exception=True,
        )
        self.assertStatus(resp, 500)
        self.assertEqual(
            resp.json["message"],
            "Folder '{}' already exists in {}".format(
                dir1.name, self.public_folder["_id"]),
        )

        new_root_path = pathlib.Path(self.private_folder["fsPath"])
        dir2 = new_root_path / "level1"
        dir2.mkdir()
        new_folder_id = VirtualObject.generate_id(dir2,
                                                  self.private_folder["_id"])

        resp = self.request(
            path="/folder/{}".format(folder_id),
            method="PUT",
            user=self.users["admin"],
            params={
                "parentId": new_folder_id,
                "parentType": "folder"
            },
        )
        self.assertStatusOk(resp)
        self.assertFalse(dir1.exists())
        self.assertTrue((dir2 / dir1.name).exists())
        new_file = dir2 / dir1.name / file1.name
        self.assertTrue(new_file.exists())
        new_file.unlink()
        (dir2 / dir1.name).rmdir()
        dir2.rmdir()
    def test_move_to_root(self):
        from girder.plugins.virtual_resources.rest import VirtualObject

        root_path = pathlib.Path(self.public_folder["fsPath"])
        dir1 = root_path / "some_dir"
        dir1.mkdir()
        file1 = dir1 / "some_file"
        with file1.open(mode="wb") as fp:
            fp.write(b"\n")
        folder_id = VirtualObject.generate_id(dir1, self.public_folder["_id"])

        resp = self.request(
            path="/folder/{}".format(folder_id),
            method="PUT",
            user=self.users["admin"],
            params={
                "parentId": self.private_folder["_id"],
                "parentType": "folder"
            },
        )
        self.assertStatusOk(resp)
        self.assertFalse(dir1.exists())

        root_path = pathlib.Path(self.private_folder["fsPath"])
        dir1 = root_path / "some_dir"
        file1 = dir1 / "some_file"
        self.assertTrue(dir1.exists())
        self.assertTrue(file1.exists())
        file1.unlink()
        dir1.rmdir()
    def test_folder_delete_contents(self):
        from girder.plugins.virtual_resources.rest import VirtualObject

        root_path = pathlib.Path(self.public_folder["fsPath"])
        nested_dir = root_path / "lone_survivor"
        nested_dir.mkdir(parents=True)
        folder_id = VirtualObject.generate_id(nested_dir,
                                              self.public_folder["_id"])

        dir1 = nested_dir / "subfolder"
        dir1.mkdir()
        file1 = dir1 / "some_file.txt"
        with file1.open(mode="wb") as fp:
            fp.write(b"file1\n")
        file2 = nested_dir / "other_file.txt"
        with file2.open(mode="wb") as fp:
            fp.write(b"file2\n")
        self.assertEqual(len(list(nested_dir.iterdir())), 2)

        resp = self.request(
            path="/folder/{}/contents".format(folder_id),
            method="DELETE",
            user=self.users["admin"],
        )
        self.assertStatusOk(resp)
        self.assertEqual(len(list(nested_dir.iterdir())), 0)
        nested_dir.rmdir()
    def test_item_rootpath(self):
        from girder.plugins.virtual_resources.rest import VirtualObject

        root_path = pathlib.Path(self.public_folder["fsPath"])
        nested_dir = root_path / "level0" / "level1"
        nested_dir.mkdir(parents=True)

        file1 = nested_dir / "some_file"
        file_contents = b"hello world\n"
        with file1.open(mode="wb") as fp:
            fp.write(file_contents)

        item_id = VirtualObject.generate_id(file1, self.public_folder["_id"])
        resp = self.request(
            path="/item/{}/rootpath".format(item_id),
            method="GET",
            user=self.users["admin"],
        )
        self.assertStatusOk(resp)
        self.assertEqual(len(resp.json), 4)
        rootpath = resp.json
        self.assertEqual(rootpath[0]["type"], "collection")
        self.assertEqual(rootpath[0]["object"]["_id"],
                         str(self.base_collection["_id"]))
        self.assertEqual(rootpath[1]["type"], "folder")
        self.assertEqual(rootpath[1]["object"]["_id"],
                         str(self.public_folder["_id"]))
        self.assertEqual(rootpath[2]["type"], "folder")
        self.assertEqual(rootpath[2]["object"]["name"], "level0")
        self.assertEqual(rootpath[3]["type"], "folder")
        self.assertEqual(rootpath[3]["object"]["name"], "level1")

        shutil.rmtree((root_path / "level0").as_posix())
    def test_folder_download(self):
        from girder.plugins.virtual_resources.rest import VirtualObject

        root_path = pathlib.Path(self.public_folder["fsPath"])
        nested_dir = root_path / "lone_survivor"
        nested_dir.mkdir(parents=True)
        folder_id = VirtualObject.generate_id(nested_dir,
                                              self.public_folder["_id"])

        dir1 = nested_dir / "subfolder"
        dir1.mkdir()
        file1 = dir1 / "some_file.txt"
        with file1.open(mode="wb") as fp:
            fp.write(b"file1\n")
        file2 = nested_dir / "other_file.txt"
        with file2.open(mode="wb") as fp:
            fp.write(b"file2\n")
        self.assertEqual(len(list(nested_dir.iterdir())), 2)

        resp = self.request(
            path="/folder/{}/download".format(folder_id),
            method="GET",
            user=self.users["admin"],
            isJson=False,
        )
        self.assertStatusOk(resp)
        with zipfile.ZipFile(io.BytesIO(self.getBody(resp, text=False)),
                             "r") as fp:
            self.assertEqual(sorted(fp.namelist()),
                             ["other_file.txt", "subfolder/some_file.txt"])
    def test_copy_existing_name(self):
        from girder.plugins.virtual_resources.rest import VirtualObject

        root_path = pathlib.Path(self.private_folder["fsPath"])
        file1 = root_path / "existing.txt"
        file1_contents = b"Blah Blah Blah"
        with file1.open(mode="wb") as fp:
            fp.write(file1_contents)

        resources = {
            "item": [
                VirtualObject.generate_id(file1.as_posix(),
                                          self.private_folder["_id"])
            ]
        }
        resp = self.request(
            path="/resource/copy",
            method="POST",
            user=self.users["admin"],
            params={
                "parentType": "folder",
                "parentId": self.private_folder["_id"],
                "resources": json.dumps(resources),
            },
        )
        self.assertStatusOk(resp)
        self.assertTrue((root_path / "existing.txt (1)").is_file())
        file1.unlink()
        (root_path / "existing.txt (1)").unlink()
    def test_folder_rootpath(self):
        from girder.plugins.virtual_resources.rest import VirtualObject

        root_path = pathlib.Path(self.public_folder["fsPath"])
        nested_dir = root_path / "level0" / "level1" / "level2"
        nested_dir.mkdir(parents=True)

        folder_id = VirtualObject.generate_id(nested_dir,
                                              self.public_folder["_id"])
        resp = self.request(
            path="/folder/{}/rootpath".format(folder_id),
            method="GET",
            user=self.users["admin"],
        )
        self.assertStatusOk(resp)
        self.assertEqual(len(resp.json), 4)
        rootpath = resp.json
        self.assertEqual(rootpath[0]["type"], "collection")
        self.assertEqual(rootpath[0]["object"]["_id"],
                         str(self.base_collection["_id"]))
        self.assertEqual(rootpath[1]["type"], "folder")
        self.assertEqual(rootpath[1]["object"]["_id"],
                         str(self.public_folder["_id"]))
        self.assertEqual(rootpath[2]["type"], "folder")
        self.assertEqual(rootpath[2]["object"]["name"], "level0")
        self.assertEqual(rootpath[3]["type"], "folder")
        self.assertEqual(rootpath[3]["object"]["name"], "level1")

        shutil.rmtree((root_path / "level0").as_posix())
    def test_copy_existing_name(self):
        from girder.plugins.virtual_resources.rest import VirtualObject

        root_path = pathlib.Path(self.private_folder["fsPath"])
        file1 = root_path / "existing.txt"
        file1_contents = b"Blah Blah Blah"
        with file1.open(mode="wb") as fp:
            fp.write(file1_contents)
        item_id = VirtualObject.generate_id(file1, self.private_folder["_id"])

        resp = self.request(
            path="/item/{}/copy".format(item_id),
            method="POST",
            user=self.users["admin"],
            params={},
        )
        self.assertStatusOk(resp)
        self.assertEqual(resp.json["name"], "existing.txt (1)")

        item = resp.json
        resp = self.request(
            path="/item",
            method="POST",
            user=self.users["admin"],
            params={
                "folderId": item["folderId"],
                "name": item["name"]
            },
        )
        self.assertStatus(resp, 400)
        folder = resp.json
        self.assertEqual(
            folder,
            {
                "type": "validation",
                "message": "An item with that name already exists here.",
                "field": "name",
            },
        )

        self.assertTrue((root_path / "existing.txt (1)").is_file())
        file1.unlink()
        (root_path / "existing.txt (1)").unlink()
Exemple #12
0
    def test_upload_odd_cases(self):
        from girder.plugins.virtual_resources.rest import VirtualObject as vo

        # Change dest perms to ro
        dest_dir = pathlib.Path(self.private_folder["fsPath"])
        dest_dir.chmod(0o551)
        resp = self.request(
            path="/file",
            method="POST",
            user=self.users["sally"],
            params={
                "parentType": "folder",
                "parentId": self.private_folder["_id"],
                "name": "empty_file.txt",
                "size": "0",
                "mimeType": "text/plain",
            },
            exception=True,
        )
        self.assertStatus(resp, 500)
        self.assertEqual(
            resp.json["message"],
            "Insufficient perms to write on {}".format(self.private_folder["fsPath"]),
        )

        dest_dir.chmod(0o751)
        (dest_dir / "empty_file.txt").mkdir()
        resp = self.request(
            path="/file",
            method="POST",
            user=self.users["sally"],
            params={
                "parentType": "folder",
                "parentId": self.private_folder["_id"],
                "name": "empty_file.txt",
                "size": "0",
                "mimeType": "text/plain",
            },
            exception=True,
        )
        self.assertStatus(resp, 500)
        self.assertEqual(
            resp.json["message"],
            "IsADirectoryError: IsADirectoryError(21, 'Is a directory')",
        )
        (dest_dir / "empty_file.txt").rmdir()

        resp = self.request(
            path="/file",
            method="POST",
            user=self.users["sally"],
            params={
                "parentType": "folder",
                "parentId": self.private_folder["_id"],
                "name": "empty_file.txt",
                "size": 0,
                "mimeType": "text/plain",
            },
        )
        self.assertStatusOk(resp)

        resp = self.request(
            path="/file",
            method="POST",
            user=self.users["sally"],
            params={
                "parentType": "folder",
                "parentId": self.private_folder["_id"],
                "name": "blah_file.txt",
                "size": len(chunk1),
                "mimeType": "text/plain",
            },
        )
        self.assertStatusOk(resp)
        upload = resp.json

        (dest_dir / "blah_file.txt").unlink()
        dest_dir.chmod(0o551)
        resp = self.request(
            path="/file/chunk",
            method="POST",
            user=self.users["sally"],
            params={"uploadId": upload["_id"], "offset": 0},
            type="text/plain",
            body=chunk1,
            exception=True,
        )
        self.assertStatus(resp, 500)
        self.assertEqual(
            resp.json["message"], "Exception: Exception('Failed to store upload.')",
        )
        dest_dir.chmod(0o775)

        resp = self.request(
            path="/file",
            method="POST",
            user=self.users["sally"],
            params={
                "parentType": "folder",
                "parentId": self.private_folder["_id"],
                "name": "full_body.txt",
                "size": len(chunk1),
                "mimeType": "text/plain",
            },
            type="text/plain",
            body=chunk1,
        )
        self.assertStatusOk(resp)
        fobj = resp.json
        self.assertEqual(fobj["size"], len(chunk1))
        self.assertEqual(fobj["_modelType"], "file")

        dest_dir = pathlib.Path(self.private_folder["fsPath"]) / "some_dir"
        dest_dir.mkdir()
        resp = self.request(
            path="/file",
            method="POST",
            user=self.users["sally"],
            params={
                "parentType": "folder",
                "parentId": vo.generate_id(
                    dest_dir.as_posix(), self.private_folder["_id"]
                ),
                "name": "full_body.txt",
                "size": len(chunk1),
                "mimeType": "text/plain",
            },
            type="text/plain",
            body=chunk1,
        )
        self.assertStatusOk(resp)
        fobj = resp.json
        self.assertEqual(fobj["size"], len(chunk1))
        self.assertTrue((dest_dir / fobj["name"]).is_file())
Exemple #13
0
    def test_basic_file_ops(self):
        from girder.plugins.virtual_resources.rest import VirtualObject as vo

        root_path = pathlib.Path(self.public_folder["fsPath"])
        dir1 = root_path / "some_dir"
        dir1.mkdir()
        file1 = dir1 / "some_file"
        file_contents = b"hello world\n"
        with file1.open(mode="wb") as fp:
            fp.write(file_contents)

        resp = self.request(
            path="/file/{}".format(
                vo.generate_id(file1.as_posix(), self.public_folder["_id"])
            ),
            method="GET",
            user=self.users["sally"],
        )
        self.assertStatusOk(resp)
        fobj = resp.json
        self.assertEqual(fobj["name"], "some_file")
        self.assertEqual(int(fobj["size"]), file1.stat().st_size)

        resp = self.request(
            path="/file/{_id}".format(**fobj),
            method="PUT",
            user=self.users["joel"],
            params={"name": "new_name"},
        )
        self.assertStatus(resp, 403)

        resp = self.request(
            path="/file/{_id}".format(**fobj),
            method="PUT",
            user=self.users["sally"],
            params={"name": "new_name"},
        )
        self.assertStatusOk(resp)
        fobj = resp.json

        self.assertFalse(file1.exists())
        file1 = file1.with_name(fobj["name"])
        self.assertTrue(file1.exists() and file1.is_file())

        resp = self.request(
            path="/file/{_id}/download".format(**fobj),
            method="GET",
            user=self.users["joel"],
            isJson=False,
        )
        self.assertStatusOk(resp)

        contentDisposition = 'filename="%s"' % fobj["name"]
        self.assertEqual(resp.headers["Content-Type"], "application/octet-stream")
        self.assertEqual(
            resp.headers["Content-Disposition"], "attachment; %s" % contentDisposition
        )
        self.assertEqual(file_contents.decode(), self.getBody(resp))

        # Test downloading the file with contentDisposition=inline.
        params = {"contentDisposition": "inline"}
        resp = self.request(
            path="/file/{_id}/download".format(**fobj),
            method="GET",
            user=self.users["joel"],
            isJson=False,
            params=params,
        )
        self.assertStatusOk(resp)
        self.assertEqual(resp.headers["Content-Type"], "application/octet-stream")
        self.assertEqual(
            resp.headers["Content-Disposition"], "inline; %s" % contentDisposition
        )
        self.assertEqual(file_contents.decode(), self.getBody(resp))

        # Test downloading with an offset
        resp = self.request(
            path="/file/{_id}/download".format(**fobj),
            method="GET",
            user=self.users["joel"],
            isJson=False,
            params={"offset": 1},
        )
        self.assertStatus(resp, 206)
        self.assertEqual(file_contents[1:].decode(), self.getBody(resp))

        # Test downloading with a range header and query range params
        respHeader = self.request(
            path="/file/{_id}/download".format(**fobj),
            method="GET",
            user=self.users["joel"],
            isJson=False,
            additionalHeaders=[("Range", "bytes=2-7")],
        )
        respQuery = self.request(
            path="/file/{_id}/download".format(**fobj),
            method="GET",
            user=self.users["joel"],
            isJson=False,
            params={"offset": 2, "endByte": 8},
        )
        for resp in [respHeader, respQuery]:
            self.assertEqual(file_contents[2:8].decode(), self.getBody(resp))
            self.assertEqual(resp.headers["Accept-Ranges"], "bytes")
            length = len(file_contents)
            begin, end = min(length, 2), min(length, 8)
            self.assertEqual(resp.headers["Content-Length"], end - begin)
            if length:
                self.assertStatus(resp, 206)
                self.assertEqual(
                    resp.headers["Content-Range"],
                    "bytes %d-%d/%d" % (begin, end - 1, length),
                )
            else:
                self.assertStatusOk(resp)

        resp = self.request(
            path="/file/{_id}".format(**fobj),
            method="DELETE",
            user=self.users["sally"],
            isJson=False,
        )
        self.assertStatusOk(resp)
        self.assertFalse(file1.exists())
    def test_basic_ops(self):
        from girder.plugins.virtual_resources.rest import VirtualObject

        root_path = pathlib.Path(self.public_folder["fsPath"])
        nested_dir = root_path / "level0"
        nested_dir.mkdir(parents=True)

        file1 = root_path / "some_file.txt"
        file1_contents = b"Blah Blah Blah"
        with file1.open(mode="wb") as fp:
            fp.write(file1_contents)

        file2 = nested_dir / "some_other_file.txt"
        file2_contents = b"Lorem ipsum..."
        with file2.open(mode="wb") as fp:
            fp.write(file2_contents)

        # COPY
        copy_target_dir = root_path / "copy_dest"
        copy_target_dir.mkdir()

        resources = {
            "item": [
                VirtualObject.generate_id(file1.as_posix(),
                                          self.public_folder["_id"])
            ],
            "folder": [
                VirtualObject.generate_id(nested_dir.as_posix(),
                                          self.public_folder["_id"])
            ],
        }

        parentId = VirtualObject.generate_id(copy_target_dir.as_posix(),
                                             self.public_folder["_id"])

        resp = self.request(
            path="/resource/copy",
            method="POST",
            user=self.users["admin"],
            params={
                "parentType": "folder",
                "parentId": parentId,
                "resources": json.dumps(resources),
            },
        )
        self.assertStatusOk(resp)

        copied_dir = copy_target_dir / nested_dir.name
        self.assertTrue(copied_dir.is_dir())
        copied_file1 = copy_target_dir / file1.name
        self.assertTrue(copied_file1.is_file())
        with copied_file1.open(mode="rb") as fp:
            self.assertEqual(fp.read(), file1_contents)
        copied_file2 = copied_dir / file2.name
        self.assertTrue(copied_file2.is_file())
        with copied_file2.open(mode="rb") as fp:
            self.assertEqual(fp.read(), file2_contents)

        # MOVE
        move_target_dir = root_path / "moved"
        move_target_dir.mkdir()
        resources = {
            "item": [
                VirtualObject.generate_id(file1.as_posix(),
                                          self.public_folder["_id"]),
                VirtualObject.generate_id(copied_file2.as_posix(),
                                          self.public_folder["_id"]),
            ],
            "folder": [
                VirtualObject.generate_id(copy_target_dir.as_posix(),
                                          self.public_folder["_id"])
            ],
        }
        parentId = VirtualObject.generate_id(move_target_dir.as_posix(),
                                             self.public_folder["_id"])
        resp = self.request(
            path="/resource/move",
            method="PUT",
            user=self.users["admin"],
            params={
                "parentType": "folder",
                "parentId": parentId,
                "resources": json.dumps(resources),
            },
        )
        self.assertStatusOk(resp)
        for resource in (copy_target_dir, file1, copied_file2):
            self.assertFalse(resource.exists())

        moved_dir = move_target_dir / copy_target_dir.name
        moved_file1 = move_target_dir / file1.name
        moved_file2 = move_target_dir / file2.name
        self.assertTrue(moved_dir.is_dir())
        self.assertTrue(moved_file1.is_file())
        self.assertTrue(moved_file2.is_file())

        # DELETE
        regular_folder = Folder().createFolder(
            self.base_collection,
            "public",
            parentType="collection",
            public=True,
            reuseExisting=True,
        )
        with file1.open(mode="wb") as fp:  # Recreate
            fp.write(file1_contents)

        resources = {"item": [], "folder": [str(regular_folder["_id"])]}
        for path in root_path.iterdir():
            if path.is_dir():
                key = "folder"
            else:
                key = "item"
            resources[key].append(
                VirtualObject.generate_id(path.as_posix(),
                                          self.public_folder["_id"]))

        resp = self.request(
            path="/resource",
            method="DELETE",
            user=self.users["admin"],
            params={"resources": json.dumps(resources)},
        )
        self.assertStatusOk(resp)
        self.assertEqual(len(list(root_path.iterdir())), 0)
        regular_folder = Folder().load(regular_folder["_id"], force=True)
        self.assertTrue(regular_folder is None)
    def test_move_item(self):
        from girder.plugins.virtual_resources.rest import VirtualObject

        root_path = pathlib.Path(self.public_folder["fsPath"])
        subdir = root_path / "subdir"
        subdir.mkdir()
        file1 = subdir / "to_be_moved"
        file_contents = b"hello world asdfadsf\n"
        with file1.open(mode="wb") as fp:
            fp.write(file_contents)
        folder_id = VirtualObject.generate_id(subdir,
                                              self.public_folder["_id"])
        item_id = VirtualObject.generate_id(file1, self.public_folder["_id"])

        # Move with the same name (noop)
        resp = self.request(
            path="/item/{}".format(item_id),
            method="PUT",
            user=self.users["admin"],
            params={
                "name": file1.name,
                "folderId": folder_id
            },
        )
        self.assertStatusOk(resp)
        self.assertTrue(file1.exists())

        # Move within the same folder
        resp = self.request(
            path="/item/{}".format(item_id),
            method="PUT",
            user=self.users["admin"],
            params={
                "name": "after_move",
                "folderId": folder_id
            },
        )
        self.assertStatusOk(resp)
        self.assertTrue((subdir / "after_move").exists())
        self.assertFalse(file1.exists())

        # Move to a different folder
        file1 = subdir / "after_move"
        item_id = VirtualObject.generate_id(file1, self.public_folder["_id"])
        resp = self.request(
            path="/item/{}".format(item_id),
            method="PUT",
            user=self.users["admin"],
            params={
                "name": "after_move",
                "folderId": self.private_folder["_id"]
            },
        )
        self.assertStatusOk(resp)
        self.assertFalse(file1.exists())
        root_path = pathlib.Path(self.private_folder["fsPath"])
        file_new = root_path / "after_move"
        item_id = VirtualObject.generate_id(file_new,
                                            self.private_folder["_id"])

        self.assertTrue(file_new.is_file())
        with open(file_new.as_posix(), "rb") as fp:
            self.assertEqual(fp.read(), file_contents)

        # Try to move not into mapping and fail
        resp = self.request(
            path="/item/{}".format(item_id),
            method="PUT",
            user=self.users["sally"],
            params={
                "name": "after_move",
                "folderId": str(self.regular_folder["_id"]),
                "parentType": "folder",
            },
            exception=True,
        )
        self.assertStatus(resp, 500)
        self.assertEqual(
            resp.json["message"],
            "Folder {} is not a mapping.".format(self.regular_folder["_id"]),
        )

        # move it back to subdir in a mapping
        resp = self.request(
            path="/item/{}".format(item_id),
            method="PUT",
            user=self.users["admin"],
            params={
                "name": "final_move",
                "folderId": folder_id
            },
        )
        self.assertStatusOk(resp)
        self.assertFalse(file_new.exists())
        file_new = subdir / "final_move"
        self.assertTrue(file_new.exists())
        file_new.unlink()
    def test_folder_copy(self):
        from girder.plugins.virtual_resources.rest import VirtualObject

        root_path = pathlib.Path(self.public_folder["fsPath"])
        dir1 = root_path / "source_folder"
        dir1.mkdir(parents=True)
        folder_id = VirtualObject.generate_id(dir1, self.public_folder["_id"])
        file1 = dir1 / "file.dat"
        with file1.open(mode="wb") as fp:
            fp.write(b"file1\n")

        resp = self.request(
            path="/folder/{}/copy".format(self.public_folder["_id"]),
            method="POST",
            user=self.users["sally"],
            params={"name": "new_copy"},
            exception=True,
        )
        self.assertStatus(resp, 500)
        self.assertEqual(resp.json["message"],
                         "Copying mappings is not allowed.")

        resp = self.request(
            path="/folder/{}/copy".format(folder_id),
            method="POST",
            user=self.users["joel"],
            params={
                "name": "new_copy",
                "parentId": str(self.regular_folder["_id"]),
                "parentType": "folder",
            },
        )
        self.assertStatus(resp, 403)

        resp = self.request(
            path="/folder/{}/copy".format(folder_id),
            method="POST",
            user=self.users["sally"],
            params={
                "name": "new_copy",
                "parentId": str(self.regular_folder["_id"]),
                "parentType": "folder",
            },
            exception=True,
        )
        self.assertStatus(resp, 500)
        self.assertEqual(
            resp.json["message"],
            "Folder {} is not a mapping.".format(self.regular_folder["_id"]),
        )

        resp = self.request(
            path="/folder/{}/copy".format(folder_id),
            method="POST",
            user=self.users["sally"],
            params={"name": "new_copy"},
        )
        self.assertStatus(resp, 403)
        self.assertFalse((dir1.with_name("new_copy") / file1.name).is_file())

        resp = self.request(
            path="/folder/{}/copy".format(folder_id),
            method="POST",
            user=self.users["admin"],
            params={},
            exception=True,
        )
        self.assertStatus(resp, 200)
        new_folder = resp.json
        self.assertEqual(new_folder["name"], "source_folder (1)")
        self.assertTrue(
            (dir1.with_name("source_folder (1)") / file1.name).is_file())

        resp = self.request(
            path="/folder/{}/copy".format(folder_id),
            method="POST",
            user=self.users["admin"],
            params={"name": "new_copy"},
        )
        self.assertStatusOk(resp)
        new_folder = resp.json
        self.assertEqual(new_folder["name"], "new_copy")
        self.assertTrue((dir1.with_name("new_copy") / file1.name).is_file())

        resp = self.request(
            path="/folder/{}/copy".format(folder_id),
            method="POST",
            user=self.users["admin"],
            params={
                "name": "copy_within_copy",
                "parentId": new_folder["_id"],
                "parentType": "folder",
            },
        )
        self.assertStatusOk(resp)
        self.assertTrue((dir1.with_name("new_copy") / "copy_within_copy" /
                         file1.name).is_file())
    def test_copy_item(self):
        from girder.plugins.virtual_resources.rest import VirtualObject

        root_path = pathlib.Path(self.public_folder["fsPath"])
        file1 = root_path / "some_file"
        file_contents = b"hello world\n"
        with file1.open(mode="wb") as fp:
            fp.write(file_contents)
        item_id = VirtualObject.generate_id(file1, self.public_folder["_id"])

        # Copy in the same folder
        resp = self.request(
            path="/item/{}/copy".format(item_id),
            method="POST",
            user=self.users["admin"],
            params={"name": "copy"},
        )
        self.assertStatusOk(resp)

        self.assertTrue(file1.with_name("copy").is_file())
        with open(file1.with_name("copy").as_posix(), "rb") as fp:
            self.assertEqual(fp.read(), file_contents)

        # Copy in the same mapping but different folder
        new_dir = root_path / "some_dir"
        new_dir.mkdir()
        folder_id = VirtualObject.generate_id(new_dir,
                                              self.public_folder["_id"])
        resp = self.request(
            path="/item/{}/copy".format(item_id),
            method="POST",
            user=self.users["admin"],
            params={"folderId": str(folder_id)},
        )
        self.assertStatusOk(resp)
        new_file = new_dir / "some_file"
        self.assertTrue(new_file.is_file())
        with open(new_file.as_posix(), "rb") as fp:
            self.assertEqual(fp.read(), file_contents)

        # Copy between two mappings
        resp = self.request(
            path="/item/{}/copy".format(item_id),
            method="POST",
            user=self.users["admin"],
            params={"folderId": str(self.private_folder["_id"])},
        )
        self.assertStatusOk(resp)
        cors_file = pathlib.Path(self.private_folder["fsPath"]) / "some_file"
        self.assertTrue(cors_file.is_file())
        with open(cors_file.as_posix(), "rb") as fp:
            self.assertEqual(fp.read(), file_contents)

        # Try to copy to non mapping
        resp = self.request(
            path="/item/{}/copy".format(item_id),
            method="POST",
            user=self.users["admin"],
            params={"folderId": str(self.regular_folder["_id"])},
            exception=True,
        )
        self.assertStatus(resp, 500)
        self.assertEqual(
            resp.json["message"],
            "Folder {} is not a mapping.".format(self.regular_folder["_id"]),
        )

        shutil.rmtree(new_dir.as_posix())
        file1.unlink()
        file1.with_name("copy").unlink()
        cors_file.unlink()
    def test_basic_item_ops(self):
        from girder.plugins.virtual_resources.rest import VirtualObject

        root_path = pathlib.Path(self.public_folder["fsPath"])
        nested_dir = root_path / "level0"
        nested_dir.mkdir(parents=True)
        parentId = VirtualObject.generate_id(nested_dir.as_posix(),
                                             self.public_folder["_id"])

        resp = self.request(
            path="/item",
            method="POST",
            user=self.users["admin"],
            params={
                "folderId": parentId,
                "name": "test_item"
            },
        )
        self.assertStatusOk(resp)
        item = resp.json

        actual_item_path = nested_dir / item["name"]
        self.assertTrue(actual_item_path.is_file())

        decoded_path, decoded_root_id = VirtualObject.path_from_id(item["_id"])
        self.assertEqual(decoded_path, actual_item_path)
        self.assertEqual(decoded_root_id, str(self.public_folder["_id"]))

        resp = self.request(
            path="/item",
            method="GET",
            user=self.users["admin"],
            params={
                "parentType": "folder",
                "parentId": str(parentId),
                "name": "nope"
            },
        )
        self.assertStatusOk(resp)
        self.assertEqual(len(resp.json), 0)

        resp = self.request(
            path="/item",
            method="GET",
            user=self.users["admin"],
            params={
                "parentType": "folder",
                "parentId": str(parentId),
                "name": item["name"]
            },
        )
        self.assertStatusOk(resp)
        self.assertEqual(len(resp.json), 1)

        resp = self.request(
            path="/item",
            method="GET",
            user=self.users["admin"],
            params={
                "parentType": "folder",
                "parentId": str(parentId)
            },
        )
        self.assertStatusOk(resp)
        get_items = resp.json
        self.assertEqual(len(get_items), 1)
        self.assertEqual(get_items[0], item)

        resp = self.request(path="/item/{_id}".format(**item),
                            method="GET",
                            user=self.users["admin"])
        self.assertStatusOk(resp)
        self.assertEqual(resp.json, get_items[0])

        resp = self.request(
            path="/item/{_id}".format(**item),
            method="PUT",
            user=self.users["admin"],
            params={"name": "renamed"},
        )
        self.assertStatusOk(resp)
        item = resp.json
        self.assertFalse(actual_item_path.exists())
        actual_item_path = actual_item_path.with_name(item["name"])
        self.assertTrue(actual_item_path.is_file())

        resp = self.request(
            path="/item/{_id}/files".format(**item),
            method="GET",
            user=self.users["admin"],
        )
        self.assertStatusOk(resp)
        files = resp.json
        self.assertEqual(len(files), 1)
        self.assertEqual(files[0]["_id"], item["_id"])

        resp = self.request(path="/item/{_id}".format(**item),
                            method="DELETE",
                            user=self.users["admin"])
        self.assertStatusOk(resp)
        self.assertFalse(actual_item_path.exists())
        shutil.rmtree(nested_dir.as_posix())