Merge nucleic/warm-north-vole-pf37 into dev
This commit is contained in:
@@ -0,0 +1,113 @@
|
||||
using System.Text.Json;
|
||||
using NucleicApp.Services;
|
||||
using NucleicApp.ViewModels;
|
||||
using NucleicProtocol.Interop;
|
||||
|
||||
namespace NucleicApp.Tests;
|
||||
|
||||
public sealed class PresentationModelTests
|
||||
{
|
||||
[Fact]
|
||||
public void HomeDerivesAttentionActivityAndCountsOnlyFromHostProjections()
|
||||
{
|
||||
using var store = new RendererStore();
|
||||
store.Apply("""
|
||||
{"input":[
|
||||
{"archived":false,"disposition":"awaitingInput","pendingApprovalCount":0,
|
||||
"sessionID":"needs-input","status":"awaitingInput","title":"Needs input","updatedAt":3},
|
||||
{"archived":false,"pendingApprovalCount":0,
|
||||
"sessionID":"running","status":"running","title":"Running","updatedAt":2},
|
||||
{"archived":true,"pendingApprovalCount":1,
|
||||
"sessionID":"archived","status":"awaitingApproval","title":"Archived","updatedAt":4}
|
||||
],"t":"sessionList"}
|
||||
""");
|
||||
store.Apply("""
|
||||
{"activity":[],"counts":{"activeChats":2,"chats":3,"messages":8,
|
||||
"projects":1,"tokens":1200},"projects":[],"statusFeeds":[],
|
||||
"t":"dashboard","todos":[{"status":"open"},{"status":"done"}]}
|
||||
""");
|
||||
using var home = new HomeViewModel(
|
||||
store, () => new DateTimeOffset(2026, 8, 4, 9, 0, 0, TimeSpan.Zero));
|
||||
|
||||
Assert.Equal("Good morning", home.Greeting);
|
||||
Assert.Equal(new DashboardCounts(1, 2, 3, 8, 1200), home.Counts);
|
||||
Assert.Equal("2 active of 3 chats · 1 project", home.Subtitle);
|
||||
Assert.Equal("needs-input", Assert.Single(home.NeedsAttention).Id);
|
||||
Assert.Equal("running", Assert.Single(home.InProgress).Id);
|
||||
Assert.Equal(2, home.LiveSessions.Count);
|
||||
Assert.Equal(1, home.OpenTodoCount);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task ShellSessionLifecycleEmitsSubscriptionComposerAndApprovalIntents()
|
||||
{
|
||||
var directory = Directory.CreateTempSubdirectory("nucleic-shell-");
|
||||
try
|
||||
{
|
||||
var rendezvousPath = Path.Combine(directory.FullName, "hostd.json");
|
||||
await File.WriteAllTextAsync(rendezvousPath, JsonSerializer.Serialize(
|
||||
ProtocolInteropTests.ValidRendezvous()));
|
||||
var native = new FakeNativeProtocol
|
||||
{
|
||||
ProjectionResult =
|
||||
"{\"sessionID\":\"session-1\",\"splices\":[{\"deleteCount\":0,\"items\":[],\"start\":0}],\"version\":1}",
|
||||
};
|
||||
using var store = new RendererStore(new ProtocolProjection(native));
|
||||
store.Apply(TestRepository.Fixture("host", "sessionList"));
|
||||
store.Apply(TestRepository.Fixture("host", "approvalRequested"));
|
||||
|
||||
var client = new FakeProtocolClient();
|
||||
await using var connection = new HostConnection(
|
||||
store, Path.Combine(directory.FullName, "identity"),
|
||||
new FakeProtocolClientFactory(client), InlineRendererDispatcher.Instance);
|
||||
await connection.StartLocalAsync(rendezvousPath);
|
||||
using var shell = new ShellViewModel(store, connection);
|
||||
|
||||
Assert.Equal(ProtocolResult.Ok, shell.OpenSession("session-1", 6));
|
||||
var detail = Assert.IsType<SessionDetailViewModel>(shell.SelectedSession);
|
||||
Assert.Equal(ShellSection.Sessions, shell.Section);
|
||||
Assert.Equal("session-1", detail.Session?.Id);
|
||||
Assert.Equal("approval-1", Assert.Single(detail.PendingApprovals).Id);
|
||||
|
||||
Assert.Equal(ProtocolResult.InvalidArgument, detail.SendText(" "));
|
||||
Assert.Equal(ProtocolResult.Ok, detail.SendText("continue"));
|
||||
var approval = Assert.Single(detail.PendingApprovals);
|
||||
Assert.Equal(ProtocolResult.Ok, detail.Allow(approval));
|
||||
Assert.Equal(ProtocolResult.Ok, detail.Deny(approval, "not now"));
|
||||
Assert.Equal(ProtocolResult.Ok,
|
||||
detail.AllowAlways(approval, ApprovalAlwaysScope.ToolName));
|
||||
Assert.Equal(ProtocolResult.Ok, detail.CancelRun(approval));
|
||||
|
||||
store.Apply(TestRepository.Fixture("host", "pong"));
|
||||
Assert.NotNull(detail.LastProjection);
|
||||
|
||||
shell.Navigate(ShellSection.Home);
|
||||
Assert.Null(shell.SelectedSession);
|
||||
Assert.Equal(ShellSection.Home, shell.Section);
|
||||
|
||||
var messages = client.Intents.Select(ProtocolMessage.Parse).ToArray();
|
||||
Assert.Equal(
|
||||
["subscribe", "sendInput", "approvalRespond", "approvalRespond",
|
||||
"approvalRespond", "approvalRespond", "unsubscribe"],
|
||||
messages.Select(message => message.Tag));
|
||||
Assert.Equal(6UL, messages[0].Root.GetProperty("sinceSeq").GetUInt64());
|
||||
Assert.Equal("continue",
|
||||
messages[1].Root.GetProperty("input").GetProperty("parts")[0]
|
||||
.GetProperty("text").GetString());
|
||||
Assert.Equal("allow",
|
||||
messages[2].Root.GetProperty("decision").GetProperty("type").GetString());
|
||||
Assert.Equal("deny",
|
||||
messages[3].Root.GetProperty("decision").GetProperty("type").GetString());
|
||||
Assert.Equal("not now",
|
||||
messages[3].Root.GetProperty("decision").GetProperty("reason").GetString());
|
||||
Assert.Equal("allowAlways",
|
||||
messages[4].Root.GetProperty("decision").GetProperty("type").GetString());
|
||||
Assert.Equal("toolName",
|
||||
messages[4].Root.GetProperty("decision").GetProperty("scope").GetString());
|
||||
Assert.Equal("cancelRun",
|
||||
messages[5].Root.GetProperty("decision").GetProperty("type").GetString());
|
||||
Assert.Equal("session-1", messages[6].Root.GetProperty("sessionID").GetString());
|
||||
}
|
||||
finally { directory.Delete(recursive: true); }
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user