using Bit.Core.AdminConsole.Models.Data.EventIntegrations; using Bit.Core.Models.Slack; using Bit.Core.Services; using Bit.Test.Common.AutoFixture; using Bit.Test.Common.AutoFixture.Attributes; using Bit.Test.Common.Helpers; using NSubstitute; using Xunit; namespace Bit.Core.Test.Services; [SutProviderCustomize] public class SlackIntegrationHandlerTests { private readonly ISlackService _slackService = Substitute.For(); private readonly string _channelId = "C12345"; private readonly string _token = "xoxb-test-token"; private SutProvider GetSutProvider() { return new SutProvider() .SetDependency(_slackService) .Create(); } [Theory, BitAutoData] public async Task HandleAsync_SuccessfulRequest_ReturnsSuccess(IntegrationMessage message) { var sutProvider = GetSutProvider(); message.Configuration = new SlackIntegrationConfigurationDetails(_channelId, _token); _slackService.SendSlackMessageByChannelIdAsync(Arg.Any(), Arg.Any(), Arg.Any()) .Returns(new SlackSendMessageResponse() { Ok = true, Channel = _channelId }); var result = await sutProvider.Sut.HandleAsync(message); Assert.True(result.Success); Assert.Equal(result.Message, message); await sutProvider.GetDependency().Received(1).SendSlackMessageByChannelIdAsync( Arg.Is(AssertHelper.AssertPropertyEqual(_token)), Arg.Is(AssertHelper.AssertPropertyEqual(message.RenderedTemplate)), Arg.Is(AssertHelper.AssertPropertyEqual(_channelId)) ); } [Theory] [InlineData("service_unavailable")] [InlineData("ratelimited")] [InlineData("rate_limited")] [InlineData("internal_error")] [InlineData("message_limit_exceeded")] public async Task HandleAsync_FailedRetryableRequest_ReturnsFailureWithRetryable(string error) { var sutProvider = GetSutProvider(); var message = new IntegrationMessage() { Configuration = new SlackIntegrationConfigurationDetails(_channelId, _token), MessageId = "MessageId", RenderedTemplate = "Test Message" }; _slackService.SendSlackMessageByChannelIdAsync(Arg.Any(), Arg.Any(), Arg.Any()) .Returns(new SlackSendMessageResponse() { Ok = false, Channel = _channelId, Error = error }); var result = await sutProvider.Sut.HandleAsync(message); Assert.False(result.Success); Assert.True(result.Retryable); Assert.NotNull(result.FailureReason); Assert.Equal(result.Message, message); await sutProvider.GetDependency().Received(1).SendSlackMessageByChannelIdAsync( Arg.Is(AssertHelper.AssertPropertyEqual(_token)), Arg.Is(AssertHelper.AssertPropertyEqual(message.RenderedTemplate)), Arg.Is(AssertHelper.AssertPropertyEqual(_channelId)) ); } [Theory] [InlineData("access_denied")] [InlineData("channel_not_found")] [InlineData("token_expired")] [InlineData("token_revoked")] public async Task HandleAsync_FailedNonRetryableRequest_ReturnsNonRetryableFailure(string error) { var sutProvider = GetSutProvider(); var message = new IntegrationMessage() { Configuration = new SlackIntegrationConfigurationDetails(_channelId, _token), MessageId = "MessageId", RenderedTemplate = "Test Message" }; _slackService.SendSlackMessageByChannelIdAsync(Arg.Any(), Arg.Any(), Arg.Any()) .Returns(new SlackSendMessageResponse() { Ok = false, Channel = _channelId, Error = error }); var result = await sutProvider.Sut.HandleAsync(message); Assert.False(result.Success); Assert.False(result.Retryable); Assert.NotNull(result.FailureReason); Assert.Equal(result.Message, message); await sutProvider.GetDependency().Received(1).SendSlackMessageByChannelIdAsync( Arg.Is(AssertHelper.AssertPropertyEqual(_token)), Arg.Is(AssertHelper.AssertPropertyEqual(message.RenderedTemplate)), Arg.Is(AssertHelper.AssertPropertyEqual(_channelId)) ); } [Fact] public async Task HandleAsync_NullResponse_ReturnsNonRetryableFailure() { var sutProvider = GetSutProvider(); var message = new IntegrationMessage() { Configuration = new SlackIntegrationConfigurationDetails(_channelId, _token), MessageId = "MessageId", RenderedTemplate = "Test Message" }; _slackService.SendSlackMessageByChannelIdAsync(Arg.Any(), Arg.Any(), Arg.Any()) .Returns((SlackSendMessageResponse?)null); var result = await sutProvider.Sut.HandleAsync(message); Assert.False(result.Success); Assert.False(result.Retryable); Assert.Equal("Slack response was null", result.FailureReason); Assert.Equal(result.Message, message); await sutProvider.GetDependency().Received(1).SendSlackMessageByChannelIdAsync( Arg.Is(AssertHelper.AssertPropertyEqual(_token)), Arg.Is(AssertHelper.AssertPropertyEqual(message.RenderedTemplate)), Arg.Is(AssertHelper.AssertPropertyEqual(_channelId)) ); } }