Shady nagy/net6 (#614)

* udated to .net6

* used the .net6 version RC2

* added editconfig.

* App core new Scoped Namespaces style.

* BlazorAdmin new Scoped Namespaces style.

* Blazor Shared new Scoped Namespaces style.

* Infra new Scoped Namespaces style.

* public api new Scoped Namespaces style.

* web new Scoped Namespaces style.

* FunctionalTests new Scoped Namespaces style.

* Integrational tests new Scoped Namespaces style.

* unit tests new Scoped Namespaces style.

* update github action.

* update github action.

* change the global.
This commit is contained in:
Shady Nagy
2021-11-06 01:55:48 +02:00
committed by GitHub
parent 64f150dc07
commit 9db2feb930
252 changed files with 6307 additions and 6413 deletions

View File

@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net5.0</TargetFramework>
<TargetFramework>net6.0</TargetFramework>
<RootNamespace>Microsoft.eShopWeb.FunctionalTests</RootNamespace>
<IsPackable>false</IsPackable>
</PropertyGroup>

View File

@@ -1,4 +1,5 @@
using Microsoft.AspNetCore.Hosting;
using System;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc.Testing;
using Microsoft.EntityFrameworkCore;
@@ -7,38 +8,37 @@ using Microsoft.eShopWeb.Infrastructure.Identity;
using Microsoft.eShopWeb.PublicApi;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using System;
namespace Microsoft.eShopWeb.FunctionalTests.PublicApi
namespace Microsoft.eShopWeb.FunctionalTests.PublicApi;
public class ApiTestFixture : WebApplicationFactory<Startup>
{
public class ApiTestFixture : WebApplicationFactory<Startup>
protected override void ConfigureWebHost(IWebHostBuilder builder)
{
protected override void ConfigureWebHost(IWebHostBuilder builder)
{
builder.UseEnvironment("Testing");
builder.UseEnvironment("Testing");
builder.ConfigureServices(services =>
{
services.AddEntityFrameworkInMemoryDatabase();
builder.ConfigureServices(services =>
{
services.AddEntityFrameworkInMemoryDatabase();
// Create a new service provider.
var provider = services
.AddEntityFrameworkInMemoryDatabase()
.BuildServiceProvider();
.AddEntityFrameworkInMemoryDatabase()
.BuildServiceProvider();
// Add a database context (ApplicationDbContext) using an in-memory
// database for testing.
services.AddDbContext<CatalogContext>(options =>
{
options.UseInMemoryDatabase("InMemoryDbForTesting");
options.UseInternalServiceProvider(provider);
});
{
options.UseInMemoryDatabase("InMemoryDbForTesting");
options.UseInternalServiceProvider(provider);
});
services.AddDbContext<AppIdentityDbContext>(options =>
{
options.UseInMemoryDatabase("Identity");
options.UseInternalServiceProvider(provider);
});
services.AddDbContext<AppIdentityDbContext>(options =>
{
options.UseInMemoryDatabase("Identity");
options.UseInternalServiceProvider(provider);
});
// Build the service provider.
var sp = services.BuildServiceProvider();
@@ -46,34 +46,33 @@ namespace Microsoft.eShopWeb.FunctionalTests.PublicApi
// 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 scopedServices = scope.ServiceProvider;
var db = scopedServices.GetRequiredService<CatalogContext>();
var loggerFactory = scopedServices.GetRequiredService<ILoggerFactory>();
var logger = scopedServices
.GetRequiredService<ILogger<ApiTestFixture>>();
var logger = scopedServices
.GetRequiredService<ILogger<ApiTestFixture>>();
// Ensure the database is created.
db.Database.EnsureCreated();
try
{
try
{
// Seed the database with test data.
CatalogContextSeed.SeedAsync(db, loggerFactory).Wait();
// seed sample user data
var userManager = scopedServices.GetRequiredService<UserManager<ApplicationUser>>();
var roleManager = scopedServices.GetRequiredService<RoleManager<IdentityRole>>();
AppIdentityDbContextSeed.SeedAsync(userManager, roleManager).Wait();
}
catch (Exception ex)
{
logger.LogError(ex, $"An error occurred seeding the " +
"database with test messages. Error: {ex.Message}");
}
var roleManager = scopedServices.GetRequiredService<RoleManager<IdentityRole>>();
AppIdentityDbContextSeed.SeedAsync(userManager, roleManager).Wait();
}
});
}
catch (Exception ex)
{
logger.LogError(ex, $"An error occurred seeding the " +
"database with test messages. Error: {ex.Message}");
}
}
});
}
}

View File

@@ -1,50 +1,49 @@
using Microsoft.eShopWeb.ApplicationCore.Constants;
using Microsoft.IdentityModel.Tokens;
using System;
using System;
using System.Collections.Generic;
using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims;
using System.Text;
using Microsoft.eShopWeb.ApplicationCore.Constants;
using Microsoft.IdentityModel.Tokens;
namespace Microsoft.eShopWeb.FunctionalTests.Web.Api
namespace Microsoft.eShopWeb.FunctionalTests.Web.Api;
public class ApiTokenHelper
{
public class ApiTokenHelper
public static string GetAdminUserToken()
{
public static string GetAdminUserToken()
{
string userName = "admin@microsoft.com";
string[] roles = { "Administrators" };
string userName = "admin@microsoft.com";
string[] roles = { "Administrators" };
return CreateToken(userName, roles);
return CreateToken(userName, roles);
}
public static string GetNormalUserToken()
{
string userName = "demouser@microsoft.com";
string[] roles = { };
return CreateToken(userName, roles);
}
private static string CreateToken(string userName, string[] roles)
{
var claims = new List<Claim> { new Claim(ClaimTypes.Name, userName) };
foreach (var role in roles)
{
claims.Add(new Claim(ClaimTypes.Role, role));
}
public static string GetNormalUserToken()
var key = Encoding.ASCII.GetBytes(AuthorizationConstants.JWT_SECRET_KEY);
var tokenDescriptor = new SecurityTokenDescriptor
{
string userName = "demouser@microsoft.com";
string[] roles = { };
return CreateToken(userName, roles);
}
private static string CreateToken(string userName, string[] roles)
{
var claims = new List<Claim> { new Claim(ClaimTypes.Name, userName) };
foreach (var role in roles)
{
claims.Add(new Claim(ClaimTypes.Role, role));
}
var key = Encoding.ASCII.GetBytes(AuthorizationConstants.JWT_SECRET_KEY);
var tokenDescriptor = new SecurityTokenDescriptor
{
Subject = new ClaimsIdentity(claims.ToArray()),
Expires = DateTime.UtcNow.AddHours(1),
SigningCredentials = new SigningCredentials(new SymmetricSecurityKey(key), SecurityAlgorithms.HmacSha256Signature)
};
var tokenHandler = new JwtSecurityTokenHandler();
var token = tokenHandler.CreateToken(tokenDescriptor);
return tokenHandler.WriteToken(token);
}
Subject = new ClaimsIdentity(claims.ToArray()),
Expires = DateTime.UtcNow.AddHours(1),
SigningCredentials = new SigningCredentials(new SymmetricSecurityKey(key), SecurityAlgorithms.HmacSha256Signature)
};
var tokenHandler = new JwtSecurityTokenHandler();
var token = tokenHandler.CreateToken(tokenDescriptor);
return tokenHandler.WriteToken(token);
}
}

View File

@@ -1,44 +1,43 @@
using Microsoft.eShopWeb.ApplicationCore.Constants;
using Microsoft.eShopWeb.FunctionalTests.PublicApi;
using Microsoft.eShopWeb.PublicApi.AuthEndpoints;
using System.Net.Http;
using System.Net.Http;
using System.Text;
using System.Text.Json;
using System.Threading.Tasks;
using Microsoft.eShopWeb.ApplicationCore.Constants;
using Microsoft.eShopWeb.FunctionalTests.PublicApi;
using Microsoft.eShopWeb.PublicApi.AuthEndpoints;
using Xunit;
namespace Microsoft.eShopWeb.FunctionalTests.Web.Controllers
namespace Microsoft.eShopWeb.FunctionalTests.Web.Controllers;
[Collection("Sequential")]
public class AuthenticateEndpoint : IClassFixture<ApiTestFixture>
{
[Collection("Sequential")]
public class AuthenticateEndpoint : IClassFixture<ApiTestFixture>
JsonSerializerOptions _jsonOptions = new JsonSerializerOptions { PropertyNameCaseInsensitive = true };
public AuthenticateEndpoint(ApiTestFixture factory)
{
JsonSerializerOptions _jsonOptions = new JsonSerializerOptions { PropertyNameCaseInsensitive = true };
Client = factory.CreateClient();
}
public AuthenticateEndpoint(ApiTestFixture factory)
public HttpClient Client { get; }
[Theory]
[InlineData("demouser@microsoft.com", AuthorizationConstants.DEFAULT_PASSWORD, true)]
[InlineData("demouser@microsoft.com", "badpassword", false)]
[InlineData("baduser@microsoft.com", "badpassword", false)]
public async Task ReturnsExpectedResultGivenCredentials(string testUsername, string testPassword, bool expectedResult)
{
var request = new AuthenticateRequest()
{
Client = factory.CreateClient();
}
Username = testUsername,
Password = testPassword
};
var jsonContent = new StringContent(JsonSerializer.Serialize(request), Encoding.UTF8, "application/json");
var response = await Client.PostAsync("api/authenticate", jsonContent);
response.EnsureSuccessStatusCode();
var stringResponse = await response.Content.ReadAsStringAsync();
var model = stringResponse.FromJson<AuthenticateResponse>();
public HttpClient Client { get; }
[Theory]
[InlineData("demouser@microsoft.com", AuthorizationConstants.DEFAULT_PASSWORD, true)]
[InlineData("demouser@microsoft.com", "badpassword", false)]
[InlineData("baduser@microsoft.com", "badpassword", false)]
public async Task ReturnsExpectedResultGivenCredentials(string testUsername, string testPassword, bool expectedResult)
{
var request = new AuthenticateRequest()
{
Username = testUsername,
Password = testPassword
};
var jsonContent = new StringContent(JsonSerializer.Serialize(request), Encoding.UTF8, "application/json");
var response = await Client.PostAsync("api/authenticate", jsonContent);
response.EnsureSuccessStatusCode();
var stringResponse = await response.Content.ReadAsStringAsync();
var model = stringResponse.FromJson<AuthenticateResponse>();
Assert.Equal(expectedResult, model.Result);
}
Assert.Equal(expectedResult, model.Result);
}
}

View File

@@ -1,42 +1,41 @@
using Microsoft.eShopWeb.FunctionalTests.PublicApi;
using Microsoft.eShopWeb.Web.ViewModels;
using System.Linq;
using System.Linq;
using System.Net.Http;
using System.Threading.Tasks;
using Microsoft.eShopWeb.FunctionalTests.PublicApi;
using Microsoft.eShopWeb.Web.ViewModels;
using Xunit;
namespace Microsoft.eShopWeb.FunctionalTests.Web.Controllers
namespace Microsoft.eShopWeb.FunctionalTests.Web.Controllers;
[Collection("Sequential")]
public class ApiCatalogControllerList : IClassFixture<ApiTestFixture>
{
[Collection("Sequential")]
public class ApiCatalogControllerList : IClassFixture<ApiTestFixture>
public ApiCatalogControllerList(ApiTestFixture factory)
{
public ApiCatalogControllerList(ApiTestFixture factory)
{
Client = factory.CreateClient();
}
Client = factory.CreateClient();
}
public HttpClient Client { get; }
public HttpClient Client { get; }
[Fact]
public async Task ReturnsFirst10CatalogItems()
{
var response = await Client.GetAsync("/api/catalog-items?pageSize=10");
response.EnsureSuccessStatusCode();
var stringResponse = await response.Content.ReadAsStringAsync();
var model = stringResponse.FromJson<CatalogIndexViewModel>();
[Fact]
public async Task ReturnsFirst10CatalogItems()
{
var response = await Client.GetAsync("/api/catalog-items?pageSize=10");
response.EnsureSuccessStatusCode();
var stringResponse = await response.Content.ReadAsStringAsync();
var model = stringResponse.FromJson<CatalogIndexViewModel>();
Assert.Equal(10, model.CatalogItems.Count());
}
Assert.Equal(10, model.CatalogItems.Count());
}
[Fact]
public async Task ReturnsLast2CatalogItemsGivenPageIndex1()
{
var response = await Client.GetAsync("/api/catalog-items?pageSize=10&pageIndex=1");
response.EnsureSuccessStatusCode();
var stringResponse = await response.Content.ReadAsStringAsync();
var model = stringResponse.FromJson<CatalogIndexViewModel>();
[Fact]
public async Task ReturnsLast2CatalogItemsGivenPageIndex1()
{
var response = await Client.GetAsync("/api/catalog-items?pageSize=10&pageIndex=1");
response.EnsureSuccessStatusCode();
var stringResponse = await response.Content.ReadAsStringAsync();
var model = stringResponse.FromJson<CatalogIndexViewModel>();
Assert.Equal(2, model.CatalogItems.Count());
}
Assert.Equal(2, model.CatalogItems.Count());
}
}

View File

