@@ -80,6 +80,7 @@ func TestDeserializeValue(t *testing.T) {
8080 logger : logger .NewLogger ("kafka_test" ),
8181 }
8282 kJSON .srClient .CodecJsonEnabled (true )
83+ kJSON .useAvroJSON = false
8384 schemaJSON , _ := registryJSON .CreateSchema ("my-topic-value" , testSchema1 , srclient .Avro )
8485
8586 // set up for Standard JSON
@@ -194,6 +195,41 @@ func TestDeserializeValue(t *testing.T) {
194195 _ , err := kInv .DeserializeValue (& msg , handlerConfig )
195196 require .Error (t , err , "schema registry details not set" )
196197 })
198+
199+ t .Run ("verifying issue with union types due to codec state mutation is fixed" , func (t * testing.T ) {
200+ // Arrange
201+ testSchemaUnion := `["null", "long"]`
202+
203+ // In happy path, codec is initialized and NativeFromBinary is called first, which sets the states of the codec
204+ codecCard1 , err := goavro .NewCodecForStandardJSONFull (testSchemaUnion )
205+ require .NoError (t , err )
206+
207+ datum1 , _ , err := codecCard1 .NativeFromBinary ([]byte {0x02 , 0x06 })
208+ require .NoError (t , err )
209+
210+ // As expected, the datum is a long with value 3
211+ require .Equal (t , int64 (3 ), datum1 .(map [string ]any )["long" ])
212+
213+ // Reproducing the error when NativeFromTextual is called before NativeFromBinary, which changes the states of the codec
214+ codecCard2 , err := goavro .NewCodecForStandardJSONFull (testSchemaUnion )
215+ require .NoError (t , err )
216+
217+ // Trigger textual path that mutates states
218+ codecCard2 .NativeFromTextual ([]byte ("1" ))
219+
220+ // Binary for union index 1 (long) with value 3: 0x02 0x06
221+ datum , _ , err := codecCard2 .NativeFromBinary ([]byte {0x02 , 0x06 })
222+ require .NoError (t , err )
223+
224+ // Prior to bug fix, the datum would be returned as a {"null", 3} but should return '{"long":3}'!
225+ require .Nil (t , datum .(map [string ]any )["null" ])
226+ require .Equal (t , int64 (3 ), datum .(map [string ]any )["long" ])
227+
228+ // As a result, next call to TextualFromNative would fail with "Cannot encode textual union: cannot encode textual null: expected: Go nil; received: int64"
229+ act , err := codecCard2 .TextualFromNative (nil , datum )
230+ require .NoError (t , err )
231+ require .Equal (t , []byte ("3" ), act )
232+ })
197233}
198234
199235func formatByteRecord (schemaID int , valueBytes []byte ) []byte {
@@ -249,12 +285,14 @@ func TestSerializeValueCachingDisabled(t *testing.T) {
249285 srClient : registryJSON ,
250286 schemaCachingEnabled : false ,
251287 logger : logger .NewLogger ("kafka_test" ),
288+ useAvroJSON : false ,
252289 }
253290
254291 kAvroJSON := Kafka {
255292 srClient : registryAvroJSON ,
256293 schemaCachingEnabled : false ,
257294 logger : logger .NewLogger ("kafka_test" ),
295+ useAvroJSON : true ,
258296 }
259297
260298 t .Run ("valueSchemaType not set, leave value as is" , func (t * testing.T ) {
@@ -327,6 +365,7 @@ func TestSerializeValueCachingEnabled(t *testing.T) {
327365 latestSchemaCache : make (map [string ]SchemaCacheEntry ),
328366 latestSchemaCacheTTL : time .Minute * 5 ,
329367 logger : logger .NewLogger ("kafka_test" ),
368+ useAvroJSON : false ,
330369 }
331370
332371 t .Run ("valueSchemaType not set, leave value as is" , func (t * testing.T ) {
0 commit comments