@@ -3,6 +3,7 @@ package main
33import (
44 "fmt"
55 "log"
6+ "reflect"
67 "testing"
78
89 "github.com/cipherstash/goeql"
@@ -181,7 +182,7 @@ func TestMatchQueryEmail(t *testing.T) {
181182 assert .
Equal (
t ,
EncryptedTextField (
"[email protected] " ),
returnedExample .
EncryptedTextField ,
"EncryptedTextField should match" )
182183}
183184
184- func TestJsonbQuerySimple (t * testing.T ) {
185+ func TestJsonbQueryContainment (t * testing.T ) {
185186 engine := proxyEngine ()
186187 truncateDb (engine )
187188
@@ -242,7 +243,7 @@ func TestJsonbQuerySimple(t *testing.T) {
242243 assert .Equal (t , EncryptedJsonbField (expectedJson ), returnedExample .EncryptedJsonbField , "EncryptedJsonb field should match" )
243244}
244245
245- func TestJsonbQueryNested (t * testing.T ) {
246+ func TestJsonbQueryNestedContainment (t * testing.T ) {
246247 engine := proxyEngine ()
247248 truncateDb (engine )
248249
@@ -308,6 +309,242 @@ func TestJsonbQueryNested(t *testing.T) {
308309 assert .Equal (t , EncryptedJsonbField (expectedJson ), returnedExample .EncryptedJsonbField , "EncryptedJsonb field should match" )
309310}
310311
312+ func TestJsonbExtractionOp (t * testing.T ) {
313+ engine := proxyEngine ()
314+ truncateDb (engine )
315+
316+ expected_one := map [string ]interface {}{
317+ "nested_two" : "hello world" ,
318+ }
319+ jsonOne := map [string ]interface {}{
320+ "top" : map [string ]interface {}{
321+ "integer" : float64 (101 ),
322+ "float" : 1.234 ,
323+ "string" : "some string" ,
324+ "nested" : expected_one ,
325+ },
326+ "bottom" : "value_three" ,
327+ }
328+ expected_two := map [string ]interface {}{
329+ "nested_two" : "foo bar" ,
330+ }
331+ jsonTwo := map [string ]interface {}{
332+ "top" : map [string ]interface {}{
333+ "integer" : float64 (101 ),
334+ "float" : 1.234 ,
335+ "string" : "some string" ,
336+ "nested" : expected_two ,
337+ },
338+ "bottom" : "value_three" ,
339+ }
340+
341+ examples := []Example {
342+ {
343+ NonEncryptedField : "sydney" ,
344+ EncryptedTextField : "testing" ,
345+ EncryptedIntField : 42 ,
346+ EncryptedJsonbField : jsonOne ,
347+ },
348+ {
349+ NonEncryptedField : "melbourne" ,
350+ EncryptedIntField : 42 ,
351+ EncryptedTextField :
"[email protected] " ,
352+ EncryptedJsonbField : jsonTwo ,
353+ },
354+ }
355+
356+ inserted , err := engine .Insert (& examples )
357+
358+ if err != nil {
359+ t .Errorf ("Error inserting examples: %v" , err )
360+ }
361+
362+ assert .Equal (t , int64 (2 ), inserted , "Expected to insert 2 rows" )
363+
364+ sql := `SELECT cs_ste_vec_value_v1(encrypted_jsonb_field, ?) AS val FROM examples`
365+ ejson_path , err := goeql .EJsonPathQuery ("$.top.nested" , "examples" , "encrypted_jsonb_field" )
366+
367+ if err != nil {
368+ log .Fatalf ("Error serializing fields_encrypted query: %v" , err )
369+ }
370+ results , err := engine .Query (sql , ejson_path )
371+ if err != nil {
372+ t .Fatalf ("Could not retrieve example using extraction: %v" , err )
373+ }
374+
375+ assert .Equal (t , 2 , len (results ))
376+
377+ for i := range results {
378+
379+ var encryptedJson goeql.EncryptedJsonb
380+
381+ deserializedValue , err := encryptedJson .Deserialize (results [i ]["val" ])
382+ if err != nil {
383+ log .Fatal ("Deserialization error:" , err )
384+ }
385+ jsonb_expected_one := goeql .EncryptedJsonb (expected_one )
386+ jsonb_expected_two := goeql .EncryptedJsonb (expected_two )
387+
388+ if ! reflect .DeepEqual (deserializedValue , jsonb_expected_one ) && ! reflect .DeepEqual (deserializedValue , jsonb_expected_two ) {
389+ t .Errorf ("Expected value to be either %v or %v, but got %v" , jsonb_expected_one , jsonb_expected_two , deserializedValue )
390+ }
391+
392+ }
393+ }
394+
395+ func TestJsonbComparisonOp (t * testing.T ) {
396+ engine := proxyEngine ()
397+ truncateDb (engine )
398+
399+ jsonOne := map [string ]interface {}{
400+ "top" : map [string ]interface {}{
401+ "integer" : 3 ,
402+ "float" : 1.234 ,
403+ "string" : "some string" ,
404+ },
405+ "bottom" : "value_three" ,
406+ }
407+ jsonTwo := map [string ]interface {}{
408+ "top" : map [string ]interface {}{
409+ "integer" : 50 ,
410+ "float" : 1.234 ,
411+ "string" : "some string" ,
412+ },
413+ "bottom" : "value_three" ,
414+ }
415+ expected_id := int64 (2 )
416+ example_one := Example {
417+ Id : int64 (1 ),
418+ NonEncryptedField : "sydney" ,
419+ EncryptedTextField : "testing" ,
420+ EncryptedIntField : 42 ,
421+ EncryptedJsonbField : jsonOne ,
422+ }
423+ example_two := Example {
424+ Id : expected_id ,
425+ NonEncryptedField : "melbourne" ,
426+ EncryptedIntField : 42 ,
427+ EncryptedTextField :
"[email protected] " ,
428+ EncryptedJsonbField : jsonTwo ,
429+ }
430+
431+ examples := []Example {
432+ example_one ,
433+ example_two ,
434+ }
435+
436+ inserted , err := engine .Insert (& examples )
437+
438+ if err != nil {
439+ t .Errorf ("Error inserting examples: %v" , err )
440+ }
441+
442+ assert .Equal (t , int64 (2 ), inserted , "Expected to insert 2 rows" )
443+
444+ t .Skip ("TODO: Fix failing test due to issue with cllw ore" )
445+ path := "$.top.integer"
446+ ejson_path , err := goeql .EJsonPathQuery (path , "examples" , "encrypted_jsonb_field" )
447+
448+ if err != nil {
449+ log .Fatalf ("Error serializing fields_encrypted query: %v" , err )
450+ }
451+ value := 10
452+ comparison_value , err := goeql .JsonbQuery (value , "examples" , "encrypted_jsonb_field" )
453+
454+ if err != nil {
455+ log .Fatalf ("Error marshaling comparison value: %v" , err )
456+ }
457+ var results []Example
458+ err = engine .Where ("cs_ste_vec_term_v1(examples.encrypted_jsonb_field, ?) > cs_ste_vec_term_v1(?)" , ejson_path , comparison_value ).Find (& results )
459+
460+ if err != nil {
461+ t .Fatalf ("Could not retrieve example using comparison op: %v" , err )
462+ }
463+
464+ assert .Equal (t , 1 , len (results ))
465+ assert .Equal (t , expected_id , results [0 ].Id )
466+ }
467+
468+ func TestJsonbTermsOp (t * testing.T ) {
469+ engine := proxyEngine ()
470+ truncateDb (engine )
471+
472+ jsonOne := map [string ]interface {}{
473+ "top" : map [string ]interface {}{
474+ "integer" : 3 ,
475+ "float" : 1.234 ,
476+ "string" : "some string" ,
477+ "nums" : []int64 {1 , 2 , 3 },
478+ },
479+ "bottom" : "value_three" ,
480+ }
481+ jsonTwo := map [string ]interface {}{
482+ "top" : map [string ]interface {}{
483+ "integer" : 50 ,
484+ "float" : 1.234 ,
485+ "string" : "some string" ,
486+ "nums" : []int64 {4 , 5 , 6 },
487+ },
488+ "bottom" : "value_three" ,
489+ }
490+ expected_id := int64 (2 )
491+ example_one := Example {
492+ Id : int64 (1 ),
493+ NonEncryptedField : "sydney" ,
494+ EncryptedTextField : "testing" ,
495+ EncryptedIntField : 42 ,
496+ EncryptedJsonbField : jsonOne ,
497+ }
498+ example_two := Example {
499+ Id : expected_id ,
500+ NonEncryptedField : "melbourne" ,
501+ EncryptedIntField : 42 ,
502+ EncryptedTextField :
"[email protected] " ,
503+ EncryptedJsonbField : jsonTwo ,
504+ }
505+
506+ examples := []Example {
507+ example_one ,
508+ example_two ,
509+ }
510+
511+ inserted , err := engine .Insert (& examples )
512+
513+ if err != nil {
514+ t .Errorf ("Error inserting examples: %v" , err )
515+ }
516+
517+ assert .Equal (t , int64 (2 ), inserted , "Expected to insert 2 rows" )
518+
519+ // Serialize value as jsonb
520+ value := 5
521+ comparison_value , err := goeql .JsonbQuery (value , "examples" , "encrypted_jsonb_field" )
522+ if err != nil {
523+ log .Fatalf ("Error marshaling comparison value: %v" , err )
524+ }
525+ // Serialize path
526+ path := "$.top.nums[*]"
527+ ejson_path , err := goeql .EJsonPathQuery (path , "examples" , "encrypted_jsonb_field" )
528+
529+ sql := `SELECT * from examples e
530+ WHERE EXISTS (
531+ SELECT 1
532+ FROM unnest(cs_ste_vec_terms_v1(e.encrypted_jsonb_field, ?)) AS term
533+ WHERE term > cs_ste_vec_term_v1(?)
534+ )`
535+
536+ if err != nil {
537+ log .Fatalf ("Error serializing encrypted_jsonb_field query: %v" , err )
538+ }
539+ t .Skip ("TODO: Fix failing test due to issue with cllw ore" )
540+ results , err := engine .Query (sql , ejson_path , comparison_value )
541+ if err != nil {
542+ t .Fatalf ("Could not retrieve example using terms: %v" , err )
543+ }
544+
545+ assert .Equal (t , 1 , len (results ))
546+ }
547+
311548func TestOreStringRangeQuery (t * testing.T ) {
312549 engine := proxyEngine ()
313550 truncateDb (engine )
@@ -513,3 +750,14 @@ func TestUniqueStringQuery(t *testing.T) {
513750
514751 assert .Equal (t , expected , returnedExample .EncryptedTextField , "EncryptedText field should match" )
515752}
753+
754+ func generateJsonbData (value_one string , value_two string , value_three string ) map [string ]any {
755+ data := map [string ]any {
756+ "top" : map [string ]any {
757+ "nested" : []any {value_one , value_two },
758+ },
759+ "bottom" : value_three ,
760+ }
761+
762+ return data
763+ }
0 commit comments