shoc-backend/Api.SeaHavenIndustries.Tests/FileStorageAdapterTests.cs
2026-09-08 11:09:55 -03:00

56 lines
1.9 KiB
C#

using Api.SeaHavenIndustries.Infrastructure;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Moq;
using Xunit;
namespace Api.SeaHavenIndustries.Tests;
public sealed class FileStorageAdapterTests : IDisposable
{
private readonly string _webRoot = Path.Combine(Path.GetTempPath(), $"shoc-storage-{Guid.NewGuid():N}");
private readonly FileStorageAdapter _adapter;
public FileStorageAdapterTests()
{
Directory.CreateDirectory(_webRoot);
var environment = new Mock<IWebHostEnvironment>();
environment.SetupGet(candidate => candidate.WebRootPath).Returns(_webRoot);
environment.SetupGet(candidate => candidate.ContentRootPath).Returns(_webRoot);
_adapter = new FileStorageAdapter(environment.Object, new HttpContextAccessor());
}
[Fact]
public void OpenRead_ValidStoredUrl_ReturnsReadableStream()
{
var directory = Path.Combine(_webRoot, "Assets", "Documents");
Directory.CreateDirectory(directory);
File.WriteAllText(Path.Combine(directory, "report.pdf"), "stored");
using var stream = _adapter.OpenRead("https://example.test/Assets/Documents/report.pdf");
using var reader = new StreamReader(Assert.IsAssignableFrom<Stream>(stream));
Assert.Equal("stored", reader.ReadToEnd());
}
[Theory]
[InlineData("https://example.test/Assets/Images/report.pdf")]
[InlineData("https://example.test/Assets/Documents/../secret.txt")]
[InlineData("https://example.test/Assets/Documents/%2e%2e/secret.txt")]
public void OpenRead_UnsafeUrl_ReturnsNull(string fileUrl)
{
Assert.Null(_adapter.OpenRead(fileUrl));
}
[Fact]
public void OpenRead_MissingFile_ReturnsNull()
{
Assert.Null(_adapter.OpenRead("https://example.test/Assets/Documents/missing.pdf"));
}
public void Dispose()
{
if (Directory.Exists(_webRoot))
Directory.Delete(_webRoot, recursive: true);
}
}