@@ -1,75 +1,74 @@
using Microsoft.eShopWeb.FunctionalTests.PublicApi;
using Microsoft.eShopWeb.FunctionalTests.Web.Api;
using Microsoft.eShopWeb.PublicApi.CatalogItemEndpoints;
using System.Net;
using System.Net;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;
using System.Text.Json;
using System.Threading.Tasks;
using Microsoft.eShopWeb.FunctionalTests.PublicApi;
using Microsoft.eShopWeb.FunctionalTests.Web.Api;
using Microsoft.eShopWeb.PublicApi.CatalogItemEndpoints;
using Xunit;
namespace Microsoft.eShopWeb.FunctionalTests.Web.Controllers
namespace Microsoft.eShopWeb.FunctionalTests.Web.Controllers;
[Collection("Sequential")]
public class CreateEndpoint : IClassFixture<ApiTestFixture>
{
[Collection("Sequential")]
public class CreateEndpoint : IClassFixture<ApiTestFixture>
JsonSerializerOptions _jsonOptions = new JsonSerializerOptions { PropertyNameCaseInsensitive = true };
private int _testBrandId = 1;
private int _testTypeId = 2;
private string _testDescription = "test description";
private string _testName = "test name";
private decimal _testPrice = 1.23m;
public CreateEndpoint(ApiTestFixture factory)
{
JsonSerializerOptions _jsonOptions = new JsonSerializerOptions { PropertyNameCaseInsensitive = true };
private int _testBrandId = 1;
private int _testTypeId = 2;
private string _testDescription = "test description";
private string _testName = "test name";
private decimal _testPrice = 1.23m;
Client = factory.CreateClient();
}
public CreateEndpoint(ApiTestFixture factory)
public HttpClient Client { get; }
[Fact]
public async Task ReturnsNotAuthorizedGivenNormalUserToken()
{
var jsonContent = GetValidNewItemJson();
var token = ApiTokenHelper.GetNormalUserToken();
Client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);
var response = await Client.PostAsync("api/catalog-items", jsonContent);
Assert.Equal(HttpStatusCode.Forbidden, response.StatusCode);
}
[Fact]
public async Task ReturnsSuccessGivenValidNewItemAndAdminUserToken()
{
var jsonContent = GetValidNewItemJson();
var adminToken = ApiTokenHelper.GetAdminUserToken();
Client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", adminToken);
var response = await Client.PostAsync("api/catalog-items", jsonContent);
response.EnsureSuccessStatusCode();
var stringResponse = await response.Content.ReadAsStringAsync();
var model = stringResponse.FromJson<CreateCatalogItemResponse>();
Assert.Equal(_testBrandId, model.CatalogItem.CatalogBrandId);
Assert.Equal(_testTypeId, model.CatalogItem.CatalogTypeId);
Assert.Equal(_testDescription, model.CatalogItem.Description);
Assert.Equal(_testName, model.CatalogItem.Name);
Assert.Equal(_testPrice, model.CatalogItem.Price);
}
private StringContent GetValidNewItemJson()
{
var request = new CreateCatalogItemRequest()
{
Client = factory.CreateClient();
}
CatalogBrandId = _testBrandId,
CatalogTypeId = _testTypeId,
Description = _testDescription,
Name = _testName,
Price = _testPrice
};
var jsonContent = new StringContent(JsonSerializer.Serialize(request), Encoding.UTF8, "application/json");
public HttpClient Client { get; }
[Fact]
public async Task ReturnsNotAuthorizedGivenNormalUserToken()
{
var jsonContent = GetValidNewItemJson();
var token = ApiTokenHelper.GetNormalUserToken();
Client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);
var response = await Client.PostAsync("api/catalog-items", jsonContent);
Assert.Equal(HttpStatusCode.Forbidden, response.StatusCode);
}
[Fact]
public async Task ReturnsSuccessGivenValidNewItemAndAdminUserToken()
{
var jsonContent = GetValidNewItemJson();
var adminToken = ApiTokenHelper.GetAdminUserToken();
Client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", adminToken);
var response = await Client.PostAsync("api/catalog-items", jsonContent);
response.EnsureSuccessStatusCode();
var stringResponse = await response.Content.ReadAsStringAsync();
var model = stringResponse.FromJson<CreateCatalogItemResponse>();
Assert.Equal(_testBrandId, model.CatalogItem.CatalogBrandId);
Assert.Equal(_testTypeId, model.CatalogItem.CatalogTypeId);
Assert.Equal(_testDescription, model.CatalogItem.Description);
Assert.Equal(_testName, model.CatalogItem.Name);
Assert.Equal(_testPrice, model.CatalogItem.Price);
}
private StringContent GetValidNewItemJson()
{
var request = new CreateCatalogItemRequest()
{
CatalogBrandId = _testBrandId,
CatalogTypeId = _testTypeId,
Description = _testDescription,
Name = _testName,
Price = _testPrice
};
var jsonContent = new StringContent(JsonSerializer.Serialize(request), Encoding.UTF8, "application/json");
return jsonContent;
}
return jsonContent;
}
}

View File

@@ -1,48 +1,47 @@
using Microsoft.eShopWeb.FunctionalTests.PublicApi;
using Microsoft.eShopWeb.FunctionalTests.Web.Api;
using Microsoft.eShopWeb.PublicApi.CatalogItemEndpoints;
using System.Net;
using System.Net;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text.Json;
using System.Threading.Tasks;
using Microsoft.eShopWeb.FunctionalTests.PublicApi;
using Microsoft.eShopWeb.FunctionalTests.Web.Api;
using Microsoft.eShopWeb.PublicApi.CatalogItemEndpoints;
using Xunit;
namespace Microsoft.eShopWeb.FunctionalTests.Web.Controllers
namespace Microsoft.eShopWeb.FunctionalTests.Web.Controllers;
[Collection("Sequential")]
public class DeleteEndpoint : IClassFixture<ApiTestFixture>
{
[Collection("Sequential")]
public class DeleteEndpoint : IClassFixture<ApiTestFixture>
JsonSerializerOptions _jsonOptions = new JsonSerializerOptions { PropertyNameCaseInsensitive = true };
public DeleteEndpoint(ApiTestFixture factory)
{
JsonSerializerOptions _jsonOptions = new JsonSerializerOptions { PropertyNameCaseInsensitive = true };
Client = factory.CreateClient();
}
public DeleteEndpoint(ApiTestFixture factory)
{
Client = factory.CreateClient();
}
public HttpClient Client { get; }
public HttpClient Client { get; }
[Fact]
public async Task ReturnsSuccessGivenValidIdAndAdminUserToken()
{
var adminToken = ApiTokenHelper.GetAdminUserToken();
Client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", adminToken);
var response = await Client.DeleteAsync("api/catalog-items/12");
response.EnsureSuccessStatusCode();
var stringResponse = await response.Content.ReadAsStringAsync();
var model = stringResponse.FromJson<DeleteCatalogItemResponse>();
[Fact]
public async Task ReturnsSuccessGivenValidIdAndAdminUserToken()
{
var adminToken = ApiTokenHelper.GetAdminUserToken();
Client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", adminToken);
var response = await Client.DeleteAsync("api/catalog-items/12");
response.EnsureSuccessStatusCode();
var stringResponse = await response.Content.ReadAsStringAsync();
var model = stringResponse.FromJson<DeleteCatalogItemResponse>();
Assert.Equal("Deleted", model.Status);
}
Assert.Equal("Deleted", model.Status);
}
[Fact]
public async Task ReturnsNotFoundGivenInvalidIdAndAdminUserToken()
{
var adminToken = ApiTokenHelper.GetAdminUserToken();
Client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", adminToken);
var response = await Client.DeleteAsync("api/catalog-items/0");
[Fact]
public async Task ReturnsNotFoundGivenInvalidIdAndAdminUserToken()
{
var adminToken = ApiTokenHelper.GetAdminUserToken();
Client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", adminToken);
var response = await Client.DeleteAsync("api/catalog-items/0");
Assert.Equal(HttpStatusCode.NotFound, response.StatusCode);
}
Assert.Equal(HttpStatusCode.NotFound, response.StatusCode);
}
}

View File

@@ -1,43 +1,42 @@
using Microsoft.eShopWeb.FunctionalTests.PublicApi;
using Microsoft.eShopWeb.PublicApi.CatalogItemEndpoints;
using System.Net;
using System.Net;
using System.Net.Http;
using System.Text.Json;
using System.Threading.Tasks;
using Microsoft.eShopWeb.FunctionalTests.PublicApi;
using Microsoft.eShopWeb.PublicApi.CatalogItemEndpoints;
using Xunit;
namespace Microsoft.eShopWeb.FunctionalTests.Web.Controllers
namespace Microsoft.eShopWeb.FunctionalTests.Web.Controllers;
[Collection("Sequential")]
public class GetByIdEndpoint : IClassFixture<ApiTestFixture>
{
[Collection("Sequential")]
public class GetByIdEndpoint : IClassFixture<ApiTestFixture>
JsonSerializerOptions _jsonOptions = new JsonSerializerOptions { PropertyNameCaseInsensitive = true };
public GetByIdEndpoint(ApiTestFixture factory)
{
JsonSerializerOptions _jsonOptions = new JsonSerializerOptions { PropertyNameCaseInsensitive = true };
Client = factory.CreateClient();
}
public GetByIdEndpoint(ApiTestFixture factory)
{
Client = factory.CreateClient();
}
public HttpClient Client { get; }
public HttpClient Client { get; }
[Fact]
public async Task ReturnsItemGivenValidId()
{
var response = await Client.GetAsync("api/catalog-items/5");
response.EnsureSuccessStatusCode();
var stringResponse = await response.Content.ReadAsStringAsync();
var model = stringResponse.FromJson<GetByIdCatalogItemResponse>();
[Fact]
public async Task ReturnsItemGivenValidId()
{
var response = await Client.GetAsync("api/catalog-items/5");
response.EnsureSuccessStatusCode();
var stringResponse = await response.Content.ReadAsStringAsync();
var model = stringResponse.FromJson<GetByIdCatalogItemResponse>();
Assert.Equal(5, model.CatalogItem.Id);
Assert.Equal("Roslyn Red Sheet", model.CatalogItem.Name);
}
Assert.Equal(5, model.CatalogItem.Id);
Assert.Equal("Roslyn Red Sheet", model.CatalogItem.Name);
}
[Fact]
public async Task ReturnsNotFoundGivenInvalidId()
{
var response = await Client.GetAsync("api/catalog-items/0");
[Fact]
public async Task ReturnsNotFoundGivenInvalidId()
{
var response = await Client.GetAsync("api/catalog-items/0");
Assert.Equal(HttpStatusCode.NotFound, response.StatusCode);
}
Assert.Equal(HttpStatusCode.NotFound, response.StatusCode);
}
}

View File

@@ -1,89 +1,88 @@
using Microsoft.AspNetCore.Mvc.Testing;
using System;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc.Testing;
using Xunit;
namespace Microsoft.eShopWeb.FunctionalTests.Web.Controllers
namespace Microsoft.eShopWeb.FunctionalTests.Web.Controllers;
[Collection("Sequential")]
public class AccountControllerSignIn : IClassFixture<WebTestFixture>
{
[Collection("Sequential")]
public class AccountControllerSignIn : IClassFixture<WebTestFixture>
public AccountControllerSignIn(WebTestFixture factory)
{
public AccountControllerSignIn(WebTestFixture factory)
Client = factory.CreateClient(new WebApplicationFactoryClientOptions
{
Client = factory.CreateClient(new WebApplicationFactoryClientOptions
{
AllowAutoRedirect = false
});
}
AllowAutoRedirect = false
});
}
public HttpClient Client { get; }
public HttpClient Client { get; }
[Fact]
public async Task ReturnsSignInScreenOnGet()
{
var response = await Client.GetAsync("/identity/account/login");
response.EnsureSuccessStatusCode();
var stringResponse = await response.Content.ReadAsStringAsync();
[Fact]
public async Task ReturnsSignInScreenOnGet()
{
var response = await Client.GetAsync("/identity/account/login");
response.EnsureSuccessStatusCode();
var stringResponse = await response.Content.ReadAsStringAsync();
Assert.Contains("demouser@microsoft.com", stringResponse);
}
Assert.Contains("demouser@microsoft.com", stringResponse);
}
[Fact]
public void RegexMatchesValidRequestVerificationToken()
{
// TODO: Move to a unit test
// TODO: Move regex to a constant in test project
var input = @"<input name=""__RequestVerificationToken"" type=""hidden"" value=""CfDJ8Obhlq65OzlDkoBvsSX0tgxFUkIZ_qDDSt49D_StnYwphIyXO4zxfjopCWsygfOkngsL6P0tPmS2HTB1oYW-p_JzE0_MCFb7tF9Ol_qoOg_IC_yTjBNChF0qRgoZPmKYOIJigg7e2rsBsmMZDTdbnGo"" /><input name=""RememberMe"" type=""hidden"" value=""false"" /></form>";
string regexpression = @"name=""__RequestVerificationToken"" type=""hidden"" value=""([-A-Za-z0-9+=/\\_]+?)""";
var regex = new Regex(regexpression);
var match = regex.Match(input);
var group = match.Groups.Values.LastOrDefault();
Assert.NotNull(group);
Assert.True(group.Value.Length > 50);
}
[Fact]
public void RegexMatchesValidRequestVerificationToken()
{
// TODO: Move to a unit test
// TODO: Move regex to a constant in test project
var input = @"<input name=""__RequestVerificationToken"" type=""hidden"" value=""CfDJ8Obhlq65OzlDkoBvsSX0tgxFUkIZ_qDDSt49D_StnYwphIyXO4zxfjopCWsygfOkngsL6P0tPmS2HTB1oYW-p_JzE0_MCFb7tF9Ol_qoOg_IC_yTjBNChF0qRgoZPmKYOIJigg7e2rsBsmMZDTdbnGo"" /><input name=""RememberMe"" type=""hidden"" value=""false"" /></form>";
string regexpression = @"name=""__RequestVerificationToken"" type=""hidden"" value=""([-A-Za-z0-9+=/\\_]+?)""";
var regex = new Regex(regexpression);
var match = regex.Match(input);
var group = match.Groups.Values.LastOrDefault();
Assert.NotNull(group);
Assert.True(group.Value.Length > 50);
}
[Fact]
public async Task ReturnsFormWithRequestVerificationToken()
{
var response = await Client.GetAsync("/identity/account/login");
response.EnsureSuccessStatusCode();
var stringResponse = await response.Content.ReadAsStringAsync();
[Fact]
public async Task ReturnsFormWithRequestVerificationToken()
{
var response = await Client.GetAsync("/identity/account/login");
response.EnsureSuccessStatusCode();
var stringResponse = await response.Content.ReadAsStringAsync();
string token = GetRequestVerificationToken(stringResponse);
Assert.True(token.Length > 50);
}
string token = GetRequestVerificationToken(stringResponse);
Assert.True(token.Length > 50);
}
private string GetRequestVerificationToken(string input)
{
string regexpression = @"name=""__RequestVerificationToken"" type=""hidden"" value=""([-A-Za-z0-9+=/\\_]+?)""";
var regex = new Regex(regexpression);
var match = regex.Match(input);
return match.Groups.Values.LastOrDefault().Value;
}
private string GetRequestVerificationToken(string input)
{
string regexpression = @"name=""__RequestVerificationToken"" type=""hidden"" value=""([-A-Za-z0-9+=/\\_]+?)""";
var regex = new Regex(regexpression);
var match = regex.Match(input);
return match.Groups.Values.LastOrDefault().Value;
}
[Fact]
public async Task ReturnsSuccessfulSignInOnPostWithValidCredentials()
{
var getResponse = await Client.GetAsync("/identity/account/login");
getResponse.EnsureSuccessStatusCode();
var stringResponse1 = await getResponse.Content.ReadAsStringAsync();
string token = GetRequestVerificationToken(stringResponse1);
[Fact]
public async Task ReturnsSuccessfulSignInOnPostWithValidCredentials()
{
var getResponse = await Client.GetAsync("/identity/account/login");
getResponse.EnsureSuccessStatusCode();
var stringResponse1 = await getResponse.Content.ReadAsStringAsync();
string token = GetRequestVerificationToken(stringResponse1);
var keyValues = new List<KeyValuePair<string, string>>();
keyValues.Add(new KeyValuePair<string, string>("Email", "demouser@microsoft.com"));
keyValues.Add(new KeyValuePair<string, string>("Password", "Pass@word1"));
var keyValues = new List<KeyValuePair<string, string>>();
keyValues.Add(new KeyValuePair<string, string>("Email", "demouser@microsoft.com"));
keyValues.Add(new KeyValuePair<string, string>("Password", "Pass@word1"));
keyValues.Add(new KeyValuePair<string, string>("__RequestVerificationToken", token));
var formContent = new FormUrlEncodedContent(keyValues);
keyValues.Add(new KeyValuePair<string, string>("__RequestVerificationToken", token));
var formContent = new FormUrlEncodedContent(keyValues);
var postResponse = await Client.PostAsync("/identity/account/login", formContent);
Assert.Equal(HttpStatusCode.Redirect, postResponse.StatusCode);
Assert.Equal(new System.Uri("/", UriKind.Relative), postResponse.Headers.Location);
}
var postResponse = await Client.PostAsync("/identity/account/login", formContent);
Assert.Equal(HttpStatusCode.Redirect, postResponse.StatusCode);
Assert.Equal(new System.Uri("/", UriKind.Relative), postResponse.Headers.Location);
}
}

