using Features.ImageUploads.Services;
namespace API.Specs.Mocks;
///
/// Test double for that records uploads in memory, so specs can
/// exercise photo-backed features without object storage.
///
public class MockFileStorageProvider : IFileStorageProvider
{
private readonly List _keys = [];
private readonly Dictionary _objects = new();
public IReadOnlyCollection UploadedKeys => _keys.ToList();
/// The key of the most recent upload.
/// Thrown when nothing has been uploaded yet.
public string LastUploadedKey =>
_keys.Count > 0
? _keys[^1]
: throw new InvalidOperationException("no file has been uploaded");
public Task UploadAsync(
string key,
Stream content,
string contentType,
CancellationToken cancellationToken = default
)
{
using MemoryStream buffer = new();
content.CopyTo(buffer);
if (!_objects.ContainsKey(key))
_keys.Add(key);
_objects[key] = buffer.ToArray();
return Task.CompletedTask;
}
public Task DeleteAsync(string key, CancellationToken cancellationToken = default)
{
_objects.Remove(key);
_keys.Remove(key);
return Task.CompletedTask;
}
///
/// Stands in for a signed download URL: an absolute URL on a host the object store would serve,
/// carrying the key in its path, so specs can assert the shape callers actually receive.
///
public string GetPresignedUrl(string key, TimeSpan expiresIn)
{
return $"https://storage.test/{key}?X-Amz-Expires={(int)expiresIn.TotalSeconds}";
}
}