mirror of
https://github.com/Shchoholiev/shopping-assistant-api.git
synced 2025-04-12 01:48:49 +00:00
Merge remote-tracking branch 'origin/feature/SA-33-api-product-search' into feature/SA-33-api-product-search
# Conflicts: # ShoppingAssistantApi.Persistance/PersistanceExtentions/DbInitialaizer.cs
This commit is contained in:
commit
e0e4d45a91
@ -20,7 +20,9 @@
|
|||||||
"kreativ-software.csharpextensions",
|
"kreativ-software.csharpextensions",
|
||||||
"ms-dotnettools.csharp",
|
"ms-dotnettools.csharp",
|
||||||
"patcx.vscode-nuget-gallery",
|
"patcx.vscode-nuget-gallery",
|
||||||
"mhutchie.git-graph"
|
"mhutchie.git-graph",
|
||||||
|
"fernandoescolar.vscode-solution-explorer",
|
||||||
|
"formulahendry.dotnet-test-explorer"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
3
.vscode/settings.json
vendored
Normal file
3
.vscode/settings.json
vendored
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
{
|
||||||
|
"editor.formatOnType": true
|
||||||
|
}
|
@ -7,11 +7,19 @@ namespace ShoppingAssistantApi.Api.Mutations;
|
|||||||
[ExtendObjectType(OperationTypeNames.Mutation)]
|
[ExtendObjectType(OperationTypeNames.Mutation)]
|
||||||
public class WishlistsMutation
|
public class WishlistsMutation
|
||||||
{
|
{
|
||||||
public Task<WishlistDto> StartPersonalWishlist(WishlistCreateDto dto, CancellationToken cancellationToken,
|
public Task<WishlistDto> StartPersonalWishlistAsync(WishlistCreateDto dto, CancellationToken cancellationToken,
|
||||||
[Service] IWishlistsService wishlistsService)
|
[Service] IWishlistsService wishlistsService)
|
||||||
=> wishlistsService.StartPersonalWishlistAsync(dto, cancellationToken);
|
=> wishlistsService.StartPersonalWishlistAsync(dto, cancellationToken);
|
||||||
|
|
||||||
public Task<MessageDto> AddMessageToPersonalWishlist(string wishlistId, MessageCreateDto dto, CancellationToken cancellationToken,
|
public Task<MessageDto> AddMessageToPersonalWishlistAsync(string wishlistId, MessageCreateDto dto, CancellationToken cancellationToken,
|
||||||
[Service] IWishlistsService wishlistsService)
|
[Service] IWishlistsService wishlistsService)
|
||||||
=> wishlistsService.AddMessageToPersonalWishlistAsync(wishlistId, dto, cancellationToken);
|
=> wishlistsService.AddMessageToPersonalWishlistAsync(wishlistId, dto, cancellationToken);
|
||||||
|
|
||||||
|
public Task<ProductDto> AddProductToPersonalWishlistAsync(string wishlistId, ProductCreateDto dto, CancellationToken cancellationToken,
|
||||||
|
[Service] IWishlistsService wishlistsService)
|
||||||
|
=> wishlistsService.AddProductToPersonalWishlistAsync(wishlistId, dto, cancellationToken);
|
||||||
|
|
||||||
|
public Task<WishlistDto> DeletePersonalWishlistAsync(string wishlistId, CancellationToken cancellationToken,
|
||||||
|
[Service] IWishlistsService wishlistsService)
|
||||||
|
=> wishlistsService.DeletePersonalWishlistAsync(wishlistId, cancellationToken);
|
||||||
}
|
}
|
||||||
|
@ -9,12 +9,22 @@ namespace ShoppingAssistantApi.Api.Queries;
|
|||||||
public class WishlistsQuery
|
public class WishlistsQuery
|
||||||
{
|
{
|
||||||
[Authorize]
|
[Authorize]
|
||||||
public Task<PagedList<WishlistDto>> GetPersonalWishlistsPageAsync(int pageNumber, int pageSize, CancellationToken cancellationToken,
|
public Task<PagedList<WishlistDto>> GetPersonalWishlistsPageAsync(int pageNumber, int pageSize,
|
||||||
[Service] IWishlistsService wishlistsService)
|
CancellationToken cancellationToken, [Service] IWishlistsService wishlistsService)
|
||||||
=> wishlistsService.GetPersonalWishlistsPageAsync(pageNumber, pageSize, cancellationToken);
|
=> wishlistsService.GetPersonalWishlistsPageAsync(pageNumber, pageSize, cancellationToken);
|
||||||
|
|
||||||
[Authorize]
|
[Authorize]
|
||||||
public Task<WishlistDto> GetPersonalWishlistAsync(string wishlistId, CancellationToken cancellationToken,
|
public Task<WishlistDto> GetPersonalWishlistAsync(string wishlistId, CancellationToken cancellationToken,
|
||||||
[Service] IWishlistsService wishlistsService)
|
[Service] IWishlistsService wishlistsService)
|
||||||
=> wishlistsService.GetPersonalWishlistAsync(wishlistId, cancellationToken);
|
=> wishlistsService.GetPersonalWishlistAsync(wishlistId, cancellationToken);
|
||||||
|
|
||||||
|
[Authorize]
|
||||||
|
public Task<PagedList<MessageDto>> GetMessagesPageFromPersonalWishlistAsync(string wishlistId, int pageNumber, int pageSize,
|
||||||
|
CancellationToken cancellationToken, [Service] IWishlistsService wishlistsService)
|
||||||
|
=> wishlistsService.GetMessagesPageFromPersonalWishlistAsync(wishlistId, pageNumber, pageSize, cancellationToken);
|
||||||
|
|
||||||
|
[Authorize]
|
||||||
|
public Task<PagedList<ProductDto>> GetProductsPageFromPersonalWishlistAsync(string wishlistId, int pageNumber, int pageSize,
|
||||||
|
CancellationToken cancellationToken, [Service] IWishlistsService wishlistsService)
|
||||||
|
=> wishlistsService.GetProductsPageFromPersonalWishlistAsync(wishlistId, pageNumber, pageSize, cancellationToken);
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,9 @@
|
|||||||
|
using System.Linq.Expressions;
|
||||||
using ShoppingAssistantApi.Domain.Entities;
|
using ShoppingAssistantApi.Domain.Entities;
|
||||||
|
|
||||||
namespace ShoppingAssistantApi.Application.IRepositories;
|
namespace ShoppingAssistantApi.Application.IRepositories;
|
||||||
|
|
||||||
public interface IMessagesRepository : IBaseRepository<Message> { }
|
public interface IMessagesRepository : IBaseRepository<Message>
|
||||||
|
{
|
||||||
|
Task<List<Message>> GetPageStartingFromEndAsync(int pageNumber, int pageSize, Expression<Func<Message, bool>> predicate, CancellationToken cancellationToken);
|
||||||
|
}
|
||||||
|
@ -0,0 +1,5 @@
|
|||||||
|
using ShoppingAssistantApi.Domain.Entities;
|
||||||
|
|
||||||
|
namespace ShoppingAssistantApi.Application.IRepositories;
|
||||||
|
|
||||||
|
public interface IProductsRepository : IBaseRepository<Product> { }
|
13
ShoppingAssistantApi.Application/IServices/IOpenAiService.cs
Normal file
13
ShoppingAssistantApi.Application/IServices/IOpenAiService.cs
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
using ShoppingAssistantApi.Application.Models.OpenAi;
|
||||||
|
|
||||||
|
namespace ShoppingAssistantApi.Application.IServices;
|
||||||
|
|
||||||
|
public interface IOpenAiService
|
||||||
|
{
|
||||||
|
Task<OpenAiMessage> GetChatCompletion(ChatCompletionRequest chat, CancellationToken cancellationToken);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Retrieves a stream of tokens (pieces of words) based on provided chat.
|
||||||
|
/// </summary>
|
||||||
|
IAsyncEnumerable<string> GetChatCompletionStream(ChatCompletionRequest chat, CancellationToken cancellationToken);
|
||||||
|
}
|
@ -13,4 +13,12 @@ public interface IWishlistsService
|
|||||||
Task<PagedList<WishlistDto>> GetPersonalWishlistsPageAsync(int pageNumber, int pageSize, CancellationToken cancellationToken);
|
Task<PagedList<WishlistDto>> GetPersonalWishlistsPageAsync(int pageNumber, int pageSize, CancellationToken cancellationToken);
|
||||||
|
|
||||||
Task<WishlistDto> GetPersonalWishlistAsync(string wishlistId, CancellationToken cancellationToken);
|
Task<WishlistDto> GetPersonalWishlistAsync(string wishlistId, CancellationToken cancellationToken);
|
||||||
|
|
||||||
|
Task<PagedList<MessageDto>> GetMessagesPageFromPersonalWishlistAsync(string wishlistId, int pageNumber, int pageSize, CancellationToken cancellationToken);
|
||||||
|
|
||||||
|
Task<ProductDto> AddProductToPersonalWishlistAsync(string wishlistId, ProductCreateDto dto, CancellationToken cancellationToken);
|
||||||
|
|
||||||
|
Task<PagedList<ProductDto>> GetProductsPageFromPersonalWishlistAsync(string wishlistId, int pageNumber, int pageSize, CancellationToken cancellationToken);
|
||||||
|
|
||||||
|
Task<WishlistDto> DeletePersonalWishlistAsync(string wishlistId, CancellationToken cancellationToken);
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,15 @@
|
|||||||
|
using AutoMapper;
|
||||||
|
using ShoppingAssistantApi.Application.Models.CreateDtos;
|
||||||
|
using ShoppingAssistantApi.Application.Models.Dtos;
|
||||||
|
using ShoppingAssistantApi.Domain.Entities;
|
||||||
|
|
||||||
|
namespace ShoppingAssistantApi.Application.MappingProfiles;
|
||||||
|
public class ProductProfile : Profile
|
||||||
|
{
|
||||||
|
public ProductProfile()
|
||||||
|
{
|
||||||
|
CreateMap<Product, ProductDto>().ReverseMap();
|
||||||
|
|
||||||
|
CreateMap<ProductCreateDto, Product>().ReverseMap();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,16 @@
|
|||||||
|
namespace ShoppingAssistantApi.Application.Models.CreateDtos;
|
||||||
|
|
||||||
|
public class ProductCreateDto
|
||||||
|
{
|
||||||
|
public required string Url { get; set; }
|
||||||
|
|
||||||
|
public required string Name { get; set; }
|
||||||
|
|
||||||
|
public required string Description { get; set; }
|
||||||
|
|
||||||
|
public required double Rating { get; set; }
|
||||||
|
|
||||||
|
public required string[] ImagesUrls { get; set; }
|
||||||
|
|
||||||
|
public required bool WasOpened { get; set; }
|
||||||
|
}
|
@ -8,5 +8,5 @@ public class MessageDto
|
|||||||
|
|
||||||
public required string Role { get; set; }
|
public required string Role { get; set; }
|
||||||
|
|
||||||
public string? CreatedById { get; set; } = null;
|
public required string CreatedById { get; set; }
|
||||||
}
|
}
|
||||||
|
20
ShoppingAssistantApi.Application/Models/Dtos/ProductDto.cs
Normal file
20
ShoppingAssistantApi.Application/Models/Dtos/ProductDto.cs
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
namespace ShoppingAssistantApi.Application.Models.Dtos;
|
||||||
|
|
||||||
|
public class ProductDto
|
||||||
|
{
|
||||||
|
public required string Id { get; set; }
|
||||||
|
|
||||||
|
public required string Url { get; set; }
|
||||||
|
|
||||||
|
public required string Name { get; set; }
|
||||||
|
|
||||||
|
public required string Description { get; set; }
|
||||||
|
|
||||||
|
public required double Rating { get; set; }
|
||||||
|
|
||||||
|
public required string[] ImagesUrls { get; set; }
|
||||||
|
|
||||||
|
public required bool WasOpened { get; set; }
|
||||||
|
|
||||||
|
public required string WishlistId { get; set; }
|
||||||
|
}
|
@ -8,5 +8,5 @@ public class WishlistDto
|
|||||||
|
|
||||||
public required string Type { get; set; }
|
public required string Type { get; set; }
|
||||||
|
|
||||||
public string CreatedById { get; set; } = null!;
|
public required string CreatedById { get; set; }
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,14 @@
|
|||||||
|
namespace ShoppingAssistantApi.Application.Models.OpenAi;
|
||||||
|
|
||||||
|
public class ChatCompletionRequest
|
||||||
|
{
|
||||||
|
public string Model { get; set; } = "gpt-3.5-turbo";
|
||||||
|
|
||||||
|
public List<OpenAiMessage> Messages { get; set; }
|
||||||
|
|
||||||
|
public double Temperature { get; set; } = 0.7;
|
||||||
|
|
||||||
|
public int MaxTokens { get; set; } = 256;
|
||||||
|
|
||||||
|
public bool Stream { get; set; } = false;
|
||||||
|
}
|
@ -0,0 +1,10 @@
|
|||||||
|
using ShoppingAssistantApi.Domain.Enums;
|
||||||
|
|
||||||
|
namespace ShoppingAssistantApi.Application.Models.OpenAi;
|
||||||
|
|
||||||
|
public class OpenAiMessage
|
||||||
|
{
|
||||||
|
public OpenAiRole Role { get; set; }
|
||||||
|
|
||||||
|
public string Content { get; set; }
|
||||||
|
}
|
@ -9,5 +9,5 @@ public class Message : EntityBase
|
|||||||
|
|
||||||
public required string Role { get; set; }
|
public required string Role { get; set; }
|
||||||
|
|
||||||
public ObjectId WishlistId { get; set; }
|
public required ObjectId WishlistId { get; set; }
|
||||||
}
|
}
|
||||||
|
@ -1,21 +1,22 @@
|
|||||||
using MongoDB.Bson;
|
using MongoDB.Bson;
|
||||||
using ShoppingAssistantApi.Domain.Common;
|
using ShoppingAssistantApi.Domain.Common;
|
||||||
|
|
||||||
namespace ShoppingAssistantApi.Domain.Entities;
|
namespace ShoppingAssistantApi.Domain.Entities;
|
||||||
|
|
||||||
public class Product : EntityBase
|
public class Product : EntityBase
|
||||||
{
|
{
|
||||||
public ObjectId WishlistId { get; set; }
|
|
||||||
|
public required string Url { get; set; }
|
||||||
public string? Url { get; set; }
|
|
||||||
|
public required string Name { get; set; }
|
||||||
public string? Name { get; set; }
|
|
||||||
|
public required string Description { get; set; }
|
||||||
public string? Description { get; set; }
|
|
||||||
|
public required double Rating { get; set; }
|
||||||
public double Rating { get; set; }
|
|
||||||
|
public required string[] ImagesUrls { get; set; }
|
||||||
public string[]? ImagesUrls { get; set; }
|
|
||||||
|
public required bool WasOpened { get; set; }
|
||||||
public bool WasOpened { get; set; }
|
|
||||||
}
|
public required ObjectId WishlistId { get; set; }
|
||||||
|
}
|
||||||
|
8
ShoppingAssistantApi.Domain/Enums/OpenAiRole.cs
Normal file
8
ShoppingAssistantApi.Domain/Enums/OpenAiRole.cs
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
namespace ShoppingAssistantApi.Domain.Enums;
|
||||||
|
|
||||||
|
public enum OpenAiRole
|
||||||
|
{
|
||||||
|
System,
|
||||||
|
User,
|
||||||
|
Assistant
|
||||||
|
}
|
@ -0,0 +1,24 @@
|
|||||||
|
using ShoppingAssistantApi.Application.IServices;
|
||||||
|
using ShoppingAssistantApi.Application.Models.OpenAi;
|
||||||
|
|
||||||
|
namespace ShoppingAssistantApi.Infrastructure.Services;
|
||||||
|
|
||||||
|
public class OpenAiService : IOpenAiService
|
||||||
|
{
|
||||||
|
private readonly HttpClient _httpClient;
|
||||||
|
|
||||||
|
public OpenAiService(HttpClient client)
|
||||||
|
{
|
||||||
|
_httpClient = client;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Task<OpenAiMessage> GetChatCompletion(ChatCompletionRequest chat, CancellationToken cancellationToken)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public IAsyncEnumerable<string> GetChatCompletionStream(ChatCompletionRequest chat, CancellationToken cancellationToken)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
}
|
@ -18,12 +18,15 @@ public class WishlistsService : IWishlistsService
|
|||||||
|
|
||||||
private readonly IMessagesRepository _messagesRepository;
|
private readonly IMessagesRepository _messagesRepository;
|
||||||
|
|
||||||
|
private readonly IProductsRepository _productsRepository;
|
||||||
|
|
||||||
private readonly IMapper _mapper;
|
private readonly IMapper _mapper;
|
||||||
|
|
||||||
public WishlistsService(IWishlistsRepository wishlistRepository, IMessagesRepository messageRepository, IMapper mapper)
|
public WishlistsService(IWishlistsRepository wishlistRepository, IMessagesRepository messageRepository, IProductsRepository productRepository, IMapper mapper)
|
||||||
{
|
{
|
||||||
_wishlistsRepository = wishlistRepository;
|
_wishlistsRepository = wishlistRepository;
|
||||||
_messagesRepository = messageRepository;
|
_messagesRepository = messageRepository;
|
||||||
|
_productsRepository = productRepository;
|
||||||
_mapper = mapper;
|
_mapper = mapper;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -47,6 +50,8 @@ public class WishlistsService : IWishlistsService
|
|||||||
{
|
{
|
||||||
Text = dto.FirstMessageText,
|
Text = dto.FirstMessageText,
|
||||||
Role = MessageRoles.User.ToString(),
|
Role = MessageRoles.User.ToString(),
|
||||||
|
CreatedById = (ObjectId) GlobalUser.Id,
|
||||||
|
CreatedDateUtc = DateTime.UtcNow,
|
||||||
WishlistId = createdWishlist.Id
|
WishlistId = createdWishlist.Id
|
||||||
};
|
};
|
||||||
var createdMessage = await _messagesRepository.AddAsync(newMessage, cancellationToken);
|
var createdMessage = await _messagesRepository.AddAsync(newMessage, cancellationToken);
|
||||||
@ -62,17 +67,13 @@ public class WishlistsService : IWishlistsService
|
|||||||
{
|
{
|
||||||
throw new InvalidDataException("Provided id is invalid.");
|
throw new InvalidDataException("Provided id is invalid.");
|
||||||
}
|
}
|
||||||
newMessage.WishlistId = wishlistObjectId;
|
|
||||||
newMessage.Role = MessageRoles.User.ToString();
|
newMessage.Role = MessageRoles.User.ToString();
|
||||||
newMessage.CreatedById = (ObjectId) GlobalUser.Id;
|
newMessage.CreatedById = (ObjectId) GlobalUser.Id;
|
||||||
newMessage.CreatedDateUtc = DateTime.UtcNow;
|
newMessage.CreatedDateUtc = DateTime.UtcNow;
|
||||||
|
newMessage.WishlistId = wishlistObjectId;
|
||||||
|
|
||||||
var relatedWishlist = await _wishlistsRepository.GetWishlistAsync(x => x.Id == wishlistObjectId && x.CreatedById == GlobalUser.Id, cancellationToken);
|
await TryGetPersonalWishlist(wishlistObjectId, cancellationToken);
|
||||||
|
|
||||||
if (relatedWishlist == null)
|
|
||||||
{
|
|
||||||
throw new UnAuthorizedException<Wishlist>();
|
|
||||||
}
|
|
||||||
|
|
||||||
var createdMessage = await _messagesRepository.AddAsync(newMessage, cancellationToken);
|
var createdMessage = await _messagesRepository.AddAsync(newMessage, cancellationToken);
|
||||||
|
|
||||||
@ -81,7 +82,7 @@ public class WishlistsService : IWishlistsService
|
|||||||
|
|
||||||
public async Task<PagedList<WishlistDto>> GetPersonalWishlistsPageAsync(int pageNumber, int pageSize, CancellationToken cancellationToken)
|
public async Task<PagedList<WishlistDto>> GetPersonalWishlistsPageAsync(int pageNumber, int pageSize, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
var entities = await _wishlistsRepository.GetPageAsync(pageNumber, pageSize, cancellationToken);
|
var entities = await _wishlistsRepository.GetPageAsync(pageNumber, pageSize, x => x.CreatedById == GlobalUser.Id, cancellationToken);
|
||||||
var dtos = _mapper.Map<List<WishlistDto>>(entities);
|
var dtos = _mapper.Map<List<WishlistDto>>(entities);
|
||||||
var count = await _wishlistsRepository.GetTotalCountAsync();
|
var count = await _wishlistsRepository.GetTotalCountAsync();
|
||||||
return new PagedList<WishlistDto>(dtos, pageNumber, pageSize, count);
|
return new PagedList<WishlistDto>(dtos, pageNumber, pageSize, count);
|
||||||
@ -93,15 +94,95 @@ public class WishlistsService : IWishlistsService
|
|||||||
{
|
{
|
||||||
throw new InvalidDataException("Provided id is invalid.");
|
throw new InvalidDataException("Provided id is invalid.");
|
||||||
}
|
}
|
||||||
var entity = await _wishlistsRepository.GetWishlistAsync(x => x.Id == wishlistObjectId && x.CreatedById == GlobalUser.Id, cancellationToken);
|
|
||||||
|
|
||||||
Console.WriteLine(" WISHLIST: " + entity.CreatedById + " " + GlobalUser.Id);
|
var entity = await TryGetPersonalWishlist(wishlistObjectId, cancellationToken);
|
||||||
|
|
||||||
if (entity == null)
|
|
||||||
{
|
|
||||||
throw new UnAuthorizedException<Wishlist>();
|
|
||||||
}
|
|
||||||
|
|
||||||
return _mapper.Map<WishlistDto>(entity);
|
return _mapper.Map<WishlistDto>(entity);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async Task<PagedList<MessageDto>> GetMessagesPageFromPersonalWishlistAsync(string wishlistId, int pageNumber, int pageSize, CancellationToken cancellationToken)
|
||||||
|
{
|
||||||
|
if (!ObjectId.TryParse(wishlistId, out var wishlistObjectId))
|
||||||
|
{
|
||||||
|
throw new InvalidDataException("Provided id is invalid.");
|
||||||
|
}
|
||||||
|
|
||||||
|
await TryGetPersonalWishlist(wishlistObjectId, cancellationToken);
|
||||||
|
|
||||||
|
var entities = await _messagesRepository.GetPageStartingFromEndAsync(pageNumber, pageSize, x => x.WishlistId == wishlistObjectId, cancellationToken);
|
||||||
|
|
||||||
|
var dtos = _mapper.Map<List<MessageDto>>(entities);
|
||||||
|
var count = await _messagesRepository.GetCountAsync(x => x.WishlistId == wishlistObjectId, cancellationToken);
|
||||||
|
return new PagedList<MessageDto>(dtos, pageNumber, pageSize, count);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<ProductDto> AddProductToPersonalWishlistAsync(string wishlistId, ProductCreateDto dto, CancellationToken cancellationToken)
|
||||||
|
{
|
||||||
|
var newProduct = _mapper.Map<Product>(dto);
|
||||||
|
|
||||||
|
if (!ObjectId.TryParse(wishlistId, out var wishlistObjectId))
|
||||||
|
{
|
||||||
|
throw new InvalidDataException("Provided id is invalid.");
|
||||||
|
}
|
||||||
|
|
||||||
|
await TryGetPersonalWishlist(wishlistObjectId, cancellationToken);
|
||||||
|
|
||||||
|
newProduct.CreatedById = (ObjectId) GlobalUser.Id;
|
||||||
|
newProduct.CreatedDateUtc = DateTime.UtcNow;
|
||||||
|
newProduct.WishlistId = wishlistObjectId;
|
||||||
|
|
||||||
|
var createdProduct = await _productsRepository.AddAsync(newProduct, cancellationToken);
|
||||||
|
|
||||||
|
return _mapper.Map<ProductDto>(createdProduct);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<PagedList<ProductDto>> GetProductsPageFromPersonalWishlistAsync(string wishlistId, int pageNumber, int pageSize, CancellationToken cancellationToken)
|
||||||
|
{
|
||||||
|
if (!ObjectId.TryParse(wishlistId, out var wishlistObjectId))
|
||||||
|
{
|
||||||
|
throw new InvalidDataException("Provided id is invalid.");
|
||||||
|
}
|
||||||
|
|
||||||
|
await TryGetPersonalWishlist(wishlistObjectId, cancellationToken);
|
||||||
|
|
||||||
|
var entities = await _productsRepository.GetPageAsync(pageNumber, pageSize, x => x.WishlistId == wishlistObjectId, cancellationToken);
|
||||||
|
|
||||||
|
var dtos = _mapper.Map<List<ProductDto>>(entities);
|
||||||
|
var count = await _productsRepository.GetCountAsync(x => x.WishlistId == wishlistObjectId, cancellationToken);
|
||||||
|
return new PagedList<ProductDto>(dtos, pageNumber, pageSize, count);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<WishlistDto> DeletePersonalWishlistAsync(string wishlistId, CancellationToken cancellationToken)
|
||||||
|
{
|
||||||
|
if (!ObjectId.TryParse(wishlistId, out var wishlistObjectId))
|
||||||
|
{
|
||||||
|
throw new InvalidDataException("Provided id is invalid.");
|
||||||
|
}
|
||||||
|
|
||||||
|
var entity = await TryGetPersonalWishlist(wishlistObjectId, cancellationToken);
|
||||||
|
|
||||||
|
entity.LastModifiedById = GlobalUser.Id;
|
||||||
|
entity.LastModifiedDateUtc = DateTime.UtcNow;
|
||||||
|
|
||||||
|
await _wishlistsRepository.DeleteAsync(entity, cancellationToken);
|
||||||
|
|
||||||
|
return _mapper.Map<WishlistDto>(entity);
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task<Wishlist> TryGetPersonalWishlist(ObjectId wishlistId, CancellationToken cancellationToken)
|
||||||
|
{
|
||||||
|
var entity = await _wishlistsRepository.GetWishlistAsync(x => x.Id == wishlistId, cancellationToken);
|
||||||
|
|
||||||
|
if (entity.CreatedById != GlobalUser.Id)
|
||||||
|
{
|
||||||
|
throw new UnAuthorizedException<Wishlist>();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (entity == null)
|
||||||
|
{
|
||||||
|
throw new EntityNotFoundException<Wishlist>();
|
||||||
|
}
|
||||||
|
|
||||||
|
return entity;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -50,7 +50,6 @@ public class DbInitialaizer
|
|||||||
await AddRoles(cancellationToken);
|
await AddRoles(cancellationToken);
|
||||||
await AddUsers(cancellationToken);
|
await AddUsers(cancellationToken);
|
||||||
await AddWishlistsWithMessages(cancellationToken);
|
await AddWishlistsWithMessages(cancellationToken);
|
||||||
await AddProducts(cancellationToken);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task AddUsers(CancellationToken cancellationToken)
|
public async Task AddUsers(CancellationToken cancellationToken)
|
||||||
|
@ -15,6 +15,7 @@ public static class RepositoriesExtention
|
|||||||
services.AddScoped<IUsersRepository, UsersRepository>();
|
services.AddScoped<IUsersRepository, UsersRepository>();
|
||||||
services.AddScoped<IWishlistsRepository, WishlistsRepository>();
|
services.AddScoped<IWishlistsRepository, WishlistsRepository>();
|
||||||
services.AddScoped<IMessagesRepository, MessagesRepository>();
|
services.AddScoped<IMessagesRepository, MessagesRepository>();
|
||||||
|
services.AddScoped<IProductsRepository, ProductsRepository>();
|
||||||
|
|
||||||
return services;
|
return services;
|
||||||
}
|
}
|
||||||
|
@ -69,4 +69,4 @@ public abstract class BaseRepository<TEntity> where TEntity : EntityBase
|
|||||||
return await this._collection.FindOneAndUpdateAsync(
|
return await this._collection.FindOneAndUpdateAsync(
|
||||||
Builders<TEntity>.Filter.Eq(e => e.Id, entity.Id), updateDefinition, options, cancellationToken);
|
Builders<TEntity>.Filter.Eq(e => e.Id, entity.Id), updateDefinition, options, cancellationToken);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
using System.Linq.Expressions;
|
||||||
|
using MongoDB.Driver;
|
||||||
using ShoppingAssistantApi.Application.IRepositories;
|
using ShoppingAssistantApi.Application.IRepositories;
|
||||||
using ShoppingAssistantApi.Domain.Entities;
|
using ShoppingAssistantApi.Domain.Entities;
|
||||||
using ShoppingAssistantApi.Persistance.Database;
|
using ShoppingAssistantApi.Persistance.Database;
|
||||||
@ -7,4 +9,13 @@ namespace ShoppingAssistantApi.Persistance.Repositories;
|
|||||||
public class MessagesRepository : BaseRepository<Message>, IMessagesRepository
|
public class MessagesRepository : BaseRepository<Message>, IMessagesRepository
|
||||||
{
|
{
|
||||||
public MessagesRepository(MongoDbContext db) : base(db, "Messages") { }
|
public MessagesRepository(MongoDbContext db) : base(db, "Messages") { }
|
||||||
|
|
||||||
|
public async Task<List<Message>> GetPageStartingFromEndAsync(int pageNumber, int pageSize, Expression<Func<Message, bool>> predicate, CancellationToken cancellationToken)
|
||||||
|
{
|
||||||
|
return await _collection.Find(predicate)
|
||||||
|
.SortByDescending(x => x.CreatedDateUtc)
|
||||||
|
.Skip((pageNumber - 1) * pageSize)
|
||||||
|
.Limit(pageSize)
|
||||||
|
.ToListAsync(cancellationToken);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,10 @@
|
|||||||
|
using ShoppingAssistantApi.Application.IRepositories;
|
||||||
|
using ShoppingAssistantApi.Domain.Entities;
|
||||||
|
using ShoppingAssistantApi.Persistance.Database;
|
||||||
|
|
||||||
|
namespace ShoppingAssistantApi.Persistance.Repositories;
|
||||||
|
|
||||||
|
public class ProductsRepository : BaseRepository<Product>, IProductsRepository
|
||||||
|
{
|
||||||
|
public ProductsRepository(MongoDbContext db) : base(db, "Products") { }
|
||||||
|
}
|
@ -17,7 +17,15 @@ public class WishlistsTests : IClassFixture<TestingFactory<Program>>
|
|||||||
|
|
||||||
private const string WISHLIST_TESTING_USER_PASSWORD = "Yuiop12345";
|
private const string WISHLIST_TESTING_USER_PASSWORD = "Yuiop12345";
|
||||||
|
|
||||||
private const string TESTING_WISHLIST_ID = "ab79cde6f69abcd3efab65cd";
|
private const string WISHLIST_TESTING_VALID_WISHLIST_ID = "ab79cde6f69abcd3efab65cd";
|
||||||
|
|
||||||
|
private const string WISHLIST_TESTING_VALID_WISHLIST_NAME = "Gaming PC";
|
||||||
|
|
||||||
|
private const WishlistTypes WISHLIST_TESTING_VALID_WISHLIST_TYPE = WishlistTypes.Product;
|
||||||
|
|
||||||
|
private const string WISHLIST_TESTING_INVALID_WISHLIST_ID = "1234567890abcdef12345678";
|
||||||
|
|
||||||
|
private const string WISHLIST_TESTING_OTHER_USER_WISHLIST_ID = "ab6c2c2d9edf39abcd1ef9ab";
|
||||||
|
|
||||||
public WishlistsTests(TestingFactory<Program> factory)
|
public WishlistsTests(TestingFactory<Program> factory)
|
||||||
{
|
{
|
||||||
@ -78,7 +86,7 @@ public class WishlistsTests : IClassFixture<TestingFactory<Program>>
|
|||||||
variables = new
|
variables = new
|
||||||
{
|
{
|
||||||
pageNumber = 1,
|
pageNumber = 1,
|
||||||
pageSize = 1
|
pageSize = 5
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -111,7 +119,7 @@ public class WishlistsTests : IClassFixture<TestingFactory<Program>>
|
|||||||
query = "query personalWishlist($wishlistId: String!) { personalWishlist(wishlistId: $wishlistId) { createdById, id, name, type } }",
|
query = "query personalWishlist($wishlistId: String!) { personalWishlist(wishlistId: $wishlistId) { createdById, id, name, type } }",
|
||||||
variables = new
|
variables = new
|
||||||
{
|
{
|
||||||
wishlistId = TESTING_WISHLIST_ID
|
wishlistId = WISHLIST_TESTING_VALID_WISHLIST_ID
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -130,9 +138,9 @@ public class WishlistsTests : IClassFixture<TestingFactory<Program>>
|
|||||||
var personalWishlistType = (string) document.data.personalWishlist.type;
|
var personalWishlistType = (string) document.data.personalWishlist.type;
|
||||||
var personalWishlistCreatedById = (string) document.data.personalWishlist.createdById;
|
var personalWishlistCreatedById = (string) document.data.personalWishlist.createdById;
|
||||||
|
|
||||||
Assert.Equal(TESTING_WISHLIST_ID, personalWishlistId);
|
Assert.Equal(WISHLIST_TESTING_VALID_WISHLIST_ID, personalWishlistId);
|
||||||
Assert.Equal("Gaming PC", personalWishlistName);
|
Assert.Equal(WISHLIST_TESTING_VALID_WISHLIST_NAME, personalWishlistName);
|
||||||
Assert.Equal(WishlistTypes.Product.ToString(), personalWishlistType);
|
Assert.Equal(WISHLIST_TESTING_VALID_WISHLIST_TYPE.ToString(), personalWishlistType);
|
||||||
Assert.Equal(user.Id, personalWishlistCreatedById);
|
Assert.Equal(user.Id, personalWishlistCreatedById);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -150,7 +158,7 @@ public class WishlistsTests : IClassFixture<TestingFactory<Program>>
|
|||||||
query = "mutation addMessageToPersonalWishlist($wishlistId: String!, $dto: MessageCreateDtoInput!) { addMessageToPersonalWishlist (wishlistId: $wishlistId, dto: $dto) { role, text, createdById } }",
|
query = "mutation addMessageToPersonalWishlist($wishlistId: String!, $dto: MessageCreateDtoInput!) { addMessageToPersonalWishlist (wishlistId: $wishlistId, dto: $dto) { role, text, createdById } }",
|
||||||
variables = new
|
variables = new
|
||||||
{
|
{
|
||||||
wishlistId = TESTING_WISHLIST_ID,
|
wishlistId = WISHLIST_TESTING_VALID_WISHLIST_ID,
|
||||||
dto = new
|
dto = new
|
||||||
{
|
{
|
||||||
text = MESSAGE_TEXT
|
text = MESSAGE_TEXT
|
||||||
@ -177,6 +185,158 @@ public class WishlistsTests : IClassFixture<TestingFactory<Program>>
|
|||||||
Assert.Equal(user.Id, messageCreatedById);
|
Assert.Equal(user.Id, messageCreatedById);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task GetMessagesPageFromPersonalWishlist_ValidPageNumberAndSizeValidWishlistIdOrAuthorizedAccess_ReturnsPage()
|
||||||
|
{
|
||||||
|
var tokensModel = await AccessExtention.Login(WISHLIST_TESTING_USER_EMAIL, WISHLIST_TESTING_USER_PASSWORD, _httpClient);
|
||||||
|
_httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", tokensModel.AccessToken);
|
||||||
|
var user = await UserExtention.GetCurrentUser(_httpClient);
|
||||||
|
|
||||||
|
var mutation = new
|
||||||
|
{
|
||||||
|
query = "query messagesPageFromPersonalWishlist($wishlistId: String!, $pageNumber: Int!, $pageSize: Int!) { messagesPageFromPersonalWishlist (wishlistId: $wishlistId, pageNumber: $pageNumber, pageSize: $pageSize) { hasNextPage, hasPreviousPage, items { id, text, role, createdById }, pageNumber, pageSize, totalItems, totalPages } }",
|
||||||
|
variables = new
|
||||||
|
{
|
||||||
|
wishlistId = WISHLIST_TESTING_VALID_WISHLIST_ID,
|
||||||
|
pageNumber = 1,
|
||||||
|
pageSize = 2
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
var jsonPayload = JsonConvert.SerializeObject(mutation);
|
||||||
|
var content = new StringContent(jsonPayload, Encoding.UTF8, "application/json");
|
||||||
|
|
||||||
|
using var response = await _httpClient.PostAsync("graphql", content);
|
||||||
|
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
||||||
|
|
||||||
|
var responseString = await response.Content.ReadAsStringAsync();
|
||||||
|
var document = JsonConvert.DeserializeObject<dynamic>(responseString);
|
||||||
|
|
||||||
|
Console.WriteLine(document);
|
||||||
|
|
||||||
|
var messagesPageFromPersonalWishlist = Enumerable.ToList(document.data.messagesPageFromPersonalWishlist.items);
|
||||||
|
var firstMessageInPage = messagesPageFromPersonalWishlist[0];
|
||||||
|
var secondMessageInPage = messagesPageFromPersonalWishlist[1];
|
||||||
|
|
||||||
|
Assert.Equal("Message 6", (string) firstMessageInPage.text);
|
||||||
|
Assert.Equal(MessageRoles.Application.ToString(), (string) firstMessageInPage.role);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task AddProductToPersonalWishlist_ValidMessageModel_ReturnsNewProductModel()
|
||||||
|
{
|
||||||
|
var tokensModel = await AccessExtention.Login(WISHLIST_TESTING_USER_EMAIL, WISHLIST_TESTING_USER_PASSWORD, _httpClient);
|
||||||
|
_httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", tokensModel.AccessToken);
|
||||||
|
var user = await UserExtention.GetCurrentUser(_httpClient);
|
||||||
|
|
||||||
|
var mutation = new
|
||||||
|
{
|
||||||
|
query = "mutation addProductToPersonalWishlist($wishlistId: String!, $dto: ProductCreateDtoInput!) { addProductToPersonalWishlist (wishlistId: $wishlistId, dto: $dto) { url, name, description, rating, imagesUrls, wasOpened } }",
|
||||||
|
variables = new
|
||||||
|
{
|
||||||
|
wishlistId = WISHLIST_TESTING_VALID_WISHLIST_ID,
|
||||||
|
dto = new
|
||||||
|
{
|
||||||
|
url = "https://www.amazon.com/url",
|
||||||
|
name = "Generic name",
|
||||||
|
description = "Generic description",
|
||||||
|
rating = 4.8,
|
||||||
|
imagesUrls = new string[]
|
||||||
|
{
|
||||||
|
"https://www.amazon.com/image-url-1",
|
||||||
|
"https://www.amazon.com/image-url-2"
|
||||||
|
},
|
||||||
|
wasOpened = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
var jsonPayload = JsonConvert.SerializeObject(mutation);
|
||||||
|
var content = new StringContent(jsonPayload, Encoding.UTF8, "application/json");
|
||||||
|
|
||||||
|
using var response = await _httpClient.PostAsync("graphql", content);
|
||||||
|
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
||||||
|
|
||||||
|
var responseString = await response.Content.ReadAsStringAsync();
|
||||||
|
var document = JsonConvert.DeserializeObject<dynamic>(responseString);
|
||||||
|
|
||||||
|
Assert.Equal("https://www.amazon.com/url", (string) document.data.addProductToPersonalWishlist.url);
|
||||||
|
Assert.Equal("Generic name", (string) document.data.addProductToPersonalWishlist.name);
|
||||||
|
Assert.Equal("Generic description", (string) document.data.addProductToPersonalWishlist.description);
|
||||||
|
Assert.Equal(4.8, (double) document.data.addProductToPersonalWishlist.rating);
|
||||||
|
Assert.Equal("https://www.amazon.com/image-url-1", (string) document.data.addProductToPersonalWishlist.imagesUrls[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task GetProductsPageFromPersonalWishlist_ValidPageNumberAndSizeValidWishlistIdOrAuthorizedAccess_ReturnsPage()
|
||||||
|
{
|
||||||
|
var tokensModel = await AccessExtention.Login(WISHLIST_TESTING_USER_EMAIL, WISHLIST_TESTING_USER_PASSWORD, _httpClient);
|
||||||
|
_httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", tokensModel.AccessToken);
|
||||||
|
var user = await UserExtention.GetCurrentUser(_httpClient);
|
||||||
|
|
||||||
|
var mutation = new
|
||||||
|
{
|
||||||
|
query = "query productsPageFromPersonalWishlist($wishlistId: String!, $pageNumber: Int!, $pageSize: Int!) { productsPageFromPersonalWishlist (wishlistId: $wishlistId, pageNumber: $pageNumber, pageSize: $pageSize) { hasNextPage, hasPreviousPage, items { id, url, name, description, rating, imagesUrls, wasOpened, wishlistId }, pageNumber, pageSize, totalItems, totalPages } }",
|
||||||
|
variables = new
|
||||||
|
{
|
||||||
|
wishlistId = WISHLIST_TESTING_VALID_WISHLIST_ID,
|
||||||
|
pageNumber = 1,
|
||||||
|
pageSize = 2
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
var jsonPayload = JsonConvert.SerializeObject(mutation);
|
||||||
|
var content = new StringContent(jsonPayload, Encoding.UTF8, "application/json");
|
||||||
|
|
||||||
|
using var response = await _httpClient.PostAsync("graphql", content);
|
||||||
|
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
||||||
|
|
||||||
|
var responseString = await response.Content.ReadAsStringAsync();
|
||||||
|
var document = JsonConvert.DeserializeObject<dynamic>(responseString);
|
||||||
|
|
||||||
|
var productsPageFromPersonalWishlist = Enumerable.ToList(document.data.productsPageFromPersonalWishlist.items);
|
||||||
|
var secondProductInPage = productsPageFromPersonalWishlist[1];
|
||||||
|
|
||||||
|
Assert.Equal("Samsung 970 EVO Plus SSD 2TB NVMe M.2 Internal Solid State Hard Drive, V-NAND Technology, Storage and Memory Expansion for Gaming, Graphics w/ Heat Control, Max Speed, MZ-V7S2T0B/AM ", (string) secondProductInPage.name);
|
||||||
|
Assert.Equal(WISHLIST_TESTING_VALID_WISHLIST_ID, (string) secondProductInPage.wishlistId);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task DeletePersonalWishlist_ValidWishlistIdOrAuthorizedAccess_ReturnsWishlistModel()
|
||||||
|
{
|
||||||
|
var tokensModel = await AccessExtention.Login(WISHLIST_TESTING_USER_EMAIL, WISHLIST_TESTING_USER_PASSWORD, _httpClient);
|
||||||
|
_httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", tokensModel.AccessToken);
|
||||||
|
var user = await UserExtention.GetCurrentUser(_httpClient);
|
||||||
|
|
||||||
|
var mutation = new
|
||||||
|
{
|
||||||
|
query = "mutation deletePersonalWishlist($wishlistId: String!) { deletePersonalWishlist (wishlistId: $wishlistId) { createdById, id, name, type } }",
|
||||||
|
variables = new
|
||||||
|
{
|
||||||
|
wishlistId = WISHLIST_TESTING_VALID_WISHLIST_ID
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
var jsonPayload = JsonConvert.SerializeObject(mutation);
|
||||||
|
var content = new StringContent(jsonPayload, Encoding.UTF8, "application/json");
|
||||||
|
|
||||||
|
using var response = await _httpClient.PostAsync("graphql", content);
|
||||||
|
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
||||||
|
|
||||||
|
var responseString = await response.Content.ReadAsStringAsync();
|
||||||
|
var document = JsonConvert.DeserializeObject<dynamic>(responseString);
|
||||||
|
|
||||||
|
var personalWishlistId = (string) document.data.deletePersonalWishlist.id;
|
||||||
|
var personalWishlistName = (string) document.data.deletePersonalWishlist.name;
|
||||||
|
var personalWishlistType = (string) document.data.deletePersonalWishlist.type;
|
||||||
|
var personalWishlistCreatedById = (string) document.data.deletePersonalWishlist.createdById;
|
||||||
|
|
||||||
|
Assert.Equal(WISHLIST_TESTING_VALID_WISHLIST_ID, personalWishlistId);
|
||||||
|
Assert.Equal(WISHLIST_TESTING_VALID_WISHLIST_NAME, personalWishlistName);
|
||||||
|
Assert.Equal(WISHLIST_TESTING_VALID_WISHLIST_TYPE.ToString(), personalWishlistType);
|
||||||
|
Assert.Equal(user.Id, personalWishlistCreatedById);
|
||||||
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public async Task StartPersonalWishlistAsync_InvalidWishlistModel_ReturnsInternalServerError()
|
public async Task StartPersonalWishlistAsync_InvalidWishlistModel_ReturnsInternalServerError()
|
||||||
{
|
{
|
||||||
@ -204,6 +364,76 @@ public class WishlistsTests : IClassFixture<TestingFactory<Program>>
|
|||||||
Assert.Equal(HttpStatusCode.InternalServerError, response.StatusCode);
|
Assert.Equal(HttpStatusCode.InternalServerError, response.StatusCode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task GetPersonalWishlistsPage_InValidPageNumber_ReturnsEmptyList()
|
||||||
|
{
|
||||||
|
var tokensModel = await AccessExtention.Login(WISHLIST_TESTING_USER_EMAIL, WISHLIST_TESTING_USER_PASSWORD, _httpClient);
|
||||||
|
_httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", tokensModel.AccessToken);
|
||||||
|
var user = await UserExtention.GetCurrentUser(_httpClient);
|
||||||
|
|
||||||
|
var query = new
|
||||||
|
{
|
||||||
|
query = "query personalWishlistsPage($pageNumber: Int!, $pageSize: Int!) { personalWishlistsPage(pageNumber: $pageNumber, pageSize: $pageSize) { items { createdById, id, name, type } } }",
|
||||||
|
variables = new
|
||||||
|
{
|
||||||
|
pageNumber = 100,
|
||||||
|
pageSize = 1
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
var jsonPayload = JsonConvert.SerializeObject(query);
|
||||||
|
var content = new StringContent(jsonPayload, Encoding.UTF8, "application/json");
|
||||||
|
|
||||||
|
using var response = await _httpClient.PostAsync("graphql", content);
|
||||||
|
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
||||||
|
|
||||||
|
var responseString = await response.Content.ReadAsStringAsync();
|
||||||
|
var document = JsonConvert.DeserializeObject<dynamic>(responseString);
|
||||||
|
|
||||||
|
Console.WriteLine(document);
|
||||||
|
|
||||||
|
var personalWishlistsPageItems = Enumerable.ToList(document.data.personalWishlistsPage.items);
|
||||||
|
|
||||||
|
Assert.Empty(personalWishlistsPageItems);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task GetPersonalWishlistsPage_InValidPageSize_ReturnsPage()
|
||||||
|
{
|
||||||
|
var tokensModel = await AccessExtention.Login(WISHLIST_TESTING_USER_EMAIL, WISHLIST_TESTING_USER_PASSWORD, _httpClient);
|
||||||
|
_httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", tokensModel.AccessToken);
|
||||||
|
var user = await UserExtention.GetCurrentUser(_httpClient);
|
||||||
|
|
||||||
|
var query = new
|
||||||
|
{
|
||||||
|
query = "query personalWishlistsPage($pageNumber: Int!, $pageSize: Int!) { personalWishlistsPage(pageNumber: $pageNumber, pageSize: $pageSize) { items { createdById, id, name, type } } }",
|
||||||
|
variables = new
|
||||||
|
{
|
||||||
|
pageNumber = 1,
|
||||||
|
pageSize = 100
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
var jsonPayload = JsonConvert.SerializeObject(query);
|
||||||
|
var content = new StringContent(jsonPayload, Encoding.UTF8, "application/json");
|
||||||
|
|
||||||
|
using var response = await _httpClient.PostAsync("graphql", content);
|
||||||
|
response.EnsureSuccessStatusCode();
|
||||||
|
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
||||||
|
|
||||||
|
var responseString = await response.Content.ReadAsStringAsync();
|
||||||
|
var document = JsonConvert.DeserializeObject<dynamic>(responseString);
|
||||||
|
|
||||||
|
Console.WriteLine(document);
|
||||||
|
|
||||||
|
|
||||||
|
var personalWishlistsPageItems = Enumerable.ToList(document.data.personalWishlistsPage.items);
|
||||||
|
var personalWishlistCreatedById = (string) personalWishlistsPageItems[0].createdById;
|
||||||
|
|
||||||
|
Assert.NotEmpty(personalWishlistsPageItems);
|
||||||
|
Assert.Equal(user.Id, personalWishlistCreatedById);
|
||||||
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public async Task GetPersonalWishlist_InvalidWishlistId_ReturnsInternalServerError()
|
public async Task GetPersonalWishlist_InvalidWishlistId_ReturnsInternalServerError()
|
||||||
{
|
{
|
||||||
@ -216,7 +446,7 @@ public class WishlistsTests : IClassFixture<TestingFactory<Program>>
|
|||||||
query = "query personalWishlist($wishlistId: String!) { personalWishlist(wishlistId: $wishlistId) { createdById, id, name, type } }",
|
query = "query personalWishlist($wishlistId: String!) { personalWishlist(wishlistId: $wishlistId) { createdById, id, name, type } }",
|
||||||
variables = new
|
variables = new
|
||||||
{
|
{
|
||||||
wishlistId = "1234567890abcdef12345678" // Invalid wishlistId
|
wishlistId = WISHLIST_TESTING_INVALID_WISHLIST_ID
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -239,7 +469,7 @@ public class WishlistsTests : IClassFixture<TestingFactory<Program>>
|
|||||||
query = "query personalWishlist($wishlistId: String!) { personalWishlist(wishlistId: $wishlistId) { createdById, id, name, type } }",
|
query = "query personalWishlist($wishlistId: String!) { personalWishlist(wishlistId: $wishlistId) { createdById, id, name, type } }",
|
||||||
variables = new
|
variables = new
|
||||||
{
|
{
|
||||||
wishlistId = "ab6c2c2d9edf39abcd1ef9ab" // Other user's wishlist
|
wishlistId = WISHLIST_TESTING_OTHER_USER_WISHLIST_ID
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -251,7 +481,7 @@ public class WishlistsTests : IClassFixture<TestingFactory<Program>>
|
|||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public async Task AddMessageToPersonalWishlist_InvalidMessageModel_ReturnsInternalServerError()
|
public async Task AddMessageToPersonalWishlist_InvalidWishlistId_ReturnsInternalServerError()
|
||||||
{
|
{
|
||||||
var tokensModel = await AccessExtention.Login(WISHLIST_TESTING_USER_EMAIL, WISHLIST_TESTING_USER_PASSWORD, _httpClient);
|
var tokensModel = await AccessExtention.Login(WISHLIST_TESTING_USER_EMAIL, WISHLIST_TESTING_USER_PASSWORD, _httpClient);
|
||||||
_httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", tokensModel.AccessToken);
|
_httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", tokensModel.AccessToken);
|
||||||
@ -264,7 +494,7 @@ public class WishlistsTests : IClassFixture<TestingFactory<Program>>
|
|||||||
query = "mutation addMessageToPersonalWishlist($wishlistId: String!, $dto: MessageCreateDtoInput!) { addMessageToPersonalWishlist (wishlistId: $wishlistId, dto: $dto) { role, text, createdById } }",
|
query = "mutation addMessageToPersonalWishlist($wishlistId: String!, $dto: MessageCreateDtoInput!) { addMessageToPersonalWishlist (wishlistId: $wishlistId, dto: $dto) { role, text, createdById } }",
|
||||||
variables = new
|
variables = new
|
||||||
{
|
{
|
||||||
wishlistId = "8125jad7g12", // Invalid wishlistId
|
wishlistId = WISHLIST_TESTING_INVALID_WISHLIST_ID,
|
||||||
dto = new
|
dto = new
|
||||||
{
|
{
|
||||||
text = MESSAGE_TEXT,
|
text = MESSAGE_TEXT,
|
||||||
@ -278,4 +508,383 @@ public class WishlistsTests : IClassFixture<TestingFactory<Program>>
|
|||||||
using var response = await _httpClient.PostAsync("graphql", content);
|
using var response = await _httpClient.PostAsync("graphql", content);
|
||||||
Assert.Equal(HttpStatusCode.InternalServerError, response.StatusCode);
|
Assert.Equal(HttpStatusCode.InternalServerError, response.StatusCode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task AddMessageToPersonalWishlist_UnAuthorizedAccess_ReturnsInternalServerError()
|
||||||
|
{
|
||||||
|
var tokensModel = await AccessExtention.Login(WISHLIST_TESTING_USER_EMAIL, WISHLIST_TESTING_USER_PASSWORD, _httpClient);
|
||||||
|
_httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", tokensModel.AccessToken);
|
||||||
|
var user = await UserExtention.GetCurrentUser(_httpClient);
|
||||||
|
|
||||||
|
const string MESSAGE_TEXT = "Second Message";
|
||||||
|
|
||||||
|
var mutation = new
|
||||||
|
{
|
||||||
|
query = "mutation addMessageToPersonalWishlist($wishlistId: String!, $dto: MessageCreateDtoInput!) { addMessageToPersonalWishlist (wishlistId: $wishlistId, dto: $dto) { role, text, createdById } }",
|
||||||
|
variables = new
|
||||||
|
{
|
||||||
|
wishlistId = WISHLIST_TESTING_OTHER_USER_WISHLIST_ID,
|
||||||
|
dto = new
|
||||||
|
{
|
||||||
|
text = MESSAGE_TEXT,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
var jsonPayload = JsonConvert.SerializeObject(mutation);
|
||||||
|
var content = new StringContent(jsonPayload, Encoding.UTF8, "application/json");
|
||||||
|
|
||||||
|
using var response = await _httpClient.PostAsync("graphql", content);
|
||||||
|
Assert.Equal(HttpStatusCode.InternalServerError, response.StatusCode);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task GetMessagesPageFromPersonalWishlist_InValidPageNumber_ReturnsEmptyList()
|
||||||
|
{
|
||||||
|
var tokensModel = await AccessExtention.Login(WISHLIST_TESTING_USER_EMAIL, WISHLIST_TESTING_USER_PASSWORD, _httpClient);
|
||||||
|
_httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", tokensModel.AccessToken);
|
||||||
|
var user = await UserExtention.GetCurrentUser(_httpClient);
|
||||||
|
|
||||||
|
var mutation = new
|
||||||
|
{
|
||||||
|
query = "query messagesPageFromPersonalWishlist($wishlistId: String!, $pageNumber: Int!, $pageSize: Int!) { messagesPageFromPersonalWishlist (wishlistId: $wishlistId, pageNumber: $pageNumber, pageSize: $pageSize) { hasNextPage, hasPreviousPage, items { id, text, role, createdById }, pageNumber, pageSize, totalItems, totalPages } }",
|
||||||
|
variables = new
|
||||||
|
{
|
||||||
|
wishlistId = WISHLIST_TESTING_VALID_WISHLIST_ID,
|
||||||
|
pageNumber = 4,
|
||||||
|
pageSize = 2
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
var jsonPayload = JsonConvert.SerializeObject(mutation);
|
||||||
|
var content = new StringContent(jsonPayload, Encoding.UTF8, "application/json");
|
||||||
|
|
||||||
|
using var response = await _httpClient.PostAsync("graphql", content);
|
||||||
|
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
||||||
|
|
||||||
|
var responseString = await response.Content.ReadAsStringAsync();
|
||||||
|
var document = JsonConvert.DeserializeObject<dynamic>(responseString);
|
||||||
|
|
||||||
|
Console.WriteLine(document);
|
||||||
|
|
||||||
|
|
||||||
|
var messagesPageFromPersonalWishlistItems = Enumerable.ToList(document.data.messagesPageFromPersonalWishlist.items);
|
||||||
|
|
||||||
|
Assert.Empty(messagesPageFromPersonalWishlistItems);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task GetMessagesPageFromPersonalWishlist_InValidPageSize_ReturnsPage()
|
||||||
|
{
|
||||||
|
var tokensModel = await AccessExtention.Login(WISHLIST_TESTING_USER_EMAIL, WISHLIST_TESTING_USER_PASSWORD, _httpClient);
|
||||||
|
_httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", tokensModel.AccessToken);
|
||||||
|
var user = await UserExtention.GetCurrentUser(_httpClient);
|
||||||
|
|
||||||
|
var mutation = new
|
||||||
|
{
|
||||||
|
query = "query messagesPageFromPersonalWishlist($wishlistId: String!, $pageNumber: Int!, $pageSize: Int!) { messagesPageFromPersonalWishlist (wishlistId: $wishlistId, pageNumber: $pageNumber, pageSize: $pageSize) { hasNextPage, hasPreviousPage, items { id, text, role, createdById }, pageNumber, pageSize, totalItems, totalPages } }",
|
||||||
|
variables = new
|
||||||
|
{
|
||||||
|
wishlistId = WISHLIST_TESTING_VALID_WISHLIST_ID,
|
||||||
|
pageNumber = 1,
|
||||||
|
pageSize = 10
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
var jsonPayload = JsonConvert.SerializeObject(mutation);
|
||||||
|
var content = new StringContent(jsonPayload, Encoding.UTF8, "application/json");
|
||||||
|
|
||||||
|
using var response = await _httpClient.PostAsync("graphql", content);
|
||||||
|
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
||||||
|
|
||||||
|
var responseString = await response.Content.ReadAsStringAsync();
|
||||||
|
var document = JsonConvert.DeserializeObject<dynamic>(responseString);
|
||||||
|
|
||||||
|
Console.WriteLine(document);
|
||||||
|
|
||||||
|
|
||||||
|
var messagesPageFromPersonalWishlist = Enumerable.ToList(document.data.messagesPageFromPersonalWishlist.items);
|
||||||
|
var firstMessageInPage = messagesPageFromPersonalWishlist[0];
|
||||||
|
var secondMessageInPage = messagesPageFromPersonalWishlist[1];
|
||||||
|
|
||||||
|
Assert.Equal("Message 6", (string) firstMessageInPage.text);
|
||||||
|
Assert.Equal(MessageRoles.Application.ToString(), (string) firstMessageInPage.role);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task GetMessagesPageFromPersonalWishlist_InValidWishlistId_ReturnsInternalServerError()
|
||||||
|
{
|
||||||
|
var tokensModel = await AccessExtention.Login(WISHLIST_TESTING_USER_EMAIL, WISHLIST_TESTING_USER_PASSWORD, _httpClient);
|
||||||
|
_httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", tokensModel.AccessToken);
|
||||||
|
var user = await UserExtention.GetCurrentUser(_httpClient);
|
||||||
|
|
||||||
|
var mutation = new
|
||||||
|
{
|
||||||
|
query = "query messagesPageFromPersonalWishlist($wishlistId: String!, $pageNumber: Int!, $pageSize: Int!) { messagesPageFromPersonalWishlist (wishlistId: $wishlistId, pageNumber: $pageNumber, pageSize: $pageSize) { hasNextPage, hasPreviousPage, items { id, text, role, createdById }, pageNumber, pageSize, totalItems, totalPages } }",
|
||||||
|
variables = new
|
||||||
|
{
|
||||||
|
wishlistId = WISHLIST_TESTING_INVALID_WISHLIST_ID,
|
||||||
|
pageNumber = 1,
|
||||||
|
pageSize = 2
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
var jsonPayload = JsonConvert.SerializeObject(mutation);
|
||||||
|
var content = new StringContent(jsonPayload, Encoding.UTF8, "application/json");
|
||||||
|
|
||||||
|
using var response = await _httpClient.PostAsync("graphql", content);
|
||||||
|
Assert.Equal(HttpStatusCode.InternalServerError, response.StatusCode);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task GetMessagesPageFromPersonalWishlist_UnAuthorizedAccess_ReturnsInternalServerError()
|
||||||
|
{
|
||||||
|
var tokensModel = await AccessExtention.Login(WISHLIST_TESTING_USER_EMAIL, WISHLIST_TESTING_USER_PASSWORD, _httpClient);
|
||||||
|
_httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", tokensModel.AccessToken);
|
||||||
|
var user = await UserExtention.GetCurrentUser(_httpClient);
|
||||||
|
|
||||||
|
var mutation = new
|
||||||
|
{
|
||||||
|
query = "query messagesPageFromPersonalWishlist($wishlistId: String!, $pageNumber: Int!, $pageSize: Int!) { messagesPageFromPersonalWishlist (wishlistId: $wishlistId, pageNumber: $pageNumber, pageSize: $pageSize) { hasNextPage, hasPreviousPage, items { id, text, role, createdById }, pageNumber, pageSize, totalItems, totalPages } }",
|
||||||
|
variables = new
|
||||||
|
{
|
||||||
|
wishlistId = WISHLIST_TESTING_OTHER_USER_WISHLIST_ID,
|
||||||
|
pageNumber = 1,
|
||||||
|
pageSize = 2
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
var jsonPayload = JsonConvert.SerializeObject(mutation);
|
||||||
|
var content = new StringContent(jsonPayload, Encoding.UTF8, "application/json");
|
||||||
|
|
||||||
|
using var response = await _httpClient.PostAsync("graphql", content);
|
||||||
|
Assert.Equal(HttpStatusCode.InternalServerError, response.StatusCode);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task AddProductToPersonalWishlist_InValidWishlistId_RturnsInternalServerError()
|
||||||
|
{
|
||||||
|
var tokensModel = await AccessExtention.Login(WISHLIST_TESTING_USER_EMAIL, WISHLIST_TESTING_USER_PASSWORD, _httpClient);
|
||||||
|
_httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", tokensModel.AccessToken);
|
||||||
|
var user = await UserExtention.GetCurrentUser(_httpClient);
|
||||||
|
|
||||||
|
var mutation = new
|
||||||
|
{
|
||||||
|
query = "mutation addProductToPersonalWishlist($wishlistId: String!, $dto: ProductCreateDtoInput!) { addProductToPersonalWishlist (wishlistId: $wishlistId, dto: $dto) { url, name, description, rating, imagesUrls, wasOpened } }",
|
||||||
|
variables = new
|
||||||
|
{
|
||||||
|
wishlistId = WISHLIST_TESTING_INVALID_WISHLIST_ID,
|
||||||
|
dto = new
|
||||||
|
{
|
||||||
|
url = "https://www.amazon.com/url",
|
||||||
|
name = "Generic name",
|
||||||
|
description = "Generic description",
|
||||||
|
rating = 4.8,
|
||||||
|
imagesUrls = new string[]
|
||||||
|
{
|
||||||
|
"https://www.amazon.com/image-url-1",
|
||||||
|
"https://www.amazon.com/image-url-2"
|
||||||
|
},
|
||||||
|
wasOpened = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
var jsonPayload = JsonConvert.SerializeObject(mutation);
|
||||||
|
var content = new StringContent(jsonPayload, Encoding.UTF8, "application/json");
|
||||||
|
|
||||||
|
using var response = await _httpClient.PostAsync("graphql", content);
|
||||||
|
Assert.Equal(HttpStatusCode.InternalServerError, response.StatusCode);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task AddProductToPersonalWishlist_UnAuthorizedAccess_RturnsInternalServerError()
|
||||||
|
{
|
||||||
|
var tokensModel = await AccessExtention.Login(WISHLIST_TESTING_USER_EMAIL, WISHLIST_TESTING_USER_PASSWORD, _httpClient);
|
||||||
|
_httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", tokensModel.AccessToken);
|
||||||
|
var user = await UserExtention.GetCurrentUser(_httpClient);
|
||||||
|
|
||||||
|
var mutation = new
|
||||||
|
{
|
||||||
|
query = "mutation addProductToPersonalWishlist($wishlistId: String!, $dto: ProductCreateDtoInput!) { addProductToPersonalWishlist (wishlistId: $wishlistId, dto: $dto) { url, name, description, rating, imagesUrls, wasOpened } }",
|
||||||
|
variables = new
|
||||||
|
{
|
||||||
|
wishlistId = WISHLIST_TESTING_OTHER_USER_WISHLIST_ID,
|
||||||
|
dto = new
|
||||||
|
{
|
||||||
|
url = "https://www.amazon.com/url",
|
||||||
|
name = "Generic name",
|
||||||
|
description = "Generic description",
|
||||||
|
rating = 4.8,
|
||||||
|
imagesUrls = new string[]
|
||||||
|
{
|
||||||
|
"https://www.amazon.com/image-url-1",
|
||||||
|
"https://www.amazon.com/image-url-2"
|
||||||
|
},
|
||||||
|
wasOpened = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
var jsonPayload = JsonConvert.SerializeObject(mutation);
|
||||||
|
var content = new StringContent(jsonPayload, Encoding.UTF8, "application/json");
|
||||||
|
|
||||||
|
using var response = await _httpClient.PostAsync("graphql", content);
|
||||||
|
Assert.Equal(HttpStatusCode.InternalServerError, response.StatusCode);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task GetProductsPageFromPersonalWishlist_InValidPageNumber_ReturnsInternalServerError()
|
||||||
|
{
|
||||||
|
var tokensModel = await AccessExtention.Login(WISHLIST_TESTING_USER_EMAIL, WISHLIST_TESTING_USER_PASSWORD, _httpClient);
|
||||||
|
_httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", tokensModel.AccessToken);
|
||||||
|
var user = await UserExtention.GetCurrentUser(_httpClient);
|
||||||
|
|
||||||
|
var mutation = new
|
||||||
|
{
|
||||||
|
query = "query productsPageFromPersonalWishlist($wishlistId: String!, $pageNumber: Int!, $pageSize: Int!) { productsPageFromPersonalWishlist (wishlistId: $wishlistId, pageNumber: $pageNumber, pageSize: $pageSize) { hasNextPage, hasPreviousPage, items { id, url, name, description, rating, imagesUrls, wasOpened, wishlistId }, pageNumber, pageSize, totalItems, totalPages } }",
|
||||||
|
variables = new
|
||||||
|
{
|
||||||
|
wishlistId = WISHLIST_TESTING_VALID_WISHLIST_ID,
|
||||||
|
pageNumber = 0,
|
||||||
|
pageSize = 2
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
var jsonPayload = JsonConvert.SerializeObject(mutation);
|
||||||
|
var content = new StringContent(jsonPayload, Encoding.UTF8, "application/json");
|
||||||
|
|
||||||
|
using var response = await _httpClient.PostAsync("graphql", content);
|
||||||
|
Assert.Equal(HttpStatusCode.InternalServerError, response.StatusCode);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task GetProductsPageFromPersonalWishlist_InValidPageSize_ReturnsPage()
|
||||||
|
{
|
||||||
|
var tokensModel = await AccessExtention.Login(WISHLIST_TESTING_USER_EMAIL, WISHLIST_TESTING_USER_PASSWORD, _httpClient);
|
||||||
|
_httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", tokensModel.AccessToken);
|
||||||
|
var user = await UserExtention.GetCurrentUser(_httpClient);
|
||||||
|
|
||||||
|
var mutation = new
|
||||||
|
{
|
||||||
|
query = "query productsPageFromPersonalWishlist($wishlistId: String!, $pageNumber: Int!, $pageSize: Int!) { productsPageFromPersonalWishlist (wishlistId: $wishlistId, pageNumber: $pageNumber, pageSize: $pageSize) { hasNextPage, hasPreviousPage, items { id, url, name, description, rating, imagesUrls, wasOpened, wishlistId }, pageNumber, pageSize, totalItems, totalPages } }",
|
||||||
|
variables = new
|
||||||
|
{
|
||||||
|
wishlistId = WISHLIST_TESTING_VALID_WISHLIST_ID,
|
||||||
|
pageNumber = 1,
|
||||||
|
pageSize = 100
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
var jsonPayload = JsonConvert.SerializeObject(mutation);
|
||||||
|
var content = new StringContent(jsonPayload, Encoding.UTF8, "application/json");
|
||||||
|
|
||||||
|
using var response = await _httpClient.PostAsync("graphql", content);
|
||||||
|
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
||||||
|
|
||||||
|
var responseString = await response.Content.ReadAsStringAsync();
|
||||||
|
var document = JsonConvert.DeserializeObject<dynamic>(responseString);
|
||||||
|
|
||||||
|
var productsPageFromPersonalWishlist = Enumerable.ToList(document.data.productsPageFromPersonalWishlist.items);
|
||||||
|
var secondProductInPage = productsPageFromPersonalWishlist[1];
|
||||||
|
|
||||||
|
Assert.Equal("Samsung 970 EVO Plus SSD 2TB NVMe M.2 Internal Solid State Hard Drive, V-NAND Technology, Storage and Memory Expansion for Gaming, Graphics w/ Heat Control, Max Speed, MZ-V7S2T0B/AM ", (string) secondProductInPage.name);
|
||||||
|
Assert.Equal(WISHLIST_TESTING_VALID_WISHLIST_ID, (string) secondProductInPage.wishlistId);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task GetProductsPageFromPersonalWishlist_InValidWishlistId_ReturnsInternalServerError()
|
||||||
|
{
|
||||||
|
var tokensModel = await AccessExtention.Login(WISHLIST_TESTING_USER_EMAIL, WISHLIST_TESTING_USER_PASSWORD, _httpClient);
|
||||||
|
_httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", tokensModel.AccessToken);
|
||||||
|
var user = await UserExtention.GetCurrentUser(_httpClient);
|
||||||
|
|
||||||
|
var mutation = new
|
||||||
|
{
|
||||||
|
query = "query productsPageFromPersonalWishlist($wishlistId: String!, $pageNumber: Int!, $pageSize: Int!) { productsPageFromPersonalWishlist (wishlistId: $wishlistId, pageNumber: $pageNumber, pageSize: $pageSize) { hasNextPage, hasPreviousPage, items { id, url, name, description, rating, imagesUrls, wasOpened, wishlistId }, pageNumber, pageSize, totalItems, totalPages } }",
|
||||||
|
variables = new
|
||||||
|
{
|
||||||
|
wishlistId = WISHLIST_TESTING_INVALID_WISHLIST_ID,
|
||||||
|
pageNumber = 0,
|
||||||
|
pageSize = 2
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
var jsonPayload = JsonConvert.SerializeObject(mutation);
|
||||||
|
var content = new StringContent(jsonPayload, Encoding.UTF8, "application/json");
|
||||||
|
|
||||||
|
using var response = await _httpClient.PostAsync("graphql", content);
|
||||||
|
Assert.Equal(HttpStatusCode.InternalServerError, response.StatusCode);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task GetProductsPageFromPersonalWishlist_UnAuthorizedAccess_ReturnsInternalServerError()
|
||||||
|
{
|
||||||
|
var tokensModel = await AccessExtention.Login(WISHLIST_TESTING_USER_EMAIL, WISHLIST_TESTING_USER_PASSWORD, _httpClient);
|
||||||
|
_httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", tokensModel.AccessToken);
|
||||||
|
var user = await UserExtention.GetCurrentUser(_httpClient);
|
||||||
|
|
||||||
|
var mutation = new
|
||||||
|
{
|
||||||
|
query = "query productsPageFromPersonalWishlist($wishlistId: String!, $pageNumber: Int!, $pageSize: Int!) { productsPageFromPersonalWishlist (wishlistId: $wishlistId, pageNumber: $pageNumber, pageSize: $pageSize) { hasNextPage, hasPreviousPage, items { id, url, name, description, rating, imagesUrls, wasOpened, wishlistId }, pageNumber, pageSize, totalItems, totalPages } }",
|
||||||
|
variables = new
|
||||||
|
{
|
||||||
|
wishlistId = WISHLIST_TESTING_OTHER_USER_WISHLIST_ID,
|
||||||
|
pageNumber = 0,
|
||||||
|
pageSize = 2
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
var jsonPayload = JsonConvert.SerializeObject(mutation);
|
||||||
|
var content = new StringContent(jsonPayload, Encoding.UTF8, "application/json");
|
||||||
|
|
||||||
|
using var response = await _httpClient.PostAsync("graphql", content);
|
||||||
|
Assert.Equal(HttpStatusCode.InternalServerError, response.StatusCode);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task DeletePersonalWishlist_InValidWishlistId_ReturnsInternalServerError()
|
||||||
|
{
|
||||||
|
var tokensModel = await AccessExtention.Login(WISHLIST_TESTING_USER_EMAIL, WISHLIST_TESTING_USER_PASSWORD, _httpClient);
|
||||||
|
_httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", tokensModel.AccessToken);
|
||||||
|
var user = await UserExtention.GetCurrentUser(_httpClient);
|
||||||
|
|
||||||
|
var mutation = new
|
||||||
|
{
|
||||||
|
query = "mutation deletePersonalWishlist($wishlistId: String!) { deletePersonalWishlist (wishlistId: $wishlistId) { createdById, id, name, type } }",
|
||||||
|
variables = new
|
||||||
|
{
|
||||||
|
wishlistId = WISHLIST_TESTING_INVALID_WISHLIST_ID
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
var jsonPayload = JsonConvert.SerializeObject(mutation);
|
||||||
|
var content = new StringContent(jsonPayload, Encoding.UTF8, "application/json");
|
||||||
|
|
||||||
|
using var response = await _httpClient.PostAsync("graphql", content);
|
||||||
|
Assert.Equal(HttpStatusCode.InternalServerError, response.StatusCode);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task DeletePersonalWishlist_UnAuthorizedAccess_ReturnsInternalServerError()
|
||||||
|
{
|
||||||
|
var tokensModel = await AccessExtention.Login(WISHLIST_TESTING_USER_EMAIL, WISHLIST_TESTING_USER_PASSWORD, _httpClient);
|
||||||
|
_httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", tokensModel.AccessToken);
|
||||||
|
var user = await UserExtention.GetCurrentUser(_httpClient);
|
||||||
|
|
||||||
|
var mutation = new
|
||||||
|
{
|
||||||
|
query = "mutation deletePersonalWishlist($wishlistId: String!) { deletePersonalWishlist (wishlistId: $wishlistId) { createdById, id, name, type } }",
|
||||||
|
variables = new
|
||||||
|
{
|
||||||
|
wishlistId = WISHLIST_TESTING_OTHER_USER_WISHLIST_ID
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
var jsonPayload = JsonConvert.SerializeObject(mutation);
|
||||||
|
var content = new StringContent(jsonPayload, Encoding.UTF8, "application/json");
|
||||||
|
|
||||||
|
using var response = await _httpClient.PostAsync("graphql", content);
|
||||||
|
Assert.Equal(HttpStatusCode.InternalServerError, response.StatusCode);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
1
ShoppingAssistantApi.UnitTests/GlobalUsings.cs
Normal file
1
ShoppingAssistantApi.UnitTests/GlobalUsings.cs
Normal file
@ -0,0 +1 @@
|
|||||||
|
global using Xunit;
|
@ -0,0 +1,31 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<TargetFramework>net7.0</TargetFramework>
|
||||||
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
|
<Nullable>enable</Nullable>
|
||||||
|
|
||||||
|
<IsPackable>false</IsPackable>
|
||||||
|
<IsTestProject>true</IsTestProject>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.7.1" />
|
||||||
|
<PackageReference Include="Moq" Version="4.20.69" />
|
||||||
|
<PackageReference Include="xunit" Version="2.4.2" />
|
||||||
|
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.5">
|
||||||
|
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||||
|
<PrivateAssets>all</PrivateAssets>
|
||||||
|
</PackageReference>
|
||||||
|
<PackageReference Include="coverlet.collector" Version="3.2.0">
|
||||||
|
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||||
|
<PrivateAssets>all</PrivateAssets>
|
||||||
|
</PackageReference>
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\ShoppingAssistantApi.Infrastructure\ShoppingAssistantApi.Infrastructure.csproj" />
|
||||||
|
<ProjectReference Include="..\ShoppingAssistantApi.Application\ShoppingAssistantApi.Application.csproj" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
</Project>
|
@ -15,6 +15,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ShoppingAssistantApi.Api",
|
|||||||
EndProject
|
EndProject
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ShoppingAssistantApi.Tests", "ShoppingAssistantApi.Tests\ShoppingAssistantApi.Tests.csproj", "{297B5378-79D7-406C-80A5-151C6B3EA147}"
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ShoppingAssistantApi.Tests", "ShoppingAssistantApi.Tests\ShoppingAssistantApi.Tests.csproj", "{297B5378-79D7-406C-80A5-151C6B3EA147}"
|
||||||
EndProject
|
EndProject
|
||||||
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ShoppingAssistantApi.UnitTests", "ShoppingAssistantApi.UnitTests\ShoppingAssistantApi.UnitTests.csproj", "{B4EFE8F1-89F5-44E4-BD0A-4F63D09C8E6F}"
|
||||||
|
EndProject
|
||||||
Global
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
Debug|Any CPU = Debug|Any CPU
|
Debug|Any CPU = Debug|Any CPU
|
||||||
@ -45,6 +47,10 @@ Global
|
|||||||
{297B5378-79D7-406C-80A5-151C6B3EA147}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{297B5378-79D7-406C-80A5-151C6B3EA147}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
{297B5378-79D7-406C-80A5-151C6B3EA147}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{297B5378-79D7-406C-80A5-151C6B3EA147}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{297B5378-79D7-406C-80A5-151C6B3EA147}.Release|Any CPU.Build.0 = Release|Any CPU
|
{297B5378-79D7-406C-80A5-151C6B3EA147}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{B4EFE8F1-89F5-44E4-BD0A-4F63D09C8E6F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{B4EFE8F1-89F5-44E4-BD0A-4F63D09C8E6F}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{B4EFE8F1-89F5-44E4-BD0A-4F63D09C8E6F}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{B4EFE8F1-89F5-44E4-BD0A-4F63D09C8E6F}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(SolutionProperties) = preSolution
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
HideSolutionNode = FALSE
|
HideSolutionNode = FALSE
|
||||||
|
Loading…
Reference in New Issue
Block a user