Browse Source
* Initial update endpoint working * Updated CatalogItem to support more updates; added tests * Got MediatR domain events working to check for duplicate item names * Adding reference link * Remove domain events spike code * clean up usingsmain
committed by
GitHub
13 changed files with 205 additions and 7 deletions
@ -0,0 +1,14 @@ |
|||||
|
using System; |
||||
|
|
||||
|
namespace Microsoft.eShopWeb.ApplicationCore.Exceptions |
||||
|
{ |
||||
|
public class DuplicateCatalogItemNameException : Exception |
||||
|
{ |
||||
|
public DuplicateCatalogItemNameException(string message, int duplicateItemId) : base(message) |
||||
|
{ |
||||
|
DuplicateItemId = duplicateItemId; |
||||
|
} |
||||
|
|
||||
|
public int DuplicateItemId { get; } |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,21 @@ |
|||||
|
using System.ComponentModel.DataAnnotations; |
||||
|
|
||||
|
namespace Microsoft.eShopWeb.PublicApi.CatalogItemEndpoints |
||||
|
{ |
||||
|
public class UpdateCatalogItemRequest : BaseRequest |
||||
|
{ |
||||
|
[Range(1, 10000)] |
||||
|
public int Id { get; set; } |
||||
|
[Range(1, 10000)] |
||||
|
public int CatalogBrandId { get; set; } |
||||
|
[Range(1, 10000)] |
||||
|
public int CatalogTypeId { get; set; } |
||||
|
[Required] |
||||
|
public string Description { get; set; } |
||||
|
[Required] |
||||
|
public string Name { get; set; } |
||||
|
public string PictureUri { get; set; } |
||||
|
[Range(0.01, 10000)] |
||||
|
public decimal Price { get; set; } |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,17 @@ |
|||||
|
using System; |
||||
|
|
||||
|
namespace Microsoft.eShopWeb.PublicApi.CatalogItemEndpoints |
||||
|
{ |
||||
|
public class UpdateCatalogItemResponse : BaseResponse |
||||
|
{ |
||||
|
public UpdateCatalogItemResponse(Guid correlationId) : base(correlationId) |
||||
|
{ |
||||
|
} |
||||
|
|
||||
|
public UpdateCatalogItemResponse() |
||||
|
{ |
||||
|
} |
||||
|
|
||||
|
public CatalogItemDto CatalogItem { get; set; } |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,58 @@ |
|||||
|
using Ardalis.ApiEndpoints; |
||||
|
using Microsoft.AspNetCore.Authentication.JwtBearer; |
||||
|
using Microsoft.AspNetCore.Authorization; |
||||
|
using Microsoft.AspNetCore.Mvc; |
||||
|
using Microsoft.eShopWeb.ApplicationCore.Constants; |
||||
|
using Microsoft.eShopWeb.ApplicationCore.Entities; |
||||
|
using Microsoft.eShopWeb.ApplicationCore.Exceptions; |
||||
|
using Microsoft.eShopWeb.ApplicationCore.Interfaces; |
||||
|
using Swashbuckle.AspNetCore.Annotations; |
||||
|
using System; |
||||
|
using System.Threading.Tasks; |
||||
|
|
||||
|
namespace Microsoft.eShopWeb.PublicApi.CatalogItemEndpoints |
||||
|
{ |
||||
|
[Authorize(Roles = AuthorizationConstants.Roles.ADMINISTRATORS, AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)] |
||||
|
public class Update : BaseAsyncEndpoint<UpdateCatalogItemRequest, UpdateCatalogItemResponse> |
||||
|
{ |
||||
|
private readonly IAsyncRepository<CatalogItem> _itemRepository; |
||||
|
|
||||
|
public Update(IAsyncRepository<CatalogItem> itemRepository) |
||||
|
{ |
||||
|
_itemRepository = itemRepository; |
||||
|
} |
||||
|
|
||||
|
[HttpPut("api/catalog-items")] |
||||
|
[SwaggerOperation( |
||||
|
Summary = "Updates a Catalog Item", |
||||
|
Description = "Updates a Catalog Item", |
||||
|
OperationId = "catalog-items.update", |
||||
|
Tags = new[] { "CatalogItemEndpoints" }) |
||||
|
] |
||||
|
public override async Task<ActionResult<UpdateCatalogItemResponse>> HandleAsync(UpdateCatalogItemRequest request) |
||||
|
{ |
||||
|
var response = new UpdateCatalogItemResponse(request.CorrelationId()); |
||||
|
|
||||
|
var existingItem = await _itemRepository.GetByIdAsync(request.Id); |
||||
|
|
||||
|
existingItem.UpdateDetails(request.Name, request.Description, request.Price); |
||||
|
existingItem.UpdateBrand(request.CatalogBrandId); |
||||
|
existingItem.UpdateType(request.CatalogTypeId); |
||||
|
|
||||
|
await _itemRepository.UpdateAsync(existingItem); |
||||
|
|
||||
|
var dto = new CatalogItemDto |
||||
|
{ |
||||
|
Id = existingItem.Id, |
||||
|
CatalogBrandId = existingItem.CatalogBrandId, |
||||
|
CatalogTypeId = existingItem.CatalogTypeId, |
||||
|
Description = existingItem.Description, |
||||
|
Name = existingItem.Name, |
||||
|
PictureUri = existingItem.PictureUri, |
||||
|
Price = existingItem.Price |
||||
|
}; |
||||
|
response.CatalogItem = dto; |
||||
|
return response; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,56 @@ |
|||||
|
using Xunit; |
||||
|
using Microsoft.eShopWeb.ApplicationCore.Entities; |
||||
|
using System; |
||||
|
|
||||
|
namespace Microsoft.eShopWeb.UnitTests.ApplicationCore.Entities.CatalogItemTests |
||||
|
{ |
||||
|
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() |
||||
|
{ |
||||
|
_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 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 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)); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
Loading…
Reference in new issue