125 lines
4.0 KiB
C#
125 lines
4.0 KiB
C#
using FluentAssertions;
|
|
using FnbEngine.Domain.AggregatesModel.RecipeAggregate;
|
|
using Xunit;
|
|
|
|
namespace FnbEngine.UnitTests.Domain;
|
|
|
|
/// <summary>
|
|
/// EN: Unit tests for Recipe aggregate behavior.
|
|
/// VI: Unit tests cho hanh vi aggregate Recipe.
|
|
/// </summary>
|
|
public class RecipeTests
|
|
{
|
|
private static readonly Guid ValidShopId = Guid.NewGuid();
|
|
private static readonly Guid ValidProductId = Guid.NewGuid();
|
|
|
|
[Fact]
|
|
public void Constructor_WithValidData_ShouldCreateActiveRecipe()
|
|
{
|
|
// Act
|
|
var recipe = new Recipe(ValidShopId, ValidProductId, "Pho Bo", "Boil broth for 8 hours", 480);
|
|
|
|
// Assert
|
|
recipe.Id.Should().NotBeEmpty();
|
|
recipe.ShopId.Should().Be(ValidShopId);
|
|
recipe.ProductId.Should().Be(ValidProductId);
|
|
recipe.Name.Should().Be("Pho Bo");
|
|
recipe.Instructions.Should().Be("Boil broth for 8 hours");
|
|
recipe.PrepTimeMinutes.Should().Be(480);
|
|
recipe.IsActive.Should().BeTrue();
|
|
recipe.Ingredients.Should().BeEmpty();
|
|
recipe.CreatedAt.Should().BeCloseTo(DateTime.UtcNow, TimeSpan.FromSeconds(5));
|
|
recipe.UpdatedAt.Should().BeNull();
|
|
}
|
|
|
|
[Fact]
|
|
public void Constructor_WithNullInstructions_ShouldAllowNull()
|
|
{
|
|
var recipe = new Recipe(ValidShopId, ValidProductId, "Simple Dish", null, 10);
|
|
recipe.Instructions.Should().BeNull();
|
|
}
|
|
|
|
[Fact]
|
|
public void Update_ShouldModifyAllFields()
|
|
{
|
|
// Arrange
|
|
var recipe = new Recipe(ValidShopId, ValidProductId, "Old Name", "Old instructions", 30);
|
|
var newProductId = Guid.NewGuid();
|
|
|
|
// Act
|
|
recipe.Update(newProductId, "New Name", "New instructions", 60);
|
|
|
|
// Assert
|
|
recipe.ProductId.Should().Be(newProductId);
|
|
recipe.Name.Should().Be("New Name");
|
|
recipe.Instructions.Should().Be("New instructions");
|
|
recipe.PrepTimeMinutes.Should().Be(60);
|
|
recipe.UpdatedAt.Should().NotBeNull();
|
|
}
|
|
|
|
[Fact]
|
|
public void AddIngredient_ShouldAppendToIngredientsList()
|
|
{
|
|
// Arrange
|
|
var recipe = new Recipe(ValidShopId, ValidProductId, "Pho Bo", null, 480);
|
|
|
|
// Act
|
|
recipe.AddIngredient("Beef bones", 2.0m, "kg", 150_000m);
|
|
recipe.AddIngredient("Rice noodles", 0.5m, "kg", 30_000m);
|
|
|
|
// Assert
|
|
recipe.Ingredients.Should().HaveCount(2);
|
|
recipe.Ingredients[0].IngredientName.Should().Be("Beef bones");
|
|
recipe.Ingredients[0].Quantity.Should().Be(2.0m);
|
|
recipe.Ingredients[0].Unit.Should().Be("kg");
|
|
recipe.Ingredients[0].CostPerUnit.Should().Be(150_000m);
|
|
recipe.Ingredients[1].IngredientName.Should().Be("Rice noodles");
|
|
}
|
|
|
|
[Fact]
|
|
public void AddIngredient_WithInventoryItemId_ShouldSetCOGSFields()
|
|
{
|
|
// Arrange
|
|
var recipe = new Recipe(ValidShopId, ValidProductId, "Pho Bo", null, 480);
|
|
var inventoryItemId = Guid.NewGuid();
|
|
|
|
// Act
|
|
recipe.AddIngredient("Beef", 1.0m, "kg", 200_000m, inventoryItemId, 0.3m);
|
|
|
|
// Assert
|
|
var ingredient = recipe.Ingredients.Single();
|
|
ingredient.InventoryItemId.Should().Be(inventoryItemId);
|
|
ingredient.QuantityPerServing.Should().Be(0.3m);
|
|
}
|
|
|
|
[Fact]
|
|
public void ClearIngredients_ShouldRemoveAll()
|
|
{
|
|
// Arrange
|
|
var recipe = new Recipe(ValidShopId, ValidProductId, "Pho Bo", null, 480);
|
|
recipe.AddIngredient("Beef bones", 2.0m, "kg", 150_000m);
|
|
recipe.AddIngredient("Noodles", 0.5m, "kg", 30_000m);
|
|
|
|
// Act
|
|
recipe.ClearIngredients();
|
|
|
|
// Assert
|
|
recipe.Ingredients.Should().BeEmpty();
|
|
recipe.UpdatedAt.Should().NotBeNull();
|
|
}
|
|
|
|
[Fact]
|
|
public void Deactivate_ShouldSetIsActiveToFalse()
|
|
{
|
|
// Arrange
|
|
var recipe = new Recipe(ValidShopId, ValidProductId, "Pho Bo", null, 480);
|
|
|
|
// Act
|
|
recipe.Deactivate();
|
|
|
|
// Assert
|
|
recipe.IsActive.Should().BeFalse();
|
|
recipe.UpdatedAt.Should().NotBeNull();
|
|
}
|
|
}
|