using System.Text.Json; using Bit.Core.Entities; using Bit.Core.Enums; using Bit.Core.Exceptions; using Bit.Core.Repositories; using Bit.Core.Services; using Bit.Scim.Models; using Bit.Scim.Users; using Bit.Scim.Utilities; using Bit.Test.Common.AutoFixture; using Bit.Test.Common.AutoFixture.Attributes; using NSubstitute; using Xunit; namespace Bit.Scim.Test.Users; [SutProviderCustomize] public class PatchUserCommandTests { [Theory] [BitAutoData] public async Task PatchUser_RestorePath_Success(SutProvider sutProvider, OrganizationUser organizationUser) { organizationUser.Status = Core.Enums.OrganizationUserStatusType.Revoked; sutProvider.GetDependency() .GetByIdAsync(organizationUser.Id) .Returns(organizationUser); var scimPatchModel = new Models.ScimPatchModel { Operations = new List { new ScimPatchModel.OperationModel { Op = "replace", Path = "active", Value = JsonDocument.Parse("true").RootElement } }, Schemas = new List { ScimConstants.Scim2SchemaUser } }; await sutProvider.Sut.PatchUserAsync(organizationUser.OrganizationId, organizationUser.Id, scimPatchModel); await sutProvider.GetDependency().Received(1).RestoreUserAsync(organizationUser, EventSystemUser.SCIM, Arg.Any()); } [Theory] [BitAutoData] public async Task PatchUser_RestoreValue_Success(SutProvider sutProvider, OrganizationUser organizationUser) { organizationUser.Status = Core.Enums.OrganizationUserStatusType.Revoked; sutProvider.GetDependency() .GetByIdAsync(organizationUser.Id) .Returns(organizationUser); var scimPatchModel = new Models.ScimPatchModel { Operations = new List { new ScimPatchModel.OperationModel { Op = "replace", Value = JsonDocument.Parse("{\"active\":true}").RootElement } }, Schemas = new List { ScimConstants.Scim2SchemaUser } }; await sutProvider.Sut.PatchUserAsync(organizationUser.OrganizationId, organizationUser.Id, scimPatchModel); await sutProvider.GetDependency().Received(1).RestoreUserAsync(organizationUser, EventSystemUser.SCIM, Arg.Any()); } [Theory] [BitAutoData] public async Task PatchUser_RevokePath_Success(SutProvider sutProvider, OrganizationUser organizationUser) { organizationUser.Status = Core.Enums.OrganizationUserStatusType.Confirmed; sutProvider.GetDependency() .GetByIdAsync(organizationUser.Id) .Returns(organizationUser); var scimPatchModel = new Models.ScimPatchModel { Operations = new List { new ScimPatchModel.OperationModel { Op = "replace", Path = "active", Value = JsonDocument.Parse("false").RootElement } }, Schemas = new List { ScimConstants.Scim2SchemaUser } }; await sutProvider.Sut.PatchUserAsync(organizationUser.OrganizationId, organizationUser.Id, scimPatchModel); await sutProvider.GetDependency().Received(1).RevokeUserAsync(organizationUser, EventSystemUser.SCIM); } [Theory] [BitAutoData] public async Task PatchUser_RevokeValue_Success(SutProvider sutProvider, OrganizationUser organizationUser) { organizationUser.Status = Core.Enums.OrganizationUserStatusType.Confirmed; sutProvider.GetDependency() .GetByIdAsync(organizationUser.Id) .Returns(organizationUser); var scimPatchModel = new Models.ScimPatchModel { Operations = new List { new ScimPatchModel.OperationModel { Op = "replace", Value = JsonDocument.Parse("{\"active\":false}").RootElement } }, Schemas = new List { ScimConstants.Scim2SchemaUser } }; await sutProvider.Sut.PatchUserAsync(organizationUser.OrganizationId, organizationUser.Id, scimPatchModel); await sutProvider.GetDependency().Received(1).RevokeUserAsync(organizationUser, EventSystemUser.SCIM); } [Theory] [BitAutoData] public async Task PatchUser_NoAction_Success(SutProvider sutProvider, OrganizationUser organizationUser) { sutProvider.GetDependency() .GetByIdAsync(organizationUser.Id) .Returns(organizationUser); var scimPatchModel = new Models.ScimPatchModel { Operations = new List(), Schemas = new List { ScimConstants.Scim2SchemaUser } }; await sutProvider.Sut.PatchUserAsync(organizationUser.OrganizationId, organizationUser.Id, scimPatchModel); await sutProvider.GetDependency().DidNotReceiveWithAnyArgs().RestoreUserAsync(default, EventSystemUser.SCIM, default); await sutProvider.GetDependency().DidNotReceiveWithAnyArgs().RevokeUserAsync(default, EventSystemUser.SCIM); } [Theory] [BitAutoData] public async Task PatchUser_NotFound_Throws(SutProvider sutProvider, Guid organizationId, Guid organizationUserId) { var scimPatchModel = new Models.ScimPatchModel { Operations = new List(), Schemas = new List { ScimConstants.Scim2SchemaUser } }; await Assert.ThrowsAsync(async () => await sutProvider.Sut.PatchUserAsync(organizationId, organizationUserId, scimPatchModel)); } [Theory] [BitAutoData] public async Task PatchUser_MismatchingOrganizationId_Throws(SutProvider sutProvider, Guid organizationId, Guid organizationUserId) { var scimPatchModel = new Models.ScimPatchModel { Operations = new List(), Schemas = new List { ScimConstants.Scim2SchemaUser } }; sutProvider.GetDependency() .GetByIdAsync(organizationUserId) .Returns(new OrganizationUser { Id = organizationUserId, OrganizationId = Guid.NewGuid() }); await Assert.ThrowsAsync(async () => await sutProvider.Sut.PatchUserAsync(organizationId, organizationUserId, scimPatchModel)); } }