@@ -270,3 +270,164 @@ describe('fromRpcTypedData - modelBindingData path', () => {
270
270
) ;
271
271
} ) ;
272
272
} ) ;
273
+ describe ( 'fromRpcTypedData - collectionModelBindingData path' , ( ) => {
274
+ let sandbox : sinon . SinonSandbox ;
275
+ let originalGetInstance : typeof ResourceFactoryResolver . getInstance ;
276
+
277
+ beforeEach ( ( ) => {
278
+ sandbox = sinon . createSandbox ( ) ;
279
+ originalGetInstance = ResourceFactoryResolver . getInstance . bind ( ResourceFactoryResolver ) ;
280
+ } ) ;
281
+
282
+ afterEach ( ( ) => {
283
+ sandbox . restore ( ) ;
284
+ ResourceFactoryResolver . getInstance = originalGetInstance ;
285
+ } ) ;
286
+
287
+ it ( 'should successfully create a client when collectionModelBindingData is valid' , ( ) => {
288
+ const mockClient = { name : 'testCollectionClient' } ;
289
+ const mockResolver = {
290
+ createClient : sinon . stub ( ) . returns ( mockClient ) ,
291
+ } ;
292
+ ResourceFactoryResolver . getInstance = sinon . stub ( ) . returns ( mockResolver ) ;
293
+
294
+ const collectionModelBindingData = {
295
+ modelBindingData : [
296
+ {
297
+ content : Buffer . from ( 'test-content-1' ) ,
298
+ source : 'blob' ,
299
+ contentType : 'application/octet-stream' ,
300
+ } ,
301
+ {
302
+ content : Buffer . from ( 'test-content-2' ) ,
303
+ source : 'blob' ,
304
+ contentType : 'application/octet-stream' ,
305
+ } ,
306
+ ] ,
307
+ } ;
308
+
309
+ const data : RpcTypedData = {
310
+ collectionModelBindingData,
311
+ } ;
312
+
313
+ const result = fromRpcTypedData ( data ) ;
314
+
315
+ sinon . assert . calledWith ( mockResolver . createClient , 'blob' , collectionModelBindingData . modelBindingData ) ;
316
+ expect ( result ) . to . equal ( mockClient ) ;
317
+ } ) ;
318
+
319
+ it ( 'should handle collectionModelBindingData with undefined source' , ( ) => {
320
+ const mockClient = { name : 'testCollectionClient' } ;
321
+ const mockResolver = {
322
+ createClient : sinon . stub ( ) . returns ( mockClient ) ,
323
+ } ;
324
+ ResourceFactoryResolver . getInstance = sinon . stub ( ) . returns ( mockResolver ) ;
325
+
326
+ const collectionModelBindingData = {
327
+ modelBindingData : [
328
+ {
329
+ content : Buffer . from ( 'test-content-1' ) ,
330
+ // source is undefined
331
+ contentType : 'application/octet-stream' ,
332
+ } ,
333
+ ] ,
334
+ } ;
335
+
336
+ const data : RpcTypedData = {
337
+ collectionModelBindingData,
338
+ } ;
339
+
340
+ const result = fromRpcTypedData ( data ) ;
341
+
342
+ expect ( mockResolver . createClient . calledWith ( undefined , collectionModelBindingData . modelBindingData ) ) . to . be . true ;
343
+ expect ( result ) . to . equal ( mockClient ) ;
344
+ } ) ;
345
+
346
+ it ( 'should throw enhanced error when ResourceFactoryResolver.createClient throws for collectionModelBindingData' , ( ) => {
347
+ const originalError = new Error ( 'Collection factory not registered' ) ;
348
+ const mockResolver = {
349
+ createClient : sinon . stub ( ) . throws ( originalError ) ,
350
+ } ;
351
+ ResourceFactoryResolver . getInstance = sinon . stub ( ) . returns ( mockResolver ) ;
352
+
353
+ const collectionModelBindingData = {
354
+ modelBindingData : [
355
+ {
356
+ content : Buffer . from ( 'test-content-1' ) ,
357
+ source : 'blob' ,
358
+ contentType : 'application/octet-stream' ,
359
+ } ,
360
+ ] ,
361
+ } ;
362
+
363
+ const data : RpcTypedData = {
364
+ collectionModelBindingData,
365
+ } ;
366
+
367
+ expect ( ( ) => fromRpcTypedData ( data ) ) . to . throw (
368
+ 'Unable to create client. Please register the extensions library with your function app. ' +
369
+ 'Error: Collection factory not registered'
370
+ ) ;
371
+ } ) ;
372
+
373
+ it ( 'should throw enhanced error when ResourceFactoryResolver.getInstance throws for collectionModelBindingData' , ( ) => {
374
+ const originalError = new Error ( 'Collection resolver not initialized' ) ;
375
+ ResourceFactoryResolver . getInstance = sinon . stub ( ) . throws ( originalError ) ;
376
+
377
+ const collectionModelBindingData = {
378
+ modelBindingData : [
379
+ {
380
+ content : Buffer . from ( 'test-content-1' ) ,
381
+ source : 'blob' ,
382
+ contentType : 'application/octet-stream' ,
383
+ } ,
384
+ ] ,
385
+ } ;
386
+
387
+ const data : RpcTypedData = {
388
+ collectionModelBindingData,
389
+ } ;
390
+
391
+ expect ( ( ) => fromRpcTypedData ( data ) ) . to . throw (
392
+ 'Unable to create client. Please register the extensions library with your function app. ' +
393
+ 'Error: Collection resolver not initialized'
394
+ ) ;
395
+ } ) ;
396
+
397
+ it ( 'should handle non-Error exceptions by converting to string for collectionModelBindingData' , ( ) => {
398
+ const mockResolver = {
399
+ createClient : sinon . stub ( ) . throws ( 'String exception for collection' ) , // Non-Error exception
400
+ } ;
401
+ ResourceFactoryResolver . getInstance = sinon . stub ( ) . returns ( mockResolver ) ;
402
+
403
+ const collectionModelBindingData = {
404
+ modelBindingData : [
405
+ {
406
+ content : Buffer . from ( 'test-content-1' ) ,
407
+ source : 'blob' ,
408
+ contentType : 'application/octet-stream' ,
409
+ } ,
410
+ ] ,
411
+ } ;
412
+
413
+ const data : RpcTypedData = {
414
+ collectionModelBindingData,
415
+ } ;
416
+
417
+ expect ( ( ) => fromRpcTypedData ( data ) ) . to . throw (
418
+ 'Unable to create client. Please register the extensions library with your function app. ' +
419
+ 'Error: Sinon-provided String exception for collection'
420
+ ) ;
421
+ } ) ;
422
+ } ) ;
423
+
424
+ describe ( 'fromRpcTypedData - fallback/undefined cases' , ( ) => {
425
+ it ( 'should return undefined for unknown data shape' , ( ) => {
426
+ const data : RpcTypedData = { foo : 'bar' } as any ;
427
+ expect ( fromRpcTypedData ( data ) ) . to . be . undefined ;
428
+ } ) ;
429
+
430
+ it ( 'should return undefined for empty object' , ( ) => {
431
+ expect ( fromRpcTypedData ( { } as RpcTypedData ) ) . to . be . undefined ;
432
+ } ) ;
433
+ } ) ;
0 commit comments