Basic tests & refactor for PostUnlockUsers
This commit is contained in:
@@ -1,12 +1,19 @@
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Net.Http;
|
||||
using System.Net.Http.Formatting;
|
||||
using System.Reflection;
|
||||
using System.Security.Cryptography;
|
||||
using System.Threading.Tasks;
|
||||
using System.Web.Http;
|
||||
using System.Web.Http.Controllers;
|
||||
using System.Web.Http.Hosting;
|
||||
using Microsoft.AspNetCore.Identity;
|
||||
using Microsoft.Owin;
|
||||
using Moq;
|
||||
using Newtonsoft.Json;
|
||||
using NUnit.Framework;
|
||||
@@ -19,12 +26,10 @@ using Umbraco.Core.Logging;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.Models.Membership;
|
||||
using Umbraco.Core.Persistence;
|
||||
using Umbraco.Core.Persistence.DatabaseModelDefinitions;
|
||||
using Umbraco.Core.Persistence.Mappers;
|
||||
using Umbraco.Core.Persistence.Querying;
|
||||
using Umbraco.Core.Persistence.SqlSyntax;
|
||||
using Umbraco.Core.Services;
|
||||
using Umbraco.Core.Strings;
|
||||
using Umbraco.Tests.TestHelpers;
|
||||
using Umbraco.Tests.TestHelpers.ControllerTesting;
|
||||
using Umbraco.Tests.TestHelpers.Entities;
|
||||
@@ -39,6 +44,9 @@ using Umbraco.Core.Configuration.UmbracoSettings;
|
||||
using Umbraco.Core.Hosting;
|
||||
using Umbraco.Web.Routing;
|
||||
using Umbraco.Core.Media;
|
||||
using Umbraco.Net;
|
||||
using Umbraco.Web.Models.Identity;
|
||||
using Umbraco.Web.Security;
|
||||
|
||||
namespace Umbraco.Tests.Web.Controllers
|
||||
{
|
||||
@@ -62,7 +70,7 @@ namespace Umbraco.Tests.Web.Controllers
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async System.Threading.Tasks.Task Save_User()
|
||||
public async Task Save_User()
|
||||
{
|
||||
ApiController CtrlFactory(HttpRequestMessage message, IUmbracoContextAccessor umbracoContextAccessor)
|
||||
{
|
||||
@@ -149,7 +157,7 @@ namespace Umbraco.Tests.Web.Controllers
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async System.Threading.Tasks.Task GetPagedUsers_Empty()
|
||||
public async Task GetPagedUsers_Empty()
|
||||
{
|
||||
ApiController CtrlFactory(HttpRequestMessage message, IUmbracoContextAccessor umbracoContextAccessor)
|
||||
{
|
||||
@@ -183,7 +191,7 @@ namespace Umbraco.Tests.Web.Controllers
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async System.Threading.Tasks.Task GetPagedUsers_10()
|
||||
public async Task GetPagedUsers_10()
|
||||
{
|
||||
ApiController CtrlFactory(HttpRequestMessage message, IUmbracoContextAccessor umbracoContextAccessor)
|
||||
{
|
||||
@@ -227,7 +235,7 @@ namespace Umbraco.Tests.Web.Controllers
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async System.Threading.Tasks.Task GetPagedUsers_Fips()
|
||||
public async Task GetPagedUsers_Fips()
|
||||
{
|
||||
await RunFipsTest("GetPagedUsers", mock =>
|
||||
{
|
||||
@@ -246,7 +254,7 @@ namespace Umbraco.Tests.Web.Controllers
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async System.Threading.Tasks.Task GetById_Fips()
|
||||
public async Task GetById_Fips()
|
||||
{
|
||||
const int mockUserId = 1234;
|
||||
var user = MockedUser.CreateUser();
|
||||
@@ -264,7 +272,7 @@ namespace Umbraco.Tests.Web.Controllers
|
||||
}
|
||||
|
||||
|
||||
private async System.Threading.Tasks.Task RunFipsTest(string action, Action<Mock<IUserService>> userServiceSetup,
|
||||
private async Task RunFipsTest(string action, Action<Mock<IUserService>> userServiceSetup,
|
||||
Action<Tuple<HttpResponseMessage, string>> verification,
|
||||
object routeDefaults = null, string url = null)
|
||||
{
|
||||
@@ -324,5 +332,185 @@ namespace Umbraco.Tests.Web.Controllers
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task PostUnlockUsers_When_UserIds_Not_Supplied_Expect_Ok_Response()
|
||||
{
|
||||
var usersController = CreateSut();
|
||||
|
||||
usersController.Request = new HttpRequestMessage();
|
||||
|
||||
var response = await usersController.PostUnlockUsers(new int[0]);
|
||||
|
||||
Assert.AreEqual(HttpStatusCode.OK, response.StatusCode);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void PostUnlockUsers_When_User_Does_Not_Exist_Expect_InvalidOperationException()
|
||||
{
|
||||
var mockUserManager = CreateMockUserManager();
|
||||
var usersController = CreateSut(mockUserManager);
|
||||
|
||||
mockUserManager.Setup(x => x.FindByIdAsync(It.IsAny<string>()))
|
||||
.ReturnsAsync((BackOfficeIdentityUser) null);
|
||||
|
||||
Assert.ThrowsAsync<InvalidOperationException>(async () => await usersController.PostUnlockUsers(new[] {1}));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task PostUnlockUsers_When_User_Lockout_Update_Fails_Expect_Failure_Response()
|
||||
{
|
||||
var mockUserManager = CreateMockUserManager();
|
||||
var usersController = CreateSut(mockUserManager);
|
||||
|
||||
const string expectedMessage = "identity error!";
|
||||
var user = new BackOfficeIdentityUser(
|
||||
new Mock<IGlobalSettings>().Object,
|
||||
1,
|
||||
new List<IReadOnlyUserGroup>())
|
||||
{
|
||||
Name = "bob"
|
||||
};
|
||||
|
||||
mockUserManager.Setup(x => x.FindByIdAsync(It.IsAny<string>()))
|
||||
.ReturnsAsync(user);
|
||||
mockUserManager.Setup(x => x.SetLockoutEndDateAsync(user, It.IsAny<DateTimeOffset?>()))
|
||||
.ReturnsAsync(IdentityResult.Failed(new IdentityError {Description = expectedMessage}));
|
||||
|
||||
var response = await usersController.PostUnlockUsers(new[] { 1 });
|
||||
|
||||
Assert.AreEqual(HttpStatusCode.BadRequest, response.StatusCode);
|
||||
Assert.True(response.Headers.TryGetValues("X-Status-Reason", out var values));
|
||||
Assert.True(values.Contains("Validation failed"));
|
||||
|
||||
var responseContent = response.Content as ObjectContent<HttpError>;
|
||||
var responseValue = responseContent?.Value as HttpError;
|
||||
Assert.NotNull(responseValue);
|
||||
Assert.True(responseValue.Message.Contains(expectedMessage));
|
||||
Assert.True(responseValue.Message.Contains(user.Id.ToString()));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task PostUnlockUsers_When_One_UserId_Supplied_Expect_User_Locked_Out_With_Correct_Response_Message()
|
||||
{
|
||||
var mockUserManager = CreateMockUserManager();
|
||||
var usersController = CreateSut(mockUserManager);
|
||||
|
||||
var user = new BackOfficeIdentityUser(
|
||||
new Mock<IGlobalSettings>().Object,
|
||||
1,
|
||||
new List<IReadOnlyUserGroup>())
|
||||
{
|
||||
Name = "bob"
|
||||
};
|
||||
|
||||
mockUserManager.Setup(x => x.FindByIdAsync(user.Id.ToString()))
|
||||
.ReturnsAsync(user);
|
||||
mockUserManager.Setup(x => x.SetLockoutEndDateAsync(user, It.IsAny<DateTimeOffset>()))
|
||||
.ReturnsAsync(IdentityResult.Success)
|
||||
.Verifiable();
|
||||
|
||||
var response = await usersController.PostUnlockUsers(new[] { user.Id });
|
||||
|
||||
Assert.AreEqual(HttpStatusCode.OK, response.StatusCode);
|
||||
|
||||
var responseContent = response.Content as ObjectContent<SimpleNotificationModel>;
|
||||
var notifications = responseContent?.Value as SimpleNotificationModel;
|
||||
Assert.NotNull(notifications);
|
||||
Assert.AreEqual(user.Name, notifications.Message);
|
||||
mockUserManager.Verify();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task PostUnlockUsers_When_Multiple_UserIds_Supplied_Expect_User_Locked_Out_With_Correct_Response_Message()
|
||||
{
|
||||
var mockUserManager = CreateMockUserManager();
|
||||
var usersController = CreateSut(mockUserManager);
|
||||
|
||||
var user1 = new BackOfficeIdentityUser(
|
||||
new Mock<IGlobalSettings>().Object,
|
||||
1,
|
||||
new List<IReadOnlyUserGroup>())
|
||||
{
|
||||
Name = "bob"
|
||||
};
|
||||
var user2 = new BackOfficeIdentityUser(
|
||||
new Mock<IGlobalSettings>().Object,
|
||||
2,
|
||||
new List<IReadOnlyUserGroup>())
|
||||
{
|
||||
Name = "alice"
|
||||
};
|
||||
var userIdsToLock = new[] {user1.Id, user2.Id};
|
||||
|
||||
mockUserManager.Setup(x => x.FindByIdAsync(user1.Id.ToString()))
|
||||
.ReturnsAsync(user1);
|
||||
mockUserManager.Setup(x => x.FindByIdAsync(user2.Id.ToString()))
|
||||
.ReturnsAsync(user2);
|
||||
mockUserManager.Setup(x => x.SetLockoutEndDateAsync(user1, It.IsAny<DateTimeOffset>()))
|
||||
.ReturnsAsync(IdentityResult.Success)
|
||||
.Verifiable();
|
||||
mockUserManager.Setup(x => x.SetLockoutEndDateAsync(user2, It.IsAny<DateTimeOffset>()))
|
||||
.ReturnsAsync(IdentityResult.Success)
|
||||
.Verifiable();
|
||||
|
||||
var response = await usersController.PostUnlockUsers(userIdsToLock);
|
||||
|
||||
Assert.AreEqual(HttpStatusCode.OK, response.StatusCode);
|
||||
|
||||
var responseContent = response.Content as ObjectContent<SimpleNotificationModel>;
|
||||
var notifications = responseContent?.Value as SimpleNotificationModel;
|
||||
Assert.NotNull(notifications);
|
||||
Assert.AreEqual(userIdsToLock.Length.ToString(), notifications.Message);
|
||||
mockUserManager.Verify();
|
||||
}
|
||||
|
||||
private UsersController CreateSut(IMock<BackOfficeUserManager<BackOfficeIdentityUser>> mockUserManager = null)
|
||||
{
|
||||
var mockLocalizedTextService = new Mock<ILocalizedTextService>();
|
||||
mockLocalizedTextService.Setup(x => x.Localize(It.IsAny<string>(), It.IsAny<CultureInfo>(), It.IsAny<IDictionary<string, string>>()))
|
||||
.Returns((string key, CultureInfo ci, IDictionary<string, string> tokens)
|
||||
=> tokens.Aggregate("", (current, next) => current + (current == string.Empty ? "" : ",") + next.Value));
|
||||
|
||||
var usersController = new UsersController(
|
||||
Factory.GetInstance<IGlobalSettings>(),
|
||||
Factory.GetInstance<IUmbracoContextAccessor>(),
|
||||
Factory.GetInstance<ISqlContext>(),
|
||||
ServiceContext.CreatePartial(localizedTextService: mockLocalizedTextService.Object),
|
||||
Factory.GetInstance<AppCaches>(),
|
||||
Factory.GetInstance<IProfilingLogger>(),
|
||||
Factory.GetInstance<IRuntimeState>(),
|
||||
Factory.GetInstance<IMediaFileSystem>(),
|
||||
ShortStringHelper,
|
||||
Factory.GetInstance<UmbracoMapper>(),
|
||||
Factory.GetInstance<IContentSettings>(),
|
||||
Factory.GetInstance<IHostingEnvironment>(),
|
||||
Factory.GetInstance<IImageUrlGenerator>(),
|
||||
Factory.GetInstance<IPublishedUrlProvider>(),
|
||||
Factory.GetInstance<ISecuritySettings>());
|
||||
|
||||
var mockOwinContext = new Mock<IOwinContext>();
|
||||
var mockUserManagerMarker = new Mock<IBackOfficeUserManagerMarker>();
|
||||
|
||||
mockOwinContext.Setup(x => x.Get<IBackOfficeUserManagerMarker>(It.IsAny<string>()))
|
||||
.Returns(mockUserManagerMarker.Object);
|
||||
mockUserManagerMarker.Setup(x => x.GetManager(It.IsAny<IOwinContext>()))
|
||||
.Returns(mockUserManager?.Object ?? CreateMockUserManager().Object);
|
||||
|
||||
usersController.Request = new HttpRequestMessage();
|
||||
usersController.Request.Properties["MS_OwinContext"] = mockOwinContext.Object;
|
||||
usersController.Request.Properties[HttpPropertyKeys.RequestContextKey] = new HttpRequestContext {Configuration = new HttpConfiguration()};
|
||||
|
||||
return usersController;
|
||||
}
|
||||
|
||||
private static Mock<BackOfficeUserManager<BackOfficeIdentityUser>> CreateMockUserManager()
|
||||
{
|
||||
return new Mock<BackOfficeUserManager<BackOfficeIdentityUser>>(
|
||||
new Mock<IPasswordConfiguration>().Object,
|
||||
new Mock<IIpResolver>().Object,
|
||||
new Mock<IUserStore<BackOfficeIdentityUser>>().Object,
|
||||
null, null, null, null, null, null, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -701,38 +701,29 @@ namespace Umbraco.Web.Editors
|
||||
[AdminUsersAuthorize("userIds")]
|
||||
public async Task<HttpResponseMessage> PostUnlockUsers([FromUri]int[] userIds)
|
||||
{
|
||||
if (userIds.Length <= 0)
|
||||
return Request.CreateResponse(HttpStatusCode.OK);
|
||||
|
||||
var user = await UserManager.FindByIdAsync(userIds[0].ToString());
|
||||
|
||||
if (userIds.Length == 1)
|
||||
{
|
||||
|
||||
|
||||
var unlockResult = await UserManager.SetLockoutEndDateAsync(user, DateTimeOffset.Now);
|
||||
if (unlockResult.Succeeded == false)
|
||||
{
|
||||
return Request.CreateValidationErrorResponse(
|
||||
string.Format("Could not unlock for user {0} - error {1}", userIds[0], unlockResult.Errors.First()));
|
||||
}
|
||||
|
||||
return Request.CreateNotificationSuccessResponse(
|
||||
Services.TextService.Localize("speechBubbles/unlockUserSuccess", new[] { user.Name }));
|
||||
}
|
||||
if (userIds.Length <= 0) return Request.CreateResponse(HttpStatusCode.OK);
|
||||
|
||||
foreach (var u in userIds)
|
||||
{
|
||||
var user = await UserManager.FindByIdAsync(u.ToString());
|
||||
if (user == null) throw new InvalidOperationException();
|
||||
|
||||
var unlockResult = await UserManager.SetLockoutEndDateAsync(user, DateTimeOffset.Now);
|
||||
if (unlockResult.Succeeded == false)
|
||||
{
|
||||
return Request.CreateValidationErrorResponse(
|
||||
string.Format("Could not unlock for user {0} - error {1}", u, unlockResult.Errors.First()));
|
||||
string.Format("Could not unlock for user {0} - error {1}", u, unlockResult.Errors.First().Description));
|
||||
}
|
||||
|
||||
if (userIds.Length == 1)
|
||||
{
|
||||
return Request.CreateNotificationSuccessResponse(
|
||||
Services.TextService.Localize("speechBubbles/unlockUserSuccess", new[] {user.Name}));
|
||||
}
|
||||
}
|
||||
|
||||
return Request.CreateNotificationSuccessResponse(
|
||||
Services.TextService.Localize("speechBubbles/unlockUsersSuccess", new[] { userIds.Length.ToString() }));
|
||||
Services.TextService.Localize("speechBubbles/unlockUsersSuccess", new[] {userIds.Length.ToString()}));
|
||||
}
|
||||
|
||||
[AdminUsersAuthorize("userIds")]
|
||||
|
||||
Reference in New Issue
Block a user