@@ -1377,6 +1377,27 @@ def test_field_updates(self):
13771377 expected_data = {'a' : {'b' : data ['a' ]['b' ]}}
13781378 self .assertEqual (actual_data , expected_data )
13791379
1380+ def test_field_updates_w_empty_value (self ):
1381+ import collections
1382+ from google .cloud .firestore_v1beta1 import _helpers
1383+ from google .cloud .firestore_v1beta1 .constants import SERVER_TIMESTAMP
1384+
1385+ # "Cheat" and use OrderedDict-s so that iteritems() is deterministic.
1386+ data = collections .OrderedDict ((
1387+ ('a' , {'b' : 10 }),
1388+ ('c.d' , {'e' : SERVER_TIMESTAMP }),
1389+ ('f.g' , SERVER_TIMESTAMP ),
1390+ ('h' , {}),
1391+ ))
1392+ transform_paths , actual_data , field_paths = self ._call_fut (data )
1393+ self .assertEqual (
1394+ transform_paths ,
1395+ [_helpers .FieldPath ('c' , 'd' , 'e' ),
1396+ _helpers .FieldPath ('f' , 'g' )])
1397+
1398+ expected_data = {'a' : {'b' : data ['a' ]['b' ]}, 'h' : {}}
1399+ self .assertEqual (actual_data , expected_data )
1400+
13801401
13811402class Test_canonicalize_field_paths (unittest .TestCase ):
13821403
@@ -1460,78 +1481,108 @@ def test_it(self):
14601481class Test_pbs_for_set (unittest .TestCase ):
14611482
14621483 @staticmethod
1463- def _call_fut (document_path , document_data , option ):
1484+ def _call_fut (document_path , document_data , merge = False , exists = None ):
14641485 from google .cloud .firestore_v1beta1 ._helpers import pbs_for_set
14651486
1466- return pbs_for_set (document_path , document_data , option )
1487+ return pbs_for_set (
1488+ document_path , document_data , merge = merge , exists = exists )
14671489
1468- def _helper (self , merge = False , do_transform = False , ** write_kwargs ):
1469- from google .cloud .firestore_v1beta1 .constants import SERVER_TIMESTAMP
1470- from google .cloud .firestore_v1beta1 .gapic import enums
1471- from google .cloud .firestore_v1beta1 .proto import common_pb2
1490+ @staticmethod
1491+ def _make_write_w_document (document_path , ** data ):
14721492 from google .cloud .firestore_v1beta1 .proto import document_pb2
14731493 from google .cloud .firestore_v1beta1 .proto import write_pb2
1494+ from google .cloud .firestore_v1beta1 ._helpers import encode_dict
14741495
1475- document_path = _make_ref_string (
1476- u'little' , u'town' , u'of' , u'ham' )
1477- field_name1 = 'cheese'
1478- value1 = 1.5
1479- field_name2 = 'crackers'
1480- value2 = True
1481- field_name3 = 'butter'
1496+ return write_pb2 .Write (
1497+ update = document_pb2 .Document (
1498+ name = document_path ,
1499+ fields = encode_dict (data ),
1500+ ),
1501+ )
1502+
1503+ @staticmethod
1504+ def _make_write_w_transform (document_path , fields ):
1505+ from google .cloud .firestore_v1beta1 .proto import write_pb2
1506+ from google .cloud .firestore_v1beta1 .gapic import enums
1507+
1508+ server_val = enums .DocumentTransform .FieldTransform .ServerValue
1509+ transforms = [
1510+ write_pb2 .DocumentTransform .FieldTransform (
1511+ field_path = field , set_to_server_value = server_val .REQUEST_TIME )
1512+ for field in fields
1513+ ]
1514+
1515+ return write_pb2 .Write (
1516+ transform = write_pb2 .DocumentTransform (
1517+ document = document_path ,
1518+ field_transforms = transforms ,
1519+ ),
1520+ )
1521+
1522+ def _helper (self , merge = False , do_transform = False , exists = None ,
1523+ empty_val = False ):
1524+ from google .cloud .firestore_v1beta1 .constants import SERVER_TIMESTAMP
1525+ from google .cloud .firestore_v1beta1 .proto import common_pb2
14821526
1527+ document_path = _make_ref_string (u'little' , u'town' , u'of' , u'ham' )
14831528 document_data = {
1484- field_name1 : value1 ,
1485- field_name2 : value2 ,
1529+ 'cheese' : 1.5 ,
1530+ 'crackers' : True ,
14861531 }
1532+
14871533 if do_transform :
1488- document_data [field_name3 ] = SERVER_TIMESTAMP
1534+ document_data ['butter' ] = SERVER_TIMESTAMP
14891535
1490- write_pbs = self ._call_fut (document_path , document_data , merge )
1536+ if empty_val :
1537+ document_data ['mustard' ] = {}
14911538
1492- expected_update_pb = write_pb2 .Write (
1493- update = document_pb2 .Document (
1494- name = document_path ,
1495- fields = {
1496- field_name1 : _value_pb (double_value = value1 ),
1497- field_name2 : _value_pb (boolean_value = value2 ),
1498- },
1499- ),
1500- ** write_kwargs
1501- )
1502- expected_pbs = [expected_update_pb ]
1539+ write_pbs = self ._call_fut (
1540+ document_path , document_data , merge , exists )
1541+
1542+ if empty_val :
1543+ update_pb = self ._make_write_w_document (
1544+ document_path , cheese = 1.5 , crackers = True , mustard = {},
1545+ )
1546+ else :
1547+ update_pb = self ._make_write_w_document (
1548+ document_path , cheese = 1.5 , crackers = True ,
1549+ )
1550+ expected_pbs = [update_pb ]
15031551
15041552 if merge :
1505- field_paths = [field_name1 , field_name2 ]
1506- mask = common_pb2 .DocumentMask (field_paths = sorted (field_paths ))
1507- expected_pbs [0 ].update_mask .CopyFrom (mask )
1553+ field_paths = sorted (['cheese' , 'crackers' ])
1554+ update_pb .update_mask .CopyFrom (
1555+ common_pb2 .DocumentMask (field_paths = field_paths ))
1556+
1557+ if exists is not None :
1558+ update_pb .current_document .CopyFrom (
1559+ common_pb2 .Precondition (exists = exists ))
15081560
15091561 if do_transform :
1510- server_val = enums .DocumentTransform .FieldTransform .ServerValue
1511- expected_transform_pb = write_pb2 .Write (
1512- transform = write_pb2 .DocumentTransform (
1513- document = document_path ,
1514- field_transforms = [
1515- write_pb2 .DocumentTransform .FieldTransform (
1516- field_path = field_name3 ,
1517- set_to_server_value = server_val .REQUEST_TIME ,
1518- ),
1519- ],
1520- ),
1521- )
1522- expected_pbs .append (expected_transform_pb )
1562+ expected_pbs .append (
1563+ self ._make_write_w_transform (document_path , fields = ['butter' ]))
15231564
15241565 self .assertEqual (write_pbs , expected_pbs )
15251566
1526- def test_without_option (self ):
1567+ def test_without_merge (self ):
15271568 self ._helper ()
15281569
1529- def test_with_merge_option (self ):
1570+ def test_with_merge (self ):
15301571 self ._helper (merge = True )
15311572
1532- def test_update_and_transform (self ):
1573+ def test_with_exists_false (self ):
1574+ self ._helper (exists = False )
1575+
1576+ def test_with_exists_true (self ):
1577+ self ._helper (exists = True )
1578+
1579+ def test_w_transform (self ):
15331580 self ._helper (do_transform = True )
15341581
1582+ def test_w_transform_and_empty_value (self ):
1583+ # Exercise #5944
1584+ self ._helper (do_transform = True , empty_val = True )
1585+
15351586
15361587class Test_pbs_for_update (unittest .TestCase ):
15371588
0 commit comments