feat: add app settings manager to do the reading and writing
This commit is contained in:
@@ -11,6 +11,7 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<InternalsVisibleTo Include="DynamicProxyGenAssembly2" />
|
||||||
<InternalsVisibleTo Include="$(AssemblyName).Tests" />
|
<InternalsVisibleTo Include="$(AssemblyName).Tests" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
|
|||||||
@@ -2,35 +2,28 @@ namespace AltGen.Console.Tests.Unit;
|
|||||||
|
|
||||||
public class AddConfigCommandTests : IDisposable
|
public class AddConfigCommandTests : IDisposable
|
||||||
{
|
{
|
||||||
readonly Mock<IFileSystem> _fileSystem = new();
|
readonly Mock<IAppSettingsManager> _mockSettingsManager = new();
|
||||||
readonly TestConsole _testConsole = new();
|
readonly TestConsole _testConsole = new();
|
||||||
readonly AddConfigCommand _sut;
|
readonly AddConfigCommand _sut;
|
||||||
|
|
||||||
public AddConfigCommandTests()
|
public AddConfigCommandTests()
|
||||||
{
|
{
|
||||||
_sut = new AddConfigCommand(_testConsole, _fileSystem.Object);
|
_sut = new AddConfigCommand(_testConsole, _mockSettingsManager.Object);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public async Task ExecuteAsync_WhenSettingsDoNotExist_ItShouldCreateSettings()
|
public async Task ExecuteAsync_WhenSettingsDoNotExist_ItShouldCreateSettings()
|
||||||
{
|
{
|
||||||
var testSettingsPath = "appsettings.json";
|
|
||||||
var expectedAppSettings = new AppSettings([
|
var expectedAppSettings = new AppSettings([
|
||||||
new("provider", "key", false)
|
new("provider", "key", false)
|
||||||
]);
|
]);
|
||||||
var expectedJson = JsonSerializer.Serialize(expectedAppSettings, JsonOptions.Default);
|
|
||||||
|
|
||||||
|
_mockSettingsManager
|
||||||
_fileSystem
|
.Setup(static x => x.AppSettingsExist())
|
||||||
.Setup(static x => x.Path.Combine(It.IsAny<string>(), It.IsAny<string>()))
|
|
||||||
.Returns(testSettingsPath);
|
|
||||||
|
|
||||||
_fileSystem
|
|
||||||
.Setup(static x => x.File.Exists(It.IsAny<string>()))
|
|
||||||
.Returns(false);
|
.Returns(false);
|
||||||
|
|
||||||
var commandSettings = new AddConfigCommand.Settings(_fileSystem.Object)
|
var commandSettings = new AddConfigCommand.Settings()
|
||||||
{
|
{
|
||||||
Provider = "provider",
|
Provider = "provider",
|
||||||
Key = "key",
|
Key = "key",
|
||||||
@@ -40,39 +33,36 @@ public class AddConfigCommandTests : IDisposable
|
|||||||
|
|
||||||
result.Should().Be(0);
|
result.Should().Be(0);
|
||||||
|
|
||||||
_fileSystem
|
_mockSettingsManager.Verify(
|
||||||
.Verify(
|
static x => x.SaveAppSettingsAsync(It.Is<AppSettings>(
|
||||||
x => x.File.WriteAllTextAsync(testSettingsPath, expectedJson, default),
|
static x => x.Providers[0].Provider == "provider" &&
|
||||||
Times.Once
|
x.Providers[0].Key == "key" &&
|
||||||
);
|
x.Providers[0].Default == false
|
||||||
|
)),
|
||||||
|
Times.Once
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public async Task ExecuteAsync_WhenSettingsExist_ItShouldUpdateSettings()
|
public async Task ExecuteAsync_WhenSettingsExist_ItShouldUpdateSettings()
|
||||||
{
|
{
|
||||||
var testSettingsPath = "appsettings.json";
|
|
||||||
var existingAppSettings = new AppSettings([
|
var existingAppSettings = new AppSettings([
|
||||||
new("existing", "existing", false)
|
new("existing", "existing", false)
|
||||||
]);
|
]);
|
||||||
var existingJson = JsonSerializer.Serialize(existingAppSettings, JsonOptions.Default);
|
|
||||||
var expectedAppSettings = new AppSettings([
|
var expectedAppSettings = new AppSettings([
|
||||||
new("existing", "key", true)
|
new("existing", "key", true)
|
||||||
]);
|
]);
|
||||||
var expectedJson = JsonSerializer.Serialize(expectedAppSettings, JsonOptions.Default);
|
|
||||||
|
|
||||||
_fileSystem
|
_mockSettingsManager
|
||||||
.Setup(static x => x.Path.Combine(It.IsAny<string>(), It.IsAny<string>()))
|
.Setup(static x => x.AppSettingsExist())
|
||||||
.Returns(testSettingsPath);
|
|
||||||
|
|
||||||
_fileSystem
|
|
||||||
.Setup(static x => x.File.Exists(It.IsAny<string>()))
|
|
||||||
.Returns(true);
|
.Returns(true);
|
||||||
|
|
||||||
_fileSystem
|
_mockSettingsManager
|
||||||
.Setup(static x => x.File.ReadAllTextAsync(It.IsAny<string>(), default))
|
.Setup(static x => x.GetAppSettingsAsync())
|
||||||
.ReturnsAsync(existingJson);
|
.ReturnsAsync(existingAppSettings);
|
||||||
|
|
||||||
var commandSettings = new AddConfigCommand.Settings(_fileSystem.Object)
|
var commandSettings = new AddConfigCommand.Settings()
|
||||||
{
|
{
|
||||||
Provider = "existing",
|
Provider = "existing",
|
||||||
Key = "key",
|
Key = "key",
|
||||||
@@ -83,39 +73,14 @@ public class AddConfigCommandTests : IDisposable
|
|||||||
|
|
||||||
result.Should().Be(0);
|
result.Should().Be(0);
|
||||||
|
|
||||||
_fileSystem
|
_mockSettingsManager.Verify(
|
||||||
.Verify(
|
static x => x.SaveAppSettingsAsync(It.Is<AppSettings>(
|
||||||
x => x.File.WriteAllTextAsync(testSettingsPath, expectedJson, default),
|
static x => x.Providers[0].Provider == "existing" &&
|
||||||
Times.Once
|
x.Providers[0].Key == "key" &&
|
||||||
);
|
x.Providers[0].Default == true
|
||||||
}
|
)),
|
||||||
|
Times.Once
|
||||||
[Fact]
|
);
|
||||||
public async Task ExecuteAsync_WhenSettingsExistButCanNotBeDeserialized_ItShouldThrow()
|
|
||||||
{
|
|
||||||
var testSettingsPath = "appsettings.json";
|
|
||||||
|
|
||||||
_fileSystem
|
|
||||||
.Setup(static x => x.Path.Combine(It.IsAny<string>(), It.IsAny<string>()))
|
|
||||||
.Returns(testSettingsPath);
|
|
||||||
|
|
||||||
_fileSystem
|
|
||||||
.Setup(static x => x.File.Exists(It.IsAny<string>()))
|
|
||||||
.Returns(true);
|
|
||||||
|
|
||||||
_fileSystem
|
|
||||||
.Setup(static x => x.File.ReadAllTextAsync(It.IsAny<string>(), default))
|
|
||||||
.ReturnsAsync("null");
|
|
||||||
|
|
||||||
var commandSettings = new AddConfigCommand.Settings(_fileSystem.Object)
|
|
||||||
{
|
|
||||||
Provider = "provider",
|
|
||||||
Key = "key",
|
|
||||||
};
|
|
||||||
|
|
||||||
var act = async () => await _sut.ExecuteAsync(null!, commandSettings);
|
|
||||||
|
|
||||||
await act.Should().ThrowAsync<ConfigException>();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
|
|||||||
@@ -0,0 +1,100 @@
|
|||||||
|
namespace AltGen.Console.Tests.Unit;
|
||||||
|
|
||||||
|
public class AppSettingsManagerTests
|
||||||
|
{
|
||||||
|
readonly Mock<IFileSystem> _mockFileSystem = new();
|
||||||
|
readonly AppSettingsManager _sut;
|
||||||
|
|
||||||
|
public AppSettingsManagerTests()
|
||||||
|
{
|
||||||
|
_mockFileSystem
|
||||||
|
.Setup(static x => x.Path.Combine(It.IsAny<string>(), It.IsAny<string>()))
|
||||||
|
.Returns("path");
|
||||||
|
|
||||||
|
_sut = new AppSettingsManager(_mockFileSystem.Object);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void AppSettingsExist_WhenSettingsDoNotExist_ItShouldReturnFalse()
|
||||||
|
{
|
||||||
|
_mockFileSystem
|
||||||
|
.Setup(static x => x.Path.Exists(It.IsAny<string>()))
|
||||||
|
.Returns(false);
|
||||||
|
|
||||||
|
var result = _sut.AppSettingsExist();
|
||||||
|
|
||||||
|
result.Should().BeFalse();
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void AppSettingsExist_WhenSettingsExist_ItShouldReturnTrue()
|
||||||
|
{
|
||||||
|
_mockFileSystem
|
||||||
|
.Setup(static x => x.Path.Exists(It.IsAny<string>()))
|
||||||
|
.Returns(true);
|
||||||
|
|
||||||
|
var result = _sut.AppSettingsExist();
|
||||||
|
|
||||||
|
result.Should().BeTrue();
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task GetAppSettingsAsync_WhenSettingsExist_ItShouldReturnSettings()
|
||||||
|
{
|
||||||
|
var testSettings = new AppSettings([
|
||||||
|
new("provider", "key", false)
|
||||||
|
]);
|
||||||
|
|
||||||
|
var json = JsonSerializer.Serialize(testSettings, JsonOptions.Default);
|
||||||
|
|
||||||
|
_mockFileSystem
|
||||||
|
.Setup(static x => x.File.ReadAllTextAsync(It.IsAny<string>(), default))
|
||||||
|
.ReturnsAsync(json);
|
||||||
|
|
||||||
|
var result = await _sut.GetAppSettingsAsync();
|
||||||
|
|
||||||
|
result.Should().BeEquivalentTo(testSettings);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task GetAppSettingsAsync_WhenDeserializingSettingsIsNull_ItShouldReturnEmptySettings()
|
||||||
|
{
|
||||||
|
_mockFileSystem
|
||||||
|
.Setup(static x => x.File.ReadAllTextAsync(It.IsAny<string>(), default))
|
||||||
|
.ReturnsAsync("null");
|
||||||
|
|
||||||
|
var result = await _sut.GetAppSettingsAsync();
|
||||||
|
|
||||||
|
result.Should().BeEquivalentTo(new AppSettings([]));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task GetAppSettingsAsync_WhenSettingsDoNotExist_ItShouldThrow()
|
||||||
|
{
|
||||||
|
_mockFileSystem
|
||||||
|
.Setup(static x => x.File.ReadAllTextAsync(It.IsAny<string>(), default))
|
||||||
|
.ThrowsAsync(new FileNotFoundException());
|
||||||
|
|
||||||
|
var action = _sut.GetAppSettingsAsync;
|
||||||
|
|
||||||
|
await action.Should().ThrowAsync<FileNotFoundException>();
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task SaveAppSettingsAsync_WhenCalled_ItShouldSaveSettings()
|
||||||
|
{
|
||||||
|
_mockFileSystem
|
||||||
|
.Setup(static x => x.File.WriteAllTextAsync(It.IsAny<string>(), It.IsAny<string>(), default))
|
||||||
|
.Returns(Task.CompletedTask);
|
||||||
|
|
||||||
|
var testSettings = new AppSettings([
|
||||||
|
new("provider", "key", false)
|
||||||
|
]);
|
||||||
|
|
||||||
|
var json = JsonSerializer.Serialize(testSettings, JsonOptions.Default);
|
||||||
|
|
||||||
|
await _sut.SaveAppSettingsAsync(testSettings);
|
||||||
|
|
||||||
|
_mockFileSystem.Verify(x => x.File.WriteAllTextAsync(It.IsAny<string>(), json, default), Times.Once);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -2,14 +2,12 @@ namespace AltGen.Console.Tests.Unit;
|
|||||||
|
|
||||||
public class AppSettingsTests
|
public class AppSettingsTests
|
||||||
{
|
{
|
||||||
readonly Mock<IFileSystem> _fileSystemMock = new();
|
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void AddOrUpdateProvider_WhenProviderDoesNotExist_ItShouldAddProvider()
|
public void AddOrUpdateProvider_WhenProviderDoesNotExist_ItShouldAddProvider()
|
||||||
{
|
{
|
||||||
var providerSettings = new ProviderSettings("provider", "key", true);
|
var providerSettings = new ProviderSettings("provider", "key", true);
|
||||||
|
|
||||||
var commandSettings = new AddConfigCommand.Settings(_fileSystemMock.Object)
|
var commandSettings = new AddConfigCommand.Settings()
|
||||||
{
|
{
|
||||||
Provider = providerSettings.Provider,
|
Provider = providerSettings.Provider,
|
||||||
Key = providerSettings.Key,
|
Key = providerSettings.Key,
|
||||||
@@ -29,7 +27,7 @@ public class AppSettingsTests
|
|||||||
var providerSettings = new ProviderSettings("provider", "key", true);
|
var providerSettings = new ProviderSettings("provider", "key", true);
|
||||||
var existingProviderSettings = new ProviderSettings("provider", "key", false);
|
var existingProviderSettings = new ProviderSettings("provider", "key", false);
|
||||||
|
|
||||||
var commandSettings = new AddConfigCommand.Settings(_fileSystemMock.Object)
|
var commandSettings = new AddConfigCommand.Settings()
|
||||||
{
|
{
|
||||||
Provider = providerSettings.Provider,
|
Provider = providerSettings.Provider,
|
||||||
Key = providerSettings.Key,
|
Key = providerSettings.Key,
|
||||||
@@ -48,7 +46,7 @@ public class AppSettingsTests
|
|||||||
var providerSettings = new ProviderSettings("claude", "key", true);
|
var providerSettings = new ProviderSettings("claude", "key", true);
|
||||||
var existingProviderSettings = new ProviderSettings("gemini", "key", true);
|
var existingProviderSettings = new ProviderSettings("gemini", "key", true);
|
||||||
|
|
||||||
var commandSettings = new AddConfigCommand.Settings(_fileSystemMock.Object)
|
var commandSettings = new AddConfigCommand.Settings()
|
||||||
{
|
{
|
||||||
Provider = providerSettings.Provider,
|
Provider = providerSettings.Provider,
|
||||||
Key = providerSettings.Key,
|
Key = providerSettings.Key,
|
||||||
@@ -69,7 +67,7 @@ public class AppSettingsTests
|
|||||||
{
|
{
|
||||||
var existingProviderSettings = new ProviderSettings("provider", "key", true);
|
var existingProviderSettings = new ProviderSettings("provider", "key", true);
|
||||||
|
|
||||||
var commandSettings = new RemoveConfigCommand.Settings(_fileSystemMock.Object)
|
var commandSettings = new RemoveConfigCommand.Settings()
|
||||||
{
|
{
|
||||||
Provider = existingProviderSettings.Provider,
|
Provider = existingProviderSettings.Provider,
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -2,26 +2,20 @@ namespace AltGen.Console.Tests.Unit;
|
|||||||
|
|
||||||
public class ListConfigCommandTests : IDisposable
|
public class ListConfigCommandTests : IDisposable
|
||||||
{
|
{
|
||||||
readonly Mock<IFileSystem> _fileSystem = new();
|
readonly Mock<IAppSettingsManager> _mockSettingsManager = new();
|
||||||
readonly TestConsole _testConsole = new();
|
readonly TestConsole _testConsole = new();
|
||||||
readonly ListConfigCommand _sut;
|
readonly ListConfigCommand _sut;
|
||||||
|
|
||||||
public ListConfigCommandTests()
|
public ListConfigCommandTests()
|
||||||
{
|
{
|
||||||
_sut = new ListConfigCommand(_testConsole, _fileSystem.Object);
|
_sut = new ListConfigCommand(_testConsole, _mockSettingsManager.Object);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public async Task ExecuteAsync_WhenSettingsDoNotExist_ItShouldOutputNoSettings()
|
public async Task ExecuteAsync_WhenSettingsDoNotExist_ItShouldOutputNoSettings()
|
||||||
{
|
{
|
||||||
var testSettingsPath = "appsettings.json";
|
_mockSettingsManager
|
||||||
|
.Setup(static x => x.AppSettingsExist())
|
||||||
_fileSystem
|
|
||||||
.Setup(static x => x.Path.Combine(It.IsAny<string>(), It.IsAny<string>()))
|
|
||||||
.Returns(testSettingsPath);
|
|
||||||
|
|
||||||
_fileSystem
|
|
||||||
.Setup(static x => x.File.Exists(It.IsAny<string>()))
|
|
||||||
.Returns(false);
|
.Returns(false);
|
||||||
|
|
||||||
var result = await _sut.ExecuteAsync(null!);
|
var result = await _sut.ExecuteAsync(null!);
|
||||||
@@ -37,23 +31,17 @@ public class ListConfigCommandTests : IDisposable
|
|||||||
[Fact]
|
[Fact]
|
||||||
public async Task ExecuteAsync_WhenSettingsExist_ItShouldOutputSettings()
|
public async Task ExecuteAsync_WhenSettingsExist_ItShouldOutputSettings()
|
||||||
{
|
{
|
||||||
var testSettingsPath = "appsettings.json";
|
|
||||||
var testSettings = new AppSettings([
|
var testSettings = new AppSettings([
|
||||||
new("provider", "key", false)
|
new("provider", "key", false)
|
||||||
]);
|
]);
|
||||||
var testSettingsJson = JsonSerializer.Serialize(testSettings, JsonOptions.Default);
|
|
||||||
|
|
||||||
_fileSystem
|
_mockSettingsManager
|
||||||
.Setup(static x => x.Path.Combine(It.IsAny<string>(), It.IsAny<string>()))
|
.Setup(static x => x.AppSettingsExist())
|
||||||
.Returns(testSettingsPath);
|
|
||||||
|
|
||||||
_fileSystem
|
|
||||||
.Setup(static x => x.File.Exists(It.IsAny<string>()))
|
|
||||||
.Returns(true);
|
.Returns(true);
|
||||||
|
|
||||||
_fileSystem
|
_mockSettingsManager
|
||||||
.Setup(static x => x.File.ReadAllTextAsync(It.IsAny<string>(), default))
|
.Setup(static x => x.GetAppSettingsAsync())
|
||||||
.ReturnsAsync(testSettingsJson);
|
.ReturnsAsync(testSettings);
|
||||||
|
|
||||||
var result = await _sut.ExecuteAsync(null!);
|
var result = await _sut.ExecuteAsync(null!);
|
||||||
|
|
||||||
@@ -68,23 +56,17 @@ public class ListConfigCommandTests : IDisposable
|
|||||||
[Fact]
|
[Fact]
|
||||||
public async Task ExecuteAsync_WhenSettingsExistAndDefault_ItShouldOutputSettings()
|
public async Task ExecuteAsync_WhenSettingsExistAndDefault_ItShouldOutputSettings()
|
||||||
{
|
{
|
||||||
var testSettingsPath = "appsettings.json";
|
|
||||||
var testSettings = new AppSettings([
|
var testSettings = new AppSettings([
|
||||||
new("provider", "key", true)
|
new("provider", "key", true)
|
||||||
]);
|
]);
|
||||||
var testSettingsJson = JsonSerializer.Serialize(testSettings, JsonOptions.Default);
|
|
||||||
|
|
||||||
_fileSystem
|
_mockSettingsManager
|
||||||
.Setup(static x => x.Path.Combine(It.IsAny<string>(), It.IsAny<string>()))
|
.Setup(static x => x.AppSettingsExist())
|
||||||
.Returns(testSettingsPath);
|
|
||||||
|
|
||||||
_fileSystem
|
|
||||||
.Setup(static x => x.File.Exists(It.IsAny<string>()))
|
|
||||||
.Returns(true);
|
.Returns(true);
|
||||||
|
|
||||||
_fileSystem
|
_mockSettingsManager
|
||||||
.Setup(static x => x.File.ReadAllTextAsync(It.IsAny<string>(), default))
|
.Setup(static x => x.GetAppSettingsAsync())
|
||||||
.ReturnsAsync(testSettingsJson);
|
.ReturnsAsync(testSettings);
|
||||||
|
|
||||||
var result = await _sut.ExecuteAsync(null!);
|
var result = await _sut.ExecuteAsync(null!);
|
||||||
|
|
||||||
@@ -96,28 +78,6 @@ public class ListConfigCommandTests : IDisposable
|
|||||||
.Contain("provider key (default)");
|
.Contain("provider key (default)");
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public async Task ExecuteAsync_WhenSettingsCanNotBeDeserialized_ItShouldThrowConfigException()
|
|
||||||
{
|
|
||||||
var testSettingsPath = "appsettings.json";
|
|
||||||
|
|
||||||
_fileSystem
|
|
||||||
.Setup(static x => x.Path.Combine(It.IsAny<string>(), It.IsAny<string>()))
|
|
||||||
.Returns(testSettingsPath);
|
|
||||||
|
|
||||||
_fileSystem
|
|
||||||
.Setup(static x => x.File.Exists(It.IsAny<string>()))
|
|
||||||
.Returns(true);
|
|
||||||
|
|
||||||
_fileSystem
|
|
||||||
.Setup(static x => x.File.ReadAllTextAsync(It.IsAny<string>(), default))
|
|
||||||
.ReturnsAsync("null");
|
|
||||||
|
|
||||||
var action = async () => await _sut.ExecuteAsync(null!);
|
|
||||||
|
|
||||||
await action.Should().ThrowAsync<ConfigException>();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
{
|
{
|
||||||
_testConsole.Dispose();
|
_testConsole.Dispose();
|
||||||
|
|||||||
@@ -2,29 +2,23 @@ namespace AltGen.Console.Tests.Unit;
|
|||||||
|
|
||||||
public class RemoveConfigCommandTests : IDisposable
|
public class RemoveConfigCommandTests : IDisposable
|
||||||
{
|
{
|
||||||
readonly Mock<IFileSystem> _fileSystem = new();
|
readonly Mock<IAppSettingsManager> _mockSettingsManager = new();
|
||||||
readonly TestConsole _testConsole = new();
|
readonly TestConsole _testConsole = new();
|
||||||
readonly RemoveConfigCommand _sut;
|
readonly RemoveConfigCommand _sut;
|
||||||
|
|
||||||
public RemoveConfigCommandTests()
|
public RemoveConfigCommandTests()
|
||||||
{
|
{
|
||||||
_sut = new RemoveConfigCommand(_fileSystem.Object, _testConsole);
|
_sut = new RemoveConfigCommand(_testConsole, _mockSettingsManager.Object);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public async Task ExecuteAsync_WhenSettingsDoNotExist_ItShouldThrow()
|
public async Task ExecuteAsync_WhenSettingsDoNotExist_ItShouldThrow()
|
||||||
{
|
{
|
||||||
var testSettingsPath = "appsettings.json";
|
_mockSettingsManager
|
||||||
|
.Setup(static x => x.AppSettingsExist())
|
||||||
_fileSystem
|
|
||||||
.Setup(static x => x.Path.Combine(It.IsAny<string>(), It.IsAny<string>()))
|
|
||||||
.Returns(testSettingsPath);
|
|
||||||
|
|
||||||
_fileSystem
|
|
||||||
.Setup(static x => x.Path.Exists(It.IsAny<string>()))
|
|
||||||
.Returns(false);
|
.Returns(false);
|
||||||
|
|
||||||
var commandSettings = new RemoveConfigCommand.Settings(_fileSystem.Object)
|
var commandSettings = new RemoveConfigCommand.Settings()
|
||||||
{
|
{
|
||||||
Provider = "provider",
|
Provider = "provider",
|
||||||
};
|
};
|
||||||
@@ -38,23 +32,17 @@ public class RemoveConfigCommandTests : IDisposable
|
|||||||
[Fact]
|
[Fact]
|
||||||
public async Task ExecuteAsync_WhenProviderDoesNotExist_ItShouldDoNothing()
|
public async Task ExecuteAsync_WhenProviderDoesNotExist_ItShouldDoNothing()
|
||||||
{
|
{
|
||||||
var testSettingsPath = "appsettings.json";
|
|
||||||
var testSettings = new AppSettings([]);
|
var testSettings = new AppSettings([]);
|
||||||
var testSettingsJson = JsonSerializer.Serialize(testSettings, JsonOptions.Default);
|
|
||||||
|
|
||||||
_fileSystem
|
_mockSettingsManager
|
||||||
.Setup(static x => x.Path.Combine(It.IsAny<string>(), It.IsAny<string>()))
|
.Setup(static x => x.AppSettingsExist())
|
||||||
.Returns(testSettingsPath);
|
|
||||||
|
|
||||||
_fileSystem
|
|
||||||
.Setup(static x => x.Path.Exists(It.IsAny<string>()))
|
|
||||||
.Returns(true);
|
.Returns(true);
|
||||||
|
|
||||||
_fileSystem
|
_mockSettingsManager
|
||||||
.Setup(static x => x.File.ReadAllTextAsync(It.IsAny<string>(), default))
|
.Setup(static x => x.GetAppSettingsAsync())
|
||||||
.ReturnsAsync(testSettingsJson);
|
.ReturnsAsync(testSettings);
|
||||||
|
|
||||||
var commandSettings = new RemoveConfigCommand.Settings(_fileSystem.Object)
|
var commandSettings = new RemoveConfigCommand.Settings()
|
||||||
{
|
{
|
||||||
Provider = "provider",
|
Provider = "provider",
|
||||||
};
|
};
|
||||||
@@ -63,35 +51,27 @@ public class RemoveConfigCommandTests : IDisposable
|
|||||||
|
|
||||||
result.Should().Be(0);
|
result.Should().Be(0);
|
||||||
|
|
||||||
_fileSystem
|
_mockSettingsManager.Verify(x => x.SaveAppSettingsAsync(testSettings), Times.Once);
|
||||||
.Verify(
|
|
||||||
x => x.File.WriteAllTextAsync(testSettingsPath, testSettingsJson, default),
|
|
||||||
Times.Once
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public async Task ExecuteAsync_WhenProviderExists_ItShouldRemoveProviderFromSettings()
|
public async Task ExecuteAsync_WhenProviderExists_ItShouldRemoveProviderFromSettings()
|
||||||
{
|
{
|
||||||
var testSettingsPath = "appsettings.json";
|
|
||||||
var testSettings = new AppSettings([
|
var testSettings = new AppSettings([
|
||||||
new("provider", "key", false)
|
new("provider", "key", false)
|
||||||
]);
|
]);
|
||||||
var testSettingsJson = JsonSerializer.Serialize(testSettings, JsonOptions.Default);
|
|
||||||
|
|
||||||
_fileSystem
|
var expectedSettings = new AppSettings([]);
|
||||||
.Setup(static x => x.Path.Combine(It.IsAny<string>(), It.IsAny<string>()))
|
|
||||||
.Returns(testSettingsPath);
|
|
||||||
|
|
||||||
_fileSystem
|
_mockSettingsManager
|
||||||
.Setup(static x => x.Path.Exists(It.IsAny<string>()))
|
.Setup(static x => x.AppSettingsExist())
|
||||||
.Returns(true);
|
.Returns(true);
|
||||||
|
|
||||||
_fileSystem
|
_mockSettingsManager
|
||||||
.Setup(static x => x.File.ReadAllTextAsync(It.IsAny<string>(), default))
|
.Setup(static x => x.GetAppSettingsAsync())
|
||||||
.ReturnsAsync(testSettingsJson);
|
.ReturnsAsync(testSettings);
|
||||||
|
|
||||||
var commandSettings = new RemoveConfigCommand.Settings(_fileSystem.Object)
|
var commandSettings = new RemoveConfigCommand.Settings()
|
||||||
{
|
{
|
||||||
Provider = "provider",
|
Provider = "provider",
|
||||||
};
|
};
|
||||||
@@ -100,14 +80,7 @@ public class RemoveConfigCommandTests : IDisposable
|
|||||||
|
|
||||||
result.Should().Be(0);
|
result.Should().Be(0);
|
||||||
|
|
||||||
var expectedSettings = new AppSettings([]);
|
_mockSettingsManager.Verify(x => x.SaveAppSettingsAsync(expectedSettings), Times.Once);
|
||||||
var expectedSettingsJson = JsonSerializer.Serialize(expectedSettings, JsonOptions.Default);
|
|
||||||
|
|
||||||
_fileSystem
|
|
||||||
.Verify(
|
|
||||||
x => x.File.WriteAllTextAsync(testSettingsPath, expectedSettingsJson, default),
|
|
||||||
Times.Once
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
|
|||||||
@@ -17,6 +17,7 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<InternalsVisibleTo Include="DynamicProxyGenAssembly2" />
|
||||||
<InternalsVisibleTo Include="$(AssemblyName).Tests" />
|
<InternalsVisibleTo Include="$(AssemblyName).Tests" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
|
|||||||
@@ -2,16 +2,14 @@ namespace AltGen.Console.Config;
|
|||||||
|
|
||||||
sealed class AddConfigCommand(
|
sealed class AddConfigCommand(
|
||||||
IAnsiConsole console,
|
IAnsiConsole console,
|
||||||
IFileSystem fileSystem
|
IAppSettingsManager settingsManager
|
||||||
) : AsyncCommand<AddConfigCommand.Settings>
|
) : AsyncCommand<AddConfigCommand.Settings>
|
||||||
{
|
{
|
||||||
readonly IAnsiConsole _console = console;
|
readonly IAnsiConsole _console = console;
|
||||||
readonly IFileSystem _fileSystem = fileSystem;
|
readonly IAppSettingsManager _settingsManager = settingsManager;
|
||||||
|
|
||||||
public class Settings(IFileSystem filesystem) : CommandSettings
|
public class Settings : CommandSettings
|
||||||
{
|
{
|
||||||
readonly IFileSystem _fileSystem = filesystem;
|
|
||||||
|
|
||||||
[CommandArgument(1, "<provider>")]
|
[CommandArgument(1, "<provider>")]
|
||||||
[Description("The provider to configure.")]
|
[Description("The provider to configure.")]
|
||||||
public string Provider { get; init; } = string.Empty;
|
public string Provider { get; init; } = string.Empty;
|
||||||
@@ -23,32 +21,23 @@ sealed class AddConfigCommand(
|
|||||||
[CommandOption("-d|--default")]
|
[CommandOption("-d|--default")]
|
||||||
[Description("Set the provider as the default.")]
|
[Description("Set the provider as the default.")]
|
||||||
public bool Default { get; init; }
|
public bool Default { get; init; }
|
||||||
|
|
||||||
public string SettingsPath => _fileSystem.Path.Combine(AppContext.BaseDirectory, AppSettings.SettingsFileName);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override async Task<int> ExecuteAsync(CommandContext context, Settings settings)
|
public override async Task<int> ExecuteAsync(CommandContext context, Settings settings)
|
||||||
{
|
{
|
||||||
var settingsExist = _fileSystem.File.Exists(settings.SettingsPath);
|
if (_settingsManager.AppSettingsExist() is false)
|
||||||
|
|
||||||
if (settingsExist is false)
|
|
||||||
{
|
{
|
||||||
var appSettings = new AppSettings([
|
var appSettings = new AppSettings([
|
||||||
new(settings.Provider, settings.Key, settings.Default)
|
new(settings.Provider, settings.Key, settings.Default)
|
||||||
]);
|
]);
|
||||||
|
await _settingsManager.SaveAppSettingsAsync(appSettings);
|
||||||
var json = JsonSerializer.Serialize(appSettings, JsonOptions.Default);
|
|
||||||
await _fileSystem.File.WriteAllTextAsync(settings.SettingsPath, json);
|
|
||||||
_console.MarkupLine($"[bold]{settings.Provider}[/] has been configured.");
|
_console.MarkupLine($"[bold]{settings.Provider}[/] has been configured.");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
var existingJson = await _fileSystem.File.ReadAllTextAsync(settings.SettingsPath);
|
var existingAppSettings = await _settingsManager.GetAppSettingsAsync();
|
||||||
var existingAppSettings = JsonSerializer.Deserialize<AppSettings>(existingJson, JsonOptions.Default)
|
|
||||||
?? throw new ConfigException("Failed to deserialize settings.");
|
|
||||||
var updatedAppSettings = existingAppSettings.AddOrUpdateProvider(settings);
|
var updatedAppSettings = existingAppSettings.AddOrUpdateProvider(settings);
|
||||||
var udpatedJson = JsonSerializer.Serialize(updatedAppSettings, JsonOptions.Default);
|
await _settingsManager.SaveAppSettingsAsync(updatedAppSettings);
|
||||||
await _fileSystem.File.WriteAllTextAsync(settings.SettingsPath, udpatedJson);
|
|
||||||
_console.MarkupLine($"[bold]{settings.Provider}[/] has been configured.");
|
_console.MarkupLine($"[bold]{settings.Provider}[/] has been configured.");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,30 @@
|
|||||||
|
namespace AltGen.Console.Config;
|
||||||
|
|
||||||
|
class AppSettingsManager(IFileSystem fileSystem) : IAppSettingsManager
|
||||||
|
{
|
||||||
|
const string SettingsFileName = "appsettings.json";
|
||||||
|
readonly IFileSystem _fileSystem = fileSystem;
|
||||||
|
|
||||||
|
public bool AppSettingsExist()
|
||||||
|
{
|
||||||
|
return _fileSystem.Path.Exists(SettingsFileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<AppSettings> GetAppSettingsAsync()
|
||||||
|
{
|
||||||
|
var existingJson = await _fileSystem.File.ReadAllTextAsync(GetSettingsPath());
|
||||||
|
var existingAppSettings = JsonSerializer.Deserialize<AppSettings>(existingJson, JsonOptions.Default) ?? new AppSettings([]);
|
||||||
|
return existingAppSettings;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task SaveAppSettingsAsync(AppSettings appSettings)
|
||||||
|
{
|
||||||
|
var json = JsonSerializer.Serialize(appSettings, JsonOptions.Default);
|
||||||
|
await _fileSystem.File.WriteAllTextAsync(GetSettingsPath(), json);
|
||||||
|
}
|
||||||
|
|
||||||
|
string GetSettingsPath()
|
||||||
|
{
|
||||||
|
return _fileSystem.Path.Combine(AppContext.BaseDirectory, SettingsFileName);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
namespace AltGen.Console.Config;
|
||||||
|
|
||||||
|
interface IAppSettingsManager
|
||||||
|
{
|
||||||
|
bool AppSettingsExist();
|
||||||
|
Task<AppSettings> GetAppSettingsAsync();
|
||||||
|
Task SaveAppSettingsAsync(AppSettings appSettings);
|
||||||
|
}
|
||||||
@@ -1,25 +1,23 @@
|
|||||||
|
|
||||||
namespace AltGen.Console.Config;
|
namespace AltGen.Console.Config;
|
||||||
|
|
||||||
sealed class ListConfigCommand(IAnsiConsole console, IFileSystem fileSystem) : AsyncCommand
|
sealed class ListConfigCommand(
|
||||||
|
IAnsiConsole console,
|
||||||
|
IAppSettingsManager settingsManager
|
||||||
|
) : AsyncCommand
|
||||||
{
|
{
|
||||||
readonly IAnsiConsole _console = console;
|
readonly IAnsiConsole _console = console;
|
||||||
readonly IFileSystem _fileSystem = fileSystem;
|
readonly IAppSettingsManager _settingsManager = settingsManager;
|
||||||
|
|
||||||
public override async Task<int> ExecuteAsync(CommandContext context)
|
public override async Task<int> ExecuteAsync(CommandContext context)
|
||||||
{
|
{
|
||||||
var settingsPath = _fileSystem.Path.Combine(AppContext.BaseDirectory, AppSettings.SettingsFileName);
|
if (_settingsManager.AppSettingsExist() is false)
|
||||||
var settingsExist = _fileSystem.File.Exists(settingsPath);
|
|
||||||
|
|
||||||
if (settingsExist is false)
|
|
||||||
{
|
{
|
||||||
_console.MarkupLine("No settings found.");
|
_console.MarkupLine("No settings found.");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
var settingsJson = await _fileSystem.File.ReadAllTextAsync(settingsPath);
|
var appSettings = await _settingsManager.GetAppSettingsAsync();
|
||||||
var appSettings = JsonSerializer.Deserialize<AppSettings>(settingsJson, JsonOptions.Default)
|
|
||||||
?? throw new ConfigException("Failed to deserialize settings.");
|
|
||||||
|
|
||||||
foreach (var provider in appSettings.Providers)
|
foreach (var provider in appSettings.Providers)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,39 +1,30 @@
|
|||||||
namespace AltGen.Console.Config;
|
namespace AltGen.Console.Config;
|
||||||
|
|
||||||
sealed class RemoveConfigCommand(
|
sealed class RemoveConfigCommand(
|
||||||
IFileSystem fileSystem,
|
IAnsiConsole console,
|
||||||
IAnsiConsole console
|
IAppSettingsManager settingsManager
|
||||||
) : AsyncCommand<RemoveConfigCommand.Settings>
|
) : AsyncCommand<RemoveConfigCommand.Settings>
|
||||||
{
|
{
|
||||||
readonly IFileSystem _fileSystem = fileSystem;
|
|
||||||
readonly IAnsiConsole _console = console;
|
readonly IAnsiConsole _console = console;
|
||||||
|
readonly IAppSettingsManager _settingsManager = settingsManager;
|
||||||
|
|
||||||
public class Settings(IFileSystem fileSystem) : CommandSettings
|
public class Settings : CommandSettings
|
||||||
{
|
{
|
||||||
readonly IFileSystem _fileSystem = fileSystem;
|
|
||||||
|
|
||||||
[CommandArgument(1, "<provider>")]
|
[CommandArgument(1, "<provider>")]
|
||||||
[Description("The provider to remove.")]
|
[Description("The provider to remove.")]
|
||||||
public string Provider { get; init; } = string.Empty;
|
public string Provider { get; init; } = string.Empty;
|
||||||
|
|
||||||
public string SettingsPath => _fileSystem.Path.Combine(AppContext.BaseDirectory, AppSettings.SettingsFileName);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override async Task<int> ExecuteAsync(CommandContext context, Settings settings)
|
public override async Task<int> ExecuteAsync(CommandContext context, Settings settings)
|
||||||
{
|
{
|
||||||
var exists = _fileSystem.Path.Exists(settings.SettingsPath);
|
if (_settingsManager.AppSettingsExist() is false)
|
||||||
|
|
||||||
if (exists is false)
|
|
||||||
{
|
{
|
||||||
throw new ConfigException("No existing settings found.");
|
throw new ConfigException("No existing settings found.");
|
||||||
}
|
}
|
||||||
|
|
||||||
var settingsJson = await _fileSystem.File.ReadAllTextAsync(settings.SettingsPath);
|
var appSettings = await _settingsManager.GetAppSettingsAsync();
|
||||||
var appSettings = JsonSerializer.Deserialize<AppSettings>(settingsJson, JsonOptions.Default)
|
|
||||||
?? throw new ConfigException("Failed to deserialize app settings.");
|
|
||||||
var updatedAppSettings = appSettings.RemoveProvider(settings);
|
var updatedAppSettings = appSettings.RemoveProvider(settings);
|
||||||
var updatedJson = JsonSerializer.Serialize(updatedAppSettings, JsonOptions.Default);
|
await _settingsManager.SaveAppSettingsAsync(updatedAppSettings);
|
||||||
await _fileSystem.File.WriteAllTextAsync(settings.SettingsPath, updatedJson);
|
|
||||||
_console.MarkupLine($"[bold]{settings.Provider}[/] has been removed.");
|
_console.MarkupLine($"[bold]{settings.Provider}[/] has been removed.");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
interface IAltGenService
|
interface IAltGenService
|
||||||
{
|
{
|
||||||
Task<string> GenerateAltTextAsync(GenerateAltTextRequest req);
|
Task<string> GenerateAltTextAsync(GenerateAltTextRequest req);
|
||||||
}
|
}
|
||||||
@@ -3,6 +3,7 @@
|
|||||||
.ConfigureServices(static (_, services) =>
|
.ConfigureServices(static (_, services) =>
|
||||||
{
|
{
|
||||||
services.AddSingleton<IFileSystem, FileSystem>();
|
services.AddSingleton<IFileSystem, FileSystem>();
|
||||||
|
services.AddSingleton<IAppSettingsManager, AppSettingsManager>();
|
||||||
services.AddSingleton(AnsiConsole.Console);
|
services.AddSingleton(AnsiConsole.Console);
|
||||||
services.AddHttpClient<IAltGenService, AltGenService>()
|
services.AddHttpClient<IAltGenService, AltGenService>()
|
||||||
.AddStandardResilienceHandler();
|
.AddStandardResilienceHandler();
|
||||||
|
|||||||
Reference in New Issue
Block a user