github.com/slspeek/camlistore_namedsearch@v0.0.0-20140519202248-ed6f70f7721a/server/camlistored/ui/navigator_test.js (about)

     1  /*
     2  Copyright 2014 Google Inc.
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8       http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  goog.require('goog.Uri');
    18  goog.require('goog.events.EventTarget');
    19  var assert = require('assert');
    20  
    21  goog.require('cam.Navigator');
    22  
    23  var MockLocation = function() {
    24  	goog.base(this);
    25  	this.href = '';
    26  	this.reloadCount = 0;
    27  };
    28  goog.inherits(MockLocation, goog.events.EventTarget);
    29  MockLocation.prototype.reload = function() {
    30  	this.reloadCount++;
    31  };
    32  
    33  var MockHistory = function() {
    34  	this.states = [null];
    35  };
    36  MockHistory.prototype.pushState = function(a, b, url) {
    37  	this.states.push({state:a, url:url});
    38  };
    39  MockHistory.prototype.replaceState = function(a, b, url) {
    40  	this.states[this.states.length - 1] = {state:a, url:url};
    41  }
    42  
    43  var Handler = function() {
    44  	this.lastURL = null;
    45  	this.returnsTrue = false;
    46  	this.handle = this.handle.bind(this);
    47  };
    48  Handler.prototype.handle = function(url) {
    49  	this.lastURL = url;
    50  	return this.returnsTrue;
    51  };
    52  
    53  describe('cam.Navigator', function() {
    54  	var mockWindow, mockLocation, mockHistory, handler, navigator;
    55  	var url = new goog.Uri('http://www.camlistore.org/foobar');
    56  
    57  	beforeEach(function() {
    58  		mockWindow = new goog.events.EventTarget();
    59  		mockLocation = new MockLocation();
    60  		mockHistory = new MockHistory();
    61  		handler = new Handler();
    62  		navigator = new cam.Navigator(mockWindow, mockLocation, mockHistory);
    63  		navigator.onNavigate = handler.handle;
    64  	});
    65  
    66  	it ('#constructor - seed initial state', function() {
    67  		assert.deepEqual(mockHistory.states, [{state:{}, url:''}]);
    68  	});
    69  
    70  	it('#navigate - no handler', function() {
    71  		// We should do network navigation.
    72  		navigator.onNavigate = function(){};
    73  		navigator.navigate(url);
    74  		assert.equal(mockLocation.href, url.toString());
    75  		assert.equal(mockHistory.states.length, 1);
    76  	});
    77  
    78  	it('#navigate - handler returns false', function() {
    79  		// Both handlers should get called, we should do network navigation.
    80  		navigator.navigate(url);
    81  		assert.equal(handler.lastURL, url);
    82  		assert.equal(mockLocation.href, url.toString());
    83  		assert.equal(mockHistory.states.length, 1);
    84  	});
    85  
    86  	it('#navigate - handler returns true', function() {
    87  		// Both handlers should get called, we should do pushState() navigation.
    88  		handler.returnsTrue = true;
    89  		navigator.navigate(url);
    90  		assert.equal(handler.lastURL, url);
    91  		assert.equal(mockLocation.href, '');
    92  		assert.deepEqual(mockHistory.states, [{state:{}, url:''}, {state:{}, url:url.toString()}]);
    93  	});
    94  
    95  	it('#handleClick_ - handled', function() {
    96  		handler.returnsTrue = true;
    97  		var ev = new goog.events.Event('click');
    98  		ev.button = 0;
    99  		ev.target = {
   100  			nodeName: 'A',
   101  			href: url.toString()
   102  		};
   103  		mockWindow.dispatchEvent(ev);
   104  		assert.equal(mockLocation.href, '');
   105  		assert.deepEqual(mockHistory.states, [{state:{}, url:''}, {state:{}, url:url.toString()}]);
   106  	});
   107  
   108  	it('#handleClick_ - not handled', function() {
   109  		var ev = new goog.events.Event('click');
   110  		ev.button = 0;
   111  		ev.target = {
   112  			nodeName: 'A',
   113  			href: url.toString()
   114  		};
   115  		mockWindow.dispatchEvent(ev);
   116  		assert.equal(mockLocation.href, '');
   117  		assert.deepEqual(mockHistory.states, [{state:{}, url:''}]);
   118  		assert.equal(ev.defaultPrevented, false);
   119  	});
   120  
   121  	it('#handlePopState_ - handled', function() {
   122  		handler.returnsTrue = true;
   123  		mockWindow.dispatchEvent({type:'popstate', state:{}});
   124  		assert.equal(mockLocation.reloadCount, 0);
   125  		assert.deepEqual(mockHistory.states, [{state:{}, url:''}]);
   126  	});
   127  
   128  	it('#handlePopState_ - not handled', function() {
   129  		mockWindow.dispatchEvent({type:'popstate', state:{}});
   130  		assert.equal(mockLocation.reloadCount, 1);
   131  		assert.deepEqual(mockHistory.states, [{state:{}, url:''}]);
   132  	});
   133  
   134  	it('#handlePopState_ - ignore initial popstate', function() {
   135  		// Fire a popstate with no state property. This simulates what happens in buggy browsers onload. This one should be ignored.
   136  		mockWindow.dispatchEvent({type:'popstate', state:null});
   137  		assert.equal(mockLocation.reloadCount, 0);
   138  
   139  		// Now fire a popstate with a state property it should be handled.
   140  		mockWindow.dispatchEvent({type:'popstate', state:{}});
   141  		assert.equal(mockLocation.reloadCount, 1);
   142  	});
   143  });