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.AdminConsole.EventIntegrations.OrganizationIntegrations.Interfaces; using Bit.Core.Context; using Bit.Core.Enums; using Bit.Core.Exceptions; 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(OrganizationIntegrationController))] [SutProviderCustomize] public class OrganizationIntegrationControllerTests { private readonly OrganizationIntegrationRequestModel _webhookRequestModel = new() { Configuration = null, Type = IntegrationType.Webhook }; [Theory, BitAutoData] public async Task GetAsync_UserIsNotOrganizationAdmin_ThrowsNotFound( SutProvider sutProvider, Guid organizationId) { sutProvider.Sut.Url = Substitute.For(); sutProvider.GetDependency() .OrganizationOwner(organizationId) .Returns(false); await Assert.ThrowsAsync(() => sutProvider.Sut.GetAsync(organizationId)); } [Theory, BitAutoData] public async Task GetAsync_IntegrationsExist_ReturnsIntegrations( SutProvider sutProvider, Guid organizationId, List integrations) { sutProvider.Sut.Url = Substitute.For(); sutProvider.GetDependency() .OrganizationOwner(organizationId) .Returns(true); sutProvider.GetDependency() .GetManyByOrganizationAsync(organizationId) .Returns(integrations); var result = await sutProvider.Sut.GetAsync(organizationId); await sutProvider.GetDependency().Received(1) .GetManyByOrganizationAsync(organizationId); Assert.Equal(integrations.Count, result.Count); Assert.All(result, r => Assert.IsType(r)); } [Theory, BitAutoData] public async Task GetAsync_NoIntegrations_ReturnsEmptyList( SutProvider sutProvider, Guid organizationId) { sutProvider.Sut.Url = Substitute.For(); sutProvider.GetDependency() .OrganizationOwner(organizationId) .Returns(true); sutProvider.GetDependency() .GetManyByOrganizationAsync(organizationId) .Returns([]); var result = await sutProvider.Sut.GetAsync(organizationId); Assert.Empty(result); } [Theory, BitAutoData] public async Task CreateAsync_AllParamsProvided_Succeeds( SutProvider sutProvider, Guid organizationId, OrganizationIntegration integration) { sutProvider.Sut.Url = Substitute.For(); sutProvider.GetDependency() .OrganizationOwner(organizationId) .Returns(true); sutProvider.GetDependency() .CreateAsync(Arg.Any()) .Returns(integration); var response = await sutProvider.Sut.CreateAsync(organizationId, _webhookRequestModel); await sutProvider.GetDependency().Received(1) .CreateAsync(Arg.Is(i => i.OrganizationId == organizationId && i.Type == IntegrationType.Webhook)); Assert.IsType(response); } [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, Guid integrationId) { sutProvider.Sut.Url = Substitute.For(); sutProvider.GetDependency() .OrganizationOwner(organizationId) .Returns(true); await sutProvider.Sut.DeleteAsync(organizationId, integrationId); await sutProvider.GetDependency().Received(1) .DeleteAsync(organizationId, integrationId); } [Theory, BitAutoData] [Obsolete("Obsolete")] public async Task PostDeleteAsync_AllParamsProvided_Succeeds( SutProvider sutProvider, Guid organizationId, Guid integrationId) { sutProvider.Sut.Url = Substitute.For(); sutProvider.GetDependency() .OrganizationOwner(organizationId) .Returns(true); await sutProvider.Sut.PostDeleteAsync(organizationId, integrationId); await sutProvider.GetDependency().Received(1) .DeleteAsync(organizationId, integrationId); } [Theory, BitAutoData] public async Task DeleteAsync_UserIsNotOrganizationAdmin_ThrowsNotFound( SutProvider sutProvider, Guid organizationId, Guid integrationId) { sutProvider.Sut.Url = Substitute.For(); sutProvider.GetDependency() .OrganizationOwner(organizationId) .Returns(false); await Assert.ThrowsAsync(async () => await sutProvider.Sut.DeleteAsync(organizationId, integrationId)); } [Theory, BitAutoData] public async Task UpdateAsync_AllParamsProvided_Succeeds( SutProvider sutProvider, Guid organizationId, Guid integrationId, OrganizationIntegration integration) { integration.OrganizationId = organizationId; integration.Id = integrationId; integration.Type = IntegrationType.Webhook; sutProvider.Sut.Url = Substitute.For(); sutProvider.GetDependency() .OrganizationOwner(organizationId) .Returns(true); sutProvider.GetDependency() .UpdateAsync(organizationId, integrationId, Arg.Any()) .Returns(integration); var response = await sutProvider.Sut.UpdateAsync(organizationId, integrationId, _webhookRequestModel); await sutProvider.GetDependency().Received(1) .UpdateAsync(organizationId, integrationId, Arg.Is(i => i.OrganizationId == organizationId && i.Type == IntegrationType.Webhook)); Assert.IsType(response); Assert.Equal(IntegrationType.Webhook, response.Type); } [Theory, BitAutoData] public async Task UpdateAsync_UserIsNotOrganizationAdmin_ThrowsNotFound( SutProvider sutProvider, Guid organizationId, Guid integrationId) { sutProvider.Sut.Url = Substitute.For(); sutProvider.GetDependency() .OrganizationOwner(organizationId) .Returns(false); await Assert.ThrowsAsync(async () => await sutProvider.Sut.UpdateAsync(organizationId, integrationId, _webhookRequestModel)); } }