Browse Source

Some tests

pull/65/head
Sebastian Stehle 9 years ago
parent
commit
bc3bd42d32
  1. 8
      src/Squidex/Controllers/UI/Extensions.cs
  2. 66
      src/Squidex/Controllers/UI/Profile/ProfileController.cs
  3. 4
      src/Squidex/Controllers/UI/Profile/ProfileVM.cs
  4. 113
      src/Squidex/Views/Profile/Profile.cshtml
  5. 18
      tests/Squidex.Read.Tests/Apps/CachingAppProviderTests.cs
  6. 18
      tests/Squidex.Read.Tests/Schemas/CachingSchemaProviderTests.cs
  7. 60
      tests/Squidex.Read.Tests/Users/AssetUserPictureStoreTests.cs

8
src/Squidex/Controllers/UI/Extensions.cs

@ -15,6 +15,14 @@ namespace Squidex.Controllers.UI
{
public static class Extensions
{
public static Task<IdentityResult> UpdateAsync(this UserManager<IUser> userManager, IUser user, string email, string displayName)
{
user.UpdateEmail(email);
user.UpdateDisplayName(displayName);
return userManager.UpdateAsync(user);
}
public static async Task<ExternalLoginInfo> GetExternalLoginInfoWithDisplayNameAsync(this SignInManager<IUser> signInManager, string expectedXsrf = null)
{
var externalLogin = await signInManager.GetExternalLoginInfoAsync(expectedXsrf);

66
src/Squidex/Controllers/UI/Profile/ProfileController.cs

@ -57,26 +57,11 @@ namespace Squidex.Controllers.UI.Profile
{
var user = await userManager.GetUserAsync(User);
ViewBag.SuccessMessage = successMessage;
return View(await GetProfileVM(user));
}
[HttpPost]
[Route("/account/profile")]
public Task<IActionResult> Profile(ChangeProfileModel model)
{
return MakeChangeAsync(async user =>
{
user.UpdateEmail(model.Email);
user.UpdateDisplayName(model.DisplayName);
return await userManager.UpdateAsync(user);
}, "Account updated successfully. Please logout and login again to see the changes.");
return View(await GetProfileVM(user, successMessage: successMessage));
}
[HttpPost]
[Route("account/add-login/")]
[Route("/account/profile/login-add/")]
public async Task<IActionResult> AddLogin(string provider)
{
await HttpContext.Authentication.SignOutAsync(identityCookieOptions.Value.ExternalCookieAuthenticationScheme);
@ -89,7 +74,7 @@ namespace Squidex.Controllers.UI.Profile
}
[HttpGet]
[Route("account/add-login-callback/")]
[Route("/account/profile/login-add-callback/")]
public Task<IActionResult> AddLoginCallback(string remoteError = null)
{
return MakeChangeAsync(async user =>
@ -101,7 +86,23 @@ namespace Squidex.Controllers.UI.Profile
}
[HttpPost]
[Route("/account/set-password")]
[Route("/account/profile/update")]
public Task<IActionResult> Profile(ChangeProfileModel model)
{
return MakeChangeAsync(user => userManager.UpdateAsync(user, model.Email, model.DisplayName),
"Account updated successfully.");
}
[HttpPost]
[Route("/account/profile/login-remove")]
public Task<IActionResult> RemoveLogin(RemoveLoginModel model)
{
return MakeChangeAsync(user => userManager.RemoveLoginAsync(user, model.LoginProvider, model.ProviderKey),
"Login provider removed successfully.");
}
[HttpPost]
[Route("/account/profile/password-set")]
public Task<IActionResult> SetPassword(SetPasswordModel model)
{
return MakeChangeAsync(user => userManager.AddPasswordAsync(user, model.Password),
@ -109,7 +110,7 @@ namespace Squidex.Controllers.UI.Profile
}
[HttpPost]
[Route("/account/change-password")]
[Route("/account/profile/password-change")]
public Task<IActionResult> ChangePassword(ChangePasswordModel model)
{
return MakeChangeAsync(user => userManager.ChangePasswordAsync(user, model.OldPassword, model.Password),
@ -117,15 +118,7 @@ namespace Squidex.Controllers.UI.Profile
}
[HttpPost]
[Route("/account/remove-login")]
public Task<IActionResult> RemoveLogin(RemoveLoginModel model)
{
return MakeChangeAsync(user => userManager.RemoveLoginAsync(user, model.LoginProvider, model.ProviderKey),
"Login provider removed successfully.");
}
[HttpPost]
[Route("/account/upload-picture")]
[Route("/account/profile/upload-picture")]
public Task<IActionResult> UploadPicture(List<IFormFile> file)
{
return MakeChangeAsync(async user =>
@ -152,7 +145,7 @@ namespace Squidex.Controllers.UI.Profile
user.SetPictureUrlToStore();
return await userManager.UpdateAsync(user);
}, "Password set successfully.");
}, "Picture uploaded successfully.");
}
private async Task<IActionResult> MakeChangeAsync(Func<IUser, Task<IdentityResult>> action, string successMessage, ChangeProfileModel model = null)
@ -164,6 +157,7 @@ namespace Squidex.Controllers.UI.Profile
return View("Profile", await GetProfileVM(user, model));
}
string errorMessage;
try
{
var result = await action(user);
@ -175,17 +169,17 @@ namespace Squidex.Controllers.UI.Profile
return RedirectToAction(nameof(Profile), new { successMessage });
}
ViewBag.ErrorMessage = string.Join(". ", result.Errors.Select(x => x.Description));
errorMessage = string.Join(". ", result.Errors.Select(x => x.Description));
}
catch
{
ViewBag.ErrorMessage = "An unexpected exception occurred.";
errorMessage = "An unexpected exception occurred.";
}
return View("Profile", await GetProfileVM(user, model));
return View("Profile", await GetProfileVM(user, model, errorMessage));
}
private async Task<ProfileVM> GetProfileVM(IUser user, ChangeProfileModel model = null)
private async Task<ProfileVM> GetProfileVM(IUser user, ChangeProfileModel model = null, string errorMessage = null, string successMessage = null)
{
var providers =
signInManager.GetExternalAuthenticationSchemes()
@ -195,11 +189,13 @@ namespace Squidex.Controllers.UI.Profile
{
Id = user.Id,
Email = user.Email,
ErrorMessage = errorMessage,
ExternalLogins = user.Logins,
ExternalProviders = providers,
DisplayName = user.DisplayName(),
HasPassword = await userManager.HasPasswordAsync(user),
HasPasswordAuth = identityOptions.Value.AllowPasswordAuth
HasPasswordAuth = identityOptions.Value.AllowPasswordAuth,
SuccessMessage = successMessage
};
if (model != null)

4
src/Squidex/Controllers/UI/Profile/ProfileVM.cs

@ -19,6 +19,10 @@ namespace Squidex.Controllers.UI.Profile
public string DisplayName { get; set; }
public string ErrorMessage { get; set; }
public string SuccessMessage { get; set; }
public bool HasPassword { get; set; }
public bool HasPasswordAuth { get; set; }

113
src/Squidex/Views/Profile/Profile.cshtml

@ -15,17 +15,17 @@
<h2>Personal Information</h2>
@if (!string.IsNullOrWhiteSpace(ViewBag.SuccessMessage))
@if (!string.IsNullOrWhiteSpace(Model.SuccessMessage))
{
<div class="form-alert form-alert-success" id="success">
@ViewBag.SuccessMessage
@Model.SuccessMessage
</div>
}
@if (!string.IsNullOrWhiteSpace(ViewBag.ErrorMessage))
@if (!string.IsNullOrWhiteSpace(Model.ErrorMessage))
{
<div class="form-alert form-alert-error">
@ViewBag.ErrorMessage
@Model.ErrorMessage
</div>
}
@ -74,56 +74,59 @@
<button type="submit" class="btn btn-primary">Save</button>
</form>
<div class="profile-section">
<h2>Logins</h2>
<table class="table table-fixed table-lesspadding">
<colgroup>
<col style="width: 100px;" />
<col style="width: 100%;" />
<col style="width: 100px;" />
</colgroup>
@foreach (var login in Model.ExternalLogins)
{
<tr>
<td>
<span>@login.LoginProvider</span>
</td>
<td>
<span class="truncate">@login.ProviderDisplayName</span>
</td>
<td class="text-right">
@if (Model.ExternalLogins.Count > 1 || Model.HasPassword)
{
<form asp-controller="Profile" asp-action="RemoveLogin" method="post">
<input type="hidden" value="@login.LoginProvider" name="LoginProvider" />
<input type="hidden" value="@login.ProviderKey" name="ProviderKey" />
<button type="submit" class="btn btn-link btn-danger btn-sm">
Remove
</button>
</form>
}
</td>
</tr>
}
</table>
<form asp-controller="Profile" asp-action="AddLogin" method="post">
@foreach (var provider in Model.ExternalProviders)
{
var schema = provider.AuthenticationScheme.ToLowerInvariant();
<button class="btn external-button-small btn btn-@schema" type="submit" name="provider" value="@provider.AuthenticationScheme">
<i class="icon-@schema external-icon"></i>
</button>
}
</form>
</div>
@if (Model.ExternalProviders.Any())
{
<div class="profile-section">
<h2>Logins</h2>
<table class="table table-fixed table-lesspadding">
<colgroup>
<col style="width: 100px;"/>
<col style="width: 100%;"/>
<col style="width: 100px;"/>
</colgroup>
@foreach (var login in Model.ExternalLogins)
{
<tr>
<td>
<span>@login.LoginProvider</span>
</td>
<td>
<span class="truncate">@login.ProviderDisplayName</span>
</td>
<td class="text-right">
@if (Model.ExternalLogins.Count > 1 || Model.HasPassword)
{
<form asp-controller="Profile" asp-action="RemoveLogin" method="post">
<input type="hidden" value="@login.LoginProvider" name="LoginProvider"/>
<input type="hidden" value="@login.ProviderKey" name="ProviderKey"/>
<button type="submit" class="btn btn-link btn-danger btn-sm">
Remove
</button>
</form>
}
</td>
</tr>
}
</table>
<form asp-controller="Profile" asp-action="AddLogin" method="post">
@foreach (var provider in Model.ExternalProviders.Where(x => !Model.ExternalLogins.Any(y => x.AuthenticationScheme == y.LoginProvider)))
{
var schema = provider.AuthenticationScheme.ToLowerInvariant();
<button class="btn external-button-small btn btn-@schema" type="submit" name="provider" value="@provider.AuthenticationScheme">
<i class="icon-@schema external-icon"></i>
</button>
}
</form>
</div>
}
<div class="profile-section">
@if (Model.HasPasswordAuth)
{
@if (Model.HasPasswordAuth)
{
<div class="profile-section">
<h2>Password</h2>
@if (Model.HasPassword)
@ -207,8 +210,8 @@
</div>
</form>
}
}
</div>
</div>
}
</div>
<script>

