@@ -794,3 +794,124 @@ describe("WidgetApi", () => {
794794 } ) ;
795795 } ) ;
796796} ) ;
797+
798+ describe ( "postMessage" , ( ) => {
799+ let widgetApi : WidgetApi ;
800+ const onHandledRequest = jest . fn ( ) ;
801+
802+ let afterMessage : Promise < void > ;
803+ let afterMessageListener : ( ) => void ;
804+
805+ beforeEach ( ( ) => {
806+ widgetApi = new WidgetApi ( ) ;
807+ widgetApi . start ( ) ;
808+
809+ onHandledRequest . mockClear ( ) ;
810+ widgetApi . transport . on ( "message" , onHandledRequest ) ;
811+
812+ ( { promise : afterMessage , resolve : afterMessageListener } = Promise . withResolvers < void > ( ) ) ;
813+ afterMessage = new Promise ( ( resolve ) => {
814+ afterMessageListener = resolve ;
815+ globalThis . addEventListener ( "message" , afterMessageListener ) ;
816+ } ) ;
817+ } ) ;
818+
819+ afterEach ( ( ) => {
820+ globalThis . removeEventListener ( "message" , afterMessageListener ) ;
821+ widgetApi . transport . removeAllListeners ( ) ;
822+ } ) ;
823+
824+ async function postMessage ( message : unknown ) : Promise < void > {
825+ globalThis . postMessage ( message , "*" ) ;
826+ await afterMessage ;
827+ }
828+
829+ it ( "should handle a valid request" , async ( ) => {
830+ const action = "a" ;
831+ widgetApi . on ( `action:${ action } ` , ( ev : Event ) => {
832+ ev . preventDefault ( ) ;
833+ } ) ;
834+
835+ await postMessage ( {
836+ api : WidgetApiDirection . ToWidget ,
837+ requestId : "rid" ,
838+ action,
839+ widgetId : "w" ,
840+ data : { } ,
841+ } satisfies IWidgetApiRequest ) ;
842+ expect ( onHandledRequest ) . toHaveBeenCalled ( ) ;
843+ } ) ;
844+
845+ it ( "should drop a request with the wrong direction" , async ( ) => {
846+ await postMessage ( {
847+ api : WidgetApiDirection . FromWidget ,
848+ requestId : "rid" ,
849+ action : "a" ,
850+ widgetId : "w" ,
851+ data : { } ,
852+ } satisfies IWidgetApiRequest ) ;
853+ expect ( onHandledRequest ) . not . toHaveBeenCalled ( ) ;
854+ } ) ;
855+
856+ it ( "should drop a request without an action" , async ( ) => {
857+ await postMessage ( {
858+ api : WidgetApiDirection . ToWidget ,
859+ requestId : "rid" ,
860+ widgetId : "w" ,
861+ data : { } ,
862+ } satisfies Omit < IWidgetApiRequest , "action" > ) ;
863+ expect ( onHandledRequest ) . not . toHaveBeenCalled ( ) ;
864+ } ) ;
865+
866+ it ( "should drop a request without an request ID" , async ( ) => {
867+ await postMessage ( {
868+ api : WidgetApiDirection . ToWidget ,
869+ action : "a" ,
870+ widgetId : "w" ,
871+ data : { } ,
872+ } satisfies Omit < IWidgetApiRequest , "requestId" > ) ;
873+ expect ( onHandledRequest ) . not . toHaveBeenCalled ( ) ;
874+ } ) ;
875+
876+ it ( "should drop a request without an widget ID" , async ( ) => {
877+ await postMessage ( {
878+ api : WidgetApiDirection . ToWidget ,
879+ action : "a" ,
880+ requestId : "rid" ,
881+ data : { } ,
882+ } satisfies Omit < IWidgetApiRequest , "widgetId" > ) ;
883+ expect ( onHandledRequest ) . not . toHaveBeenCalled ( ) ;
884+ } ) ;
885+
886+ it ( "should enforce strictOriginCheck" , async ( ) => {
887+ // the generated MessageEvent will have an empty origin
888+ widgetApi . transport . strictOriginCheck = true ;
889+
890+ await postMessage ( {
891+ api : WidgetApiDirection . ToWidget ,
892+ requestId : "rid" ,
893+ action : "a" ,
894+ widgetId : "w" ,
895+ data : { } ,
896+ } satisfies IWidgetApiRequest ) ;
897+ expect ( onHandledRequest ) . not . toHaveBeenCalled ( ) ;
898+ } ) ;
899+
900+ it ( "should drop a null message" , async ( ) => {
901+ await postMessage ( null ) ;
902+ expect ( onHandledRequest ) . not . toHaveBeenCalled ( ) ;
903+ } ) ;
904+
905+ it ( "should drop a request after having aborted" , async ( ) => {
906+ widgetApi . transport . stop ( ) ;
907+
908+ await postMessage ( {
909+ api : WidgetApiDirection . ToWidget ,
910+ requestId : "rid" ,
911+ action : "a" ,
912+ widgetId : "w" ,
913+ data : { } ,
914+ } satisfies IWidgetApiRequest ) ;
915+ expect ( onHandledRequest ) . not . toHaveBeenCalled ( ) ;
916+ } ) ;
917+ } ) ;
0 commit comments