Skip to content
This repository was archived by the owner on Apr 12, 2024. It is now read-only.

Commit 98e884c

Browse files
committed
refactor($browser): normalize inputted URLs
1 parent 33492fe commit 98e884c

File tree

2 files changed

+62
-5
lines changed

2 files changed

+62
-5
lines changed

src/ng/browser.js

+3
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,9 @@ function Browser(window, document, $log, $sniffer, $$taskTrackerFactory) {
108108
if (url) {
109109
var sameState = lastHistoryState === state;
110110

111+
// Normalize the inputted URL
112+
url = urlResolve(url).href;
113+
111114
// Don't change anything if previous and current URLs and states match. This also prevents
112115
// IE<10 from getting into redirect loop when in LocationHashbangInHtml5Url mode.
113116
// See https://github.com/angular/angular.js/commit/ffb2701

test/ng/browserSpecs.js

+59-5
Original file line numberDiff line numberDiff line change
@@ -418,7 +418,7 @@ describe('browser', function() {
418418
browser.url('http://new.org');
419419

420420
expect(pushState).toHaveBeenCalledOnce();
421-
expect(pushState.calls.argsFor(0)[2]).toEqual('http://new.org');
421+
expect(pushState.calls.argsFor(0)[2]).toEqual('http://new.org/');
422422

423423
expect(replaceState).not.toHaveBeenCalled();
424424
expect(locationReplace).not.toHaveBeenCalled();
@@ -430,7 +430,7 @@ describe('browser', function() {
430430
browser.url('http://new.org', true);
431431

432432
expect(replaceState).toHaveBeenCalledOnce();
433-
expect(replaceState.calls.argsFor(0)[2]).toEqual('http://new.org');
433+
expect(replaceState.calls.argsFor(0)[2]).toEqual('http://new.org/');
434434

435435
expect(pushState).not.toHaveBeenCalled();
436436
expect(locationReplace).not.toHaveBeenCalled();
@@ -474,7 +474,7 @@ describe('browser', function() {
474474
sniffer.history = false;
475475
browser.url('http://new.org', true);
476476

477-
expect(locationReplace).toHaveBeenCalledWith('http://new.org');
477+
expect(locationReplace).toHaveBeenCalledWith('http://new.org/');
478478

479479
expect(pushState).not.toHaveBeenCalled();
480480
expect(replaceState).not.toHaveBeenCalled();
@@ -689,6 +689,60 @@ describe('browser', function() {
689689
expect(replaceState).not.toHaveBeenCalled();
690690
expect(locationReplace).not.toHaveBeenCalled();
691691
});
692+
693+
it('should not do pushState with a URL only adding a trailing slash after domain', function() {
694+
// A domain without a trailing /
695+
browser.url('http://server');
696+
697+
pushState.calls.reset();
698+
replaceState.calls.reset();
699+
locationReplace.calls.reset();
700+
701+
// A domain from something such as window.location.href with a trailing slash
702+
browser.url('http://server/');
703+
expect(pushState).not.toHaveBeenCalled();
704+
expect(replaceState).not.toHaveBeenCalled();
705+
expect(locationReplace).not.toHaveBeenCalled();
706+
});
707+
708+
it('should not do pushState with a URL only removing a trailing slash after domain', function() {
709+
// A domain from something such as window.location.href with a trailing slash
710+
browser.url('http://server/');
711+
712+
pushState.calls.reset();
713+
replaceState.calls.reset();
714+
locationReplace.calls.reset();
715+
716+
// A domain without a trailing /
717+
browser.url('http://server');
718+
expect(pushState).not.toHaveBeenCalled();
719+
expect(replaceState).not.toHaveBeenCalled();
720+
expect(locationReplace).not.toHaveBeenCalled();
721+
});
722+
723+
it('should do pushState with a URL only adding a trailing slash after the path', function() {
724+
browser.url('http://server/foo');
725+
726+
pushState.calls.reset();
727+
replaceState.calls.reset();
728+
locationReplace.calls.reset();
729+
730+
browser.url('http://server/foo/');
731+
expect(pushState).toHaveBeenCalledOnce();
732+
expect(fakeWindow.location.href).toEqual('http://server/foo/');
733+
});
734+
735+
it('should do pushState with a URL only removing a trailing slash after the path', function() {
736+
browser.url('http://server/foo/');
737+
738+
pushState.calls.reset();
739+
replaceState.calls.reset();
740+
locationReplace.calls.reset();
741+
742+
browser.url('http://server/foo');
743+
expect(pushState).toHaveBeenCalledOnce();
744+
expect(fakeWindow.location.href).toEqual('http://server/foo');
745+
});
692746
};
693747
}
694748
});
@@ -813,7 +867,7 @@ describe('browser', function() {
813867
it('should not fire urlChange if changed by browser.url method', function() {
814868
sniffer.history = false;
815869
browser.onUrlChange(callback);
816-
browser.url('http://new.com/');
870+
browser.url('http://new.com');
817871

818872
fakeWindow.fire('hashchange');
819873
expect(callback).not.toHaveBeenCalled();
@@ -1093,7 +1147,7 @@ describe('browser', function() {
10931147
it('should not interfere with legacy browser url replace behavior', function() {
10941148
inject(function($rootScope) {
10951149
var current = fakeWindow.location.href;
1096-
var newUrl = 'notyet';
1150+
var newUrl = 'http://notyet/';
10971151
sniffer.history = false;
10981152
expect(historyEntriesLength).toBe(1);
10991153
browser.url(newUrl, true);

0 commit comments

Comments
 (0)