|
1 | 1 | //! Aggregate function tests |
2 | 2 | //! |
3 | | -//! Tests COUNT, MAX, MIN with encrypted data |
| 3 | +//! Tests COUNT, MAX, MIN with encrypted data including eql_v2.min() and eql_v2.max() |
4 | 4 |
|
5 | 5 | use anyhow::Result; |
6 | 6 | use sqlx::PgPool; |
@@ -64,3 +64,90 @@ async fn group_by_with_encrypted_column(pool: PgPool) -> Result<()> { |
64 | 64 |
|
65 | 65 | Ok(()) |
66 | 66 | } |
| 67 | + |
| 68 | +// ========== eql_v2.min() and eql_v2.max() Tests ========== |
| 69 | +// Source: src/encrypted/aggregates_test.sql |
| 70 | + |
| 71 | +#[sqlx::test(fixtures(path = "../fixtures", scripts("aggregate_minmax_data")))] |
| 72 | +async fn eql_v2_min_with_null_values(pool: PgPool) -> Result<()> { |
| 73 | + // Test: eql_v2.min() on NULL encrypted values returns NULL |
| 74 | + // Source SQL: ASSERT ((SELECT eql_v2.min(enc_int) FROM agg_test where enc_int IS NULL) IS NULL); |
| 75 | + |
| 76 | + let result: Option<String> = |
| 77 | + sqlx::query_scalar("SELECT eql_v2.min(enc_int)::text FROM agg_test WHERE enc_int IS NULL") |
| 78 | + .fetch_one(&pool) |
| 79 | + .await?; |
| 80 | + |
| 81 | + assert!( |
| 82 | + result.is_none(), |
| 83 | + "eql_v2.min() should return NULL when querying only NULL values" |
| 84 | + ); |
| 85 | + |
| 86 | + Ok(()) |
| 87 | +} |
| 88 | + |
| 89 | +#[sqlx::test(fixtures(path = "../fixtures", scripts("aggregate_minmax_data")))] |
| 90 | +async fn eql_v2_min_finds_minimum_encrypted_value(pool: PgPool) -> Result<()> { |
| 91 | + // Test: eql_v2.min() finds the minimum encrypted value (plain_int = 1) |
| 92 | + // Source SQL: ASSERT ((SELECT enc_int FROM agg_test WHERE plain_int = 1) = (SELECT eql_v2.min(enc_int) FROM agg_test)); |
| 93 | + |
| 94 | + // Get the expected minimum value (plain_int = 1) |
| 95 | + let expected: String = |
| 96 | + sqlx::query_scalar("SELECT enc_int::text FROM agg_test WHERE plain_int = 1") |
| 97 | + .fetch_one(&pool) |
| 98 | + .await?; |
| 99 | + |
| 100 | + // Get the actual minimum from eql_v2.min() |
| 101 | + let actual: String = sqlx::query_scalar("SELECT eql_v2.min(enc_int)::text FROM agg_test") |
| 102 | + .fetch_one(&pool) |
| 103 | + .await?; |
| 104 | + |
| 105 | + assert_eq!( |
| 106 | + actual, expected, |
| 107 | + "eql_v2.min() should return the encrypted value where plain_int = 1 (minimum)" |
| 108 | + ); |
| 109 | + |
| 110 | + Ok(()) |
| 111 | +} |
| 112 | + |
| 113 | +#[sqlx::test(fixtures(path = "../fixtures", scripts("aggregate_minmax_data")))] |
| 114 | +async fn eql_v2_max_with_null_values(pool: PgPool) -> Result<()> { |
| 115 | + // Test: eql_v2.max() on NULL encrypted values returns NULL |
| 116 | + // Source SQL: ASSERT ((SELECT eql_v2.max(enc_int) FROM agg_test where enc_int IS NULL) IS NULL); |
| 117 | + |
| 118 | + let result: Option<String> = |
| 119 | + sqlx::query_scalar("SELECT eql_v2.max(enc_int)::text FROM agg_test WHERE enc_int IS NULL") |
| 120 | + .fetch_one(&pool) |
| 121 | + .await?; |
| 122 | + |
| 123 | + assert!( |
| 124 | + result.is_none(), |
| 125 | + "eql_v2.max() should return NULL when querying only NULL values" |
| 126 | + ); |
| 127 | + |
| 128 | + Ok(()) |
| 129 | +} |
| 130 | + |
| 131 | +#[sqlx::test(fixtures(path = "../fixtures", scripts("aggregate_minmax_data")))] |
| 132 | +async fn eql_v2_max_finds_maximum_encrypted_value(pool: PgPool) -> Result<()> { |
| 133 | + // Test: eql_v2.max() finds the maximum encrypted value (plain_int = 5) |
| 134 | + // Source SQL: ASSERT ((SELECT enc_int FROM agg_test WHERE plain_int = 5) = (SELECT eql_v2.max(enc_int) FROM agg_test)); |
| 135 | + |
| 136 | + // Get the expected maximum value (plain_int = 5) |
| 137 | + let expected: String = |
| 138 | + sqlx::query_scalar("SELECT enc_int::text FROM agg_test WHERE plain_int = 5") |
| 139 | + .fetch_one(&pool) |
| 140 | + .await?; |
| 141 | + |
| 142 | + // Get the actual maximum from eql_v2.max() |
| 143 | + let actual: String = sqlx::query_scalar("SELECT eql_v2.max(enc_int)::text FROM agg_test") |
| 144 | + .fetch_one(&pool) |
| 145 | + .await?; |
| 146 | + |
| 147 | + assert_eq!( |
| 148 | + actual, expected, |
| 149 | + "eql_v2.max() should return the encrypted value where plain_int = 5 (maximum)" |
| 150 | + ); |
| 151 | + |
| 152 | + Ok(()) |
| 153 | +} |
0 commit comments