Browse Source
* Moved Privacy, Home page to Razor Pages * Migrating Basket from RazorPages to Web. * Removed BasketController; refactored viewmodels * Moved BasketComponent into Pages/Shared Added auth rules to Startup for Pages Added notes to controllers about Pages usage. * Fixed broken my orders test Consolidated Functional Tests * Fixed logo link to home page Fixed Order Detail Total $ formatmain
committed by
GitHub
42 changed files with 429 additions and 430 deletions
@ -1,112 +0,0 @@ |
|||
using Microsoft.AspNetCore.Authorization; |
|||
using Microsoft.AspNetCore.Http; |
|||
using Microsoft.AspNetCore.Identity; |
|||
using Microsoft.AspNetCore.Mvc; |
|||
using Microsoft.eShopWeb.ApplicationCore.Entities.OrderAggregate; |
|||
using Microsoft.eShopWeb.ApplicationCore.Interfaces; |
|||
using Microsoft.eShopWeb.Infrastructure.Identity; |
|||
using Microsoft.eShopWeb.Web.Interfaces; |
|||
using Microsoft.eShopWeb.Web.ViewModels; |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Threading.Tasks; |
|||
|
|||
namespace Microsoft.eShopWeb.Web.Controllers |
|||
{ |
|||
[ApiExplorerSettings(IgnoreApi = true)] |
|||
[Route("[controller]/[action]")]
|
|||
public class BasketController : Controller |
|||
{ |
|||
private readonly IBasketService _basketService; |
|||
private readonly IUriComposer _uriComposer; |
|||
private readonly SignInManager<ApplicationUser> _signInManager; |
|||
private readonly IAppLogger<BasketController> _logger; |
|||
private readonly IOrderService _orderService; |
|||
private readonly IBasketViewModelService _basketViewModelService; |
|||
|
|||
public BasketController(IBasketService basketService, |
|||
IBasketViewModelService basketViewModelService, |
|||
IOrderService orderService, |
|||
IUriComposer uriComposer, |
|||
SignInManager<ApplicationUser> signInManager, |
|||
IAppLogger<BasketController> logger) |
|||
{ |
|||
_basketService = basketService; |
|||
_uriComposer = uriComposer; |
|||
_signInManager = signInManager; |
|||
_logger = logger; |
|||
_orderService = orderService; |
|||
_basketViewModelService = basketViewModelService; |
|||
} |
|||
|
|||
[HttpGet] |
|||
public async Task<IActionResult> Index() |
|||
{ |
|||
var basketModel = await GetBasketViewModelAsync(); |
|||
|
|||
return View(basketModel); |
|||
} |
|||
|
|||
[HttpPost] |
|||
public async Task<IActionResult> Index(Dictionary<string, int> items) |
|||
{ |
|||
var basketViewModel = await GetBasketViewModelAsync(); |
|||
await _basketService.SetQuantities(basketViewModel.Id, items); |
|||
|
|||
return View(await GetBasketViewModelAsync()); |
|||
} |
|||
|
|||
|
|||
// POST: /Basket/AddToBasket
|
|||
[HttpPost] |
|||
public async Task<IActionResult> AddToBasket(CatalogItemViewModel productDetails) |
|||
{ |
|||
if (productDetails?.Id == null) |
|||
{ |
|||
return RedirectToAction("Index", "Catalog"); |
|||
} |
|||
var basketViewModel = await GetBasketViewModelAsync(); |
|||
|
|||
await _basketService.AddItemToBasket(basketViewModel.Id, productDetails.Id, productDetails.Price, 1); |
|||
|
|||
return RedirectToAction("Index"); |
|||
} |
|||
|
|||
[HttpPost] |
|||
[Authorize] |
|||
public async Task<IActionResult> Checkout(Dictionary<string, int> items) |
|||
{ |
|||
var basketViewModel = await GetBasketViewModelAsync(); |
|||
await _basketService.SetQuantities(basketViewModel.Id, items); |
|||
|
|||
await _orderService.CreateOrderAsync(basketViewModel.Id, new Address("123 Main St.", "Kent", "OH", "United States", "44240")); |
|||
|
|||
await _basketService.DeleteBasketAsync(basketViewModel.Id); |
|||
|
|||
return View("Checkout"); |
|||
} |
|||
|
|||
private async Task<BasketViewModel> GetBasketViewModelAsync() |
|||
{ |
|||
if (_signInManager.IsSignedIn(HttpContext.User)) |
|||
{ |
|||
return await _basketViewModelService.GetOrCreateBasketForUser(User.Identity.Name); |
|||
} |
|||
string anonymousId = GetOrSetBasketCookie(); |
|||
return await _basketViewModelService.GetOrCreateBasketForUser(anonymousId); |
|||
} |
|||
|
|||
private string GetOrSetBasketCookie() |
|||
{ |
|||
if (Request.Cookies.ContainsKey(Constants.BASKET_COOKIENAME)) |
|||
{ |
|||
return Request.Cookies[Constants.BASKET_COOKIENAME]; |
|||
} |
|||
string anonymousId = Guid.NewGuid().ToString(); |
|||
var cookieOptions = new CookieOptions(); |
|||
cookieOptions.Expires = DateTime.Today.AddYears(10); |
|||
Response.Cookies.Append(Constants.BASKET_COOKIENAME, anonymousId, cookieOptions); |
|||
return anonymousId; |
|||
} |
|||
} |
|||
} |
|||
@ -1,30 +0,0 @@ |
|||
using Microsoft.AspNetCore.Mvc; |
|||
using Microsoft.eShopWeb.Web.Services; |
|||
using System.Threading.Tasks; |
|||
|
|||
namespace Microsoft.eShopWeb.Web.Controllers |
|||
{ |
|||
[ApiExplorerSettings(IgnoreApi = true)] |
|||
[Route("")] |
|||
public class CatalogController : Controller |
|||
{ |
|||
private readonly ICatalogService _catalogService; |
|||
|
|||
public CatalogController(ICatalogService catalogService) => _catalogService = catalogService; |
|||
|
|||
[HttpGet] |
|||
[HttpPost] |
|||
public async Task<IActionResult> Index(int? brandFilterApplied, int? typesFilterApplied, int? page) |
|||
{ |
|||
var itemsPage = 10; |
|||
var catalogModel = await _catalogService.GetCatalogItems(page ?? 0, itemsPage, brandFilterApplied, typesFilterApplied); |
|||
return View(catalogModel); |
|||
} |
|||
|
|||
[HttpGet("Error")] |
|||
public IActionResult Error() |
|||
{ |
|||
return View(); |
|||
} |
|||
} |
|||
} |
|||
@ -1,4 +1,4 @@ |
|||
namespace Microsoft.eShopWeb.Web.ViewModels |
|||
namespace Microsoft.eShopWeb.Web.Pages.Basket |
|||
{ |
|||
public class BasketItemViewModel |
|||
{ |
|||
@ -0,0 +1,83 @@ |
|||
using Microsoft.AspNetCore.Http; |
|||
using Microsoft.AspNetCore.Identity; |
|||
using Microsoft.AspNetCore.Mvc; |
|||
using Microsoft.AspNetCore.Mvc.RazorPages; |
|||
using Microsoft.eShopWeb.ApplicationCore.Entities.OrderAggregate; |
|||
using Microsoft.eShopWeb.ApplicationCore.Interfaces; |
|||
using Microsoft.eShopWeb.Infrastructure.Identity; |
|||
using Microsoft.eShopWeb.Web.Interfaces; |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Threading.Tasks; |
|||
|
|||
namespace Microsoft.eShopWeb.Web.Pages.Basket |
|||
{ |
|||
public class CheckoutModel : PageModel |
|||
{ |
|||
private readonly IBasketService _basketService; |
|||
private readonly IUriComposer _uriComposer; |
|||
private readonly SignInManager<ApplicationUser> _signInManager; |
|||
private readonly IOrderService _orderService; |
|||
private string _username = null; |
|||
private readonly IBasketViewModelService _basketViewModelService; |
|||
|
|||
public CheckoutModel(IBasketService basketService, |
|||
IBasketViewModelService basketViewModelService, |
|||
IUriComposer uriComposer, |
|||
SignInManager<ApplicationUser> signInManager, |
|||
IOrderService orderService) |
|||
{ |
|||
_basketService = basketService; |
|||
_uriComposer = uriComposer; |
|||
_signInManager = signInManager; |
|||
_orderService = orderService; |
|||
_basketViewModelService = basketViewModelService; |
|||
} |
|||
|
|||
public BasketViewModel BasketModel { get; set; } = new BasketViewModel(); |
|||
|
|||
public void OnGet() |
|||
{ |
|||
} |
|||
|
|||
public async Task<IActionResult> OnPost(Dictionary<string, int> items) |
|||
{ |
|||
await SetBasketModelAsync(); |
|||
|
|||
await _basketService.SetQuantities(BasketModel.Id, items); |
|||
|
|||
await _orderService.CreateOrderAsync(BasketModel.Id, new Address("123 Main St.", "Kent", "OH", "United States", "44240")); |
|||
|
|||
await _basketService.DeleteBasketAsync(BasketModel.Id); |
|||
|
|||
return RedirectToPage(); |
|||
} |
|||
|
|||
private async Task SetBasketModelAsync() |
|||
{ |
|||
if (_signInManager.IsSignedIn(HttpContext.User)) |
|||
{ |
|||
BasketModel = await _basketViewModelService.GetOrCreateBasketForUser(User.Identity.Name); |
|||
} |
|||
else |
|||
{ |
|||
GetOrSetBasketCookieAndUserName(); |
|||
BasketModel = await _basketViewModelService.GetOrCreateBasketForUser(_username); |
|||
} |
|||
} |
|||
|
|||
private void GetOrSetBasketCookieAndUserName() |
|||
{ |
|||
if (Request.Cookies.ContainsKey(Constants.BASKET_COOKIENAME)) |
|||
{ |
|||
_username = Request.Cookies[Constants.BASKET_COOKIENAME]; |
|||
} |
|||
if (_username != null) return; |
|||
|
|||
_username = Guid.NewGuid().ToString(); |
|||
var cookieOptions = new CookieOptions(); |
|||
cookieOptions.Expires = DateTime.Today.AddYears(10); |
|||
Response.Cookies.Append(Constants.BASKET_COOKIENAME, _username, cookieOptions); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,92 @@ |
|||
using Microsoft.AspNetCore.Http; |
|||
using Microsoft.AspNetCore.Identity; |
|||
using Microsoft.AspNetCore.Mvc; |
|||
using Microsoft.AspNetCore.Mvc.RazorPages; |
|||
using Microsoft.eShopWeb.ApplicationCore.Interfaces; |
|||
using Microsoft.eShopWeb.Infrastructure.Identity; |
|||
using Microsoft.eShopWeb.Web.Interfaces; |
|||
using Microsoft.eShopWeb.Web.ViewModels; |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Threading.Tasks; |
|||
|
|||
namespace Microsoft.eShopWeb.Web.Pages.Basket |
|||
{ |
|||
public class IndexModel : PageModel |
|||
{ |
|||
private readonly IBasketService _basketService; |
|||
private const string _basketSessionKey = "basketId"; |
|||
private readonly IUriComposer _uriComposer; |
|||
private readonly SignInManager<ApplicationUser> _signInManager; |
|||
private string _username = null; |
|||
private readonly IBasketViewModelService _basketViewModelService; |
|||
|
|||
public IndexModel(IBasketService basketService, |
|||
IBasketViewModelService basketViewModelService, |
|||
IUriComposer uriComposer, |
|||
SignInManager<ApplicationUser> signInManager) |
|||
{ |
|||
_basketService = basketService; |
|||
_uriComposer = uriComposer; |
|||
_signInManager = signInManager; |
|||
_basketViewModelService = basketViewModelService; |
|||
} |
|||
|
|||
public BasketViewModel BasketModel { get; set; } = new BasketViewModel(); |
|||
|
|||
public async Task OnGet() |
|||
{ |
|||
await SetBasketModelAsync(); |
|||
} |
|||
|
|||
public async Task<IActionResult> OnPost(CatalogItemViewModel productDetails) |
|||
{ |
|||
if (productDetails?.Id == null) |
|||
{ |
|||
return RedirectToPage("/Index"); |
|||
} |
|||
await SetBasketModelAsync(); |
|||
|
|||
await _basketService.AddItemToBasket(BasketModel.Id, productDetails.Id, productDetails.Price, 1); |
|||
|
|||
await SetBasketModelAsync(); |
|||
|
|||
return RedirectToPage(); |
|||
} |
|||
|
|||
public async Task OnPostUpdate(Dictionary<string, int> items) |
|||
{ |
|||
await SetBasketModelAsync(); |
|||
await _basketService.SetQuantities(BasketModel.Id, items); |
|||
|
|||
await SetBasketModelAsync(); |
|||
} |
|||
|
|||
private async Task SetBasketModelAsync() |
|||
{ |
|||
if (_signInManager.IsSignedIn(HttpContext.User)) |
|||
{ |
|||
BasketModel = await _basketViewModelService.GetOrCreateBasketForUser(User.Identity.Name); |
|||
} |
|||
else |
|||
{ |
|||
GetOrSetBasketCookieAndUserName(); |
|||
BasketModel = await _basketViewModelService.GetOrCreateBasketForUser(_username); |
|||
} |
|||
} |
|||
|
|||
private void GetOrSetBasketCookieAndUserName() |
|||
{ |
|||
if (Request.Cookies.ContainsKey(Constants.BASKET_COOKIENAME)) |
|||
{ |
|||
_username = Request.Cookies[Constants.BASKET_COOKIENAME]; |
|||
} |
|||
if (_username != null) return; |
|||
|
|||
_username = Guid.NewGuid().ToString(); |
|||
var cookieOptions = new CookieOptions { IsEssential = true }; |
|||
cookieOptions.Expires = DateTime.Today.AddYears(10); |
|||
Response.Cookies.Append(Constants.BASKET_COOKIENAME, _username, cookieOptions); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,26 @@ |
|||
@page |
|||
@model ErrorModel |
|||
@{ |
|||
ViewData["Title"] = "Error"; |
|||
} |
|||
|
|||
<h1 class="text-danger">Error.</h1> |
|||
<h2 class="text-danger">An error occurred while processing your request.</h2> |
|||
|
|||
@if (Model.ShowRequestId) |
|||
{ |
|||
<p> |
|||
<strong>Request ID:</strong> <code>@Model.RequestId</code> |
|||
</p> |
|||
} |
|||
|
|||
<h3>Development Mode</h3> |
|||
<p> |
|||
Swapping to the <strong>Development</strong> environment displays detailed information about the error that occurred. |
|||
</p> |
|||
<p> |
|||
<strong>The Development environment shouldn't be enabled for deployed applications.</strong> |
|||
It can result in displaying sensitive information from exceptions to end users. |
|||
For local debugging, enable the <strong>Development</strong> environment by setting the <strong>ASPNETCORE_ENVIRONMENT</strong> environment variable to <strong>Development</strong> |
|||
and restarting the app. |
|||
</p> |
|||
@ -0,0 +1,19 @@ |
|||
using Microsoft.AspNetCore.Mvc; |
|||
using Microsoft.AspNetCore.Mvc.RazorPages; |
|||
using System.Diagnostics; |
|||
|
|||
namespace Microsoft.eShopWeb.Web.Pages |
|||
{ |
|||
[ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)] |
|||
public class ErrorModel : PageModel |
|||
{ |
|||
public string RequestId { get; set; } |
|||
|
|||
public bool ShowRequestId => !string.IsNullOrEmpty(RequestId); |
|||
|
|||
public void OnGet() |
|||
{ |
|||
RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier; |
|||
} |
|||
} |
|||
} |
|||
@ -1,43 +1,40 @@ |
|||
@{ |
|||
@page |
|||
@{ |
|||
ViewData["Title"] = "Catalog"; |
|||
@model CatalogIndexViewModel |
|||
@model IndexModel |
|||
} |
|||
<section class="esh-catalog-hero"> |
|||
<div class="container"> |
|||
<img class="esh-catalog-title" src="~/images/main_banner_text.png" /> |
|||
</div> |
|||
</section> |
|||
|
|||
<section class="esh-catalog-filters"> |
|||
<div class="container"> |
|||
<form asp-action="Index" asp-controller="Catalog" method="post"> |
|||
<form method="get"> |
|||
<label class="esh-catalog-label" data-title="brand"> |
|||
<select asp-for="@Model.BrandFilterApplied" asp-items="@Model.Brands" class="esh-catalog-filter"></select> |
|||
<select asp-for="@Model.CatalogModel.BrandFilterApplied" asp-items="@Model.CatalogModel.Brands" class="esh-catalog-filter"></select> |
|||
</label> |
|||
<label class="esh-catalog-label" data-title="type"> |
|||
<select asp-for="@Model.TypesFilterApplied" asp-items="@Model.Types" class="esh-catalog-filter"></select> |
|||
<select asp-for="@Model.CatalogModel.TypesFilterApplied" asp-items="@Model.CatalogModel.Types" class="esh-catalog-filter"></select> |
|||
</label> |
|||
<input class="esh-catalog-send" type="image" src="images/arrow-right.svg" /> |
|||
</form> |
|||
</div> |
|||
</section> |
|||
|
|||
<div class="container"> |
|||
|
|||
@if (Model.CatalogItems.Any()) |
|||
@if (Model.CatalogModel.CatalogItems.Any()) |
|||
{ |
|||
<partial name="_pagination" for="PaginationInfo" /> |
|||
<partial name="_pagination" for="CatalogModel.PaginationInfo" /> |
|||
|
|||
<div class="esh-catalog-items row"> |
|||
@foreach (var catalogItem in Model.CatalogItems) |
|||
@foreach (var catalogItem in Model.CatalogModel.CatalogItems) |
|||
{ |
|||
<div class="esh-catalog-item col-md-4"> |
|||
<partial name="_product" model="catalogItem" /> |
|||
<partial name="_product" for="@catalogItem" /> |
|||
</div> |
|||
} |
|||
</div> |
|||
|
|||
<partial name="_pagination" for="PaginationInfo" /> |
|||
<partial name="_pagination" for="CatalogModel.PaginationInfo" /> |
|||
} |
|||
else |
|||
{ |
|||
@ -0,0 +1,26 @@ |
|||
using Microsoft.AspNetCore.Mvc.RazorPages; |
|||
using Microsoft.eShopWeb.Web.Services; |
|||
using Microsoft.eShopWeb.Web.ViewModels; |
|||
using System.Threading.Tasks; |
|||
|
|||
namespace Microsoft.eShopWeb.Web.Pages |
|||
{ |
|||
public class IndexModel : PageModel |
|||
{ |
|||
private readonly ICatalogService _catalogService; |
|||
|
|||
public IndexModel(ICatalogService catalogService) |
|||
{ |
|||
_catalogService = catalogService; |
|||
} |
|||
|
|||
public CatalogIndexViewModel CatalogModel { get; set; } = new CatalogIndexViewModel(); |
|||
|
|||
public async Task OnGet(CatalogIndexViewModel catalogModel, int? pageId) |
|||
{ |
|||
CatalogModel = await _catalogService.GetCatalogItems(pageId ?? 0, Constants.ITEMS_PER_PAGE, catalogModel.BrandFilterApplied, catalogModel.TypesFilterApplied); |
|||
} |
|||
|
|||
|
|||
} |
|||
} |
|||
@ -1,4 +1,6 @@ |
|||
@{ |
|||
@page |
|||
@model PrivacyModel |
|||
@{ |
|||
ViewData["Title"] = "Privacy Policy"; |
|||
} |
|||
<h1>@ViewData["Title"]</h1> |
|||
@ -0,0 +1,11 @@ |
|||
using Microsoft.AspNetCore.Mvc.RazorPages; |
|||
|
|||
namespace Microsoft.eShopWeb.Web.Pages |
|||
{ |
|||
public class PrivacyModel : PageModel |
|||
{ |
|||
public void OnGet() |
|||
{ |
|||
} |
|||
} |
|||
} |
|||
@ -1,12 +1,13 @@ |
|||
using Microsoft.eShopWeb.Infrastructure.Identity; |
|||
using Microsoft.AspNetCore.Identity; |
|||
using Microsoft.AspNetCore.Identity; |
|||
using Microsoft.AspNetCore.Mvc; |
|||
using Microsoft.eShopWeb.Infrastructure.Identity; |
|||
using Microsoft.eShopWeb.Web.Interfaces; |
|||
using Microsoft.eShopWeb.Web.Pages.Basket; |
|||
using Microsoft.eShopWeb.Web.ViewModels; |
|||
using System.Linq; |
|||
using System.Threading.Tasks; |
|||
|
|||
namespace Microsoft.eShopWeb.Web.ViewComponents |
|||
namespace Microsoft.eShopWeb.Web.Pages.Shared.Components.BasketComponent |
|||
{ |
|||
public class Basket : ViewComponent |
|||
{ |
|||
@ -0,0 +1,13 @@ |
|||
@model BasketComponentViewModel |
|||
@{ |
|||
ViewData["Title"] = "My Basket"; |
|||
} |
|||
<a class="esh-basketstatus " |
|||
asp-page="/Basket/Index"> |
|||
<div class="esh-basketstatus-image"> |
|||
<img src="~/images/cart.png" /> |
|||
</div> |
|||
<div class="esh-basketstatus-badge"> |
|||
@Model.ItemsCount |
|||
</div> |
|||
</a> |
|||
@ -1,22 +1,14 @@ |
|||
@model CatalogItemViewModel |
|||
|
|||
|
|||
<form asp-controller="Basket" asp-action="AddToBasket"> |
|||
|
|||
<form asp-page="/Basket/Index" method="post"> |
|||
<img class="esh-catalog-thumbnail" src="@Model.PictureUri" /> |
|||
<input class="esh-catalog-button" type="submit" value="[ ADD TO BASKET ]" /> |
|||
|
|||
<div class="esh-catalog-name"> |
|||
<span>@Model.Name</span> |
|||
</div> |
|||
<div class="esh-catalog-price"> |
|||
<span>@Model.Price.ToString("N2")</span> |
|||
</div> |
|||
@*<input type="hidden" asp-for="@Model.CatalogBrand" name="brand" /> |
|||
<input type="hidden" asp-for="@Model.CatalogBrandId" name="brandId" /> |
|||
<input type="hidden" asp-for="@Model.CatalogType" name="type" /> |
|||
<input type="hidden" asp-for="@Model.CatalogTypeId" name="typeId" /> |
|||
<input type="hidden" asp-for="@Model.Description" name="description" />*@ |
|||
<input type="hidden" asp-for="@Model.Id" name="id" /> |
|||
<input type="hidden" asp-for="@Model.Name" name="name" /> |
|||
<input type="hidden" asp-for="@Model.PictureUri" name="pictureUri" /> |
|||
@ -0,0 +1,9 @@ |
|||
@using Microsoft.eShopWeb.Web |
|||
@using Microsoft.eShopWeb.Web.ViewModels |
|||
@using Microsoft.eShopWeb.Web.ViewModels.Account |
|||
@using Microsoft.eShopWeb.Web.ViewModels.Manage |
|||
@using Microsoft.eShopWeb.Web.Pages |
|||
@using Microsoft.AspNetCore.Identity |
|||
@using Microsoft.eShopWeb.Infrastructure.Identity |
|||
@namespace Microsoft.eShopWeb.Web.Pages |
|||
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers |
|||
@ -0,0 +1,3 @@ |
|||
@{ |
|||
Layout = "_Layout"; |
|||
} |
|||
@ -1,8 +0,0 @@ |
|||
@{ |
|||
ViewData["Title"] = "Home Page"; |
|||
} |
|||
|
|||
<div class="text-center"> |
|||
<h1 class="display-4">Welcome</h1> |
|||
<p>Learn about <a href="https://docs.microsoft.com/aspnet/core">building Web apps with ASP.NET Core</a>.</p> |
|||
</div> |
|||
@ -1,77 +1,66 @@ |
|||
<!DOCTYPE html> |
|||
<html> |
|||
<head> |
|||
<meta charset="utf-8" /> |
|||
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> |
|||
<title>@ViewData["Title"] - Microsoft.eShopOnWeb</title> |
|||
|
|||
<environment names="Development"> |
|||
<link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.css" /> |
|||
<link rel="stylesheet" href="~/css/app.css" /> |
|||
</environment> |
|||
<environment names="Staging,Production"> |
|||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.0.0-alpha.5/css/bootstrap.min.css" |
|||
asp-fallback-href="~/lib/bootstrap/dist/css/bootstrap.min.css" |
|||
asp-fallback-test-class="sr-only" asp-fallback-test-property="position" asp-fallback-test-value="absolute" /> |
|||
<link rel="stylesheet" href="~/css/app.min.css" asp-append-version="true" /> |
|||
</environment> |
|||
<meta charset="utf-8" /> |
|||
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> |
|||
<title>@ViewData["Title"] - Microsoft.eShopOnWeb</title> |
|||
<environment names="Development"> |
|||
<link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.css" /> |
|||
<link rel="stylesheet" href="~/css/app.css" /> |
|||
</environment> |
|||
<environment names="Staging,Production"> |
|||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.0.0-alpha.5/css/bootstrap.min.css" |
|||
asp-fallback-href="~/lib/bootstrap/dist/css/bootstrap.min.css" |
|||
asp-fallback-test-class="sr-only" asp-fallback-test-property="position" asp-fallback-test-value="absolute" /> |
|||
<link rel="stylesheet" href="~/css/app.min.css" asp-append-version="true" /> |
|||
</environment> |
|||
<link rel="stylesheet" href="~/css/app.component.css" /> |
|||
<link rel="stylesheet" href="~/css/basket/basket.component.css" /> |
|||
<link rel="stylesheet" href="~/css/catalog/pager.css" /> |
|||
<link rel="stylesheet" href="~/css/catalog/catalog.component.css" /> |
|||
<link rel="stylesheet" href="~/css/catalog/catalog.component.css" /> |
|||
<link rel="stylesheet" href="~/css/basket/basket-status/basket-status.component.css" /> |
|||
<link rel="stylesheet" href="~/css/orders/orders.component.css" /> |
|||
</head> |
|||
<body> |
|||
<header class="navbar navbar-light navbar-static-top"> |
|||
<div class="container"> |
|||
<article class="row"> |
|||
|
|||
<section class="col-lg-7 col-md-6 col-xs-12"> |
|||
<a asp-area="" asp-controller="Catalog" asp-action="Index" class="navbar-brand"> |
|||
<img src="~/images/brand.png" alt="eShop On Web"/> |
|||
</a> |
|||
</section> |
|||
<header class="navbar navbar-light navbar-static-top"> |
|||
<div class="container"> |
|||
<article class="row"> |
|||
<section class="col-lg-7 col-md-6 col-xs-12"> |
|||
<a asp-area="" asp-page="/Index" class="navbar-brand"> |
|||
<img src="~/images/brand.png" alt="eShop On Web" /> |
|||
</a> |
|||
</section> |
|||
<partial name="_LoginPartial" /> |
|||
</article> |
|||
</div> |
|||
</header> |
|||
|
|||
@RenderBody() |
|||
|
|||
|
|||
<footer class="esh-app-footer"> |
|||
<div class="container"> |
|||
<article class="row"> |
|||
|
|||
<section class="col-sm-6"> |
|||
</section> |
|||
|
|||
<section class="col-sm-6"> |
|||
<div class="esh-app-footer-text hidden-xs"> e-ShopOnWeb. All rights reserved </div> |
|||
</section> |
|||
|
|||
</article> |
|||
</div> |
|||
</footer> |
|||
|
|||
<environment names="Development"> |
|||
<script src="~/lib/jquery/dist/jquery.js"></script> |
|||
<script src="~/lib/bootstrap/dist/js/bootstrap.js"></script> |
|||
<script src="~/js/site.js" asp-append-version="true"></script> |
|||
</environment> |
|||
<environment names="Staging,Production"> |
|||
<script src="https://ajax.aspnetcdn.com/ajax/jquery/jquery-2.2.0.min.js" |
|||
asp-fallback-src="~/lib/jquery/dist/jquery.min.js" |
|||
asp-fallback-test="window.jQuery"> |
|||
</script> |
|||
<script src="https://ajax.aspnetcdn.com/ajax/bootstrap/3.3.6/bootstrap.min.js" |
|||
asp-fallback-src="~/lib/bootstrap/dist/js/bootstrap.min.js" |
|||
asp-fallback-test="window.jQuery && window.jQuery.fn && window.jQuery.fn.modal"> |
|||
</script> |
|||
<script src="~/js/site.min.js" asp-append-version="true"></script> |
|||
</environment> |
|||
|
|||
@RenderSection("scripts", required: false) |
|||
</article> |
|||
</div> |
|||
</header> |
|||
@RenderBody() |
|||
<footer class="esh-app-footer"> |
|||
<div class="container"> |
|||
<article class="row"> |
|||
<section class="col-sm-6"></section> |
|||
<section class="col-sm-6"> |
|||
<div class="esh-app-footer-text hidden-xs"> e-ShopOnWeb. All rights reserved </div> |
|||
</section> |
|||
</article> |
|||
</div> |
|||
</footer> |
|||
<environment names="Development"> |
|||
<script src="~/lib/jquery/dist/jquery.js"></script> |
|||
<script src="~/lib/bootstrap/dist/js/bootstrap.js"></script> |
|||
<script src="~/js/site.js" asp-append-version="true"></script> |
|||
</environment> |
|||
<environment names="Staging,Production"> |
|||
<script src="https://ajax.aspnetcdn.com/ajax/jquery/jquery-2.2.0.min.js" |
|||
asp-fallback-src="~/lib/jquery/dist/jquery.min.js" |
|||
asp-fallback-test="window.jQuery"> |
|||
</script> |
|||
<script src="https://ajax.aspnetcdn.com/ajax/bootstrap/3.3.6/bootstrap.min.js" |
|||
asp-fallback-src="~/lib/bootstrap/dist/js/bootstrap.min.js" |
|||
asp-fallback-test="window.jQuery && window.jQuery.fn && window.jQuery.fn.modal"> |
|||
</script> |
|||
<script src="~/js/site.min.js" asp-append-version="true"></script> |
|||
</environment> |
|||
@RenderSection("scripts", required: false) |
|||
</body> |
|||
</html> |
|||
|
|||
@ -1,13 +1,14 @@ |
|||
using Microsoft.eShopWeb.RazorPages; |
|||
using Microsoft.eShopWeb.FunctionalTests.Web.Controllers; |
|||
using Microsoft.eShopWeb.Web; |
|||
using System.Net.Http; |
|||
using System.Threading.Tasks; |
|||
using Xunit; |
|||
|
|||
namespace Microsoft.eShopWeb.FunctionalTests.WebRazorPages |
|||
{ |
|||
public class HomePageOnGet : IClassFixture<CustomWebRazorPagesApplicationFactory<Startup>> |
|||
public class HomePageOnGet : IClassFixture<CustomWebApplicationFactory<Startup>> |
|||
{ |
|||
public HomePageOnGet(CustomWebRazorPagesApplicationFactory<Startup> factory) |
|||
public HomePageOnGet(CustomWebApplicationFactory<Startup> factory) |
|||
{ |
|||
Client = factory.CreateClient(); |
|||
} |
|||
@ -1,70 +0,0 @@ |
|||
using Microsoft.AspNetCore.Hosting; |
|||
using Microsoft.AspNetCore.Mvc.Testing; |
|||
using Microsoft.EntityFrameworkCore; |
|||
using Microsoft.eShopWeb.Infrastructure.Data; |
|||
using Microsoft.eShopWeb.Infrastructure.Identity; |
|||
using Microsoft.eShopWeb.RazorPages; |
|||
using Microsoft.Extensions.DependencyInjection; |
|||
using Microsoft.Extensions.Logging; |
|||
using System; |
|||
|
|||
namespace Microsoft.eShopWeb.FunctionalTests.WebRazorPages |
|||
{ |
|||
public class CustomWebRazorPagesApplicationFactory<TStartup> |
|||
: WebApplicationFactory<Startup> |
|||
{ |
|||
protected override void ConfigureWebHost(IWebHostBuilder builder) |
|||
{ |
|||
builder.ConfigureServices(services => |
|||
{ |
|||
// Create a new service provider.
|
|||
var serviceProvider = new ServiceCollection() |
|||
.AddEntityFrameworkInMemoryDatabase() |
|||
.BuildServiceProvider(); |
|||
|
|||
// Add a database context (ApplicationDbContext) using an in-memory
|
|||
// database for testing.
|
|||
services.AddDbContext<CatalogContext>(options => |
|||
{ |
|||
options.UseInMemoryDatabase("InMemoryDbForTesting"); |
|||
options.UseInternalServiceProvider(serviceProvider); |
|||
}); |
|||
|
|||
services.AddDbContext<AppIdentityDbContext>(options => |
|||
{ |
|||
options.UseInMemoryDatabase("Identity"); |
|||
options.UseInternalServiceProvider(serviceProvider); |
|||
}); |
|||
|
|||
// Build the service provider.
|
|||
var sp = services.BuildServiceProvider(); |
|||
|
|||
// Create a scope to obtain a reference to the database
|
|||
// context (ApplicationDbContext).
|
|||
using (var scope = sp.CreateScope()) |
|||
{ |
|||
var scopedServices = scope.ServiceProvider; |
|||
var db = scopedServices.GetRequiredService<CatalogContext>(); |
|||
var loggerFactory = scopedServices.GetRequiredService<ILoggerFactory>(); |
|||
|
|||
var logger = scopedServices |
|||
.GetRequiredService<ILogger<CustomWebRazorPagesApplicationFactory<TStartup>>>(); |
|||
|
|||
// Ensure the database is created.
|
|||
db.Database.EnsureCreated(); |
|||
|
|||
try |
|||
{ |
|||
// Seed the database with test data.
|
|||
CatalogContextSeed.SeedAsync(db, loggerFactory).Wait(); |
|||
} |
|||
catch (Exception ex) |
|||
{ |
|||
logger.LogError(ex, $"An error occurred seeding the " + |
|||
"database with test messages. Error: {ex.Message}"); |
|||
} |
|||
} |
|||
}); |
|||
} |
|||
} |
|||
} |
|||
@ -1,32 +0,0 @@ |
|||
using Microsoft.AspNetCore.Mvc.Testing; |
|||
using Microsoft.eShopWeb.RazorPages; |
|||
using System.Net; |
|||
using System.Net.Http; |
|||
using System.Threading.Tasks; |
|||
using Xunit; |
|||
|
|||
namespace Microsoft.eShopWeb.FunctionalTests.WebRazorPages |
|||
{ |
|||
public class OrderIndexOnGet : IClassFixture<CustomWebRazorPagesApplicationFactory<Startup>> |
|||
{ |
|||
public OrderIndexOnGet(CustomWebRazorPagesApplicationFactory<Startup> factory) |
|||
{ |
|||
Client = factory.CreateClient(new WebApplicationFactoryClientOptions |
|||
{ |
|||
AllowAutoRedirect = false |
|||
}); |
|||
} |
|||
|
|||
public HttpClient Client { get; } |
|||
|
|||
[Fact] |
|||
public async Task ReturnsRedirectGivenAnonymousUser() |
|||
{ |
|||
var response = await Client.GetAsync("/Order/Index"); |
|||
var redirectLocation = response.Headers.Location.OriginalString; |
|||
|
|||
Assert.Equal(HttpStatusCode.Redirect, response.StatusCode); |
|||
Assert.Contains("Account/Login", redirectLocation); |
|||
} |
|||
} |
|||
} |
|||
Loading…
Reference in new issue