KeyValueListCommandTests.cs•6.63 kB
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
using System.CommandLine.Parsing;
using System.Text.Json;
using AzureMcp.AppConfig.Commands.KeyValue;
using AzureMcp.AppConfig.Models;
using AzureMcp.AppConfig.Services;
using AzureMcp.Core.Models.Command;
using AzureMcp.Core.Options;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using NSubstitute;
using NSubstitute.ExceptionExtensions;
using Xunit;
using static AzureMcp.AppConfig.Commands.KeyValue.KeyValueListCommand;
namespace AzureMcp.AppConfig.UnitTests.KeyValue;
[Trait("Area", "AppConfig")]
public class KeyValueListCommandTests
{
    private readonly IServiceProvider _serviceProvider;
    private readonly IAppConfigService _appConfigService;
    private readonly ILogger<KeyValueListCommand> _logger;
    private readonly KeyValueListCommand _command;
    private readonly CommandContext _context;
    private readonly Parser _parser;
    public KeyValueListCommandTests()
    {
        _appConfigService = Substitute.For<IAppConfigService>();
        _logger = Substitute.For<ILogger<KeyValueListCommand>>();
        _command = new(_logger);
        _parser = new(_command.GetCommand());
        _serviceProvider = new ServiceCollection()
            .AddSingleton(_appConfigService)
            .BuildServiceProvider();
        _context = new(_serviceProvider);
    }
    [Fact]
    public async Task ExecuteAsync_ReturnsSettings_WhenSettingsExist()
    {
        // Arrange
        var expectedSettings = new List<KeyValueSetting>
        {
            new() { Key = "key1", Value = "value1", Label = "prod" },
            new() { Key = "key2", Value = "value2", Label = "dev" }
        };
        _appConfigService.ListKeyValues(
          Arg.Any<string>(),
          Arg.Any<string>(),
          Arg.Any<string>(),
          Arg.Any<string>(),
          Arg.Any<string>(),
          Arg.Any<RetryPolicyOptions>())
          .Returns(expectedSettings);
        var args = _parser.Parse(["--subscription", "sub123", "--account", "account1"]);
        // Act
        var response = await _command.ExecuteAsync(_context, args);
        // Assert
        Assert.Equal(200, response.Status);
        Assert.NotNull(response.Results);
        var json = JsonSerializer.Serialize(response.Results);
        var result = JsonSerializer.Deserialize<KeyValueListCommandResult>(json, new JsonSerializerOptions
        {
            PropertyNamingPolicy = JsonNamingPolicy.CamelCase
        });
        Assert.NotNull(result);
        Assert.Equal(2, result.Settings.Count);
        Assert.Equal("key1", result.Settings[0].Key);
        Assert.Equal("key2", result.Settings[1].Key);
    }
    [Fact]
    public async Task ExecuteAsync_ReturnsFilteredSettings_WhenKeyFilterProvided()
    {
        // Arrange
        var expectedSettings = new List<KeyValueSetting>
        {
            new() { Key = "key1", Value = "value1", Label = "prod" }
        };
        _appConfigService.ListKeyValues(
          Arg.Any<string>(),
          Arg.Any<string>(),
          Arg.Any<string>(),
          Arg.Any<string>(),
          Arg.Any<string>(),
          Arg.Any<RetryPolicyOptions>())
          .Returns(expectedSettings);
        var args = _parser.Parse(["--subscription", "sub123", "--account", "account1", "--key", "key1"]);
        // Act
        var response = await _command.ExecuteAsync(_context, args);
        // Assert
        Assert.Equal(200, response.Status);
        Assert.NotNull(response.Results);
        var json = JsonSerializer.Serialize(response.Results);
        var result = JsonSerializer.Deserialize<KeyValueListCommandResult>(json, new JsonSerializerOptions
        {
            PropertyNamingPolicy = JsonNamingPolicy.CamelCase
        });
        Assert.NotNull(result);
        Assert.Single(result.Settings);
        Assert.Equal("key1", result.Settings[0].Key);
        Assert.Equal("value1", result.Settings[0].Value);
        Assert.Equal("prod", result.Settings[0].Label);
    }
    [Fact]
    public async Task ExecuteAsync_ReturnsFilteredSettings_WhenLabelFilterProvided()
    {
        // Arrange
        var expectedSettings = new List<KeyValueSetting>
        {
            new() { Key = "key1", Value = "value1", Label = "prod" }
        };
        _appConfigService.ListKeyValues(
          Arg.Any<string>(),
          Arg.Any<string>(),
          Arg.Any<string>(),
          Arg.Any<string>(),
          Arg.Any<string>(),
          Arg.Any<RetryPolicyOptions>())
          .Returns(expectedSettings);
        var args = _parser.Parse(["--subscription", "sub123", "--account", "account1", "--label", "prod"]);
        // Act
        var response = await _command.ExecuteAsync(_context, args);
        // Assert
        Assert.Equal(200, response.Status);
        Assert.NotNull(response.Results);
        var json = JsonSerializer.Serialize(response.Results);
        var result = JsonSerializer.Deserialize<KeyValueListCommandResult>(json, new JsonSerializerOptions
        {
            PropertyNamingPolicy = JsonNamingPolicy.CamelCase
        });
        Assert.NotNull(result);
        Assert.Single(result.Settings);
        Assert.Equal("key1", result.Settings[0].Key);
        Assert.Equal("value1", result.Settings[0].Value);
        Assert.Equal("prod", result.Settings[0].Label);
    }
    [Fact]
    public async Task ExecuteAsync_Returns500_WhenServiceThrowsException()
    {
        // Arrange
        _appConfigService.ListKeyValues(Arg.Any<string>(),
            Arg.Any<string>(),
            Arg.Any<string>(),
            Arg.Any<string>(),
            Arg.Any<string>(),
            Arg.Any<RetryPolicyOptions>())
            .ThrowsAsync(new Exception("Service error"));
        var args = _parser.Parse(["--subscription", "sub123", "--account", "account1"]);
        // Act
        var response = await _command.ExecuteAsync(_context, args);
        // Assert
        Assert.Equal(500, response.Status);
        Assert.Contains("Service error", response.Message);
    }
    [Theory]
    [InlineData("--account", "account1")] // Missing subscription
    [InlineData("--subscription", "sub123")] // Missing account
    public async Task ExecuteAsync_Returns400_WhenRequiredParametersAreMissing(params string[] args)
    {
        // Arrange
        var parseResult = _parser.Parse(args);
        // Act
        var response = await _command.ExecuteAsync(_context, parseResult);
        // Assert
        Assert.Equal(400, response.Status);
        Assert.Contains("required", response.Message.ToLower());
    }
}