72 lines
2.5 KiB
C#
72 lines
2.5 KiB
C#
using backend.Conversations;
|
|
using backend.Data;
|
|
using FluentAssertions;
|
|
using Microsoft.EntityFrameworkCore;
|
|
using Microsoft.Extensions.DependencyInjection;
|
|
using Xunit;
|
|
|
|
namespace backend.tests;
|
|
|
|
public class ConversationLogTests(ApiFactory factory) : IClassFixture<ApiFactory>
|
|
{
|
|
private readonly ApiFactory _factory = factory;
|
|
|
|
private async Task<(AppDbContext db, ConversationLog log, Guid deviceId)> ArrangeAsync()
|
|
{
|
|
var scope = _factory.Services.CreateScope();
|
|
var db = scope.ServiceProvider.GetRequiredService<AppDbContext>();
|
|
var log = scope.ServiceProvider.GetRequiredService<ConversationLog>();
|
|
var deviceId = Guid.NewGuid();
|
|
return (db, log, deviceId);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task Start_creates_conversation_row()
|
|
{
|
|
var (db, log, deviceId) = await ArrangeAsync();
|
|
|
|
var convo = await log.StartAsync(deviceId, default);
|
|
|
|
var row = await db.Conversations.FirstAsync(c => c.Id == convo.Id);
|
|
row.DeviceId.Should().Be(deviceId);
|
|
row.EndedAt.Should().BeNull();
|
|
row.EndReason.Should().Be(EndReason.Unknown);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task Turns_are_persisted_with_monotonic_index_per_conversation()
|
|
{
|
|
var (db, log, deviceId) = await ArrangeAsync();
|
|
var convo = await log.StartAsync(deviceId, default);
|
|
|
|
await log.AppendUserAsync(convo.Id, "hi", default);
|
|
await log.AppendAssistantAsync(convo.Id, "hello there", default);
|
|
await log.AppendToolAsync(convo.Id, "get_current_time", "{}", "{\"now\":\"2026-06-11T00:00:00Z\"}", default);
|
|
|
|
var turns = await db.Turns
|
|
.Where(t => t.ConversationId == convo.Id)
|
|
.OrderBy(t => t.Index)
|
|
.ToListAsync();
|
|
|
|
turns.Should().HaveCount(3);
|
|
turns.Select(t => t.Index).Should().Equal(0, 1, 2);
|
|
turns.Select(t => t.Role).Should().Equal(TurnRole.User, TurnRole.Assistant, TurnRole.Tool);
|
|
turns[0].Text.Should().Be("hi");
|
|
turns[1].Text.Should().Be("hello there");
|
|
turns[2].ToolName.Should().Be("get_current_time");
|
|
}
|
|
|
|
[Fact]
|
|
public async Task End_sets_ended_at_and_reason()
|
|
{
|
|
var (db, log, deviceId) = await ArrangeAsync();
|
|
var convo = await log.StartAsync(deviceId, default);
|
|
|
|
await log.EndAsync(convo.Id, EndReason.Idle, default);
|
|
|
|
var row = await db.Conversations.FirstAsync(c => c.Id == convo.Id);
|
|
row.EndedAt.Should().NotBeNull();
|
|
row.EndReason.Should().Be(EndReason.Idle);
|
|
}
|
|
}
|