@@ -663,6 +663,27 @@ describe('$location', function() {
663663 } ) ;
664664 } ) ;
665665
666+
667+ it ( 'should not get caught in infinite digest when replacing path in locationChangeSuccess handler' , function ( ) {
668+ initService ( { html5Mode :true , supportHistory :false } ) ;
669+ mockUpBrowser ( { initialUrl :'http://server/base/home' , baseHref :'/base/' } ) ;
670+ inject (
671+ function ( $browser , $location , $rootScope , $window ) {
672+ var handlerCalled = false ;
673+ $rootScope . $on ( '$locationChangeSuccess' , function ( ) {
674+ handlerCalled = true ;
675+ if ( $location . path ( ) !== '/' ) {
676+ $location . path ( '/' ) . replace ( ) ;
677+ }
678+ } ) ;
679+ expect ( $browser . url ( ) ) . toEqual ( 'http://server/base/#/home' ) ;
680+ $rootScope . $digest ( ) ;
681+ expect ( handlerCalled ) . toEqual ( true ) ;
682+ expect ( $browser . url ( ) ) . toEqual ( 'http://server/base/#/' ) ;
683+ }
684+ ) ;
685+ } ) ;
686+
666687 it ( 'should not infinitely digest when using a semicolon in initial path' , function ( ) {
667688 initService ( { html5Mode :true , supportHistory :true } ) ;
668689 mockUpBrowser ( { initialUrl :'http://localhost:9876/;jsessionid=foo' , baseHref :'/' } ) ;
@@ -672,6 +693,156 @@ describe('$location', function() {
672693 } ) . not . toThrow ( ) ;
673694 } ) ;
674695 } ) ;
696+
697+
698+ function updatePathOnLocationChangeSuccessTo ( newPath ) {
699+ inject ( function ( $rootScope , $location ) {
700+ $rootScope . $on ( '$locationChangeSuccess' , function ( event , newUrl , oldUrl ) {
701+ $location . path ( newPath ) ;
702+ } ) ;
703+ } ) ;
704+ }
705+
706+
707+ describe ( 'location watch for hashbang browsers' , function ( ) {
708+
709+ it ( 'should not infinite $digest when going to base URL without trailing slash when $locationChangeSuccess watcher changes path to /Home' , function ( ) {
710+ initService ( { html5Mode : true , supportHistory : false } ) ;
711+ mockUpBrowser ( { initialUrl :'http://server/app/' , baseHref :'/app/' } ) ;
712+ inject ( function ( $rootScope , $location , $browser ) {
713+ var $browserUrl = spyOnlyCallsWithArgs ( $browser , 'url' ) . andCallThrough ( ) ;
714+
715+ updatePathOnLocationChangeSuccessTo ( '/Home' ) ;
716+
717+ $rootScope . $digest ( ) ;
718+
719+ expect ( $browser . url ( ) ) . toEqual ( 'http://server/app/#/Home' ) ;
720+ expect ( $location . path ( ) ) . toEqual ( '/Home' ) ;
721+ expect ( $browserUrl . calls . length ) . toEqual ( 1 ) ;
722+ } ) ;
723+ } ) ;
724+
725+ it ( 'should not infinite $digest when going to base URL without trailing slash when $locationChangeSuccess watcher changes path to /' , function ( ) {
726+ initService ( { html5Mode : true , supportHistory : false } ) ;
727+ mockUpBrowser ( { initialUrl :'http://server/app/Home' , baseHref :'/app/' } ) ;
728+ inject ( function ( $rootScope , $location , $browser , $window ) {
729+ var $browserUrl = spyOnlyCallsWithArgs ( $browser , 'url' ) . andCallThrough ( ) ;
730+
731+ updatePathOnLocationChangeSuccessTo ( '/' ) ;
732+
733+ $rootScope . $digest ( ) ;
734+
735+ expect ( $browser . url ( ) ) . toEqual ( 'http://server/app/#/' ) ;
736+ expect ( $location . path ( ) ) . toEqual ( '/' ) ;
737+ expect ( $browserUrl . calls . length ) . toEqual ( 1 ) ;
738+ expect ( $browserUrl . calls [ 0 ] . args ) . toEqual ( [ 'http://server/app/#/' , false , null ] ) ;
739+ } ) ;
740+ } ) ;
741+
742+ it ( 'should not infinite $digest when going to base URL with trailing slash when $locationChangeSuccess watcher changes path to /Home' , function ( ) {
743+ initService ( { html5Mode : true , supportHistory : false } ) ;
744+ mockUpBrowser ( { initialUrl :'http://server/app/' , baseHref :'/app/' } ) ;
745+ inject ( function ( $rootScope , $location , $browser ) {
746+ var $browserUrl = spyOnlyCallsWithArgs ( $browser , 'url' ) . andCallThrough ( ) ;
747+
748+ updatePathOnLocationChangeSuccessTo ( '/Home' ) ;
749+ $rootScope . $digest ( ) ;
750+
751+ expect ( $browser . url ( ) ) . toEqual ( 'http://server/app/#/Home' ) ;
752+ expect ( $location . path ( ) ) . toEqual ( '/Home' ) ;
753+ expect ( $browserUrl . calls . length ) . toEqual ( 1 ) ;
754+ expect ( $browserUrl . calls [ 0 ] . args ) . toEqual ( [ 'http://server/app/#/Home' , false , null ] ) ;
755+ } ) ;
756+ } ) ;
757+
758+ it ( 'should not infinite $digest when going to base URL with trailing slash when $locationChangeSuccess watcher changes path to /' , function ( ) {
759+ initService ( { html5Mode : true , supportHistory : false } ) ;
760+ mockUpBrowser ( { initialUrl :'http://server/app/' , baseHref :'/app/' } ) ;
761+ inject ( function ( $rootScope , $location , $browser ) {
762+ var $browserUrl = spyOnlyCallsWithArgs ( $browser , 'url' ) . andCallThrough ( ) ;
763+
764+ updatePathOnLocationChangeSuccessTo ( '/' ) ;
765+ $rootScope . $digest ( ) ;
766+
767+ expect ( $browser . url ( ) ) . toEqual ( 'http://server/app/#/' ) ;
768+ expect ( $location . path ( ) ) . toEqual ( '/' ) ;
769+ expect ( $browserUrl . calls . length ) . toEqual ( 1 ) ;
770+ } ) ;
771+ } ) ;
772+ } ) ;
773+
774+
775+ describe ( 'location watch for HTML5 browsers' , function ( ) {
776+
777+ it ( 'should not infinite $digest when going to base URL without trailing slash when $locationChangeSuccess watcher changes path to /Home' , function ( ) {
778+ initService ( { html5Mode : true , supportHistory : true } ) ;
779+ mockUpBrowser ( { initialUrl :'http://server/app/' , baseHref :'/app/' } ) ;
780+ inject ( function ( $rootScope , $injector , $browser ) {
781+ var $browserUrl = spyOnlyCallsWithArgs ( $browser , 'url' ) . andCallThrough ( ) ;
782+
783+ var $location = $injector . get ( '$location' ) ;
784+ updatePathOnLocationChangeSuccessTo ( '/Home' ) ;
785+
786+ $rootScope . $digest ( ) ;
787+
788+ expect ( $browser . url ( ) ) . toEqual ( 'http://server/app/Home' ) ;
789+ expect ( $location . path ( ) ) . toEqual ( '/Home' ) ;
790+ expect ( $browserUrl . calls . length ) . toEqual ( 1 ) ;
791+ } ) ;
792+ } ) ;
793+
794+ it ( 'should not infinite $digest when going to base URL without trailing slash when $locationChangeSuccess watcher changes path to /' , function ( ) {
795+ initService ( { html5Mode : true , supportHistory : true } ) ;
796+ mockUpBrowser ( { initialUrl :'http://server/app/' , baseHref :'/app/' } ) ;
797+ inject ( function ( $rootScope , $injector , $browser ) {
798+ var $browserUrl = spyOnlyCallsWithArgs ( $browser , 'url' ) . andCallThrough ( ) ;
799+
800+ var $location = $injector . get ( '$location' ) ;
801+ updatePathOnLocationChangeSuccessTo ( '/' ) ;
802+
803+ $rootScope . $digest ( ) ;
804+
805+ expect ( $browser . url ( ) ) . toEqual ( 'http://server/app/' ) ;
806+ expect ( $location . path ( ) ) . toEqual ( '/' ) ;
807+ expect ( $browserUrl . calls . length ) . toEqual ( 0 ) ;
808+ } ) ;
809+ } ) ;
810+
811+ it ( 'should not infinite $digest when going to base URL with trailing slash when $locationChangeSuccess watcher changes path to /Home' , function ( ) {
812+ initService ( { html5Mode : true , supportHistory : true } ) ;
813+ mockUpBrowser ( { initialUrl :'http://server/app/' , baseHref :'/app/' } ) ;
814+ inject ( function ( $rootScope , $injector , $browser ) {
815+ var $browserUrl = spyOnlyCallsWithArgs ( $browser , 'url' ) . andCallThrough ( ) ;
816+
817+ var $location = $injector . get ( '$location' ) ;
818+ updatePathOnLocationChangeSuccessTo ( '/Home' ) ;
819+
820+ $rootScope . $digest ( ) ;
821+
822+ expect ( $browser . url ( ) ) . toEqual ( 'http://server/app/Home' ) ;
823+ expect ( $location . path ( ) ) . toEqual ( '/Home' ) ;
824+ expect ( $browserUrl . calls . length ) . toEqual ( 1 ) ;
825+ } ) ;
826+ } ) ;
827+
828+ it ( 'should not infinite $digest when going to base URL with trailing slash when $locationChangeSuccess watcher changes path to /' , function ( ) {
829+ initService ( { html5Mode : true , supportHistory : true } ) ;
830+ mockUpBrowser ( { initialUrl :'http://server/app/' , baseHref :'/app/' } ) ;
831+ inject ( function ( $rootScope , $injector , $browser ) {
832+ var $browserUrl = spyOnlyCallsWithArgs ( $browser , 'url' ) . andCallThrough ( ) ;
833+
834+ var $location = $injector . get ( '$location' ) ;
835+ updatePathOnLocationChangeSuccessTo ( '/' ) ;
836+
837+ $rootScope . $digest ( ) ;
838+
839+ expect ( $browser . url ( ) ) . toEqual ( 'http://server/app/' ) ;
840+ expect ( $location . path ( ) ) . toEqual ( '/' ) ;
841+ expect ( $browserUrl . calls . length ) . toEqual ( 0 ) ;
842+ } ) ;
843+ } ) ;
844+ } ) ;
845+
675846 } ) ;
676847
677848 describe ( 'wiring' , function ( ) {
0 commit comments