using Bit.Api.AdminConsole.Controllers; using Bit.Api.AdminConsole.Models.Request.Organizations; using Bit.Api.AdminConsole.Models.Response.Organizations; using Bit.Core.AdminConsole.Entities; using Bit.Core.Context; using Bit.Core.Enums; using Bit.Core.Exceptions; using Bit.Core.Repositories; using Bit.Test.Common.AutoFixture; using Bit.Test.Common.AutoFixture.Attributes; using Microsoft.AspNetCore.Mvc; using NSubstitute; using NSubstitute.ReturnsExtensions; using Xunit; namespace Bit.Api.Test.AdminConsole.Controllers; [ControllerCustomize(typeof(OrganizationIntegrationController))] [SutProviderCustomize] public class OrganizationIntegrationControllerTests { private OrganizationIntegrationRequestModel _webhookRequestModel = new OrganizationIntegrationRequestModel() { Configuration = null, Type = IntegrationType.Webhook }; [Theory, BitAutoData] public async Task CreateAsync_Webhook_AllParamsProvided_Succeeds( SutProvider sutProvider, Guid organizationId) { sutProvider.Sut.Url = Substitute.For(); sutProvider.GetDependency() .OrganizationOwner(organizationId) .Returns(true); sutProvider.GetDependency() .CreateAsync(Arg.Any()) .Returns(callInfo => callInfo.Arg()); var response = await sutProvider.Sut.CreateAsync(organizationId, _webhookRequestModel); await sutProvider.GetDependency().Received(1) .CreateAsync(Arg.Any()); Assert.IsType(response); Assert.Equal(IntegrationType.Webhook, response.Type); } [Theory, BitAutoData] public async Task CreateAsync_UserIsNotOrganizationAdmin_ThrowsNotFound(SutProvider sutProvider, Guid organizationId) { sutProvider.Sut.Url = Substitute.For(); sutProvider.GetDependency() .OrganizationOwner(organizationId) .Returns(false); await Assert.ThrowsAsync(async () => await sutProvider.Sut.CreateAsync(organizationId, _webhookRequestModel)); } [Theory, BitAutoData] public async Task DeleteAsync_AllParamsProvided_Succeeds( SutProvider sutProvider, Guid organizationId, OrganizationIntegration organizationIntegration) { organizationIntegration.OrganizationId = organizationId; sutProvider.Sut.Url = Substitute.For(); sutProvider.GetDependency() .OrganizationOwner(organizationId) .Returns(true); sutProvider.GetDependency() .GetByIdAsync(Arg.Any()) .Returns(organizationIntegration); await sutProvider.Sut.DeleteAsync(organizationId, organizationIntegration.Id); await sutProvider.GetDependency().Received(1) .GetByIdAsync(organizationIntegration.Id); await sutProvider.GetDependency().Received(1) .DeleteAsync(organizationIntegration); } [Theory, BitAutoData] public async Task DeleteAsync_IntegrationDoesNotBelongToOrganization_ThrowsNotFound( SutProvider sutProvider, Guid organizationId, OrganizationIntegration organizationIntegration) { organizationIntegration.OrganizationId = Guid.NewGuid(); sutProvider.Sut.Url = Substitute.For(); sutProvider.GetDependency() .OrganizationOwner(organizationId) .Returns(true); sutProvider.GetDependency() .GetByIdAsync(Arg.Any()) .ReturnsNull(); await Assert.ThrowsAsync(async () => await sutProvider.Sut.DeleteAsync(organizationId, Guid.Empty)); } [Theory, BitAutoData] public async Task DeleteAsync_IntegrationDoesNotExist_ThrowsNotFound( SutProvider sutProvider, Guid organizationId) { sutProvider.Sut.Url = Substitute.For(); sutProvider.GetDependency() .OrganizationOwner(organizationId) .Returns(true); sutProvider.GetDependency() .GetByIdAsync(Arg.Any()) .ReturnsNull(); await Assert.ThrowsAsync(async () => await sutProvider.Sut.DeleteAsync(organizationId, Guid.Empty)); } [Theory, BitAutoData] public async Task DeleteAsync_UserIsNotOrganizationAdmin_ThrowsNotFound( SutProvider sutProvider, Guid organizationId) { sutProvider.Sut.Url = Substitute.For(); sutProvider.GetDependency() .OrganizationOwner(organizationId) .Returns(false); await Assert.ThrowsAsync(async () => await sutProvider.Sut.DeleteAsync(organizationId, Guid.Empty)); } [Theory, BitAutoData] public async Task UpdateAsync_AllParamsProvided_Succeeds( SutProvider sutProvider, Guid organizationId, OrganizationIntegration organizationIntegration) { organizationIntegration.OrganizationId = organizationId; organizationIntegration.Type = IntegrationType.Webhook; sutProvider.Sut.Url = Substitute.For(); sutProvider.GetDependency() .OrganizationOwner(organizationId) .Returns(true); sutProvider.GetDependency() .GetByIdAsync(Arg.Any()) .Returns(organizationIntegration); var response = await sutProvider.Sut.UpdateAsync(organizationId, organizationIntegration.Id, _webhookRequestModel); await sutProvider.GetDependency().Received(1) .GetByIdAsync(organizationIntegration.Id); await sutProvider.GetDependency().Received(1) .ReplaceAsync(organizationIntegration); Assert.IsType(response); Assert.Equal(IntegrationType.Webhook, response.Type); } [Theory, BitAutoData] public async Task UpdateAsync_IntegrationDoesNotBelongToOrganization_ThrowsNotFound( SutProvider sutProvider, Guid organizationId, OrganizationIntegration organizationIntegration) { organizationIntegration.OrganizationId = Guid.NewGuid(); sutProvider.Sut.Url = Substitute.For(); sutProvider.GetDependency() .OrganizationOwner(organizationId) .Returns(true); sutProvider.GetDependency() .GetByIdAsync(Arg.Any()) .ReturnsNull(); await Assert.ThrowsAsync(async () => await sutProvider.Sut.UpdateAsync(organizationId, Guid.Empty, _webhookRequestModel)); } [Theory, BitAutoData] public async Task UpdateAsync_IntegrationDoesNotExist_ThrowsNotFound( SutProvider sutProvider, Guid organizationId) { sutProvider.Sut.Url = Substitute.For(); sutProvider.GetDependency() .OrganizationOwner(organizationId) .Returns(true); sutProvider.GetDependency() .GetByIdAsync(Arg.Any()) .ReturnsNull(); await Assert.ThrowsAsync(async () => await sutProvider.Sut.UpdateAsync(organizationId, Guid.Empty, _webhookRequestModel)); } [Theory, BitAutoData] public async Task UpdateAsync_UserIsNotOrganizationAdmin_ThrowsNotFound( SutProvider sutProvider, Guid organizationId) { sutProvider.Sut.Url = Substitute.For(); sutProvider.GetDependency() .OrganizationOwner(organizationId) .Returns(false); await Assert.ThrowsAsync(async () => await sutProvider.Sut.UpdateAsync(organizationId, Guid.Empty, _webhookRequestModel)); } }