@@ -620,4 +620,206 @@ describe('ApexMigration', () => {
620620 expect ( dmNameUpdateFailed . size ) . to . equal ( 0 ) ;
621621 } ) ;
622622 } ) ;
623+
624+ describe ( 'processApexFileForRemotecalls' , ( ) => {
625+ it ( 'should return empty array when class already implements only System.Callable' , ( ) => {
626+ // Arrange
627+ const mockFile = { name : 'TestClass.cls' , location : '/test/path' } ;
628+ const callableInterface = new InterfaceImplements ( 'Callable' , 'System' ) ;
629+ const mockParser = {
630+ implementsInterfaces : new Map ( [ [ callableInterface , [ { startIndex : 10 , stopIndex : 25 , text : 'System.Callable' } ] ] ] ) ,
631+ hasCallMethodImplemented : true ,
632+ classDeclaration : { } ,
633+ } ;
634+
635+ // Act
636+ const result = ( apexMigration as any ) . processApexFileForRemotecalls ( mockFile , mockParser ) ;
637+
638+ // Assert
639+ expect ( result ) . to . be . an ( 'array' ) . with . length ( 0 ) ;
640+ } ) ;
641+
642+ it ( 'should replace only VlocityOpenInterface2 with System.Callable' , ( ) => {
643+ // Arrange
644+ const mockFile = { name : 'TestClass.cls' , location : '/test/path' } ;
645+ const vlocityOpenInterface2 = new InterfaceImplements ( 'VlocityOpenInterface2' , testNamespace ) ;
646+ const mockParser = {
647+ implementsInterfaces : new Map ( [
648+ [ vlocityOpenInterface2 , [ { startIndex : 10 , stopIndex : 45 , text : `${ testNamespace } .VlocityOpenInterface2` } ] ] ,
649+ ] ) ,
650+ hasCallMethodImplemented : false ,
651+ classDeclaration : { stopIndex : 100 } ,
652+ } ;
653+
654+ // Act
655+ const result = ( apexMigration as any ) . processApexFileForRemotecalls ( mockFile , mockParser ) ;
656+
657+ // Assert
658+ expect ( result ) . to . be . an ( 'array' ) . with . length ( 2 ) ;
659+ expect ( result [ 0 ] . constructor . name ) . to . equal ( 'RangeTokenUpdate' ) ;
660+ expect ( result [ 0 ] . newText ) . to . equal ( 'System.Callable' ) ;
661+ expect ( result [ 1 ] . constructor . name ) . to . equal ( 'InsertAfterTokenUpdate' ) ;
662+ } ) ;
663+
664+ it ( 'should replace only VlocityOpenInterface with System.Callable' , ( ) => {
665+ // Arrange
666+ const mockFile = { name : 'TestClass.cls' , location : '/test/path' } ;
667+ const vlocityOpenInterface = new InterfaceImplements ( 'VlocityOpenInterface' , testNamespace ) ;
668+ const mockParser = {
669+ implementsInterfaces : new Map ( [
670+ [ vlocityOpenInterface , [ { startIndex : 10 , stopIndex : 44 , text : `${ testNamespace } .VlocityOpenInterface` } ] ] ,
671+ ] ) ,
672+ hasCallMethodImplemented : false ,
673+ classDeclaration : { stopIndex : 100 } ,
674+ } ;
675+
676+ // Act
677+ const result = ( apexMigration as any ) . processApexFileForRemotecalls ( mockFile , mockParser ) ;
678+
679+ // Assert
680+ expect ( result ) . to . be . an ( 'array' ) . with . length ( 2 ) ;
681+ expect ( result [ 0 ] . constructor . name ) . to . equal ( 'RangeTokenUpdate' ) ;
682+ expect ( result [ 0 ] . newText ) . to . equal ( 'System.Callable' ) ;
683+ expect ( result [ 1 ] . constructor . name ) . to . equal ( 'InsertAfterTokenUpdate' ) ;
684+ } ) ;
685+
686+ it ( 'should replace BOTH VlocityOpenInterface and VlocityOpenInterface2 with System.Callable' , ( ) => {
687+ // Arrange - This is the FIX scenario
688+ const mockFile = { name : 'TestClass.cls' , location : '/test/path' } ;
689+ const vlocityOpenInterface = new InterfaceImplements ( 'VlocityOpenInterface' , testNamespace ) ;
690+ const vlocityOpenInterface2 = new InterfaceImplements ( 'VlocityOpenInterface2' , testNamespace ) ;
691+ const mockParser = {
692+ implementsInterfaces : new Map ( [
693+ [ vlocityOpenInterface , [ { startIndex : 10 , stopIndex : 44 , text : `${ testNamespace } .VlocityOpenInterface` } ] ] ,
694+ [ vlocityOpenInterface2 , [ { startIndex : 46 , stopIndex : 81 , text : `${ testNamespace } .VlocityOpenInterface2` } ] ] ,
695+ ] ) ,
696+ hasCallMethodImplemented : false ,
697+ classDeclaration : { stopIndex : 100 } ,
698+ } ;
699+
700+ // Act
701+ const result = ( apexMigration as any ) . processApexFileForRemotecalls ( mockFile , mockParser ) ;
702+
703+ // Assert
704+ // Should call replaceAllInterfaces and replace entire implements clause with System.Callable
705+ expect ( result ) . to . be . an ( 'array' ) . with . length ( 2 ) ;
706+ expect ( result [ 0 ] . constructor . name ) . to . equal ( 'RangeTokenUpdate' ) ;
707+ expect ( result [ 0 ] . newText ) . to . equal ( 'System.Callable' ) ;
708+ expect ( result [ 1 ] . constructor . name ) . to . equal ( 'InsertAfterTokenUpdate' ) ;
709+ } ) ;
710+
711+ it ( 'should replace System.Callable with other interfaces to only System.Callable' , ( ) => {
712+ // Arrange
713+ const mockFile = { name : 'TestClass.cls' , location : '/test/path' } ;
714+ const callableInterface = new InterfaceImplements ( 'Callable' , 'System' ) ;
715+ const vlocityOpenInterface2 = new InterfaceImplements ( 'VlocityOpenInterface2' , testNamespace ) ;
716+ const mockParser = {
717+ implementsInterfaces : new Map ( [
718+ [ callableInterface , [ { startIndex : 10 , stopIndex : 25 , text : 'System.Callable' } ] ] ,
719+ [ vlocityOpenInterface2 , [ { startIndex : 27 , stopIndex : 62 , text : `${ testNamespace } .VlocityOpenInterface2` } ] ] ,
720+ ] ) ,
721+ hasCallMethodImplemented : false ,
722+ classDeclaration : { stopIndex : 100 } ,
723+ } ;
724+
725+ // Act
726+ const result = ( apexMigration as any ) . processApexFileForRemotecalls ( mockFile , mockParser ) ;
727+
728+ // Assert
729+ // Should call replaceAllInterfaces and keep only System.Callable
730+ expect ( result ) . to . be . an ( 'array' ) . with . length ( 2 ) ;
731+ expect ( result [ 0 ] . constructor . name ) . to . equal ( 'RangeTokenUpdate' ) ;
732+ expect ( result [ 0 ] . newText ) . to . equal ( 'System.Callable' ) ;
733+ expect ( result [ 1 ] . constructor . name ) . to . equal ( 'InsertAfterTokenUpdate' ) ;
734+ } ) ;
735+
736+ it ( 'should replace BOTH Vlocity interfaces AND System.Callable with only System.Callable' , ( ) => {
737+ // Arrange - This is the FIX scenario with Callable already present
738+ const mockFile = { name : 'TestClass.cls' , location : '/test/path' } ;
739+ const callableInterface = new InterfaceImplements ( 'Callable' , 'System' ) ;
740+ const vlocityOpenInterface = new InterfaceImplements ( 'VlocityOpenInterface' , testNamespace ) ;
741+ const vlocityOpenInterface2 = new InterfaceImplements ( 'VlocityOpenInterface2' , testNamespace ) ;
742+ const mockParser = {
743+ implementsInterfaces : new Map ( [
744+ [ callableInterface , [ { startIndex : 10 , stopIndex : 25 , text : 'System.Callable' } ] ] ,
745+ [ vlocityOpenInterface , [ { startIndex : 27 , stopIndex : 61 , text : `${ testNamespace } .VlocityOpenInterface` } ] ] ,
746+ [ vlocityOpenInterface2 , [ { startIndex : 63 , stopIndex : 98 , text : `${ testNamespace } .VlocityOpenInterface2` } ] ] ,
747+ ] ) ,
748+ hasCallMethodImplemented : false ,
749+ classDeclaration : { stopIndex : 100 } ,
750+ } ;
751+
752+ // Act
753+ const result = ( apexMigration as any ) . processApexFileForRemotecalls ( mockFile , mockParser ) ;
754+
755+ // Assert
756+ // Should call replaceAllInterfaces and keep only System.Callable, removing both Vlocity interfaces
757+ expect ( result ) . to . be . an ( 'array' ) . with . length ( 2 ) ;
758+ expect ( result [ 0 ] . constructor . name ) . to . equal ( 'RangeTokenUpdate' ) ;
759+ expect ( result [ 0 ] . newText ) . to . equal ( 'System.Callable' ) ;
760+ expect ( result [ 1 ] . constructor . name ) . to . equal ( 'InsertAfterTokenUpdate' ) ;
761+ } ) ;
762+
763+ it ( 'should not add call method when it already exists' , ( ) => {
764+ // Arrange
765+ const mockFile = { name : 'TestClass.cls' , location : '/test/path' } ;
766+ const vlocityOpenInterface2 = new InterfaceImplements ( 'VlocityOpenInterface2' , testNamespace ) ;
767+ const mockParser = {
768+ implementsInterfaces : new Map ( [
769+ [ vlocityOpenInterface2 , [ { startIndex : 10 , stopIndex : 45 , text : `${ testNamespace } .VlocityOpenInterface2` } ] ] ,
770+ ] ) ,
771+ hasCallMethodImplemented : true ,
772+ classDeclaration : { stopIndex : 100 } ,
773+ } ;
774+
775+ // Act
776+ const result = ( apexMigration as any ) . processApexFileForRemotecalls ( mockFile , mockParser ) ;
777+
778+ // Assert
779+ // Should only have RangeTokenUpdate, no InsertAfterTokenUpdate
780+ expect ( result ) . to . be . an ( 'array' ) . with . length ( 1 ) ;
781+ expect ( result [ 0 ] . constructor . name ) . to . equal ( 'RangeTokenUpdate' ) ;
782+ expect ( result [ 0 ] . newText ) . to . equal ( 'System.Callable' ) ;
783+ } ) ;
784+
785+ it ( 'should handle both Vlocity interfaces when call method already exists' , ( ) => {
786+ // Arrange
787+ const mockFile = { name : 'TestClass.cls' , location : '/test/path' } ;
788+ const vlocityOpenInterface = new InterfaceImplements ( 'VlocityOpenInterface' , testNamespace ) ;
789+ const vlocityOpenInterface2 = new InterfaceImplements ( 'VlocityOpenInterface2' , testNamespace ) ;
790+ const mockParser = {
791+ implementsInterfaces : new Map ( [
792+ [ vlocityOpenInterface , [ { startIndex : 10 , stopIndex : 44 , text : `${ testNamespace } .VlocityOpenInterface` } ] ] ,
793+ [ vlocityOpenInterface2 , [ { startIndex : 46 , stopIndex : 81 , text : `${ testNamespace } .VlocityOpenInterface2` } ] ] ,
794+ ] ) ,
795+ hasCallMethodImplemented : true ,
796+ classDeclaration : { stopIndex : 100 } ,
797+ } ;
798+
799+ // Act
800+ const result = ( apexMigration as any ) . processApexFileForRemotecalls ( mockFile , mockParser ) ;
801+
802+ // Assert
803+ // Should call replaceAllInterfaces but not add call method
804+ expect ( result ) . to . be . an ( 'array' ) . with . length ( 1 ) ;
805+ expect ( result [ 0 ] . constructor . name ) . to . equal ( 'RangeTokenUpdate' ) ;
806+ expect ( result [ 0 ] . newText ) . to . equal ( 'System.Callable' ) ;
807+ } ) ;
808+
809+ it ( 'should return empty array when no interfaces are present' , ( ) => {
810+ // Arrange
811+ const mockFile = { name : 'TestClass.cls' , location : '/test/path' } ;
812+ const mockParser = {
813+ implementsInterfaces : new Map ( ) ,
814+ hasCallMethodImplemented : false ,
815+ classDeclaration : { stopIndex : 100 } ,
816+ } ;
817+
818+ // Act
819+ const result = ( apexMigration as any ) . processApexFileForRemotecalls ( mockFile , mockParser ) ;
820+
821+ // Assert
822+ expect ( result ) . to . be . an ( 'array' ) . with . length ( 0 ) ;
823+ } ) ;
824+ } ) ;
623825} ) ;
0 commit comments