From 9f724f6ac4a65160c9847d29bc748e07ce06c7d2 Mon Sep 17 00:00:00 2001 From: Justin Kotalik Date: Tue, 19 Mar 2019 11:03:48 -0700 Subject: [PATCH] Revert "Publish MusicStore as part of build (#8578)" (#8655) This reverts commit f3eaa73c1a52163b10139f1335db331bd2c89df4. --- .../src/PublishedApplicationPublisher.cs | 47 ---- src/MusicStore/MusicStore.sln | 14 + .../samples/MusicStore/MusicStore.csproj | 1 - .../MusicStore.E2ETests.csproj | 43 +-- .../MusicStore.E2ETests/PublishAndRunTests.cs | 13 +- .../PublishAssetAttribute.cs | 44 --- .../CartSummaryComponentTest.cs | 90 +++++++ .../MusicStore.Test/CheckoutControllerTest.cs | 254 ++++++++++++++++++ .../MusicStore.Test/GenreMenuComponentTest.cs | 59 ++++ .../MusicStore.Test/HomeControllerTest.cs | 131 +++++++++ .../MusicStore.Test/ManageControllerTest.cs | 121 +++++++++ .../Models/ShoppingCartTest.cs | 64 +++++ .../MusicStore.Test/MusicStore.Test.csproj | 16 ++ .../ShoppingCartControllerTest.cs | 242 +++++++++++++++++ .../MusicStore.Test/StoreControllerTest.cs | 182 +++++++++++++ .../test/MusicStore.Test/TestAppSettings.cs | 26 ++ .../test/MusicStore.Test/TestSession.cs | 50 ++++ .../PublishedApplicationPublisher.cs | 14 +- .../PublishedSitesFixture.cs | 4 +- .../Utilities/IISTestSiteFixture.cs | 6 +- 20 files changed, 1270 insertions(+), 151 deletions(-) delete mode 100644 src/Hosting/Server.IntegrationTesting/src/PublishedApplicationPublisher.cs delete mode 100644 src/MusicStore/test/MusicStore.E2ETests/PublishAssetAttribute.cs create mode 100644 src/MusicStore/test/MusicStore.Test/CartSummaryComponentTest.cs create mode 100644 src/MusicStore/test/MusicStore.Test/CheckoutControllerTest.cs create mode 100644 src/MusicStore/test/MusicStore.Test/GenreMenuComponentTest.cs create mode 100644 src/MusicStore/test/MusicStore.Test/HomeControllerTest.cs create mode 100644 src/MusicStore/test/MusicStore.Test/ManageControllerTest.cs create mode 100644 src/MusicStore/test/MusicStore.Test/Models/ShoppingCartTest.cs create mode 100644 src/MusicStore/test/MusicStore.Test/MusicStore.Test.csproj create mode 100644 src/MusicStore/test/MusicStore.Test/ShoppingCartControllerTest.cs create mode 100644 src/MusicStore/test/MusicStore.Test/StoreControllerTest.cs create mode 100644 src/MusicStore/test/MusicStore.Test/TestAppSettings.cs create mode 100644 src/MusicStore/test/MusicStore.Test/TestSession.cs diff --git a/src/Hosting/Server.IntegrationTesting/src/PublishedApplicationPublisher.cs b/src/Hosting/Server.IntegrationTesting/src/PublishedApplicationPublisher.cs deleted file mode 100644 index d44e907a07..0000000000 --- a/src/Hosting/Server.IntegrationTesting/src/PublishedApplicationPublisher.cs +++ /dev/null @@ -1,47 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using System; -using System.IO; -using System.Threading.Tasks; -using Microsoft.Extensions.Logging; - -namespace Microsoft.AspNetCore.Server.IntegrationTesting -{ - public class PublishedApplicationPublisher : ApplicationPublisher - { - public PublishedApplicationPublisher(string applicationName) - : base(applicationName) - { - } - - public override Task Publish(DeploymentParameters deploymentParameters, ILogger logger) - { - var path = ResolvePublishedApplicationPath(deploymentParameters, logger); - - logger.LogInformation("Using prepublished application from {PublishDir}", path); - - var target = CreateTempDirectory(); - - var source = new DirectoryInfo(path); - CachingApplicationPublisher.CopyFiles(source, target, logger); - return Task.FromResult(new PublishedApplication(target.FullName, logger)); - } - - protected virtual string ResolvePublishedApplicationPath(DeploymentParameters deploymentParameters, ILogger logger) - { - var path = deploymentParameters.PublishedApplicationRootPath; - if (string.IsNullOrEmpty(path)) - { - throw new ArgumentException($"{nameof(DeploymentParameters)}.{nameof(DeploymentParameters.PublishedApplicationRootPath)} not set."); - } - - if (!Directory.Exists(path)) - { - throw new DirectoryNotFoundException($"Published application not found at '{path}'."); - } - - return deploymentParameters.PublishedApplicationRootPath; - } - } -} diff --git a/src/MusicStore/MusicStore.sln b/src/MusicStore/MusicStore.sln index 562ba9b772..cbe1dfc195 100644 --- a/src/MusicStore/MusicStore.sln +++ b/src/MusicStore/MusicStore.sln @@ -5,6 +5,8 @@ VisualStudioVersion = 16.0.0.0 MinimumVisualStudioVersion = 16.0.0.0 Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MusicStore", "samples\MusicStore\MusicStore.csproj", "{3CFBED5D-2ED8-49DB-96FB-BDAA748DC5A0}" EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MusicStore.Test", "test\MusicStore.Test\MusicStore.Test.csproj", "{CA663205-77DE-4E55-B300-85594181B5A9}" +EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MusicStore.E2ETests", "test\MusicStore.E2ETests\MusicStore.E2ETests.csproj", "{72A5F455-121F-4954-BF28-D712C6BE88EA}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.Antiforgery", "..\Antiforgery\src\Microsoft.AspNetCore.Antiforgery.csproj", "{DECBCA36-8E91-4A46-914D-832ECCE7D3F4}" @@ -165,6 +167,18 @@ Global {3CFBED5D-2ED8-49DB-96FB-BDAA748DC5A0}.Release|x64.Build.0 = Release|x64 {3CFBED5D-2ED8-49DB-96FB-BDAA748DC5A0}.Release|x86.ActiveCfg = Release|x86 {3CFBED5D-2ED8-49DB-96FB-BDAA748DC5A0}.Release|x86.Build.0 = Release|x86 + {CA663205-77DE-4E55-B300-85594181B5A9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {CA663205-77DE-4E55-B300-85594181B5A9}.Debug|Any CPU.Build.0 = Debug|Any CPU + {CA663205-77DE-4E55-B300-85594181B5A9}.Debug|x64.ActiveCfg = Debug|Any CPU + {CA663205-77DE-4E55-B300-85594181B5A9}.Debug|x64.Build.0 = Debug|Any CPU + {CA663205-77DE-4E55-B300-85594181B5A9}.Debug|x86.ActiveCfg = Debug|Any CPU + {CA663205-77DE-4E55-B300-85594181B5A9}.Debug|x86.Build.0 = Debug|Any CPU + {CA663205-77DE-4E55-B300-85594181B5A9}.Release|Any CPU.ActiveCfg = Release|Any CPU + {CA663205-77DE-4E55-B300-85594181B5A9}.Release|Any CPU.Build.0 = Release|Any CPU + {CA663205-77DE-4E55-B300-85594181B5A9}.Release|x64.ActiveCfg = Release|Any CPU + {CA663205-77DE-4E55-B300-85594181B5A9}.Release|x64.Build.0 = Release|Any CPU + {CA663205-77DE-4E55-B300-85594181B5A9}.Release|x86.ActiveCfg = Release|Any CPU + {CA663205-77DE-4E55-B300-85594181B5A9}.Release|x86.Build.0 = Release|Any CPU {72A5F455-121F-4954-BF28-D712C6BE88EA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {72A5F455-121F-4954-BF28-D712C6BE88EA}.Debug|Any CPU.Build.0 = Debug|Any CPU {72A5F455-121F-4954-BF28-D712C6BE88EA}.Debug|x64.ActiveCfg = Debug|Any CPU diff --git a/src/MusicStore/samples/MusicStore/MusicStore.csproj b/src/MusicStore/samples/MusicStore/MusicStore.csproj index 1135a09b2a..682cc74754 100644 --- a/src/MusicStore/samples/MusicStore/MusicStore.csproj +++ b/src/MusicStore/samples/MusicStore/MusicStore.csproj @@ -8,7 +8,6 @@ $(DefineConstants);DEMO win-x86;win-x64;linux-x64;osx-x64 true - false diff --git a/src/MusicStore/test/MusicStore.E2ETests/MusicStore.E2ETests.csproj b/src/MusicStore/test/MusicStore.E2ETests/MusicStore.E2ETests.csproj index 244d7aba96..13182d0a2a 100644 --- a/src/MusicStore/test/MusicStore.E2ETests/MusicStore.E2ETests.csproj +++ b/src/MusicStore/test/MusicStore.E2ETests/MusicStore.E2ETests.csproj @@ -11,6 +11,9 @@ $(NoWarn);NU1605 false + false + false + false @@ -36,44 +39,4 @@ - - - - - - - - - - - - - - - - - - <_TargetOsName Condition=" $([MSBuild]::IsOSPlatform('Windows'))">win - <_TargetOsName Condition=" $([MSBuild]::IsOSPlatform('OSX'))">osx - <_TargetOsName Condition=" $([MSBuild]::IsOSPlatform('Linux'))">linux - - PublishDir=$(PublishDirectory);Configuration=$(Configuration);TargetArchitecture=$(Architecture) - $(PublishCommandOptions);RuntimeIdentifier=$(_TargetOsName)-$(Architecture) - - - $(PublishCommandOptions);UseAppHost=false; - - - - - - diff --git a/src/MusicStore/test/MusicStore.E2ETests/PublishAndRunTests.cs b/src/MusicStore/test/MusicStore.E2ETests/PublishAndRunTests.cs index 4d3c651a2f..8c31c9c2f6 100644 --- a/src/MusicStore/test/MusicStore.E2ETests/PublishAndRunTests.cs +++ b/src/MusicStore/test/MusicStore.E2ETests/PublishAndRunTests.cs @@ -1,15 +1,12 @@ using System; using System.Collections.Generic; using System.IO; -using System.Linq; using System.Net.Http; -using System.Reflection; using System.Threading.Tasks; using Microsoft.AspNetCore.Server.IntegrationTesting; using Microsoft.AspNetCore.Testing.xunit; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging.Testing; -using MusicStore; using Xunit; namespace E2ETests @@ -18,7 +15,7 @@ namespace E2ETests public class PublishAndRunTests : LoggedTest { public static TestMatrix TestVariants - => TestMatrix.ForServers(ServerType.IISExpress, ServerType.HttpSys, ServerType.Kestrel) + => TestMatrix.ForServers(ServerType.IISExpress, ServerType.HttpSys) .WithTfms(Tfm.NetCoreApp30) .WithAllApplicationTypes() .WithAllHostingModels() @@ -34,19 +31,15 @@ namespace E2ETests var logger = loggerFactory.CreateLogger("Publish_And_Run_Tests"); var musicStoreDbName = DbUtils.GetUniqueName(); - var publishDirectory = Path.Combine(AppContext.BaseDirectory, "testassets", variant.ApplicationType.ToString(), variant.Architecture.ToString()); - var deploymentParameters = new DeploymentParameters(variant) { - ApplicationName = "MusicStore", ApplicationPath = Helpers.GetApplicationPath(), - PublishedApplicationRootPath = publishDirectory, + PublishApplicationBeforeDeployment = true, PreservePublishedApplicationForDebugging = Helpers.PreservePublishedApplicationForDebugging, UserAdditionalCleanup = parameters => { DbUtils.DropDatabase(musicStoreDbName, logger); - }, - ApplicationPublisher = new PublishedApplicationPublisher("MusicStore"), + } }; // Override the connection strings using environment based configuration diff --git a/src/MusicStore/test/MusicStore.E2ETests/PublishAssetAttribute.cs b/src/MusicStore/test/MusicStore.E2ETests/PublishAssetAttribute.cs deleted file mode 100644 index c7bfd10fc7..0000000000 --- a/src/MusicStore/test/MusicStore.E2ETests/PublishAssetAttribute.cs +++ /dev/null @@ -1,44 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using System; -using Microsoft.AspNetCore.Server.IntegrationTesting; - -namespace MusicStore -{ - [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)] - public class PublishAssetAttribute : Attribute - { - public PublishAssetAttribute(string architecture, string applicationType, string server, string hostingModel, string publishDirectory) - { - RuntimeArchitecture = Enum.Parse(architecture); - ApplicationType = Enum.Parse(applicationType); - ServerType = Enum.Parse(server); - HostingModel = Enum.Parse(hostingModel); - PublishDirectory = publishDirectory; - } - - internal TestVariant GetTestVariant() - { - return new TestVariant - { - ApplicationType = ApplicationType, - Architecture = RuntimeArchitecture, - HostingModel = HostingModel, - Server = ServerType, - Tfm = Tfm.NetCoreApp30, - }; - } - - public RuntimeArchitecture RuntimeArchitecture { get; } - - public ApplicationType ApplicationType { get; } - - public ServerType ServerType { get; } - - public HostingModel HostingModel { get; } - - public string PublishDirectory { get; } - } - -} diff --git a/src/MusicStore/test/MusicStore.Test/CartSummaryComponentTest.cs b/src/MusicStore/test/MusicStore.Test/CartSummaryComponentTest.cs new file mode 100644 index 0000000000..c5ba830c80 --- /dev/null +++ b/src/MusicStore/test/MusicStore.Test/CartSummaryComponentTest.cs @@ -0,0 +1,90 @@ +using System; +using System.Linq; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Mvc.Rendering; +using Microsoft.AspNetCore.Mvc.ViewComponents; +using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.DependencyInjection; +using MusicStore.Controllers; +using MusicStore.Models; +using Xunit; + +namespace MusicStore.Components +{ + public class CartSummaryComponentTest + { + private readonly IServiceProvider _serviceProvider; + + public CartSummaryComponentTest() + { + var efServiceProvider = new ServiceCollection().AddEntityFrameworkInMemoryDatabase().BuildServiceProvider(); + + var services = new ServiceCollection(); + + services + .AddMemoryCache() + .AddLogging() + .AddDbContext(b => b.UseInMemoryDatabase("Scratch").UseInternalServiceProvider(efServiceProvider)); + + _serviceProvider = services.BuildServiceProvider(); + } + + [Fact] + public async Task CartSummaryComponent_Returns_CartedItems() + { + // Arrange + var viewContext = new ViewContext() + { + HttpContext = new DefaultHttpContext() + }; + + // Session initialization + var cartId = "CartId_A"; + viewContext.HttpContext.Session = new TestSession(); + viewContext.HttpContext.Session.SetString("Session", cartId); + + // DbContext initialization + var dbContext = _serviceProvider.GetRequiredService(); + PopulateData(dbContext, cartId, albumTitle: "AlbumA", itemCount: 10); + + // CartSummaryComponent initialization + var cartSummaryComponent = new CartSummaryComponent(dbContext) + { + ViewComponentContext = new ViewComponentContext() { ViewContext = viewContext } + }; + + // Act + var result = await cartSummaryComponent.InvokeAsync(); + + // Assert + Assert.NotNull(result); + var viewResult = Assert.IsType(result); + Assert.Null(viewResult.ViewName); + Assert.Null(viewResult.ViewData.Model); + Assert.Equal(10, cartSummaryComponent.ViewBag.CartCount); + Assert.Equal("AlbumA", cartSummaryComponent.ViewBag.CartSummary); + } + + private static void PopulateData(MusicStoreContext context, string cartId, string albumTitle, int itemCount) + { + var album = new Album() + { + AlbumId = 1, + Title = albumTitle, + }; + + var cartItems = Enumerable.Range(1, itemCount).Select(n => + new CartItem() + { + AlbumId = 1, + Album = album, + Count = 1, + CartId = cartId, + }).ToArray(); + + context.AddRange(cartItems); + context.SaveChanges(); + } + } +} diff --git a/src/MusicStore/test/MusicStore.Test/CheckoutControllerTest.cs b/src/MusicStore/test/MusicStore.Test/CheckoutControllerTest.cs new file mode 100644 index 0000000000..e978410877 --- /dev/null +++ b/src/MusicStore/test/MusicStore.Test/CheckoutControllerTest.cs @@ -0,0 +1,254 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Security.Claims; +using System.Threading; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Mvc; +using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Primitives; +using MusicStore.Models; +using Xunit; + +namespace MusicStore.Controllers +{ + public class CheckoutControllerTest + { + private readonly IServiceProvider _serviceProvider; + + public CheckoutControllerTest() + { + var efServiceProvider = new ServiceCollection().AddEntityFrameworkInMemoryDatabase().BuildServiceProvider(); + + var services = new ServiceCollection(); + + services + .AddMemoryCache() + .AddLogging() + .AddDbContext(b => b.UseInMemoryDatabase("Scratch").UseInternalServiceProvider(efServiceProvider)); + + _serviceProvider = services.BuildServiceProvider(); + } + + [Fact] + public void AddressAndPayment_ReturnsDefaultView() + { + // Arrange + var controller = new CheckoutController(_serviceProvider.GetService>()); + + // Act + var result = controller.AddressAndPayment(); + + // Assert + var viewResult = Assert.IsType(result); + Assert.Null(viewResult.ViewName); + } + + [Fact] + public async Task AddressAndPayment_RedirectToCompleteWhenSuccessful() + { + // Arrange + var httpContext = new DefaultHttpContext(); + + var orderId = 10; + var order = new Order() + { + OrderId = orderId, + }; + + // Session initialization + var cartId = "CartId_A"; + httpContext.Session = new TestSession(); + httpContext.Session.SetString("Session", cartId); + + // FormCollection initialization + httpContext.Request.Form = + new FormCollection( + new Dictionary() + { { "PromoCode", new[] { "FREE" } } } + ); + + // UserName initialization + var claims = new List { new Claim(ClaimTypes.Name, "TestUserName") }; + httpContext.User = new ClaimsPrincipal(new ClaimsIdentity(claims)); + + // DbContext initialization + var dbContext = _serviceProvider.GetRequiredService(); + var cartItems = CreateTestCartItems( + cartId, + itemPrice: 10, + numberOfItem: 1); + dbContext.AddRange(cartItems.Select(n => n.Album).Distinct()); + dbContext.AddRange(cartItems); + dbContext.SaveChanges(); + + var controller = new CheckoutController(_serviceProvider.GetService>()); + controller.ControllerContext.HttpContext = httpContext; + + // Act + var result = await controller.AddressAndPayment(dbContext, order, CancellationToken.None); + + // Assert + var redirectResult = Assert.IsType(result); + Assert.Equal("Complete", redirectResult.ActionName); + Assert.Null(redirectResult.ControllerName); + Assert.NotNull(redirectResult.RouteValues); + + Assert.Equal(orderId, redirectResult.RouteValues["Id"]); + } + + [Fact] + public async Task AddressAndPayment_ReturnsOrderIfInvalidPromoCode() + { + // Arrange + var context = new DefaultHttpContext(); + var dbContext = _serviceProvider.GetRequiredService(); + + // AddressAndPayment action reads the Promo code from FormCollection. + context.Request.Form = + new FormCollection(new Dictionary()); + + var controller = new CheckoutController(_serviceProvider.GetService>()); + controller.ControllerContext.HttpContext = context; + + // Do not need actual data for Order; the Order object will be checked for the reference equality. + var order = new Order(); + + // Act + var result = await controller.AddressAndPayment(dbContext, order, CancellationToken.None); + + // Assert + var viewResult = Assert.IsType(result); + Assert.Null(viewResult.ViewName); + + Assert.NotNull(viewResult.ViewData); + Assert.Same(order, viewResult.ViewData.Model); + } + + [Fact] + public async Task AddressAndPayment_ReturnsOrderIfRequestCanceled() + { + // Arrange + var context = new DefaultHttpContext(); + context.Request.Form = + new FormCollection(new Dictionary()); + var dbContext = _serviceProvider.GetRequiredService(); + + var controller = new CheckoutController(_serviceProvider.GetService>()); + controller.ControllerContext.HttpContext = context; + + var order = new Order(); + + // Act + var result = await controller.AddressAndPayment(dbContext, order, new CancellationToken(true)); + + // Assert + var viewResult = Assert.IsType(result); + Assert.Null(viewResult.ViewName); + + Assert.NotNull(viewResult.ViewData); + Assert.Same(order, viewResult.ViewData.Model); + } + + [Fact] + public async Task AddressAndPayment_ReturnsOrderIfInvalidOrderModel() + { + // Arrange + var controller = new CheckoutController(_serviceProvider.GetService>()); + controller.ModelState.AddModelError("a", "ModelErrorA"); + var dbContext = _serviceProvider.GetRequiredService(); + + var order = new Order(); + + // Act + var result = await controller.AddressAndPayment(dbContext, order, CancellationToken.None); + + // Assert + var viewResult = Assert.IsType(result); + Assert.Null(viewResult.ViewName); + + Assert.NotNull(viewResult.ViewData); + Assert.Same(order, viewResult.ViewData.Model); + } + + [Fact] + public async Task Complete_ReturnsOrderIdIfValid() + { + // Arrange + var orderId = 100; + var userName = "TestUserA"; + var claims = new List { new Claim(ClaimTypes.Name, userName) }; + + var httpContext = new DefaultHttpContext() + { + User = new ClaimsPrincipal(new ClaimsIdentity(claims)), + }; + + var dbContext = + _serviceProvider.GetRequiredService(); + dbContext.Add(new Order() + { + OrderId = orderId, + Username = userName + }); + dbContext.SaveChanges(); + + var controller = new CheckoutController(_serviceProvider.GetService>()); + controller.ControllerContext.HttpContext = httpContext; + + // Act + var result = await controller.Complete(dbContext, orderId); + + // Assert + var viewResult = Assert.IsType(result); + Assert.Null(viewResult.ViewName); + + Assert.NotNull(viewResult.ViewData); + Assert.Equal(orderId, viewResult.ViewData.Model); + } + + [Fact] + public async Task Complete_ReturnsErrorIfInvalidOrder() + { + // Arrange + var invalidOrderId = 100; + var dbContext = + _serviceProvider.GetRequiredService(); + + var controller = new CheckoutController(_serviceProvider.GetService>()); + controller.ControllerContext.HttpContext = new DefaultHttpContext(); + + // Act + var result = await controller.Complete(dbContext, invalidOrderId); + + // Assert + var viewResult = Assert.IsType(result); + + Assert.Equal("Error", viewResult.ViewName); + } + + private static CartItem[] CreateTestCartItems(string cartId, decimal itemPrice, int numberOfItem) + { + var albums = Enumerable.Range(1, 10).Select(n => + new Album() + { + AlbumId = n, + Price = itemPrice, + }).ToArray(); + + var cartItems = Enumerable.Range(1, numberOfItem).Select(n => + new CartItem() + { + Count = 1, + CartId = cartId, + AlbumId = n % 10, + Album = albums[n % 10], + }).ToArray(); + + return cartItems; + } + } +} diff --git a/src/MusicStore/test/MusicStore.Test/GenreMenuComponentTest.cs b/src/MusicStore/test/MusicStore.Test/GenreMenuComponentTest.cs new file mode 100644 index 0000000000..30ac743ec0 --- /dev/null +++ b/src/MusicStore/test/MusicStore.Test/GenreMenuComponentTest.cs @@ -0,0 +1,59 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Mvc.ViewComponents; +using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.DependencyInjection; +using MusicStore.Models; +using Xunit; + +namespace MusicStore.Components +{ + public class GenreMenuComponentTest + { + private readonly IServiceProvider _serviceProvider; + + public GenreMenuComponentTest() + { + var efServiceProvider = new ServiceCollection().AddEntityFrameworkInMemoryDatabase().BuildServiceProvider(); + + var services = new ServiceCollection(); + + services + .AddMemoryCache() + .AddLogging() + .AddDbContext(b => b.UseInMemoryDatabase("Scratch").UseInternalServiceProvider(efServiceProvider)); + + _serviceProvider = services.BuildServiceProvider(); + } + + [Fact] + public async Task GenreMenuComponent_Returns_NineGenres() + { + // Arrange + var dbContext = _serviceProvider.GetRequiredService(); + var genreMenuComponent = new GenreMenuComponent(dbContext); + + PopulateData(dbContext); + + // Act + var result = await genreMenuComponent.InvokeAsync(); + + // Assert + Assert.NotNull(result); + var viewResult = Assert.IsType(result); + Assert.Null(viewResult.ViewName); + var genreResult = Assert.IsType>(viewResult.ViewData.Model); + Assert.Equal(9, genreResult.Count); + } + + private static void PopulateData(MusicStoreContext context) + { + var genres = Enumerable.Range(1, 10).Select(n => new Genre { GenreId = n }); + + context.AddRange(genres); + context.SaveChanges(); + } + } +} diff --git a/src/MusicStore/test/MusicStore.Test/HomeControllerTest.cs b/src/MusicStore/test/MusicStore.Test/HomeControllerTest.cs new file mode 100644 index 0000000000..3a12ab8f3a --- /dev/null +++ b/src/MusicStore/test/MusicStore.Test/HomeControllerTest.cs @@ -0,0 +1,131 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Mvc; +using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.Caching.Memory; +using Microsoft.Extensions.DependencyInjection; +using MusicStore.Models; +using MusicStore.Test; +using Xunit; + +namespace MusicStore.Controllers +{ + public class HomeControllerTest + { + private readonly IServiceProvider _serviceProvider; + + public HomeControllerTest() + { + var efServiceProvider = new ServiceCollection().AddEntityFrameworkInMemoryDatabase().BuildServiceProvider(); + + var services = new ServiceCollection(); + + services + .AddMemoryCache() + .AddLogging() + .AddDbContext(b => b.UseInMemoryDatabase("Scratch").UseInternalServiceProvider(efServiceProvider)); + + _serviceProvider = services.BuildServiceProvider(); + } + + [Fact] + public void Error_ReturnsErrorView() + { + // Arrange + var controller = new HomeController(new TestAppSettings()); + var errorView = "~/Views/Shared/Error.cshtml"; + + // Act + var result = controller.Error(); + + // Assert + var viewResult = Assert.IsType(result); + + Assert.Equal(errorView, viewResult.ViewName); + } + + [Fact] + public async Task Index_GetsSixTopAlbums() + { + // Arrange + var dbContext = _serviceProvider.GetRequiredService(); + var cache = _serviceProvider.GetRequiredService(); + var controller = new HomeController(new TestAppSettings()); + PopulateData(dbContext); + + // Action + var result = await controller.Index(dbContext, cache); + + // Assert + var viewResult = Assert.IsType(result); + Assert.Null(viewResult.ViewName); + + Assert.NotNull(viewResult.ViewData); + Assert.NotNull(viewResult.ViewData.Model); + + var albums = Assert.IsType>(viewResult.ViewData.Model); + Assert.Equal(6, albums.Count); + } + + [Fact] + public void StatusCodePage_ReturnsStatusCodePage() + { + // Arrange + var controller = new HomeController(new TestAppSettings()); + var statusCodeView = "~/Views/Shared/StatusCodePage.cshtml"; + + // Action + var result = controller.StatusCodePage(); + + // Assert + var viewResult = Assert.IsType(result); + + Assert.Equal(statusCodeView, viewResult.ViewName); + } + + private void PopulateData(DbContext context) + { + var albums = TestAlbumDataProvider.GetAlbums(); + + foreach (var album in albums) + { + context.Add(album); + } + + context.SaveChanges(); + } + + private class TestAlbumDataProvider + { + public static Album[] GetAlbums() + { + var generes = Enumerable.Range(1, 10).Select(n => + new Genre() + { + GenreId = n, + Name = "Genre Name " + n, + }).ToArray(); + + var artists = Enumerable.Range(1, 10).Select(n => + new Artist() + { + ArtistId = n + 1, + Name = "Artist Name " + n, + }).ToArray(); + + var albums = Enumerable.Range(1, 10).Select(n => + new Album() + { + Artist = artists[n - 1], + ArtistId = n, + Genre = generes[n - 1], + GenreId = n, + }).ToArray(); + + return albums; + } + } + } +} diff --git a/src/MusicStore/test/MusicStore.Test/ManageControllerTest.cs b/src/MusicStore/test/MusicStore.Test/ManageControllerTest.cs new file mode 100644 index 0000000000..459f91db33 --- /dev/null +++ b/src/MusicStore/test/MusicStore.Test/ManageControllerTest.cs @@ -0,0 +1,121 @@ +using System; +using System.Collections.Generic; +using System.Security.Claims; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Authentication; +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Identity; +using Microsoft.AspNetCore.Identity.EntityFrameworkCore; +using Microsoft.AspNetCore.Mvc; +using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; +using MusicStore.Models; +using Xunit; + +namespace MusicStore.Controllers +{ + public class ManageControllerTest + { + private readonly IServiceProvider _serviceProvider; + + public ManageControllerTest() + { + var efServiceProvider = new ServiceCollection().AddEntityFrameworkInMemoryDatabase().BuildServiceProvider(); + + var services = new ServiceCollection(); + services.AddSingleton(new ConfigurationBuilder().Build()); + services.AddOptions(); + services + .AddMemoryCache() + .AddDbContext(b => b.UseInMemoryDatabase("Scratch").UseInternalServiceProvider(efServiceProvider)); + + services.AddIdentity() + .AddEntityFrameworkStores(); + + services.AddMvc(); + services.AddSingleton(); + services.AddLogging(); + + // IHttpContextAccessor is required for SignInManager, and UserManager + var context = new DefaultHttpContext(); + services.AddSingleton( + new HttpContextAccessor() + { + HttpContext = context, + }); + + _serviceProvider = services.BuildServiceProvider(); + } + + [Fact] + public async Task Index_ReturnsViewBagMessagesExpected() + { + // Arrange + var userId = "TestUserA"; + var phone = "abcdefg"; + var claims = new List { new Claim(ClaimTypes.NameIdentifier, userId) }; + + var userManager = _serviceProvider.GetRequiredService>(); + var userManagerResult = await userManager.CreateAsync( + new ApplicationUser { Id = userId, UserName = "Test", TwoFactorEnabled = true, PhoneNumber = phone }, + "Pass@word1"); + Assert.True(userManagerResult.Succeeded); + + var signInManager = _serviceProvider.GetRequiredService>(); + + var httpContext = _serviceProvider.GetRequiredService().HttpContext; + httpContext.User = new ClaimsPrincipal(new ClaimsIdentity(claims)); + httpContext.RequestServices = _serviceProvider; + + var schemeProvider = _serviceProvider.GetRequiredService(); + + var controller = new ManageController(userManager, signInManager, schemeProvider); + controller.ControllerContext.HttpContext = httpContext; + + // Act + var result = await controller.Index(); + + // Assert + var viewResult = Assert.IsType(result); + Assert.Null(viewResult.ViewName); + + Assert.Empty(controller.ViewBag.StatusMessage); + + Assert.NotNull(viewResult.ViewData); + var model = Assert.IsType(viewResult.ViewData.Model); + Assert.True(model.TwoFactor); + Assert.Equal(phone, model.PhoneNumber); + Assert.True(model.HasPassword); + } + + public class NoOpAuth : IAuthenticationService + { + public Task AuthenticateAsync(HttpContext context, string scheme) + { + return Task.FromResult(AuthenticateResult.NoResult()); + } + + public Task ChallengeAsync(HttpContext context, string scheme, AuthenticationProperties properties) + { + return Task.FromResult(0); + } + + public Task ForbidAsync(HttpContext context, string scheme, AuthenticationProperties properties) + { + return Task.FromResult(0); + } + + public Task SignInAsync(HttpContext context, string scheme, ClaimsPrincipal principal, AuthenticationProperties properties) + { + throw new NotImplementedException(); + } + + public Task SignOutAsync(HttpContext context, string scheme, AuthenticationProperties properties) + { + throw new NotImplementedException(); + } + } + + } +} diff --git a/src/MusicStore/test/MusicStore.Test/Models/ShoppingCartTest.cs b/src/MusicStore/test/MusicStore.Test/Models/ShoppingCartTest.cs new file mode 100644 index 0000000000..58dd56c9a8 --- /dev/null +++ b/src/MusicStore/test/MusicStore.Test/Models/ShoppingCartTest.cs @@ -0,0 +1,64 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// See License.txt in the project root for license information + +using System; +using System.Threading.Tasks; +using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.DependencyInjection; +using MusicStore.Models; +using Xunit; + +namespace MusicStore.Test +{ + public class ShoppingCartTest : IClassFixture + { + private readonly ShoppingCartFixture _fixture; + + public ShoppingCartTest(ShoppingCartFixture fixture) + { + _fixture = fixture; + } + + [Fact] + public async Task ComputesTotal() + { + var cartId = Guid.NewGuid().ToString(); + using (var db = _fixture.CreateContext()) + { + var a = db.Albums.Add( + new Album + { + Price = 15.99m + }).Entity; + + db.CartItems.Add(new CartItem { Album = a, Count = 2, CartId = cartId }); + + db.SaveChanges(); + + Assert.Equal(31.98m, await ShoppingCart.GetCart(db, cartId).GetTotal()); + } + } + } + + public class ShoppingCartFixture + { + private readonly IServiceProvider _serviceProvider; + + public ShoppingCartFixture() + { + var efServiceProvider = new ServiceCollection().AddEntityFrameworkInMemoryDatabase().BuildServiceProvider(); + + var services = new ServiceCollection(); + + services + .AddMemoryCache() + .AddLogging() + .AddDbContext(b => b.UseInMemoryDatabase("Scratch").UseInternalServiceProvider(efServiceProvider)); + + _serviceProvider = services.BuildServiceProvider(); + } + + public virtual MusicStoreContext CreateContext() + => _serviceProvider.GetRequiredService(); + } +} diff --git a/src/MusicStore/test/MusicStore.Test/MusicStore.Test.csproj b/src/MusicStore/test/MusicStore.Test/MusicStore.Test.csproj new file mode 100644 index 0000000000..88a794f766 --- /dev/null +++ b/src/MusicStore/test/MusicStore.Test/MusicStore.Test.csproj @@ -0,0 +1,16 @@ + + + + netcoreapp3.0 + + + + + + + + + + + + diff --git a/src/MusicStore/test/MusicStore.Test/ShoppingCartControllerTest.cs b/src/MusicStore/test/MusicStore.Test/ShoppingCartControllerTest.cs new file mode 100644 index 0000000000..1306b48475 --- /dev/null +++ b/src/MusicStore/test/MusicStore.Test/ShoppingCartControllerTest.cs @@ -0,0 +1,242 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Antiforgery; +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Http.Features; +using Microsoft.AspNetCore.Mvc; +using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Logging; +using Microsoft.Extensions.ObjectPool; +using Microsoft.Extensions.Primitives; +using MusicStore.Models; +using MusicStore.ViewModels; +using Xunit; + +namespace MusicStore.Controllers +{ + public class ShoppingCartControllerTest + { + private readonly IServiceProvider _serviceProvider; + + public ShoppingCartControllerTest() + { + var efServiceProvider = new ServiceCollection().AddEntityFrameworkInMemoryDatabase().BuildServiceProvider(); + + var services = new ServiceCollection(); + services + .AddMemoryCache() + .AddLogging() + .AddDbContext(b => b.UseInMemoryDatabase("Scratch").UseInternalServiceProvider(efServiceProvider)); + + services.AddMvc(); + + _serviceProvider = services.BuildServiceProvider(); + } + + [Fact] + public async Task Index_ReturnsNoCartItems_WhenSessionEmpty() + { + // Arrange + var httpContext = new DefaultHttpContext(); + httpContext.Session = new TestSession(); + + var controller = new ShoppingCartController( + _serviceProvider.GetRequiredService(), + _serviceProvider.GetService>()); + controller.ControllerContext.HttpContext = httpContext; + + // Act + var result = await controller.Index(); + + // Assert + var viewResult = Assert.IsType(result); + Assert.NotNull(viewResult.ViewData); + Assert.Null(viewResult.ViewName); + + var model = Assert.IsType(viewResult.ViewData.Model); + Assert.Empty(model.CartItems); + Assert.Equal(0, model.CartTotal); + } + + [Fact] + public async Task Index_ReturnsNoCartItems_WhenNoItemsInCart() + { + // Arrange + var httpContext = new DefaultHttpContext(); + httpContext.Session = new TestSession(); + httpContext.Session.SetString("Session", "CartId_A"); + + var controller = new ShoppingCartController( + _serviceProvider.GetRequiredService(), + _serviceProvider.GetService>()); + controller.ControllerContext.HttpContext = httpContext; + + // Act + var result = await controller.Index(); + + // Assert + var viewResult = Assert.IsType(result); + Assert.NotNull(viewResult.ViewData); + Assert.Null(viewResult.ViewName); + + var model = Assert.IsType(viewResult.ViewData.Model); + Assert.Empty(model.CartItems); + Assert.Equal(0, model.CartTotal); + } + + [Fact] + public async Task Index_ReturnsCartItems_WhenItemsInCart() + { + // Arrange + var cartId = "CartId_A"; + var httpContext = new DefaultHttpContext(); + httpContext.Session = new TestSession(); + httpContext.Session.SetString("Session", cartId); + + var dbContext = _serviceProvider.GetRequiredService(); + var cartItems = CreateTestCartItems( + cartId, + itemPrice: 10, + numberOfItem: 5); + dbContext.AddRange(cartItems.Select(n => n.Album).Distinct()); + dbContext.AddRange(cartItems); + dbContext.SaveChanges(); + + var controller = new ShoppingCartController( + dbContext, + _serviceProvider.GetService>()); + controller.ControllerContext.HttpContext = httpContext; + + // Act + var result = await controller.Index(); + + // Assert + var viewResult = Assert.IsType(result); + Assert.NotNull(viewResult.ViewData); + Assert.Null(viewResult.ViewName); + + var model = Assert.IsType(viewResult.ViewData.Model); + Assert.Equal(5, model.CartItems.Count); + Assert.Equal(5 * 10, model.CartTotal); + } + + [Fact] + public async Task AddToCart_AddsItemToCart() + { + // Arrange + var albumId = 3; + var httpContext = new DefaultHttpContext(); + httpContext.Session = new TestSession(); + httpContext.Session.SetString("Session", "CartId_A"); + + // Creates the albums of AlbumId = 1 ~ 10. + var dbContext = _serviceProvider.GetRequiredService(); + var albums = CreateTestAlbums(itemPrice: 10); + dbContext.AddRange(albums); + dbContext.SaveChanges(); + + var controller = new ShoppingCartController( + dbContext, + _serviceProvider.GetService>()); + controller.ControllerContext.HttpContext = httpContext; + + // Act + var result = await controller.AddToCart(albumId, CancellationToken.None); + + // Assert + var cart = ShoppingCart.GetCart(dbContext, httpContext); + Assert.Single(await cart.GetCartItems()); + Assert.Equal(albumId, (await cart.GetCartItems()).Single().AlbumId); + + var redirectResult = Assert.IsType(result); + Assert.Null(redirectResult.ControllerName); + Assert.Equal("Index", redirectResult.ActionName); + } + + [Fact] + public async Task RemoveFromCart_RemovesItemFromCart() + { + // Arrange + var cartId = "CartId_A"; + var cartItemId = 3; + var numberOfItem = 5; + var unitPrice = 10; + var httpContext = new DefaultHttpContext(); + + // Session and cart initialization + httpContext.Session = new TestSession(); + httpContext.Session.SetString("Session", cartId); + + // DbContext initialization + var dbContext = _serviceProvider.GetRequiredService(); + var cartItems = CreateTestCartItems(cartId, unitPrice, numberOfItem); + dbContext.AddRange(cartItems.Select(n => n.Album).Distinct()); + dbContext.AddRange(cartItems); + dbContext.SaveChanges(); + + // ServiceProvder initialization + var serviceProviderFeature = new ServiceProvidersFeature(); + httpContext.Features.Set(serviceProviderFeature); + + // AntiForgery initialization + serviceProviderFeature.RequestServices = _serviceProvider; + var antiForgery = serviceProviderFeature.RequestServices.GetRequiredService(); + var tokens = antiForgery.GetTokens(httpContext); + + // Header initialization for AntiForgery + var headers = new KeyValuePair( + "RequestVerificationToken", + new string[] { tokens.CookieToken + ":" + tokens.RequestToken }); + httpContext.Request.Headers.Add(headers); + + // Cotroller initialization + var controller = new ShoppingCartController( + dbContext, + _serviceProvider.GetService>()); + controller.ControllerContext.HttpContext = httpContext; + + // Act + var result = await controller.RemoveFromCart(cartItemId, CancellationToken.None); + + // Assert + var jsonResult = Assert.IsType(result); + var viewModel = Assert.IsType(jsonResult.Value); + Assert.Equal(numberOfItem - 1, viewModel.CartCount); + Assert.Equal((numberOfItem - 1) * 10, viewModel.CartTotal); + Assert.Equal(" has been removed from your shopping cart.", viewModel.Message); + + var cart = ShoppingCart.GetCart(dbContext, httpContext); + Assert.DoesNotContain((await cart.GetCartItems()), c => c.CartItemId == cartItemId); + } + + private static CartItem[] CreateTestCartItems(string cartId, decimal itemPrice, int numberOfItem) + { + var albums = CreateTestAlbums(itemPrice); + + var cartItems = Enumerable.Range(1, numberOfItem).Select(n => + new CartItem() + { + Count = 1, + CartId = cartId, + AlbumId = n % albums.Length, + Album = albums[n % albums.Length], + }).ToArray(); + + return cartItems; + } + + private static Album[] CreateTestAlbums(decimal itemPrice) + { + return Enumerable.Range(1, 10).Select(n => + new Album() + { + AlbumId = n, + Price = itemPrice, + }).ToArray(); + } + } +} diff --git a/src/MusicStore/test/MusicStore.Test/StoreControllerTest.cs b/src/MusicStore/test/MusicStore.Test/StoreControllerTest.cs new file mode 100644 index 0000000000..e7c278bf12 --- /dev/null +++ b/src/MusicStore/test/MusicStore.Test/StoreControllerTest.cs @@ -0,0 +1,182 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Mvc; +using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.Caching.Memory; +using Microsoft.Extensions.DependencyInjection; +using MusicStore.Models; +using MusicStore.Test; +using Xunit; + +namespace MusicStore.Controllers +{ + public class StoreControllerTest + { + private readonly IServiceProvider _serviceProvider; + + public StoreControllerTest() + { + var efServiceProvider = new ServiceCollection().AddEntityFrameworkInMemoryDatabase().BuildServiceProvider(); + + var services = new ServiceCollection(); + + services + .AddMemoryCache() + .AddLogging() + .AddDbContext(b => b.UseInMemoryDatabase("Scratch").UseInternalServiceProvider(efServiceProvider)); + + _serviceProvider = services.BuildServiceProvider(); + } + + [Fact] + public async Task Index_CreatesViewWithGenres() + { + // Arrange + var dbContext = _serviceProvider.GetRequiredService(); + CreateTestGenres(numberOfGenres: 10, numberOfAlbums: 1, dbContext: dbContext); + + var controller = new StoreController(dbContext, new TestAppSettings()); + + // Act + var result = await controller.Index(); + + // Assert + var viewResult = Assert.IsType(result); + Assert.Null(viewResult.ViewName); + + Assert.NotNull(viewResult.ViewData); + var viewModel = Assert.IsType>(viewResult.ViewData.Model); + Assert.Equal(10, viewModel.Count); + } + + [Fact] + public async Task Browse_ReturnsHttpNotFoundWhenNoGenreData() + { + // Arrange + var controller = new StoreController( + _serviceProvider.GetRequiredService(), + new TestAppSettings()); + + // Act + var result = await controller.Browse(string.Empty); + + // Assert + Assert.IsType(result); + } + + [Fact] + public async Task Browse_ReturnsViewWithGenre() + { + // Arrange + var genreName = "Genre 1"; + + var dbContext = _serviceProvider.GetRequiredService(); + CreateTestGenres(numberOfGenres: 3, numberOfAlbums: 3, dbContext: dbContext); + + var controller = new StoreController(dbContext, new TestAppSettings()); + + // Act + var result = await controller.Browse(genreName); + + // Assert + var viewResult = Assert.IsType(result); + Assert.Null(viewResult.ViewName); + + Assert.NotNull(viewResult.ViewData); + var viewModel = Assert.IsType(viewResult.ViewData.Model); + Assert.Equal(genreName, viewModel.Name); + Assert.NotNull(viewModel.Albums); + Assert.Equal(3, viewModel.Albums.Count); + } + + [Fact] + public async Task Details_ReturnsHttpNotFoundWhenNoAlbumData() + { + // Arrange + var albumId = int.MinValue; + var controller = new StoreController( + _serviceProvider.GetRequiredService(), + new TestAppSettings()); + + // Act + var result = await controller.Details(_serviceProvider.GetRequiredService(), albumId); + + // Assert + Assert.IsType(result); + } + + [Fact] + public async Task Details_ReturnsAlbumDetail() + { + // Arrange + var albumId = 1; + + var dbContext = _serviceProvider.GetRequiredService(); + var genres = CreateTestGenres(numberOfGenres: 3, numberOfAlbums: 3, dbContext: dbContext); + + var cache = _serviceProvider.GetRequiredService(); + + var controller = new StoreController(dbContext, new TestAppSettings()); + + // Act + var result = await controller.Details(cache, albumId); + + // Assert + var viewResult = Assert.IsType(result); + Assert.Null(viewResult.ViewName); + + Assert.NotNull(viewResult.ViewData); + var viewModel = Assert.IsType(viewResult.ViewData.Model); + Assert.NotNull(viewModel.Genre); + var genre = genres.SingleOrDefault(g => g.GenreId == viewModel.GenreId); + Assert.NotNull(genre); + Assert.NotNull(genre.Albums.SingleOrDefault(a => a.AlbumId == albumId)); + Assert.NotNull(viewModel.Artist); + Assert.Equal(1, viewModel.ArtistId); + + var cachedAlbum = cache.Get("album_1"); + Assert.NotNull(cachedAlbum); + Assert.Equal(albumId, cachedAlbum.AlbumId); + } + + private static Genre[] CreateTestGenres(int numberOfGenres, int numberOfAlbums, DbContext dbContext) + { + var artist = new Artist(); + artist.ArtistId = 1; + artist.Name = "Artist1"; + + var albums = Enumerable.Range(1, numberOfAlbums * numberOfGenres).Select(n => + new Album() + { + AlbumId = n, + Artist = artist, + ArtistId = artist.ArtistId + }).ToList(); + + var generes = Enumerable.Range(1, numberOfGenres).Select(n => + new Genre() + { + Albums = albums.Where(i => i.AlbumId % numberOfGenres == n - 1).ToList(), + GenreId = n, + Name = "Genre " + n + }); + + var artis = Enumerable.Range(1, numberOfGenres).Select(n => + new Genre() + { + Albums = albums.Where(i => i.AlbumId % numberOfGenres == n - 1).ToList(), + GenreId = n, + Name = "Genre " + n, + }); + + dbContext.Add(artist); + dbContext.AddRange(albums); + dbContext.AddRange(generes); + dbContext.SaveChanges(); + + return generes.ToArray(); + } + } +} diff --git a/src/MusicStore/test/MusicStore.Test/TestAppSettings.cs b/src/MusicStore/test/MusicStore.Test/TestAppSettings.cs new file mode 100644 index 0000000000..8e87882462 --- /dev/null +++ b/src/MusicStore/test/MusicStore.Test/TestAppSettings.cs @@ -0,0 +1,26 @@ +using Microsoft.Extensions.Options; + +namespace MusicStore.Test +{ + public class TestAppSettings : IOptions + { + private readonly AppSettings _appSettings; + + public TestAppSettings(bool storeInCache = true) + { + _appSettings = new AppSettings() + { + SiteTitle = "ASP.NET MVC Music Store", + CacheDbResults = storeInCache + }; + } + + public AppSettings Value + { + get + { + return _appSettings; + } + } + } +} diff --git a/src/MusicStore/test/MusicStore.Test/TestSession.cs b/src/MusicStore/test/MusicStore.Test/TestSession.cs new file mode 100644 index 0000000000..9c0dfeca44 --- /dev/null +++ b/src/MusicStore/test/MusicStore.Test/TestSession.cs @@ -0,0 +1,50 @@ +using System; +using System.Collections.Generic; +using System.Threading; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Http; + +namespace MusicStore.Controllers +{ + internal class TestSession : ISession + { + private Dictionary _store + = new Dictionary(StringComparer.OrdinalIgnoreCase); + + public IEnumerable Keys { get { return _store.Keys; } } + + public string Id { get; set; } + + public bool IsAvailable { get; } = true; + + public void Clear() + { + _store.Clear(); + } + + public Task CommitAsync(CancellationToken cancellationToken = default(CancellationToken)) + { + return Task.FromResult(0); + } + + public Task LoadAsync(CancellationToken cancellationToken = default(CancellationToken)) + { + return Task.FromResult(0); + } + + public void Remove(string key) + { + _store.Remove(key); + } + + public void Set(string key, byte[] value) + { + _store[key] = value; + } + + public bool TryGetValue(string key, out byte[] value) + { + return _store.TryGetValue(key, out value); + } + } +} diff --git a/src/Servers/IIS/IIS/test/Common.FunctionalTests/PublishedApplicationPublisher.cs b/src/Servers/IIS/IIS/test/Common.FunctionalTests/PublishedApplicationPublisher.cs index a780d7ca40..3e09818933 100644 --- a/src/Servers/IIS/IIS/test/Common.FunctionalTests/PublishedApplicationPublisher.cs +++ b/src/Servers/IIS/IIS/test/Common.FunctionalTests/PublishedApplicationPublisher.cs @@ -11,16 +11,16 @@ using Microsoft.Extensions.Logging; namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests { - public class IISPublishedApplicationPublisher: PublishedApplicationPublisher + public class PublishedApplicationPublisher: ApplicationPublisher { private readonly string _applicationName; - public IISPublishedApplicationPublisher(string applicationName) : base(applicationName) + public PublishedApplicationPublisher(string applicationName) : base(applicationName) { _applicationName = applicationName; } - protected override string ResolvePublishedApplicationPath(DeploymentParameters deploymentParameters, ILogger logger) + public override Task Publish(DeploymentParameters deploymentParameters, ILogger logger) { var path = Path.Combine(AppContext.BaseDirectory, GetProfileName(deploymentParameters)); @@ -31,7 +31,13 @@ namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests path = solutionPath; } - return path; + logger.LogInformation("Using prepublished application from {PublishDir}", path); + + var target = CreateTempDirectory(); + + var source = new DirectoryInfo(path); + CachingApplicationPublisher.CopyFiles(source, target, logger); + return Task.FromResult(new PublishedApplication(target.FullName, logger)); } private string GetProjectReferencePublishLocation(DeploymentParameters deploymentParameters) diff --git a/src/Servers/IIS/IIS/test/Common.FunctionalTests/PublishedSitesFixture.cs b/src/Servers/IIS/IIS/test/Common.FunctionalTests/PublishedSitesFixture.cs index ffd2e6c806..097d7e8ccb 100644 --- a/src/Servers/IIS/IIS/test/Common.FunctionalTests/PublishedSitesFixture.cs +++ b/src/Servers/IIS/IIS/test/Common.FunctionalTests/PublishedSitesFixture.cs @@ -19,8 +19,8 @@ namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests public class PublishedSitesFixture : IDisposable { - public PublishedApplicationPublisher InProcessTestSite { get; } = new IISPublishedApplicationPublisher(Helpers.GetInProcessTestSitesName()); - public PublishedApplicationPublisher OutOfProcessTestSite { get; } = new IISPublishedApplicationPublisher(Helpers.GetOutOfProcessTestSitesName()); + public PublishedApplicationPublisher InProcessTestSite { get; } = new PublishedApplicationPublisher(Helpers.GetInProcessTestSitesName()); + public PublishedApplicationPublisher OutOfProcessTestSite { get; } = new PublishedApplicationPublisher(Helpers.GetOutOfProcessTestSitesName()); public void Dispose() { diff --git a/src/Servers/IIS/IIS/test/Common.FunctionalTests/Utilities/IISTestSiteFixture.cs b/src/Servers/IIS/IIS/test/Common.FunctionalTests/Utilities/IISTestSiteFixture.cs index d1aed8f708..ff966acc48 100644 --- a/src/Servers/IIS/IIS/test/Common.FunctionalTests/Utilities/IISTestSiteFixture.cs +++ b/src/Servers/IIS/IIS/test/Common.FunctionalTests/Utilities/IISTestSiteFixture.cs @@ -19,7 +19,7 @@ namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests private static void Configure(IISDeploymentParameters deploymentParameters) { - deploymentParameters.ApplicationPublisher = new IISPublishedApplicationPublisher(Helpers.GetOutOfProcessTestSitesName());; + deploymentParameters.ApplicationPublisher = new PublishedApplicationPublisher(Helpers.GetOutOfProcessTestSitesName());; deploymentParameters.HostingModel = HostingModel.OutOfProcess; } } @@ -32,7 +32,7 @@ namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests private static void Configure(IISDeploymentParameters deploymentParameters) { - deploymentParameters.ApplicationPublisher = new IISPublishedApplicationPublisher(Helpers.GetOutOfProcessTestSitesName());; + deploymentParameters.ApplicationPublisher = new PublishedApplicationPublisher(Helpers.GetOutOfProcessTestSitesName());; deploymentParameters.ApplicationPath = Helpers.GetOutOfProcessTestSitesName(); deploymentParameters.HostingModel = HostingModel.OutOfProcess; } @@ -115,7 +115,7 @@ namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests TargetFramework = Tfm.NetCoreApp30, HostingModel = HostingModel.InProcess, PublishApplicationBeforeDeployment = true, - ApplicationPublisher = new IISPublishedApplicationPublisher(Helpers.GetInProcessTestSitesName()), + ApplicationPublisher = new PublishedApplicationPublisher(Helpers.GetInProcessTestSitesName()), ServerType = DeployerSelector.ServerType };