Merge pull request #16 from Shchoholiev/SA-149-Fix-StartPersonalWishlistAsync

SA-149 all issues are fixed
This commit is contained in:
Mykhailo Bilodid 2023-11-15 16:58:04 +02:00 committed by GitHub
commit 49837d4f18
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 67 additions and 24 deletions

View File

@ -3,6 +3,8 @@ using Microsoft.AspNetCore.Mvc;
using Newtonsoft.Json; using Newtonsoft.Json;
using ShoppingAssistantApi.Application.IServices; using ShoppingAssistantApi.Application.IServices;
using ShoppingAssistantApi.Application.Models.CreateDtos; using ShoppingAssistantApi.Application.Models.CreateDtos;
using ShoppingAssistantApi.Application.Models.Dtos;
using ShoppingAssistantApi.Domain.Enums;
namespace ShoppingAssistantApi.Api.Controllers; namespace ShoppingAssistantApi.Api.Controllers;
@ -11,14 +13,24 @@ public class ProductsSearchController : BaseController
{ {
private readonly IProductService _productService; private readonly IProductService _productService;
public ProductsSearchController(IProductService productService) private readonly IWishlistsService _wishlistsService;
public ProductsSearchController(IProductService productService, IWishlistsService wishlistsService)
{ {
_productService = productService; _productService = productService;
_wishlistsService = wishlistsService;
} }
[HttpPost("search/{wishlistId}")] [HttpPost("search/{wishlistId}")]
public async Task StreamDataToClient(string wishlistId, [FromBody]MessageCreateDto message, CancellationToken cancellationToken) public async Task StreamDataToClient(string wishlistId, [FromBody]MessageCreateDto message, CancellationToken cancellationToken)
{ {
var dto = new MessageDto()
{
Text = message.Text,
Role = MessageRoles.User.ToString(),
};
await _wishlistsService.AddMessageToPersonalWishlistAsync(wishlistId, dto, cancellationToken);
Response.Headers.Add("Content-Type", "text/event-stream"); Response.Headers.Add("Content-Type", "text/event-stream");
Response.Headers.Add("Cache-Control", "no-cache"); Response.Headers.Add("Cache-Control", "no-cache");
Response.Headers.Add("Connection", "keep-alive"); Response.Headers.Add("Connection", "keep-alive");

View File

@ -15,7 +15,7 @@ public class WishlistsMutation
[Service] IWishlistsService wishlistsService) [Service] IWishlistsService wishlistsService)
=> wishlistsService.GenerateNameForPersonalWishlistAsync(wishlistId, cancellationToken); => wishlistsService.GenerateNameForPersonalWishlistAsync(wishlistId, cancellationToken);
public Task<MessageDto> AddMessageToPersonalWishlistAsync(string wishlistId, MessageCreateDto dto, CancellationToken cancellationToken, public Task<MessageDto> AddMessageToPersonalWishlistAsync(string wishlistId, MessageDto dto, CancellationToken cancellationToken,
[Service] IWishlistsService wishlistsService) [Service] IWishlistsService wishlistsService)
=> wishlistsService.AddMessageToPersonalWishlistAsync(wishlistId, dto, cancellationToken); => wishlistsService.AddMessageToPersonalWishlistAsync(wishlistId, dto, cancellationToken);

View File

@ -10,7 +10,7 @@ public interface IWishlistsService
Task<WishlistDto> GenerateNameForPersonalWishlistAsync(string wishlistId, CancellationToken cancellationToken); Task<WishlistDto> GenerateNameForPersonalWishlistAsync(string wishlistId, CancellationToken cancellationToken);
Task<MessageDto> AddMessageToPersonalWishlistAsync(string wishlistId, MessageCreateDto dto, CancellationToken cancellationToken); Task<MessageDto> AddMessageToPersonalWishlistAsync(string wishlistId, MessageDto dto, CancellationToken cancellationToken);
Task<PagedList<WishlistDto>> GetPersonalWishlistsPageAsync(int pageNumber, int pageSize, CancellationToken cancellationToken); Task<PagedList<WishlistDto>> GetPersonalWishlistsPageAsync(int pageNumber, int pageSize, CancellationToken cancellationToken);

View File

@ -2,11 +2,11 @@ namespace ShoppingAssistantApi.Application.Models.Dtos;
public class MessageDto public class MessageDto
{ {
public required string Id { get; set; } public string Id { get; set; }
public required string Text { get; set; } public string Text { get; set; }
public required string Role { get; set; } public string Role { get; set; }
public required string CreatedById { get; set; } public string CreatedById { get; set; }
} }

View File

@ -93,9 +93,10 @@ public class ProductService : IProductService
{ {
if (data == "[") if (data == "[")
{ {
_wishlistsService.AddMessageToPersonalWishlistAsync(wishlistId, new MessageCreateDto() _wishlistsService.AddMessageToPersonalWishlistAsync(wishlistId, new MessageDto()
{ {
Text = messageBuffer.Text, Text = messageBuffer.Text,
Role = MessageRoles.Application.ToString(),
}, cancellationToken); }, cancellationToken);
mqchecker = false; mqchecker = false;
} }
@ -180,9 +181,10 @@ public class ProductService : IProductService
} }
if (currentDataType == SearchEventType.Message) if (currentDataType == SearchEventType.Message)
{ {
_wishlistsService.AddMessageToPersonalWishlistAsync(wishlistId, new MessageCreateDto() _wishlistsService.AddMessageToPersonalWishlistAsync(wishlistId, new MessageDto()
{ {
Text = messageBuffer.Text, Text = messageBuffer.Text,
Role = MessageRoles.Application.ToString(),
}, cancellationToken); }, cancellationToken);
mqchecker = false; mqchecker = false;
} }

View File

@ -45,7 +45,7 @@ public class WishlistsService : IWishlistsService
throw new InvalidDataException("Provided type is invalid."); throw new InvalidDataException("Provided type is invalid.");
} }
newWishlist.CreatedById = (ObjectId) GlobalUser.Id; newWishlist.CreatedById = GlobalUser.Id.Value;
newWishlist.CreatedDateUtc = DateTime.UtcNow; newWishlist.CreatedDateUtc = DateTime.UtcNow;
newWishlist.Name = $"{newWishlist.Type} Search"; newWishlist.Name = $"{newWishlist.Type} Search";
@ -54,8 +54,8 @@ public class WishlistsService : IWishlistsService
var newMessage = new Message var newMessage = new Message
{ {
Text = dto.FirstMessageText, Text = dto.FirstMessageText,
Role = MessageRoles.User.ToString(), Role = MessageRoles.Application.ToString(),
CreatedById = (ObjectId) GlobalUser.Id, CreatedById = GlobalUser.Id.Value,
CreatedDateUtc = DateTime.UtcNow, CreatedDateUtc = DateTime.UtcNow,
WishlistId = createdWishlist.Id WishlistId = createdWishlist.Id
}; };
@ -95,12 +95,12 @@ public class WishlistsService : IWishlistsService
var openAiMessage = await _openAiService.GetChatCompletion(chatCompletionRequest, cancellationToken); var openAiMessage = await _openAiService.GetChatCompletion(chatCompletionRequest, cancellationToken);
wishlist = await _wishlistsRepository.UpdateWishlistNameAsync(wishlist.Id, wishlist = await _wishlistsRepository.UpdateWishlistNameAsync(wishlist.Id,
openAiMessage.Content, (ObjectId) GlobalUser.Id, cancellationToken); openAiMessage.Content, GlobalUser.Id.Value, cancellationToken);
return _mapper.Map<WishlistDto>(wishlist); return _mapper.Map<WishlistDto>(wishlist);
} }
public async Task<MessageDto> AddMessageToPersonalWishlistAsync(string wishlistId, MessageCreateDto dto, CancellationToken cancellationToken) public async Task<MessageDto> AddMessageToPersonalWishlistAsync(string wishlistId, MessageDto dto, CancellationToken cancellationToken)
{ {
var newMessage = _mapper.Map<Message>(dto); var newMessage = _mapper.Map<Message>(dto);
@ -109,8 +109,7 @@ public class WishlistsService : IWishlistsService
throw new InvalidDataException("Provided id is invalid."); throw new InvalidDataException("Provided id is invalid.");
} }
newMessage.Role = MessageRoles.User.ToString(); newMessage.CreatedById = GlobalUser.Id.Value;
newMessage.CreatedById = (ObjectId) GlobalUser.Id;
newMessage.CreatedDateUtc = DateTime.UtcNow; newMessage.CreatedDateUtc = DateTime.UtcNow;
newMessage.WishlistId = wishlistObjectId; newMessage.WishlistId = wishlistObjectId;
@ -168,7 +167,7 @@ public class WishlistsService : IWishlistsService
await TryGetPersonalWishlist(wishlistObjectId, cancellationToken); await TryGetPersonalWishlist(wishlistObjectId, cancellationToken);
newProduct.CreatedById = (ObjectId) GlobalUser.Id; newProduct.CreatedById = GlobalUser.Id.Value;
newProduct.CreatedDateUtc = DateTime.UtcNow; newProduct.CreatedDateUtc = DateTime.UtcNow;
newProduct.WishlistId = wishlistObjectId; newProduct.WishlistId = wishlistObjectId;

