using System; using System.Collections.Generic; using System.Linq; using System.Net; using System.Net.Http; using System.Net.Mime; using System.Text; using System.Threading.Tasks; using Newtonsoft.Json; using NUnit.Framework; using Umbraco.Core; using Umbraco.Core.Models; using Umbraco.Core.Models.Membership; using Umbraco.Core.Services; using Umbraco.Tests.Common.Builders; using Umbraco.Tests.Common.Builders.Extensions; using Umbraco.Tests.Testing; using Umbraco.Web.BackOffice.Controllers; using Umbraco.Web.Common.Filters; using Umbraco.Web.Common.Formatters; using Umbraco.Web.Models.ContentEditing; namespace Umbraco.Tests.Integration.TestServerTest.Controllers { // [Explicit("We need to fix the tests on buildserver and when running multiple tests in one run")] [TestFixture] [UmbracoTest(Database = UmbracoTestOptions.Database.NewSchemaPerTest)] public class UsersControllerTests : UmbracoTestServerTestBase { [Test] public async Task Save_User() { var url = PrepareUrl(x => x.PostSaveUser(null)); var userService = GetRequiredService(); var user = new UserBuilder() .AddUserGroup() .WithAlias("writer") // Needs to be an existing alias .Done() .Build(); userService.Save(user); var userSave = new UserSave { Id = user.Id, Email = user.Email, Username = user.Username, Culture = "en", Name = user.Name, UserGroups = user.Groups.Select(x => x.Alias).ToArray() }; // Act var response = await Client.PostAsync(url, new StringContent(JsonConvert.SerializeObject(userSave), Encoding.UTF8, MediaTypeNames.Application.Json)); // Assert Assert.Multiple(() => { Assert.AreEqual(HttpStatusCode.OK, response.StatusCode); var body = response.Content.ReadAsStringAsync().GetAwaiter().GetResult(); body = body.TrimStart(AngularJsonMediaTypeFormatter.XsrfPrefix); var actual = JsonConvert.DeserializeObject(body, new JsonSerializerSettings { ContractResolver = new IgnoreRequiredAttributsResolver() }); Assert.AreEqual(userSave.Name, actual.Name); Assert.AreEqual(userSave.Id, actual.Id); Assert.AreEqual(userSave.Email, actual.Email); var userGroupAliases = actual.UserGroups.Select(x => x.Alias).ToArray(); CollectionAssert.AreEquivalent(userSave.UserGroups, userGroupAliases); }); } [Test] public async Task GetPagedUsers_Empty() { //We get page 2 to force an empty response because there always in the useradmin user var url = PrepareUrl(x => x.GetPagedUsers(2, 10, "username", Direction.Ascending, null, null, string.Empty)); // Act var response = await Client.GetAsync(url); var body = await response.Content.ReadAsStringAsync(); body = body.TrimStart(AngularJsonMediaTypeFormatter.XsrfPrefix); Assert.AreEqual(HttpStatusCode.OK, response.StatusCode); var actual = JsonConvert.DeserializeObject>(body, new JsonSerializerSettings { ContractResolver = new IgnoreRequiredAttributsResolver() }); Assert.Multiple(() => { Assert.IsNotNull(actual); Assert.AreEqual(1, actual.TotalItems); CollectionAssert.IsEmpty(actual.Items); }); } [Test] public async Task GetPagedUsers_11() { var totalNumberOfUsers = 11; var pageSize = totalNumberOfUsers - 1; var url = PrepareUrl(x => x.GetPagedUsers(1, pageSize, "username", Direction.Ascending, null, null, string.Empty)); var userService = GetRequiredService(); for (int i = 1; i < totalNumberOfUsers; i++) // We already has admin user = -1, so we start from 1 { var user = new UserBuilder() .WithName($"Test user {i}") .AddUserGroup() .WithAlias("writer") // Needs to be an existing alias .Done() .Build(); userService.Save(user); } // Act var response = await Client.GetAsync(url); var body = await response.Content.ReadAsStringAsync(); body = body.TrimStart(AngularJsonMediaTypeFormatter.XsrfPrefix); Assert.AreEqual(HttpStatusCode.OK, response.StatusCode); var actual = JsonConvert.DeserializeObject>(body, new JsonSerializerSettings { ContractResolver = new IgnoreRequiredAttributsResolver() }); Assert.Multiple(() => { Assert.IsNotNull(actual); Assert.AreEqual(totalNumberOfUsers, actual.TotalItems); Assert.AreEqual(pageSize, actual.Items.Count()); }); } [Test] public async Task PostUnlockUsers_When_UserIds_Not_Supplied_Expect_Ok_Response() { var url = PrepareUrl(x => x.PostUnlockUsers(Array.Empty())); // Act var response = await Client.PostAsync(url, new StringContent(string.Empty)); Assert.AreEqual(HttpStatusCode.OK, response.StatusCode); } [Test] public async Task PostUnlockUsers_When_User_Does_Not_Exist_Expect_InvalidOperationException() { var userId = 42; // Must not exist var url = PrepareUrl(x => x.PostUnlockUsers(new []{userId})); // Act var response = await Client.PostAsync(url, new StringContent(string.Empty)); var body = await response.Content.ReadAsStringAsync(); body = body.TrimStart(AngularJsonMediaTypeFormatter.XsrfPrefix); Assert.AreEqual(HttpStatusCode.InternalServerError, response.StatusCode); var actual = JsonConvert.DeserializeObject(body, new JsonSerializerSettings { ContractResolver = new IgnoreRequiredAttributsResolver() }); Assert.Multiple(() => { var expected = new InvalidOperationException(); Assert.IsNotNull(actual); Assert.AreEqual(expected.GetType(), actual.ExceptionType); Assert.AreEqual(expected.Message, actual.ExceptionMessage); }); } // [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().Object, // // 1, // // new List()) // // { // // Name = "bob" // // }; // // // // mockUserManager.Setup(x => x.FindByIdAsync(It.IsAny())) // // .ReturnsAsync(user); // // mockUserManager.Setup(x => x.SetLockoutEndDateAsync(user, It.IsAny())) // // .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; // // 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 userService = GetRequiredService(); var user = new UserBuilder() .AddUserGroup() .WithAlias("writer") // Needs to be an existing alias .Done() .WithIsLockedOut(true, DateTime.UtcNow) .Build(); userService.Save(user); var url = PrepareUrl(x => x.PostUnlockUsers(new []{user.Id})); // Act var response = await Client.PostAsync(url, new StringContent(string.Empty)); var body = await response.Content.ReadAsStringAsync(); body = body.TrimStart(AngularJsonMediaTypeFormatter.XsrfPrefix); Assert.AreEqual(HttpStatusCode.OK, response.StatusCode); var actual = JsonConvert.DeserializeObject(body, new JsonSerializerSettings { ContractResolver = new IgnoreRequiredAttributsResolver() }); Assert.Multiple(() => { Assert.NotNull(actual); Assert.AreEqual($"{user.Name} is now unlocked", actual.Message); }); } [Test] public async Task PostUnlockUsers_When_Multiple_UserIds_Supplied_Expect_User_Locked_Out_With_Correct_Response_Message() { var numberOfUsers = 3; var userService = GetRequiredService(); var users = new List(); for (int i = 0; i < numberOfUsers; i++) { users.Add(new UserBuilder() .WithName($"Test User {i}") .WithEmail($"TestUser{i}@umbraco.com") .WithUsername($"TestUser{i}") .AddUserGroup() .WithAlias("writer") // Needs to be an existing alias .Done() .WithIsLockedOut(true, DateTime.UtcNow) .Build()); } foreach (var user in users) { userService.Save(user); } var url = PrepareUrl(x => x.PostUnlockUsers(users.Select(x=>x.Id).ToArray())); // Act var response = await Client.PostAsync(url, new StringContent(string.Empty)); var body = await response.Content.ReadAsStringAsync(); body = body.TrimStart(AngularJsonMediaTypeFormatter.XsrfPrefix); Assert.AreEqual(HttpStatusCode.OK, response.StatusCode); var actual = JsonConvert.DeserializeObject(body, new JsonSerializerSettings { ContractResolver = new IgnoreRequiredAttributsResolver() }); Assert.Multiple(() => { Assert.NotNull(actual); Assert.AreEqual($"Unlocked {users.Count()} users", actual.Message); }); } // // [Test] // public async Task GetPagedUsers_Fips() // { // await RunFipsTest("GetPagedUsers", mock => // { // var users = MockedUser.CreateMulipleUsers(10); // long outVal = 10; // mock.Setup(service => service.GetAll( // It.IsAny(), It.IsAny(), out outVal, It.IsAny(), It.IsAny(), // It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny>())) // .Returns(() => users); // }, response => // { // var obj = JsonConvert.DeserializeObject>(response.Item2); // Assert.AreEqual(10, obj.TotalItems); // Assert.AreEqual(10, obj.Items.Count()); // }); // } // // [Test] // public async Task GetById_Fips() // { // const int mockUserId = 1234; // var user = MockedUser.CreateUser(); // // await RunFipsTest("GetById", mock => // { // mock.Setup(service => service.GetUserById(1234)) // .Returns((int i) => i == mockUserId ? user : null); // }, response => // { // var obj = JsonConvert.DeserializeObject(response.Item2); // Assert.AreEqual(user.Username, obj.Username); // Assert.AreEqual(user.Email, obj.Email); // }, new { controller = "Users", action = "GetById" }, $"Users/GetById/{mockUserId}"); // } } }