@@ -17,7 +17,7 @@ admin.initializeApp({
1717const db = admin . firestore ( ) ;
1818
1919async function clearFirestore ( ) {
20- const collections = [ 'detail1' , 'detail2' , 'somecoll' ] ;
20+ const collections = [ 'detail1' , 'detail2' , 'detail3' , ' somecoll'] ;
2121 for ( const collection of collections ) {
2222 const { docs } = await admin
2323 . firestore ( )
@@ -55,14 +55,19 @@ testsuites.forEach(testsuite => {
5555 testPrimaryKey ( sut , t , name ) ) ;
5656 test ( `[${ name } ] test target collection parameter swap` , async t =>
5757 testTargetVariableSwap ( sut , t , name ) ) ;
58+
59+ // Standard functionality
5860 test ( `[${ name } ] test replicate attributes` , async t =>
5961 testReplicateAttributes ( sut , t , name ) ) ;
6062 test ( `[${ name } ] test delete references` , async t =>
6163 testDeleteReferences ( sut , t , name ) ) ;
6264 test ( `[${ name } ] test maintain count` , async t => testMaintainCount ( sut , t ) ) ;
6365
66+ // Added by GitLive
6467 test ( `[${ name } ] test replicate attributes delete when field is not there` , async t =>
6568 testReplicateAttributesDeleteEmpty ( sut , t , name ) ) ;
69+ test ( `[${ name } ] test replicate attributes with missing primary key in source reference` , async t =>
70+ testReplicateMissingSourceCollectionKey ( sut , t , name ) ) ;
6671
6772 test ( `[${ name } ] test delete with masterId in target reference` , async t =>
6873 testDeleteParamReferences ( sut , t , name ) ) ;
@@ -75,7 +80,6 @@ testsuites.forEach(testsuite => {
7580
7681 test ( `[${ name } ] test delete all sub-collections in target reference` , async t =>
7782 testDeleteAllSubCollections ( sut , t , name ) ) ;
78-
7983 test ( `[${ name } ] test delete missing arguments error` , async t =>
8084 testDeleteMissingArgumentsError ( sut , t , name ) ) ;
8185} ) ;
@@ -233,9 +237,9 @@ async function testReplicateAttributes(sut, t, name) {
233237
234238async function testReplicateAttributesDeleteEmpty ( sut , t , name ) {
235239 // Add a couple of detail documents to follow master
236- const masterId = makeid ( ) ;
240+ const primaryKey = makeid ( ) ;
237241 await db . collection ( 'detail1' ) . add ( {
238- tempId : masterId ,
242+ tempId : primaryKey ,
239243 foreignDetail1 : 'foreign_detail_1' ,
240244 foreignDetail2 : 'foreign_detail_2' ,
241245 } ) ;
@@ -246,13 +250,13 @@ async function testReplicateAttributesDeleteEmpty(sut, t, name) {
246250 masterDetail1 : 'after1' ,
247251 masterDetail2 : 'after2' ,
248252 } ,
249- `master/${ masterId } `
253+ `master/${ primaryKey } `
250254 ) ;
251255 const afterSnap = fft . firestore . makeDocumentSnapshot (
252256 {
253257 masterDetail2 : 'after3' ,
254258 } ,
255- `master/${ masterId } `
259+ `master/${ primaryKey } `
256260 ) ;
257261 const change = fft . makeChange ( beforeSnap , afterSnap ) ;
258262 const wrapped = fft . wrap ( sut . replicateMasterDeleteWhenEmpty ) ;
@@ -262,7 +266,7 @@ async function testReplicateAttributesDeleteEmpty(sut, t, name) {
262266 } ) ;
263267 await wrapped ( change , {
264268 params : {
265- masterId : masterId ,
269+ primaryKey : primaryKey ,
266270 } ,
267271 } ) ;
268272
@@ -271,28 +275,97 @@ async function testReplicateAttributesDeleteEmpty(sut, t, name) {
271275 const state = getState ( ) ;
272276 t . truthy ( state . change ) ;
273277 t . truthy ( state . context ) ;
274- t . is ( state . context . params . masterId , masterId ) ;
278+ t . is ( state . context . params . primaryKey , primaryKey ) ;
275279 }
276280
277281 // Assert that attributes get replicated to detail documents
278282 await assertQuerySizeEventually (
279283 db
280284 . collection ( 'detail1' )
281- . where ( 'tempId' , '==' , masterId )
285+ . where ( 'tempId' , '==' , primaryKey )
282286 . where ( 'foreignDetail1' , '==' , 'foreign_detail_1' ) ,
283287 0
284288 ) ;
285289 await assertQuerySizeEventually (
286290 db
287291 . collection ( 'detail1' )
288- . where ( 'tempId' , '==' , masterId )
292+ . where ( 'tempId' , '==' , primaryKey )
289293 . where ( 'foreignDetail2' , '==' , 'after3' ) ,
290294 1
291295 ) ;
292296
293297 await t . pass ( ) ;
294298}
295299
300+ async function testReplicateMissingSourceCollectionKey ( sut , t , name ) {
301+ // Create some docs referencing master doc
302+ const randomId = makeid ( ) ;
303+ await db . collection ( 'detail1' ) . add ( {
304+ tempId : randomId ,
305+ foreignDetail1 : 'foreign_detail_1' ,
306+ foreignDetail2 : 'foreign_detail_2' ,
307+ } ) ;
308+
309+ // Trigger function to delete references
310+ const beforeSnap = fft . firestore . makeDocumentSnapshot (
311+ {
312+ masterDetail1 : 'after1' ,
313+ masterDetail2 : 'after2' ,
314+ } ,
315+ `master/${ randomId } `
316+ ) ;
317+ const afterSnap = fft . firestore . makeDocumentSnapshot (
318+ {
319+ masterDetail2 : 'after3' ,
320+ } ,
321+ `master/${ randomId } `
322+ ) ;
323+ const change = fft . makeChange ( beforeSnap , afterSnap ) ;
324+ const wrapped = fft . wrap ( sut . replicateReferencesWithMissingKey ) ;
325+ setState ( {
326+ snap : null ,
327+ context : null ,
328+ } ) ;
329+
330+ const error = await t . throwsAsync ( async ( ) => {
331+ await wrapped ( change , {
332+ params : {
333+ randomId : randomId ,
334+ } ,
335+ } ) ;
336+ } ) ;
337+
338+ t . is (
339+ error . message ,
340+ 'integrify: Missing a primary key [masterId] in the source params'
341+ ) ;
342+
343+ // Assert pre-hook was called (only for rules-in-situ)
344+ if ( name === 'rules-in-situ' ) {
345+ const state = getState ( ) ;
346+ t . is ( state . snap , null ) ;
347+ t . is ( state . context , null ) ;
348+ }
349+
350+ // Assert referencing docs were not deleted
351+ await assertQuerySizeEventually (
352+ db
353+ . collection ( 'detail1' )
354+ . where ( 'tempId' , '==' , randomId )
355+ . where ( 'foreignDetail1' , '==' , 'foreign_detail_1' ) ,
356+ 1
357+ ) ;
358+ await assertQuerySizeEventually (
359+ db
360+ . collection ( 'detail1' )
361+ . where ( 'tempId' , '==' , randomId )
362+ . where ( 'foreignDetail2' , '==' , 'foreign_detail_2' ) ,
363+ 1
364+ ) ;
365+
366+ t . pass ( ) ;
367+ }
368+
296369async function testDeleteReferences ( sut , t , name ) {
297370 // Create some docs referencing master doc
298371 const masterId = makeid ( ) ;
0 commit comments