api-swift / Tests / IrdAPITests / Flows / JobsFlowTests.swift
286 words
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
import Foundation
import Testing
@testable import IrdAPI

let queuedJob = json(202, #"{"job":{"id":"j1","type":"embedding","status":"queued","created_at":"2026-09-08T10:00:00Z"}}"#)
func jobState(_ status: String, error: String? = nil) -> HTTPResponse {
    json(200, #"{"job":{"id":"j1","type":"embedding","status":"\#(status)","error":\#(error.map { "\"\($0)\"" } ?? "null"),"attempts":1,"created_at":"2026-09-08T10:00:00Z"}}"#)
}

@Suite struct JobsFlowTests {
    @Test func runEnqueuesPollsAndFetchesTheResult() async throws {
        let (client, http) = captureClient(script: [
            queuedJob, jobState("queued"), jobState("processing"), jobState("succeeded"),
            json(200, #"{"job-id":"j1","type":"embedding","result":{"vector":[0.1,0.2]}}"#),
        ])
        let result = try await client.jobs.run(.embedding(input: "x"))
        #expect(result.jobId == "j1")
        #expect(result.result["vector"] == [0.1, 0.2])
        #expect(http.trail == ["POST /jobs", "GET /jobs/j1", "GET /jobs/j1", "GET /jobs/j1", "GET /jobs/j1/result"])
        #expect(bodyJSON(http.requests.first) == ["type": "embedding", "input": "x"])
    }

    @Test func failedJobThrowsJobFailed() async throws {
        let (client, _) = captureClient(script: [queuedJob, jobState("failed", error: "boom")])
        let e = await caught { _ = try await client.jobs.run(.nlpDetectLanguage(input: "ce limbă e asta?")) }
        guard case .jobFailed(let job)? = e else { Issue.record("expected jobFailed, got \(String(describing: e))"); return }
        #expect(job.id == "j1")
        #expect(job.error == "boom")
        #expect(e?.description == "Job j1 failed: boom")
    }

    @Test func deadlineThrowsTimeoutWithTheLastJob() async throws {
        let (client, _) = captureClient(script: [queuedJob, jobState("processing")])
        let e = await caught { _ = try await client.jobs.run(.embedding(input: "x"), options: PollOptions(timeout: .seconds(-1), message: "Timed out waiting for the job")) }
        guard case .timeout(let message, let last)? = e else { Issue.record("expected timeout, got \(String(describing: e))"); return }
        #expect(message == "Timed out waiting for the job")
        #expect(last?["status"] == "processing")
    }

    @Test func buildersProduceTheWirePayloads() throws {
        let chat = try JSONValue(encoding: JobSpec.llmChat(messages: [.system("be brief"), .user("Salut!")], maxTokens: 256, temperature: 0.2))
        #expect(chat["type"] == "llm-chat")
        #expect(chat["max_tokens"] == 256)
        #expect(chat["messages"]?[1] == ["role": "user", "content": "Salut!"])
        #expect(chat["model"] == nil)
        let bulk = try JSONValue(encoding: JobSpec.domainAvailabilityBulk(domains: ["a.ro", "b.ro"]))
        #expect(bulk == ["type": "domain-availability-bulk", "domains": ["a.ro", "b.ro"]])
        let raw = try JSONValue(encoding: JobSpec.llmRawCompletion(prompt: "Once"))
        #expect(raw == ["type": "llm-raw-completion", "prompt": "Once"])
        let nlp = try JSONValue(encoding: JobSpec.nlpAnalyze(input: "text", language: .unrecognized("xx")))
        #expect(nlp["language"] == "xx")
    }
}

static mirror of HEAD · about · clone: git clone https://ird.cod-sursa.ro/api-swift.git