View File

@@ -2,28 +2,27 @@
using System.Threading.Tasks;
using Xunit;
namespace Microsoft.eShopWeb.FunctionalTests.Web.Controllers
namespace Microsoft.eShopWeb.FunctionalTests.Web.Controllers;
[Collection("Sequential")]
public class CatalogControllerIndex : IClassFixture<WebTestFixture>
{
[Collection("Sequential")]
public class CatalogControllerIndex : IClassFixture<WebTestFixture>
public CatalogControllerIndex(WebTestFixture factory)
{
public CatalogControllerIndex(WebTestFixture factory)
{
Client = factory.CreateClient();
}
Client = factory.CreateClient();
}
public HttpClient Client { get; }
public HttpClient Client { get; }
[Fact]
public async Task ReturnsHomePageWithProductListing()
{
// Arrange & Act
var response = await Client.GetAsync("/");
response.EnsureSuccessStatusCode();
var stringResponse = await response.Content.ReadAsStringAsync();
[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);
}
// Assert
Assert.Contains(".NET Bot Black Sweatshirt", stringResponse);
}
}

View File

@@ -1,32 +1,31 @@
using Microsoft.AspNetCore.Mvc.Testing;
using System.Net;
using System.Net;
using System.Net.Http;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc.Testing;
using Xunit;
namespace Microsoft.eShopWeb.FunctionalTests.Web.Controllers
namespace Microsoft.eShopWeb.FunctionalTests.Web.Controllers;
[Collection("Sequential")]
public class OrderIndexOnGet : IClassFixture<WebTestFixture>
{
[Collection("Sequential")]
public class OrderIndexOnGet : IClassFixture<WebTestFixture>
public OrderIndexOnGet(WebTestFixture factory)
{
public OrderIndexOnGet(WebTestFixture factory)
Client = factory.CreateClient(new WebApplicationFactoryClientOptions
{
Client = factory.CreateClient(new WebApplicationFactoryClientOptions
{
AllowAutoRedirect = false
});
}
AllowAutoRedirect = false
});
}
public HttpClient Client { get; }
public HttpClient Client { get; }
[Fact]
public async Task ReturnsRedirectGivenAnonymousUser()
{
var response = await Client.GetAsync("/order/my-orders");
var redirectLocation = response.Headers.Location.OriginalString;
[Fact]
public async Task ReturnsRedirectGivenAnonymousUser()
{
var response = await Client.GetAsync("/order/my-orders");
var redirectLocation = response.Headers.Location.OriginalString;
Assert.Equal(HttpStatusCode.Redirect, response.StatusCode);
Assert.Contains("/Account/Login", redirectLocation);
}
Assert.Equal(HttpStatusCode.Redirect, response.StatusCode);
Assert.Contains("/Account/Login", redirectLocation);
}
}

View File

@@ -1,70 +1,69 @@
using Microsoft.AspNetCore.Mvc.Testing;
using Microsoft.eShopWeb.FunctionalTests.Web;
using System.Collections.Generic;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc.Testing;
using Microsoft.eShopWeb.FunctionalTests.Web;
using Xunit;
namespace Microsoft.eShopWeb.FunctionalTests.WebRazorPages
namespace Microsoft.eShopWeb.FunctionalTests.WebRazorPages;
[Collection("Sequential")]
public class BasketPageCheckout : IClassFixture<WebTestFixture>
{
[Collection("Sequential")]
public class BasketPageCheckout : IClassFixture<WebTestFixture>
public BasketPageCheckout(WebTestFixture factory)
{
public BasketPageCheckout(WebTestFixture factory)
Client = factory.CreateClient(new WebApplicationFactoryClientOptions
{
Client = factory.CreateClient(new WebApplicationFactoryClientOptions
{
AllowAutoRedirect = true
});
}
AllowAutoRedirect = true
});
}
public HttpClient Client { get; }
public HttpClient Client { get; }
private string GetRequestVerificationToken(string input)
{
string regexpression = @"name=""__RequestVerificationToken"" type=""hidden"" value=""([-A-Za-z0-9+=/\\_]+?)""";
var regex = new Regex(regexpression);
var match = regex.Match(input);
return match.Groups.Values.LastOrDefault().Value;
}
private string GetRequestVerificationToken(string input)
{
string regexpression = @"name=""__RequestVerificationToken"" type=""hidden"" value=""([-A-Za-z0-9+=/\\_]+?)""";
var regex = new Regex(regexpression);
var match = regex.Match(input);
return match.Groups.Values.LastOrDefault().Value;
}
[Fact]
public async Task RedirectsToLoginIfNotAuthenticated()
{
// Arrange & Act
[Fact]
public async Task RedirectsToLoginIfNotAuthenticated()
{
// Arrange & Act
// Load Home Page
var response = await Client.GetAsync("/");
response.EnsureSuccessStatusCode();
var stringResponse1 = await response.Content.ReadAsStringAsync();
// Load Home Page
var response = await Client.GetAsync("/");
response.EnsureSuccessStatusCode();
var stringResponse1 = await response.Content.ReadAsStringAsync();
string token = GetRequestVerificationToken(stringResponse1);
string token = GetRequestVerificationToken(stringResponse1);
// Add Item to Cart
var keyValues = new List<KeyValuePair<string, string>>();
keyValues.Add(new KeyValuePair<string, string>("id", "2"));
keyValues.Add(new KeyValuePair<string, string>("name", "shirt"));
// Add Item to Cart
var keyValues = new List<KeyValuePair<string, string>>();
keyValues.Add(new KeyValuePair<string, string>("id", "2"));
keyValues.Add(new KeyValuePair<string, string>("name", "shirt"));
keyValues.Add(new KeyValuePair<string, string>("price", "19.49"));
keyValues.Add(new KeyValuePair<string, string>("__RequestVerificationToken", token));
keyValues.Add(new KeyValuePair<string, string>("price", "19.49"));
keyValues.Add(new KeyValuePair<string, string>("__RequestVerificationToken", token));
var formContent = new FormUrlEncodedContent(keyValues);
var formContent = new FormUrlEncodedContent(keyValues);
var postResponse = await Client.PostAsync("/basket/index", formContent);
postResponse.EnsureSuccessStatusCode();
var stringResponse = await postResponse.Content.ReadAsStringAsync();
var postResponse = await Client.PostAsync("/basket/index", formContent);
postResponse.EnsureSuccessStatusCode();
var stringResponse = await postResponse.Content.ReadAsStringAsync();
// Assert
Assert.Contains(".NET Black &amp; White Mug", stringResponse);
// Assert
Assert.Contains(".NET Black &amp; White Mug", stringResponse);
keyValues.Clear();
keyValues.Add(new KeyValuePair<string, string>("__RequestVerificationToken", token));
keyValues.Clear();
keyValues.Add(new KeyValuePair<string, string>("__RequestVerificationToken", token));
formContent = new FormUrlEncodedContent(keyValues);
var postResponse2 = await Client.PostAsync("/Basket/Checkout", formContent);
Assert.Contains("/Identity/Account/Login", postResponse2.RequestMessage.RequestUri.ToString());
}
formContent = new FormUrlEncodedContent(keyValues);
var postResponse2 = await Client.PostAsync("/Basket/Checkout", formContent);
Assert.Contains("/Identity/Account/Login", postResponse2.RequestMessage.RequestUri.ToString());
}
}

View File

@@ -1,30 +1,29 @@
using Microsoft.eShopWeb.FunctionalTests.Web;
using System.Net.Http;
using System.Net.Http;
using System.Threading.Tasks;
using Microsoft.eShopWeb.FunctionalTests.Web;
using Xunit;
namespace Microsoft.eShopWeb.FunctionalTests.WebRazorPages
namespace Microsoft.eShopWeb.FunctionalTests.WebRazorPages;
[Collection("Sequential")]
public class HomePageOnGet : IClassFixture<WebTestFixture>
{
[Collection("Sequential")]
public class HomePageOnGet : IClassFixture<WebTestFixture>
public HomePageOnGet(WebTestFixture factory)
{
public HomePageOnGet(WebTestFixture factory)
{
Client = factory.CreateClient();
}
Client = factory.CreateClient();
}
public HttpClient Client { get; }
public HttpClient Client { get; }
[Fact]
public async Task ReturnsHomePageWithProductListing()
{
// Arrange & Act
var response = await Client.GetAsync("/");
response.EnsureSuccessStatusCode();
var stringResponse = await response.Content.ReadAsStringAsync();
[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);
}
// Assert
Assert.Contains(".NET Bot Black Sweatshirt", stringResponse);
}
}

View File

@@ -1,4 +1,5 @@
using Microsoft.AspNetCore.Hosting;
using System;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc.Testing;
using Microsoft.EntityFrameworkCore;
@@ -7,38 +8,37 @@ using Microsoft.eShopWeb.Infrastructure.Identity;
using Microsoft.eShopWeb.Web;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using System;
namespace Microsoft.eShopWeb.FunctionalTests.Web
namespace Microsoft.eShopWeb.FunctionalTests.Web;
public class WebTestFixture : WebApplicationFactory<Startup>
{
public class WebTestFixture : WebApplicationFactory<Startup>
protected override void ConfigureWebHost(IWebHostBuilder builder)
{
protected override void ConfigureWebHost(IWebHostBuilder builder)
{
builder.UseEnvironment("Testing");
builder.UseEnvironment("Testing");
builder.ConfigureServices(services =>
{
services.AddEntityFrameworkInMemoryDatabase();
builder.ConfigureServices(services =>
{
services.AddEntityFrameworkInMemoryDatabase();
// Create a new service provider.
var provider = services
.AddEntityFrameworkInMemoryDatabase()
.BuildServiceProvider();
.AddEntityFrameworkInMemoryDatabase()
.BuildServiceProvider();
// Add a database context (ApplicationDbContext) using an in-memory
// database for testing.
services.AddDbContext<CatalogContext>(options =>
{
options.UseInMemoryDatabase("InMemoryDbForTesting");
options.UseInternalServiceProvider(provider);
});
{
options.UseInMemoryDatabase("InMemoryDbForTesting");
options.UseInternalServiceProvider(provider);
});
services.AddDbContext<AppIdentityDbContext>(options =>
{
options.UseInMemoryDatabase("Identity");
options.UseInternalServiceProvider(provider);
});
services.AddDbContext<AppIdentityDbContext>(options =>
{
options.UseInMemoryDatabase("Identity");
options.UseInternalServiceProvider(provider);
});
// Build the service provider.
var sp = services.BuildServiceProvider();
@@ -46,34 +46,33 @@ namespace Microsoft.eShopWeb.FunctionalTests.Web
// 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 scopedServices = scope.ServiceProvider;
var db = scopedServices.GetRequiredService<CatalogContext>();
var loggerFactory = scopedServices.GetRequiredService<ILoggerFactory>();
var logger = scopedServices
.GetRequiredService<ILogger<WebTestFixture>>();
var logger = scopedServices
.GetRequiredService<ILogger<WebTestFixture>>();
// Ensure the database is created.
db.Database.EnsureCreated();
try
{
try
{
// Seed the database with test data.
CatalogContextSeed.SeedAsync(db, loggerFactory).Wait();
// seed sample user data
var userManager = scopedServices.GetRequiredService<UserManager<ApplicationUser>>();
var roleManager = scopedServices.GetRequiredService<RoleManager<IdentityRole>>();
AppIdentityDbContextSeed.SeedAsync(userManager, roleManager).Wait();
}
catch (Exception ex)
{
logger.LogError(ex, $"An error occurred seeding the " +
"database with test messages. Error: {ex.Message}");
}
var roleManager = scopedServices.GetRequiredService<RoleManager<IdentityRole>>();
AppIdentityDbContextSeed.SeedAsync(userManager, roleManager).Wait();
}
});
}
catch (Exception ex)
{
logger.LogError(ex, $"An error occurred seeding the " +
"database with test messages. Error: {ex.Message}");
}
}
});
}
}

View File

@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net5.0</TargetFramework>
<TargetFramework>net6.0</TargetFramework>
<RootNamespace>Microsoft.eShopWeb.IntegrationTests</RootNamespace>
<IsPackable>false</IsPackable>
</PropertyGroup>

View File

@@ -1,41 +1,40 @@
using Microsoft.EntityFrameworkCore;
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore;
using Microsoft.eShopWeb.ApplicationCore.Entities.BasketAggregate;
using Microsoft.eShopWeb.ApplicationCore.Interfaces;
using Microsoft.eShopWeb.ApplicationCore.Services;
using Microsoft.eShopWeb.Infrastructure.Data;
using Microsoft.eShopWeb.UnitTests.Builders;
using System.Collections.Generic;
using System.Threading.Tasks;
using Xunit;
namespace Microsoft.eShopWeb.IntegrationTests.Repositories.BasketRepositoryTests
namespace Microsoft.eShopWeb.IntegrationTests.Repositories.BasketRepositoryTests;
public class SetQuantities
{
public class SetQuantities
private readonly CatalogContext _catalogContext;
private readonly EfRepository<Basket> _basketRepository;
private readonly BasketBuilder BasketBuilder = new BasketBuilder();
public SetQuantities()
{
private readonly CatalogContext _catalogContext;
private readonly EfRepository<Basket> _basketRepository;
private readonly BasketBuilder BasketBuilder = new BasketBuilder();
var dbOptions = new DbContextOptionsBuilder<CatalogContext>()
.UseInMemoryDatabase(databaseName: "TestCatalog")
.Options;
_catalogContext = new CatalogContext(dbOptions);
_basketRepository = new EfRepository<Basket>(_catalogContext);
}
public SetQuantities()
{
var dbOptions = new DbContextOptionsBuilder<CatalogContext>()
.UseInMemoryDatabase(databaseName: "TestCatalog")
.Options;
_catalogContext = new CatalogContext(dbOptions);
_basketRepository = new EfRepository<Basket>(_catalogContext);
}
[Fact]
public async Task RemoveEmptyQuantities()
{
var basket = BasketBuilder.WithOneBasketItem();
var basketService = new BasketService(_basketRepository, null);
await _basketRepository.AddAsync(basket);
_catalogContext.SaveChanges();
[Fact]
public async Task RemoveEmptyQuantities()
{
var basket = BasketBuilder.WithOneBasketItem();
var basketService = new BasketService(_basketRepository, null);
await _basketRepository.AddAsync(basket);
_catalogContext.SaveChanges();
await basketService.SetQuantities(BasketBuilder.BasketId, new Dictionary<string, int>() { { BasketBuilder.BasketId.ToString(), 0 } });
await basketService.SetQuantities(BasketBuilder.BasketId, new Dictionary<string, int>() { { BasketBuilder.BasketId.ToString(), 0 } });
Assert.Equal(0, basket.Items.Count);
}
Assert.Equal(0, basket.Items.Count);
}
}

