124 lines
4.1 KiB
C#
124 lines
4.1 KiB
C#
using Moq;
|
|
using Xunit;
|
|
using FluentAssertions;
|
|
using Microsoft.AspNetCore.Mvc;
|
|
using Microsoft.AspNetCore.Http;
|
|
using Microsoft.EntityFrameworkCore;
|
|
using Seasoned.Backend.Controllers;
|
|
using Seasoned.Backend.Services;
|
|
using Seasoned.Backend.DTOs;
|
|
using Seasoned.Backend.Data;
|
|
using Seasoned.Backend.Models;
|
|
using System.Security.Claims;
|
|
|
|
namespace Seasoned.Tests;
|
|
|
|
public class RecipeControllerTests
|
|
{
|
|
private readonly Mock<IRecipeService> _mockService;
|
|
private readonly ApplicationDbContext _context;
|
|
private readonly RecipeController _controller;
|
|
private readonly string _testUserId = "chef-123";
|
|
|
|
public RecipeControllerTests()
|
|
{
|
|
_mockService = new Mock<IRecipeService>();
|
|
|
|
// Setup InMemory Postgres replacement
|
|
var options = new DbContextOptionsBuilder<ApplicationDbContext>()
|
|
.UseInMemoryDatabase(databaseName: Guid.NewGuid().ToString())
|
|
.Options;
|
|
_context = new ApplicationDbContext(options);
|
|
|
|
_controller = new RecipeController(_mockService.Object, _context);
|
|
|
|
// Mock the User Identity (User.FindFirstValue(ClaimTypes.NameIdentifier))
|
|
var user = new ClaimsPrincipal(new ClaimsIdentity(new Claim[]
|
|
{
|
|
new Claim(ClaimTypes.NameIdentifier, _testUserId),
|
|
}, "mock"));
|
|
|
|
_controller.ControllerContext = new ControllerContext()
|
|
{
|
|
HttpContext = new DefaultHttpContext() { User = user }
|
|
};
|
|
}
|
|
|
|
[Fact]
|
|
public async Task UploadRecipe_ReturnsOk_WithParsedDataAndImage()
|
|
{
|
|
// Arrange
|
|
var fakeRecipe = new RecipeResponseDto
|
|
{
|
|
Title = "Roasted Garlic Pasta",
|
|
ImageUrl = "data:image/png;base64,header_captured_image"
|
|
};
|
|
|
|
_mockService.Setup(s => s.ParseRecipeImageAsync(It.IsAny<IFormFile>()))
|
|
.ReturnsAsync(fakeRecipe);
|
|
|
|
var file = CreateMockFile("test-recipe.jpg");
|
|
|
|
// Act
|
|
var result = await _controller.UploadRecipe(file);
|
|
|
|
// Assert
|
|
var okResult = result.Result as OkObjectResult;
|
|
okResult.Should().NotBeNull();
|
|
var returned = okResult!.Value as RecipeResponseDto;
|
|
returned!.Title.Should().Be("Roasted Garlic Pasta");
|
|
returned.ImageUrl.Should().Contain("base64");
|
|
}
|
|
|
|
[Fact]
|
|
public async Task SaveRecipe_PersistsToPostgres_ForCurrentUser()
|
|
{
|
|
// Arrange
|
|
var dto = new RecipeResponseDto
|
|
{
|
|
Title = "Jenkins Special Brew",
|
|
Ingredients = new List<string> { "Coffee", "Code" },
|
|
ImageUrl = "base64-string"
|
|
};
|
|
|
|
// Act
|
|
var result = await _controller.SaveRecipe(dto);
|
|
|
|
// Assert
|
|
var okResult = result as OkResult; // Or OkObjectResult based on your Controller return
|
|
var savedRecipe = await _context.Recipes.FirstOrDefaultAsync(r => r.Title == "Jenkins Special Brew");
|
|
|
|
savedRecipe.Should().NotBeNull();
|
|
savedRecipe!.UserId.Should().Be(_testUserId);
|
|
savedRecipe.ImageUrl.Should().Be("base64-string");
|
|
}
|
|
|
|
[Fact]
|
|
public async Task ConsultChef_ReturnsChefResponse()
|
|
{
|
|
// Arrange
|
|
var request = new ChatRequestDto { Prompt = "How do I sear a steak?" };
|
|
var expectedResponse = new ChefConsultResponseDto { Reply = "High heat, my friend!" };
|
|
|
|
_mockService.Setup(s => s.ConsultChefAsync(It.IsAny<string>()))
|
|
.ReturnsAsync(expectedResponse);
|
|
|
|
// Act
|
|
var result = await _controller.Consult(request);
|
|
|
|
// Assert
|
|
var okResult = result as OkObjectResult;
|
|
var response = okResult!.Value as ChefConsultResponseDto;
|
|
response!.Reply.Should().Be("High heat, my friend!");
|
|
}
|
|
|
|
private IFormFile CreateMockFile(string fileName)
|
|
{
|
|
var ms = new MemoryStream();
|
|
var writer = new StreamWriter(ms);
|
|
writer.Write("fake image binary data");
|
|
writer.Flush();
|
|
ms.Position = 0;
|
|
return new FormFile(ms, 0, ms.Length, "image", fileName);
|
|
}
|
|
} |