fix(codec): FLOP 子类型白名单,白名单外 STYP 落 Unsupported(ACM2-84)

- kindOf FLOP 分支仅放行现行七类(US-05 AC1),FDEL 独立分派不受影响
- 白名单外子类型(ACTT/CNCL 等 Q3 闭合目标)解码为 Unsupported,经 ACM2-83 路径记 SKIPPED、不改航班
- 补 codec 白名单回归与处理层「跳过且不触碰航班」用例
This commit is contained in:
windyboy
2026-09-21 11:44:43 +08:00
parent 3c577b4d1e
commit 29465e2131
3 changed files with 54 additions and 1 deletions
@@ -250,4 +250,25 @@ class JacksonXmlCodecTest {
val unknown = (codec.decode(raw("XYZZ", "TEST")) as DecodeResult.Ok).message
assertEquals(MsgKind.Unsupported("XYZZ-TEST"), unknown.kind)
}
@Test
fun `FLOP subtype whitelist sends only the seven current types to FlopProcessor`() {
fun raw(styp: String) = """
<MSG><META><SNDR>AODB</SNDR><SEQN>9</SEQN><DTTM>20021010090311</DTTM>
<TYPE>FLOP</TYPE><STYP>$styp</STYP></META></MSG>
""".trimIndent()
// 现行白名单 7 类(US-05 AC1
for (styp in listOf("ABTM", "DELY", "PSDT", "CKDT", "CLDT", "CHDT", "GTDT")) {
assertEquals(MsgKind.Flop(styp), (codec.decode(raw(styp)) as DecodeResult.Ok).message.kind)
}
// FDEL 独立分派,不参与白名单判定
assertEquals(MsgKind.Fdel, (codec.decode(raw("FDEL")) as DecodeResult.Ok).message.kind)
// 白名单外子类型(ACTT/CNCL 是 Q3 闭合目标)与空 STYP 都落 Unsupported,不走合并路径
assertEquals(MsgKind.Unsupported("FLOP-ACTT"), (codec.decode(raw("ACTT")) as DecodeResult.Ok).message.kind)
assertEquals(MsgKind.Unsupported("FLOP-CNCL"), (codec.decode(raw("CNCL")) as DecodeResult.Ok).message.kind)
assertEquals(MsgKind.Unsupported("FLOP-"), (codec.decode(raw("")) as DecodeResult.Ok).message.kind)
}
}
@@ -24,6 +24,7 @@ import com.gzzn.omms.msgexchange.infra.stub.StubSnapshotLog
import com.fasterxml.jackson.databind.ObjectMapper
import org.junit.jupiter.api.Assertions.assertEquals
import org.junit.jupiter.api.Assertions.assertNotNull
import org.junit.jupiter.api.Assertions.assertTrue
import org.junit.jupiter.api.Test
import java.time.Clock
import java.time.Instant
@@ -212,6 +213,28 @@ class IgnoreBranchTest {
assertEquals("refdata-pending:ARPT", row.lastError)
}
@Test
fun `flop subtype outside whitelist is skipped without touching flights`() {
val proc = StubProcState()
proc.insertIfAbsent(msgId, null)
val inbox = StubInbox()
inbox.raws[msgId] = "<RAW/>"
val msg = DecodedMessage(
meta = MetaFields("AODB", "FLOP", "ACTT", 500L, 1L),
kind = MsgKind.Unsupported("FLOP-ACTT"),
rawXml = "<RAW/>",
)
val flights = StubFlightState()
val p = processor(proc = proc, inbox = inbox, codec = codecReturning(msg))
p.processOne(head())
val row = proc.find(msgId)!!
assertEquals(ProcStatus.SKIPPED, row.state)
assertEquals("unsupported:FLOP-ACTT", row.lastError)
assertTrue(flights.snapshots.isEmpty()) // 白名单外子类型不改航班(US-05 AC1)
}
@Test
fun `ignore increments counter`() {
val proc = StubProcState()