View File

@@ -1,46 +1,45 @@
using Microsoft.EntityFrameworkCore;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore;
using Microsoft.eShopWeb.ApplicationCore.Entities.OrderAggregate;
using Microsoft.eShopWeb.Infrastructure.Data;
using Microsoft.eShopWeb.UnitTests.Builders;
using System.Linq;
using System.Threading.Tasks;
using Xunit;
using Xunit.Abstractions;
namespace Microsoft.eShopWeb.IntegrationTests.Repositories.OrderRepositoryTests
namespace Microsoft.eShopWeb.IntegrationTests.Repositories.OrderRepositoryTests;
public class GetById
{
public class GetById
private readonly CatalogContext _catalogContext;
private readonly EfRepository<Order> _orderRepository;
private OrderBuilder OrderBuilder { get; } = new OrderBuilder();
private readonly ITestOutputHelper _output;
public GetById(ITestOutputHelper output)
{
private readonly CatalogContext _catalogContext;
private readonly EfRepository<Order> _orderRepository;
private OrderBuilder OrderBuilder { get; } = new OrderBuilder();
private readonly ITestOutputHelper _output;
public GetById(ITestOutputHelper output)
{
_output = output;
var dbOptions = new DbContextOptionsBuilder<CatalogContext>()
.UseInMemoryDatabase(databaseName: "TestCatalog")
.Options;
_catalogContext = new CatalogContext(dbOptions);
_orderRepository = new EfRepository<Order>(_catalogContext);
}
_output = output;
var dbOptions = new DbContextOptionsBuilder<CatalogContext>()
.UseInMemoryDatabase(databaseName: "TestCatalog")
.Options;
_catalogContext = new CatalogContext(dbOptions);
_orderRepository = new EfRepository<Order>(_catalogContext);
}
[Fact]
public async Task GetsExistingOrder()
{
var existingOrder = OrderBuilder.WithDefaultValues();
_catalogContext.Orders.Add(existingOrder);
_catalogContext.SaveChanges();
int orderId = existingOrder.Id;
_output.WriteLine($"OrderId: {orderId}");
[Fact]
public async Task GetsExistingOrder()
{
var existingOrder = OrderBuilder.WithDefaultValues();
_catalogContext.Orders.Add(existingOrder);
_catalogContext.SaveChanges();
int orderId = existingOrder.Id;
_output.WriteLine($"OrderId: {orderId}");
var orderFromRepo = await _orderRepository.GetByIdAsync(orderId);
Assert.Equal(OrderBuilder.TestBuyerId, orderFromRepo.BuyerId);
var orderFromRepo = await _orderRepository.GetByIdAsync(orderId);
Assert.Equal(OrderBuilder.TestBuyerId, orderFromRepo.BuyerId);
// Note: Using InMemoryDatabase OrderItems is available. Will be null if using SQL DB.
// Use the OrderWithItemsByIdSpec instead of just GetById to get the full aggregate
var firstItem = orderFromRepo.OrderItems.FirstOrDefault();
Assert.Equal(OrderBuilder.TestUnits, firstItem.Units);
}
// Note: Using InMemoryDatabase OrderItems is available. Will be null if using SQL DB.
// Use the OrderWithItemsByIdSpec instead of just GetById to get the full aggregate
var firstItem = orderFromRepo.OrderItems.FirstOrDefault();
Assert.Equal(OrderBuilder.TestUnits, firstItem.Units);
}
}

View File

@@ -1,63 +1,62 @@
using Microsoft.EntityFrameworkCore;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore;
using Microsoft.eShopWeb.ApplicationCore.Entities.OrderAggregate;
using Microsoft.eShopWeb.ApplicationCore.Specifications;
using Microsoft.eShopWeb.Infrastructure.Data;
using Microsoft.eShopWeb.UnitTests.Builders;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Xunit;
namespace Microsoft.eShopWeb.IntegrationTests.Repositories.OrderRepositoryTests
namespace Microsoft.eShopWeb.IntegrationTests.Repositories.OrderRepositoryTests;
public class GetByIdWithItemsAsync
{
public class GetByIdWithItemsAsync
private readonly CatalogContext _catalogContext;
private readonly EfRepository<Order> _orderRepository;
private OrderBuilder OrderBuilder { get; } = new OrderBuilder();
public GetByIdWithItemsAsync()
{
private readonly CatalogContext _catalogContext;
private readonly EfRepository<Order> _orderRepository;
private OrderBuilder OrderBuilder { get; } = new OrderBuilder();
var dbOptions = new DbContextOptionsBuilder<CatalogContext>()
.UseInMemoryDatabase(databaseName: "TestCatalog")
.Options;
_catalogContext = new CatalogContext(dbOptions);
_orderRepository = new EfRepository<Order>(_catalogContext);
}
public GetByIdWithItemsAsync()
{
var dbOptions = new DbContextOptionsBuilder<CatalogContext>()
.UseInMemoryDatabase(databaseName: "TestCatalog")
.Options;
_catalogContext = new CatalogContext(dbOptions);
_orderRepository = new EfRepository<Order>(_catalogContext);
}
[Fact]
public async Task GetOrderAndItemsByOrderIdWhenMultipleOrdersPresent()
{
//Arrange
var itemOneUnitPrice = 5.50m;
var itemOneUnits = 2;
var itemTwoUnitPrice = 7.50m;
var itemTwoUnits = 5;
[Fact]
public async Task GetOrderAndItemsByOrderIdWhenMultipleOrdersPresent()
{
//Arrange
var itemOneUnitPrice = 5.50m;
var itemOneUnits = 2;
var itemTwoUnitPrice = 7.50m;
var itemTwoUnits = 5;
var firstOrder = OrderBuilder.WithDefaultValues();
_catalogContext.Orders.Add(firstOrder);
int firstOrderId = firstOrder.Id;
var firstOrder = OrderBuilder.WithDefaultValues();
_catalogContext.Orders.Add(firstOrder);
int firstOrderId = firstOrder.Id;
var secondOrderItems = new List<OrderItem>();
secondOrderItems.Add(new OrderItem(OrderBuilder.TestCatalogItemOrdered, itemOneUnitPrice, itemOneUnits));
secondOrderItems.Add(new OrderItem(OrderBuilder.TestCatalogItemOrdered, itemTwoUnitPrice, itemTwoUnits));
var secondOrder = OrderBuilder.WithItems(secondOrderItems);
_catalogContext.Orders.Add(secondOrder);
int secondOrderId = secondOrder.Id;
var secondOrderItems = new List<OrderItem>();
secondOrderItems.Add(new OrderItem(OrderBuilder.TestCatalogItemOrdered, itemOneUnitPrice, itemOneUnits));
secondOrderItems.Add(new OrderItem(OrderBuilder.TestCatalogItemOrdered, itemTwoUnitPrice, itemTwoUnits));
var secondOrder = OrderBuilder.WithItems(secondOrderItems);
_catalogContext.Orders.Add(secondOrder);
int secondOrderId = secondOrder.Id;
_catalogContext.SaveChanges();
_catalogContext.SaveChanges();
//Act
var spec = new OrderWithItemsByIdSpec(secondOrderId);
var orderFromRepo = await _orderRepository.GetBySpecAsync(spec);
//Act
var spec = new OrderWithItemsByIdSpec(secondOrderId);
var orderFromRepo = await _orderRepository.GetBySpecAsync(spec);
//Assert
Assert.Equal(secondOrderId, orderFromRepo.Id);
Assert.Equal(secondOrder.OrderItems.Count, orderFromRepo.OrderItems.Count);
Assert.Equal(1, orderFromRepo.OrderItems.Count(x => x.UnitPrice == itemOneUnitPrice));
Assert.Equal(1, orderFromRepo.OrderItems.Count(x => x.UnitPrice == itemTwoUnitPrice));
Assert.Equal(itemOneUnits, orderFromRepo.OrderItems.SingleOrDefault(x => x.UnitPrice == itemOneUnitPrice).Units);
Assert.Equal(itemTwoUnits, orderFromRepo.OrderItems.SingleOrDefault(x => x.UnitPrice == itemTwoUnitPrice).Units);
}
//Assert
Assert.Equal(secondOrderId, orderFromRepo.Id);
Assert.Equal(secondOrder.OrderItems.Count, orderFromRepo.OrderItems.Count);
Assert.Equal(1, orderFromRepo.OrderItems.Count(x => x.UnitPrice == itemOneUnitPrice));
Assert.Equal(1, orderFromRepo.OrderItems.Count(x => x.UnitPrice == itemTwoUnitPrice));
Assert.Equal(itemOneUnits, orderFromRepo.OrderItems.SingleOrDefault(x => x.UnitPrice == itemOneUnitPrice).Units);
Assert.Equal(itemTwoUnits, orderFromRepo.OrderItems.SingleOrDefault(x => x.UnitPrice == itemTwoUnitPrice).Units);
}
}

View File

