Skip to content

Commit

Permalink
Replace getCastCallableForType with a cast function
Browse files Browse the repository at this point in the history
  • Loading branch information
GromNaN committed Sep 13, 2024
1 parent 7852790 commit 87db4d0
Showing 1 changed file with 29 additions and 38 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
use ArrayIterator;
use Generator;
use Iterator;
use LogicException;
use MongoDB\BSON\Binary;
use MongoDB\BSON\Decimal128;
use MongoDB\BSON\Document;
Expand Down Expand Up @@ -96,14 +97,13 @@ public function setUpWithTypeAndRangeOpts(string $type, array $rangeOpts): void
'rangeOpts' => $rangeOpts,
];

$cast = self::getCastCallableForType($type);
$fieldName = 'encrypted' . $type;

$this->collection->insertMany([
['_id' => 0, $fieldName => $this->clientEncryption->encrypt($cast(0), $encryptOpts)],
['_id' => 1, $fieldName => $this->clientEncryption->encrypt($cast(6), $encryptOpts)],
['_id' => 2, $fieldName => $this->clientEncryption->encrypt($cast(30), $encryptOpts)],
['_id' => 3, $fieldName => $this->clientEncryption->encrypt($cast(200), $encryptOpts)],
['_id' => 0, $fieldName => $this->clientEncryption->encrypt(self::cast($type, 0), $encryptOpts)],
['_id' => 1, $fieldName => $this->clientEncryption->encrypt(self::cast($type, 6), $encryptOpts)],
['_id' => 2, $fieldName => $this->clientEncryption->encrypt(self::cast($type, 30), $encryptOpts)],
['_id' => 3, $fieldName => $this->clientEncryption->encrypt(self::cast($type, 200), $encryptOpts)],
]);
}

Expand Down Expand Up @@ -193,16 +193,15 @@ public function testCase1_CanDecryptAPayload(string $type, array $rangeOpts): vo
'rangeOpts' => $rangeOpts,
];

$cast = self::getCastCallableForType($type);
$originalValue = $cast(6);
$originalValue = self::cast($type, 6);

$insertPayload = $this->clientEncryption->encrypt($originalValue, $encryptOpts);
$decryptedValue = $this->clientEncryption->decrypt($insertPayload);

/* Decryption of a 64-bit integer will likely result in a scalar int, so
* cast it back to an Int64 before comparing to the original value. */
if ($type === 'Long' && is_int($decryptedValue)) {
$decryptedValue = $cast($decryptedValue);
$decryptedValue = self::cast($type, $decryptedValue);
}

