Files
oai-swift/oAITests/JarvisModelsTests.swift
T
rune 1925c9c657 Add clickable run detail view to Jarvis run history; fix field mismatches
Each row in the Run History list now opens a Run Details sheet showing
the full, untruncated output/error (the old inline chevron-expand
capped output at 20 lines) plus duration, trigger, tokens, and cost.
Output/error use an explicit Copy button rather than
.textSelection(.enabled), to avoid the same Escape-beeps-instead-of-
dismissing bug just fixed in ModelInfoView.

While wiring this up, found the JarvisAgentRun model didn't match the
real oAI-Web API response shape: output decoded from a nonexistent
"output" key instead of "result" (always nil, hence "No output for
this run" even on successful runs with real content), finishedAt
decoded from "finished_at" instead of "ended_at" (Duration silently
never showed), and the status icon only recognized "completed"/
"failed" instead of the API's actual "success"/"error" values (plain
gray circle instead of a green checkmark). Fixed all three, verified
against a real API response, added 4 decoding tests.
2026-08-07 13:31:39 +02:00

68 lines
2.7 KiB
Swift

//
// JarvisModelsTests.swift
// oAITests
//
// SPDX-License-Identifier: PolyForm-Noncommercial-1.0.0
// Copyright (C) 2026 Rune Olsen
import Testing
import Foundation
@testable import Confab
@Suite("JarvisAgentRun decoding")
struct JarvisModelsTests {
// Real shape returned by the oAI-Web /api/agents/{id}/runs endpoint — confirmed by Rune
// against a live run. Guards against the "result"/"output" and "ended_at"/"finished_at"
// field-name mismatch that shipped in the initial Run Details modal (output always showed
// "No output for this run" even when the API had real content).
private static let sampleJSON = """
{
"id": "8628fa26-8ff1-4053-b106-8ba84a0e10e0",
"agent_id": "531c884b-a401-4985-8717-bfa6bcc1d148",
"started_at": "2026-08-07T10:00:00.135999+00:00",
"ended_at": "2026-08-07T10:00:13.815956+00:00",
"status": "success",
"input_tokens": 25615,
"output_tokens": 1233,
"cost_usd": 0.031780000776052475,
"result": "Infrastructure Status: HEALTHY",
"error": null,
"model": "anthropic:claude-haiku-4-5-20251001"
}
"""
@Test("Decodes the API's 'result' field into .output")
func decodesResultIntoOutput() throws {
let run = try JSONDecoder().decode(JarvisAgentRun.self, from: Data(Self.sampleJSON.utf8))
#expect(run.output == "Infrastructure Status: HEALTHY")
}
@Test("Decodes the API's 'ended_at' field into .finishedAt")
func decodesEndedAtIntoFinishedAt() throws {
let run = try JSONDecoder().decode(JarvisAgentRun.self, from: Data(Self.sampleJSON.utf8))
#expect(run.finishedAt == "2026-08-07T10:00:13.815956+00:00")
}
@Test("Decodes a full real run without losing any field")
func decodesAllFields() throws {
let run = try JSONDecoder().decode(JarvisAgentRun.self, from: Data(Self.sampleJSON.utf8))
#expect(run.id == "8628fa26-8ff1-4053-b106-8ba84a0e10e0")
#expect(run.agentId == "531c884b-a401-4985-8717-bfa6bcc1d148")
#expect(run.status == "success")
#expect(run.startedAt == "2026-08-07T10:00:00.135999+00:00")
#expect(run.inputTokens == 25615)
#expect(run.outputTokens == 1233)
#expect(run.totalTokens == 26848)
#expect(run.costUsd == 0.031780000776052475)
#expect(run.error == nil)
}
@Test("A finished run with both started_at and ended_at produces a non-nil duration")
func computesDurationFromRealFieldNames() throws {
let run = try JSONDecoder().decode(JarvisAgentRun.self, from: Data(Self.sampleJSON.utf8))
#expect(run.formattedDuration != nil)
#expect(run.formattedDuration == "13s")
}
}