dojo.provide("tests.webmap.MapManager");

dojo.require("doh.runner");
dojo.require("webmap.MapManager");
dojo.require("tests.Util");
dojo.require("webmap.data");


doh.register("tests.webmap.MapManager", 
	[	
		{
			name: "constructor",
			manager: null,
			subscribeArgs: [],
			addOnLoadArg: null,
			subscribe: dojo.subscribe,
			addOnLoad: dojo.addOnLoad,
			setUp: function(){
				window.undockedWin = null;
				var _this = this;
				dojo.subscribe = function(a0, a1, a2) {
					_this.subscribeArgs.push([a0, a1, a2]);
				};
				dojo.addOnLoad = function(f0) {
					_this.addOnLoadArg = f0;
				};
				this.manager = new webmap.MapManager();
			},
			runTest: function(){
				//TODO: test querystring parsing
				tests.assertEqual(new gov.nyc.doitt.gis.service.webmap.domain.MapData(), this.manager._mapData);
				tests.assertEqual(15, this.subscribeArgs.length);
				tests.assertEqual(["webmap.widget.LayerControl.identified", this.manager, "_identify"], 
					this.subscribeArgs[0]);
				tests.assertEqual(["webmap.WindowManager.identifyItem", this.manager, "_identify"], 
					this.subscribeArgs[1]);
				tests.assertEqual(["webmap.widget.MapEventControl.mouseUp", this.manager, "_doMapEvent"], 
					this.subscribeArgs[2]);
				tests.assertEqual(["webmap.widget.ThemeSelector.changeTheme", this.manager, "_changeTheme"], 
					this.subscribeArgs[3]);
				tests.assertEqual(["webmap.widget.PanControl.panned", this.manager, "_panDir"], 
					this.subscribeArgs[4]);
				tests.assertEqual(["webmap.widget.ZoomControl.zoomLevelChanged", this.manager, "_changeZoomLevel"], 
					this.subscribeArgs[5]);
				tests.assertEqual(["webmap.widget.LayerControl.layerNeeded", this.manager, "_getLayer"], 
					this.subscribeArgs[6]);
				tests.assertEqual(["webmap.widget.LayerControl.layerOff", this.manager, "_layerOff"], 
					this.subscribeArgs[7]);
				tests.assertEqual(["webmap.widget.LayerControl.layersUpdated", this.manager, "_clearMarkup"], 
					this.subscribeArgs[8]);
				tests.assertEqual(["webmap.widget.DockControl.unDocking", this.manager, "_pushMapDataToUndockedWin"], 
					this.subscribeArgs[9]);
				tests.assertEqual(["webmap.widget.DockControl.reDocking", this.manager, "_pushMapDataToRedockedWin"], 
					this.subscribeArgs[10]);
				tests.assertEqual(["webmap.MapManager.reDockComplete", this.manager, "_makeVisible"], 
					this.subscribeArgs[11]);
				tests.assertEqual(["webmap.MapManager.unDockComplete", this.manager, "_resize"], 
					this.subscribeArgs[12]);
				tests.assertEqual(["webmap.widget.LayerControl.resized", this.manager, "_resize"], 
					this.subscribeArgs[13]);
				tests.assertEqual(["webmap.widget.Exporter.beginExport", this.manager, "_export"], 
					this.subscribeArgs[14]);
				tests.assertFalse(this.addOnLoadArg == null);
			},
			tearDown: function(){
				this.manager.destroy();
				dojo.subscribe = this.subscribe;
				dojo.addOnLoad = this.addOnLoad;
			}
		},
		{
			name: "publishMapDataChanged",
			manager: null,
			subscription: null,
			publishArgs: [],
			setUp: function(){
				this.manager = new webmap.MapManager();
				var _this = this;
				this.subscription = dojo.subscribe("webmap.MapManager.mapDataChanged", function(a0, a1) {
					_this.publishArgs.push([a0, a1]);
				});
			},
			runTest: function(){
				// when has layer id
				this.manager._mapData = {clientDataStore: {themeLayerId: 'my theme id'}};
				this.manager._publishMapDataChanged();
				tests.assertEqual(1, this.publishArgs.length);
				tests.assertEqual(2, this.publishArgs[0].length);
				tests.assertEqual(this.manager._mapData, this.publishArgs[0][0]);
				tests.assertEqual(this.manager._mapData.clientDataStore.themeLayerId, this.publishArgs[0][1]);

				// when has client data store, but no layer id
				this.manager._mapData.clientDataStore.themeLayerId = null;
				this.publishArgs = [];
				this.manager._publishMapDataChanged();
				tests.assertEqual(1, this.publishArgs.length);
				tests.assertEqual(2, this.publishArgs[0].length);
				tests.assertEqual(this.manager._mapData, this.publishArgs[0][0]);
				tests.assertEqual(null, this.publishArgs[0][1]);

				// when has no client data store
				this.manager._mapData.clientDataStore = null;
				this.publishArgs = [];
				this.manager._publishMapDataChanged();
				tests.assertEqual(1, this.publishArgs.length);
				tests.assertEqual(2, this.publishArgs[0].length);
				tests.assertEqual(this.manager._mapData, this.publishArgs[0][0]);
				tests.assertEqual(null, this.publishArgs[0][1]);
			},
			tearDown: function(){
				dojo.unsubscribe(this.subscription);
				this.manager.destroy();
			}
		},
		{
			name: "destroy",
			manager: null,
			setUp: function(){
				window.undockedWin = null;
				this.manager = new webmap.MapManager();
			},
			runTest: function(){
				this.manager.destroy();
				tests.assertEqual(null, this.manager._mapData);
				tests.assertEqual(null, this.manager._subscriptions);
			}
		},
		{
			name: "updateClientData",
			manager: null,
			subscription: null,
			pubs: null,
			data: null,
			setUp: function(){
				this.manager = new webmap.MapManager();
				webmap.serviceUrl = null;
				var _this = this;
				this.subscription = dojo.subscribe("webmap.MapManager.clientDataChanged", function(){_this.pubs++;});
				this.manager._xyGroupedCallback = function(d){_this.data = d;};
			},
			runTest: function(){
				var cd = '{identifier:"C0", aliases: {},items: []}';
				var expected = {"store": {"identifier": "C0", "aliases": {}, "items": []}, "_ds": {"_arrayOfAllItems": [], "_arrayOfTopLevelItems": [], "_loadFinished": true, "_jsonFileUrl": undefined, "_jsonData": null, "_datatypeMap": {"Date": {}}, "_features": {"dojo.data.api.Read": true, "dojo.data.api.Identity": "C0"}, "_itemsByIdentity": {}, "_storeRefPropName": "_S", "_itemNumPropName": "_0", "_rootItemPropName": "_RI", "_loadInProgress": false, "_queuedFetches": [], "identifier": "C0", "aliases": {}, "_labelAttr": undefined, "preamble": null, "declaredClass": "dojo.data.ItemFileReadStore", "url": ""}, "_id": "C0", "preamble": null, "declaredClass": "webmap.data.ClientDataStore", "callback": null, "grouped": null, "_xFld": "C1", "_yFld": "C2", "_themeFld": null, "listFields": ["C6", "C4", "C3"], "detailFields": ["C3", "C5", "C7", "C4", "C8", "C9"]};
				this.manager.updateClientData(cd);
				tests.assertEqual(1,this. pubs);
				tests.assertEqual(webmap.config.jsonUrl, webmap.serviceUrl);
				tests.assertEqual(expected, this.manager._clientData);
				expected = {"data": {}, "envelope": {"minX": undefined, "minY": undefined, "maxX": undefined, "maxY": undefined, "preamble": null, "declaredClass": "gov.nyc.doitt.gis.service.map.domain.MapEnvelope"}, "preamble": null, "declaredClass": "gov.nyc.doitt.gis.service.webmap.domain.XyClientData"};
				tests.assertEqual(expected, this.data);
			},
			tearDown: function(){
				webmap.serviceUrl = null;
				this.manager.destroy();
				dojo.unsubscribe(this.subscription);
			}
		},
		{
			name: "updateClientData_addOnLoad",
			manager: null,
			addOnLoad: dojo.addOnLoad,
			added: 0,
			setUp: function(){
				this.manager = new webmap.MapManager();
				webmap.serviceUrl = null;
				var _this = this;
				dojo.addOnLoad = function(){_this.added++;};
			},
			runTest: function(){
				this.manager.updateClientData();
				tests.assertEqual(1, this.added);
			},
			tearDown: function(){
				dojo.addOnLoad = this.addOnLoad;
				this.manager.destroy();
			}
		},
		{
			name: "requestByClientDataStore_passed_sql",
			manager: null,
			ajaxArgs: null,
			setUp: function(){
				window.undockedWin = null;
				this.manager = new webmap.MapManager();
				var _this = this;
				this.manager._ajaxCall = function(args){_this.ajaxArgs = args;};
			},
			runTest: function(){
				this.manager.requestByClientDataStore("my query");
				tests.assertEqual(webmap.config.getThematicMap, this.ajaxArgs[webmap.config.method]);
				tests.assertEqual(this.manager._mapData, this.ajaxArgs[webmap.config.mapData]);
				tests.assertEqual(escape("my query"), this.ajaxArgs[webmap.config.sql]);
				tests.assertEqual('requestByClientDataStore', this.ajaxArgs.caller);
				tests.assertEqual(window.name, this.ajaxArgs.callerWindow);
				
				this.ajaxArgs = null;
				window.undockedWin = "not null";
				this.manager.requestByClientDataStore("my query");
				tests.assertEqual(null, this.ajaxArgs);
			},
			tearDown: function(){
				window.undockedWin = null;
				this.manager.destroy();
			}
		},
		{
			name: "requestByClientDataStore_no_sql",
			manager: null,
			ajaxArgs: null,
			setUp: function(){
				window.undockedWin = null;
				this.manager = new webmap.MapManager();
				this.manager._sql =  escape("my query");
				var _this = this;
				this.manager._ajaxCall = function(args){_this.ajaxArgs = args;};
			},
			runTest: function(){
				this.manager.requestByClientDataStore();
				tests.assertEqual(webmap.config.getThematicMap, this.ajaxArgs[webmap.config.method]);
				tests.assertEqual(this.manager._mapData, this.ajaxArgs[webmap.config.mapData]);
				tests.assertEqual(escape("my query"), this.ajaxArgs[webmap.config.sql]);
				tests.assertEqual('requestByClientDataStore', this.ajaxArgs.caller);
				tests.assertEqual(window.name, this.ajaxArgs.callerWindow);
			},
			tearDown: function(){
				window.undockedWin = null;
				this.manager.destroy();
			}
		},
		{
			name: "toggleTool",
			manager: null,
			subscription: null,
			manager: null,
			setUp: function(){
				window.undockedWin = null;
				this.manager = new webmap.MapManager();
				var _this = this;
				this.subscription = dojo.subscribe("webmap.MapManager.toolToggled", function(args){_this.message = args;});
			},
			runTest: function(){
				this.manager.toggleTool("david");
				tests.assertEqual({tool:"david"}, this.message);
			},
			tearDown: function(){
				this.manager.destroy();
				dojo.unsubscribe(this.subscription);
			}
		},
		{
			name: "_changeTheme",
			manager: null,
			ajaxArgs: null,
			setUp: function(){
				window.undockedWin = null;
				this.manager = new webmap.MapManager();
				var _this = this;
				this.manager._ajaxCall = function(args){_this.ajaxArgs = args;};
			},
			runTest: function(){
				// test not dormant window
				webmap.publish("webmap.widget.ThemeSelector.changeTheme",["aLayer"]);
				tests.assertEqual(webmap.config.getThematicMap, this.ajaxArgs[webmap.config.method]);
				tests.assertEqual(this.manager._mapData, this.ajaxArgs[webmap.config.mapData]);
				tests.assertEqual("aLayer", this.ajaxArgs[webmap.config.themeLayerId]);
				tests.assertEqual('_changeTheme', this.ajaxArgs.caller);
				tests.assertEqual(window.name, this.ajaxArgs.callerWindow);

				// test dormant window
				this.ajaxArgs = null;
				window.undockedWin = "not null";
				webmap.publish("webmap.widget.ThemeSelector.changeTheme",["aLayer"]);
				tests.assertEqual(null, this.ajaxArgs);
			},
			tearDown: function(){
				window.undockedWin = null;
				this.manager.destroy();
			}
		},
		{
			name: "_pushMapDataToUndockedWin",
			manager: null,
			serviceUrl: webmap.config.serviceUrl,
			subscription: null,
			pubs: 0,
			setUp: function(){
				window.undockedWin = {
					MapManager:{
						mapData: null,
						clientData: null,
						_deserializeData:function(mapData, clientData){
							this.mapData = mapData;
							this.clientData = clientData;
						},
						_sql: 'undockedSql'
					},
					webmap:{
						config:{
							serviceUrl:null
						}
					}
				};
				this.manager = new webmap.MapManager();
				this.manager._sql = 'managerSql';
				webmap.config.serviceUrl = "url";
				window.isUndocked = false;
				var _this = this;
				this.subscription = dojo.subscribe("webmap.MapManager.unDockComplete", function(){_this.pubs++;});
			},
			runTest: function(){
				this.manager._mapData = new gov.nyc.doitt.gis.service.webmap.domain.MapData();
				this.manager._clientData = new webmap.data.ClientDataStore({
					data:'{identifier:"C0", aliases: {},items: []}',
					xField: webmap.config.xField,
					yField: webmap.config.yField,
					identifyListFields: webmap.config.identifyListFields,
					identifyDetailFields: webmap.config.identifyDetailFields
				});
				webmap.publish("webmap.widget.DockControl.unDocking", []);
				tests.assertEqual(1, this.pubs);
				tests.assertEqual(dojo.toJson(this.manager._mapData), window.undockedWin.MapManager.mapData);
				tests.assertEqual(dojo.toJson(this.manager._clientData), window.undockedWin.MapManager.clientData);
				tests.assertEqual("url", window.webmap.config.serviceUrl);
				tests.assertEqual(this.manager._sql, window.undockedWin.MapManager._sql);
			},
			tearDown: function(){
				this.manager.destroy();
				dojo.unsubscribe(this.subscription);
				webmap.config.serviceUrl = this.serviceUrl;
			}
		},
		{
			name: "_pushMapDataToUndockedWin_isUndocked",
			manager: null,
			subscription: null,
			pubs: 0,
			setUp: function(){
				window.undockedWin = {
					MapManager:{
						mapData: null,
						clientData: null,
						_deserializeData:function(mapData, clientData){
							this.mapData = mapData;
							this.clientData = clientData;
						}
					},
					webmap:{
						config:{
							serviceUrl:null
						}
					}
				};
				this.manager = new webmap.MapManager();
				window.isUndocked = true;
				var _this = this;
				this.subscription = dojo.subscribe("webmap.MapManager.unDockComplete", function(){_this.pubs++;});
			},
			runTest: function(){
				webmap.publish("webmap.widget.DockControl.unDocking", []);
				tests.assertEqual(null, window.undockedWin.MapManager.mapData);
				tests.assertEqual(null, window.undockedWin.MapManager.clientData);
				tests.assertEqual(null, window.webmap.config.serviceUrl);
				tests.assertEqual(0, this.pubs);
			},
			tearDown: function(){
				this.manager.destroy();
				window.undockedWin = null;
				window.isUndocked = false;
				dojo.unsubscribe(this.subscription);
			}
		},
		{
			name: "_pushMapDataToRedockedWin",
			manager: null,
			subscription: null,
			close: window.close,
			closeCalled: false,
			serviceUrl: webmap.serviceUrl,
			pubs: 0,
			setUp: function(){
				opener = {
					MapManager:{
						mapData: null,
						clientData: null,
						_deserializeData:function(mapData, clientData){
							this.mapData = mapData;
							this.clientData = clientData;
						},
						_sql: 'openerSql'
					},
					webmap:{
						serviceUrl:null
					},
					undockedWin: {}
				};
				this.manager = new webmap.MapManager();
				this.manager._sql = 'managerSql';
				window.undockedWin = null;
				window.isUndocked = true;
				webmap.serviceUrl = "url";
				var _this = this;
				window.close = function(){_this.closeCalled = true;};
				this.subscription = dojo.subscribe("webmap.MapManager.reDockComplete", function(){_this.pubs++;});
			},
			runTest: function(){
				var expected = dojo.toJson(this.manager._mapData);
				webmap.publish("webmap.widget.DockControl.reDocking", []);
				tests.assertEqual(expected, window.opener.MapManager.mapData);
				tests.assertEqual("url", window.opener.webmap.serviceUrl);
				tests.assertEqual(null, this.manager._mapData);
				tests.assertEqual(null, this.manager._clientData);
				tests.assertEqual(null, window.opener.undockedWin);
				tests.assertTrue(this.closeCalled);
				tests.assertEqual(1, this.pubs);
				tests.assertEqual(this.manager._sql, window.opener.MapManager._sql); 
			},
			tearDown: function(){
				this.manager.destroy();
				window.close = this.close;
				webmap.serviceUrl = this.serviceUrl;
				window.opener = null;
				window.undockedWin = null;
				window.isUndocked = false;
				dojo.unsubscribe(this.subscription);
			}
		},
		{
			name: "_getLayer",
			manager: null,
			ajaxArgs: null,
			setUp: function(){
				window.undockedWin = null;
				this.manager = new webmap.MapManager();
				var _this = this;
				this.manager._ajaxCall = function(args){_this.ajaxArgs = args;};
			},
			runTest: function(){
				// test not dormant window
				webmap.publish("webmap.widget.LayerControl.layerNeeded",["aLayer"]);
				tests.assertEqual(webmap.config.getLayer, this.ajaxArgs[webmap.config.method]);
				tests.assertEqual(this.manager._mapData, this.ajaxArgs[webmap.config.mapData]);
				tests.assertEqual("aLayer", this.ajaxArgs[webmap.config.layerId]);
				tests.assertEqual("_getLayer", this.ajaxArgs.caller);
				tests.assertEqual(window.name, this.ajaxArgs.callerWindow);
				
				// test dormant window
				this.ajaxArgs = null;
				window.undockedWin = "not null";
				webmap.publish("webmap.widget.LayerControl.layerNeeded",["aLayer"]);
				tests.assertEqual(null, this.ajaxArgs);
			},
			tearDown: function(){
				this.manager.destroy();
				window.undockedWin = null;
			}
		},
		{
			name: "_gotLayer",
			manager: null,
			subscription: null,
			message: [],
			setUp: function(){
				window.undockedWin = null;
				this.manager = new webmap.MapManager();
				this.manager._isServerError = function(){return false;};
				var _this = this;
				this.subscription = dojo.subscribe("webmap.MapManager.mapDataChanged", function(a0,a1) {
					_this.message.push([a0,a1]);
				});
			},
			runTest: function(){
				// no error
				var mapData = {clientDataStore:{themeLayerId:'abc'}};
				this.manager._gotLayer(mapData);
				tests.assertEqual(1, this.message.length);
				tests.assertEqual(2, this.message[0].length);
				tests.assertEqual(mapData, this.message[0][0]);
				tests.assertEqual(mapData, this.manager._mapData);
				tests.assertEqual('abc', this.message[0][1]);

				// on server error				
				this.message = null;
				this.manager._isServerError = function(){return true;};
				this.manager._gotLayer("another mapData");
				tests.assertEqual(null, this.message);
				tests.assertEqual(mapData, this.manager._mapData);
			},
			tearDown: function(){
				this.manager.destroy();
				dojo.unsubscribe(this.subscription);
			}
		},
		{
			name: "_ajaxCall",
			manager: null,
			subscription: null,
			message: null,
			setUp: function(){
				window.undockedWin = null;
				this.manager = new webmap.MapManager();
				var _this = this;
				this.subscription = dojo.subscribe("webmap.MapManager.ajaxCalled", function(args){_this.message = args;});
			},
			runTest: function(){
				this.manager._ajaxCall({arg:"anArg"});
				tests.assertEqual({arg:"anArg", callback:"_refresh"}, this.message);
				this.manager._ajaxCall({arg:"anArg", callback:"aMethod"});
				tests.assertEqual({arg:"anArg", callback:"aMethod"}, this.message);
			},
			tearDown: function(){
				this.manager.destroy();
				dojo.unsubscribe(this.subscription);
			}
		},
		{
			name: "_afterResize",
			manager: null,
			subscription: null,
			message: [],
			mapData: {clientDataStore:{themeLayerId:'my theme id'}},
			setUp: function(){
				window.undockedWin = null;
				this.manager = new webmap.MapManager();
				this.manager._isServerError = function(){return false;};
				var _this = this;
				this.subscription = dojo.subscribe("webmap.MapManager.mapDataChanged", function(a0, a1){
					_this.message.push([a0, a1]);
				});
			},
			runTest: function(){
				this.manager._afterResize(this.mapData);
				tests.assertEqual([[this.mapData, this.mapData.clientDataStore.themeLayerId]], this.message);
				tests.assertEqual(this.mapData, this.manager._mapData);
				this.message = null;
				this.manager._isServerError = function(){return true;};
				this.manager._afterResize("another mapData");
				tests.assertEqual(null, this.message);
				tests.assertEqual(this.mapData, this.manager._mapData);
			},
			tearDown: function(){
				this.manager.destroy();
				dojo.unsubscribe(this.subscription);
			}
		},
		{
			name: "_resize",
			manager: null,
			ajaxArgs: null,
			setUp: function(){
				window.undockedWin = null;
				this.manager = new webmap.MapManager();
				var _this = this;
				this.manager._ajaxCall = function(args){_this.ajaxArgs = args;};
			},
			runTest: function(){
				this.manager._resize({w:800, h:600});
				tests.assertEqual(webmap.config.reDraw, this.ajaxArgs[webmap.config.method]);
				tests.assertEqual(this.manager._mapData, this.ajaxArgs[webmap.config.mapData]);
				tests.assertEqual('_resize', this.ajaxArgs.caller);
				tests.assertEqual(window.name, this.ajaxArgs.callerWindow);
				tests.assertEqual(800, this.manager._mapData.viewportWidth);
				tests.assertEqual(600, this.manager._mapData.viewportHeight);
			},
			tearDown: function(){
				this.manager.destroy();
			}
		},
		{
			name: "_identify_locations",
			manager: null,
			subscription: null,
			message: null,
			setUp: function(){
				window.undockedWin = null;
				this.manager = new webmap.MapManager();
				this.manager._userPoint = null;
				this.manager._featureId = null;
				var _this = this;
				this.subscription = dojo.subscribe("webmap.MapManager.queryingClientData", function(){_this.message = "received";});
			},
			runTest: function(){
				var clientDataArgs = null;
				this.manager._idClientData = function(a){clientDataArgs = a;};
				var args = new Object();
				args.layerId = "locations"
				args[webmap.config.point] = "p";
				args[webmap.config.featureId] = "fid";
				webmap.publish("webmap.widget.LayerControl.identified", [args]);				
				var expected = new Object();
				tests.assertEqual(args[webmap.config.point], this.manager._userPoint);
				tests.assertEqual(args[webmap.config.featureId], this.manager._featureId);
				tests.assertEqual(args, clientDataArgs);
				tests.assertEqual("received", this.message);
				clientDataArgs = null;
				this.message = null;
				window.undockedWin = "not null";
				webmap.publish("webmap.widget.LayerControl.identified", [{layerId:"locations"}]);				
				tests.assertEqual(null, clientDataArgs);
				tests.assertEqual(null, this.message);
			},
			tearDown: function(){
				window.undockedWin = null;
				this.manager.destroy();
				dojo.unsubscribe(this.subscription);
			}
		},
		{
			name: "_identify_other",
			manager: null,
			subscription: null,
			message: null,
			ajaxArgs: null,
			setUp: function(){
				window.undockedWin = null;
				this.manager = new webmap.MapManager();
				this.manager._userPoint = "p";
				this.manager._featureId = "fid";
				var _this = this;
				this.subscription = dojo.subscribe("webmap.MapManager.queryingClientData", function(){_this.message = "received";});
				this.manager._ajaxCall = function(args){_this.ajaxArgs = args;};
			},
			runTest: function(){
				webmap.publish("webmap.widget.LayerControl.identified", [{layerId:"other"}]);				
				tests.assertEqual(webmap.config.identify, this.ajaxArgs[webmap.config.method]);
				tests.assertEqual('other', this.ajaxArgs[webmap.config.layerId]);
				tests.assertEqual(this.manager._featureId, this.ajaxArgs[webmap.config.featureId]);
				tests.assertEqual(this.manager._userPoint, this.ajaxArgs[webmap.config.point]);
				tests.assertEqual('_identify', this.ajaxArgs.caller);
				tests.assertEqual(window.name, this.ajaxArgs.callerWindow);
				tests.assertEqual(this.manager, this.ajaxArgs.scope);
				tests.assertEqual('_idCallback', this.ajaxArgs.callback);
				tests.assertEqual("received", this.message);
				
				this.ajaxArgs = null;
				this.message = null;
				window.undockedWin = "not null";
				webmap.publish("webmap.widget.LayerControl.identified", [{layerId:"other"}]);				
				tests.assertEqual(null, this.ajaxArgs);
				tests.assertEqual(null, this.message);
			},
			tearDown: function(){
				window.undockedWin = null;
				this.manager.destroy();
				dojo.unsubscribe(this.subscription);
			}
		},
		{
			name: "_panDir",
			manager: null,
			ajaxArgs: null,
			setUp: function(){
				window.undockedWin = null;
				this.manager = new webmap.MapManager();
				var _this = this;
				this.manager._ajaxCall = function(args){_this.ajaxArgs = args;};
			},
			runTest: function(){
				webmap.publish("webmap.widget.PanControl.panned", [{direction:"direction"}]);				
				tests.assertEqual(webmap.config.panDirection, this.ajaxArgs[webmap.config.method]);
				tests.assertEqual(this.manager._mapData, this.ajaxArgs[webmap.config.mapData]);
				tests.assertEqual("direction", this.ajaxArgs[webmap.config.direction]);
				tests.assertEqual("_panDir", this.ajaxArgs.caller);
				tests.assertEqual(window.name, this.ajaxArgs.callerWindow);
		
				this.ajaxArgs = null;
				window.undockedWin = "not null";
				webmap.publish("webmap.widget.PanControl.panned", [{direction:"direction"}]);				
				tests.assertEqual(null, this.ajaxArgs);
			},
			tearDown: function(){
				window.undockedWin = null;
				this.manager.destroy();
			}
		},
		{
			name: "_changeZoomLevel",
			manager: null,
			ajaxArgs: null,
			setUp: function(){
				window.undockedWin = null;
				this.manager = new webmap.MapManager();
				var _this = this;
				this.manager._ajaxCall = function(args) {
					_this.ajaxArgs = args;
				};
			},
			runTest: function(){
				// test window is not dormant
				webmap.publish("webmap.widget.ZoomControl.zoomLevelChanged", [{zoomLevel:9}]);				
				tests.assertEqual(webmap.config.zoomToLevel, this.ajaxArgs[webmap.config.method]);
				tests.assertEqual(this.manager._mapData, this.ajaxArgs[webmap.config.mapData]);
				tests.assertEqual(9, this.ajaxArgs[webmap.config.zoomLevel]);
				tests.assertEqual("_changeZoomLevel", this.ajaxArgs.caller);
				tests.assertEqual(window.name, this.ajaxArgs.callerWindow);
				
				// test when window is dormant
				this.ajaxArgs = null;
				window.undockedWin = "not null";
				webmap.publish("webmap.widget.ZoomControl.zoomLevelChanged", [{zoomLevel:5}]);				
				tests.assertEqual(null, this.ajaxArgs);
			},
			tearDown: function(){
				window.undockedWin = null;
				this.manager.destroy();
			}
		},
		{
			name: "_doMapEvent_zoomIn",
			manager: null,
			ajaxArgs: null,
			setUp: function(){
				window.undockedWin = null;
				this.manager = new webmap.MapManager();
				var _this = this;
				this.manager._ajaxCall = function(args){_this.ajaxArgs = args;};
				this.manager._getZoomArgs = function(args){args.method = "zoomIn";return args;};
			},
			runTest: function(){
				webmap.publish("webmap.widget.MapEventControl.mouseUp", [{tool:"zoomIn", arg:"anArg"}]);
				var expected = new Object();
				expected.method = "zoomIn";
				expected.arg = "anArg";
				tests.assertEqual(expected, this.ajaxArgs);
				this.ajaxArgs = null;
				window.undockedWin = "not null";
				webmap.publish("webmap.widget.MapEventControl.mouseUp", [{tool:"zoomIn", arg:"anArg"}]);
				tests.assertEqual(null, this.ajaxArgs);
			},
			tearDown: function(){
				window.undockedWin = null;
				this.manager.destroy();
			}
		},
		{
			name: "_doMapEvent_pan",
			manager: null,
			ajaxArgs: null,
			setUp: function(){
				window.undockedWin = null;
				this.manager = new webmap.MapManager();
				var _this = this;
				this.manager._ajaxCall = function(args){_this.ajaxArgs = args;};
				this.manager._getPanArgs = function(args){args.method = "pan";return args;};
			},
			runTest: function(){
				webmap.publish("webmap.widget.MapEventControl.mouseUp", [{tool:"pan", arg:"anArg"}]);
				var expected = new Object();
				expected.method = "pan";
				expected.arg = "anArg";
				tests.assertEqual(expected, this.ajaxArgs);
				this.ajaxArgs = null;
				window.undockedWin = "not null";
				webmap.publish("webmap.widget.MapEventControl.mouseUp", [{tool:"pan", arg:"anArg"}]);
				tests.assertEqual(null, this.ajaxArgs);
			},
			tearDown: function(){
				window.undockedWin = null;
				this.manager.destroy();
			}
		},
		{
			name: "_getZoomArgs_isNotPointClick",
			manager: null,
			setUp: function() {
				this.manager = new webmap.MapManager();
			},
			runTest: function() {
				var args = {
					isPointClick: function() { return false;}, 
					getEnvelope: function() { return 'abc'}};
				var ajaxArgs = this.manager._getZoomArgs(args);
				tests.assertEqual(this.manager._mapData, ajaxArgs[webmap.config.mapData]);
				tests.assertEqual(webmap.config.zoomToEnvelope, ajaxArgs[webmap.config.method]);
				tests.assertEqual('abc', ajaxArgs[webmap.config.envelope]);
				tests.assertEqual('_getZoomArgs', ajaxArgs.caller);
				tests.assertEqual(window.name, ajaxArgs.callerWindow); 
			},
			tearDown: function() {
				this.manager.destroy();
			}
		},
		{
			name: "_getZoomArgs_isPointClick",
			manager: null,
			setUp: function() {
				this.manager = new webmap.MapManager();
			},
			runTest: function() {
				var args = {isPointClick: function() { return true;}, getOrigin: function() { return 'abc'}};
				var ajaxArgs = this.manager._getZoomArgs(args);
				tests.assertEqual(this.manager._mapData, ajaxArgs[webmap.config.mapData]);
				tests.assertEqual(webmap.config.zoomToPoint, ajaxArgs[webmap.config.method]);
				tests.assertEqual('abc', ajaxArgs[webmap.config.point] = args.getOrigin());
				tests.assertEqual(window.name, ajaxArgs.callerWindow); 
			},
			tearDown: function() {
				this.manager.destroy();
			}
		},
		{
			name: "_getPanArgs_isNotPointClick",
			manager: null,
			setUp: function() {
				this.manager = new webmap.MapManager();
			},
			runTest: function() {
				var args = {
					isPointClick: function() { return false;}, 
					getFromPoint: function() { return 'abc'}, 
					getToPoint: function() { return 'def'}};
				var ajaxArgs = this.manager._getPanArgs(args);
				tests.assertEqual(webmap.config.pan, ajaxArgs[webmap.config.method]);
				tests.assertEqual('abc', ajaxArgs[webmap.config.fromPoint]);
				tests.assertEqual('def', ajaxArgs[webmap.config.toPoint]);
				tests.assertEqual('_getPanArgs', ajaxArgs.caller);
				tests.assertEqual(window.name, ajaxArgs.callerWindow); 
			},
			tearDown: function() {
				this.manager.destroy();
			}
		},
		{
			name: "_getPanArgs_isPointClick",
			manager: null,
			setUp: function() {
				this.manager = new webmap.MapManager();
			},
			runTest: function() {
				var args = {isPointClick: function() { return true;}, getOrigin: function() { return 'abc'}};
				var ajaxArgs = this.manager._getPanArgs(args);
				tests.assertEqual(webmap.config.reCenter, ajaxArgs[webmap.config.method]);
				tests.assertEqual('abc', ajaxArgs[webmap.config.point]);
				tests.assertEqual('_getPanArgs', ajaxArgs.caller);
				tests.assertEqual(window.name, ajaxArgs.callerWindow); 
			},
			tearDown: function() {
				this.manager.destroy();
			}
		},
		{
			name: "_xyGroupedCallback",
			manager: null,
			ajaxArgs: null,
			setUp: function(){
				window.undockedWin = null;
				this.manager = new webmap.MapManager();
				var _this = this;
				this.manager._ajaxCall = function(args){_this.ajaxArgs = args;};
			},
			runTest: function(){
				this.manager._xyGroupedCallback("data");
				var expected = new Object();
				expected[webmap.config.method] = webmap.config.getThematicMap;
				expected[webmap.config.mapData] = this.manager._mapData;
				tests.assertEqual("data", this.manager._mapData.clientData);
				tests.assertEqual(expected, this.ajaxArgs);
				tests.assertEqual("_xyGroupedCallback", this.ajaxArgs.caller);
				tests.assertEqual(window.name, this.ajaxArgs.callerWindow);
			},
			tearDown: function(){
				this.manager.destroy();
			}
		},
		{
			name: "_refresh_not_null_clientData_no_theme",
			manager: null,
			mapData: null,
			themeId: null,
			subscription: null,
			setUp: function(){
				window.undockedWin = null;
				this.manager = new webmap.MapManager();
				var _this = this;
				this.subscription = dojo.subscribe("webmap.MapManager.mapDataChanged", function(a0,a1){_this.mapData = a0;_this.themeId = a1;});
				this.manager._clientData = "not null";
				this.manager._isServerError = function(){return false;};
			},
			runTest: function(){
				this.manager._refresh({clientDataStore:"client Data Store"});
				tests.assertEqual({clientDataStore:"client Data Store"}, this.manager._mapData);
				tests.assertEqual(this.manager._mapData, this.mapData);
				tests.assertEqual(null, this.themeId);
				tests.assertEqual("client Data Store", this.manager._mapData.clientDataStore);
				tests.assertEqual("not null", this.manager._clientData);
			},
			tearDown: function(){
				this.manager.destroy();
				dojo.unsubscribe(this.subscription);
			}
		},
		{
			name: "_refresh_not_null_clientData_has_theme",
			manager: null,
			args: [],
			subscription: null,
			setUp: function(){
				window.undockedWin = null;
				this.manager = new webmap.MapManager();
				var _this = this;
				this.subscription = dojo.subscribe("webmap.MapManager.mapDataChanged", function(a0,a1){
					_this.args.push([a0,a1]);
				});
				this.manager._clientData = "not null";
				this.manager._isServerError = function(){return false;};
			},
			runTest: function(){
				this.manager._refresh({clientDataStore:{themeLayerId:"theme"}});
				tests.assertEqual(1, this.args.length);
				tests.assertEqual(2, this.args[0].length);
				tests.assertEqual({clientDataStore:{themeLayerId:"theme"}}, this.manager._mapData);
				tests.assertEqual(this.manager._mapData, this.args[0][0]);
				tests.assertEqual("theme", this.args[0][1]);
				tests.assertEqual({themeLayerId:"theme"}, this.manager._mapData.clientDataStore);
				tests.assertEqual("not null", this.manager._clientData);
			},
			tearDown: function(){
				this.manager.destroy();
				dojo.unsubscribe(this.subscription);
			}
		},
		{
			name: "_refresh_null_clientData",
			manager: null,
			message: [],
			subscription: null,
			setUp: function(){
				window.undockedWin = null;
				this.manager = new webmap.MapManager();
				var _this = this;
				this.subscription = dojo.subscribe("webmap.MapManager.mapDataChanged", function(a0, a1){
					_this.message.push([a0, a1]);
				});
				this.manager._isServerError = function(){return false;};
			},
			runTest: function(){
				// test when clientDatStore has no layer id
				this.manager._refresh({clientDataStore:{}});
				tests.assertEqual(1, this.message.length);
				tests.assertEqual(2, this.message[0].length);
				tests.assertEqual([this.manager._mapData, null], this.message);
				tests.assertEqual(null, this.manager._mapData.clientDataStore);
				tests.assertEqual("webmap.data.ClientDataStore", this.manager._clientData.declaredClass);

				// test when server error
				this.message = null;
				this.manager._isServerError = function(){return true;};
				this.manager._mapData = "map data before";
				this.manager._clientData = "client data before";
				this.manager._refresh("another mapData");
				tests.assertEqual(null, this.message);
				tests.assertEqual("map data before", this.manager._mapData);
				tests.assertEqual("client data before", this.manager._clientData);
			},
			tearDown: function(){
				this.manager.destroy();
				dojo.unsubscribe(this.subscription);
			}
		},
		{
			name: "_idCallback",
			manager: null,
			message: null,
			subscription: null,
			setUp: function(){
				window.undockedWin = null;
				this.manager = new webmap.MapManager();
				var _this = this;
				this.subscription = dojo.subscribe("webmap.MapManager.identified", function(args){_this.message = args;});
				this.manager._userPoint = "user point";
				this.manager._featureId = "fid";
			},
			runTest: function(){
				this.manager._idCallback("data");
				var expected = new Object();
				expected[webmap.config.point] = this.manager._userPoint;
				expected[webmap.config.featureId] = this.manager._featureId;
				expected.data = "data";
				tests.assertEqual(expected, this.message);
			},
			tearDown: function(){
				this.manager.destroy();
				dojo.unsubscribe(this.subscription);
			}
		},
		{
			name: "_clearMarkup",
			manager: null,
			setUp: function(){
				window.undockedWin = null;
				this.manager = new webmap.MapManager();
			},
			runTest: function(){
				this.manager._mapData = {markup:"markup"};
				webmap.publish("webmap.widget.LayerControl.layersUpdated");
				tests.assertEqual(null,	this.manager._mapData.markup);
			},
			tearDown: function(){
				this.manager.destroy();
			}
		},
		{
			name: "_export",
			manager: null,
			subscription: null,
			message: null,
			setUp: function(){
				window.undockedWin = null;
				this.manager = new webmap.MapManager();
				this.manager._mapData = "map data";
				var _this = this;
				this.subscription = dojo.subscribe("webmap.MapManager.exporting", function(arg){_this.message = arg;});
			},
			runTest: function(){
				this.manager._export();
				tests.assertEqual(this.manager._mapData, this.message);
				this.manager._mapData = "other";
				window.undockedWin = "not null";
				this.message = null;
				this.manager._export();
				tests.assertEqual(null, this.message);
			},
			tearDown: function(){
				window.undockedWin = null;
				this.manager.destroy();
			}
		},
		{
			name: "_isServerError",
			manager: null,
			subscription: null,
			message: null,
			errorMessage: null,
			errorMapData: {statusCode:1, statusMessage:"THIS ERROR MESSAGE IS A SUCCESSFUL TEST OF ERROR HANDLING"},
			errorConsole: console.error,
			setUp: function(){
				window.undockedWin = null;
				this.manager = new webmap.MapManager();
				this.manager._mapData = "map data";
				var _this = this;
				this.subscription = dojo.subscribe("webmap.MapManager.serverError", function(arg){_this.message = arg;});
				console.error = function(msg){_this.errorMessage = msg;};
			},
			runTest: function(){
				tests.assertFalse(this.manager._isServerError({statusCode:0}));
				tests.assertTrue(this.manager._isServerError(this.errorMapData));
				tests.assertEqual(this.errorMapData, this.message);
				tests.assertEqual(this.errorMapData.statusMessage, this.errorMessage);
			},
			tearDown: function(){
				console.error = this.errorConsole;
				window.undockedWin = null;
				this.manager.destroy();
			}
		},
		{
			name: "publish_not_null_undockedWin",
			dojoPublish: dojo.publish,
			dojoEvt: null,
			dojoArgs: null,
			dojoCount: 0,
			publishSerialized: webmap.publishSerialized,
			webmapEvt: null,
			webmapArgs: null,
			webmapCount: 0,
			undockedWin: null,
			setUp: function(){
				var _this = this;
				dojo.publish = function(evt, args){
					_this.dojoCount++; 
					_this.dojoEvt = evt; 
					_this.dojoArgs = args;
				};
				webmap.publishSerialized = function(win, evt, args){
					_this.webmapCount++; 
					_this.undockedWin = win; 
					_this.webmapEvt = evt; 
					_this.webmapArgs = args;
				};
				window.undockedWin = "not null";
			},
			runTest: function(){
				webmap.publish("event", "message");
				tests.assertEqual("event", this.dojoEvt);
				tests.assertEqual("message", this.dojoArgs);
				tests.assertEqual(1, this.dojoCount);
				tests.assertEqual(window.undockedWin, this.undockedWin);
				tests.assertEqual("event", this.webmapEvt);
				tests.assertEqual("message", this.webmapArgs);
				tests.assertEqual(1, this.webmapCount);
			},
			tearDown: function(){
				window.undockedWin = null;
				dojo.publish = this.dojoPublish;
				webmap.publishSerialized = this.publishSerialized;
			}
		},
		{
			name: "publish_null_undockedWin_isUndocked_true_opener_has_no_parent",
			dojoPublish: dojo.publish,
			dojoEvt: null,
			dojoArgs: null,
			dojoCount: 0,
			publishSerialized: webmap.publishSerialized,
			webmapEvt: null,
			webmapArgs: null,
			webmapCount: 0,
			win: null,
			setUp: function(){
				var _this = this;
				dojo.publish = function(evt, args){
					_this.dojoCount++; 
					_this.dojoEvt = evt; 
					_this.dojoArgs = args;
				};
				webmap.publishSerialized = function(win, evt, args){
					_this.webmapCount++; 
					_this.win = win; 
					_this.webmapEvt = evt; 
					_this.webmapArgs = args;
				};
				opener = {};
				opener.parent = opener;
				window.undockedWin = null;
				window.isUndocked = true;
			},
			runTest: function(){
				webmap.publish("event", "message");
				tests.assertEqual("event", this.dojoEvt);
				tests.assertEqual("message", this.dojoArgs);
				tests.assertEqual(1, this.dojoCount);
				tests.assertEqual(window.opener, this.win);
				tests.assertEqual("event", this.webmapEvt);
				tests.assertEqual("message", this.webmapArgs);
				tests.assertEqual(1, this.webmapCount);
			},
			tearDown: function(){
				window.isUndocked = false;
				window.opener = null;
				dojo.publish = this.dojoPublish;
				webmap.publishSerialized = this.publishSerialized;
			}
		},
		{
			name: "publish_null_undockedWin_isUndocked_false_window_has_no_parent",
			dojoPublish: dojo.publish,
			dojoEvt: null,
			dojoArgs: null,
			dojoCount: 0,
			publishSerialized: webmap.publishSerialized,
			webmapEvt: null,
			webmapArgs: null,
			webmapCount: 0,
			win: null,
			setUp: function(){
				var _this = this;
				dojo.publish = function(evt, args){
					_this.dojoCount++; 
					_this.dojoEvt = evt; 
					_this.dojoArgs = args;
				};
				webmap.publishSerialized = function(win, evt, args){
					_this.webmapCount++; 
					_this.win = win; 
					_this.webmapEvt = evt; 
					_this.webmapArgs = args;
				};
				window.undockedWin = null;
				window.isUndocked = false;
			},
			runTest: function(){
				webmap.publish("event", "message");
				tests.assertEqual("event", this.dojoEvt);
				tests.assertEqual("message", this.dojoArgs);
				tests.assertEqual(1, this.dojoCount);
				tests.assertEqual(null, this.win);
				tests.assertEqual(null, this.webmapEvt);
				tests.assertEqual(null, this.webmapArgs);
				tests.assertEqual(0, this.webmapCount);
			},
			tearDown: function(){
				dojo.publish = this.dojoPublish;
				webmap.publishSerialized = this.publishSerialized;
			}
		},
		{
			name: "publish_null_undockedWin_isUndocked_false_window_has_parent",
			dojoPublish: dojo.publish,
			dojoEvt: null,
			dojoArgs: null,
			dojoCount: 0,
			publishSerialized: webmap.publishSerialized,
			webmapEvt: null,
			webmapArgs: null,
			webmapCount: 0,
			win: null,
			setUp: function(){
				var _this = this;
				dojo.publish = function(evt, args){
					_this.dojoCount++; 
					_this.dojoEvt = evt; 
					_this.dojoArgs = args;
				};
				webmap.publishSerialized = function(win, evt, args){
					_this.webmapCount++; 
					_this.win = win; 
					_this.webmapEvt = evt; 
					_this.webmapArgs = args;
				};
				parent = {name:"parentWin"};
				window.undockedWin = null;
				window.isUndocked = false;
			},
			runTest: function(){
				webmap.publish("event", "message");
				tests.assertEqual("event", this.dojoEvt);
				tests.assertEqual("message", this.dojoArgs);
				tests.assertEqual(1, this.dojoCount);
				tests.assertEqual(window.parent, this.win);
				tests.assertEqual("event", this.webmapEvt);
				tests.assertEqual("message", this.webmapArgs);
				tests.assertEqual(1, this.webmapCount);
			},
			tearDown: function(){
				window.parent = window;
				dojo.publish = this.dojoPublish;
				webmap.publishSerialized = this.publishSerialized;
			}
		},
		{
			name: "publish_null_undockedWin_isUndocked_true_opener_has_parent",
			dojoPublish: dojo.publish,
			dojoEvt: null,
			dojoArgs: null,
			dojoCount: 0,
			publishSerialized: webmap.publishSerialized,
			webmapEvt: [],
			webmapArgs: [],
			win: [],
			setUp: function(){
				var _this = this;
				dojo.publish = function(evt, args){
					_this.dojoCount++; 
					_this.dojoEvt = evt; 
					_this.dojoArgs = args;
				};
				webmap.publishSerialized = function(win, evt, args){
					_this.win.push(win); 
					_this.webmapEvt.push(evt); 
					_this.webmapArgs.push(args);
				};
				opener = {parent:{name:"parentWin"}};
				window.undockedWin = null;
				window.isUndocked = true;
			},
			runTest: function(){
				webmap.publish("event", "message");
				tests.assertEqual("event", this.dojoEvt);
				tests.assertEqual("message", this.dojoArgs);
				tests.assertEqual(1, this.dojoCount);
				tests.assertEqual([window.opener,window.opener.parent], this.win);
				tests.assertEqual(["event","event"], this.webmapEvt);
				tests.assertEqual(["message","message"], this.webmapArgs);
			},
			tearDown: function(){
				window.isUndocked = false;
				window.opener = null;
				dojo.publish = this.dojoPublish;
				webmap.publishSerialized = this.publishSerialized;
			}
		},
		{
			name: "ff_publishSerialized_win_has_dojo",
			dojoPublish: dojo.publish,
			dojoEvt: null,
			dojoArgs: null,
			dojoCount: 0,
			win: null,
			setUp: function(){
				var _this = this;
				this.win = {
					dojo: {
						publish: function(evt, args){
							_this.dojoCount++; 
							_this.dojoEvt = evt; 
							_this.dojoArgs = args;
						}
					}
				};
				window.undockedWin = null;
			},
			runTest: function(){
				webmap.publishSerialized(this.win, "event", "message");
				tests.assertEqual("event", this.dojoEvt);
				tests.assertEqual("message", this.dojoArgs);
				tests.assertEqual(1, this.dojoCount);
			},
			tearDown: function(){
				dojo.publish = this.dojoPublish;
			}
		}
	]
);