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