11import datetime
22import uuid
33from decimal import Decimal
4+ from operator import attrgetter
45
56from bson import ObjectId
67from django .db import DatabaseError
2021 BigIntegerModel ,
2122 Billing ,
2223 BinaryModel ,
24+ Book ,
2325 BooleanModel ,
2426 CharModel ,
2527 DateModel ,
@@ -217,6 +219,23 @@ def test_time(self):
217219
218220
219221class QueryTests (EncryptionTestCase ):
222+ def test_aggregate (self ):
223+ msg = (
224+ "Aggregation stage $internalFacetTeeConsumer is not allowed or "
225+ "supported with automatic encryption."
226+ )
227+ with self .assertRaisesMessage (DatabaseError , msg ):
228+ list (IntegerModel .objects .aggregate (Avg ("value" )))
229+
230+ def test_alias (self ):
231+ msg = (
232+ "Cannot group on field '_id.value' which is encrypted with the "
233+ "random algorithm or whose encryption properties are not known "
234+ "until runtime"
235+ )
236+ with self .assertRaisesMessage (DatabaseError , msg ):
237+ list (IntegerModel .objects .alias (avg = Avg ("value" )))
238+
220239 def test_annotate (self ):
221240 msg = (
222241 "Cannot group on field '_id.value' which is encrypted with the "
@@ -226,6 +245,27 @@ def test_annotate(self):
226245 with self .assertRaisesMessage (DatabaseError , msg ):
227246 list (IntegerModel .objects .annotate (avg = Avg ("value" )))
228247
248+ def test_bulk_create (self ):
249+ CharModel .objects .bulk_create ([CharModel (value = "abc" ), CharModel (value = "xyz" )])
250+ self .assertQuerySetEqual (
251+ CharModel .objects .order_by ("pk" ), ["abc" , "xyz" ], attrgetter ("value" )
252+ )
253+
254+ def test_bulk_update (self ):
255+ objs = [
256+ CharModel .objects .create (value = "abc" ),
257+ CharModel .objects .create (value = "xyz" ),
258+ ]
259+ objs [0 ].value = "def"
260+ objs [1 ].value = "mno"
261+ msg = "Multi-document updates are not allowed with Queryable Encryption"
262+ with self .assertRaisesMessage (DatabaseError , msg ):
263+ CharModel .objects .bulk_update (objs , ["value" ])
264+
265+ def test_contains (self ):
266+ obj = CharModel .objects .create (value = "abc" )
267+ self .assertIs (CharModel .objects .contains (obj ), True )
268+
229269 def test_count (self ):
230270 msg = (
231271 "Aggregation stage $internalFacetTeeConsumer is not allowed or "
@@ -248,32 +288,66 @@ def test_datetimes(self):
248288 with self .assertRaisesMessage (DatabaseError , msg ):
249289 list (DateTimeModel .objects .datetimes ("value" , "year" ))
250290
291+ def test_distinct (self ):
292+ msg = (
293+ "Cannot group on field '_id.value' which is encrypted with the "
294+ "random algorithm or whose encryption properties are not known "
295+ "until runtime"
296+ )
297+ with self .assertRaisesMessage (DatabaseError , msg ):
298+ list (CharModel .objects .distinct ("value" ))
299+
300+ def test_exclude (self ):
301+ obj1 = CharModel .objects .create (value = "abc" )
302+ obj2 = CharModel .objects .create (value = "xyz" )
303+ self .assertSequenceEqual (CharModel .objects .exclude (value = obj1 .value ), [obj2 ])
304+
251305 def test_exists (self ):
252306 self .assertIs (CharModel .objects .exists (), False )
253307
308+ def test_get_or_create (self ):
309+ obj1 , created1 = CharModel .objects .get_or_create (value = "abc" )
310+ self .assertIs (created1 , True )
311+ obj2 , created2 = CharModel .objects .get_or_create (value = "abc" )
312+ self .assertIs (created2 , False )
313+ self .assertEqual (obj1 , obj2 )
314+
315+ def test_join (self ):
316+ list (Book .objects .filter (author__name = "xxx" ))
317+
254318 def test_order_by (self ):
255319 msg = "Cannot add an encrypted field as a prefix of another encrypted field"
256320 with self .assertRaisesMessage (DatabaseError , msg ):
257321 list (CharModel .objects .order_by ("value" ))
258322
323+ def test_select_related (self ):
324+ list (Book .objects .select_related ("author" ))
325+
326+ def test_update (self ):
327+ msg = "Multi-document updates are not allowed with Queryable Encryption"
328+ with self .assertRaisesMessage (DatabaseError , msg ):
329+ self .assertEqual (CharModel .objects .update (value = "xyz" ), 1 )
330+
331+ def test_update_or_create (self ):
332+ # TODO
333+ # msg = "Multi-document updates are not allowed with Queryable Encryption"
334+ # with self.assertRaisesMessage(DatabaseError, msg):
335+ # obj, created = CharModel.objects.update_or_create(value="xyz"), 1)
336+ pass
337+
338+ def test_union (self ):
339+ msg = "Aggregation stage $unionWith is not allowed or supported with automatic encryption."
340+ qs1 = IntegerModel .objects .filter (value__gt = 1 )
341+ qs2 = IntegerModel .objects .filter (value__gte = 8 )
342+ with self .assertRaisesMessage (DatabaseError , msg ):
343+ list (qs1 .union (qs2 ))
344+
259345 def test_values (self ):
260346 list (CharModel .objects .values ("value" ))
261347
262348 def test_values_list (self ):
263349 list (CharModel .objects .values_list ("value" ))
264350
265- def test_distinct (self ):
266- msg = (
267- "Cannot group on field '_id.value' which is encrypted with the "
268- "random algorithm or whose encryption properties are not known "
269- "until runtime"
270- )
271- with self .assertRaisesMessage (DatabaseError , msg ):
272- list (CharModel .objects .distinct ("value" ))
273-
274- def test_only (self ):
275- list (CharModel .objects .only ("value" ))
276-
277351
278352class FieldMixinTests (EncryptionTestCase ):
279353 def test_db_index (self ):
0 commit comments