diff --git a/ShoppingAssistantApi.Api/Controllers/ProductsSearchController.cs b/ShoppingAssistantApi.Api/Controllers/ProductsSearchController.cs index 7dd9949..f00b26a 100644 --- a/ShoppingAssistantApi.Api/Controllers/ProductsSearchController.cs +++ b/ShoppingAssistantApi.Api/Controllers/ProductsSearchController.cs @@ -3,6 +3,8 @@ using Microsoft.AspNetCore.Mvc; using Newtonsoft.Json; using ShoppingAssistantApi.Application.IServices; using ShoppingAssistantApi.Application.Models.CreateDtos; +using ShoppingAssistantApi.Application.Models.Dtos; +using ShoppingAssistantApi.Domain.Enums; namespace ShoppingAssistantApi.Api.Controllers; @@ -11,14 +13,24 @@ public class ProductsSearchController : BaseController { private readonly IProductService _productService; - public ProductsSearchController(IProductService productService) + private readonly IWishlistsService _wishlistsService; + + public ProductsSearchController(IProductService productService, IWishlistsService wishlistsService) { _productService = productService; + _wishlistsService = wishlistsService; } [HttpPost("search/{wishlistId}")] 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("Cache-Control", "no-cache"); Response.Headers.Add("Connection", "keep-alive"); diff --git a/ShoppingAssistantApi.Api/Mutations/WishlistsMutation.cs b/ShoppingAssistantApi.Api/Mutations/WishlistsMutation.cs index d33cf81..a8f1d8f 100644 --- a/ShoppingAssistantApi.Api/Mutations/WishlistsMutation.cs +++ b/ShoppingAssistantApi.Api/Mutations/WishlistsMutation.cs @@ -15,7 +15,7 @@ public class WishlistsMutation [Service] IWishlistsService wishlistsService) => wishlistsService.GenerateNameForPersonalWishlistAsync(wishlistId, cancellationToken); - public Task AddMessageToPersonalWishlistAsync(string wishlistId, MessageCreateDto dto, CancellationToken cancellationToken, + public Task AddMessageToPersonalWishlistAsync(string wishlistId, MessageDto dto, CancellationToken cancellationToken, [Service] IWishlistsService wishlistsService) => wishlistsService.AddMessageToPersonalWishlistAsync(wishlistId, dto, cancellationToken); diff --git a/ShoppingAssistantApi.Application/IServices/IWishlistService.cs b/ShoppingAssistantApi.Application/IServices/IWishlistService.cs index 4b26cf1..c2d5899 100644 --- a/ShoppingAssistantApi.Application/IServices/IWishlistService.cs +++ b/ShoppingAssistantApi.Application/IServices/IWishlistService.cs @@ -10,7 +10,7 @@ public interface IWishlistsService Task GenerateNameForPersonalWishlistAsync(string wishlistId, CancellationToken cancellationToken); - Task AddMessageToPersonalWishlistAsync(string wishlistId, MessageCreateDto dto, CancellationToken cancellationToken); + Task AddMessageToPersonalWishlistAsync(string wishlistId, MessageDto dto, CancellationToken cancellationToken); Task> GetPersonalWishlistsPageAsync(int pageNumber, int pageSize, CancellationToken cancellationToken); diff --git a/ShoppingAssistantApi.Application/Models/Dtos/MessageDto.cs b/ShoppingAssistantApi.Application/Models/Dtos/MessageDto.cs index 9225d00..7c2a7cd 100644 --- a/ShoppingAssistantApi.Application/Models/Dtos/MessageDto.cs +++ b/ShoppingAssistantApi.Application/Models/Dtos/MessageDto.cs @@ -2,11 +2,11 @@ namespace ShoppingAssistantApi.Application.Models.Dtos; 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; } } diff --git a/ShoppingAssistantApi.Infrastructure/Services/ProductService.cs b/ShoppingAssistantApi.Infrastructure/Services/ProductService.cs index e18da09..bb3d83d 100644 --- a/ShoppingAssistantApi.Infrastructure/Services/ProductService.cs +++ b/ShoppingAssistantApi.Infrastructure/Services/ProductService.cs @@ -93,9 +93,10 @@ public class ProductService : IProductService { if (data == "[") { - _wishlistsService.AddMessageToPersonalWishlistAsync(wishlistId, new MessageCreateDto() + _wishlistsService.AddMessageToPersonalWishlistAsync(wishlistId, new MessageDto() { Text = messageBuffer.Text, + Role = MessageRoles.Application.ToString(), }, cancellationToken); mqchecker = false; } @@ -180,9 +181,10 @@ public class ProductService : IProductService } if (currentDataType == SearchEventType.Message) { - _wishlistsService.AddMessageToPersonalWishlistAsync(wishlistId, new MessageCreateDto() + _wishlistsService.AddMessageToPersonalWishlistAsync(wishlistId, new MessageDto() { Text = messageBuffer.Text, + Role = MessageRoles.Application.ToString(), }, cancellationToken); mqchecker = false; } diff --git a/ShoppingAssistantApi.Infrastructure/Services/WishlistsService.cs b/ShoppingAssistantApi.Infrastructure/Services/WishlistsService.cs index b6814bb..42ae372 100644 --- a/ShoppingAssistantApi.Infrastructure/Services/WishlistsService.cs +++ b/ShoppingAssistantApi.Infrastructure/Services/WishlistsService.cs @@ -45,7 +45,7 @@ public class WishlistsService : IWishlistsService throw new InvalidDataException("Provided type is invalid."); } - newWishlist.CreatedById = (ObjectId) GlobalUser.Id; + newWishlist.CreatedById = GlobalUser.Id.Value; newWishlist.CreatedDateUtc = DateTime.UtcNow; newWishlist.Name = $"{newWishlist.Type} Search"; @@ -54,8 +54,8 @@ public class WishlistsService : IWishlistsService var newMessage = new Message { Text = dto.FirstMessageText, - Role = MessageRoles.User.ToString(), - CreatedById = (ObjectId) GlobalUser.Id, + Role = MessageRoles.Application.ToString(), + CreatedById = GlobalUser.Id.Value, CreatedDateUtc = DateTime.UtcNow, WishlistId = createdWishlist.Id }; @@ -95,12 +95,12 @@ public class WishlistsService : IWishlistsService var openAiMessage = await _openAiService.GetChatCompletion(chatCompletionRequest, cancellationToken); wishlist = await _wishlistsRepository.UpdateWishlistNameAsync(wishlist.Id, - openAiMessage.Content, (ObjectId) GlobalUser.Id, cancellationToken); + openAiMessage.Content, GlobalUser.Id.Value, cancellationToken); return _mapper.Map(wishlist); } - public async Task AddMessageToPersonalWishlistAsync(string wishlistId, MessageCreateDto dto, CancellationToken cancellationToken) + public async Task AddMessageToPersonalWishlistAsync(string wishlistId, MessageDto dto, CancellationToken cancellationToken) { var newMessage = _mapper.Map(dto); @@ -109,8 +109,7 @@ public class WishlistsService : IWishlistsService throw new InvalidDataException("Provided id is invalid."); } - newMessage.Role = MessageRoles.User.ToString(); - newMessage.CreatedById = (ObjectId) GlobalUser.Id; + newMessage.CreatedById = GlobalUser.Id.Value; newMessage.CreatedDateUtc = DateTime.UtcNow; newMessage.WishlistId = wishlistObjectId; @@ -168,7 +167,7 @@ public class WishlistsService : IWishlistsService await TryGetPersonalWishlist(wishlistObjectId, cancellationToken); - newProduct.CreatedById = (ObjectId) GlobalUser.Id; + newProduct.CreatedById = GlobalUser.Id.Value; newProduct.CreatedDateUtc = DateTime.UtcNow; newProduct.WishlistId = wishlistObjectId; diff --git a/ShoppingAssistantApi.Tests/Tests/WishlistsTests.cs b/ShoppingAssistantApi.Tests/Tests/WishlistsTests.cs index 6a3c3a0..4d1e5d8 100644 --- a/ShoppingAssistantApi.Tests/Tests/WishlistsTests.cs +++ b/ShoppingAssistantApi.Tests/Tests/WishlistsTests.cs @@ -3,6 +3,7 @@ using ShoppingAssistantApi.Domain.Enums; using ShoppingAssistantApi.Application.Models.Dtos; using ShoppingAssistantApi.Application.Paging; using Newtonsoft.Json.Linq; +using MongoDB.Bson; namespace ShoppingAssistantApi.Tests.Tests; @@ -88,6 +89,30 @@ public class WishlistsTests : TestsBase 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 { query = @" @@ -174,7 +199,7 @@ public class WishlistsTests : TestsBase var mutation = new { query = @" - mutation addMessageToPersonalWishlist($wishlistId: String!, $dto: MessageCreateDtoInput!) { + mutation addMessageToPersonalWishlist($wishlistId: String!, $dto: MessageDtoInput!) { addMessageToPersonalWishlist(wishlistId: $wishlistId, dto: $dto) { role, text, createdById } @@ -184,7 +209,10 @@ public class WishlistsTests : TestsBase wishlistId = TestingValidWishlistId, 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 = @" mutation addProductToPersonalWishlist($wishlistId: String!, $dto: ProductCreateDtoInput!) { addProductToPersonalWishlist (wishlistId: $wishlistId, dto: $dto) { - url, name, description, rating, imagesUrls, wasOpened + url, name, price, description, rating, imagesUrls, wasOpened } }", variables = new @@ -252,6 +280,7 @@ public class WishlistsTests : TestsBase { url = "https://www.amazon.com/url", name = "Generic name", + price = 1, description = "Generic description", rating = 4.8, imagesUrls = new string[] @@ -272,6 +301,7 @@ public class WishlistsTests : TestsBase Assert.Equal("Generic name", product.Name); Assert.Equal("Generic description", product.Description); Assert.Equal(4.8, product.Rating); + Assert.Equal(1, product.Price); Assert.Equal("https://www.amazon.com/image-url-1", product.ImagesUrls[0]); } diff --git a/ShoppingAssistantApi.UnitTests/ProductTests.cs b/ShoppingAssistantApi.UnitTests/ProductTests.cs index 18b83ea..e5de43e 100644 --- a/ShoppingAssistantApi.UnitTests/ProductTests.cs +++ b/ShoppingAssistantApi.UnitTests/ProductTests.cs @@ -59,7 +59,7 @@ public class ProductTests _messagesRepositoryMock.Setup(m => m.GetCountAsync(It.IsAny>>(), It.IsAny())) .ReturnsAsync(1); - _wishListServiceMock.Setup(w => w.AddMessageToPersonalWishlistAsync(wishlistId, It.IsAny(), cancellationToken)) + _wishListServiceMock.Setup(w => w.AddMessageToPersonalWishlistAsync(wishlistId, It.IsAny(), cancellationToken)) .Verifiable(); _wishListServiceMock @@ -135,7 +135,7 @@ public class ProductTests _messagesRepositoryMock.Setup(m => m.GetCountAsync(It.IsAny>>(), It.IsAny())) .ReturnsAsync(3); - _wishListServiceMock.Setup(w => w.AddMessageToPersonalWishlistAsync(wishlistId, It.IsAny(), cancellationToken)) + _wishListServiceMock.Setup(w => w.AddMessageToPersonalWishlistAsync(wishlistId, It.IsAny(), cancellationToken)) .Verifiable(); _wishListServiceMock @@ -186,7 +186,7 @@ public class ProductTests Assert.NotNull(actualSseEvents); Assert.Equal(expectedMessages, receivedMessages); Assert.Equal(expectedSuggestions, receivedSuggestions); - _wishListServiceMock.Verify(w => w.AddMessageToPersonalWishlistAsync(wishlistId, It.IsAny(), cancellationToken), Times.Once); + _wishListServiceMock.Verify(w => w.AddMessageToPersonalWishlistAsync(wishlistId, It.IsAny(), cancellationToken), Times.Once); } @@ -276,6 +276,6 @@ public class ProductTests _wishListServiceMock.Verify(w => w.AddProductToPersonalWishlistAsync( It.IsAny(), It.IsAny(), It.IsAny()), Times.Exactly(3)); _wishListServiceMock.Verify(w => w.AddMessageToPersonalWishlistAsync( - wishlistId, It.IsAny(), cancellationToken), Times.Once); + wishlistId, It.IsAny(), cancellationToken), Times.Once); } } \ No newline at end of file