feat(cli): notification smtp update --transport smtp|ews
This commit is contained in:
@@ -144,6 +144,7 @@ public static class NotificationCommands
|
|||||||
updateCmd.Add(SmtpCredentialsOption);
|
updateCmd.Add(SmtpCredentialsOption);
|
||||||
updateCmd.Add(SmtpOAuth2AuthorityOption);
|
updateCmd.Add(SmtpOAuth2AuthorityOption);
|
||||||
updateCmd.Add(SmtpOAuth2ScopeOption);
|
updateCmd.Add(SmtpOAuth2ScopeOption);
|
||||||
|
updateCmd.Add(SmtpTransportOption);
|
||||||
updateCmd.SetAction(async (ParseResult result) =>
|
updateCmd.SetAction(async (ParseResult result) =>
|
||||||
{
|
{
|
||||||
return await CommandHelpers.ExecuteCommandAsync(
|
return await CommandHelpers.ExecuteCommandAsync(
|
||||||
@@ -187,6 +188,20 @@ public static class NotificationCommands
|
|||||||
"(optional; preserves existing / M365 default if omitted)",
|
"(optional; preserves existing / M365 default if omitted)",
|
||||||
};
|
};
|
||||||
|
|
||||||
|
private static readonly Option<string?> SmtpTransportOption = CreateTransportOption();
|
||||||
|
|
||||||
|
private static Option<string?> CreateTransportOption()
|
||||||
|
{
|
||||||
|
var option = new Option<string?>("--transport")
|
||||||
|
{
|
||||||
|
Description = "Email transport: Smtp or Ews (optional; preserves existing if omitted). " +
|
||||||
|
"Under Ews, --server is the full EWS URL (https://…/ews/exchange.asmx), " +
|
||||||
|
"--auth-mode must be basic, and --port/--tls-mode are unused.",
|
||||||
|
};
|
||||||
|
option.AcceptOnlyFromAmong("Smtp", "Ews");
|
||||||
|
return option;
|
||||||
|
}
|
||||||
|
|
||||||
private static Option<string?> CreateTlsModeOption()
|
private static Option<string?> CreateTlsModeOption()
|
||||||
{
|
{
|
||||||
var option = new Option<string?>("--tls-mode")
|
var option = new Option<string?>("--tls-mode")
|
||||||
@@ -200,8 +215,8 @@ public static class NotificationCommands
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Builds the <see cref="UpdateSmtpConfigCommand"/> from a parsed <c>smtp update</c>
|
/// Builds the <see cref="UpdateSmtpConfigCommand"/> from a parsed <c>smtp update</c>
|
||||||
/// invocation. The optional <c>--tls-mode</c> / <c>--credentials</c> /
|
/// invocation. The optional <c>--tls-mode</c> / <c>--credentials</c> /
|
||||||
/// <c>--oauth2-authority</c> / <c>--oauth2-scope</c> flags map to null when omitted
|
/// <c>--oauth2-authority</c> / <c>--oauth2-scope</c> / <c>--transport</c> flags map to
|
||||||
/// so the server-side handler preserves the existing values.
|
/// null when omitted so the server-side handler preserves the existing values.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="result">The parsed command-line result from the <c>smtp update</c> invocation.</param>
|
/// <param name="result">The parsed command-line result from the <c>smtp update</c> invocation.</param>
|
||||||
/// <returns>An <see cref="UpdateSmtpConfigCommand"/> populated from the parsed result.</returns>
|
/// <returns>An <see cref="UpdateSmtpConfigCommand"/> populated from the parsed result.</returns>
|
||||||
@@ -216,7 +231,8 @@ public static class NotificationCommands
|
|||||||
var credentials = result.GetValue(SmtpCredentialsOption);
|
var credentials = result.GetValue(SmtpCredentialsOption);
|
||||||
var oauth2Authority = result.GetValue(SmtpOAuth2AuthorityOption);
|
var oauth2Authority = result.GetValue(SmtpOAuth2AuthorityOption);
|
||||||
var oauth2Scope = result.GetValue(SmtpOAuth2ScopeOption);
|
var oauth2Scope = result.GetValue(SmtpOAuth2ScopeOption);
|
||||||
return new UpdateSmtpConfigCommand(id, server, port, authMode, from, tlsMode, credentials, oauth2Authority, oauth2Scope);
|
var transport = result.GetValue(SmtpTransportOption);
|
||||||
|
return new UpdateSmtpConfigCommand(id, server, port, authMode, from, tlsMode, credentials, oauth2Authority, oauth2Scope, transport);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Command BuildSms(Option<string> urlOption, Option<string> formatOption, Option<string> usernameOption, Option<string> passwordOption)
|
private static Command BuildSms(Option<string> urlOption, Option<string> formatOption, Option<string> usernameOption, Option<string> passwordOption)
|
||||||
|
|||||||
@@ -6,10 +6,11 @@ namespace ZB.MOM.WW.ScadaBridge.CLI.Tests.Commands;
|
|||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Tests for the <c>scadabridge notification smtp update</c> subcommand. The command
|
/// Tests for the <c>scadabridge notification smtp update</c> subcommand. The command
|
||||||
/// gained two optional flags — <c>--tls-mode</c> and <c>--credentials</c> — that plumb
|
/// gained optional flags — <c>--tls-mode</c>, <c>--credentials</c> and <c>--transport</c> —
|
||||||
/// through to <see cref="UpdateSmtpConfigCommand"/>. These tests pin that the flags
|
/// that plumb through to <see cref="UpdateSmtpConfigCommand"/>. These tests pin that the
|
||||||
/// parse, are genuinely optional (non-breaking), and that <c>--tls-mode</c> rejects
|
/// flags parse, are genuinely optional (non-breaking), that <c>--tls-mode</c> rejects
|
||||||
/// values outside the canonical {None, StartTLS, SSL} set.
|
/// values outside the canonical {None, StartTLS, SSL} set, and that <c>--transport</c>
|
||||||
|
/// rejects values outside {Smtp, Ews}.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class SmtpUpdateCommandTests
|
public class SmtpUpdateCommandTests
|
||||||
{
|
{
|
||||||
@@ -91,6 +92,46 @@ public class SmtpUpdateCommandTests
|
|||||||
Assert.NotEmpty(parse.Errors);
|
Assert.NotEmpty(parse.Errors);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void Update_WithTransportEws_ProducesCommandCarryingIt()
|
||||||
|
{
|
||||||
|
var parse = ParseUpdate(
|
||||||
|
"--id", "1", "--server", "https://mail.example.com/ews/exchange.asmx", "--port", "443",
|
||||||
|
"--auth-mode", "Basic", "--from-address", "noreply@example.com",
|
||||||
|
"--transport", "Ews");
|
||||||
|
|
||||||
|
Assert.Empty(parse.Errors);
|
||||||
|
var cmd = NotificationCommands.BuildUpdateSmtpConfigCommand(parse);
|
||||||
|
|
||||||
|
Assert.Equal("Ews", cmd.Transport);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void Update_WithoutTransport_ProducesCommandWithNullTransport()
|
||||||
|
{
|
||||||
|
var parse = ParseUpdate(
|
||||||
|
"--id", "2", "--server", "smtp.example.com", "--port", "25",
|
||||||
|
"--auth-mode", "Basic", "--from-address", "noreply@example.com");
|
||||||
|
|
||||||
|
Assert.Empty(parse.Errors);
|
||||||
|
var cmd = NotificationCommands.BuildUpdateSmtpConfigCommand(parse);
|
||||||
|
|
||||||
|
Assert.Null(cmd.Transport);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Theory]
|
||||||
|
[InlineData("Graph")]
|
||||||
|
[InlineData("ews")] // AcceptOnlyFromAmong is case-sensitive: constrain to canonical spelling
|
||||||
|
public void Update_TransportOption_RejectsValuesOutsideCanonicalSet(string value)
|
||||||
|
{
|
||||||
|
var parse = ParseUpdate(
|
||||||
|
"--id", "1", "--server", "smtp.example.com", "--port", "587",
|
||||||
|
"--auth-mode", "Basic", "--from-address", "noreply@example.com",
|
||||||
|
"--transport", value);
|
||||||
|
|
||||||
|
Assert.NotEmpty(parse.Errors);
|
||||||
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void Update_TlsModeAndCredentials_AreNotRequired()
|
public void Update_TlsModeAndCredentials_AreNotRequired()
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user