Skip to content

Commit 8942b82

Browse files
authored
Fixes and added tests for AspNetExtensions (#15)
1 parent 8990b25 commit 8942b82

12 files changed

Lines changed: 322 additions & 44 deletions

File tree

ManagedCode.Storage.AspNetExtensions/FormFileExtensions.cs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using System.Collections.Generic;
2+
using System.IO;
23
using System.Threading;
34
using System.Threading.Tasks;
45
using ManagedCode.Storage.Core;
@@ -10,15 +11,16 @@ public static class FormFileExtensions
1011
{
1112
public static async Task<LocalFile> ToLocalFileAsync(this IFormFile formFile, CancellationToken cancellationToken = default)
1213
{
13-
LocalFile localFile = new();
14+
var tempPath = Path.GetTempPath();
15+
LocalFile localFile = new($"{tempPath}/{formFile.Name}");
1416

1517
await formFile.CopyToAsync(localFile.FileStream, cancellationToken);
1618

1719
return localFile;
1820
}
1921

2022
public static async Task<IEnumerable<LocalFile>> ToLocalFilesAsync(this IFormFileCollection formFileCollection,
21-
CancellationToken cancellationToken)
23+
CancellationToken cancellationToken = default)
2224
{
2325
List<LocalFile> localFiles = new();
2426

ManagedCode.Storage.AspNetExtensions/Helpers/MimeHelper.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33

44
namespace ManagedCode.Storage.AspNetExtensions.Helpers;
55

6-
internal class MimeHelper
6+
public class MimeHelper
77
{
88
private static readonly IDictionary<string, string> Mappings = new Dictionary<string, string>(StringComparer.InvariantCultureIgnoreCase)
99
{
@@ -569,7 +569,7 @@ internal class MimeHelper
569569
{".zip", "application/x-zip-compressed"},
570570
};
571571

572-
internal static string GetMimeType(string extension)
572+
public static string GetMimeType(string extension)
573573
{
574574
if (!extension.StartsWith("."))
575575
{

ManagedCode.Storage.AspNetExtensions/StorageExtensions.cs

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using System;
2+
using System.IO;
23
using System.Threading;
34
using System.Threading.Tasks;
45
using ManagedCode.Storage.AspNetExtensions.Options;
@@ -14,14 +15,16 @@ public static class StorageExtensions
1415
{
1516
private const int MinLengthForLargeFile = 256 * 1024;
1617

17-
public static async Task UploadToStorageAsync(this IStorage storage, IFormFile formFile, UploadToStorageOptions? options = null,
18+
public static async Task<string> UploadToStorageAsync(this IStorage storage, IFormFile formFile, UploadToStorageOptions? options = null,
1819
CancellationToken cancellationToken = default)
1920
{
2021
options ??= new UploadToStorageOptions();
2122

23+
var extension = Path.GetExtension(formFile.FileName);
24+
2225
BlobMetadata blobMetadata = new()
2326
{
24-
Name = options.UseRandomName ? Guid.NewGuid().ToString("N").ToLowerInvariant() : formFile.FileName,
27+
Name = options.UseRandomName ? $"{Guid.NewGuid().ToString("N").ToLowerInvariant()}{extension}" : formFile.FileName,
2528
ContentType = formFile.ContentType,
2629
Rewrite = options.Rewrite
2730
};
@@ -39,19 +42,28 @@ public static async Task UploadToStorageAsync(this IStorage storage, IFormFile f
3942
await storage.UploadStreamAsync(blobMetadata, stream, cancellationToken);
4043
}
4144
}
45+
46+
return blobMetadata.Name;
4247
}
4348

4449
public static async Task<FileResult> DownloadAsFileResult(this IStorage storage, string blobName, CancellationToken cancellationToken = default)
4550
{
4651
var localFile = await storage.DownloadAsync(blobName, cancellationToken);
4752

48-
return new FileStreamResult(localFile.FileStream, MimeHelper.GetMimeType(localFile.FileInfo.Extension));
53+
return new FileStreamResult(localFile.FileStream, MimeHelper.GetMimeType(localFile.FileInfo.Extension))
54+
{
55+
FileDownloadName = localFile.FileName
56+
};
4957
}
50-
51-
public static async Task<FileResult> DownloadAsFileResult(this IStorage storage, BlobMetadata blobMetadata, CancellationToken cancellationToken = default)
58+
59+
public static async Task<FileResult> DownloadAsFileResult(this IStorage storage, BlobMetadata blobMetadata,
60+
CancellationToken cancellationToken = default)
5261
{
5362
var localFile = await storage.DownloadAsync(blobMetadata, cancellationToken);
5463

55-
return new FileStreamResult(localFile.FileStream, MimeHelper.GetMimeType(localFile.FileInfo.Extension));
64+
return new FileStreamResult(localFile.FileStream, MimeHelper.GetMimeType(localFile.FileInfo.Extension))
65+
{
66+
FileDownloadName = localFile.FileName
67+
};
5668
}
5769
}

ManagedCode.Storage.Core/LocalFile.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,8 @@ public LocalFile(string path, bool keepAlive = false)
3838

3939
if (!File.Exists(FilePath))
4040
{
41-
File.Create(FilePath);
41+
var fs = File.Create(FilePath);
42+
fs.Close();
4243
}
4344

4445
FileName = FileInfo.Name;

ManagedCode.Storage.FileSystem/FileSystemStorage.cs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ public async Task<LocalFile> DownloadAsync(string blobName, CancellationToken ca
9595

9696
var filePath = Path.Combine(_path, blobName);
9797

98-
return new LocalFile(filePath, false);
98+
return new LocalFile(filePath);
9999
}
100100

101101
public async Task<LocalFile> DownloadAsync(BlobMetadata blobMetadata, CancellationToken cancellationToken = default)
@@ -211,7 +211,6 @@ public async Task UploadAsync(string blobName, string content, CancellationToken
211211
EnsureDirectoryExists();
212212
var filePath = Path.Combine(_path, blobName);
213213

214-
//TODO: Need fix
215214
await Task.Run(() => File.WriteAllText(filePath, content), cancellationToken);
216215
}
217216

@@ -235,7 +234,6 @@ public async Task UploadAsync(BlobMetadata blobMetadata, byte[] data, Cancellati
235234
EnsureDirectoryExists();
236235
var filePath = Path.Combine(_path, blobMetadata.Name);
237236

238-
//TODO: Need fix
239237
await Task.Run(() => File.WriteAllBytes(filePath, data), cancellationToken);
240238
}
241239

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
using System;
2+
using System.Linq;
3+
using System.Threading.Tasks;
4+
using FluentAssertions;
5+
using ManagedCode.Storage.AspNetExtensions;
6+
using Microsoft.AspNetCore.Http.Internal;
7+
using Xunit;
8+
9+
namespace ManagedCode.Storage.Tests.AspNetExtensions;
10+
11+
public class FormFileExtensionsTests
12+
{
13+
[Fact]
14+
public async Task ToLocalFileAsync_SmallFile()
15+
{
16+
// Arrange
17+
const int size = 200 * 1024; // 200 KB
18+
var fileName = FileHelper.GenerateRandomFileName("txt");
19+
var formFile = FileHelper.GenerateFormFile(fileName, size);
20+
21+
// Act
22+
var localFile = await formFile.ToLocalFileAsync();
23+
24+
// Assert
25+
localFile.FileStream.Length.Should().Be(formFile.Length);
26+
localFile.FileName.Should().Be(formFile.FileName);
27+
}
28+
29+
[Fact]
30+
public async Task ToLocalFileAsync_LargeFile()
31+
{
32+
// Arrange
33+
const int size = 300 * 1024 * 1024; // 300 MB
34+
var fileName = FileHelper.GenerateRandomFileName("txt");
35+
var formFile = FileHelper.GenerateFormFile(fileName, size);
36+
37+
// Act
38+
var localFile = await formFile.ToLocalFileAsync();
39+
40+
// Assert
41+
localFile.FileStream.Length.Should().Be(formFile.Length);
42+
localFile.FileName.Should().Be(formFile.FileName);
43+
}
44+
45+
[Fact]
46+
public async Task ToLocalFilesAsync_SmallFiles()
47+
{
48+
// Arrange
49+
const int filesCount = 10;
50+
Random random = new();
51+
FormFileCollection collection = new();
52+
53+
for (var i = 0; i < filesCount; i++)
54+
{
55+
var size = random.Next(10, 1000) * 1024;
56+
var fileName = FileHelper.GenerateRandomFileName("txt");
57+
collection.Add(FileHelper.GenerateFormFile(fileName, size));
58+
}
59+
60+
// Act
61+
var localFiles = (await collection.ToLocalFilesAsync()).ToList();
62+
63+
// Assert
64+
localFiles.Count.Should().Be(filesCount);
65+
66+
for (var i = 0; i < filesCount; i++)
67+
{
68+
localFiles[i].FileStream.Length.Should().Be(collection[i].Length);
69+
localFiles[i].FileName.Should().Be(collection[i].FileName);
70+
}
71+
}
72+
}
Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
1+
using System;
2+
using System.IO;
3+
using System.Threading.Tasks;
4+
using FluentAssertions;
5+
using ManagedCode.Storage.AspNetExtensions;
6+
using ManagedCode.Storage.AspNetExtensions.Helpers;
7+
using ManagedCode.Storage.AspNetExtensions.Options;
8+
using ManagedCode.Storage.Core;
9+
using ManagedCode.Storage.Core.Models;
10+
using ManagedCode.Storage.FileSystem.Extensions;
11+
using Microsoft.Extensions.DependencyInjection;
12+
using Xunit;
13+
14+
namespace ManagedCode.Storage.Tests.AspNetExtensions;
15+
16+
public class StorageExtensionsTests
17+
{
18+
public IStorage Storage { get; }
19+
public ServiceProvider ServiceProvider { get; }
20+
21+
public StorageExtensionsTests()
22+
{
23+
ServiceProvider = ConfigureServices();
24+
Storage = ServiceProvider.GetService<IStorage>()!;
25+
}
26+
27+
public static ServiceProvider ConfigureServices()
28+
{
29+
var services = new ServiceCollection();
30+
31+
services.AddFileSystemStorageAsDefault(opt =>
32+
{
33+
opt.CommonPath = Path.Combine(Environment.CurrentDirectory, "managed-code-bucket");
34+
opt.Path = "managed-code-bucket";
35+
});
36+
37+
return services.BuildServiceProvider();
38+
}
39+
40+
[Fact]
41+
public async Task UploadToStorageAsync_SmallFile()
42+
{
43+
// Arrange
44+
const int size = 200 * 1024; // 200 KB
45+
var fileName = FileHelper.GenerateRandomFileName("txt");
46+
var formFile = FileHelper.GenerateFormFile(fileName, size);
47+
48+
// Act
49+
await Storage.UploadToStorageAsync(formFile);
50+
var localFile = await Storage.DownloadAsync(fileName);
51+
52+
// Assert
53+
localFile.FileInfo.Length.Should().Be(formFile.Length);
54+
localFile.FileName.Should().Be(formFile.FileName);
55+
56+
await Storage.DeleteAsync(fileName);
57+
}
58+
59+
[Fact]
60+
public async Task UploadToStorageAsync_LargeFile()
61+
{
62+
// Arrange
63+
const int size = 50 * 1024 * 1024; // 50 MB
64+
var fileName = FileHelper.GenerateRandomFileName("txt");
65+
var formFile = FileHelper.GenerateFormFile(fileName, size);
66+
67+
// Act
68+
await Storage.UploadToStorageAsync(formFile);
69+
var localFile = await Storage.DownloadAsync(fileName);
70+
71+
// Assert
72+
localFile.FileInfo.Length.Should().Be(formFile.Length);
73+
localFile.FileName.Should().Be(formFile.FileName);
74+
75+
await Storage.DeleteAsync(fileName);
76+
}
77+
78+
[Fact]
79+
public async Task UploadToStorageAsync_WithRandomName()
80+
{
81+
// Arrange
82+
const int size = 200 * 1024; // 200 KB
83+
var fileName = FileHelper.GenerateRandomFileName("txt");
84+
var formFile = FileHelper.GenerateFormFile(fileName, size);
85+
86+
// Act
87+
var newFileName = await Storage.UploadToStorageAsync(formFile, new UploadToStorageOptions {UseRandomName = true});
88+
var localFile = await Storage.DownloadAsync(newFileName);
89+
90+
// Assert
91+
localFile.FileInfo.Length.Should().Be(formFile.Length);
92+
localFile.FileName.Should().Be(newFileName);
93+
localFile.FileName.Should().NotBe(formFile.FileName);
94+
95+
await Storage.DeleteAsync(fileName);
96+
}
97+
98+
[Fact]
99+
public async Task DownloadAsFileResult_WithFileName()
100+
{
101+
// Arrange
102+
const int size = 200 * 1024; // 200 KB
103+
var fileName = FileHelper.GenerateRandomFileName("txt");
104+
var localFile = FileHelper.GenerateLocalFile(fileName, size);
105+
106+
// Act
107+
await Storage.UploadFileAsync(fileName, localFile.FilePath);
108+
var fileResult = await Storage.DownloadAsFileResult(fileName);
109+
110+
// Assert
111+
fileResult.ContentType.Should().Be(MimeHelper.GetMimeType(localFile.FileInfo.Extension));
112+
fileResult.FileDownloadName.Should().Be(localFile.FileName);
113+
114+
await Storage.DeleteAsync(fileName);
115+
}
116+
117+
[Fact]
118+
public async Task DownloadAsFileResult_WithBlobMetadata()
119+
{
120+
// Arrange
121+
const int size = 200 * 1024; // 200 KB
122+
var fileName = FileHelper.GenerateRandomFileName("txt");
123+
var localFile = FileHelper.GenerateLocalFile(fileName, size);
124+
125+
BlobMetadata blobMetadata = new() {Name = fileName};
126+
127+
// Act
128+
await Storage.UploadFileAsync(blobMetadata, localFile.FilePath);
129+
var fileResult = await Storage.DownloadAsFileResult(blobMetadata);
130+
131+
// Assert
132+
fileResult.ContentType.Should().Be(MimeHelper.GetMimeType(localFile.FileInfo.Extension));
133+
fileResult.FileDownloadName.Should().Be(localFile.FileName);
134+
135+
await Storage.DeleteAsync(fileName);
136+
}
137+
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
using Xunit;
2+
3+
[assembly: CollectionBehavior(DisableTestParallelization = true)]

0 commit comments

Comments
 (0)