feat: implement readallasync method

This commit is contained in:
Stevan Freeborn
2026-03-29 21:07:48 -05:00
parent 38daead9b2
commit a8774aefe6
2 changed files with 56 additions and 20 deletions
@@ -13,19 +13,7 @@ public sealed class JsonFileStorageProvider(JsonStorageOptions options)
public async Task<string> ReadAsync(string key, CancellationToken ct = default) public async Task<string> ReadAsync(string key, CancellationToken ct = default)
{ {
if (File.Exists(_options.FullPath) is false) var data = await LoadAsync(ct);
{
return string.Empty;
}
using var stream = new FileStream(_options.FullPath, FileMode.Open, FileAccess.Read);
if (stream.Length is 0)
{
return string.Empty;
}
var data = await JsonSerializer.DeserializeAsync<Dictionary<string, string>>(stream, cancellationToken: ct);
if (data is not null && data.TryGetValue(key, out var v)) if (data is not null && data.TryGetValue(key, out var v))
{ {
@@ -35,14 +23,17 @@ public sealed class JsonFileStorageProvider(JsonStorageOptions options)
return string.Empty; return string.Empty;
} }
public Task<Dictionary<string, string>> ReadAllAsync(CancellationToken ct = default)
{
return LoadAsync(ct);
}
public async Task WriteAsync(string key, string encryptedData, CancellationToken ct = default) public async Task WriteAsync(string key, string encryptedData, CancellationToken ct = default)
{ {
Directory.CreateDirectory(_options.DirectoryPath); Directory.CreateDirectory(_options.DirectoryPath);
var data = new Dictionary<string, string> var data = await LoadAsync(ct);
{ data[key] = encryptedData;
[key] = encryptedData
};
using var stream = new FileStream( using var stream = new FileStream(
_options.FullPath, _options.FullPath,
@@ -53,4 +44,23 @@ public sealed class JsonFileStorageProvider(JsonStorageOptions options)
await JsonSerializer.SerializeAsync(stream, data, JsonOptions, ct); await JsonSerializer.SerializeAsync(stream, data, JsonOptions, ct);
} }
private async Task<Dictionary<string, string>> LoadAsync(CancellationToken ct)
{
if (File.Exists(_options.FullPath) is false)
{
return [];
}
using var stream = new FileStream(_options.FullPath, FileMode.Open, FileAccess.Read);
if (stream.Length is 0)
{
return [];
}
var data = await JsonSerializer.DeserializeAsync<Dictionary<string, string>>(stream, cancellationToken: ct);
return data ?? [];
}
} }
@@ -2,7 +2,7 @@ using StevanFreeborn.Extensions.Configuration.Secure.Storage;
namespace StevanFreeborn.Extensions.Configuration.Secure.Tests.Unit.Storage; namespace StevanFreeborn.Extensions.Configuration.Secure.Tests.Unit.Storage;
public class JsonFileStorageProviderTests public class JsonFileStorageProviderTests : IDisposable
{ {
private readonly string _tmpDirectory; private readonly string _tmpDirectory;
private readonly JsonStorageOptions _options; private readonly JsonStorageOptions _options;
@@ -15,7 +15,8 @@ public class JsonFileStorageProviderTests
_options = new() _options = new()
{ {
FileName = "testsettings.json" FileName = "testsettings.json",
DirectoryPath = _tmpDirectory,
}; };
_sut = new(_options); _sut = new(_options);
@@ -32,7 +33,7 @@ public class JsonFileStorageProviderTests
[Fact] [Fact]
public async Task WriteAsync_And_ReadAsync_WhenCalled_ItShouldBeAbleToPersistAndRetrieveValues() public async Task WriteAsync_And_ReadAsync_WhenCalled_ItShouldBeAbleToPersistAndRetrieveValues()
{ {
var configKey = "Key"; var configKey = "KeyA";
var configValue = "Value"; var configValue = "Value";
await _sut.WriteAsync(configKey, configValue); await _sut.WriteAsync(configKey, configValue);
@@ -41,4 +42,29 @@ public class JsonFileStorageProviderTests
result.Should().Be(configValue); result.Should().Be(configValue);
File.Exists(_options.FullPath).Should().BeTrue(); File.Exists(_options.FullPath).Should().BeTrue();
} }
[Fact]
public async Task ReadAllAsync_WhenCalled_ItShouldReturnAllStoredKeys()
{
await _sut.WriteAsync("Key1", "Val1");
await _sut.WriteAsync("Key2", "Val2");
var allData = await _sut.ReadAllAsync();
allData.Should().BeEquivalentTo(new Dictionary<string, string>()
{
["Key1"] = "Val1",
["Key2"] = "Val2",
});
}
public void Dispose()
{
if (Directory.Exists(_tmpDirectory))
{
Directory.Delete(_tmpDirectory, true);
}
GC.SuppressFinalize(this);
}
} }