View File

@ -3,6 +3,7 @@ using ShoppingAssistantApi.Domain.Enums;
using ShoppingAssistantApi.Application.Models.Dtos; using ShoppingAssistantApi.Application.Models.Dtos;
using ShoppingAssistantApi.Application.Paging; using ShoppingAssistantApi.Application.Paging;
using Newtonsoft.Json.Linq; using Newtonsoft.Json.Linq;
using MongoDB.Bson;
namespace ShoppingAssistantApi.Tests.Tests; namespace ShoppingAssistantApi.Tests.Tests;
@ -88,6 +89,30 @@ public class WishlistsTests : TestsBase
Assert.NotNull(startWishlistResponse); Assert.NotNull(startWishlistResponse);
const string MessageText = "I want laptop";
var mutation = new
{
query = @"
mutation addMessageToPersonalWishlist($wishlistId: String!, $dto: MessageDtoInput!) {
addMessageToPersonalWishlist(wishlistId: $wishlistId, dto: $dto) {
role, text, createdById
}
}",
variables = new
{
wishlistId = startWishlistResponse.Id,
dto = new
{
id = ObjectId.Empty,
text = MessageText,
role = MessageRoles.User.ToString(),
createdById = ObjectId.Empty,
}
}
};
await SendGraphQlRequestAsync(mutation);
var generateWishlistNameMutation = new var generateWishlistNameMutation = new
{ {
query = @" query = @"
@ -174,7 +199,7 @@ public class WishlistsTests : TestsBase
var mutation = new var mutation = new
{ {
query = @" query = @"
mutation addMessageToPersonalWishlist($wishlistId: String!, $dto: MessageCreateDtoInput!) { mutation addMessageToPersonalWishlist($wishlistId: String!, $dto: MessageDtoInput!) {
addMessageToPersonalWishlist(wishlistId: $wishlistId, dto: $dto) { addMessageToPersonalWishlist(wishlistId: $wishlistId, dto: $dto) {
role, text, createdById role, text, createdById
} }
@ -184,7 +209,10 @@ public class WishlistsTests : TestsBase
wishlistId = TestingValidWishlistId, wishlistId = TestingValidWishlistId,
dto = new dto = new
{ {
text = MessageText id = ObjectId.Empty,
text = MessageText,
role = MessageRoles.User.ToString(),
createdById = ObjectId.Empty,
} }
} }
}; };
@ -242,7 +270,7 @@ public class WishlistsTests : TestsBase
query = @" query = @"
mutation addProductToPersonalWishlist($wishlistId: String!, $dto: ProductCreateDtoInput!) { mutation addProductToPersonalWishlist($wishlistId: String!, $dto: ProductCreateDtoInput!) {
addProductToPersonalWishlist (wishlistId: $wishlistId, dto: $dto) { addProductToPersonalWishlist (wishlistId: $wishlistId, dto: $dto) {
url, name, description, rating, imagesUrls, wasOpened url, name, price, description, rating, imagesUrls, wasOpened
} }
}", }",
variables = new variables = new
@ -252,6 +280,7 @@ public class WishlistsTests : TestsBase
{ {
url = "https://www.amazon.com/url", url = "https://www.amazon.com/url",
name = "Generic name", name = "Generic name",
price = 1,
description = "Generic description", description = "Generic description",
rating = 4.8, rating = 4.8,
imagesUrls = new string[] imagesUrls = new string[]
@ -272,6 +301,7 @@ public class WishlistsTests : TestsBase
Assert.Equal("Generic name", product.Name); Assert.Equal("Generic name", product.Name);
Assert.Equal("Generic description", product.Description); Assert.Equal("Generic description", product.Description);
Assert.Equal(4.8, product.Rating); Assert.Equal(4.8, product.Rating);
Assert.Equal(1, product.Price);
Assert.Equal("https://www.amazon.com/image-url-1", product.ImagesUrls[0]); Assert.Equal("https://www.amazon.com/image-url-1", product.ImagesUrls[0]);
} }

View File

@ -59,7 +59,7 @@ public class ProductTests
_messagesRepositoryMock.Setup(m => m.GetCountAsync(It.IsAny<Expression<Func<Message, bool>>>(), It.IsAny<CancellationToken>())) _messagesRepositoryMock.Setup(m => m.GetCountAsync(It.IsAny<Expression<Func<Message, bool>>>(), It.IsAny<CancellationToken>()))
.ReturnsAsync(1); .ReturnsAsync(1);
_wishListServiceMock.Setup(w => w.AddMessageToPersonalWishlistAsync(wishlistId, It.IsAny<MessageCreateDto>(), cancellationToken)) _wishListServiceMock.Setup(w => w.AddMessageToPersonalWishlistAsync(wishlistId, It.IsAny<MessageDto>(), cancellationToken))
.Verifiable(); .Verifiable();
_wishListServiceMock _wishListServiceMock
@ -135,7 +135,7 @@ public class ProductTests
_messagesRepositoryMock.Setup(m => m.GetCountAsync(It.IsAny<Expression<Func<Message, bool>>>(), It.IsAny<CancellationToken>())) _messagesRepositoryMock.Setup(m => m.GetCountAsync(It.IsAny<Expression<Func<Message, bool>>>(), It.IsAny<CancellationToken>()))
.ReturnsAsync(3); .ReturnsAsync(3);
_wishListServiceMock.Setup(w => w.AddMessageToPersonalWishlistAsync(wishlistId, It.IsAny<MessageCreateDto>(), cancellationToken)) _wishListServiceMock.Setup(w => w.AddMessageToPersonalWishlistAsync(wishlistId, It.IsAny<MessageDto>(), cancellationToken))
.Verifiable(); .Verifiable();
_wishListServiceMock _wishListServiceMock
@ -186,7 +186,7 @@ public class ProductTests
Assert.NotNull(actualSseEvents); Assert.NotNull(actualSseEvents);
Assert.Equal(expectedMessages, receivedMessages); Assert.Equal(expectedMessages, receivedMessages);
Assert.Equal(expectedSuggestions, receivedSuggestions); Assert.Equal(expectedSuggestions, receivedSuggestions);
_wishListServiceMock.Verify(w => w.AddMessageToPersonalWishlistAsync(wishlistId, It.IsAny<MessageCreateDto>(), cancellationToken), Times.Once); _wishListServiceMock.Verify(w => w.AddMessageToPersonalWishlistAsync(wishlistId, It.IsAny<MessageDto>(), cancellationToken), Times.Once);
} }
@ -276,6 +276,6 @@ public class ProductTests
_wishListServiceMock.Verify(w => w.AddProductToPersonalWishlistAsync( _wishListServiceMock.Verify(w => w.AddProductToPersonalWishlistAsync(
It.IsAny<string>(), It.IsAny<ProductCreateDto>(), It.IsAny<CancellationToken>()), Times.Exactly(3)); It.IsAny<string>(), It.IsAny<ProductCreateDto>(), It.IsAny<CancellationToken>()), Times.Exactly(3));
_wishListServiceMock.Verify(w => w.AddMessageToPersonalWishlistAsync( _wishListServiceMock.Verify(w => w.AddMessageToPersonalWishlistAsync(
wishlistId, It.IsAny<MessageCreateDto>(), cancellationToken), Times.Once); wishlistId, It.IsAny<MessageDto>(), cancellationToken), Times.Once);
} }
} }