@@ -1,76 +1,75 @@
using Microsoft.eShopWeb.ApplicationCore.Entities.BasketAggregate;
using System;
using System;
using System.Linq;
using Microsoft.eShopWeb.ApplicationCore.Entities.BasketAggregate;
using Xunit;
namespace Microsoft.eShopWeb.UnitTests.ApplicationCore.Entities.BasketTests
{
public class BasketAddItem
{
private readonly int _testCatalogItemId = 123;
private readonly decimal _testUnitPrice = 1.23m;
private readonly int _testQuantity = 2;
private readonly string _buyerId = "Test buyerId";
[Fact]
public void AddsBasketItemIfNotPresent()
{
var basket = new Basket(_buyerId);
basket.AddItem(_testCatalogItemId, _testUnitPrice, _testQuantity);
var firstItem = basket.Items.Single();
Assert.Equal(_testCatalogItemId, firstItem.CatalogItemId);
Assert.Equal(_testUnitPrice, firstItem.UnitPrice);
Assert.Equal(_testQuantity, firstItem.Quantity);
}
[Fact]
public void IncrementsQuantityOfItemIfPresent()
{
var basket = new Basket(_buyerId);
basket.AddItem(_testCatalogItemId, _testUnitPrice, _testQuantity);
basket.AddItem(_testCatalogItemId, _testUnitPrice, _testQuantity);
var firstItem = basket.Items.Single();
Assert.Equal(_testQuantity * 2, firstItem.Quantity);
}
[Fact]
public void KeepsOriginalUnitPriceIfMoreItemsAdded()
{
var basket = new Basket(_buyerId);
basket.AddItem(_testCatalogItemId, _testUnitPrice, _testQuantity);
basket.AddItem(_testCatalogItemId, _testUnitPrice * 2, _testQuantity);
var firstItem = basket.Items.Single();
Assert.Equal(_testUnitPrice, firstItem.UnitPrice);
}
[Fact]
public void DefaultsToQuantityOfOne()
{
var basket = new Basket(_buyerId);
basket.AddItem(_testCatalogItemId, _testUnitPrice);
var firstItem = basket.Items.Single();
Assert.Equal(1, firstItem.Quantity);
}
namespace Microsoft.eShopWeb.UnitTests.ApplicationCore.Entities.BasketTests;
[Fact]
public void CantAddItemWithNegativeQuantity()
{
var basket = new Basket(_buyerId);
public class BasketAddItem
{
private readonly int _testCatalogItemId = 123;
private readonly decimal _testUnitPrice = 1.23m;
private readonly int _testQuantity = 2;
private readonly string _buyerId = "Test buyerId";
Assert.Throws<ArgumentOutOfRangeException>(() => basket.AddItem(_testCatalogItemId, _testUnitPrice, -1));
}
[Fact]
public void AddsBasketItemIfNotPresent()
{
var basket = new Basket(_buyerId);
basket.AddItem(_testCatalogItemId, _testUnitPrice, _testQuantity);
[Fact]
public void CantModifyQuantityToNegativeNumber()
{
var basket = new Basket(_buyerId);
basket.AddItem(_testCatalogItemId, _testUnitPrice);
var firstItem = basket.Items.Single();
Assert.Equal(_testCatalogItemId, firstItem.CatalogItemId);
Assert.Equal(_testUnitPrice, firstItem.UnitPrice);
Assert.Equal(_testQuantity, firstItem.Quantity);
}
Assert.Throws<ArgumentOutOfRangeException>(() => basket.AddItem(_testCatalogItemId, _testUnitPrice, -2));
}
}
[Fact]
public void IncrementsQuantityOfItemIfPresent()
{
var basket = new Basket(_buyerId);
basket.AddItem(_testCatalogItemId, _testUnitPrice, _testQuantity);
basket.AddItem(_testCatalogItemId, _testUnitPrice, _testQuantity);
var firstItem = basket.Items.Single();
Assert.Equal(_testQuantity * 2, firstItem.Quantity);
}
[Fact]
public void KeepsOriginalUnitPriceIfMoreItemsAdded()
{
var basket = new Basket(_buyerId);
basket.AddItem(_testCatalogItemId, _testUnitPrice, _testQuantity);
basket.AddItem(_testCatalogItemId, _testUnitPrice * 2, _testQuantity);
var firstItem = basket.Items.Single();
Assert.Equal(_testUnitPrice, firstItem.UnitPrice);
}
[Fact]
public void DefaultsToQuantityOfOne()
{
var basket = new Basket(_buyerId);
basket.AddItem(_testCatalogItemId, _testUnitPrice);
var firstItem = basket.Items.Single();
Assert.Equal(1, firstItem.Quantity);
}
[Fact]
public void CantAddItemWithNegativeQuantity()
{
var basket = new Basket(_buyerId);
Assert.Throws<ArgumentOutOfRangeException>(() => basket.AddItem(_testCatalogItemId, _testUnitPrice, -1));
}
[Fact]
public void CantModifyQuantityToNegativeNumber()
{
var basket = new Basket(_buyerId);
basket.AddItem(_testCatalogItemId, _testUnitPrice);
Assert.Throws<ArgumentOutOfRangeException>(() => basket.AddItem(_testCatalogItemId, _testUnitPrice, -2));
}
}

View File

@@ -1,22 +1,21 @@
using Microsoft.eShopWeb.ApplicationCore.Entities.BasketAggregate;
using Xunit;
namespace Microsoft.eShopWeb.UnitTests.ApplicationCore.Entities.BasketTests
namespace Microsoft.eShopWeb.UnitTests.ApplicationCore.Entities.BasketTests;
public class BasketRemoveEmptyItems
{
public class BasketRemoveEmptyItems
private readonly int _testCatalogItemId = 123;
private readonly decimal _testUnitPrice = 1.23m;
private readonly string _buyerId = "Test buyerId";
[Fact]
public void RemovesEmptyBasketItems()
{
private readonly int _testCatalogItemId = 123;
private readonly decimal _testUnitPrice = 1.23m;
private readonly string _buyerId = "Test buyerId";
var basket = new Basket(_buyerId);
basket.AddItem(_testCatalogItemId, _testUnitPrice, 0);
basket.RemoveEmptyItems();
[Fact]
public void RemovesEmptyBasketItems()
{
var basket = new Basket(_buyerId);
basket.AddItem(_testCatalogItemId, _testUnitPrice, 0);
basket.RemoveEmptyItems();
Assert.Equal(0, basket.Items.Count);
}
Assert.Equal(0, basket.Items.Count);
}
}

View File

@@ -1,56 +1,55 @@
using Microsoft.eShopWeb.ApplicationCore.Entities;
using System;
using System;
using Microsoft.eShopWeb.ApplicationCore.Entities;
using Xunit;
namespace Microsoft.eShopWeb.UnitTests.ApplicationCore.Entities.CatalogItemTests
namespace Microsoft.eShopWeb.UnitTests.ApplicationCore.Entities.CatalogItemTests;
public class UpdateDetails
{
public class UpdateDetails
private CatalogItem _testItem;
private int _validTypeId = 1;
private int _validBrandId = 2;
private string _validDescription = "test description";
private string _validName = "test name";
private decimal _validPrice = 1.23m;
private string _validUri = "/123";
public UpdateDetails()
{
private CatalogItem _testItem;
private int _validTypeId = 1;
private int _validBrandId = 2;
private string _validDescription = "test description";
private string _validName = "test name";
private decimal _validPrice = 1.23m;
private string _validUri = "/123";
_testItem = new CatalogItem(_validTypeId, _validBrandId, _validDescription, _validName, _validPrice, _validUri);
}
public UpdateDetails()
{
_testItem = new CatalogItem(_validTypeId, _validBrandId, _validDescription, _validName, _validPrice, _validUri);
}
[Fact]
public void ThrowsArgumentExceptionGivenEmptyName()
{
string newValue = "";
Assert.Throws<ArgumentException>(() => _testItem.UpdateDetails(newValue, _validDescription, _validPrice));
}
[Fact]
public void ThrowsArgumentExceptionGivenEmptyName()
{
string newValue = "";
Assert.Throws<ArgumentException>(() => _testItem.UpdateDetails(newValue, _validDescription, _validPrice));
}
[Fact]
public void ThrowsArgumentExceptionGivenEmptyDescription()
{
string newValue = "";
Assert.Throws<ArgumentException>(() => _testItem.UpdateDetails(_validName, newValue, _validPrice));
}
[Fact]
public void ThrowsArgumentExceptionGivenEmptyDescription()
{
string newValue = "";
Assert.Throws<ArgumentException>(() => _testItem.UpdateDetails(_validName, newValue, _validPrice));
}
[Fact]
public void ThrowsArgumentNullExceptionGivenNullName()
{
Assert.Throws<ArgumentNullException>(() => _testItem.UpdateDetails(null, _validDescription, _validPrice));
}
[Fact]
public void ThrowsArgumentNullExceptionGivenNullName()
{
Assert.Throws<ArgumentNullException>(() => _testItem.UpdateDetails(null, _validDescription, _validPrice));
}
[Fact]
public void ThrowsArgumentNullExceptionGivenNullDescription()
{
Assert.Throws<ArgumentNullException>(() => _testItem.UpdateDetails(_validName, null, _validPrice));
}
[Fact]
public void ThrowsArgumentNullExceptionGivenNullDescription()
{
Assert.Throws<ArgumentNullException>(() => _testItem.UpdateDetails(_validName, null, _validPrice));
}
[Theory]
[InlineData(0)]
[InlineData(-1.23)]
public void ThrowsArgumentExceptionGivenNonPositivePrice(decimal newPrice)
{
Assert.Throws<ArgumentException>(() => _testItem.UpdateDetails(_validName, _validDescription, newPrice));
}
[Theory]
[InlineData(0)]
[InlineData(-1.23)]
public void ThrowsArgumentExceptionGivenNonPositivePrice(decimal newPrice)
{
Assert.Throws<ArgumentException>(() => _testItem.UpdateDetails(_validName, _validDescription, newPrice));
}
}

View File

@@ -1,41 +1,40 @@
using Microsoft.eShopWeb.ApplicationCore.Entities.OrderAggregate;
using System.Collections.Generic;
using Microsoft.eShopWeb.ApplicationCore.Entities.OrderAggregate;
using Microsoft.eShopWeb.UnitTests.Builders;
using System.Collections.Generic;
using Xunit;
namespace Microsoft.eShopWeb.UnitTests.ApplicationCore.Entities.OrderTests
namespace Microsoft.eShopWeb.UnitTests.ApplicationCore.Entities.OrderTests;
public class OrderTotal
{
public class OrderTotal
private decimal _testUnitPrice = 42m;
[Fact]
public void IsZeroForNewOrder()
{
private decimal _testUnitPrice = 42m;
var order = new OrderBuilder().WithNoItems();
[Fact]
public void IsZeroForNewOrder()
{
var order = new OrderBuilder().WithNoItems();
Assert.Equal(0, order.Total());
}
Assert.Equal(0, order.Total());
}
[Fact]
public void IsCorrectGiven1Item()
{
var builder = new OrderBuilder();
var items = new List<OrderItem>
[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());
}
var order = new OrderBuilder().WithItems(items);
Assert.Equal(_testUnitPrice, order.Total());
}
[Fact]
public void IsCorrectGiven3Items()
{
var builder = new OrderBuilder();
var order = builder.WithDefaultValues();
[Fact]
public void IsCorrectGiven3Items()
{
var builder = new OrderBuilder();
var order = builder.WithDefaultValues();
Assert.Equal(builder.TestUnitPrice * builder.TestUnits, order.Total());
}
Assert.Equal(builder.TestUnitPrice * builder.TestUnits, order.Total());
}
}

View File

@@ -1,36 +1,35 @@
using Xunit;
namespace Microsoft.eShopWeb.UnitTests.ApplicationCore.Extensions
namespace Microsoft.eShopWeb.UnitTests.ApplicationCore.Extensions;
public class JsonExtensions
{
public class JsonExtensions
[Fact]
public void CorrectlySerializesAndDeserializesObject()
{
[Fact]
public void CorrectlySerializesAndDeserializesObject()
var testParent = new TestParent
{
var testParent = new TestParent
Id = 7,
Name = "Test name",
Children = new[]
{
Id = 7,
Name = "Test name",
Children = new[]
{
new TestChild(),
new TestChild(),
new TestChild()
}
};
var json = testParent.ToJson();
var result = json.FromJson<TestParent>();
Assert.Equal(testParent, result);
}
[
Theory,
InlineData("{ \"id\": 9, \"name\": \"Another test\" }", 9, "Another test"),
InlineData("{ \"id\": 3124, \"name\": \"Test Value 1\" }", 3124, "Test Value 1"),
]
public void CorrectlyDeserializesJson(string json, int expectedId, string expectedName) =>
Assert.Equal(new TestParent { Id = expectedId, Name = expectedName }, json.FromJson<TestParent>());
};
var json = testParent.ToJson();
var result = json.FromJson<TestParent>();
Assert.Equal(testParent, result);
}
}
[
Theory,
InlineData("{ \"id\": 9, \"name\": \"Another test\" }", 9, "Another test"),
InlineData("{ \"id\": 3124, \"name\": \"Test Value 1\" }", 3124, "Test Value 1"),
]
public void CorrectlyDeserializesJson(string json, int expectedId, string expectedName) =>
Assert.Equal(new TestParent { Id = expectedId, Name = expectedName }, json.FromJson<TestParent>());
}

View File

@@ -2,16 +2,15 @@
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
namespace Microsoft.eShopWeb.UnitTests.ApplicationCore.Extensions
namespace Microsoft.eShopWeb.UnitTests.ApplicationCore.Extensions;
[DebuggerDisplay("Id={Id}, Date={Date}")]
public class TestChild : IEquatable<TestChild>
{
[DebuggerDisplay("Id={Id}, Date={Date}")]
public class TestChild : IEquatable<TestChild>
{
public Guid Id { get; set; } = Guid.NewGuid();
public Guid Id { get; set; } = Guid.NewGuid();
public DateTime Date { get; set; } = DateTime.UtcNow;
public DateTime Date { get; set; } = DateTime.UtcNow;
public bool Equals([AllowNull] TestChild other) =>
other?.Date == Date && other?.Id == Id;
}
public bool Equals([AllowNull] TestChild other) =>
other?.Date == Date && other?.Id == Id;
}

View File

@@ -3,19 +3,18 @@ using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
namespace Microsoft.eShopWeb.UnitTests.ApplicationCore.Extensions
namespace Microsoft.eShopWeb.UnitTests.ApplicationCore.Extensions;
public class TestParent : IEquatable<TestParent>
{
public class TestParent : IEquatable<TestParent>
{
public int Id { get; set; }
public int Id { get; set; }
public string Name { get; set; }
public string Name { get; set; }
public IEnumerable<TestChild> Children { get; set; }
public IEnumerable<TestChild> Children { get; set; }
public bool Equals([AllowNull] TestParent other) =>
other?.Id == Id && other?.Name == Name &&
(other?.Children is null && Children is null ||
(other?.Children?.Zip(Children)?.All(t => t.First?.Equals(t.Second) ?? false) ?? false));
}
}
public bool Equals([AllowNull] TestParent other) =>
other?.Id == Id && other?.Name == Name &&
(other?.Children is null && Children is null ||
(other?.Children?.Zip(Children)?.All(t => t.First?.Equals(t.Second) ?? false) ?? false));
}

View File

@@ -1,44 +1,43 @@
using Microsoft.eShopWeb.ApplicationCore.Entities.BasketAggregate;
using System.Threading.Tasks;
using Microsoft.eShopWeb.ApplicationCore.Entities.BasketAggregate;
using Microsoft.eShopWeb.ApplicationCore.Interfaces;
using Microsoft.eShopWeb.ApplicationCore.Services;
using Microsoft.eShopWeb.ApplicationCore.Specifications;
using Moq;
using System.Threading.Tasks;
using Xunit;
namespace Microsoft.eShopWeb.UnitTests.ApplicationCore.Services.BasketServiceTests
namespace Microsoft.eShopWeb.UnitTests.ApplicationCore.Services.BasketServiceTests;
public class AddItemToBasket
{
public class AddItemToBasket
private readonly string _buyerId = "Test buyerId";
private readonly Mock<IRepository<Basket>> _mockBasketRepo = new();
[Fact]
public async Task InvokesBasketRepositoryGetBySpecAsyncOnce()
{
private readonly string _buyerId = "Test buyerId";
private readonly Mock<IRepository<Basket>> _mockBasketRepo = new();
var basket = new Basket(_buyerId);
basket.AddItem(1, It.IsAny<decimal>(), It.IsAny<int>());
_mockBasketRepo.Setup(x => x.GetBySpecAsync(It.IsAny<BasketWithItemsSpecification>(), default)).ReturnsAsync(basket);
[Fact]
public async Task InvokesBasketRepositoryGetBySpecAsyncOnce()
{
var basket = new Basket(_buyerId);
basket.AddItem(1, It.IsAny<decimal>(), It.IsAny<int>());
_mockBasketRepo.Setup(x => x.GetBySpecAsync(It.IsAny<BasketWithItemsSpecification>(), default)).ReturnsAsync(basket);
var basketService = new BasketService(_mockBasketRepo.Object, null);
var basketService = new BasketService(_mockBasketRepo.Object, null);
await basketService.AddItemToBasket(basket.BuyerId, 1, 1.50m);
await basketService.AddItemToBasket(basket.BuyerId, 1, 1.50m);
_mockBasketRepo.Verify(x => x.GetBySpecAsync(It.IsAny<BasketWithItemsSpecification>(), default), Times.Once);
}
_mockBasketRepo.Verify(x => x.GetBySpecAsync(It.IsAny<BasketWithItemsSpecification>(), default), Times.Once);
}
[Fact]
public async Task InvokesBasketRepositoryUpdateAsyncOnce()
{
var basket = new Basket(_buyerId);
basket.AddItem(1, It.IsAny<decimal>(), It.IsAny<int>());
_mockBasketRepo.Setup(x => x.GetBySpecAsync(It.IsAny<BasketWithItemsSpecification>(), default)).ReturnsAsync(basket);
[Fact]
public async Task InvokesBasketRepositoryUpdateAsyncOnce()
{
var basket = new Basket(_buyerId);
basket.AddItem(1, It.IsAny<decimal>(), It.IsAny<int>());
_mockBasketRepo.Setup(x => x.GetBySpecAsync(It.IsAny<BasketWithItemsSpecification>(), default)).ReturnsAsync(basket);
var basketService = new BasketService(_mockBasketRepo.Object, null);
var basketService = new BasketService(_mockBasketRepo.Object, null);
await basketService.AddItemToBasket(basket.BuyerId, 1, 1.50m);
await basketService.AddItemToBasket(basket.BuyerId, 1, 1.50m);
_mockBasketRepo.Verify(x => x.UpdateAsync(basket, default), Times.Once);
}
_mockBasketRepo.Verify(x => x.UpdateAsync(basket, default), Times.Once);
}
}

View File

@@ -1,30 +1,29 @@
using Microsoft.eShopWeb.ApplicationCore.Entities.BasketAggregate;
using System.Threading.Tasks;
using Microsoft.eShopWeb.ApplicationCore.Entities.BasketAggregate;
using Microsoft.eShopWeb.ApplicationCore.Interfaces;
using Microsoft.eShopWeb.ApplicationCore.Services;
using Moq;
using System.Threading.Tasks;
using Xunit;
namespace Microsoft.eShopWeb.UnitTests.ApplicationCore.Services.BasketServiceTests
namespace Microsoft.eShopWeb.UnitTests.ApplicationCore.Services.BasketServiceTests;
public class DeleteBasket
{
public class DeleteBasket
private readonly string _buyerId = "Test buyerId";
private readonly Mock<IRepository<Basket>> _mockBasketRepo = new();
[Fact]
public async Task ShouldInvokeBasketRepositoryDeleteAsyncOnce()
{
private readonly string _buyerId = "Test buyerId";
private readonly Mock<IRepository<Basket>> _mockBasketRepo = new();
var basket = new Basket(_buyerId);
basket.AddItem(1, It.IsAny<decimal>(), It.IsAny<int>());
basket.AddItem(2, It.IsAny<decimal>(), It.IsAny<int>());
_mockBasketRepo.Setup(x => x.GetByIdAsync(It.IsAny<int>(), default))
.ReturnsAsync(basket);
var basketService = new BasketService(_mockBasketRepo.Object, null);
[Fact]
public async Task ShouldInvokeBasketRepositoryDeleteAsyncOnce()
{
var basket = new Basket(_buyerId);
basket.AddItem(1, It.IsAny<decimal>(), It.IsAny<int>());
basket.AddItem(2, It.IsAny<decimal>(), It.IsAny<int>());
_mockBasketRepo.Setup(x => x.GetByIdAsync(It.IsAny<int>(),default))
.ReturnsAsync(basket);
var basketService = new BasketService(_mockBasketRepo.Object, null);
await basketService.DeleteBasketAsync(It.IsAny<int>());
await basketService.DeleteBasketAsync(It.IsAny<int>());
_mockBasketRepo.Verify(x => x.DeleteAsync(It.IsAny<Basket>(),default), Times.Once);
}
_mockBasketRepo.Verify(x => x.DeleteAsync(It.IsAny<Basket>(), default), Times.Once);
}
}