/* Use separate assertions for type and equality as assertSame isn't
Expand All @@ -228,23 +227,22 @@ public function testCase2_CanFindEncryptedRangeAndReturnTheMaximum(string $type,
'rangeOpts' => $rangeOpts,
];

$cast = self::getCastCallableForType($type);
$fieldName = 'encrypted' . $type;

$expr = [
'$and' => [
[$fieldName => ['$gte' => $cast(6)]],
[$fieldName => ['$lte' => $cast(200)]],
[$fieldName => ['$gte' => self::cast($type, 6)]],
[$fieldName => ['$lte' => self::cast($type, 200)]],
],
];

$encryptedExpr = $this->clientEncryption->encryptExpression($expr, $encryptOpts);
$cursor = $this->collection->find($encryptedExpr, ['sort' => ['_id' => 1]]);

$expectedDocuments = [
['_id' => 1, $fieldName => $cast(6)],
['_id' => 2, $fieldName => $cast(30)],
['_id' => 3, $fieldName => $cast(200)],
['_id' => 1, $fieldName => self::cast($type, 6)],
['_id' => 2, $fieldName => self::cast($type, 30)],
['_id' => 3, $fieldName => self::cast($type, 200)],
];

$this->assertMultipleDocumentsMatch($expectedDocuments, $cursor);
Expand All @@ -266,22 +264,21 @@ public function testCase3_CanFindEncryptedRangeAndReturnTheMinimum(string $type,
'rangeOpts' => $rangeOpts,
];

$cast = self::getCastCallableForType($type);
$fieldName = 'encrypted' . $type;

$expr = [
'$and' => [
[$fieldName => ['$gte' => $cast(0)]],
[$fieldName => ['$lte' => $cast(6)]],
[$fieldName => ['$gte' => self::cast($type, 0)]],
[$fieldName => ['$lte' => self::cast($type, 6)]],
],
];

$encryptedExpr = $this->clientEncryption->encryptExpression($expr, $encryptOpts);
$cursor = $this->collection->find($encryptedExpr, ['sort' => ['_id' => 1]]);

$expectedDocuments = [
['_id' => 0, $fieldName => $cast(0)],
['_id' => 1, $fieldName => $cast(6)],
['_id' => 0, $fieldName => self::cast($type, 0)],
['_id' => 1, $fieldName => self::cast($type, 6)],
];

$this->assertMultipleDocumentsMatch($expectedDocuments, $cursor);
Expand All @@ -303,14 +300,13 @@ public function testCase4_CanFindEncryptedRangeWithAnOpenRangeQuery(string $type
'rangeOpts' => $rangeOpts,
];

$cast = self::getCastCallableForType($type);
$fieldName = 'encrypted' . $type;

$expr = ['$and' => [[$fieldName => ['$gt' => $cast(30)]]]];
$expr = ['$and' => [[$fieldName => ['$gt' => self::cast($type, 30)]]]];

$encryptedExpr = $this->clientEncryption->encryptExpression($expr, $encryptOpts);
$cursor = $this->collection->find($encryptedExpr, ['sort' => ['_id' => 1]]);
$expectedDocuments = [['_id' => 3, $fieldName => $cast(200)]];
$expectedDocuments = [['_id' => 3, $fieldName => self::cast($type, 200)]];

$this->assertMultipleDocumentsMatch($expectedDocuments, $cursor);
}
Expand All @@ -331,18 +327,17 @@ public function testCase5_CanRunAnAggregationExpressionInsideExpr(string $type,
'rangeOpts' => $rangeOpts,
];

$cast = self::getCastCallableForType($type);
$fieldName = 'encrypted' . $type;
$fieldPath = '$' . $fieldName;

$expr = ['$and' => [['$lt' => [$fieldPath, $cast(30)]]]];
$expr = ['$and' => [['$lt' => [$fieldPath, self::cast($type, 30)]]]];

$encryptedExpr = $this->clientEncryption->encryptExpression($expr, $encryptOpts);
$cursor = $this->collection->find(['$expr' => $encryptedExpr], ['sort' => ['_id' => 1]]);

$expectedDocuments = [
['_id' => 0, $fieldName => $cast(0)],
['_id' => 1, $fieldName => $cast(6)],
['_id' => 0, $fieldName => self::cast($type, 0)],
['_id' => 1, $fieldName => self::cast($type, 6)],
];

$this->assertMultipleDocumentsMatch($expectedDocuments, $cursor);
Expand All @@ -367,11 +362,9 @@ public function testCase6_EncryptingADocumentGreaterThanTheMaximumErrors(string
'rangeOpts' => $rangeOpts,
];

$cast = self::getCastCallableForType($type);

$this->expectException(EncryptionException::class);
$this->expectExceptionMessage('Value must be greater than or equal to the minimum value and less than or equal to the maximum value');
$this->clientEncryption->encrypt($cast(201), $encryptOpts);
$this->clientEncryption->encrypt(self::cast($type, 201), $encryptOpts);
}

/**
Expand Down Expand Up @@ -421,11 +414,9 @@ public function testCase8_SettingPrecisionErrorsIfTheTypeIsNotDoubleOrDecimal128
'rangeOpts' => $rangeOpts + ['precision' => 2],
];

$cast = self::getCastCallableForType($type);

$this->expectException(EncryptionException::class);
$this->expectExceptionMessage('expected \'precision\' to be set with double or decimal128 index');
$this->clientEncryption->encrypt($cast(6), $encryptOpts);
$this->clientEncryption->encrypt(self::cast($type, 6), $encryptOpts);
}

private function assertMultipleDocumentsMatch(array $expectedDocuments, Iterator $actualDocuments): void
Expand All @@ -443,14 +434,14 @@ private function assertMultipleDocumentsMatch(array $expectedDocuments, Iterator
}
}

private static function getCastCallableForType(string $type): callable
private static function cast(string $type, int $value): mixed
{
return match ($type) {
'DecimalNoPrecision', 'DecimalPrecision' => fn (int $value) => new Decimal128((string) $value),
'DoubleNoPrecision', 'DoublePrecision' => fn (int $value) => (double) $value,
'Date' => fn (int $value) => new UTCDateTime($value),
'Int' => fn (int $value) => $value,
'Long' => fn (int $value) => new Int64($value),
'DecimalNoPrecision', 'DecimalPrecision' => new Decimal128((string) $value),
'DoubleNoPrecision', 'DoublePrecision' => (double) $value,
'Date' => new UTCDateTime($value),
'Int' => $value,
'Long' => new Int64($value),
default => throw new LogicException('Unsupported type: ' . $type),
};
}
Expand Down

0 comments on commit 87db4d0

Please sign in to comment.