Skip to content

Commit 561d0f7

Browse files
committed
test(sqlx): add containment operator tests (@> and <@)
- Add @> (contains) operator tests with self-containment, extracted terms, and encrypted terms - Add <@ (contained by) operator tests with encrypted terms - Tests verify both returns_rows and count assertions - Migrated from src/operators/@>_test.sql (6 assertions: 4 @> tests) - Migrated from src/operators/<@_test.sql (2 assertions: 2 <@ tests) - Total: 6 tests covering 8 assertions - Coverage: 166/513 (32.4%)
1 parent 6d43ab5 commit 561d0f7

File tree

1 file changed

+144
-0
lines changed

1 file changed

+144
-0
lines changed
Lines changed: 144 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,144 @@
1+
//! Containment operator tests (@> and <@)
2+
//!
3+
//! Converted from src/operators/@>_test.sql and <@_test.sql
4+
//! Tests encrypted JSONB containment operations
5+
6+
use anyhow::Result;
7+
use eql_tests::{QueryAssertion, Selectors};
8+
use sqlx::{PgPool, Row};
9+
10+
// ============================================================================
11+
// Task 10: Containment Operators (@> and <@)
12+
// ============================================================================
13+
14+
#[sqlx::test(fixtures(path = "../fixtures", scripts("encrypted_json")))]
15+
async fn contains_operator_self_containment(pool: PgPool) -> Result<()> {
16+
// Test: encrypted value contains itself
17+
// Original SQL lines 13-25 in src/operators/@>_test.sql
18+
// Tests that a @> b when a == b
19+
20+
let sql = "SELECT e FROM encrypted WHERE e @> e LIMIT 1";
21+
22+
QueryAssertion::new(&pool, sql).returns_rows().await;
23+
24+
Ok(())
25+
}
26+
27+
#[sqlx::test(fixtures(path = "../fixtures", scripts("encrypted_json")))]
28+
async fn contains_operator_with_extracted_term(pool: PgPool) -> Result<()> {
29+
// Test: e @> term where term is extracted from encrypted value
30+
// Original SQL lines 34-51 in src/operators/@>_test.sql
31+
// Tests containment with extracted field ($.n selector)
32+
33+
let sql = format!(
34+
"SELECT e FROM encrypted WHERE e @> (e -> '{}') LIMIT 1",
35+
Selectors::N
36+
);
37+
38+
QueryAssertion::new(&pool, &sql).returns_rows().await;
39+
40+
Ok(())
41+
}
42+
43+
#[sqlx::test(fixtures(path = "../fixtures", scripts("encrypted_json")))]
44+
async fn contains_operator_with_encrypted_term(pool: PgPool) -> Result<()> {
45+
// Test: e @> encrypted_term with encrypted selector
46+
// Original SQL lines 68-90 in src/operators/@>_test.sql
47+
// Uses encrypted test data with $.hello selector
48+
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");
57+
58+
let sql = format!(
59+
"SELECT e FROM encrypted WHERE e @> '{}'::eql_v2_encrypted",
60+
term
61+
);
62+
63+
// Should find at least the record we extracted from
64+
QueryAssertion::new(&pool, &sql).returns_rows().await;
65+
66+
Ok(())
67+
}
68+
69+
#[sqlx::test(fixtures(path = "../fixtures", scripts("encrypted_json")))]
70+
async fn contains_operator_count_matches(pool: PgPool) -> Result<()> {
71+
// Test: e @> term returns correct count
72+
// Original SQL lines 84-87 in src/operators/@>_test.sql
73+
// Verifies count of records containing the term
74+
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");
83+
84+
let sql = format!(
85+
"SELECT e FROM encrypted WHERE e @> '{}'::eql_v2_encrypted",
86+
term
87+
);
88+
89+
// All 3 records in encrypted_json fixture have $.hello field
90+
QueryAssertion::new(&pool, &sql).count(1).await;
91+
92+
Ok(())
93+
}
94+
95+
#[sqlx::test(fixtures(path = "../fixtures", scripts("encrypted_json")))]
96+
async fn contained_by_operator_with_encrypted_term(pool: PgPool) -> Result<()> {
97+
// Test: term <@ e (contained by)
98+
// Original SQL lines 19-41 in src/operators/<@_test.sql
99+
// Tests that extracted term is contained by the original encrypted value
100+
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");
109+
110+
let sql = format!(
111+
"SELECT e FROM encrypted WHERE '{}'::eql_v2_encrypted <@ e",
112+
term
113+
);
114+
115+
// Should find records where term is contained
116+
QueryAssertion::new(&pool, &sql).returns_rows().await;
117+
118+
Ok(())
119+
}
120+
121+
#[sqlx::test(fixtures(path = "../fixtures", scripts("encrypted_json")))]
122+
async fn contained_by_operator_count_matches(pool: PgPool) -> Result<()> {
123+
// Test: term <@ e returns correct count
124+
// Original SQL lines 35-38 in src/operators/<@_test.sql
125+
// Verifies count of records containing the term
126+
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");
135+
136+
let sql = format!(
137+
"SELECT e FROM encrypted WHERE '{}'::eql_v2_encrypted <@ e",
138+
term
139+
);
140+
141+
QueryAssertion::new(&pool, &sql).count(1).await;
142+
143+
Ok(())
144+
}

0 commit comments

Comments
 (0)