18
tests/Squidex.Read.Tests/Apps/CachingAppProviderTests.cs

@ -49,6 +49,24 @@ namespace Squidex.Read.Apps
sut = new CachingAppProvider(cache, repository.Object);
}
[Fact]
public void Should_return_empty_for_events_filter()
{
Assert.Equal(string.Empty, sut.EventsFilter);
}
[Fact]
public void Should_return_empty_for_name()
{
Assert.Equal(typeof(CachingAppProvider).Name, sut.Name);
}
[Fact]
public void Should_do_nothing_when_clearing()
{
Assert.NotNull(sut.ClearAsync());
}
[Fact]
public async Task Should_also_retrieve_app_by_name_if_retrieved_by_id_before()
{

18
tests/Squidex.Read.Tests/Schemas/CachingSchemaProviderTests.cs

@ -52,6 +52,24 @@ namespace Squidex.Read.Schemas
sut = new CachingSchemaProvider(cache, repository.Object);
}
[Fact]
public void Should_return_empty_for_events_filter()
{
Assert.Equal(string.Empty, sut.EventsFilter);
}
[Fact]
public void Should_return_empty_for_name()
{
Assert.Equal(typeof(CachingSchemaProvider).Name, sut.Name);
}
[Fact]
public void Should_do_nothing_when_clearing()
{
Assert.NotNull(sut.ClearAsync());
}
[Fact]
public async Task Should_also_retrieve_schema_by_name_if_retrieved_by_id_before()
{

60
tests/Squidex.Read.Tests/Users/AssetUserPictureStoreTests.cs

@ -0,0 +1,60 @@
// ==========================================================================
// AssetUserPictureStoreTests.cs
// Squidex Headless CMS
// ==========================================================================
// Copyright (c) Squidex Group
// All rights reserved.
// ==========================================================================
using System;
using System.IO;
using System.Threading.Tasks;
using Moq;
using Squidex.Infrastructure.Assets;
using Squidex.Infrastructure.Tasks;
using Xunit;
namespace Squidex.Read.Users
{
public class AssetUserPictureStoreTests
{
private readonly Mock<IAssetStore> assetStore = new Mock<IAssetStore>();
private readonly AssetUserPictureStore sut;
private readonly string userId = Guid.NewGuid().ToString();
public AssetUserPictureStoreTests()
{
sut = new AssetUserPictureStore(assetStore.Object);
}
[Fact]
public async Task Should_invoke_asset_store_to_upload_picture()
{
var stream = new MemoryStream();
assetStore.Setup(x => x.UploadAsync(userId, 0, "picture", stream))
.Returns(TaskHelper.Done)
.Verifiable();
await sut.UploadAsync(userId, stream);
assetStore.VerifyAll();
}
[Fact]
public async Task Should_invoke_asset_store_to_download_picture()
{
assetStore.Setup(x => x.DownloadAsync(userId, 0, "picture", It.IsAny<Stream>()))
.Callback<string, long, string, Stream>((id, version, suffix, stream) => stream.Write(new byte[] { 1, 2, 3, 4 }, 0, 4 ))
.Returns(TaskHelper.Done)
.Verifiable();
var result = await sut.DownloadAsync(userId);
Assert.Equal(0, result.Position);
Assert.Equal(4, result.Length);
assetStore.VerifyAll();
}
}
}
Loading…
Cancel
Save