mirror of
https://github.com/openclaw/openclaw.git
synced 2026-08-17 08:02:12 -06:00
0021e51f22
* feat(apple): complete media playback and uploads * fix(apple): preserve movie picker metadata * fix(apple): harden rendition and picker routing * style(apple): fix macOS media formatting
140 lines
5.7 KiB
Swift
140 lines
5.7 KiB
Swift
import Foundation
|
|
import Testing
|
|
@testable import OpenClawChatUI
|
|
|
|
@Suite("Managed chat image attachments")
|
|
struct ChatMessageMediaAttachmentTests {
|
|
@Test func `decodes canonical managed image fields`() throws {
|
|
let message = try JSONDecoder().decode(
|
|
OpenClawChatMessage.self,
|
|
from: Data(
|
|
"""
|
|
{
|
|
"role": "assistant",
|
|
"content": [{
|
|
"type": "image",
|
|
"artifactId": "artifact_managed_image_11111111-1111-4111-8111-111111111111",
|
|
"url": "/api/chat/media/outgoing/agent%3Amain%3Amain/11111111-1111-4111-8111-111111111111/full",
|
|
"openUrl": "/api/chat/media/outgoing/agent%3Amain%3Amain/11111111-1111-4111-8111-111111111111/full",
|
|
"alt": "Chart",
|
|
"mimeType": "image/png",
|
|
"width": 1200,
|
|
"height": 800,
|
|
"sizeBytes": 2048
|
|
}]
|
|
}
|
|
""".utf8))
|
|
|
|
let image = try #require(message.content.first)
|
|
#expect(image.artifactId == "artifact_managed_image_11111111-1111-4111-8111-111111111111")
|
|
#expect(image.alt == "Chart")
|
|
#expect(image.mimeType == "image/png")
|
|
#expect(image.width == 1200)
|
|
#expect(image.height == 800)
|
|
#expect(image.sizeBytes == 2048)
|
|
#expect(image.isInlineAttachment)
|
|
}
|
|
|
|
@Test func `decodes url-only managed video as fetchable inline media`() throws {
|
|
let message = try JSONDecoder().decode(
|
|
OpenClawChatMessage.self,
|
|
from: Data(
|
|
"""
|
|
{
|
|
"role": "assistant",
|
|
"content": [{
|
|
"type": "video",
|
|
"url": "/api/chat/media/outgoing/agent%3Amain%3Amain/22222222-2222-4222-8222-222222222222/full",
|
|
"mimeType": "video/mp4",
|
|
"fileName": "demo.mp4",
|
|
"durationMs": 1250,
|
|
"playback": "transcode",
|
|
"width": 1920,
|
|
"height": 1080
|
|
}]
|
|
}
|
|
""".utf8))
|
|
|
|
let video = try #require(message.content.first)
|
|
#expect(video.artifactId == "artifact_managed_media_22222222-2222-4222-8222-222222222222")
|
|
#expect(video.mediaKind == .video)
|
|
#expect(video.durationSeconds == 1.25)
|
|
#expect(video.playback == .transcode)
|
|
#expect(video.isInlineAttachment)
|
|
}
|
|
|
|
@Test(arguments: [
|
|
(OpenClawChatMediaKind.image, "artifact_managed_image_11111111-1111-4111-8111-111111111111", true),
|
|
(OpenClawChatMediaKind.image, "artifact_managed_media_11111111-1111-4111-8111-111111111111", false),
|
|
(OpenClawChatMediaKind.audio, "artifact_managed_media_11111111-1111-4111-8111-111111111111", true),
|
|
(OpenClawChatMediaKind.video, "artifact_managed_media_11111111-1111-4111-8111-111111111111", true),
|
|
(OpenClawChatMediaKind.video, "artifact_managed_image_11111111-1111-4111-8111-111111111111", false),
|
|
])
|
|
func `routes managed artifact ids only to their media family`(
|
|
kind: OpenClawChatMediaKind,
|
|
artifactID: String,
|
|
expected: Bool)
|
|
{
|
|
#expect(kind.acceptsManagedArtifactID(artifactID) == expected)
|
|
}
|
|
|
|
@Test @MainActor func `distinct images never reconcile as the same final message`() {
|
|
let first = Self.message(artifactId: "artifact_managed_image_11111111-1111-4111-8111-111111111111")
|
|
let second = Self.message(artifactId: "artifact_managed_image_22222222-2222-4222-8222-222222222222")
|
|
|
|
#expect(
|
|
OpenClawChatViewModel.finalMessageContentFingerprint(for: first) !=
|
|
OpenClawChatViewModel.finalMessageContentFingerprint(for: second))
|
|
#expect(
|
|
OpenClawChatViewModel.messageContentFingerprint(for: first) !=
|
|
OpenClawChatViewModel.messageContentFingerprint(for: second))
|
|
}
|
|
|
|
@Test func `derives stable identity for shipped managed image blocks`() throws {
|
|
let message = try JSONDecoder().decode(
|
|
OpenClawChatMessage.self,
|
|
from: Data(
|
|
"""
|
|
{
|
|
"role": "assistant",
|
|
"content": [{
|
|
"type": "image",
|
|
"url": "/api/chat/media/outgoing/main/11111111-1111-4111-8111-111111111111/full",
|
|
"mimeType": "image/png"
|
|
}]
|
|
}
|
|
""".utf8))
|
|
|
|
#expect(
|
|
message.content.first?.artifactId ==
|
|
"artifact_managed_image_11111111-1111-4111-8111-111111111111")
|
|
}
|
|
|
|
@Test func `transcript cache preserves references without image bytes`() throws {
|
|
let message = Self.message(
|
|
artifactId: "artifact_managed_image_11111111-1111-4111-8111-111111111111")
|
|
let cached = try #require(OpenClawChatSQLiteTranscriptCache.cacheableMessages([message]).first)
|
|
let image = try #require(cached.content.first)
|
|
|
|
#expect(image.artifactId == message.content.first?.artifactId)
|
|
#expect(image.url == message.content.first?.url)
|
|
#expect(image.content == nil)
|
|
}
|
|
|
|
private static func message(artifactId: String) -> OpenClawChatMessage {
|
|
OpenClawChatMessage(
|
|
role: "assistant",
|
|
content: [
|
|
OpenClawChatMessageContent(
|
|
type: "image",
|
|
text: nil,
|
|
mimeType: "image/png",
|
|
fileName: nil,
|
|
artifactId: artifactId,
|
|
url: "/api/chat/media/outgoing/main/\(artifactId)/full",
|
|
content: nil),
|
|
],
|
|
timestamp: nil)
|
|
}
|
|
}
|