@@ -270,3 +270,164 @@ describe('fromRpcTypedData - modelBindingData path', () => {
270270 ) ;
271271 } ) ;
272272} ) ;
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