Files
GerbilManager/GerbilManager.Tests/GerbilCharacterTests.cs
Gulum 3afb04f646 FEAT-14a: Charakterbogen on Gerbil (traits + note) + sale-ad request extension
- Gerbil.CharacterTraits (List<string>, JSON text column, opaque labels) + CharacterNote
  (string?). On GerbilDto + Input; round-trips on GET/POST/PUT. Additive migration.
- SaleAdAnimal gains Traits (German labels) + CharacterNote; prompt builder emits
  "Charakter: …" + "Charakter-Notiz: …" lines for the AI Verkaufstext.
- Tests: traits/note round-trip (POST->GET via SQLite host), empty-default, prompt inclusion.
2026-06-06 09:10:30 +02:00

76 lines
2.7 KiB
C#

using System.Net;
using System.Net.Http.Json;
using System.Text.RegularExpressions;
using GerbilManagerWebAPI.SaleAd;
namespace GerbilManager.Tests;
/// <summary>FEAT-14a: Charakterbogen (traits + note) persists/round-trips, and the
/// sale-ad prompt includes the character info.</summary>
public class GerbilCharacterTests : IClassFixture<ApiFactory>
{
private readonly HttpClient _client;
public GerbilCharacterTests(ApiFactory factory) => _client = factory.CreateClient();
[Fact]
public async Task CharacterTraits_and_note_round_trip()
{
var create = await _client.PostAsync("/gerbils", JsonContent.Create(new
{
name = "Charakter Test",
gender = "female",
characterTraits = new[] { "zutraulich", "handzahm" },
characterNote = "sehr aktiv und neugierig",
}));
Assert.Equal(HttpStatusCode.Created, create.StatusCode);
var created = await create.Content.ReadAsStringAsync();
// POST response is the created GerbilDto — traits serialise straight back
Assert.Contains("zutraulich", created);
Assert.Contains("handzahm", created);
Assert.Contains("sehr aktiv und neugierig", created);
var id = Regex.Match(created, "\"id\":\"([^\"]+)\"").Groups[1].Value;
Assert.NotEqual("", id);
// re-read from the DB to prove persistence (not just echo)
var fetched = await _client.GetStringAsync($"/gerbils/{id}");
Assert.Contains("zutraulich", fetched);
Assert.Contains("handzahm", fetched);
Assert.Contains("sehr aktiv und neugierig", fetched);
}
[Fact]
public async Task Omitting_traits_defaults_to_empty_list()
{
var create = await _client.PostAsync("/gerbils", JsonContent.Create(new
{
name = "Ohne Charakter",
gender = "male",
}));
Assert.Equal(HttpStatusCode.Created, create.StatusCode);
var body = await create.Content.ReadAsStringAsync();
Assert.Contains("\"characterTraits\":[]", body.Replace(" ", ""));
}
[Fact]
public void SaleAd_prompt_includes_traits_and_note()
{
var request = new SaleAdRequest(
Animals: new List<SaleAdAnimal>
{
new("Bella", "Agouti", "2025-01-15", "verspielt",
Traits: new List<string> { "zutraulich", "handzahm" },
CharacterNote: "liebt Sonnenblumenkerne"),
},
StatusLine: "FREI",
Hints: "");
var prompt = SaleAdPromptBuilder.BuildUserPrompt(request);
Assert.Contains("Charakter: zutraulich, handzahm", prompt);
Assert.Contains("liebt Sonnenblumenkerne", prompt);
}
}