public void SettingPositionDoesNotThrowWithPositionInValidRange()
        {
            // Create the download stream.
            var stream = new FileDownloadStreamProxy(Mock.Of <ObjectFile>(), Mock.Of <Vault>());

            // Attempt to set the position.
            stream.Position = 50;
        }
        public void CloseDownloadSessionCleansUpDownloadSession()
        {
            // Set up a file to download.
            var objectFileMock = new Mock <ObjectFile>();

            objectFileMock.SetupGet(m => m.ID).Returns(12345);
            objectFileMock.SetupGet(m => m.Version).Returns(1);

            // Set up the vault object file operations mock.
            var vaultObjectFileOperationsMock = new Mock <VaultObjectFileOperations>();

            // When CancelFileDownloadSession is called, ensure that the correct data is passed.
            vaultObjectFileOperationsMock
            .Setup(m => m.CancelFileDownloadSession
                   (
                       Moq.It.IsAny <int>()
                   ))
            .Callback((int downloadSession) => { Assert.AreEqual(1, downloadSession); })
            .Verifiable();

            // Set up the mock vault.
            var vaultMock = new Mock <Vault>();

            vaultMock
            .SetupGet(m => m.ObjectFileOperations)
            .Returns(vaultObjectFileOperationsMock.Object);

            // Create the stream.
            var stream = new FileDownloadStreamProxy(objectFileMock.Object, vaultMock.Object);

            // Set up the download session.
            var downloadSessionMock = new Mock <FileDownloadSession>();

            downloadSessionMock.SetupGet(m => m.DownloadID).Returns(1);
            stream.DownloadSession = downloadSessionMock.Object;

            // Close the download session.
            stream.Close();

            // Ensure that the download session is empty.
            Assert.IsNull(stream.DownloadSession);

            // Ensure we got hit as expected.
            vaultMock.Verify();
            vaultObjectFileOperationsMock.Verify();
        }
        public void SeekThrowsWithInvalidPosition
        (
            long fileSize,
            long defaultPosition,
            long offset,
            SeekOrigin origin
        )
        {
            // Create the download stream.
            var stream = new FileDownloadStreamProxy(Mock.Of <ObjectFile>(), Mock.Of <Vault>())
            {
                Position = defaultPosition
            };

            Assert.AreEqual(defaultPosition, stream.Position);

            // Attempt to seek.
            stream.Position = defaultPosition;
            stream.Seek(offset, origin);
        }
        [DataRow(100, 90, 20, SeekOrigin.Current, 110)]         // Allow position > length.
        public void SeekProcessesValidPosition
        (
            long fileSize,
            long defaultPosition,
            long offset,
            SeekOrigin origin,
            long expectedNewPosition
        )
        {
            // Create the download stream.
            var stream = new FileDownloadStreamProxy(Mock.Of <ObjectFile>(), Mock.Of <Vault>())
            {
                Position = defaultPosition
            };

            Assert.AreEqual(defaultPosition, stream.Position);
            stream.SetLength(fileSize);
            Assert.AreEqual(fileSize, stream.Length);

            // Attempt to seek.
            Assert.AreEqual(expectedNewPosition, stream.Seek(offset, origin));
        }
        public void BufferSizeTooSmall()
        {
            // Set up a file to download.
            var objectFileMock = new Mock <ObjectFile>();

            objectFileMock.SetupGet(m => m.ID).Returns(12345);
            objectFileMock.SetupGet(m => m.Version).Returns(1);

            // Set up the vault object file operations mock.
            var vaultObjectFileOperationsMock = new Mock <VaultObjectFileOperations>();

            // When DownloadFileInBlocks_BeginEx is called (starting a download session), return a dummy session.
            vaultObjectFileOperationsMock
            .Setup(m => m.DownloadFileInBlocks_BeginEx
                   (
                       Moq.It.IsAny <int>(),
                       Moq.It.IsAny <int>(),
                       Moq.It.IsAny <MFFileFormat>()
                   ))
            .Returns((int receivedFileId, int receivedFileVersion, MFFileFormat receivedFileFormat) =>
            {
                // Mock a download session to return.
                var downloadSessionMock = new Mock <FileDownloadSession>();
                downloadSessionMock.SetupGet(m => m.DownloadID).Returns(1);
                downloadSessionMock.SetupGet(m => m.FileSize).Returns(1000);
                downloadSessionMock.SetupGet(m => m.FileSize32).Returns(1000);
                return(downloadSessionMock.Object);
            })
            .Verifiable();

            // When DownloadFileInBlocks_ReadBlock is called (reading a block of content), return 3 bytes.
            vaultObjectFileOperationsMock
            .Setup(m => m.DownloadFileInBlocks_ReadBlock
                   (
                       Moq.It.IsAny <int>(),
                       Moq.It.IsAny <int>(),
                       Moq.It.IsAny <long>()
                   ))
            .Returns((int downloadSession, int blockSize, long offset) =>
            {
                // Return some sample data.
                return(new byte[]
                {
                    0,
                    10,
                    200
                });
            })
            .Verifiable();

            // Set up the mock vault.
            var vaultMock = new Mock <Vault>();

            vaultMock
            .SetupGet(m => m.ObjectFileOperations)
            .Returns(vaultObjectFileOperationsMock.Object);

            // Create the stream.
            var stream = new FileDownloadStreamProxy(objectFileMock.Object, vaultMock.Object);

            // Attempt to read 4k bytes into a 1 byte buffer.
            byte[] data = new byte[1];
            stream.Read(data, 0, 4096);

            // Ensure we got hit as expected.
            vaultMock.Verify();
            vaultObjectFileOperationsMock.Verify();
        }
        public void ReadIteratesThroughData()
        {
            // File data.
            var fileData = new byte[]
            {
                0,
                10,
                200,
                20,
                10
            };

            // Set up a file to download.
            var objectFileMock = new Mock <ObjectFile>();

            objectFileMock.SetupGet(m => m.ID).Returns(12345);
            objectFileMock.SetupGet(m => m.Version).Returns(1);

            // Set up the vault object file operations mock.
            var vaultObjectFileOperationsMock = new Mock <VaultObjectFileOperations>();

            // When DownloadFileInBlocks_BeginEx is called (starting a download session), return a dummy session.
            vaultObjectFileOperationsMock
            .Setup(m => m.DownloadFileInBlocks_BeginEx
                   (
                       Moq.It.IsAny <int>(),
                       Moq.It.IsAny <int>(),
                       Moq.It.IsAny <MFFileFormat>()
                   ))
            .Returns((int receivedFileId, int receivedFileVersion, MFFileFormat receivedFileFormat) =>
            {
                // Mock a download session to return.
                var downloadSessionMock = new Mock <FileDownloadSession>();
                downloadSessionMock.SetupGet(m => m.DownloadID).Returns(1);
                downloadSessionMock.SetupGet(m => m.FileSize).Returns(1000);
                downloadSessionMock.SetupGet(m => m.FileSize32).Returns(1000);
                return(downloadSessionMock.Object);
            })
            .Verifiable();

            // When DownloadFileInBlocks_ReadBlock is called (reading a block of content), return something.
            vaultObjectFileOperationsMock
            .Setup(m => m.DownloadFileInBlocks_ReadBlock
                   (
                       Moq.It.IsAny <int>(),
                       Moq.It.IsAny <int>(),
                       Moq.It.IsAny <long>()
                   ))
            .Returns((int downloadSession, int blockSize, long offset) =>
            {
                // Validate data.
                if (offset + blockSize > fileData.Length)
                {
                    blockSize = ((int)(fileData.Length - offset));
                }
                // Return just the chunk requested.
                var output = new byte[blockSize];
                Array.Copy(fileData, offset, output, 0, blockSize);
                return(output);
            })
            .Verifiable();

            // Set up the mock vault.
            var vaultMock = new Mock <Vault>();

            vaultMock
            .SetupGet(m => m.ObjectFileOperations)
            .Returns(vaultObjectFileOperationsMock.Object);

            // Create the stream.
            var stream = new FileDownloadStreamProxy(objectFileMock.Object, vaultMock.Object);

            // Attempt to read two bytes at a time.
            for (var i = 0; i < fileData.Length; i = i + 2)
            {
                var output    = new byte[2];
                var bytesRead = stream.Read(output, 0, 2);
                switch (i)
                {
                case 0:
                case 2:
                    Assert.AreEqual(2, bytesRead);
                    Assert.AreEqual(fileData[i], output[0]);
                    Assert.AreEqual(fileData[i + 1], output[1]);
                    break;

                case 4:
                    Assert.AreEqual(1, bytesRead);
                    Assert.AreEqual(fileData[i], output[0]);
                    break;

                default:
                    throw new InvalidOperationException("Should never get here!");
                }
            }

            // Ensure that the download session is not empty.
            Assert.IsNotNull(stream.DownloadSession);

            // Ensure we got hit as expected.
            vaultMock.Verify();
            vaultObjectFileOperationsMock.Verify();
        }