diff --git a/src/FakeXrmEasy.Core/FileStorage/Db/Exceptions/InvalidBlockLengthException.cs b/src/FakeXrmEasy.Core/FileStorage/Db/Exceptions/InvalidBlockLengthException.cs
new file mode 100644
index 00000000..c200e642
--- /dev/null
+++ b/src/FakeXrmEasy.Core/FileStorage/Db/Exceptions/InvalidBlockLengthException.cs
@@ -0,0 +1,18 @@
+using System;
+
+namespace FakeXrmEasy.Core.FileStorage.Db.Exceptions
+{
+ ///
+ /// Exception raised when the BlockLength property is not valid
+ ///
+ public class InvalidBlockLengthException: Exception
+ {
+ ///
+ /// Default constructor
+ ///
+ public InvalidBlockLengthException() : base($"The BlockLength property must be greater than zero.")
+ {
+
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/FakeXrmEasy.Core/FileStorage/Db/Exceptions/InvalidOffsetException.cs b/src/FakeXrmEasy.Core/FileStorage/Db/Exceptions/InvalidOffsetException.cs
new file mode 100644
index 00000000..3fad5631
--- /dev/null
+++ b/src/FakeXrmEasy.Core/FileStorage/Db/Exceptions/InvalidOffsetException.cs
@@ -0,0 +1,22 @@
+using System;
+using FakeXrmEasy.Core.FileStorage.Download;
+
+namespace FakeXrmEasy.Core.FileStorage.Db.Exceptions
+{
+ ///
+ /// Exception raised when an Offset property is not within the range of a given file length
+ ///
+ public class InvalidOffsetException: Exception
+ {
+ ///
+ /// Default constructor
+ ///
+ ///
+ ///
+ internal InvalidOffsetException(DownloadBlockProperties properties, long actualLength)
+ : base($"The Offset '{properties.Offset.ToString()}' and block lengh '{properties.BlockLength.ToString()}' property values are not within the file's size of [0..{actualLength.ToString()}]")
+ {
+
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/FakeXrmEasy.Core/FileStorage/Db/InMemoryFileDb.cs b/src/FakeXrmEasy.Core/FileStorage/Db/InMemoryFileDb.cs
index 9e3ec0d0..b8607fb9 100644
--- a/src/FakeXrmEasy.Core/FileStorage/Db/InMemoryFileDb.cs
+++ b/src/FakeXrmEasy.Core/FileStorage/Db/InMemoryFileDb.cs
@@ -239,9 +239,36 @@ public List GetAllFileDownloadSessions()
return _fileDownloadSessions.Values.ToList();
}
- public byte[] DownloadFileBlock(DownloadBlockProperties uploadBlockProperties)
+ public byte[] DownloadFileBlock(DownloadBlockProperties downloadBlockProperties)
{
- throw new NotImplementedException();
+ var fileDownloadSession = GetFileDownloadSession(downloadBlockProperties.FileDownloadSessionId);
+ if (fileDownloadSession == null)
+ {
+ throw new FileTokenContinuationNotFoundException(downloadBlockProperties.FileDownloadSessionId);
+ }
+
+ if (downloadBlockProperties.BlockLength <= 0)
+ {
+ throw new InvalidBlockLengthException();
+ }
+
+ if (downloadBlockProperties.Offset < 0)
+ {
+ throw new InvalidOffsetException(downloadBlockProperties, fileDownloadSession.File.Content.Length);
+ }
+
+ if (downloadBlockProperties.BlockLength + downloadBlockProperties.Offset >
+ fileDownloadSession.File.Content.Length)
+ {
+ throw new InvalidOffsetException(downloadBlockProperties, fileDownloadSession.File.Content.Length);
+ }
+
+ var data = new byte[downloadBlockProperties.BlockLength];
+
+ Array.Copy(fileDownloadSession.File.Content, downloadBlockProperties.Offset, data,
+ 0, downloadBlockProperties.BlockLength);
+
+ return data;
}
#endregion
}
diff --git a/tests/FakeXrmEasy.Core.Tests/FileStorage/Db/InMemoryFileDbDownloaderTests.cs b/tests/FakeXrmEasy.Core.Tests/FileStorage/Db/InMemoryFileDbDownloaderTests.cs
index 891ba65c..eb9f3f58 100644
--- a/tests/FakeXrmEasy.Core.Tests/FileStorage/Db/InMemoryFileDbDownloaderTests.cs
+++ b/tests/FakeXrmEasy.Core.Tests/FileStorage/Db/InMemoryFileDbDownloaderTests.cs
@@ -17,7 +17,8 @@ public class InMemoryFileDbDownloaderTests
private readonly FileDownloadProperties _fileDownloadProperties;
private readonly Entity _entity;
private readonly FileAttachment _file;
-
+ private readonly DownloadBlockProperties _downloadBlockProperties;
+
public InMemoryFileDbDownloaderTests()
{
_db = new InMemoryDb();
@@ -43,6 +44,11 @@ public InMemoryFileDbDownloaderTests()
AttributeName = "dv_file",
Content = new byte[] { 1, 2, 3, 4 }
};
+
+ _downloadBlockProperties = new DownloadBlockProperties()
+ {
+ FileDownloadSessionId = ""
+ };
}
[Fact]
@@ -93,5 +99,74 @@ public void Should_return_file_download_session_if_properties_are_valid()
Assert.Equal(_fileDownloadProperties.Target.LogicalName, _entity.LogicalName);
Assert.Equal(_fileDownloadProperties.Target.Id, _entity.Id);
}
+
+ [Fact]
+ public void Should_throw_file_token_continuation_not_found_exception()
+ {
+ _downloadBlockProperties.FileDownloadSessionId = "invalid id";
+ Assert.Throws(() =>
+ _fileDb.DownloadFileBlock(_downloadBlockProperties));
+ }
+
+ [Theory]
+ [InlineData(0)]
+ [InlineData(-23456)]
+ public void Should_throw_invalid_length_exception(long blockLength)
+ {
+ _fileDb.AddFile(_file);
+
+ _entity[_fileDownloadProperties.FileAttributeName] = _file.Id;
+ _db.AddEntityRecord(_entity);
+
+ var fileContinuationToken = _fileDb.InitFileDownloadSession(_fileDownloadProperties);
+ Assert.NotNull(fileContinuationToken);
+
+ _downloadBlockProperties.FileDownloadSessionId = fileContinuationToken;
+ _downloadBlockProperties.BlockLength = blockLength;
+ Assert.Throws(() => _fileDb.DownloadFileBlock(_downloadBlockProperties));
+ }
+
+ [Theory]
+ [InlineData(-1, 2)]
+ [InlineData(0, 5)]
+ [InlineData(2, 25)]
+ [InlineData(4, 2)]
+ public void Should_throw_invalid_offset_exception_if_exceeds_file_length(long offset, long blockLength)
+ {
+ _fileDb.AddFile(_file);
+
+ _entity[_fileDownloadProperties.FileAttributeName] = _file.Id;
+ _db.AddEntityRecord(_entity);
+
+ var fileContinuationToken = _fileDb.InitFileDownloadSession(_fileDownloadProperties);
+ Assert.NotNull(fileContinuationToken);
+
+ _downloadBlockProperties.FileDownloadSessionId = fileContinuationToken;
+ _downloadBlockProperties.Offset = offset;
+ _downloadBlockProperties.BlockLength = blockLength;
+ Assert.Throws(() => _fileDb.DownloadFileBlock(_downloadBlockProperties));
+ }
+
+ [Theory]
+ [InlineData(0, 4)]
+ [InlineData(1, 3)]
+ [InlineData(3, 1)]
+ public void Should_download_a_valid_file_block(long offset, long blockLength)
+ {
+ _fileDb.AddFile(_file);
+
+ _entity[_fileDownloadProperties.FileAttributeName] = _file.Id;
+ _db.AddEntityRecord(_entity);
+
+ var fileContinuationToken = _fileDb.InitFileDownloadSession(_fileDownloadProperties);
+ Assert.NotNull(fileContinuationToken);
+
+ _downloadBlockProperties.FileDownloadSessionId = fileContinuationToken;
+ _downloadBlockProperties.Offset = offset;
+ _downloadBlockProperties.BlockLength = blockLength;
+ var data = _fileDb.DownloadFileBlock(_downloadBlockProperties);
+
+ Assert.Equal(blockLength, data.Length);
+ }
}
}
\ No newline at end of file