View File

@@ -1,35 +1,34 @@
using Microsoft.eShopWeb.ApplicationCore.Entities.BasketAggregate;
using System;
using System.Threading.Tasks;
using Microsoft.eShopWeb.ApplicationCore.Entities.BasketAggregate;
using Microsoft.eShopWeb.ApplicationCore.Exceptions;
using Microsoft.eShopWeb.ApplicationCore.Interfaces;
using Microsoft.eShopWeb.ApplicationCore.Services;
using Moq;
using System;
using System.Threading.Tasks;
using Xunit;
namespace Microsoft.eShopWeb.UnitTests.ApplicationCore.Services.BasketServiceTests
namespace Microsoft.eShopWeb.UnitTests.ApplicationCore.Services.BasketServiceTests;
public class SetQuantities
{
public class SetQuantities
private readonly int _invalidId = -1;
private readonly Mock<IRepository<Basket>> _mockBasketRepo = new();
[Fact]
public async Task ThrowsGivenInvalidBasketId()
{
private readonly int _invalidId = -1;
private readonly Mock<IRepository<Basket>> _mockBasketRepo = new();
var basketService = new BasketService(_mockBasketRepo.Object, null);
[Fact]
public async Task ThrowsGivenInvalidBasketId()
{
var basketService = new BasketService(_mockBasketRepo.Object, null);
await Assert.ThrowsAsync<BasketNotFoundException>(async () =>
await basketService.SetQuantities(_invalidId, new System.Collections.Generic.Dictionary<string, int>()));
}
await Assert.ThrowsAsync<BasketNotFoundException>(async () =>
await basketService.SetQuantities(_invalidId, new System.Collections.Generic.Dictionary<string, int>()));
}
[Fact]
public async Task ThrowsGivenNullQuantities()
{
var basketService = new BasketService(null, null);
[Fact]
public async Task ThrowsGivenNullQuantities()
{
var basketService = new BasketService(null, null);
await Assert.ThrowsAsync<ArgumentNullException>(async () =>
await basketService.SetQuantities(123, null));
}
await Assert.ThrowsAsync<ArgumentNullException>(async () =>
await basketService.SetQuantities(123, null));
}
}

View File

@@ -1,97 +1,96 @@
using Microsoft.eShopWeb.ApplicationCore.Entities.BasketAggregate;
using System;
using System.Threading.Tasks;
using Microsoft.eShopWeb.ApplicationCore.Entities.BasketAggregate;
using Microsoft.eShopWeb.ApplicationCore.Interfaces;
using Microsoft.eShopWeb.ApplicationCore.Services;
using Microsoft.eShopWeb.ApplicationCore.Specifications;
using Moq;
using System;
using System.Threading.Tasks;
using Xunit;
namespace Microsoft.eShopWeb.UnitTests.ApplicationCore.Services.BasketServiceTests
namespace Microsoft.eShopWeb.UnitTests.ApplicationCore.Services.BasketServiceTests;
public class TransferBasket
{
public class TransferBasket
private readonly string _nonexistentAnonymousBasketBuyerId = "nonexistent-anonymous-basket-buyer-id";
private readonly string _existentAnonymousBasketBuyerId = "existent-anonymous-basket-buyer-id";
private readonly string _nonexistentUserBasketBuyerId = "newuser@microsoft.com";
private readonly string _existentUserBasketBuyerId = "testuser@microsoft.com";
private readonly Mock<IRepository<Basket>> _mockBasketRepo = new();
[Fact]
public async Task ThrowsGivenNullAnonymousId()
{
private readonly string _nonexistentAnonymousBasketBuyerId = "nonexistent-anonymous-basket-buyer-id";
private readonly string _existentAnonymousBasketBuyerId = "existent-anonymous-basket-buyer-id";
private readonly string _nonexistentUserBasketBuyerId = "newuser@microsoft.com";
private readonly string _existentUserBasketBuyerId = "testuser@microsoft.com";
private readonly Mock<IRepository<Basket>> _mockBasketRepo = new();
var basketService = new BasketService(null, null);
[Fact]
public async Task ThrowsGivenNullAnonymousId()
{
var basketService = new BasketService(null, null);
await Assert.ThrowsAsync<ArgumentNullException>(async () => await basketService.TransferBasketAsync(null, "steve"));
}
await Assert.ThrowsAsync<ArgumentNullException>(async () => await basketService.TransferBasketAsync(null, "steve"));
}
[Fact]
public async Task ThrowsGivenNullUserId()
{
var basketService = new BasketService(null, null);
[Fact]
public async Task ThrowsGivenNullUserId()
{
var basketService = new BasketService(null, null);
await Assert.ThrowsAsync<ArgumentNullException>(async () => await basketService.TransferBasketAsync("abcdefg", null));
}
await Assert.ThrowsAsync<ArgumentNullException>(async () => await basketService.TransferBasketAsync("abcdefg", null));
}
[Fact]
public async Task InvokesBasketRepositoryFirstOrDefaultAsyncOnceIfAnonymousBasketNotExists()
{
var anonymousBasket = null as Basket;
var userBasket = new Basket(_existentUserBasketBuyerId);
_mockBasketRepo.SetupSequence(x => x.GetBySpecAsync(It.IsAny<BasketWithItemsSpecification>(), default))
.ReturnsAsync(anonymousBasket)
.ReturnsAsync(userBasket);
var basketService = new BasketService(_mockBasketRepo.Object, null);
await basketService.TransferBasketAsync(_nonexistentAnonymousBasketBuyerId, _existentUserBasketBuyerId);
_mockBasketRepo.Verify(x => x.GetBySpecAsync(It.IsAny<BasketWithItemsSpecification>(), default), Times.Once);
}
[Fact]
public async Task InvokesBasketRepositoryFirstOrDefaultAsyncOnceIfAnonymousBasketNotExists()
{
var anonymousBasket = null as Basket;
var userBasket = new Basket(_existentUserBasketBuyerId);
_mockBasketRepo.SetupSequence(x => x.GetBySpecAsync(It.IsAny<BasketWithItemsSpecification>(), default))
.ReturnsAsync(anonymousBasket)
.ReturnsAsync(userBasket);
var basketService = new BasketService(_mockBasketRepo.Object, null);
await basketService.TransferBasketAsync(_nonexistentAnonymousBasketBuyerId, _existentUserBasketBuyerId);
_mockBasketRepo.Verify(x => x.GetBySpecAsync(It.IsAny<BasketWithItemsSpecification>(), default), Times.Once);
}
[Fact]
public async Task TransferAnonymousBasketItemsWhilePreservingExistingUserBasketItems()
{
var anonymousBasket = new Basket(_existentAnonymousBasketBuyerId);
anonymousBasket.AddItem(1, 10, 1);
anonymousBasket.AddItem(3, 55, 7);
var userBasket = new Basket(_existentUserBasketBuyerId);
userBasket.AddItem(1, 10, 4);
userBasket.AddItem(2, 99, 3);
_mockBasketRepo.SetupSequence(x => x.GetBySpecAsync(It.IsAny<BasketWithItemsSpecification>(), default))
.ReturnsAsync(anonymousBasket)
.ReturnsAsync(userBasket);
var basketService = new BasketService(_mockBasketRepo.Object, null);
await basketService.TransferBasketAsync(_nonexistentAnonymousBasketBuyerId, _existentUserBasketBuyerId);
_mockBasketRepo.Verify(x => x.UpdateAsync(userBasket, default), Times.Once);
Assert.Equal(3, userBasket.Items.Count);
Assert.Contains(userBasket.Items, x => x.CatalogItemId == 1 && x.UnitPrice == 10 && x.Quantity == 5);
Assert.Contains(userBasket.Items, x => x.CatalogItemId == 2 && x.UnitPrice == 99 && x.Quantity == 3);
Assert.Contains(userBasket.Items, x => x.CatalogItemId == 3 && x.UnitPrice == 55 && x.Quantity == 7);
}
[Fact]
public async Task TransferAnonymousBasketItemsWhilePreservingExistingUserBasketItems()
{
var anonymousBasket = new Basket(_existentAnonymousBasketBuyerId);
anonymousBasket.AddItem(1, 10, 1);
anonymousBasket.AddItem(3, 55, 7);
var userBasket = new Basket(_existentUserBasketBuyerId);
userBasket.AddItem(1, 10, 4);
userBasket.AddItem(2, 99, 3);
_mockBasketRepo.SetupSequence(x => x.GetBySpecAsync(It.IsAny<BasketWithItemsSpecification>(), default))
.ReturnsAsync(anonymousBasket)
.ReturnsAsync(userBasket);
var basketService = new BasketService(_mockBasketRepo.Object, null);
await basketService.TransferBasketAsync(_nonexistentAnonymousBasketBuyerId, _existentUserBasketBuyerId);
_mockBasketRepo.Verify(x => x.UpdateAsync(userBasket, default), Times.Once);
Assert.Equal(3, userBasket.Items.Count);
Assert.Contains(userBasket.Items, x => x.CatalogItemId == 1 && x.UnitPrice == 10 && x.Quantity == 5);
Assert.Contains(userBasket.Items, x => x.CatalogItemId == 2 && x.UnitPrice == 99 && x.Quantity == 3);
Assert.Contains(userBasket.Items, x => x.CatalogItemId == 3 && x.UnitPrice == 55 && x.Quantity == 7);
}
[Fact]
public async Task RemovesAnonymousBasketAfterUpdatingUserBasket()
{
var anonymousBasket = new Basket(_existentAnonymousBasketBuyerId);
var userBasket = new Basket(_existentUserBasketBuyerId);
_mockBasketRepo.SetupSequence(x => x.GetBySpecAsync(It.IsAny<BasketWithItemsSpecification>(), default))
.ReturnsAsync(anonymousBasket)
.ReturnsAsync(userBasket);
var basketService = new BasketService(_mockBasketRepo.Object, null);
await basketService.TransferBasketAsync(_nonexistentAnonymousBasketBuyerId, _existentUserBasketBuyerId);
_mockBasketRepo.Verify(x => x.UpdateAsync(userBasket, default), Times.Once);
_mockBasketRepo.Verify(x => x.DeleteAsync(anonymousBasket, default), Times.Once);
}
[Fact]
public async Task RemovesAnonymousBasketAfterUpdatingUserBasket()
{
var anonymousBasket = new Basket(_existentAnonymousBasketBuyerId);
var userBasket = new Basket(_existentUserBasketBuyerId);
_mockBasketRepo.SetupSequence(x => x.GetBySpecAsync(It.IsAny<BasketWithItemsSpecification>(), default))
.ReturnsAsync(anonymousBasket)
.ReturnsAsync(userBasket);
var basketService = new BasketService(_mockBasketRepo.Object, null);
await basketService.TransferBasketAsync(_nonexistentAnonymousBasketBuyerId, _existentUserBasketBuyerId);
_mockBasketRepo.Verify(x => x.UpdateAsync(userBasket, default), Times.Once);
_mockBasketRepo.Verify(x => x.DeleteAsync(anonymousBasket, default), Times.Once);
}
[Fact]
public async Task CreatesNewUserBasketIfNotExists()
{
var anonymousBasket = new Basket(_existentAnonymousBasketBuyerId);
var userBasket = null as Basket;
_mockBasketRepo.SetupSequence(x => x.GetBySpecAsync(It.IsAny<BasketWithItemsSpecification>(), default))
.ReturnsAsync(anonymousBasket)
.ReturnsAsync(userBasket);
var basketService = new BasketService(_mockBasketRepo.Object, null);
await basketService.TransferBasketAsync(_existentAnonymousBasketBuyerId, _nonexistentUserBasketBuyerId);
_mockBasketRepo.Verify(x => x.AddAsync(It.Is<Basket>(x => x.BuyerId == _nonexistentUserBasketBuyerId), default), Times.Once);
}
[Fact]
public async Task CreatesNewUserBasketIfNotExists()
{
var anonymousBasket = new Basket(_existentAnonymousBasketBuyerId);
var userBasket = null as Basket;
_mockBasketRepo.SetupSequence(x => x.GetBySpecAsync(It.IsAny<BasketWithItemsSpecification>(), default))
.ReturnsAsync(anonymousBasket)
.ReturnsAsync(userBasket);
var basketService = new BasketService(_mockBasketRepo.Object, null);
await basketService.TransferBasketAsync(_existentAnonymousBasketBuyerId, _nonexistentUserBasketBuyerId);
_mockBasketRepo.Verify(x => x.AddAsync(It.Is<Basket>(x => x.BuyerId == _nonexistentUserBasketBuyerId), default), Times.Once);
}
}

View File

