@@ -349,6 +349,192 @@ module ForestAdminRpcAgent
349349 expect ( rpc_relations_for_rpc1 ) . not_to have_key ( 'other_rpc' )
350350 end
351351
352+ context 'with PolymorphicManyToOne relations' do
353+ it 'extracts polymorphic relation from RPC collection when targeting non-RPC collections' do
354+ rpc_collection = instance_double ( ForestAdminDatasourceToolkit ::Collection )
355+ normal_collection1 = instance_double ( ForestAdminDatasourceToolkit ::Collection )
356+ normal_collection2 = instance_double ( ForestAdminDatasourceToolkit ::Collection )
357+
358+ polymorphic_field = instance_double (
359+ ForestAdminDatasourceToolkit ::Schema ::Relations ::PolymorphicManyToOneSchema
360+ )
361+ allow ( polymorphic_field ) . to receive_messages (
362+ type : 'PolymorphicManyToOne' ,
363+ foreign_collections : %w[ NormalCollection1 NormalCollection2 ]
364+ )
365+
366+ allow ( rpc_collection ) . to receive_messages (
367+ name : 'RpcCollection' ,
368+ schema : { fields : { 'commentable' => polymorphic_field } }
369+ )
370+ allow ( normal_collection1 ) . to receive_messages ( name : 'NormalCollection1' , schema : { fields : { } } )
371+ allow ( normal_collection2 ) . to receive_messages ( name : 'NormalCollection2' , schema : { fields : { } } )
372+ allow ( datasource ) . to receive_messages (
373+ collections : {
374+ 'RpcCollection' => rpc_collection ,
375+ 'NormalCollection1' => normal_collection1 ,
376+ 'NormalCollection2' => normal_collection2
377+ } ,
378+ live_query_connections : { }
379+ )
380+
381+ instance . mark_collections_as_rpc ( 'RpcCollection' )
382+ instance . send_schema
383+
384+ expect ( instance . cached_schema [ :rpc_relations ] ) . to have_key ( 'RpcCollection' )
385+ expect ( instance . cached_schema [ :rpc_relations ] [ 'RpcCollection' ] ) . to have_key ( 'commentable' )
386+ end
387+
388+ it 'does not extract polymorphic relation from RPC collection when all targets are RPC' do
389+ rpc_collection1 = instance_double ( ForestAdminDatasourceToolkit ::Collection )
390+ rpc_collection2 = instance_double ( ForestAdminDatasourceToolkit ::Collection )
391+ rpc_collection3 = instance_double ( ForestAdminDatasourceToolkit ::Collection )
392+
393+ polymorphic_field = instance_double (
394+ ForestAdminDatasourceToolkit ::Schema ::Relations ::PolymorphicManyToOneSchema
395+ )
396+ allow ( polymorphic_field ) . to receive_messages (
397+ type : 'PolymorphicManyToOne' ,
398+ foreign_collections : %w[ RpcCollection2 RpcCollection3 ]
399+ )
400+
401+ allow ( rpc_collection1 ) . to receive_messages (
402+ name : 'RpcCollection1' ,
403+ schema : { fields : { 'commentable' => polymorphic_field } }
404+ )
405+ allow ( rpc_collection2 ) . to receive_messages ( name : 'RpcCollection2' , schema : { fields : { } } )
406+ allow ( rpc_collection3 ) . to receive_messages ( name : 'RpcCollection3' , schema : { fields : { } } )
407+ allow ( datasource ) . to receive_messages (
408+ collections : {
409+ 'RpcCollection1' => rpc_collection1 ,
410+ 'RpcCollection2' => rpc_collection2 ,
411+ 'RpcCollection3' => rpc_collection3
412+ } ,
413+ live_query_connections : { }
414+ )
415+
416+ instance . mark_collections_as_rpc ( 'RpcCollection1' , 'RpcCollection2' , 'RpcCollection3' )
417+ instance . send_schema
418+
419+ rpc_relations_for_rpc1 = instance . cached_schema [ :rpc_relations ] [ 'RpcCollection1' ] || { }
420+ expect ( rpc_relations_for_rpc1 ) . not_to have_key ( 'commentable' )
421+ end
422+
423+ it 'extracts polymorphic relation from RPC collection when some targets are RPC and some are not' do
424+ rpc_collection1 = instance_double ( ForestAdminDatasourceToolkit ::Collection )
425+ rpc_collection2 = instance_double ( ForestAdminDatasourceToolkit ::Collection )
426+ normal_collection = instance_double ( ForestAdminDatasourceToolkit ::Collection )
427+
428+ polymorphic_field = instance_double (
429+ ForestAdminDatasourceToolkit ::Schema ::Relations ::PolymorphicManyToOneSchema
430+ )
431+ allow ( polymorphic_field ) . to receive_messages (
432+ type : 'PolymorphicManyToOne' ,
433+ foreign_collections : %w[ RpcCollection2 NormalCollection ]
434+ )
435+
436+ allow ( rpc_collection1 ) . to receive_messages (
437+ name : 'RpcCollection1' ,
438+ schema : { fields : { 'commentable' => polymorphic_field } }
439+ )
440+ allow ( rpc_collection2 ) . to receive_messages ( name : 'RpcCollection2' , schema : { fields : { } } )
441+ allow ( normal_collection ) . to receive_messages ( name : 'NormalCollection' , schema : { fields : { } } )
442+ allow ( datasource ) . to receive_messages (
443+ collections : {
444+ 'RpcCollection1' => rpc_collection1 ,
445+ 'RpcCollection2' => rpc_collection2 ,
446+ 'NormalCollection' => normal_collection
447+ } ,
448+ live_query_connections : { }
449+ )
450+
451+ instance . mark_collections_as_rpc ( 'RpcCollection1' , 'RpcCollection2' )
452+ instance . send_schema
453+
454+ # Mixed targets: at least one is RPC, so the relation is NOT extracted for RPC collections
455+ # (the `next if relation_targets_rpc_collection?` skips it because .any? returns true)
456+ rpc_relations_for_rpc1 = instance . cached_schema [ :rpc_relations ] [ 'RpcCollection1' ] || { }
457+ expect ( rpc_relations_for_rpc1 ) . not_to have_key ( 'commentable' )
458+ end
459+
460+ it 'extracts polymorphic relation from normal collection when any target is an RPC collection' do
461+ rpc_collection = instance_double ( ForestAdminDatasourceToolkit ::Collection )
462+ normal_collection = instance_double ( ForestAdminDatasourceToolkit ::Collection )
463+ normal_collection2 = instance_double ( ForestAdminDatasourceToolkit ::Collection )
464+
465+ polymorphic_field = instance_double (
466+ ForestAdminDatasourceToolkit ::Schema ::Relations ::PolymorphicManyToOneSchema
467+ )
468+ allow ( polymorphic_field ) . to receive_messages (
469+ type : 'PolymorphicManyToOne' ,
470+ foreign_collections : %w[ RpcCollection NormalCollection2 ]
471+ )
472+
473+ allow ( rpc_collection ) . to receive_messages ( name : 'RpcCollection' , schema : { fields : { } } )
474+ allow ( normal_collection ) . to receive_messages (
475+ name : 'NormalCollection' ,
476+ schema : { fields : { 'commentable' => polymorphic_field } }
477+ )
478+ allow ( normal_collection2 ) . to receive_messages ( name : 'NormalCollection2' , schema : { fields : { } } )
479+ allow ( datasource ) . to receive_messages (
480+ collections : {
481+ 'RpcCollection' => rpc_collection ,
482+ 'NormalCollection' => normal_collection ,
483+ 'NormalCollection2' => normal_collection2
484+ } ,
485+ live_query_connections : { }
486+ )
487+
488+ instance . mark_collections_as_rpc ( 'RpcCollection' )
489+ instance . send_schema
490+
491+ expect ( instance . cached_schema [ :rpc_relations ] ) . to have_key ( 'NormalCollection' )
492+ expect ( instance . cached_schema [ :rpc_relations ] [ 'NormalCollection' ] ) . to have_key ( 'commentable' )
493+ end
494+
495+ it 'does not extract polymorphic relation from normal collection when no target is RPC' do
496+ normal_collection = instance_double ( ForestAdminDatasourceToolkit ::Collection )
497+ normal_collection2 = instance_double ( ForestAdminDatasourceToolkit ::Collection )
498+ normal_collection3 = instance_double ( ForestAdminDatasourceToolkit ::Collection )
499+
500+ polymorphic_field = instance_double (
501+ ForestAdminDatasourceToolkit ::Schema ::Relations ::PolymorphicManyToOneSchema
502+ )
503+ allow ( polymorphic_field ) . to receive_messages (
504+ type : 'PolymorphicManyToOne' ,
505+ foreign_collections : %w[ NormalCollection2 NormalCollection3 ]
506+ )
507+
508+ column_field = instance_double ( ForestAdminDatasourceToolkit ::Schema ::ColumnSchema )
509+ allow ( column_field ) . to receive_messages ( type : 'Column' )
510+ allow ( column_field ) . to receive ( :filter_operators= )
511+ allow ( column_field ) . to receive ( :filter_operators ) . and_return ( [ ] )
512+ allow ( ForestAdminAgent ::Utils ::Schema ::FrontendFilterable ) . to receive ( :sort_operators ) . and_return ( [ ] )
513+
514+ allow ( normal_collection ) . to receive_messages (
515+ name : 'NormalCollection' ,
516+ schema : { fields : { 'id' => column_field , 'commentable' => polymorphic_field } }
517+ )
518+ allow ( normal_collection2 ) . to receive_messages ( name : 'NormalCollection2' , schema : { fields : { } } )
519+ allow ( normal_collection3 ) . to receive_messages ( name : 'NormalCollection3' , schema : { fields : { } } )
520+ allow ( datasource ) . to receive_messages (
521+ collections : {
522+ 'NormalCollection' => normal_collection ,
523+ 'NormalCollection2' => normal_collection2 ,
524+ 'NormalCollection3' => normal_collection3
525+ } ,
526+ live_query_connections : { }
527+ )
528+
529+ instance . send_schema
530+
531+ # No RPC targets, so the polymorphic relation stays in the normal collection's fields
532+ expect ( instance . cached_schema [ :rpc_relations ] ) . not_to have_key ( 'NormalCollection' )
533+ normal_schema = instance . cached_schema [ :collections ] . find { |c | c [ :name ] == 'NormalCollection' }
534+ expect ( normal_schema [ :fields ] ) . to have_key ( 'commentable' )
535+ end
536+ end
537+
352538 it 'sorts filter_operators for Column fields' do
353539 normal_collection = instance_double ( ForestAdminDatasourceToolkit ::Collection )
354540 column_field = instance_double ( ForestAdminDatasourceToolkit ::Schema ::ColumnSchema )
0 commit comments