using Bit.Api.AdminConsole.Controllers; using Bit.Core.Context; using Bit.Core.Enums; using Bit.Core.Exceptions; using Bit.Core.Models.Data.Integrations; using Bit.Core.Repositories; using Bit.Core.Services; using Bit.Test.Common.AutoFixture; using Bit.Test.Common.AutoFixture.Attributes; using Microsoft.AspNetCore.Mvc; using NSubstitute; using Xunit; namespace Bit.Api.Test.AdminConsole.Controllers; [ControllerCustomize(typeof(SlackOAuthController))] [SutProviderCustomize] public class SlackOAuthControllerTests { [Theory, BitAutoData] public async Task OAuthCallback_CompletesSuccessfully(SutProvider sutProvider, Guid organizationId) { var token = "xoxb-test-token"; sutProvider.Sut.Url = Substitute.For(); sutProvider.GetDependency() .OrganizationOwner(organizationId) .Returns(true); sutProvider.GetDependency() .ObtainTokenViaOAuth(Arg.Any(), Arg.Any()) .Returns(token); var requestAction = await sutProvider.Sut.OAuthCallback(organizationId.ToString(), "A_test_code"); await sutProvider.GetDependency().Received(1) .CreateOrganizationIntegrationAsync(organizationId, IntegrationType.Slack, new SlackIntegration(token)); Assert.IsType(requestAction); } [Theory, BitAutoData] public async Task OAuthCallback_ThrowsBadResultWhenCodeIsEmpty(SutProvider sutProvider, Guid organizationId) { sutProvider.Sut.Url = Substitute.For(); sutProvider.GetDependency() .OrganizationOwner(organizationId) .Returns(true); await Assert.ThrowsAsync(async () => await sutProvider.Sut.OAuthCallback(organizationId.ToString(), string.Empty)); } [Theory, BitAutoData] public async Task OAuthCallback_ThrowsBadResultWhenSlackServiceReturnsEmpty(SutProvider sutProvider, Guid organizationId) { sutProvider.Sut.Url = Substitute.For(); sutProvider.GetDependency() .OrganizationOwner(organizationId) .Returns(true); sutProvider.GetDependency() .ObtainTokenViaOAuth(Arg.Any(), Arg.Any()) .Returns(string.Empty); await Assert.ThrowsAsync(async () => await sutProvider.Sut.OAuthCallback(organizationId.ToString(), "A_test_code")); } [Theory, BitAutoData] public async Task OAuthCallback_ThrowsNotFoundIfUserIsNotOrganizationAdmin(SutProvider sutProvider, Guid organizationId) { var token = "xoxb-test-token"; sutProvider.Sut.Url = Substitute.For(); sutProvider.GetDependency() .OrganizationOwner(organizationId) .Returns(false); sutProvider.GetDependency() .ObtainTokenViaOAuth(Arg.Any(), Arg.Any()) .Returns(token); await Assert.ThrowsAsync(async () => await sutProvider.Sut.OAuthCallback(organizationId.ToString(), "A_test_code")); } [Theory, BitAutoData] public async Task Redirect_ShouldRedirectToSlack(SutProvider sutProvider, Guid organizationId) { var expectedUrl = $"https://localhost/{organizationId.ToString()}"; sutProvider.Sut.Url = Substitute.For(); sutProvider.GetDependency().GetRedirectUrl(Arg.Any()).Returns(expectedUrl); sutProvider.GetDependency() .OrganizationOwner(organizationId) .Returns(true); sutProvider.GetDependency() .HttpContext.Request.Scheme .Returns("https"); var requestAction = await sutProvider.Sut.RedirectToSlack(organizationId.ToString()); var redirectResult = Assert.IsType(requestAction); Assert.Equal(expectedUrl, redirectResult.Url); } [Theory, BitAutoData] public async Task Redirect_ThrowsNotFoundWhenSlackServiceReturnsEmpty(SutProvider sutProvider, Guid organizationId) { sutProvider.Sut.Url = Substitute.For(); sutProvider.GetDependency().GetRedirectUrl(Arg.Any()).Returns(string.Empty); sutProvider.GetDependency() .OrganizationOwner(organizationId) .Returns(true); sutProvider.GetDependency() .HttpContext.Request.Scheme .Returns("https"); await Assert.ThrowsAsync(async () => await sutProvider.Sut.RedirectToSlack(organizationId.ToString())); } [Theory, BitAutoData] public async Task Redirect_ThrowsNotFoundWhenUserIsNotOrganizationAdmin(SutProvider sutProvider, Guid organizationId) { sutProvider.Sut.Url = Substitute.For(); sutProvider.GetDependency().GetRedirectUrl(Arg.Any()).Returns(string.Empty); sutProvider.GetDependency() .OrganizationOwner(organizationId) .Returns(false); sutProvider.GetDependency() .HttpContext.Request.Scheme .Returns("https"); await Assert.ThrowsAsync(async () => await sutProvider.Sut.RedirectToSlack(organizationId.ToString())); } }