@@ -1,76 +1,75 @@
using Microsoft.eShopWeb.ApplicationCore.Entities.BasketAggregate;
using System.Collections.Generic;
using System.Linq;
using Microsoft.eShopWeb.ApplicationCore.Entities.BasketAggregate;
using Microsoft.eShopWeb.ApplicationCore.Specifications;
using Moq;
using System.Collections.Generic;
using System.Linq;
using Xunit;
namespace Microsoft.eShopWeb.UnitTests.ApplicationCore.Specifications
namespace Microsoft.eShopWeb.UnitTests.ApplicationCore.Specifications;
public class BasketWithItems
{
public class BasketWithItems
private readonly int _testBasketId = 123;
private readonly string _buyerId = "Test buyerId";
[Fact]
public void MatchesBasketWithGivenBasketId()
{
private readonly int _testBasketId = 123;
private readonly string _buyerId = "Test buyerId";
var spec = new BasketWithItemsSpecification(_testBasketId);
[Fact]
public void MatchesBasketWithGivenBasketId()
{
var spec = new BasketWithItemsSpecification(_testBasketId);
var result = spec.Evaluate(GetTestBasketCollection()).FirstOrDefault();
var result = spec.Evaluate(GetTestBasketCollection()).FirstOrDefault();
Assert.NotNull(result);
Assert.Equal(_testBasketId, result.Id);
}
Assert.NotNull(result);
Assert.Equal(_testBasketId, result.Id);
}
[Fact]
public void MatchesNoBasketsIfBasketIdNotPresent()
{
int badBasketId = -1;
var spec = new BasketWithItemsSpecification(badBasketId);
[Fact]
public void MatchesNoBasketsIfBasketIdNotPresent()
{
int badBasketId = -1;
var spec = new BasketWithItemsSpecification(badBasketId);
var result = spec.Evaluate(GetTestBasketCollection()).Any();
var result = spec.Evaluate(GetTestBasketCollection()).Any();
Assert.False(result);
}
Assert.False(result);
}
[Fact]
public void MatchesBasketWithGivenBuyerId()
{
var spec = new BasketWithItemsSpecification(_buyerId);
[Fact]
public void MatchesBasketWithGivenBuyerId()
{
var spec = new BasketWithItemsSpecification(_buyerId);
var result = spec.Evaluate(GetTestBasketCollection()).FirstOrDefault();
var result = spec.Evaluate(GetTestBasketCollection()).FirstOrDefault();
Assert.NotNull(result);
Assert.Equal(_buyerId, result.BuyerId);
}
Assert.NotNull(result);
Assert.Equal(_buyerId, result.BuyerId);
}
[Fact]
public void MatchesNoBasketsIfBuyerIdNotPresent()
{
string badBuyerId = "badBuyerId";
var spec = new BasketWithItemsSpecification(badBuyerId);
[Fact]
public void MatchesNoBasketsIfBuyerIdNotPresent()
{
string badBuyerId = "badBuyerId";
var spec = new BasketWithItemsSpecification(badBuyerId);
var result = spec.Evaluate(GetTestBasketCollection()).Any();
var result = spec.Evaluate(GetTestBasketCollection()).Any();
Assert.False(result);
}
Assert.False(result);
}
public List<Basket> GetTestBasketCollection()
{
var basket1Mock = new Mock<Basket>(_buyerId);
basket1Mock.SetupGet(s => s.Id).Returns(1);
var basket2Mock = new Mock<Basket>(_buyerId);
basket2Mock.SetupGet(s => s.Id).Returns(2);
var basket3Mock = new Mock<Basket>(_buyerId);
basket3Mock.SetupGet(s => s.Id).Returns(_testBasketId);
public List<Basket> GetTestBasketCollection()
{
var basket1Mock = new Mock<Basket>(_buyerId);
basket1Mock.SetupGet(s => s.Id).Returns(1);
var basket2Mock = new Mock<Basket>(_buyerId);
basket2Mock.SetupGet(s => s.Id).Returns(2);
var basket3Mock = new Mock<Basket>(_buyerId);
basket3Mock.SetupGet(s => s.Id).Returns(_testBasketId);
return new List<Basket>()
return new List<Basket>()
{
basket1Mock.Object,
basket2Mock.Object,
basket3Mock.Object
};
}
}
}

View File

@@ -1,48 +1,47 @@
using Microsoft.eShopWeb.ApplicationCore.Entities;
using System.Collections.Generic;
using System.Collections.Generic;
using System.Linq;
using Microsoft.eShopWeb.ApplicationCore.Entities;
using Xunit;
namespace Microsoft.eShopWeb.UnitTests.ApplicationCore.Specifications
namespace Microsoft.eShopWeb.UnitTests.ApplicationCore.Specifications;
public class CatalogFilterPaginatedSpecification
{
public class CatalogFilterPaginatedSpecification
[Fact]
public void ReturnsAllCatalogItems()
{
[Fact]
public void ReturnsAllCatalogItems()
{
var spec = new eShopWeb.ApplicationCore.Specifications.CatalogFilterPaginatedSpecification(0, 10, null, null);
var spec = new eShopWeb.ApplicationCore.Specifications.CatalogFilterPaginatedSpecification(0, 10, null, null);
var result = GetTestCollection()
.AsQueryable()
.Where(spec.WhereExpressions.FirstOrDefault());
var result = GetTestCollection()
.AsQueryable()
.Where(spec.WhereExpressions.FirstOrDefault());
Assert.NotNull(result);
Assert.Equal(4, result.ToList().Count);
}
Assert.NotNull(result);
Assert.Equal(4, result.ToList().Count);
}
[Fact]
public void Returns2CatalogItemsWithSameBrandAndTypeId()
{
var spec = new eShopWeb.ApplicationCore.Specifications.CatalogFilterPaginatedSpecification(0, 10, 1, 1);
[Fact]
public void Returns2CatalogItemsWithSameBrandAndTypeId()
{
var spec = new eShopWeb.ApplicationCore.Specifications.CatalogFilterPaginatedSpecification(0, 10, 1, 1);
var result = GetTestCollection()
.AsQueryable()
.Where(spec.WhereExpressions.FirstOrDefault());
var result = GetTestCollection()
.AsQueryable()
.Where(spec.WhereExpressions.FirstOrDefault());
Assert.NotNull(result);
Assert.Equal(2, result.ToList().Count);
}
Assert.NotNull(result);
Assert.Equal(2, result.ToList().Count);
}
private List<CatalogItem> GetTestCollection()
{
var catalogItemList = new List<CatalogItem>();
private List<CatalogItem> GetTestCollection()
{
var catalogItemList = new List<CatalogItem>();
catalogItemList.Add(new CatalogItem(1, 1, "Item 1", "Item 1", 1.00m, "TestUri1"));
catalogItemList.Add(new CatalogItem(1, 1, "Item 1.5", "Item 1.5", 1.50m, "TestUri1"));
catalogItemList.Add(new CatalogItem(2, 2, "Item 2", "Item 2", 2.00m, "TestUri2"));
catalogItemList.Add(new CatalogItem(3, 3, "Item 3", "Item 3", 3.00m, "TestUri3"));
catalogItemList.Add(new CatalogItem(1, 1, "Item 1", "Item 1", 1.00m, "TestUri1"));
catalogItemList.Add(new CatalogItem(1, 1, "Item 1.5", "Item 1.5", 1.50m, "TestUri1"));
catalogItemList.Add(new CatalogItem(2, 2, "Item 2", "Item 2", 2.00m, "TestUri2"));
catalogItemList.Add(new CatalogItem(3, 3, "Item 3", "Item 3", 3.00m, "TestUri3"));
return catalogItemList;
}
return catalogItemList;
}
}

View File

@@ -1,41 +1,40 @@
using Microsoft.eShopWeb.ApplicationCore.Entities;
using System.Collections.Generic;
using System.Collections.Generic;
using System.Linq;
using Microsoft.eShopWeb.ApplicationCore.Entities;
using Xunit;
namespace Microsoft.eShopWeb.UnitTests.ApplicationCore.Specifications
namespace Microsoft.eShopWeb.UnitTests.ApplicationCore.Specifications;
public class CatalogFilterSpecification
{
public class CatalogFilterSpecification
[Theory]
[InlineData(null, null, 5)]
[InlineData(1, null, 3)]
[InlineData(2, null, 2)]
[InlineData(null, 1, 2)]
[InlineData(null, 3, 1)]
[InlineData(1, 3, 1)]
[InlineData(2, 3, 0)]
public void MatchesExpectedNumberOfItems(int? brandId, int? typeId, int expectedCount)
{
[Theory]
[InlineData(null, null, 5)]
[InlineData(1, null, 3)]
[InlineData(2, null, 2)]
[InlineData(null, 1, 2)]
[InlineData(null, 3, 1)]
[InlineData(1, 3, 1)]
[InlineData(2, 3, 0)]
public void MatchesExpectedNumberOfItems(int? brandId, int? typeId, int expectedCount)
{
var spec = new eShopWeb.ApplicationCore.Specifications.CatalogFilterSpecification(brandId, typeId);
var spec = new eShopWeb.ApplicationCore.Specifications.CatalogFilterSpecification(brandId, typeId);
var result = GetTestItemCollection()
.AsQueryable()
.Where(spec.WhereExpressions.FirstOrDefault());
var result = GetTestItemCollection()
.AsQueryable()
.Where(spec.WhereExpressions.FirstOrDefault());
Assert.Equal(expectedCount, result.Count());
}
Assert.Equal(expectedCount, result.Count());
}
public List<CatalogItem> GetTestItemCollection()
{
return new List<CatalogItem>()
public List<CatalogItem> GetTestItemCollection()
{
return new List<CatalogItem>()
{
new CatalogItem(1, 1, "Description", "Name", 0, "FakePath"),
new CatalogItem(2, 1, "Description", "Name", 0, "FakePath"),
new CatalogItem(3, 1, "Description", "Name", 0, "FakePath"),
new CatalogItem(1, 2, "Description", "Name", 0, "FakePath"),
new CatalogItem(2, 2, "Description", "Name", 0, "FakePath"),
new CatalogItem(2, 2, "Description", "Name", 0, "FakePath"),
};
}
}
}

View File

@@ -1,55 +1,54 @@
using Microsoft.eShopWeb.ApplicationCore.Entities;
using Moq;
using System.Collections.Generic;
using System.Collections.Generic;
using System.Linq;
using Microsoft.eShopWeb.ApplicationCore.Entities;
using Moq;
using Xunit;
namespace Microsoft.eShopWeb.UnitTests.ApplicationCore.Specifications
namespace Microsoft.eShopWeb.UnitTests.ApplicationCore.Specifications;
public class CatalogItemsSpecification
{
public class CatalogItemsSpecification
[Fact]
public void MatchesSpecificCatalogItem()
{
[Fact]
public void MatchesSpecificCatalogItem()
{
var catalogItemIds = new int[] { 1 };
var spec = new eShopWeb.ApplicationCore.Specifications.CatalogItemsSpecification(catalogItemIds);
var catalogItemIds = new int[] { 1 };
var spec = new eShopWeb.ApplicationCore.Specifications.CatalogItemsSpecification(catalogItemIds);
var result = GetTestCollection()
.AsQueryable()
.Where(spec.WhereExpressions.FirstOrDefault());
var result = GetTestCollection()
.AsQueryable()
.Where(spec.WhereExpressions.FirstOrDefault());
Assert.NotNull(result);
Assert.Single(result.ToList());
}
Assert.NotNull(result);
Assert.Single(result.ToList());
}
[Fact]
public void MatchesAllCatalogItems()
{
var catalogItemIds = new int[] { 1, 3 };
var spec = new eShopWeb.ApplicationCore.Specifications.CatalogItemsSpecification(catalogItemIds);
[Fact]
public void MatchesAllCatalogItems()
{
var catalogItemIds = new int[] { 1, 3 };
var spec = new eShopWeb.ApplicationCore.Specifications.CatalogItemsSpecification(catalogItemIds);
var result = GetTestCollection()
.AsQueryable()
.Where(spec.WhereExpressions.FirstOrDefault());
var result = GetTestCollection()
.AsQueryable()
.Where(spec.WhereExpressions.FirstOrDefault());
Assert.NotNull(result);
Assert.Equal(2, result.ToList().Count);
}
Assert.NotNull(result);
Assert.Equal(2, result.ToList().Count);
}
private List<CatalogItem> GetTestCollection()
{
var catalogItems = new List<CatalogItem>();
private List<CatalogItem> GetTestCollection()
{
var catalogItems = new List<CatalogItem>();
var mockCatalogItem1 = new Mock<CatalogItem>(1, 1, "Item 1 description", "Item 1", 1.5m, "Item1Uri");
mockCatalogItem1.SetupGet(x => x.Id).Returns(1);
var mockCatalogItem1 = new Mock<CatalogItem>(1, 1, "Item 1 description", "Item 1", 1.5m, "Item1Uri");
mockCatalogItem1.SetupGet(x => x.Id).Returns(1);
var mockCatalogItem3 = new Mock<CatalogItem>(3, 3, "Item 3 description", "Item 3", 3.5m, "Item3Uri");
mockCatalogItem3.SetupGet(x => x.Id).Returns(3);
var mockCatalogItem3 = new Mock<CatalogItem>(3, 3, "Item 3 description", "Item 3", 3.5m, "Item3Uri");
mockCatalogItem3.SetupGet(x => x.Id).Returns(3);
catalogItems.Add(mockCatalogItem1.Object);
catalogItems.Add(mockCatalogItem3.Object);
catalogItems.Add(mockCatalogItem1.Object);
catalogItems.Add(mockCatalogItem3.Object);
return catalogItems;
}
return catalogItems;
}
}

View File

@@ -1,66 +1,65 @@
using Microsoft.eShopWeb.ApplicationCore.Entities.OrderAggregate;
using System.Collections.Generic;
using System.Collections.Generic;
using System.Linq;
using Microsoft.eShopWeb.ApplicationCore.Entities.OrderAggregate;
using Xunit;
namespace Microsoft.eShopWeb.UnitTests.ApplicationCore.Specifications
namespace Microsoft.eShopWeb.UnitTests.ApplicationCore.Specifications;
public class CustomerOrdersWithItemsSpecification
{
public class CustomerOrdersWithItemsSpecification
private readonly string _buyerId = "TestBuyerId";
private Address _shipToAddress = new Address("Street", "City", "OH", "US", "11111");
[Fact]
public void ReturnsOrderWithOrderedItem()
{
private readonly string _buyerId = "TestBuyerId";
private Address _shipToAddress = new Address("Street", "City", "OH", "US", "11111");
var spec = new eShopWeb.ApplicationCore.Specifications.CustomerOrdersWithItemsSpecification(_buyerId);
[Fact]
public void ReturnsOrderWithOrderedItem()
{
var spec = new eShopWeb.ApplicationCore.Specifications.CustomerOrdersWithItemsSpecification(_buyerId);
var result = GetTestCollection()
.AsQueryable()
.FirstOrDefault(spec.WhereExpressions.FirstOrDefault());
var result = GetTestCollection()
.AsQueryable()
.FirstOrDefault(spec.WhereExpressions.FirstOrDefault());
Assert.NotNull(result);
Assert.NotNull(result.OrderItems);
Assert.Equal(1, result.OrderItems.Count);
Assert.NotNull(result.OrderItems.FirstOrDefault().ItemOrdered);
}
Assert.NotNull(result);
Assert.NotNull(result.OrderItems);
Assert.Equal(1, result.OrderItems.Count);
Assert.NotNull(result.OrderItems.FirstOrDefault().ItemOrdered);
}
[Fact]
public void ReturnsAllOrderWithAllOrderedItem()
{
var spec = new eShopWeb.ApplicationCore.Specifications.CustomerOrdersWithItemsSpecification(_buyerId);
[Fact]
public void ReturnsAllOrderWithAllOrderedItem()
{
var spec = new eShopWeb.ApplicationCore.Specifications.CustomerOrdersWithItemsSpecification(_buyerId);
var result = GetTestCollection()
.AsQueryable()
.Where(spec.WhereExpressions.FirstOrDefault())
.ToList();
var result = GetTestCollection()
.AsQueryable()
.Where(spec.WhereExpressions.FirstOrDefault())
.ToList();
Assert.NotNull(result);
Assert.Equal(2, result.Count);
Assert.Equal(1, result[0].OrderItems.Count);
Assert.NotNull(result[0].OrderItems.FirstOrDefault().ItemOrdered);
Assert.Equal(2, result[1].OrderItems.Count);
Assert.NotNull(result[1].OrderItems.ToList()[0].ItemOrdered);
Assert.NotNull(result[1].OrderItems.ToList()[1].ItemOrdered);
}
Assert.NotNull(result);
Assert.Equal(2, result.Count);
Assert.Equal(1, result[0].OrderItems.Count);
Assert.NotNull(result[0].OrderItems.FirstOrDefault().ItemOrdered);
Assert.Equal(2, result[1].OrderItems.Count);
Assert.NotNull(result[1].OrderItems.ToList()[0].ItemOrdered);
Assert.NotNull(result[1].OrderItems.ToList()[1].ItemOrdered);
}
public List<Order> GetTestCollection()
{
var ordersList = new List<Order>();
public List<Order> GetTestCollection()
{
var ordersList = new List<Order>();
ordersList.Add(new Order(_buyerId, _shipToAddress,
new List<OrderItem>
{
ordersList.Add(new Order(_buyerId, _shipToAddress,
new List<OrderItem>
{
new OrderItem(new CatalogItemOrdered(1, "Product1", "testurl"), 10.50m, 1)
}));
ordersList.Add(new Order(_buyerId, _shipToAddress,
new List<OrderItem>
{
}));
ordersList.Add(new Order(_buyerId, _shipToAddress,
new List<OrderItem>
{
new OrderItem(new CatalogItemOrdered(2, "Product2", "testurl"), 15.50m, 2),
new OrderItem(new CatalogItemOrdered(2, "Product3", "testurl"), 20.50m, 1)
}));
}));
return ordersList;
}
return ordersList;
}
}

