using Bit.Api.Controllers; using Bit.Api.Models.Request; using Bit.Api.Models.Request.Organizations; using Bit.Api.Models.Response; using Bit.Api.Models.Response.Organizations; using Bit.Core.Context; using Bit.Core.Exceptions; using Bit.Core.Models.Data.Organizations; using Bit.Core.OrganizationFeatures.OrganizationDomains.Interfaces; using Bit.Core.Repositories; using Bit.Test.Common.AutoFixture; using Bit.Test.Common.AutoFixture.Attributes; using NSubstitute; using NSubstitute.ReturnsExtensions; using Xunit; using Organization = Bit.Core.Entities.Organization; using OrganizationDomain = Bit.Core.Entities.OrganizationDomain; namespace Bit.Api.Test.Controllers; [ControllerCustomize(typeof(OrganizationDomainController))] [SutProviderCustomize] public class OrganizationDomainControllerTests { [Theory, BitAutoData] public async Task Get_ShouldThrowUnauthorized_WhenOrgIdCannotManageSso(Guid orgId, SutProvider sutProvider) { sutProvider.GetDependency().ManageSso(orgId).Returns(false); var requestAction = async () => await sutProvider.Sut.Get(orgId.ToString()); await Assert.ThrowsAsync(requestAction); } [Theory, BitAutoData] public async Task Get_ShouldNotFound_WhenOrganizationDoesNotExist(Guid orgId, SutProvider sutProvider) { sutProvider.GetDependency().ManageSso(orgId).Returns(true); sutProvider.GetDependency().GetByIdAsync(orgId).ReturnsNull(); var requestAction = async () => await sutProvider.Sut.Get(orgId.ToString()); await Assert.ThrowsAsync(requestAction); } [Theory, BitAutoData] public async Task Get_ShouldReturnOrganizationDomainList_WhenOrgIdIsValid(Guid orgId, SutProvider sutProvider) { sutProvider.GetDependency().ManageSso(orgId).Returns(true); sutProvider.GetDependency().GetByIdAsync(orgId).Returns(new Organization()); sutProvider.GetDependency() .GetDomainsByOrganizationId(orgId).Returns(new List { new() { Id = Guid.NewGuid(), OrganizationId = orgId, CreationDate = DateTime.UtcNow.AddDays(-7), DomainName = "test.com", Txt = "btw+12342" } }); var result = await sutProvider.Sut.Get(orgId.ToString()); Assert.IsType>(result); Assert.Equal(orgId, result.Data.Select(x => x.OrganizationId).FirstOrDefault()); } [Theory, BitAutoData] public async Task GetByOrgIdAndId_ShouldThrowUnauthorized_WhenOrgIdCannotManageSso(Guid orgId, Guid id, SutProvider sutProvider) { sutProvider.GetDependency().ManageSso(orgId).Returns(false); var requestAction = async () => await sutProvider.Sut.Get(orgId.ToString(), id.ToString()); await Assert.ThrowsAsync(requestAction); } [Theory, BitAutoData] public async Task GetByOrgIdAndId_ShouldThrowNotFound_WhenOrganizationDoesNotExist(Guid orgId, Guid id, SutProvider sutProvider) { sutProvider.GetDependency().ManageSso(orgId).Returns(true); sutProvider.GetDependency().GetByIdAsync(orgId).ReturnsNull(); var requestAction = async () => await sutProvider.Sut.Get(orgId.ToString(), id.ToString()); await Assert.ThrowsAsync(requestAction); } [Theory, BitAutoData] public async Task GetByOrgIdAndId_ShouldThrowNotFound_WhenOrganizationDomainEntryNotExist(Guid orgId, Guid id, SutProvider sutProvider) { sutProvider.GetDependency().ManageSso(orgId).Returns(true); sutProvider.GetDependency().GetByIdAsync(orgId).Returns(new Organization()); sutProvider.GetDependency().GetOrganizationDomainById(id).ReturnsNull(); var requestAction = async () => await sutProvider.Sut.Get(orgId.ToString(), id.ToString()); await Assert.ThrowsAsync(requestAction); } [Theory, BitAutoData] public async Task Get_ShouldReturnOrganizationDomain_WhenOrgIdAndIdAreValid(Guid orgId, Guid id, SutProvider sutProvider) { sutProvider.GetDependency().ManageSso(orgId).Returns(true); sutProvider.GetDependency().GetByIdAsync(orgId).Returns(new Organization()); sutProvider.GetDependency().GetOrganizationDomainById(id) .Returns(new OrganizationDomain { Id = Guid.NewGuid(), OrganizationId = orgId, CreationDate = DateTime.UtcNow.AddDays(-7), DomainName = "test.com", Txt = "btw+12342" }); var result = await sutProvider.Sut.Get(orgId.ToString(), id.ToString()); Assert.IsType(result); Assert.Equal(orgId, result.OrganizationId); } [Theory, BitAutoData] public async Task Post_ShouldThrowUnauthorized_OrgIdCannotManageSso(Guid orgId, OrganizationDomainRequestModel model, SutProvider sutProvider) { sutProvider.GetDependency().ManageSso(orgId).Returns(false); var requestAction = async () => await sutProvider.Sut.Post(orgId.ToString(), model); await Assert.ThrowsAsync(requestAction); } [Theory, BitAutoData] public async Task Post_ShouldThrowNotFound_WhenOrganizationDoesNotExist(Guid orgId, OrganizationDomainRequestModel model, SutProvider sutProvider) { sutProvider.GetDependency().ManageSso(orgId).Returns(true); sutProvider.GetDependency().GetByIdAsync(orgId).ReturnsNull(); var requestAction = async () => await sutProvider.Sut.Post(orgId.ToString(), model); await Assert.ThrowsAsync(requestAction); } [Theory, BitAutoData] public async Task Post_ShouldCreateEntry_WhenRequestIsValid(Guid orgId, OrganizationDomainRequestModel model, SutProvider sutProvider) { sutProvider.GetDependency().ManageSso(orgId).Returns(true); sutProvider.GetDependency().GetByIdAsync(orgId).Returns(new Organization()); sutProvider.GetDependency().CreateAsync(Arg.Any()) .Returns(new OrganizationDomain()); var result = await sutProvider.Sut.Post(orgId.ToString(), model); await sutProvider.GetDependency().ReceivedWithAnyArgs(1) .CreateAsync(Arg.Any()); Assert.IsType(result); } [Theory, BitAutoData] public async Task Verify_ShouldThrowUnauthorized_WhenOrgIdCannotManageSso(Guid orgId, Guid id, SutProvider sutProvider) { sutProvider.GetDependency().ManageSso(orgId).Returns(false); var requestAction = async () => await sutProvider.Sut.Verify(orgId.ToString(), id.ToString()); await Assert.ThrowsAsync(requestAction); } [Theory, BitAutoData] public async Task Verify_ShouldThrowNotFound_WhenOrganizationDoesNotExist(Guid orgId, Guid id, SutProvider sutProvider) { sutProvider.GetDependency().ManageSso(orgId).Returns(true); sutProvider.GetDependency().GetByIdAsync(orgId).ReturnsNull(); var requestAction = async () => await sutProvider.Sut.Verify(orgId.ToString(), id.ToString()); await Assert.ThrowsAsync(requestAction); } [Theory, BitAutoData] public async Task Verify_WhenRequestIsValid(Guid orgId, Guid id, SutProvider sutProvider) { sutProvider.GetDependency().ManageSso(orgId).Returns(true); sutProvider.GetDependency().GetByIdAsync(orgId).Returns(new Organization()); sutProvider.GetDependency().VerifyOrganizationDomain(id) .Returns(new OrganizationDomain()); var result = await sutProvider.Sut.Verify(orgId.ToString(), id.ToString()); await sutProvider.GetDependency().Received(1) .VerifyOrganizationDomain(id); Assert.IsType(result); } [Theory, BitAutoData] public async Task RemoveDomain_ShouldThrowUnauthorized_OrgIdCannotManageSso(Guid orgId, Guid id, SutProvider sutProvider) { sutProvider.GetDependency().ManageSso(orgId).Returns(false); var requestAction = async () => await sutProvider.Sut.RemoveDomain(orgId.ToString(), id.ToString()); await Assert.ThrowsAsync(requestAction); } [Theory, BitAutoData] public async Task RemoveDomain_ShouldThrowNotFound_WhenOrganizationDoesNotExist(Guid orgId, Guid id, SutProvider sutProvider) { sutProvider.GetDependency().ManageSso(orgId).Returns(true); sutProvider.GetDependency().GetByIdAsync(orgId).ReturnsNull(); var requestAction = async () => await sutProvider.Sut.RemoveDomain(orgId.ToString(), id.ToString()); await Assert.ThrowsAsync(requestAction); } [Theory, BitAutoData] public async Task RemoveDomain_WhenRequestIsValid(Guid orgId, Guid id, SutProvider sutProvider) { sutProvider.GetDependency().ManageSso(orgId).Returns(true); sutProvider.GetDependency().GetByIdAsync(orgId).Returns(new Organization()); await sutProvider.Sut.RemoveDomain(orgId.ToString(), id.ToString()); await sutProvider.GetDependency().Received(1) .DeleteAsync(id); } [Theory, BitAutoData] public async Task GetOrgDomainSsoDetails_ShouldThrowNotFound_WhenEmailHasNotClaimedDomain( OrganizationDomainSsoDetailsRequestModel model, SutProvider sutProvider) { sutProvider.GetDependency() .GetOrganizationDomainSsoDetailsAsync(model.Email).ReturnsNull(); var requestAction = async () => await sutProvider.Sut.GetOrgDomainSsoDetails(model); await Assert.ThrowsAsync(requestAction); } [Theory, BitAutoData] public async Task GetOrgDomainSsoDetails_ShouldReturnOrganizationDomainSsoDetails_WhenEmailHasClaimedDomain( OrganizationDomainSsoDetailsRequestModel model, OrganizationDomainSsoDetailsData ssoDetailsData, SutProvider sutProvider) { sutProvider.GetDependency() .GetOrganizationDomainSsoDetailsAsync(model.Email).Returns(ssoDetailsData); var result = await sutProvider.Sut.GetOrgDomainSsoDetails(model); Assert.IsType(result); } }