44//! Tests encrypted JSONB containment operations
55
66use anyhow:: Result ;
7- use eql_tests:: { QueryAssertion , Selectors } ;
8- use sqlx:: { PgPool , Row } ;
7+ use eql_tests:: { get_encrypted_term , QueryAssertion , Selectors } ;
8+ use sqlx:: PgPool ;
99
1010// ============================================================================
1111// Task 10: Containment Operators (@> and <@)
@@ -40,20 +40,30 @@ async fn contains_operator_with_extracted_term(pool: PgPool) -> Result<()> {
4040 Ok ( ( ) )
4141}
4242
43+ #[ sqlx:: test( fixtures( path = "../fixtures" , scripts( "encrypted_json" ) ) ) ]
44+ async fn contains_operator_term_does_not_contain_full_value ( pool : PgPool ) -> Result < ( ) > {
45+ // Test: term does NOT contain full encrypted value (asymmetric containment)
46+ // Original SQL lines 48-49 in src/operators/@>_test.sql
47+ // Verifies that while e @> term is true, term @> e is false
48+
49+ let sql = format ! (
50+ "SELECT e FROM encrypted WHERE (e -> '{}') @> e LIMIT 1" ,
51+ Selectors :: N
52+ ) ;
53+
54+ // Should return 0 records - extracted term cannot contain the full encrypted value
55+ QueryAssertion :: new ( & pool, & sql) . count ( 0 ) . await ;
56+
57+ Ok ( ( ) )
58+ }
59+
4360#[ sqlx:: test( fixtures( path = "../fixtures" , scripts( "encrypted_json" ) ) ) ]
4461async fn contains_operator_with_encrypted_term ( pool : PgPool ) -> Result < ( ) > {
4562 // Test: e @> encrypted_term with encrypted selector
4663 // Original SQL lines 68-90 in src/operators/@>_test.sql
4764 // Uses encrypted test data with $.hello selector
4865
49- // Get encrypted term by extracting $.hello from first record
50- let sql_create = format ! (
51- "SELECT (e -> '{}')::text FROM encrypted LIMIT 1" ,
52- Selectors :: HELLO
53- ) ;
54- let row = sqlx:: query ( & sql_create) . fetch_one ( & pool) . await ?;
55- let term: Option < String > = row. try_get ( 0 ) ?;
56- let term = term. expect ( "Should extract encrypted term" ) ;
66+ let term = get_encrypted_term ( & pool, Selectors :: HELLO ) . await ?;
5767
5868 let sql = format ! (
5969 "SELECT e FROM encrypted WHERE e @> '{}'::eql_v2_encrypted" ,
@@ -72,21 +82,15 @@ async fn contains_operator_count_matches(pool: PgPool) -> Result<()> {
7282 // Original SQL lines 84-87 in src/operators/@>_test.sql
7383 // Verifies count of records containing the term
7484
75- // Get encrypted term for $.hello
76- let sql_create = format ! (
77- "SELECT (e -> '{}')::text FROM encrypted LIMIT 1" ,
78- Selectors :: HELLO
79- ) ;
80- let row = sqlx:: query ( & sql_create) . fetch_one ( & pool) . await ?;
81- let term: Option < String > = row. try_get ( 0 ) ?;
82- let term = term. expect ( "Should extract encrypted term" ) ;
85+ let term = get_encrypted_term ( & pool, Selectors :: HELLO ) . await ?;
8386
8487 let sql = format ! (
8588 "SELECT e FROM encrypted WHERE e @> '{}'::eql_v2_encrypted" ,
8689 term
8790 ) ;
8891
89- // All 3 records in encrypted_json fixture have $.hello field
92+ // Expects 1 match: containment checks the specific encrypted term value,
93+ // not just the presence of the $.hello field
9094 QueryAssertion :: new ( & pool, & sql) . count ( 1 ) . await ;
9195
9296 Ok ( ( ) )
@@ -98,14 +102,7 @@ async fn contained_by_operator_with_encrypted_term(pool: PgPool) -> Result<()> {
98102 // Original SQL lines 19-41 in src/operators/<@_test.sql
99103 // Tests that extracted term is contained by the original encrypted value
100104
101- // Get encrypted term for $.hello
102- let sql_create = format ! (
103- "SELECT (e -> '{}')::text FROM encrypted LIMIT 1" ,
104- Selectors :: HELLO
105- ) ;
106- let row = sqlx:: query ( & sql_create) . fetch_one ( & pool) . await ?;
107- let term: Option < String > = row. try_get ( 0 ) ?;
108- let term = term. expect ( "Should extract encrypted term" ) ;
105+ let term = get_encrypted_term ( & pool, Selectors :: HELLO ) . await ?;
109106
110107 let sql = format ! (
111108 "SELECT e FROM encrypted WHERE '{}'::eql_v2_encrypted <@ e" ,
@@ -124,14 +121,7 @@ async fn contained_by_operator_count_matches(pool: PgPool) -> Result<()> {
124121 // Original SQL lines 35-38 in src/operators/<@_test.sql
125122 // Verifies count of records containing the term
126123
127- // Get encrypted term for $.hello
128- let sql_create = format ! (
129- "SELECT (e -> '{}')::text FROM encrypted LIMIT 1" ,
130- Selectors :: HELLO
131- ) ;
132- let row = sqlx:: query ( & sql_create) . fetch_one ( & pool) . await ?;
133- let term: Option < String > = row. try_get ( 0 ) ?;
134- let term = term. expect ( "Should extract encrypted term" ) ;
124+ let term = get_encrypted_term ( & pool, Selectors :: HELLO ) . await ?;
135125
136126 let sql = format ! (
137127 "SELECT e FROM encrypted WHERE '{}'::eql_v2_encrypted <@ e" ,
0 commit comments