View File

@@ -1,28 +1,27 @@
using Microsoft.eShopWeb.ApplicationCore.Entities.OrderAggregate;
namespace Microsoft.eShopWeb.UnitTests.Builders
{
public class AddressBuilder
{
private Address _address;
public string TestStreet => "123 Main St.";
public string TestCity => "Kent";
public string TestState => "OH";
public string TestCountry => "USA";
public string TestZipCode => "44240";
namespace Microsoft.eShopWeb.UnitTests.Builders;
public AddressBuilder()
{
_address = WithDefaultValues();
}
public Address Build()
{
return _address;
}
public Address WithDefaultValues()
{
_address = new Address(TestStreet, TestCity, TestState, TestCountry, TestZipCode);
return _address;
}
public class AddressBuilder
{
private Address _address;
public string TestStreet => "123 Main St.";
public string TestCity => "Kent";
public string TestState => "OH";
public string TestCountry => "USA";
public string TestZipCode => "44240";
public AddressBuilder()
{
_address = WithDefaultValues();
}
public Address Build()
{
return _address;
}
public Address WithDefaultValues()
{
_address = new Address(TestStreet, TestCity, TestState, TestCountry, TestZipCode);
return _address;
}
}

View File

@@ -1,40 +1,39 @@
using Microsoft.eShopWeb.ApplicationCore.Entities.BasketAggregate;
using Moq;
namespace Microsoft.eShopWeb.UnitTests.Builders
namespace Microsoft.eShopWeb.UnitTests.Builders;
public class BasketBuilder
{
public class BasketBuilder
private Basket _basket;
public string BasketBuyerId => "testbuyerId@test.com";
public int BasketId => 1;
public BasketBuilder()
{
private Basket _basket;
public string BasketBuyerId => "testbuyerId@test.com";
_basket = WithNoItems();
}
public int BasketId => 1;
public Basket Build()
{
return _basket;
}
public BasketBuilder()
{
_basket = WithNoItems();
}
public Basket WithNoItems()
{
var basketMock = new Mock<Basket>(BasketBuyerId);
basketMock.SetupGet(s => s.Id).Returns(BasketId);
public Basket Build()
{
return _basket;
}
_basket = basketMock.Object;
return _basket;
}
public Basket WithNoItems()
{
var basketMock = new Mock<Basket>(BasketBuyerId);
basketMock.SetupGet(s => s.Id).Returns(BasketId);
_basket = basketMock.Object;
return _basket;
}
public Basket WithOneBasketItem()
{
var basketMock = new Mock<Basket>(BasketBuyerId);
_basket = basketMock.Object;
_basket.AddItem(2, 3.40m, 4);
return _basket;
}
public Basket WithOneBasketItem()
{
var basketMock = new Mock<Basket>(BasketBuyerId);
_basket = basketMock.Object;
_basket.AddItem(2, 3.40m, 4);
return _basket;
}
}

View File

@@ -1,48 +1,47 @@
using Microsoft.eShopWeb.ApplicationCore.Entities.OrderAggregate;
using System.Collections.Generic;
using System.Collections.Generic;
using Microsoft.eShopWeb.ApplicationCore.Entities.OrderAggregate;
namespace Microsoft.eShopWeb.UnitTests.Builders
namespace Microsoft.eShopWeb.UnitTests.Builders;
public class OrderBuilder
{
public class OrderBuilder
private Order _order;
public string TestBuyerId => "12345";
public int TestCatalogItemId => 234;
public string TestProductName => "Test Product Name";
public string TestPictureUri => "http://test.com/image.jpg";
public decimal TestUnitPrice = 1.23m;
public int TestUnits = 3;
public CatalogItemOrdered TestCatalogItemOrdered { get; }
public OrderBuilder()
{
private Order _order;
public string TestBuyerId => "12345";
public int TestCatalogItemId => 234;
public string TestProductName => "Test Product Name";
public string TestPictureUri => "http://test.com/image.jpg";
public decimal TestUnitPrice = 1.23m;
public int TestUnits = 3;
public CatalogItemOrdered TestCatalogItemOrdered { get; }
TestCatalogItemOrdered = new CatalogItemOrdered(TestCatalogItemId, TestProductName, TestPictureUri);
_order = WithDefaultValues();
}
public OrderBuilder()
{
TestCatalogItemOrdered = new CatalogItemOrdered(TestCatalogItemId, TestProductName, TestPictureUri);
_order = WithDefaultValues();
}
public Order Build()
{
return _order;
}
public Order Build()
{
return _order;
}
public Order WithDefaultValues()
{
var orderItem = new OrderItem(TestCatalogItemOrdered, TestUnitPrice, TestUnits);
var itemList = new List<OrderItem>() { orderItem };
_order = new Order(TestBuyerId, new AddressBuilder().WithDefaultValues(), itemList);
return _order;
}
public Order WithDefaultValues()
{
var orderItem = new OrderItem(TestCatalogItemOrdered, TestUnitPrice, TestUnits);
var itemList = new List<OrderItem>() { orderItem };
_order = new Order(TestBuyerId, new AddressBuilder().WithDefaultValues(), itemList);
return _order;
}
public Order WithNoItems()
{
_order = new Order(TestBuyerId, new AddressBuilder().WithDefaultValues(), new List<OrderItem>());
return _order;
}
public Order WithNoItems()
{
_order = new Order(TestBuyerId, new AddressBuilder().WithDefaultValues(), new List<OrderItem>());
return _order;
}
public Order WithItems(List<OrderItem> items)
{
_order = new Order(TestBuyerId, new AddressBuilder().WithDefaultValues(), items);
return _order;
}
public Order WithItems(List<OrderItem> items)
{
_order = new Order(TestBuyerId, new AddressBuilder().WithDefaultValues(), items);
return _order;
}
}

View File

@@ -1,39 +1,38 @@
using Ardalis.Specification;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using Ardalis.Specification;
using Microsoft.eShopWeb.ApplicationCore.Entities.OrderAggregate;
using Microsoft.eShopWeb.ApplicationCore.Interfaces;
using Microsoft.eShopWeb.Web.Features.MyOrders;
using Moq;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using Xunit;
namespace Microsoft.eShopWeb.UnitTests.MediatorHandlers.OrdersTests
namespace Microsoft.eShopWeb.UnitTests.MediatorHandlers.OrdersTests;
public class GetMyOrders
{
public class GetMyOrders
private readonly Mock<IReadRepository<Order>> _mockOrderRepository;
public GetMyOrders()
{
private readonly Mock<IReadRepository<Order>> _mockOrderRepository;
var item = new OrderItem(new CatalogItemOrdered(1, "ProductName", "URI"), 10.00m, 10);
var address = new Address(It.IsAny<string>(), It.IsAny<string>(), It.IsAny<string>(), It.IsAny<string>(), It.IsAny<string>());
Order order = new Order("buyerId", address, new List<OrderItem> { item });
public GetMyOrders()
{
var item = new OrderItem(new CatalogItemOrdered(1, "ProductName", "URI"), 10.00m, 10);
var address = new Address(It.IsAny<string>(), It.IsAny<string>(), It.IsAny<string>(), It.IsAny<string>(), It.IsAny<string>());
Order order = new Order("buyerId", address, new List<OrderItem> { item });
_mockOrderRepository = new Mock<IReadRepository<Order>>();
_mockOrderRepository.Setup(x => x.ListAsync(It.IsAny<ISpecification<Order>>(), default)).ReturnsAsync(new List<Order> { order });
}
_mockOrderRepository = new Mock<IReadRepository<Order>>();
_mockOrderRepository.Setup(x => x.ListAsync(It.IsAny<ISpecification<Order>>(),default)).ReturnsAsync(new List<Order> { order });
}
[Fact]
public async Task NotReturnNullIfOrdersArePresIent()
{
var request = new eShopWeb.Web.Features.MyOrders.GetMyOrders("SomeUserName");
[Fact]
public async Task NotReturnNullIfOrdersArePresIent()
{
var request = new eShopWeb.Web.Features.MyOrders.GetMyOrders("SomeUserName");
var handler = new GetMyOrdersHandler(_mockOrderRepository.Object);
var handler = new GetMyOrdersHandler(_mockOrderRepository.Object);
var result = await handler.Handle(request, CancellationToken.None);
var result = await handler.Handle(request, CancellationToken.None);
Assert.NotNull(result);
}
Assert.NotNull(result);
}
}

View File

@@ -1,41 +1,40 @@
using Ardalis.Specification;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using Ardalis.Specification;
using Microsoft.eShopWeb.ApplicationCore.Entities.OrderAggregate;
using Microsoft.eShopWeb.ApplicationCore.Interfaces;
using Microsoft.eShopWeb.ApplicationCore.Specifications;
using Microsoft.eShopWeb.Web.Features.OrderDetails;
using Moq;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using Xunit;
namespace Microsoft.eShopWeb.UnitTests.MediatorHandlers.OrdersTests
namespace Microsoft.eShopWeb.UnitTests.MediatorHandlers.OrdersTests;
public class GetOrderDetails
{
public class GetOrderDetails
private readonly Mock<IReadRepository<Order>> _mockOrderRepository;
public GetOrderDetails()
{
private readonly Mock<IReadRepository<Order>> _mockOrderRepository;
var item = new OrderItem(new CatalogItemOrdered(1, "ProductName", "URI"), 10.00m, 10);
var address = new Address(It.IsAny<string>(), It.IsAny<string>(), It.IsAny<string>(), It.IsAny<string>(), It.IsAny<string>());
Order order = new Order("buyerId", address, new List<OrderItem> { item });
public GetOrderDetails()
{
var item = new OrderItem(new CatalogItemOrdered(1, "ProductName", "URI"), 10.00m, 10);
var address = new Address(It.IsAny<string>(), It.IsAny<string>(), It.IsAny<string>(), It.IsAny<string>(), It.IsAny<string>());
Order order = new Order("buyerId", address, new List<OrderItem> { item });
_mockOrderRepository = new Mock<IReadRepository<Order>>();
_mockOrderRepository.Setup(x => x.GetBySpecAsync(It.IsAny<OrderWithItemsByIdSpec>(), default))
.ReturnsAsync(order);
}
_mockOrderRepository = new Mock<IReadRepository<Order>>();
_mockOrderRepository.Setup(x => x.GetBySpecAsync(It.IsAny<OrderWithItemsByIdSpec>(),default))
.ReturnsAsync(order);
}
[Fact]
public async Task NotBeNullIfOrderExists()
{
var request = new eShopWeb.Web.Features.OrderDetails.GetOrderDetails("SomeUserName", 0);
[Fact]
public async Task NotBeNullIfOrderExists()
{
var request = new eShopWeb.Web.Features.OrderDetails.GetOrderDetails("SomeUserName", 0);
var handler = new GetOrderDetailsHandler(_mockOrderRepository.Object);
var handler = new GetOrderDetailsHandler(_mockOrderRepository.Object);
var result = await handler.Handle(request, CancellationToken.None);
var result = await handler.Handle(request, CancellationToken.None);
Assert.NotNull(result);
}
Assert.NotNull(result);
}
}

View File

@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net5.0</TargetFramework>
<TargetFramework>net6.0</TargetFramework>
<RootNamespace>Microsoft.eShopWeb.UnitTests</RootNamespace>
<IsPackable>false</IsPackable>
</PropertyGroup>

View File

@@ -1,16 +1,15 @@
using Microsoft.eShopWeb.Web.Extensions;
using Xunit;
namespace Microsoft.eShopWeb.UnitTests.Web.Extensions.CacheHelpersTests
{
public class GenerateBrandsCacheKey
{
[Fact]
public void ReturnsBrandsCacheKey()
{
var result = CacheHelpers.GenerateBrandsCacheKey();
namespace Microsoft.eShopWeb.UnitTests.Web.Extensions.CacheHelpersTests;
Assert.Equal("brands", result);
}
public class GenerateBrandsCacheKey
{
[Fact]
public void ReturnsBrandsCacheKey()
{
var result = CacheHelpers.GenerateBrandsCacheKey();
Assert.Equal("brands", result);
}
}

View File

@@ -2,20 +2,19 @@
using Microsoft.eShopWeb.Web.Extensions;
using Xunit;
namespace Microsoft.eShopWeb.UnitTests.Web.Extensions.CacheHelpersTests
namespace Microsoft.eShopWeb.UnitTests.Web.Extensions.CacheHelpersTests;
public class GenerateCatalogItemCacheKey
{
public class GenerateCatalogItemCacheKey
[Fact]
public void ReturnsCatalogItemCacheKey()
{
[Fact]
public void ReturnsCatalogItemCacheKey()
{
var pageIndex = 0;
int? brandId = null;
int? typeId = null;
var pageIndex = 0;
int? brandId = null;
int? typeId = null;
var result = CacheHelpers.GenerateCatalogItemCacheKey(pageIndex, Constants.ITEMS_PER_PAGE, brandId, typeId);
var result = CacheHelpers.GenerateCatalogItemCacheKey(pageIndex, Constants.ITEMS_PER_PAGE, brandId, typeId);
Assert.Equal("items-0-10--", result);
}
Assert.Equal("items-0-10--", result);
}
}

View File

@@ -1,16 +1,15 @@
using Microsoft.eShopWeb.Web.Extensions;
using Xunit;
namespace Microsoft.eShopWeb.UnitTests.Web.Extensions.CacheHelpersTests
{
public class GenerateTypesCacheKey
{
[Fact]
public void ReturnsTypesCacheKey()
{
var result = CacheHelpers.GenerateTypesCacheKey();
namespace Microsoft.eShopWeb.UnitTests.Web.Extensions.CacheHelpersTests;
Assert.Equal("types", result);
}
public class GenerateTypesCacheKey
{
[Fact]
public void ReturnsTypesCacheKey()
{
var result = CacheHelpers.GenerateTypesCacheKey();
Assert.Equal("types", result);
}
}