refactor(codec): map SIS XML through annotated DTOs

This commit is contained in:
windyboy
2026-09-09 19:48:45 +08:00
parent c2d4a76e3e
commit 3ed54d306e
7 changed files with 290 additions and 157 deletions
@@ -91,4 +91,49 @@ class JacksonXmlCodecTest {
assertEquals(com.gzzn.omms.msgexchange.domain.ErrorClass.MALFORMED, err.failure.errorClass)
assertTrue(err.failure.detail.contains("empty-or-non-xml"))
}
@Test
fun `SIS documented attributes and mixed DELY text become typed payload`() {
val raw = """
<MSG>
<META><SNDR>AODB</SNDR><SEQN>2</SEQN><DTTM>20021010090311</DTTM><TYPE>FLOP</TYPE><STYP>DELY</STYP></META>
<FLOP>
<FLID>121</FLID><FLNO>CA002</FLNO>
<ROUT RTNO="1"><APCD>CAN</APCD><SCDT>15DEC031340</SCDT></ROUT>
<DELY CODE="YY" STRT="15DEC031605" DURA="0200">Flight Delayed</DELY>
<FDIV ARES="O">Unused standard SIS field</FDIV>
</FLOP>
</MSG>
""".trimIndent()
val result = codec.decode(raw) as DecodeResult.Ok
val body = result.message.body as FlopPayload
assertEquals("1", body.collections["ROUT"]!!.single()["RTNO"])
assertEquals("CAN", body.collections["ROUT"]!!.single()["APCD"])
assertEquals("YY", body.collections["DELY"]!!.single()["CODE"])
assertEquals("Flight Delayed", body.collections["DELY"]!!.single()["REMC"])
}
@Test
fun `external entities are rejected by the XML codec`() {
val raw = """
<!DOCTYPE MSG [<!ENTITY xxe SYSTEM "file:///etc/passwd">]>
<MSG><META><SNDR>&xxe;</SNDR><SEQN>1</SEQN><DTTM>1</DTTM><TYPE>FLOP</TYPE><STYP>GTDT</STYP></META></MSG>
""".trimIndent()
val result = codec.decode(raw) as DecodeResult.Err
assertEquals(com.gzzn.omms.msgexchange.domain.ErrorClass.MALFORMED, result.failure.errorClass)
}
@Test
fun `SIS FDEL is an empty child of FLOP and still carries the flight id`() {
val raw = """
<MSG><META><SNDR>AODB</SNDR><SEQN>3</SEQN><DTTM>20021010090311</DTTM><TYPE>FLOP</TYPE><STYP>FDEL</STYP></META>
<FLOP><FLID>121112312</FLID><FFID>CA-CA101-A-12DEC031345-D</FFID><FDEL/></FLOP></MSG>
""".trimIndent()
val result = codec.decode(raw) as DecodeResult.Ok
assertEquals(MsgKind.Fdel, result.message.kind)
assertEquals("121112312", (result.message.body as FlopPayload).flid)
}
}