@@ -61,6 +61,9 @@ testsuites.forEach(testsuite => {
6161 testDeleteReferences ( sut , t , name ) ) ;
6262 test ( `[${ name } ] test maintain count` , async t => testMaintainCount ( sut , t ) ) ;
6363
64+ test ( `[${ name } ] test replicate attributes delete when field is not there` , async t =>
65+ testReplicateAttributesDeleteEmpty ( sut , t , name ) ) ;
66+
6467 test ( `[${ name } ] test delete with masterId in target reference` , async t =>
6568 testDeleteParamReferences ( sut , t , name ) ) ;
6669 test ( `[${ name } ] test delete with snapshot fields in target reference` , async t =>
@@ -163,7 +166,9 @@ async function testReplicateAttributes(sut, t, name) {
163166
164167 // Call trigger to replicate attributes from master
165168 const beforeSnap = fft . firestore . makeDocumentSnapshot (
166- { } ,
169+ {
170+ masterField5 : 'missing' ,
171+ } ,
167172 `master/${ masterId } `
168173 ) ;
169174 const afterSnap = fft . firestore . makeDocumentSnapshot (
@@ -226,6 +231,68 @@ async function testReplicateAttributes(sut, t, name) {
226231 await t . pass ( ) ;
227232}
228233
234+ async function testReplicateAttributesDeleteEmpty ( sut , t , name ) {
235+ // Add a couple of detail documents to follow master
236+ const masterId = makeid ( ) ;
237+ await db . collection ( 'detail1' ) . add ( {
238+ tempId : masterId ,
239+ foreignDetail1 : 'foreign_detail_1' ,
240+ foreignDetail2 : 'foreign_detail_2' ,
241+ } ) ;
242+
243+ // Call trigger to replicate attributes from master
244+ const beforeSnap = fft . firestore . makeDocumentSnapshot (
245+ {
246+ masterDetail1 : 'after1' ,
247+ masterDetail2 : 'after2' ,
248+ } ,
249+ `master/${ masterId } `
250+ ) ;
251+ const afterSnap = fft . firestore . makeDocumentSnapshot (
252+ {
253+ masterDetail2 : 'after3' ,
254+ } ,
255+ `master/${ masterId } `
256+ ) ;
257+ const change = fft . makeChange ( beforeSnap , afterSnap ) ;
258+ const wrapped = fft . wrap ( sut . replicateMasterDeleteWhenEmpty ) ;
259+ setState ( {
260+ change : null ,
261+ context : null ,
262+ } ) ;
263+ await wrapped ( change , {
264+ params : {
265+ masterId : masterId ,
266+ } ,
267+ } ) ;
268+
269+ // Assert pre-hook was called (only for rules-in-situ)
270+ if ( name === 'rules-in-situ' ) {
271+ const state = getState ( ) ;
272+ t . truthy ( state . change ) ;
273+ t . truthy ( state . context ) ;
274+ t . is ( state . context . params . masterId , masterId ) ;
275+ }
276+
277+ // Assert that attributes get replicated to detail documents
278+ await assertQuerySizeEventually (
279+ db
280+ . collection ( 'detail1' )
281+ . where ( 'tempId' , '==' , masterId )
282+ . where ( 'foreignDetail1' , '==' , 'foreign_detail_1' ) ,
283+ 0
284+ ) ;
285+ await assertQuerySizeEventually (
286+ db
287+ . collection ( 'detail1' )
288+ . where ( 'tempId' , '==' , masterId )
289+ . where ( 'foreignDetail2' , '==' , 'after3' ) ,
290+ 1
291+ ) ;
292+
293+ await t . pass ( ) ;
294+ }
295+
229296async function testDeleteReferences ( sut , t , name ) {
230297 // Create some docs referencing master doc
231298 const masterId = makeid ( ) ;
0 commit comments