public void ClearContent(FileInfoContract target)
        {
            gateway.ClearContent(rootName, target.Id);
            target.Size = 0;

            InvalidateDrive();
        }
 public void ClearContent(FileInfoContract target)
 {
     try {
         Func<FileSystemInfoLocator> locator = () => new FileSystemInfoLocator(target);
         gateway.ClearContentAsync(rootName, target.Id, locator).Wait();
         target.Size = 0;
     } catch (AggregateException ex) when (ex.InnerExceptions.Count == 1) {
         throw ex.InnerExceptions[0];
     } finally {
         InvalidateDrive();
     }
 }
        public Stream GetContent(FileInfoContract source, ProgressProxy progress)
        {
            var result = gateway.GetContent(rootName, source.Id);

            if (!result.CanSeek) {
                var bufferStream = new MemoryStream();
                result.CopyTo(bufferStream, MAX_BULKDOWNLOAD_SIZE);
                bufferStream.Seek(0, SeekOrigin.Begin);
                result.Dispose();
                result = bufferStream;
            }

            result = new ProgressStream(result, progress);

            if (!string.IsNullOrEmpty(encryptionKey))
                result = result.Decrypt(encryptionKey);

            return result;
        }
        public void SetContent(FileInfoContract target, Stream content, ProgressProxy progress)
        {
            if (!string.IsNullOrEmpty(encryptionKey))
                content = content.Encrypt(encryptionKey);

            gateway.SetContent(rootName, target.Id, content, progress);
            target.Size = content.Length;

            InvalidateDrive();
        }
        public void RenameItem_WherePathIsFile_RenamesFile()
        {
            var rootName = FileSystemFixture.GetRootName();
            var rootDirectoryItems = fileSystemFixture.RootDirectoryItems;

            var original = (FileInfoContract)rootDirectoryItems.Single(i => i.Name == "File.ext");
            var renamed = default(FileInfoContract);

            var gatewayMock = mockingFixture.InitializeGetChildItems(rootName, @"\", rootDirectoryItems);
            gatewayMock.Setup(g => g.RenameItem(rootName, new FileId(@"\File.ext"), "FileRenamed.ext"))
                .Returns(renamed = new FileInfoContract(original.Id.Value.Replace("File", "FileRenamed"), original.Name.Replace("File", "FileRenamed"), original.Created, original.Updated, original.Size, original.Hash))
                .Verifiable();
            compositionFixture.ExportGateway(gatewayMock.Object);

            var result = new PipelineFixture().Invoke(
                FileSystemFixture.NewDriveCommand,
                @"Rename-Item -Path X:\File.ext -NewName FileRenamed.ext",
                @"Get-ChildItem -Path X:\"
            );

            Assert.AreEqual(rootDirectoryItems.Count(), result.Count, "Unexpected number of results");
            CollectionAssert.DoesNotContain(result.Select(p => p.BaseObject).ToArray(), original, "Unrenamed original remains");
            CollectionAssert.Contains(result.Select(p => p.BaseObject).ToArray(), renamed, "Renamed item is missing");

            gatewayMock.VerifyAll();
        }
        public void MoveItemAsync_WherePathIsFile_MovesFile()
        {
            var rootName = FileSystemFixture.GetRootName();
            var rootDirectoryItems = fileSystemFixture.RootDirectoryItems;

            var original = (FileInfoContract)rootDirectoryItems.Single(i => i.Name == "File.ext");
            var moved = default(FileInfoContract);

            var gatewayMock = mockingFixture.InitializeGetChildItemsAsync(rootName, @"\", rootDirectoryItems);
            gatewayMock.Setup(g => g.MoveItemAsync(rootName, new FileId(@"\File.ext"), @"FileMove.ext", new DirectoryId(@"\"), It.IsAny<Func<FileSystemInfoLocator>>()))
                .ReturnsAsync(moved = new FileInfoContract(original.Id.Value.Replace("File", "FileMove"), original.Name.Replace("File", "FileMove"), original.Created, original.Updated, original.Size, original.Hash))
                .Verifiable();
            compositionFixture.ExportAsyncGateway(gatewayMock.Object);

            var result = new PipelineFixture().Invoke(
                FileSystemFixture.NewDriveCommand,
                @"Move-Item -Path X:\File.ext -Destination X:\FileMove.ext",
                @"Get-ChildItem -Path X:\"
            );

            Assert.AreEqual(rootDirectoryItems.Count(), result.Count, "Unexpected number of results");
            CollectionAssert.DoesNotContain(result.Select(p => p.BaseObject).ToArray(), original, "Original item remains");
            CollectionAssert.Contains(result.Select(p => p.BaseObject).ToArray(), moved, "Copied item is missing");

            gatewayMock.VerifyAll();
        }
        public void NewItem_WherePathIsIncompleteAndItemTypeIsFile_CreatesNewFile()
        {
            var rootName = FileSystemFixture.GetRootName();
            var rootDirectoryItems = fileSystemFixture.RootDirectoryItems;
            var newIntermediateDirectory = new DirectoryInfoContract(@"\NewSubDir", "NewSubDir", DateTime.Now, DateTime.Now);
            var newItem = new FileInfoContract(@"\NewSubDir\NewSubFile", "NewSubFile", DateTime.Now, DateTime.Now, 0, null);

            var gatewayMock = mockingFixture.InitializeGetChildItems(rootName, @"\", rootDirectoryItems);
            gatewayMock.Setup(g => g.NewDirectoryItem(rootName, new DirectoryId(@"\"), "NewSubDir"))
                .Returns(newIntermediateDirectory)
                .Verifiable();
            gatewayMock.Setup(g => g.NewFileItem(rootName, new DirectoryId(@"\NewSubDir"), "NewSubFile", null, It.Is<IProgress<ProgressValue>>(p => true)))
                .Returns(newItem)
                .Verifiable();
            var subDirs = new Queue<string>(new[] { @"\", @"\NewSubDir" });
            var predicateIterator = new Func<string, bool>(s => s == subDirs.Dequeue());
            gatewayMock.SetupSequence(g => g.GetChildItem(rootName, It.Is<DirectoryId>(d => predicateIterator(d.Value))))
                .Returns(new FileSystemInfoContract[0])
                .Returns(new FileSystemInfoContract[0])
                .Throws(new InvalidOperationException(@"Redundant access to directory"));
            compositionFixture.ExportGateway(gatewayMock.Object);

            var result = new PipelineFixture().Invoke(
                FileSystemFixture.NewDriveCommand,
                @"New-Item -Type File -Path X:\NewSubDir -Name NewSubFile -Force",
                @"Get-ChildItem -Path X:\ -Filter 'NewSub*' -Recurse"
            );

            Assert.AreEqual(2, result.Count, "Unexpected number of results");
            CollectionAssert.AreEqual(result.Select(i => i.BaseObject).ToArray(), new FileSystemInfoContract[] { newIntermediateDirectory, newItem }, "Unexpected result");

            gatewayMock.VerifyAll();
        }
        public void NewItem_WhereEncryptionKeyIsSpecifiedAndItemTypeIsFile_PassesEncryptedValue()
        {
            var rootName = FileSystemFixture.GetRootName();
            var rootDirectoryItems = fileSystemFixture.RootDirectoryItems;
            var content = TestContent.SingleLineTestContent;
            var newItem = new FileInfoContract(@"\NewFile", "NewFile", DateTime.Now, DateTime.Now, content.Length, FileSystemFixture.GetHash(content));

            var gatewayMock = mockingFixture.InitializeGetChildItems(rootName, @"\", rootDirectoryItems);
            gatewayMock.Setup(g => g.NewFileItem(rootName, new DirectoryId(@"\"), "NewFile", It.Is<Stream>(s => EncryptionFixture.GetDecryptingReader(s, FileSystemFixture.EncryptionKey).ReadToEnd() == content), It.Is<IProgress<ProgressValue>>(p => true)))
                .Returns(newItem)
                .Verifiable();
            compositionFixture.ExportGateway(gatewayMock.Object);

            var pipelineFixture = new PipelineFixture();
            pipelineFixture.SetVariable("value", content);
            var result = pipelineFixture.Invoke(
                FileSystemFixture.NewDriveCommandWithEncryptionKey,
                @"New-Item -Type File -Path X:\ -Name NewFile -Value $value"
            );

            Assert.AreEqual(1, result.Count, "Unexpected number of results");
            Assert.AreEqual(newItem, result[0].BaseObject, "Mismatching result");

            gatewayMock.VerifyAll();
        }
        public void NewItem_WherePathIsSubDirAndItemTypeIsFile_CanRemoveNewFile()
        {
            var rootName = FileSystemFixture.GetRootName();
            var rootDirectoryItems = fileSystemFixture.RootDirectoryItems;
            var subDirectoryItems = fileSystemFixture.SubDirectoryItems;
            var newItem = new FileInfoContract(@"\SubDir\NewSubFile", "NewSubFile", DateTime.Now, DateTime.Now, 0, null);

            var gatewayMock = mockingFixture.InitializeGetChildItems(rootName, @"\SubDir", rootDirectoryItems, subDirectoryItems);
            gatewayMock.Setup(g => g.NewFileItem(rootName, new DirectoryId(@"\SubDir"), "NewSubFile", null, It.Is<IProgress<ProgressValue>>(p => true)))
                .Returns(newItem)
                .Verifiable();
            gatewayMock.Setup(g => g.RemoveItem(rootName, new FileId(@"\SubDir\NewSubFile"), false)).Verifiable();
            compositionFixture.ExportGateway(gatewayMock.Object);

            var result = new PipelineFixture().Invoke(
                FileSystemFixture.NewDriveCommand,
                @"New-Item -Type File -Path X:\SubDir -Name NewSubFile",
                @"Remove-Item -Path X:\SubDir\NewSubFile",
                @"Get-ChildItem -Path X:\SubDir"
            );

            Assert.AreEqual(subDirectoryItems.Length, result.Count, "Unexpected number of results");
            CollectionAssert.DoesNotContain(result.Select(p => p.BaseObject).ToArray(), newItem, "Excessive result");

            gatewayMock.VerifyAll();
        }
        public void NewItem_WherePathIsRootAndItemTypeIsFile_CallsGatewayCorrectly()
        {
            var rootName = FileSystemFixture.GetRootName();
            var rootDirectoryItems = fileSystemFixture.RootDirectoryItems;
            var newItem = new FileInfoContract(@"\NewFile", "NewFile", DateTime.Now, DateTime.Now, 0, null);

            var gatewayMock = mockingFixture.InitializeGetChildItems(rootName, @"\", rootDirectoryItems);
            gatewayMock.Setup(g => g.NewFileItem(rootName, new DirectoryId(@"\"), "NewFile", null, It.Is<IProgress<ProgressValue>>(p => true)))
                .Returns(newItem)
                .Verifiable();
            compositionFixture.ExportGateway(gatewayMock.Object);

            var result = new PipelineFixture().Invoke(
                FileSystemFixture.NewDriveCommand,
                @"New-Item -Type File -Path X:\ -Name NewFile"
            );

            Assert.AreEqual(1, result.Count, "Unexpected number of results");
            Assert.AreEqual(newItem, result[0].BaseObject, "Mismatching result");

            gatewayMock.VerifyAll();
        }
        public void CopyItem_WherePathIsFileAndDestinationDirectoryIsDifferent_CopiesFile()
        {
            var rootName = FileSystemFixture.GetRootName();
            var rootDirectoryItems = fileSystemFixture.RootDirectoryItems;
            var subDirectoryItems = fileSystemFixture.SubDirectoryItems;

            var original = (FileInfoContract)subDirectoryItems.Single(i => i.Name == "SubFile.ext");
            var copy = default(FileInfoContract);

            var gatewayMock = mockingFixture.InitializeGetChildItems(rootName, @"\SubDir", rootDirectoryItems, subDirectoryItems);
            gatewayMock.Setup(g => g.CopyItem(rootName, new FileId(@"\File.ext"), @"FileCopy.ext", new DirectoryId(@"\SubDir"), false))
                .Returns(copy = new FileInfoContract(original.Id.Value.Replace("File", "FileCopy"), original.Name.Replace("File", "FileCopy"), original.Created, original.Updated, original.Size, original.Hash))
                .Verifiable();
            compositionFixture.ExportGateway(gatewayMock.Object);

            var result = new PipelineFixture().Invoke(
                FileSystemFixture.NewDriveCommand,
                @"Copy-Item -Path X:\File.ext -Destination X:\SubDir\FileCopy.ext",
                @"Get-ChildItem -Path X:\SubDir"
            );

            Assert.AreEqual(subDirectoryItems.Count() + 1, result.Count, "Unexpected number of results");
            CollectionAssert.Contains(result.Select(p => p.BaseObject).ToArray(), copy, "Copied item is missing");

            gatewayMock.VerifyAll();
        }
        public void NewItemAsync_WherePathIsRootAndItemTypeIsFile_CreatesNewFile()
        {
            var rootName = FileSystemFixture.GetRootName();
            var rootDirectoryItems = fileSystemFixture.RootDirectoryItems;
            var newItem = new FileInfoContract(@"\NewFile", "NewFile", DateTime.Now, DateTime.Now, 0, null);

            var gatewayMock = mockingFixture.InitializeGetChildItemsAsync(rootName, @"\", rootDirectoryItems);
            gatewayMock.Setup(g => g.NewFileItemAsync(rootName, new DirectoryId(@"\"), "NewFile", null, It.Is<IProgress<ProgressValue>>(p => true)))
                .ReturnsAsync(newItem)
                .Verifiable();
            compositionFixture.ExportAsyncGateway(gatewayMock.Object);

            var result = new PipelineFixture().Invoke(
                FileSystemFixture.NewDriveCommand,
                @"New-Item -Type File -Path X:\ -Name NewFile",
                @"Get-ChildItem -Path X:\"
            );

            Assert.AreEqual(rootDirectoryItems.Length + 1, result.Count, "Unexpected number of results");
            CollectionAssert.Contains(result.Select(p => p.BaseObject).ToArray(), newItem, "Missing result");

            gatewayMock.VerifyAll();
        }
        public Stream GetContent(FileInfoContract source, ProgressProxy progress)
        {
            try {
                var result = gateway.GetContentAsync(rootName, source.Id).Result;

                if (!result.CanSeek) {
                    var bufferStream = new MemoryStream();
                    result.CopyTo(bufferStream, MAX_BULKDOWNLOAD_SIZE);
                    bufferStream.Seek(0, SeekOrigin.Begin);
                    result.Dispose();
                    result = bufferStream;
                }

                result = new ProgressStream(result, progress);

                if (!string.IsNullOrEmpty(encryptionKey))
                    result = result.Decrypt(encryptionKey);

                return result;
            } catch (AggregateException ex) when (ex.InnerExceptions.Count == 1) {
                throw ex.InnerExceptions[0];
            }
        }
        public void SetContent(FileInfoContract target, Stream content, ProgressProxy progress)
        {
            try {
                if (!string.IsNullOrEmpty(encryptionKey))
                    content = content.Encrypt(encryptionKey);

                Func<FileSystemInfoLocator> locator = () => new FileSystemInfoLocator(target);
                ProgressProxy.ProgressFunc<bool> func = p => gateway.SetContentAsync(rootName, target.Id, content, p, locator);
                ProgressProxy.TraceProgressOn(func, progress);
                target.Size = content.Length;
            } catch (AggregateException ex) when (ex.InnerExceptions.Count == 1) {
                throw ex.InnerExceptions[0];
            } finally {
                InvalidateDrive();
            }
        }