feat(taiga): Bulk-Abfrage und Abweichungs-Marke — das Diagramm zeigt, wo Ticket und Plan auseinanderlaufen (D91-Nachtrag 10, SPEC §9)
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
e77a4d1ce4
commit
a1e4a3bbab
@@ -154,6 +154,31 @@ class TaigaApiTest {
|
||||
result.responseBody!! shouldContain """{"id":12,"name":"In progress","closed":false}"""
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `die Bulk-Abfrage liefert eine Map unter den Werkbaum-Refs`() {
|
||||
val result = client.get()
|
||||
.uri("/api/v1/taiga/tickets?slug=mi-kunde&refs=US-123,T-1234")
|
||||
.header("X-Taiga-Token", "tok-abc123")
|
||||
.exchange()
|
||||
.returnResult(String::class.java)
|
||||
result.status.value() shouldBe 200
|
||||
result.responseBody!! shouldContain "\"US-123\""
|
||||
result.responseBody!! shouldContain "\"T-1234\""
|
||||
result.responseBody!! shouldContain "\"status\":\"In progress\""
|
||||
result.responseBody!! shouldContain "\"status\":\"Done\""
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `eine ungueltige Ref in der Bulk-Liste ist ein 400, nicht still uebersprungen`() {
|
||||
val result = client.get()
|
||||
.uri("/api/v1/taiga/tickets?slug=mi-kunde&refs=US-123,kaputt")
|
||||
.header("X-Taiga-Token", "tok-abc123")
|
||||
.exchange()
|
||||
.returnResult(String::class.java)
|
||||
result.status.value() shouldBe 400
|
||||
result.responseBody!! shouldContain "kaputt"
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `ein Status wird per Ref gesetzt und antwortet mit dem neuen Stand`() {
|
||||
val result = client.patch()
|
||||
|
||||
@@ -220,6 +220,49 @@ class TaigaClientTest {
|
||||
client().ticket("tok-abc123", "mi-kunde", 123, task = false).version shouldBe 7L
|
||||
}
|
||||
|
||||
/* ---- Bulk-Lesen (D91-Nachtrag 10) ---- */
|
||||
|
||||
@Test
|
||||
fun `tickets faechert je Ref auf und liefert die Map unter den Werkbaum-Refs`() {
|
||||
routes["/api/v1/projects/by_slug"] = 200 to PROJECT_OK
|
||||
routes["/api/v1/userstories/by_ref?project=7&ref=123"] = 200 to STORY_DETAIL
|
||||
routes["/api/v1/tasks/by_ref?project=7&ref=1234"] = 200 to TASK_DETAIL
|
||||
val map = client().tickets("tok-abc123", "mi-kunde", listOf(
|
||||
TaigaBulkRefData("US-123", task = false, nr = 123),
|
||||
TaigaBulkRefData("T-1234", task = true, nr = 1234),
|
||||
))
|
||||
|
||||
map.keys shouldBe setOf("US-123", "T-1234")
|
||||
map["US-123"]!!.status shouldBe "In progress"
|
||||
map["T-1234"]!!.status shouldBe "Done"
|
||||
/* Die Projekt-Aufloesung laeuft EINMAL, nicht je Ref. */
|
||||
requests.count { it.path == "/api/v1/projects/by_slug" } shouldBe 1
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `eine Ref, die es nicht mehr gibt, fehlt still - die uebrigen kommen trotzdem`() {
|
||||
routes["/api/v1/projects/by_slug"] = 200 to PROJECT_OK
|
||||
routes["/api/v1/userstories/by_ref?project=7&ref=123"] = 200 to STORY_DETAIL
|
||||
routes["/api/v1/userstories/by_ref?project=7&ref=999"] = 404 to NOT_FOUND
|
||||
val map = client().tickets("tok-abc123", "mi-kunde", listOf(
|
||||
TaigaBulkRefData("US-123", task = false, nr = 123),
|
||||
TaigaBulkRefData("US-999", task = false, nr = 999),
|
||||
))
|
||||
|
||||
map.keys shouldBe setOf("US-123")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `ein abgelaufenes Token bricht die ganze Bulk-Anfrage ab`() {
|
||||
routes["/api/v1/projects/by_slug"] = 200 to PROJECT_OK
|
||||
routes["/api/v1/userstories/by_ref?project=7&ref=123"] = 401 to NOT_FOUND
|
||||
val ex = shouldThrow<TaigaUpstreamException> {
|
||||
client().tickets("tok-abc123", "mi-kunde",
|
||||
listOf(TaigaBulkRefData("US-123", task = false, nr = 123)))
|
||||
}
|
||||
ex.status shouldBe 401
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `ohne konfigurierte Instanz gibt es kein Ziel`() {
|
||||
val bare = TaigaClient(TaigaProperties(apiUrl = ""))
|
||||
@@ -315,7 +358,10 @@ class TaigaClientTest {
|
||||
body = ex.requestBody.readBytes().decodeToString(),
|
||||
)
|
||||
requests += recorded!!
|
||||
val route = routes[ex.requestURI.path]
|
||||
/* Query-genaue Route vor der Pfad-Route: Die Bulk-Abfrage
|
||||
trifft denselben Pfad mit verschiedenen Refs. */
|
||||
val route = routes[ex.requestURI.path + "?" + (ex.requestURI.query ?: "")]
|
||||
?: routes[ex.requestURI.path]
|
||||
val status = route?.first ?: responseStatus
|
||||
val bytes = (route?.second ?: responseBody).encodeToByteArray()
|
||||
ex.responseHeaders.set("Content-Type", "application/json")
|
||||
|
||||
Reference in New Issue
Block a user