22 changed files with 275 additions and 142 deletions
@ -1,89 +0,0 @@ |
|||||
using System; |
|
||||
using System.IO; |
|
||||
using System.Net.Http; |
|
||||
using System.Reflection; |
|
||||
using Microsoft.eShopWeb; |
|
||||
using Microsoft.AspNetCore.Hosting; |
|
||||
using Microsoft.AspNetCore.TestHost; |
|
||||
using Microsoft.Extensions.Logging; |
|
||||
using Infrastructure.Data; |
|
||||
using Infrastructure.Identity; |
|
||||
using Microsoft.AspNetCore.Identity; |
|
||||
using Microsoft.Extensions.DependencyInjection; |
|
||||
|
|
||||
namespace FunctionalTests.Web.Controllers |
|
||||
{ |
|
||||
public abstract class BaseWebTest |
|
||||
{ |
|
||||
protected readonly HttpClient _client; |
|
||||
protected string _contentRoot; |
|
||||
|
|
||||
public BaseWebTest() |
|
||||
{ |
|
||||
_client = GetClient(); |
|
||||
} |
|
||||
|
|
||||
protected HttpClient GetClient() |
|
||||
{ |
|
||||
var startupAssembly = typeof(Startup).GetTypeInfo().Assembly; |
|
||||
_contentRoot = GetProjectPath("src", startupAssembly); |
|
||||
var builder = new WebHostBuilder() |
|
||||
.UseContentRoot(_contentRoot) |
|
||||
.UseEnvironment("Testing") |
|
||||
.UseStartup<Startup>(); |
|
||||
|
|
||||
var server = new TestServer(builder); |
|
||||
|
|
||||
// seed data
|
|
||||
using (var scope = server.Host.Services.CreateScope()) |
|
||||
{ |
|
||||
var services = scope.ServiceProvider; |
|
||||
var loggerFactory = services.GetRequiredService<ILoggerFactory>(); |
|
||||
var catalogContext = services.GetRequiredService<CatalogContext>(); |
|
||||
CatalogContextSeed.SeedAsync(catalogContext, loggerFactory) |
|
||||
.Wait(); |
|
||||
|
|
||||
var userManager = services.GetRequiredService<UserManager<ApplicationUser>>(); |
|
||||
AppIdentityDbContextSeed.SeedAsync(userManager).Wait(); |
|
||||
} |
|
||||
|
|
||||
return server.CreateClient(); |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Gets the full path to the target project path that we wish to test
|
|
||||
/// </summary>
|
|
||||
/// <param name="solutionRelativePath">
|
|
||||
/// The parent directory of the target project.
|
|
||||
/// e.g. src, samples, test, or test/Websites
|
|
||||
/// </param>
|
|
||||
/// <param name="startupAssembly">The target project's assembly.</param>
|
|
||||
/// <returns>The full path to the target project.</returns>
|
|
||||
protected static string GetProjectPath(string solutionRelativePath, Assembly startupAssembly) |
|
||||
{ |
|
||||
// Get name of the target project which we want to test
|
|
||||
var projectName = startupAssembly.GetName().Name; |
|
||||
|
|
||||
// Get currently executing test project path
|
|
||||
var applicationBasePath = AppContext.BaseDirectory; |
|
||||
|
|
||||
// Find the folder which contains the solution file. We then use this information to find the target
|
|
||||
// project which we want to test.
|
|
||||
var directoryInfo = new DirectoryInfo(applicationBasePath); |
|
||||
do |
|
||||
{ |
|
||||
var solutionFileInfo = new FileInfo(Path.Combine(directoryInfo.FullName, "eShopOnWeb.sln")); |
|
||||
if (solutionFileInfo.Exists) |
|
||||
{ |
|
||||
return Path.GetFullPath(Path.Combine(directoryInfo.FullName, solutionRelativePath, projectName)); |
|
||||
} |
|
||||
|
|
||||
directoryInfo = directoryInfo.Parent; |
|
||||
} |
|
||||
while (directoryInfo.Parent != null); |
|
||||
|
|
||||
throw new Exception($"Solution root could not be located using application root {applicationBasePath}."); |
|
||||
} |
|
||||
|
|
||||
} |
|
||||
} |
|
||||
@ -0,0 +1,32 @@ |
|||||
|
using Microsoft.AspNetCore.Mvc.Testing; |
||||
|
using Microsoft.eShopWeb; |
||||
|
using System.Net; |
||||
|
using System.Net.Http; |
||||
|
using System.Threading.Tasks; |
||||
|
using Xunit; |
||||
|
|
||||
|
namespace FunctionalTests.Web.Controllers |
||||
|
{ |
||||
|
public class OrderIndexOnGet : IClassFixture<CustomWebApplicationFactory<Startup>> |
||||
|
{ |
||||
|
public OrderIndexOnGet(CustomWebApplicationFactory<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/Signin", redirectLocation); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,70 @@ |
|||||
|
using Infrastructure.Data; |
||||
|
using Microsoft.AspNetCore.Hosting; |
||||
|
using Microsoft.AspNetCore.Mvc.Testing; |
||||
|
using Microsoft.eShopWeb; |
||||
|
using Microsoft.Extensions.DependencyInjection; |
||||
|
using Microsoft.Extensions.Logging; |
||||
|
using System; |
||||
|
using Microsoft.EntityFrameworkCore; |
||||
|
using Infrastructure.Identity; |
||||
|
|
||||
|
namespace 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}"); |
||||
|
} |
||||
|
} |
||||
|
}); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,29 @@ |
|||||
|
using Microsoft.eShopWeb.RazorPages; |
||||
|
using System.Net.Http; |
||||
|
using System.Threading.Tasks; |
||||
|
using Xunit; |
||||
|
|
||||
|
namespace FunctionalTests.WebRazorPages |
||||
|
{ |
||||
|
public class HomePageOnGet : IClassFixture<CustomWebRazorPagesApplicationFactory<Startup>> |
||||
|
{ |
||||
|
public HomePageOnGet(CustomWebRazorPagesApplicationFactory<Startup> factory) |
||||
|
{ |
||||
|
Client = factory.CreateClient(); |
||||
|
} |
||||
|
|
||||
|
public HttpClient Client { get; } |
||||
|
|
||||
|
[Fact] |
||||
|
public async Task ReturnsHomePageWithProductListing() |
||||
|
{ |
||||
|
// Arrange & Act
|
||||
|
var response = await Client.GetAsync("/"); |
||||
|
response.EnsureSuccessStatusCode(); |
||||
|
var stringResponse = await response.Content.ReadAsStringAsync(); |
||||
|
|
||||
|
// Assert
|
||||
|
Assert.Contains(".NET Bot Black Sweatshirt", stringResponse); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,32 @@ |
|||||
|
using Microsoft.AspNetCore.Mvc.Testing; |
||||
|
using Microsoft.eShopWeb; |
||||
|
using System.Net; |
||||
|
using System.Net.Http; |
||||
|
using System.Threading.Tasks; |
||||
|
using Xunit; |
||||
|
|
||||
|
namespace 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/Signin", redirectLocation); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,41 @@ |
|||||
|
using ApplicationCore.Entities.OrderAggregate; |
||||
|
using System.Collections.Generic; |
||||
|
using UnitTests.Builders; |
||||
|
using Xunit; |
||||
|
|
||||
|
namespace UnitTests.ApplicationCore.Entities.OrderTests |
||||
|
{ |
||||
|
public class Total |
||||
|
{ |
||||
|
private decimal _testUnitPrice = 42m; |
||||
|
|
||||
|
[Fact] |
||||
|
public void IsZeroForNewOrder() |
||||
|
{ |
||||
|
var order = new OrderBuilder().WithNoItems(); |
||||
|
|
||||
|
Assert.Equal(0, order.Total()); |
||||
|
} |
||||
|
|
||||
|
[Fact] |
||||
|
public void IsCorrectGiven1Item() |
||||
|
{ |
||||
|
var builder = new OrderBuilder(); |
||||
|
var items = new List<OrderItem> |
||||
|
{ |
||||
|
new OrderItem(builder.TestCatalogItemOrdered, _testUnitPrice, 1) |
||||
|
}; |
||||
|
var order = new OrderBuilder().WithItems(items); |
||||
|
Assert.Equal(_testUnitPrice, order.Total()); |
||||
|
} |
||||
|
|
||||
|
[Fact] |
||||
|
public void IsCorrectGiven3Items() |
||||
|
{ |
||||
|
var builder = new OrderBuilder(); |
||||
|
var order = builder.WithDefaultValues(); |
||||
|
|
||||
|
Assert.Equal(builder.TestUnitPrice * builder.TestUnits, order.Total()); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
Loading…
Reference in new issue