1515use MongoDB \Driver \Exception \EncryptionException ;
1616use MongoDB \Driver \Exception \RuntimeException ;
1717use MongoDB \Driver \WriteConcern ;
18- use MongoDB \Operation \CreateCollection ;
1918use MongoDB \Tests \CommandObserver ;
2019use PHPUnit \Framework \Assert ;
2120use PHPUnit \Framework \SkippedTestError ;
@@ -57,6 +56,8 @@ class ClientSideEncryptionSpecTest extends FunctionalTestCase
5756 'awsTemporary: Insert a document with auto encryption using the AWS provider with temporary credentials ' => 'Not yet implemented (PHPC-1751) ' ,
5857 'awsTemporary: Insert with invalid temporary credentials ' => 'Not yet implemented (PHPC-1751) ' ,
5958 'azureKMS: Insert a document with auto encryption using Azure KMS provider ' => 'RHEL platform is missing Azure root certificate (PHPLIB-619) ' ,
59+ 'timeoutMS: timeoutMS applied to listCollections to get collection schema ' => 'Not yet implemented (PHPC-1760) ' ,
60+ 'timeoutMS: remaining timeoutMS applied to find to get keyvault data ' => 'Not yet implemented (PHPC-1760) ' ,
6061 ];
6162
6263 public function setUp (): void
@@ -90,7 +91,7 @@ public static function assertCommandMatches(stdClass $expected, stdClass $actual
9091 * @param string $databaseName Name of database under test
9192 * @param string $collectionName Name of collection under test
9293 */
93- public function testClientSideEncryption (stdClass $ test , ?array $ runOn , array $ data , ?array $ keyVaultData = null , $ jsonSchema = null , ?string $ databaseName = null , ?string $ collectionName = null ): void
94+ public function testClientSideEncryption (stdClass $ test , ?array $ runOn , array $ data , ?stdClass $ encryptedFields = null , ? array $ keyVaultData = null , ? stdClass $ jsonSchema = null , ?string $ databaseName = null , ?string $ collectionName = null ): void
9495 {
9596 if (isset (self ::$ incompleteTests [$ this ->dataDescription ()])) {
9697 $ this ->markTestIncomplete (self ::$ incompleteTests [$ this ->dataDescription ()]);
@@ -107,6 +108,11 @@ public function testClientSideEncryption(stdClass $test, ?array $runOn, array $d
107108 $ databaseName = $ databaseName ?? $ this ->getDatabaseName ();
108109 $ collectionName = $ collectionName ?? $ this ->getCollectionName ();
109110
111+ // TODO: Remove this once SERVER-66901 is implemented (see: PHPLIB-884)
112+ if (isset ($ test ->clientOptions ->autoEncryptOpts ->encryptedFieldsMap )) {
113+ $ test ->clientOptions ->autoEncryptOpts ->encryptedFieldsMap = $ this ->prepareEncryptedFieldsMap ($ test ->clientOptions ->autoEncryptOpts ->encryptedFieldsMap );
114+ }
115+
110116 try {
111117 $ context = Context::fromClientSideEncryption ($ test , $ databaseName , $ collectionName );
112118 } catch (SkippedTestError $ e ) {
@@ -116,15 +122,15 @@ public function testClientSideEncryption(stdClass $test, ?array $runOn, array $d
116122 $ this ->setContext ($ context );
117123
118124 self ::insertKeyVaultData ($ context ->getClient (), $ keyVaultData );
119- $ this ->dropTestAndOutcomeCollections ();
120- $ this ->createTestCollection ($ jsonSchema );
125+ $ this ->dropTestAndOutcomeCollections (empty ( $ encryptedFields ) ? [] : [ ' encryptedFields ' => $ encryptedFields ] );
126+ $ this ->createTestCollection ($ encryptedFields , $ jsonSchema );
121127 $ this ->insertDataFixtures ($ data );
122128
123129 if (isset ($ test ->failPoint )) {
124130 $ this ->configureFailPoint ($ test ->failPoint );
125131 }
126132
127- $ context ->enableEncryption () ;
133+ $ context ->useEncryptedClientIfConfigured = true ;
128134
129135 if (isset ($ test ->expectations )) {
130136 $ commandExpectations = CommandExpectations::fromClientSideEncryption ($ context ->getClient (), $ test ->expectations );
@@ -140,7 +146,7 @@ public function testClientSideEncryption(stdClass $test, ?array $runOn, array $d
140146 $ commandExpectations ->assert ($ this , $ context );
141147 }
142148
143- $ context ->disableEncryption () ;
149+ $ context ->useEncryptedClientIfConfigured = false ;
144150
145151 if (isset ($ test ->outcome ->collection ->data )) {
146152 $ this ->assertOutcomeCollectionData ($ test ->outcome ->collection ->data , ResultExpectation::ASSERT_DOCUMENTS_MATCH );
@@ -169,6 +175,7 @@ public function provideTests()
169175 $ runOn = $ json ->runOn ?? null ;
170176 $ data = $ json ->data ?? [];
171177 // phpcs:disable Squiz.NamingConventions.ValidVariableName.MemberNotCamelCaps
178+ $ encryptedFields = $ json ->encrypted_fields ?? null ;
172179 $ keyVaultData = $ json ->key_vault_data ?? null ;
173180 $ jsonSchema = $ json ->json_schema ?? null ;
174181 $ databaseName = $ json ->database_name ?? null ;
@@ -177,7 +184,7 @@ public function provideTests()
177184
178185 foreach ($ json ->tests as $ test ) {
179186 $ name = $ group . ': ' . $ test ->description ;
180- $ testArgs [$ name ] = [$ test , $ runOn , $ data , $ keyVaultData , $ jsonSchema , $ databaseName , $ collectionName ];
187+ $ testArgs [$ name ] = [$ test , $ runOn , $ data , $ encryptedFields , $ keyVaultData , $ jsonSchema , $ databaseName , $ collectionName ];
181188 }
182189 }
183190
@@ -1331,11 +1338,20 @@ private function createInt64(string $value): Int64
13311338 return unserialize ($ int64 );
13321339 }
13331340
1334- private function createTestCollection ($ jsonSchema ): void
1341+ private function createTestCollection (? stdClass $ encryptedFields = null , ? stdClass $ jsonSchema = null ): void
13351342 {
1336- $ options = empty ($ jsonSchema ) ? [] : ['validator ' => ['$jsonSchema ' => $ jsonSchema ]];
1337- $ operation = new CreateCollection ($ this ->getContext ()->databaseName , $ this ->getContext ()->collectionName , $ options );
1338- $ operation ->execute ($ this ->getPrimaryServer ());
1343+ $ context = $ this ->getContext ();
1344+ $ options = $ context ->defaultWriteOptions ;
1345+
1346+ if (! empty ($ encryptedFields )) {
1347+ $ options ['encryptedFields ' ] = $ this ->prepareEncryptedFields ($ encryptedFields );
1348+ }
1349+
1350+ if (! empty ($ jsonSchema )) {
1351+ $ options ['validator ' ] = ['$jsonSchema ' => $ jsonSchema ];
1352+ }
1353+
1354+ $ context ->getDatabase ()->createCollection ($ context ->collectionName , $ options );
13391355 }
13401356
13411357 private function encryptCorpusValue (string $ fieldName , stdClass $ data , ClientEncryption $ clientEncryption )
@@ -1466,6 +1482,19 @@ private function prepareEncryptedFields(stdClass $encryptedFields): stdClass
14661482 return $ encryptedFields ;
14671483 }
14681484
1485+ /**
1486+ * @todo Remove this once SERVER-66901 is implemented
1487+ * @see https://jira.mongodb.org/browse/PHPLIB-884
1488+ */
1489+ private function prepareEncryptedFieldsMap (stdClass $ encryptedFieldsMap ): stdClass
1490+ {
1491+ foreach ($ encryptedFieldsMap as $ namespace => $ encryptedFields ) {
1492+ $ encryptedFieldsMap ->{$ namespace } = $ this ->prepareEncryptedFields ($ encryptedFields );
1493+ }
1494+
1495+ return $ encryptedFieldsMap ;
1496+ }
1497+
14691498 private function skipIfLocalMongocryptdIsUnavailable (): void
14701499 {
14711500 $ paths = explode (PATH_SEPARATOR , getenv ("PATH " ));
0 commit comments