71 lines
4.0 KiB
Swift
71 lines
4.0 KiB
Swift
import AppKit
|
|
import Foundation
|
|
import Testing
|
|
@testable import ConjureKit
|
|
@testable import Conjure
|
|
|
|
@Test func translationReturnsJapaneseAndRejectsIncompleteOrFailedResponses() async throws {
|
|
let text = try await TranslationAPI.translate("Good morning", apiKey: "test-key") { request in
|
|
#expect(request.url?.absoluteString == "https://api.openai.com/v1/responses")
|
|
#expect(request.value(forHTTPHeaderField: "Authorization") == "Bearer test-key")
|
|
let body = try #require(JSONSerialization.jsonObject(with: request.httpBody!) as? [String: Any])
|
|
#expect(body["model"] as? String == "gpt-6-luna")
|
|
#expect(body["input"] as? String == "Good morning")
|
|
#expect(body["store"] as? Bool == false)
|
|
let instructions = try #require(body["instructions"] as? String)
|
|
#expect(instructions.contains("from en to ja"))
|
|
return (Data(#"{"status":"completed","output":[{"type":"reasoning"},{"content":[{"type":"output_text","text":"おはようございます"}]}]}"#.utf8),
|
|
HTTPURLResponse(url: request.url!, statusCode: 200, httpVersion: nil, headerFields: nil)!)
|
|
}
|
|
#expect(text == "おはようございます")
|
|
for (status, body) in [(401, "secret"), (200, #"{"status":"incomplete","output":[]}"#),
|
|
(200, #"{"status":"completed","output":[{"content":[{"type":"refusal"}]}]}"#)] {
|
|
await #expect(throws: (any Error).self) {
|
|
try await TranslationAPI.translate("Hello", apiKey: "test-key") { request in
|
|
(Data(body.utf8), HTTPURLResponse(url: request.url!, statusCode: status, httpVersion: nil, headerFields: nil)!)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
@Test func translationSendsReverseLanguagePairToOpenAI() async throws {
|
|
let text = try await TranslationAPI.translate(
|
|
"おはようございます", apiKey: "test-key", sourceLanguage: "ja", targetLanguage: "en"
|
|
) { request in
|
|
let body = try #require(JSONSerialization.jsonObject(with: request.httpBody!) as? [String: Any])
|
|
let instructions = try #require(body["instructions"] as? String)
|
|
#expect(instructions.contains("from ja to en"))
|
|
#expect(body["input"] as? String == "おはようございます")
|
|
return (Data(#"{"status":"completed","output":[{"content":[{"type":"output_text","text":"Good morning"}]}]}"#.utf8),
|
|
HTTPURLResponse(url: request.url!, statusCode: 200, httpVersion: nil, headerFields: nil)!)
|
|
}
|
|
#expect(text == "Good morning")
|
|
}
|
|
|
|
@Test @MainActor func translationCommandBackNavigationRestoresSearch() throws {
|
|
_ = NSApplication.shared
|
|
let launcher = LauncherWindowController()
|
|
let content = try #require(launcher.window?.contentView)
|
|
func descendants(_ view: NSView) -> [NSView] { [view] + view.subviews.flatMap(descendants) }
|
|
let search = try #require(descendants(content).compactMap { $0 as? NSSearchField }.first)
|
|
let table = try #require(descendants(content).compactMap { $0 as? NSTableView }.first)
|
|
search.stringValue = "translate"
|
|
launcher.controlTextDidChange(Notification(name: NSControl.textDidChangeNotification, object: search))
|
|
#expect(table.numberOfRows == 1)
|
|
let cell = try #require(launcher.tableView(table, viewFor: nil, row: 0) as? ApplicationCell)
|
|
#expect(cell.textField?.stringValue == "Conjure Translate")
|
|
#expect(cell.kindLabel.stringValue == "Command")
|
|
_ = launcher.control(search, textView: NSTextView(), doCommandBy: #selector(NSResponder.insertNewline(_:)))
|
|
#expect(search.stringValue.isEmpty)
|
|
#expect(search.accessibilityLabel() == "English text to translate into Japanese")
|
|
let back = try #require(descendants(content).compactMap { $0 as? NSButton }.first {
|
|
!$0.isHidden && $0.accessibilityLabel() == "Back to applications"
|
|
})
|
|
search.stringValue = "Hello"
|
|
launcher.controlTextDidChange(Notification(name: NSControl.textDidChangeNotification, object: search))
|
|
back.performClick(nil)
|
|
#expect(search.stringValue == "translate")
|
|
#expect(back.isHidden)
|
|
#expect(table.numberOfRows == 1)
|
|
}
|