diff --git a/src/Core/AdminConsole/OrganizationFeatures/OrganizationUsers/DeleteManagedOrganizationUserAccountCommand.cs b/src/Core/AdminConsole/OrganizationFeatures/OrganizationUsers/DeleteManagedOrganizationUserAccountCommand.cs index 52b99538a5..648e9b7eec 100644 --- a/src/Core/AdminConsole/OrganizationFeatures/OrganizationUsers/DeleteManagedOrganizationUserAccountCommand.cs +++ b/src/Core/AdminConsole/OrganizationFeatures/OrganizationUsers/DeleteManagedOrganizationUserAccountCommand.cs @@ -19,6 +19,7 @@ public class DeleteManagedOrganizationUserAccountCommand : IDeleteManagedOrganiz private readonly IUserRepository _userRepository; private readonly ICurrentContext _currentContext; private readonly IHasConfirmedOwnersExceptQuery _hasConfirmedOwnersExceptQuery; + private readonly IFeatureService _featureService; public DeleteManagedOrganizationUserAccountCommand( IUserService userService, @@ -27,7 +28,8 @@ public class DeleteManagedOrganizationUserAccountCommand : IDeleteManagedOrganiz IOrganizationUserRepository organizationUserRepository, IUserRepository userRepository, ICurrentContext currentContext, - IHasConfirmedOwnersExceptQuery hasConfirmedOwnersExceptQuery) + IHasConfirmedOwnersExceptQuery hasConfirmedOwnersExceptQuery, + IFeatureService featureService) { _userService = userService; _eventService = eventService; @@ -36,6 +38,7 @@ public class DeleteManagedOrganizationUserAccountCommand : IDeleteManagedOrganiz _userRepository = userRepository; _currentContext = currentContext; _hasConfirmedOwnersExceptQuery = hasConfirmedOwnersExceptQuery; + _featureService = featureService; } public async Task DeleteUserAsync(Guid organizationId, Guid organizationUserId, Guid? deletingUserId) @@ -71,6 +74,7 @@ public class DeleteManagedOrganizationUserAccountCommand : IDeleteManagedOrganiz var hasOtherConfirmedOwners = await _hasConfirmedOwnersExceptQuery.HasConfirmedOwnersExceptAsync(organizationId, orgUserIds, includeProvider: true); var results = new List<(Guid OrganizationUserId, string? ErrorMessage)>(); + var accountDeprovisioningEnabled = _featureService.IsEnabled(FeatureFlagKeys.AccountDeprovisioning); foreach (var orgUserId in orgUserIds) { try @@ -88,7 +92,10 @@ public class DeleteManagedOrganizationUserAccountCommand : IDeleteManagedOrganiz { throw new NotFoundException("Member not found."); } - + if (!accountDeprovisioningEnabled) + { + await _userService.DeleteAsync(user); + } results.Add((orgUserId, string.Empty)); } catch (Exception ex) @@ -97,7 +104,10 @@ public class DeleteManagedOrganizationUserAccountCommand : IDeleteManagedOrganiz } } - await _userService.DeleteManyAsync(users); + if (accountDeprovisioningEnabled) + { + await _userService.DeleteManyAsync(users); + } await LogDeletedOrganizationUsersAsync(orgUsers, results); return results; diff --git a/test/Core.Test/AdminConsole/OrganizationFeatures/OrganizationUsers/DeleteManagedOrganizationUserAccountCommandTests.cs b/test/Core.Test/AdminConsole/OrganizationFeatures/OrganizationUsers/DeleteManagedOrganizationUserAccountCommandTests.cs index 0f3040c6f5..6a40b360d4 100644 --- a/test/Core.Test/AdminConsole/OrganizationFeatures/OrganizationUsers/DeleteManagedOrganizationUserAccountCommandTests.cs +++ b/test/Core.Test/AdminConsole/OrganizationFeatures/OrganizationUsers/DeleteManagedOrganizationUserAccountCommandTests.cs @@ -235,7 +235,7 @@ public class DeleteManagedOrganizationUserAccountCommandTests [Theory] [BitAutoData] - public async Task DeleteManyUsersAsync_WithValidUsers_DeletesUsersAndLogsEvents( + public async Task DeleteManyUsersAsync_WhenFeatureFlagEnabled_WithValidUsers_DeletesUsersAndLogsEvents( SutProvider sutProvider, User user1, User user2, Guid organizationId, [OrganizationUser(OrganizationUserStatusType.Confirmed, OrganizationUserType.User)] OrganizationUser orgUser1, [OrganizationUser(OrganizationUserStatusType.Confirmed, OrganizationUserType.User)] OrganizationUser orgUser2) @@ -257,6 +257,9 @@ public class DeleteManagedOrganizationUserAccountCommandTests .GetUsersOrganizationManagementStatusAsync(organizationId, Arg.Any>()) .Returns(new Dictionary { { orgUser1.Id, true }, { orgUser2.Id, true } }); + sutProvider.GetDependency() + .IsEnabled(FeatureFlagKeys.AccountDeprovisioning).Returns(true); + // Act var userIds = new[] { orgUser1.Id, orgUser2.Id }; var results = await sutProvider.Sut.DeleteManyUsersAsync(organizationId, userIds, null); @@ -267,6 +270,7 @@ public class DeleteManagedOrganizationUserAccountCommandTests await sutProvider.GetDependency().Received(1).GetManyAsync(userIds); await sutProvider.GetDependency().Received(1).DeleteManyAsync(Arg.Any>()); + await sutProvider.GetDependency().Received(0).DeleteAsync(Arg.Any()); await sutProvider.GetDependency().Received(1).LogOrganizationUserEventsAsync( Arg.Is>(events => events.Count(e => e.Item1.Id == orgUser1.Id && e.Item2 == EventType.OrganizationUser_Deleted) == 1 @@ -275,11 +279,59 @@ public class DeleteManagedOrganizationUserAccountCommandTests [Theory] [BitAutoData] - public async Task DeleteManyUsersAsync_WhenUserNotFound_ReturnsErrorMessage( + public async Task DeleteManyUsersAsync_WhenFeatureFlagDisabled_WithValidUsers_DeletesUsersAndLogsEvents( + SutProvider sutProvider, User user1, User user2, Guid organizationId, + [OrganizationUser(OrganizationUserStatusType.Confirmed, OrganizationUserType.User)] OrganizationUser orgUser1, + [OrganizationUser(OrganizationUserStatusType.Confirmed, OrganizationUserType.User)] OrganizationUser orgUser2) + { + // Arrange + orgUser1.OrganizationId = orgUser2.OrganizationId = organizationId; + orgUser1.UserId = user1.Id; + orgUser2.UserId = user2.Id; + + sutProvider.GetDependency() + .GetManyAsync(Arg.Any>()) + .Returns(new List { orgUser1, orgUser2 }); + + sutProvider.GetDependency() + .GetManyAsync(Arg.Is>(ids => ids.Contains(user1.Id) && ids.Contains(user2.Id))) + .Returns(new[] { user1, user2 }); + + sutProvider.GetDependency() + .GetUsersOrganizationManagementStatusAsync(organizationId, Arg.Any>()) + .Returns(new Dictionary { { orgUser1.Id, true }, { orgUser2.Id, true } }); + + sutProvider.GetDependency() + .IsEnabled(FeatureFlagKeys.AccountDeprovisioning).Returns(false); + + // Act + var userIds = new[] { orgUser1.Id, orgUser2.Id }; + var results = await sutProvider.Sut.DeleteManyUsersAsync(organizationId, userIds, null); + + // Assert + Assert.Equal(2, results.Count()); + Assert.All(results, r => Assert.Empty(r.Item2)); + + await sutProvider.GetDependency().Received(1).GetManyAsync(userIds); + await sutProvider.GetDependency().Received(0).DeleteManyAsync(Arg.Any>()); + await sutProvider.GetDependency().Received(2).DeleteAsync(Arg.Any()); + await sutProvider.GetDependency().Received(1).LogOrganizationUserEventsAsync( + Arg.Is>(events => + events.Count(e => e.Item1.Id == orgUser1.Id && e.Item2 == EventType.OrganizationUser_Deleted) == 1 + && events.Count(e => e.Item1.Id == orgUser2.Id && e.Item2 == EventType.OrganizationUser_Deleted) == 1)); + } + + [Theory] + [BitAutoData] + public async Task DeleteManyUsersAsync_WhenFeatureFlagEnabled_WhenUserNotFound_ReturnsErrorMessage( SutProvider sutProvider, Guid organizationId, Guid orgUserId) { + // Arrang + sutProvider.GetDependency() + .IsEnabled(FeatureFlagKeys.AccountDeprovisioning).Returns(true); + // Act var result = await sutProvider.Sut.DeleteManyUsersAsync(organizationId, new[] { orgUserId }, null); @@ -287,6 +339,30 @@ public class DeleteManagedOrganizationUserAccountCommandTests Assert.Single(result); Assert.Equal(orgUserId, result.First().Item1); Assert.Contains("Member not found.", result.First().Item2); + await sutProvider.GetDependency().Received(1).DeleteManyAsync(Arg.Any>()); + await sutProvider.GetDependency().Received(0) + .LogOrganizationUserEventsAsync(Arg.Any>()); + } + + [Theory] + [BitAutoData] + public async Task DeleteManyUsersAsync_WhenFeatureFlagDisabled_WhenUserNotFound_ReturnsErrorMessage( + SutProvider sutProvider, + Guid organizationId, + Guid orgUserId) + { + // Arrang + sutProvider.GetDependency() + .IsEnabled(FeatureFlagKeys.AccountDeprovisioning).Returns(false); + + // Act + var result = await sutProvider.Sut.DeleteManyUsersAsync(organizationId, new[] { orgUserId }, null); + + // Assert + Assert.Single(result); + Assert.Equal(orgUserId, result.First().Item1); + Assert.Contains("Member not found.", result.First().Item2); + await sutProvider.GetDependency().Received(0).DeleteManyAsync(Arg.Any>()); await sutProvider.GetDependency().Received(0).DeleteAsync(Arg.Any()); await sutProvider.GetDependency().Received(0) .LogOrganizationUserEventsAsync(Arg.Any>());