@@ -285,6 +285,35 @@ func TestLoadCMVConfigs(t *testing.T) {
285285 assert .True (t , configs [0 ].AppendSourceKey )
286286}
287287
288+ func TestLoadCMVConfigsNegativeIndex (t * testing.T ) {
289+ tmpFile , err := os .CreateTemp ("" , "cmv-test-*.json" )
290+ require .NoError (t , err )
291+ defer os .Remove (tmpFile .Name ())
292+
293+ content := `[{"source_table":"events","view_id":"events_by_account","key_separator":"#","key_mapping":[-1,0]}]`
294+ _ , err = tmpFile .WriteString (content )
295+ require .NoError (t , err )
296+ tmpFile .Close ()
297+
298+ _ , err = LoadCMVConfigs (tmpFile .Name ())
299+ require .Error (t , err )
300+ assert .Contains (t , err .Error (), "negative" )
301+ }
302+
303+ func TestCMVTransformKeyOutOfBounds (t * testing.T ) {
304+ inst := & cmvInstance {
305+ config : CMVConfig {
306+ SourceTable : "events" ,
307+ ViewID : "events_by_account" ,
308+ KeySeparator : "#" ,
309+ KeyMapping : []int {0 , 99 }, // index 99 is out of bounds
310+ },
311+ }
312+ // Should not panic; out-of-bounds index produces an empty component.
313+ got := inst .transformKey ("only#two#parts" )
314+ assert .Equal (t , "only#" , got )
315+ }
316+
288317func TestParseCMVConfigFromSQL (t * testing.T ) {
289318 // Standard Bigtable CMV SQL pattern: plain SPLIT (no CAST), _key aliased,
290319 // alias appears in ORDER BY to set AppendSourceKey = true.
0 commit comments