using System.Net; using AgentWikiUi.Core; namespace AgentWikiUi.Tests; /// Motore Antigravity (docs/TESTING.md → Antigravity, AG-01…AG-10, AG-12, UP-21). [Trait("Category", "Unit")] public sealed class AgyEngineTests { static readonly Engine Agy = Engines.Agy; sealed class FakeHandler(string body) : HttpMessageHandler { public Uri? Requested; protected override Task SendAsync(HttpRequestMessage request, CancellationToken ct) { Requested = request.RequestUri; return Task.FromResult(new HttpResponseMessage(HttpStatusCode.OK) { Content = new StringContent(body) }); } } [Fact] // AG-01 public void Agy_primo_messaggio() => Assert.Equal(["--output-format", "json", "--print-timeout", "120s", "-p", "ciao"], Agy.BuildArgs("ciao", null, resume: false, model: "", effort: "", structured: true)); [Fact] // AG-02 public void Agy_ripresa() => Assert.Equal(["--output-format", "json", "--conversation", "conv-1", "--print-timeout", "120s", "-p", "ancora"], Agy.BuildArgs("ancora", "conv-1", resume: true, model: "", effort: "", structured: true)); [Fact] // AG-03 public void Agy_flag_prima_di_p() { var args = Agy.BuildArgs("ciao", "conv-1", true, "gemini-3.0-flash-low", "high", true); Assert.Equal(["-p", "ciao"], args[^2..]); Assert.Single(args, a => a == "-p"); } [Fact] // AG-04 public void Agy_modello_ed_effort() { var con = Agy.BuildArgs("x", null, false, "claude-opus-4-6-thinking", "max", true); Assert.Equal("claude-opus-4-6-thinking", con[con.IndexOf("--model") + 1]); Assert.Equal("max", con[con.IndexOf("--effort") + 1]); var senza = Agy.BuildArgs("x", null, false, "", "", true); Assert.DoesNotContain("--model", senza); Assert.DoesNotContain("--effort", senza); } [Fact] // AG-05 public void Agy_conversation_id() { Assert.True(Agy.OwnsSessionId); var r = Agy.Parse(0, """{"conversation_id":"abc-123","response":"ok","status":"SUCCESS"}""", ""); Assert.Equal("abc-123", r.SessionId); } [Fact] // AG-06 public void Agy_estrazione_risposta() { var r = Agy.Parse(0, """{"conversation_id":"c","response":" Ciao **mondo**\n","status":"SUCCESS"}""", ""); Assert.Equal("Ciao **mondo**", r.Text); Assert.Null(r.Error); } [Fact] // AG-07 public void Agy_errore_status() { var stato = Agy.Parse(0, """{"conversation_id":"c","response":"","status":"FAILED"}""", ""); Assert.Equal("Stato FAILED", stato.Error); var campo = Agy.Parse(0, """{"conversation_id":"c","status":"SUCCESS","error":"quota esaurita"}""", ""); Assert.Equal("quota esaurita", campo.Error); var uscita = Agy.Parse(2, "", "boom"); Assert.Equal("", uscita.Text); Assert.Contains("agy è uscito con codice 2", uscita.Error); Assert.Contains("boom", uscita.Error); } [Fact] // AG-08 public void Agy_estrazione_json_robusta() { var out_ = "Avviso: aggiornamento disponibile\n{\"conversation_id\":\"c9\",\"response\":\"risposta\",\"status\":\"SUCCESS\"}\nfine\n"; var r = Agy.Parse(0, out_, ""); Assert.Equal("risposta", r.Text); Assert.Equal("c9", r.SessionId); Assert.Null(r.Error); } [Fact] // AG-09 public void Agy_nessuna_risposta() { Assert.Equal("agy non ha restituito nessuna risposta.", Agy.Parse(0, "", "").Error); Assert.Equal("agy non ha restituito nessuna risposta.", Agy.Parse(0, """{"conversation_id":"c","response":" ","status":"SUCCESS"}""", "").Error); Assert.Equal("solo stderr", Agy.Parse(0, "non json", "solo stderr").Error); } [Fact] // AG-10 public void Agy_cli_senza_json() { var args = Agy.BuildArgs("ciao", null, false, "", "", structured: false); Assert.DoesNotContain("--output-format", args); Assert.DoesNotContain("json", args); Assert.Equal(["-p", "ciao"], args[^2..]); } [Fact] // AG-12 public void Agy_catalogo_modelli() { Assert.Equal( ["gemini-3.0-flash-low", "gemini-3.0-flash-medium", "gemini-3.0-flash-high", "claude-sonnet-4-6", "claude-opus-4-6-thinking", "gpt-oss-120b-medium"], Agy.Models.Select(m => m.Id)); Assert.Equal(["low", "medium", "high", "xhigh", "max"], Agy.Efforts); Assert.Equal("gemini-3.0-flash-low", Agy.DefaultModelId); Assert.Equal("low", Agy.DefaultEffort); Assert.Contains(Agy.Models, m => m.Id == Agy.DefaultModelId); Assert.Same(Agy, Engines.Find("agy")); } [Theory] // UP-21 [InlineData("Stable Version: 1.4.2\nBuild: abc", "1.4.2")] [InlineData("Stable Version: v2.0", "2.0")] [InlineData("1.9.9", "1.9.9")] public async Task Ultima_versione_agy(string body, string expected) { var handler = new FakeHandler(body); using var http = new HttpClient(handler); Assert.Equal(expected, await Agy.FetchLatestVersionAsync(http, CancellationToken.None)); Assert.NotNull(handler.Requested); } [Fact] public void Comando_manuale_di_aggiornamento() { Assert.Equal("brew upgrade agy", EngineUpdater.ManualCommand(Agy, InstallMethod.Homebrew)); Assert.Equal("agy update", EngineUpdater.ManualCommand(Agy, InstallMethod.Npm)); } }