<commit_before>/*
 ---

 name: Tree

 script: tree.js

 description: MUI.Tree - Creates a generic tree control.

 copyright: (c) 2014 Contributors in (/AUTHORS.txt).

 license: MIT-style license in (/MIT-LICENSE.txt).

 note:
 This documentation is taken directly from the javascript source files. It is built using Natural Docs.

 requires:
 - Core/Element
 - Core/Class
 - Core/Options
 - Core/Events
 - MUI
 - MUI.Core

 provides: [MUI.Tree]
 ...
 */

MUI.Tree = new NamedClass('MUI.Tree', {

	Implements: [Events, Options],

	options: {
		id:					'',				// id of the primary element, and id os control that is registered with mocha
		container:			null,			// the parent control in the document to add the control to
		clearContainer:		true,			// should the control clear its parent container before it appends itself
		drawOnInit:			true,			// true to add tree to container when control is initialized

		content:			false,			// used to load content
		nodes:				[],				// the hierarchical list of nodes

		textField:			'text',			// the name of the field that has the node's text
		valueField:			'value',		// the name of the field that has the node's value
		idField:			'id',			// the name of the field that has anchors id value
		titleField:			'title',		// the name of the field that has the node's tip text
		isCheckedField:		'checked',		// the name of the field that has the node's isChecked state
		hasChildrenField:	'hasChildren',	// the name of the field that has the node's hasChildren flag
		imageField:			'image',		// the name of the field that has the node's image if imageOpenField and imageClosedField are not defined
		imageOpenField:		'imageOpen',	// the name of the field that has the node's open image
		imageClosedField:	'imageClosed',	// the name of the field that has the node's closed image

		partner:			false,			// default partner element to send content to
		partnerMethod:		'xhr',			// default loadMethod when sending content to partner
		cssClass:			'mui-tree',			// the primary css tag
		showIcon:			true,
		showCheckBox:		false,			// true to show checkBoxes
		canSelect:			true,			// can the user select a node by clicking it
		value:				'',				// the currently selected node's value
		selectedNode:		null,			// the currently selected node
		depth:				2				// how deep to expand the nodes to

		//onNodeExpanded:	null			// event: called when node is expanded
		//onNodeChecked: 	null			// event: called when node's checkbox is checked
		//onNodeClicked:	null			// event: when a node is checked
		//onLoaded:		    null			// event: called when tree is done building itself
	},

	initialize: function(options){
		this.setOptions(options);
		options = this.options;
		this.el = {};

		// If tree has no ID, give it one.
		this.id = options.id = options.id || 'tree' + (++MUI.idCount);
		MUI.set(this.id, this);

		if (options.content){
			options.content.loadMethod = MUI.getDefaultJsonProvider(options.content.loadMethod);
			options.content.onLoaded = (function(element, options){
				this.options.nodes = MUI.Content.getRecords(options);
				this.draw();
			}).bind(this);
			MUI.Content.update(options.content);
		} else {
			// create sub items if available
			if (options.drawOnInit && options.nodes.length > 0) this.draw();
		}
	},

	draw: function(container){
		var o = this.options;
		if (!container) container = o.container;

		var isNew = false;
		var div = o.element ? o.element : $(o.id);
		var ul;
		if (!div){
			div = new Element('div', {'id': o.id, 'class': o.cssClass});
			isNew = true;
		} else ul = div.getElement('ul');
		if (!ul) ul = new Element('ul', {'class': o.cssClass}).inject(div.empty());
		else ul.empty();
		this.el.element = div;

		var nodes = o.nodes;
		if (o.nodes.length > 1){
			var li = new Element('li').inject(ul);
			ul = new Element('ul').inject(li);
		}
		nodes.each(function(node){
			this.buildNode(node, ul, 1);
		}, this);
		var first = ul.getFirst();
		if (first) first.addClass('first');
		var last = ul.getChildren().getLast();
		if (last) last.addClass('last');

		o.depth = 0;

		if (!isNew){
			this.fireEvent('loaded', [this]);
			return this;
		}

		var addToContainer = function(){
			if (o.clearContainer) container.empty();
			div.inject(container);
			this.fireEvent('loaded', [this]);
		}.bind(this);

		if (typeof(container) == 'element'){
			addToContainer();
			return this;
		} else window.addEvent('domready', function(){
			// determine parent container object
			if (typeof(container) == 'string'){
				container = $(container);
				var instance = MUI.get(container);
				if (instance){
					div.setStyle('overflow', 'auto');
					if (instance.el.content) container = instance.el.content;
				}
			}
			addToContainer();
		}.bind(this));

		return this;
	},

	selectValue: function(val, e, suppressEvent){
		var self = this;
		var o = self.options;
		var node = self.nodeFind(val);
		if (!node) return;

		if (!o.canSelect){
			if (o.showCheckBox){
				node._checkbox.checked = !node._checkbox.checked;
				self.onNodeCheck(node, e);
			} else if (!suppressEvent) this.fireEvent('nodeSelected', [node, self, e]);
			return;
		}

		if (node._element){
			if (o.selectedNode && o.selectedNode._element) o.selectedNode._element.getElement('a').removeClass('sel');
			o.selectedNode = node;
			node._element.getElement('a').addClass('sel');
		}
		o.value = val;
		if (!suppressEvent) this.fireEvent('nodeSelected', [node, self, e]);
	},

	updateNode: function(node){
		if (!node) return;

		var self = this;
		var o = self.options;
		var n = node;
		if (!node._element) n = self.nodeFind(MUI.getData(node, o.valueField));
		if (n){
			var el = n._element;
			if (el){
				self.buildNode(node, el.getParent());
				self.setLast(el.getParent());
			}
		}
	},

	buildNode: function(node, parent, depth){
		var o = this.options;
		if (!depth) depth = 1;

		var a, span, ul, li;
		var id = MUI.getData(node, o.idField);
		if (!id) id = 'tn' + (++MUI.idCount);

		if (node._element != null) li = node._element;
		if (!li) li = new Element('li', {'id': id + '_li'});
		else li.empty();

		if (parent){
			if (parent._ul) li.inject(parent._ul);
			else li.inject(parent);
		}

		var value = MUI.getData(node, o.valueField);
		var text = MUI.getData(node, o.textField);
		if (o.showCheckBox) node._checkbox = new Element('INPUT', {'type': 'checkbox', 'value': value, 'id': id + '_cb'}).inject(li);
		a = node._a = new Element('a', {'id': id}).inject(li);
		if (node.target) a.setAttribute('target', node.target); 									// add anchor target
		span = node._span = new Element('span', {'text': text, 'id': id + '_tle'}).inject(a);		// add node text
		if (o.showIcon) node._icon = new Element('span', {'class': 'mui-treeIcon'}).inject(a, 'top');	// add node image

		node._element = li;
		var title = MUI.getData(node, o.titleField);
		if (title) a.title = title;

		var url = node.url;
		if (!url || node.registered){		// is node using registered function mapping
			url = '#';

			// determine partner settings
			var partner = node.partnerContent;
			if (url && partner){
				if (!partner.element) partner.element = o.partner;
				if (!partner.loadMethod) partner.loadMethod = o.partnerMethod;
				if (!partner.title) partner.title = node.title;
				if (!partner.title) partner.title = node.text;
				if (partner.element) a.addEvent('click', MUI.getPartnerLoader(this, partner));
			} else

			// if not using a partner then check for registered method calls
			if (node.registered && node.registered != '')
				a.addEvent('click', MUI.getRegistered(this, node.registered, [node]));
		}
		a.setAttribute('href', MUI.replacePaths(url));

		if (o.value == value){
			this.el.element.getElements('.sel').removeClass('sel');
			a.className = 'sel';
			o.selectedNode = this;
		}

		if (node.nodes && node.nodes.length > 0){
			if (!ul) ul = new Element('ul').inject(li);
			if (!node.isExpanded && o.depth <= depth){
				ul.style.display = 'none';
				node.isExpanded = false;
			} else node.isExpanded = true;
			node._ul = ul;

			for (var i = 0; i < node.nodes.length; i++){
				this.buildNode(node.nodes[i], node, depth + 1);
			}
			ul.childNodes[ul.childNodes.length - 1].addClass('last');
		} else li.addClass('nochild');
		if (node.isExpanded) li.set('class', 'O');

		// add image to node if necessary
		this._nodeSetImage(node);

		var hasChildren = MUI.getData(node, o.hasChildrenField);
		if (hasChildren && li.hasClass('nochild')) li.removeClass('nochild').addClass('C');

		// set events
		if (node._checkbox){
			var isChecked = MUI.getData(node, o.isCheckedField);
			if (isChecked != null) node._checkbox.checked = isChecked;
			node._checkbox.removeEvents('click')._checkbox.addEvent('click', MUI.getWrappedEvent(this, this.onNodeCheck, [node]));
		}
		li.addEvent('click', MUI.getWrappedEvent(this, this.onNodeExpand, [node]));
		a.addEvent('click', MUI.getWrappedEvent(this, this.onNodeClick, [node]));

		return this;
	},

	nodeFind: function(val, node){
		var self = this;
		var o = self.options;
		if (node != null){
			var value = MUI.getData(node, o.valueField);
			if (value && value + '' == val + '') return node;
		} else node = self;
		var nodes;
		if (node.options) nodes = node.options.nodes;
		if (nodes == null) nodes = node.nodes;
		if (nodes){
			var l = nodes.length;
			for (var i = 0; i < l; i++){
				var snode = this.nodeFind(val, nodes[i]);
				if (snode) return snode;
			}
		}
		return null;
	},

	nodeRefresh: function(node){
		if (!node._element) return;
		this.buildNode(node, node._element.getParent())
				.setLast(node._element.getParent());
	},

	nodeGetPath: function(node){
		var self = this;
		var o = self.options;
		var value = MUI.getData(node, o.valueField);

		if (!node._parent) return value;
		return this.getPath(node._parent) + '/' + value;
	},

	setLast: function(node){
		if (!node) return this;
		if (node.childNodes){
			var u = node;
			if (node.nodeName != 'UL') u = node.getElement('ul');
			if (u){
				var children = u.getChildren();
				if (children){
					children.removeClass('last');
					children.getLast().addClass('last');
				}
			}
		}
		return this;
	},

	_nodeSetImage: function(node){
		var o = this.options;
		var span = node._span;
		var def = MUI.getData(node, o.imageField);
		var open = MUI.getData(node, o.imageOpenField) || def;
		var closed = MUI.getData(node, o.imageClosedField) || def;

		span.removeClass(closed).removeClass(open);

		if (closed && !node.isExpanded){
			if (closed.indexOf('.') < 0) span.addClass(closed);
			else span.setStyles({'background': 'transparent url(' + closed + ') no-repeat scroll left top', 'paddingLeft': '20px'});
		}
		if (open && node.isExpanded){
			if (open.indexOf('.') < 0) span.addClass(open);
			else span.setStyles({'background': 'transparent url(' + open + ') no-repeat scroll left top', 'paddingLeft': '20px'});
		}
	},

	onNodeExpand: function(e, node){
		var itm = node._element;
		var mY = 0;
		var mX = 0;
		if (e){
			e.stop();
			var c = itm.getCoordinates();
			mY = e.client.y - c.top;
			mX = e.client.x - c.left;
		}

		if (mX < 20 && mY < 20){
			var ul = itm.getElement('ul');
			if (ul && node.isExpanded){
				ul.style.display = 'none';
				itm.removeClass('O').addClass('C');
				node.isExpanded = false;
				//return;
			} else if (ul && !node.isExpanded){
				ul.style.display = '';
				itm.removeClass('C').addClass('O');
				node.isExpanded = true;
				//if (node.nodes.length > 0) return;
			}
			this._nodeSetImage(node);
		}

		this.fireEvent('nodeExpanded', [e, node, this]);
	},

	onNodeClick: function(e, node){
		var o = this.options;
		e.stop();
		this.selectValue(MUI.getData(node, o.valueField), e);
		this.fireEvent('nodeClicked', [e, node, this]);
	},

	onNodeCheck: function(e, node){
		e.stopPropagation();
		this.fireEvent('nodeChecked', [e, node, this]);
	}

});
<commit_msg>Update tree.js<commit_after>/*
 ---

 name: Tree

 script: tree.js

 description: MUI.Tree - Creates a generic tree control.

 copyright: (c) 2014 Contributors in (/AUTHORS.txt).

 license: MIT-style license in (/MIT-LICENSE.txt).

 note:
 This documentation is taken directly from the javascript source files. It is built using Natural Docs.

 requires:
 - Core/Element
 - Core/Class
 - Core/Options
 - Core/Events
 - MUI
 - MUI.Core

 provides: [MUI.Tree]
 ...
 */

MUI.Tree = new NamedClass('MUI.Tree', {

	Implements: [Events, Options],

	options: {
		id:					'',				// id of the primary element, and id os control that is registered with mocha
		container:			null,			// the parent control in the document to add the control to
		clearContainer:		true,			// should the control clear its parent container before it appends itself
		drawOnInit:			true,			// true to add tree to container when control is initialized

		content:			false,			// used to load content
		nodes:				[],				// the hierarchical list of nodes

		textField:			'text',			// the name of the field that has the node's text
		valueField:			'value',		// the name of the field that has the node's value
		idField:			'id',			// the name of the field that has anchors id value
		titleField:			'title',		// the name of the field that has the node's tip text
		isCheckedField:		'checked',		// the name of the field that has the node's isChecked state
		hasChildrenField:	'hasChildren',	// the name of the field that has the node's hasChildren flag
		imageField:			'image',		// the name of the field that has the node's image if imageOpenField and imageClosedField are not defined
		imageOpenField:		'imageOpen',	// the name of the field that has the node's open image
		imageClosedField:	'imageClosed',	// the name of the field that has the node's closed image

		partner:			false,			// default partner element to send content to
		partnerMethod:		'xhr',			// default loadMethod when sending content to partner
		cssClass:			'mui-tree',			// the primary css tag
		showIcon:			true,
		showCheckBox:		false,			// true to show checkBoxes
		canSelect:			true,			// can the user select a node by clicking it
		value:				'',				// the currently selected node's value
		selectedNode:		null,			// the currently selected node
		depth:				2				// how deep to expand the nodes to

		//onNodeExpanded:	null			// event: called when node is expanded
		//onNodeChecked: 	null			// event: called when node's checkbox is checked
		//onNodeClicked:	null			// event: when a node is checked
		//onLoaded:		    null			// event: called when tree is done building itself
	},

	initialize: function(options){
		this.setOptions(options);
		options = this.options;
		this.el = {};

		// If tree has no ID, give it one.
		this.id = options.id = options.id || 'tree' + (++MUI.idCount);
		MUI.set(this.id, this);

		if (options.content){
			options.content.loadMethod = MUI.getDefaultJsonProvider(options.content.loadMethod);
			options.content.onLoaded = (function(element, options){
				this.options.nodes = MUI.Content.getRecords(options);
				this.draw();
			}).bind(this);
			MUI.Content.update(options.content);
		} else {
			// create sub items if available
			if (options.drawOnInit && options.nodes.length > 0) this.draw();
		}
	},

	draw: function(container){
		var o = this.options;
		if (!container) container = o.container;

		var isNew = false;
		var div = o.element ? o.element : $(o.id);
		var ul;
		if (!div){
			div = new Element('div', {'id': o.id, 'class': o.cssClass});
			isNew = true;
		} else ul = div.getElement('ul');
		if (!ul) ul = new Element('ul', {'class': o.cssClass}).inject(div.empty());
		else ul.empty();
		this.el.element = div;

		var nodes = o.nodes;
		if (o.nodes.length > 1){
			var li = new Element('li').inject(ul);
			ul = new Element('ul').inject(li);
		}
		nodes.each(function(node){
			this.buildNode(node, ul, 1);
		}, this);
		var first = ul.getFirst();
		if (first) first.addClass('first');
		var last = ul.getChildren().getLast();
		if (last) last.addClass('last');

		o.depth = 0;

		if (!isNew){
			this.fireEvent('loaded', [this]);
			return this;
		}

		var addToContainer = function(){
			if (o.clearContainer) container.empty();
			div.inject(container);
			this.fireEvent('loaded', [this]);
		}.bind(this);

		if (typeof(container) == 'element'){
			addToContainer();
			return this;
		} else window.addEvent('domready', function(){
			// determine parent container object
			if (typeof(container) == 'string'){
				container = $(container);
				var instance = MUI.get(container);
				if (instance){
					div.setStyle('overflow', 'auto');
					if (instance.el.content) container = instance.el.content;
				}
			}
			addToContainer();
		}.bind(this));

		return this;
	},

	selectValue: function(val, e, suppressEvent){
		var self = this;
		var o = self.options;
		var node = self.nodeFind(val);
		if (!node) return;

		if (!o.canSelect){
			if (o.showCheckBox){
				node._checkbox.checked = !node._checkbox.checked;
				self.onNodeCheck(node, e);
			} else if (!suppressEvent) this.fireEvent('nodeSelected', [node, self, e]);
			return;
		}

		if (node._element){
			if (o.selectedNode && o.selectedNode._element) o.selectedNode._element.getElement('a').removeClass('sel');
			o.selectedNode = node;
			node._element.getElement('a').addClass('sel');
		}
		o.value = val;
		if (!suppressEvent) this.fireEvent('nodeSelected', [node, self, e]);
	},

	updateNode: function(node){
		if (!node) return;

		var self = this;
		var o = self.options;
		var n = node;
		if (!node._element) n = self.nodeFind(MUI.getData(node, o.valueField));
		if (n){
			var el = n._element;
			if (el){
				self.buildNode(node, el.getParent());
				self.setLast(el.getParent());
			}
		}
	},

	buildNode: function(node, parent, depth){
		var o = this.options;
		if (!depth) depth = 1;

		var a, span, ul, li;
		var id = MUI.getData(node, o.idField);
		if (!id) id = 'tn' + (++MUI.idCount);

		if (node._element != null) li = node._element;
		if (!li) li = new Element('li', {'id': id + '_li'});
		else li.empty();

		if (parent){
			if (parent._ul) li.inject(parent._ul);
			else li.inject(parent);
		}

		var value = MUI.getData(node, o.valueField);
		var text = MUI.getData(node, o.textField);
		if (o.showCheckBox) node._checkbox = new Element('INPUT', {'type': 'checkbox', 'value': value, 'id': id + '_cb'}).inject(li);
		a = node._a = new Element('a', {'id': id}).inject(li);
		if (node.target) a.setAttribute('target', node.target); 									// add anchor target
		span = node._span = new Element('span', {'text': text, 'id': id + '_tle'}).inject(a);		// add node text
		if (o.showIcon) node._icon = new Element('span', {'class': 'mui-treeIcon'}).inject(a, 'top');	// add node image

		node._element = li;
		var title = MUI.getData(node, o.titleField);
		if (title) a.title = title;

		var url = node.url;
		if (!url || node.registered){		// is node using registered function mapping
			url = '#';

			// determine partner settings
			var partner = node.partnerContent;
			if (url && partner){
				if (!partner.element) partner.element = o.partner;
				if (!partner.loadMethod) partner.loadMethod = o.partnerMethod;
				if (!partner.title) partner.title = node.title;
				if (!partner.title) partner.title = node.text;
				if (partner.element) a.addEvent('click', MUI.getPartnerLoader(this, partner));
			} else

			// if not using a partner then check for registered method calls
			if (node.registered && node.registered != '')
				a.addEvent('click', MUI.getRegistered(this, node.registered, [node]));
		}
// Something wrong with MUI.replacePaths
//		a.setAttribute('href', MUI.replacePaths(url));

		if (o.value == value){
			this.el.element.getElements('.sel').removeClass('sel');
			a.className = 'sel';
			o.selectedNode = this;
		}

		if (node.nodes && node.nodes.length > 0){
			if (!ul) ul = new Element('ul').inject(li);
			if (!node.isExpanded && o.depth <= depth){
				ul.style.display = 'none';
				node.isExpanded = false;
			} else node.isExpanded = true;
			node._ul = ul;

			for (var i = 0; i < node.nodes.length; i++){
				this.buildNode(node.nodes[i], node, depth + 1);
			}
			ul.childNodes[ul.childNodes.length - 1].addClass('last');
		} else li.addClass('nochild');
		if (node.isExpanded) li.set('class', 'O');

		// add image to node if necessary
		this._nodeSetImage(node);

		var hasChildren = MUI.getData(node, o.hasChildrenField);
		if (hasChildren && li.hasClass('nochild')) li.removeClass('nochild').addClass('C');

		// set events
		if (node._checkbox){
			var isChecked = MUI.getData(node, o.isCheckedField);
			if (isChecked != null) node._checkbox.checked = isChecked;
			node._checkbox.removeEvents('click').addEvent('click', MUI.getWrappedEvent(this, this.onNodeCheck, [node]));
		}
		li.addEvent('click', MUI.getWrappedEvent(this, this.onNodeExpand, [node]));
		a.addEvent('click', MUI.getWrappedEvent(this, this.onNodeClick, [node]));

		return this;
	},

	nodeFind: function(val, node){
		var self = this;
		var o = self.options;
		if (node != null){
			var value = MUI.getData(node, o.valueField);
			if (value && value + '' == val + '') return node;
		} else node = self;
		var nodes;
		if (node.options) nodes = node.options.nodes;
		if (nodes == null) nodes = node.nodes;
		if (nodes){
			var l = nodes.length;
			for (var i = 0; i < l; i++){
				var snode = this.nodeFind(val, nodes[i]);
				if (snode) return snode;
			}
		}
		return null;
	},

	nodeRefresh: function(node){
		if (!node._element) return;
		this.buildNode(node, node._element.getParent())
				.setLast(node._element.getParent());
	},

	nodeGetPath: function(node){
		var self = this;
		var o = self.options;
		var value = MUI.getData(node, o.valueField);

		if (!node._parent) return value;
		return this.getPath(node._parent) + '/' + value;
	},

	setLast: function(node){
		if (!node) return this;
		if (node.childNodes){
			var u = node;
			if (node.nodeName != 'UL') u = node.getElement('ul');
			if (u){
				var children = u.getChildren();
				if (children){
					children.removeClass('last');
					children.getLast().addClass('last');
				}
			}
		}
		return this;
	},

	_nodeSetImage: function(node){
		var o = this.options;
		var span = node._span;
		var def = MUI.getData(node, o.imageField);
		var open = MUI.getData(node, o.imageOpenField) || def;
		var closed = MUI.getData(node, o.imageClosedField) || def;

		span.removeClass(closed).removeClass(open);

		if (closed && !node.isExpanded){
			if (closed.indexOf('.') < 0) span.addClass(closed);
			else span.setStyles({'background': 'transparent url(' + closed + ') no-repeat scroll left top', 'paddingLeft': '20px'});
		}
		if (open && node.isExpanded){
			if (open.indexOf('.') < 0) span.addClass(open);
			else span.setStyles({'background': 'transparent url(' + open + ') no-repeat scroll left top', 'paddingLeft': '20px'});
		}
	},

	onNodeExpand: function(e, node){
		var itm = node._element;
		var mY = 0;
		var mX = 0;
		if (e){
			e.stop();
			var c = itm.getCoordinates();
			mY = e.client.y - c.top;
			mX = e.client.x - c.left;
		}

		if (mX < 20 && mY < 20){
			var ul = itm.getElement('ul');
			if (ul && node.isExpanded){
				ul.style.display = 'none';
				itm.removeClass('O').addClass('C');
				node.isExpanded = false;
				//return;
			} else if (ul && !node.isExpanded){
				ul.style.display = '';
				itm.removeClass('C').addClass('O');
				node.isExpanded = true;
				//if (node.nodes.length > 0) return;
			}
			this._nodeSetImage(node);
		}

		this.fireEvent('nodeExpanded', [e, node, this]);
	},

	onNodeClick: function(e, node){
		var o = this.options;
		e.stop();
		this.selectValue(MUI.getData(node, o.valueField), e);
		this.fireEvent('nodeClicked', [e, node, this]);
	},

	onNodeCheck: function(e, node){
		e.stopPropagation();
		this.fireEvent('nodeChecked', [e, node, this]);
	}

});
<|endoftext|>


<commit_before>/**
 * 气泡图控制器
 * 控制气泡图的显示方向
 *
 * Created by GUY on 2015/8/21.
 * @class
 */
BI.BubblesController = BI.inherit(BI.Controller, {
    _defaultConfig: function () {
        return BI.extend(BI.BubblesController.superclass._defaultConfig.apply(this, arguments), {});
    },

    _const: {
        bubbleHeight: 18
    },

    _init: function () {
        BI.BubblesController.superclass._init.apply(this, arguments);
        var self = this;
        this.bubblesManager = {};
        this.storeBubbles = {};
        BI.Resizers.add("bubbleController" + BI.uniqueId(), function () {
            BI.each(self.bubblesManager, function (name) {
                self.remove(name);
            });
            self.bubblesManager = {};
            self.storeBubbles = {};
        });
    },

    _createBubble: function (direct, text, level, height, fixed) {
        return BI.createWidget({
            type: fixed === false ? "bi.bubble_view" : "bi.bubble",
            text: text,
            level: level,
            height: height || 18,
            direction: direct
        });
    },

    _getOffsetLeft: function (name, context, offsetStyle) {
        var left = 0;
        if ("center" === offsetStyle) {
            left = context.element.offset().left + (context.element.bounds().width - this.get(name).element.bounds().width) / 2;
            if (left < 0) {
                left = 0;
            }
            return left;
        }
        if ("right" === offsetStyle) {
            left = context.element.offset().left + context.element.bounds().width - this.get(name).element.bounds().width;
            if (left < 0) {
                left = 0;
            }
            return left;
        }
        return context.element.offset().left;
    },

    _getOffsetTop: function (name, context, offsetStyle) {
        var top = 0;
        if ("center" === offsetStyle) {
            top = context.element.offset().top + (context.element.bounds().height - this.get(name).element.bounds().height) / 2;
            if (top < 0) {
                top = 0;
            }
            return top;
        } else if ("right" === offsetStyle) {
            top = context.element.offset().top + context.element.bounds().height - this.get(name).element.bounds().height;
            if (top < 0) {
                top = 0;
            }
            return top;
        }
        return context.element.offset().top;
    },

    _getLeftPosition: function (name, context, offsetStyle) {
        var position = BI.DOM.getLeftPosition(context, this.get(name));
        position.top = this._getOffsetTop(name, context, offsetStyle);
        return position;
    },

    _getBottomPosition: function (name, context, offsetStyle) {
        var position = BI.DOM.getBottomPosition(context, this.get(name));
        position.left = this._getOffsetLeft(name, context, offsetStyle);
        return position;
    },

    _getTopPosition: function (name, context, offsetStyle) {
        var position = BI.DOM.getTopPosition(context, this.get(name));
        position.left = this._getOffsetLeft(name, context, offsetStyle);
        return position;
    },

    _getRightPosition: function (name, context, offsetStyle) {
        var position = BI.DOM.getRightPosition(context, this.get(name));
        position.top = this._getOffsetTop(name, context, offsetStyle);
        return position;
    },

    /**
     *
     * @param name
     * @param text
     * @param context
     * @param offsetStyle center, left, right三种类型， 默认left
     * @returns {BI.BubblesController}
     */
    show: function (name, text, context, opt) {
        opt || (opt = {});
        var container = opt.container || context;
        var offsetStyle = opt.offsetStyle || "left";
        var level = opt.level || "error";
        var adjustYOffset = opt.adjustYOffset || 0;
        var adjustXOffset = opt.adjustXOffset || 0;
        var fixed = opt.fixed !== false;
        if (!this.storeBubbles[name]) {
            this.storeBubbles[name] = {};
        }
        if (!this.storeBubbles[name]["top"]) {
            this.storeBubbles[name]["top"] = this._createBubble("top", text, level, null, fixed);
        }
        BI.createWidget({
            type: "bi.absolute",
            element: container,
            items: [{
                el: this.storeBubbles[name]["top"]
            }]
        });
        this.set(name, this.storeBubbles[name]["top"]);

        // 如果是非固定位置（fixed）的bubble
        if (fixed === false) {
            var bubble = this.storeBubbles[name]["top"];
            var bounds = bubble.element.bounds();
            if (BI.DOM.isTopSpaceEnough(context, this.get(name), adjustYOffset)) {
                var top = -(bounds.height + adjustYOffset);
                switch (offsetStyle) {
                    case "center":
                        bubble.element.css({
                            left: (context.element.bounds().width - bounds.width) / 2 + adjustXOffset,
                            top: top
                        });
                        break;
                    case "right":
                        bubble.element.css({
                            right: adjustXOffset,
                            top: top
                        });
                        break;
                    default:
                        bubble.element.css({
                            left: adjustXOffset,
                            top: top
                        });
                        break;
                }
            } else {
                var bottom = -(bounds.height + adjustYOffset);
                switch (offsetStyle) {
                    case "center":
                        bubble.element.css({
                            left: (context.element.bounds().width - bounds.width) / 2 + adjustXOffset,
                            bottom: bottom
                        });
                        break;
                    case "right":
                        bubble.element.css({
                            right: adjustXOffset,
                            bottom: bottom
                        });
                        break;
                    default:
                        bubble.element.css({
                            left: adjustXOffset,
                            bottom: bottom
                        });
                        break;
                }
            }
            return this;
        }
        var position = this._getTopPosition(name, context, offsetStyle);
        this.get(name).element.css({left: position.left + adjustXOffset, top: position.top - adjustYOffset});
        if (!BI.DOM.isTopSpaceEnough(context, this.get(name), adjustYOffset)) {
            this.get(name).invisible();
            if (!this.storeBubbles[name]["left"]) {
                this.storeBubbles[name]["left"] = this._createBubble("left", text, level, 30, fixed);
            }
            BI.createWidget({
                type: "bi.absolute",
                element: container,
                items: [{
                    el: this.storeBubbles[name]["left"]
                }]
            });
            this.set(name, this.storeBubbles[name]["left"]);
            var position = this._getLeftPosition(name, context, offsetStyle);
            this.get(name).element.css({left: position.left - adjustXOffset, top: position.top - adjustYOffset});
            if (!BI.DOM.isLeftSpaceEnough(context, this.get(name), adjustXOffset)) {
                this.get(name).invisible();
                if (!this.storeBubbles[name]["right"]) {
                    this.storeBubbles[name]["right"] = this._createBubble("right", text, level, 30, fixed);
                }
                BI.createWidget({
                    type: "bi.absolute",
                    element: container,
                    items: [{
                        el: this.storeBubbles[name]["right"]
                    }]
                });
                this.set(name, this.storeBubbles[name]["right"]);
                var position = this._getRightPosition(name, context, offsetStyle);
                this.get(name).element.css({left: position.left + adjustXOffset, top: position.top - adjustYOffset});
                if (!BI.DOM.isRightSpaceEnough(context, this.get(name), adjustXOffset)) {
                    this.get(name).invisible();
                    if (!this.storeBubbles[name]["bottom"]) {
                        this.storeBubbles[name]["bottom"] = this._createBubble("bottom", text, level, null, fixed);
                    }
                    BI.createWidget({
                        type: "bi.absolute",
                        element: container,
                        items: [{
                            el: this.storeBubbles[name]["bottom"]
                        }]
                    });
                    this.set(name, this.storeBubbles[name]["bottom"]);
                    var position = this._getBottomPosition(name, context, offsetStyle);
                    this.get(name).element.css({
                        left: position.left + adjustXOffset,
                        top: position.top + adjustYOffset
                    });
                }
            }
        }
        return this;
    },

    hide: function (name) {
        if (!this.has(name)) {
            return this;
        }
        this.get(name).invisible();
        return this;
    },

    add: function (name, bubble) {
        if (this.has(name)) {
            return this;
        }
        this.set(name, bubble);
        return this;
    },

    get: function (name) {
        return this.bubblesManager[name];
    },

    set: function (name, bubble) {
        this.bubblesManager[name] = bubble;
    },

    has: function (name) {
        return this.bubblesManager[name] != null;
    },

    remove: function (name) {
        if (!this.has(name)) {
            return this;
        }
        BI.each(this.storeBubbles[name], function (dir, bubble) {
            bubble.destroy();
        });
        delete this.storeBubbles[name];
        delete this.bubblesManager[name];
        return this;
    }
});
<commit_msg>Pull request #1486: 无JIRA任务 bubble位置顺序，上、下、右、左<commit_after>/**
 * 气泡图控制器
 * 控制气泡图的显示方向
 *
 * Created by GUY on 2015/8/21.
 * @class
 */
BI.BubblesController = BI.inherit(BI.Controller, {
    _defaultConfig: function () {
        return BI.extend(BI.BubblesController.superclass._defaultConfig.apply(this, arguments), {});
    },

    _const: {
        bubbleHeight: 18
    },

    _init: function () {
        BI.BubblesController.superclass._init.apply(this, arguments);
        var self = this;
        this.bubblesManager = {};
        this.storeBubbles = {};
        BI.Resizers.add("bubbleController" + BI.uniqueId(), function () {
            BI.each(self.bubblesManager, function (name) {
                self.remove(name);
            });
            self.bubblesManager = {};
            self.storeBubbles = {};
        });
    },

    _createBubble: function (direct, text, level, height, fixed) {
        return BI.createWidget({
            type: fixed === false ? "bi.bubble_view" : "bi.bubble",
            text: text,
            level: level,
            height: height || 18,
            direction: direct
        });
    },

    _getOffsetLeft: function (name, context, offsetStyle) {
        var left = 0;
        if ("center" === offsetStyle) {
            left = context.element.offset().left + (context.element.bounds().width - this.get(name).element.bounds().width) / 2;
            if (left < 0) {
                left = 0;
            }
            return left;
        }
        if ("right" === offsetStyle) {
            left = context.element.offset().left + context.element.bounds().width - this.get(name).element.bounds().width;
            if (left < 0) {
                left = 0;
            }
            return left;
        }
        return context.element.offset().left;
    },

    _getOffsetTop: function (name, context, offsetStyle) {
        var top = 0;
        if ("center" === offsetStyle) {
            top = context.element.offset().top + (context.element.bounds().height - this.get(name).element.bounds().height) / 2;
            if (top < 0) {
                top = 0;
            }
            return top;
        } else if ("right" === offsetStyle) {
            top = context.element.offset().top + context.element.bounds().height - this.get(name).element.bounds().height;
            if (top < 0) {
                top = 0;
            }
            return top;
        }
        return context.element.offset().top;
    },

    _getLeftPosition: function (name, context, offsetStyle) {
        var position = BI.DOM.getLeftPosition(context, this.get(name));
        position.top = this._getOffsetTop(name, context, offsetStyle);
        return position;
    },

    _getBottomPosition: function (name, context, offsetStyle) {
        var position = BI.DOM.getBottomPosition(context, this.get(name));
        position.left = this._getOffsetLeft(name, context, offsetStyle);
        return position;
    },

    _getTopPosition: function (name, context, offsetStyle) {
        var position = BI.DOM.getTopPosition(context, this.get(name));
        position.left = this._getOffsetLeft(name, context, offsetStyle);
        return position;
    },

    _getRightPosition: function (name, context, offsetStyle) {
        var position = BI.DOM.getRightPosition(context, this.get(name));
        position.top = this._getOffsetTop(name, context, offsetStyle);
        return position;
    },

    /**
     *
     * @param name
     * @param text
     * @param context
     * @param offsetStyle center, left, right三种类型， 默认left
     * @returns {BI.BubblesController}
     */
    show: function (name, text, context, opt) {
        opt || (opt = {});
        var container = opt.container || context;
        var offsetStyle = opt.offsetStyle || "left";
        var level = opt.level || "error";
        var adjustYOffset = opt.adjustYOffset || 0;
        var adjustXOffset = opt.adjustXOffset || 0;
        var fixed = opt.fixed !== false;
        if (!this.storeBubbles[name]) {
            this.storeBubbles[name] = {};
        }
        if (!this.storeBubbles[name]["top"]) {
            this.storeBubbles[name]["top"] = this._createBubble("top", text, level, null, fixed);
        }
        BI.createWidget({
            type: "bi.absolute",
            element: container,
            items: [{
                el: this.storeBubbles[name]["top"]
            }]
        });
        this.set(name, this.storeBubbles[name]["top"]);

        // 如果是非固定位置（fixed）的bubble
        if (fixed === false) {
            var bubble = this.storeBubbles[name]["top"];
            var bounds = bubble.element.bounds();
            if (BI.DOM.isTopSpaceEnough(context, this.get(name), adjustYOffset)) {
                var top = -(bounds.height + adjustYOffset);
                switch (offsetStyle) {
                    case "center":
                        bubble.element.css({
                            left: (context.element.bounds().width - bounds.width) / 2 + adjustXOffset,
                            top: top
                        });
                        break;
                    case "right":
                        bubble.element.css({
                            right: adjustXOffset,
                            top: top
                        });
                        break;
                    default:
                        bubble.element.css({
                            left: adjustXOffset,
                            top: top
                        });
                        break;
                }
            } else {
                var bottom = -(bounds.height + adjustYOffset);
                switch (offsetStyle) {
                    case "center":
                        bubble.element.css({
                            left: (context.element.bounds().width - bounds.width) / 2 + adjustXOffset,
                            bottom: bottom
                        });
                        break;
                    case "right":
                        bubble.element.css({
                            right: adjustXOffset,
                            bottom: bottom
                        });
                        break;
                    default:
                        bubble.element.css({
                            left: adjustXOffset,
                            bottom: bottom
                        });
                        break;
                }
            }
            return this;
        }
        var position = this._getTopPosition(name, context, offsetStyle);
        this.get(name).element.css({left: position.left + adjustXOffset, top: position.top - adjustYOffset});
        if (!BI.DOM.isTopSpaceEnough(context, this.get(name), adjustYOffset)) {
            this.get(name).invisible();
            if (!this.storeBubbles[name]["bottom"]) {
                this.storeBubbles[name]["bottom"] = this._createBubble("bottom", text, level);
            }
            BI.createWidget({
                type: "bi.absolute",
                element: container,
                items: [{
                    el: this.storeBubbles[name]["bottom"]
                }]
            });
            this.set(name, this.storeBubbles[name]["bottom"]);
            var position = this._getBottomPosition(name, context, offsetStyle);
            this.get(name).element.css({left: position.left + adjustXOffset, top: position.top + adjustYOffset});
            if (!BI.DOM.isBottomSpaceEnough(context, this.get(name), adjustYOffset)) {
                this.get(name).invisible();
                if (!this.storeBubbles[name]["right"]) {
                    this.storeBubbles[name]["right"] = this._createBubble("right", text, level);
                }
                BI.createWidget({
                    type: "bi.absolute",
                    element: container,
                    items: [{
                        el: this.storeBubbles[name]["right"]
                    }]
                });
                this.set(name, this.storeBubbles[name]["right"]);
                var position = this._getRightPosition(name, context, offsetStyle);
                this.get(name).element.css({left: position.left + adjustXOffset, top: position.top - adjustYOffset});
                if (!BI.DOM.isRightSpaceEnough(context, this.get(name), adjustXOffset)) {
                    this.get(name).invisible();
                    if (!this.storeBubbles[name]["left"]) {
                        this.storeBubbles[name]["left"] = this._createBubble("left", text, level, 30);
                    }
                    BI.createWidget({
                        type: "bi.absolute",
                        element: container,
                        items: [{
                            el: this.storeBubbles[name]["left"]
                        }]
                    });
                    this.set(name, this.storeBubbles[name]["left"]);
                    var position = this._getLeftPosition(name, context, offsetStyle);
                    this.get(name).element.css({
                        left: position.left - adjustXOffset,
                        top: position.top - adjustYOffset
                    });
                }
            }
        }
        return this;
    },

    hide: function (name) {
        if (!this.has(name)) {
            return this;
        }
        this.get(name).invisible();
        return this;
    },

    add: function (name, bubble) {
        if (this.has(name)) {
            return this;
        }
        this.set(name, bubble);
        return this;
    },

    get: function (name) {
        return this.bubblesManager[name];
    },

    set: function (name, bubble) {
        this.bubblesManager[name] = bubble;
    },

    has: function (name) {
        return this.bubblesManager[name] != null;
    },

    remove: function (name) {
        if (!this.has(name)) {
            return this;
        }
        BI.each(this.storeBubbles[name], function (dir, bubble) {
            bubble.destroy();
        });
        delete this.storeBubbles[name];
        delete this.bubblesManager[name];
        return this;
    }
});
<|endoftext|>


<commit_before>var chai = require('chai'),
	expect = chai.expect,
	assert = chai.assert,
	mocha = require('mocha'),
	Instagram = require('../instagram.js');

var consumer_key = process.env.INSTAGRAM_CONSUMER_KEY;

describe("Instagram Client", function () {
	var instagram;
	before(() => {
		instagram = new Instagram({
			'client_key': client_key
		});
	});

	describe("instanciating an instagram client", () => {
		it("should return an instance of Instagram", () => {
			expect(instagram).to.be.an.instanceOf(Instagram);
		});
	})

	describe("getting user id", () => {
		var user;
		before(() => {
			user = {
				username: "gjl_niu",
				id: "1577045279"
			};
		});

		it("should return a user id", (done) => {
			instagram.getUserId(user.username).then((id) => {
				assert.equal(id, user.id);
				done();
			})
		});
	});

	describe("get posts by user", () => {
		var user = {
			id: "1577045279"
		};
		var numOfPosts = 4;
		it("should get the users posts", (done) => {
			instagram.getUserPosts(user.id, numOfPosts).then((posts) => {
				assert.equal(posts.length, numOfPosts);
				done();
			});
		});
	});

	describe("get posts by tag", () => {
		var tag = "NIU";
		var numOfPosts = 5;
		it("should return posts that contain the hashtag", (done) => {
			instagram.getTagPosts(tag, numOfPosts).then((posts) => {
				assert.equal(posts.length, numOfPosts);
				posts.forEach((post) => {
					var found = post.tags.filter((t) => {
						return t.toLowerCase() == tag.toLowerCase();
					});
					assert(found.length >= 0);
				});
				done();
			});
		});
	});
});<commit_msg>fix test config<commit_after>var chai = require('chai'),
	expect = chai.expect,
	assert = chai.assert,
	mocha = require('mocha'),
	Instagram = require('../instagram.js');

var client_key = process.env.INSTAGRAM_CONSUMER_KEY;

describe("Instagram Client", function () {
	var instagram;
	before(() => {
		instagram = new Instagram({
			'client_key': client_key
		});
	});

	describe("instanciating an instagram client", () => {
		it("should return an instance of Instagram", () => {
			expect(instagram).to.be.an.instanceOf(Instagram);
		});
	})

	describe("getting user id", () => {
		var user;
		before(() => {
			user = {
				username: "gjl_niu",
				id: "1577045279"
			};
		});

		it("should return a user id", (done) => {
			instagram.getUserId(user.username).then((id) => {
				assert.equal(id, user.id);
				done();
			})
		});
	});

	describe("get posts by user", () => {
		var user = {
			id: "1577045279"
		};
		var numOfPosts = 4;
		it("should get the users posts", (done) => {
			instagram.getUserPosts(user.id, numOfPosts).then((posts) => {
				assert.equal(posts.length, numOfPosts);
				done();
			});
		});
	});

	describe("get posts by tag", () => {
		var tag = "NIU";
		var numOfPosts = 5;
		it("should return posts that contain the hashtag", (done) => {
			instagram.getTagPosts(tag, numOfPosts).then((posts) => {
				assert.equal(posts.length, numOfPosts);
				posts.forEach((post) => {
					var found = post.tags.filter((t) => {
						return t.toLowerCase() == tag.toLowerCase();
					});
					assert(found.length >= 0);
				});
				done();
			});
		});
	});
});<|endoftext|>


<commit_before>function TransactionGenerationController($scope, $modal, userService, walletTransactionService){

  $scope.prepareTransaction = function(txType, rawdata, from, $modalScope){
    var addressData = userService.getAddress(from);
    var privKey = new Bitcoin.ECKey.decodeEncryptedFormat(addressData.privkey, addressData.address); // Using address as temporary password
    var pubKey = privKey.getPubKeyHex();

    var data = rawdata instanceof Array ? rawdata : [rawdata];

    pushOrderedTransactions(data,0);

    function pushOrderedTransactions(transactions,index){
      var txdata = transactions[index];
      txdata['pubkey'] = pubKey;
      $scope.TxPromise = walletTransactionService.getUnsignedTransaction(txType,txdata);
      $scope.TxPromise.then(function(successData) {
        var successData = successData.data;
        if (successData.status != 200 && successData.status != "OK") { /* Backwards compatibility for mastercoin-tools send API */
          $modalScope.waiting = false;
          $modalScope.transactionError = true;
          $modalScope.error = 'Error preparing Property Issuance transaction: ' + successData.error; /* Backwards compatibility for mastercoin-tools send API */
        } else {
        var unsignedTransaction = successData.unsignedhex || successData.transaction; /* Backwards compatibility for mastercoin-tools send API */

          try {
            var bytes = Bitcoin.Util.hexToBytes(unsignedTransaction);
            var transaction = Bitcoin.Transaction.deserialize(bytes);
            var script = parseScript(successData.sourceScript);

            transaction.ins.forEach(function(input) {
              input.script = script;
            });

            //DEBUG console.log('before',transaction, Bitcoin.Util.bytesToHex(transaction.serialize()));
            var signedSuccess = transaction.signWithKey(privKey);

            var finalTransaction = Bitcoin.Util.bytesToHex(transaction.serialize());

            //Showing the user the transaction hash doesn't work right now
            //var transactionHash = Bitcoin.Util.bytesToHex(transaction.getHash().reverse());

            walletTransactionService.pushSignedTransaction(finalTransaction).then(function(successData) {
              var successData = successData.data;
              if (successData.pushed.match(/submitted|success/gi) != null) {
                if(index +1 == transactions.length){
                  $modalScope.waiting = false;
                  $modalScope.transactionSuccess = true;
                  $modalScope.url = 'http://blockchain.info/address/' + from + '?sort=0';
                } else {
                  pushOrderedTransactions(transactions,index+1);
                }
              } else {
                $modalScope.waiting = false;
                $modalScope.transactionError = true;
                $modalScope.error = successData.pushed; //Unspecified error, show user
              }
            }, function(errorData) {
              $modalScope.waiting = false;
              $modalScope.transactionError = true;
              if (errorData.message)
                $modalScope.error = 'Server error: ' + errorData.message;
              else
                if (errorData.data)
                  $modalScope.error = 'Server error: ' + errorData.data;
                else
                  $modalScope.error = 'Unknown Server Error';
              console.error(errorData);
            });

            //DEBUG console.log(addressData, privKey, bytes, transaction, script, signedSuccess, finalTransaction );
            function parseScript(script) {
              var newScript = new Bitcoin.Script();
              var s = script.split(" ");
              for (var i = 0; i < s.length; i++) {
                if (Bitcoin.Opcode.map.hasOwnProperty(s[i])) {
                  newScript.writeOp(Bitcoin.Opcode.map[s[i]]);
                } else {
                  newScript.writeBytes(Bitcoin.Util.hexToBytes(s[i]));
                }
              }
              return newScript;
            }
          } catch (e) {
            $modalScope.sendError = true;
            if (e.message)
              $modalScope.error = 'Error sending transaction: ' + e.message;
            else
              if (e.data)
                $modalScope.error = 'Error sending transaction: ' + e.data;
              else
                $modalScope.error = 'Unknown error sending transaction';
            console.error(e);
          }
        }
      }, function(errorData) {
        $modalScope.sendError = true;
        if (errorData.message)
          $modalScope.error = 'Server error: ' + errorData.message;
        else
          if (errorData.data)
            $modalScope.error = 'Server error: ' + errorData.data;
          else
            $modalScope.error = 'Unknown Server Error';
        console.error(errorData);
      });
    };
  };

  $scope.validateForm = function() {

    var error = $scope.validateTransactionData();

    if (error.length < 8) {
      $scope.$parent.showErrors = false;
      // open modal
      var modalInstance = $modal.open({
        templateUrl: $scope.modalTemplateUrl,
        controller: function($scope, $modalInstance, data, prepareTransaction, setModalScope, convertSatoshiToDisplayedValue, getDisplayedAbbreviation) {
          setModalScope($scope);

          $scope.ok = function() {
            $scope.clicked = true;
            $scope.waiting = true;
            prepareTransaction(data.transactionType, data.transactionData, data.from, $scope);
          };

          $scope.cancel = function () {
            $modalInstance.dismiss('cancel');
          };
        },
        resolve: {
          data: function() {
            return $scope.generateData();
          },
          prepareTransaction: function() {
              return $scope.prepareTransaction;
          },
          setModalScope: function(){
            return $scope.setModalScope;
          },
          convertSatoshiToDisplayedValue: function() {
            return $scope.convertSatoshiToDisplayedValue;
          },
          getDisplayedAbbreviation: function() {
            return $scope.getDisplayedAbbreviation;
          }
        }
      });
    } else {
      error += 'and try again.';
      $scope.error = error;
      $scope.$parent.showErrors = true;
    }
  };
};<commit_msg>Generalize error text.<commit_after>function TransactionGenerationController($scope, $modal, userService, walletTransactionService){

  $scope.prepareTransaction = function(txType, rawdata, from, $modalScope){
    var addressData = userService.getAddress(from);
    var privKey = new Bitcoin.ECKey.decodeEncryptedFormat(addressData.privkey, addressData.address); // Using address as temporary password
    var pubKey = privKey.getPubKeyHex();

    var data = rawdata instanceof Array ? rawdata : [rawdata];

    pushOrderedTransactions(data,0);

    function pushOrderedTransactions(transactions,index){
      var txdata = transactions[index];
      txdata['pubkey'] = pubKey;
      $scope.TxPromise = walletTransactionService.getUnsignedTransaction(txType,txdata);
      $scope.TxPromise.then(function(successData) {
        var successData = successData.data;
        if (successData.status != 200 && successData.status != "OK") { /* Backwards compatibility for mastercoin-tools send API */
          $modalScope.waiting = false;
          $modalScope.transactionError = true;
          $modalScope.error = 'Error preparing transaction: ' + successData.error; /* Backwards compatibility for mastercoin-tools send API */
        } else {
        var unsignedTransaction = successData.unsignedhex || successData.transaction; /* Backwards compatibility for mastercoin-tools send API */

          try {
            var bytes = Bitcoin.Util.hexToBytes(unsignedTransaction);
            var transaction = Bitcoin.Transaction.deserialize(bytes);
            var script = parseScript(successData.sourceScript);

            transaction.ins.forEach(function(input) {
              input.script = script;
            });

            //DEBUG console.log('before',transaction, Bitcoin.Util.bytesToHex(transaction.serialize()));
            var signedSuccess = transaction.signWithKey(privKey);

            var finalTransaction = Bitcoin.Util.bytesToHex(transaction.serialize());

            //Showing the user the transaction hash doesn't work right now
            //var transactionHash = Bitcoin.Util.bytesToHex(transaction.getHash().reverse());

            walletTransactionService.pushSignedTransaction(finalTransaction).then(function(successData) {
              var successData = successData.data;
              if (successData.pushed.match(/submitted|success/gi) != null) {
                if(index +1 == transactions.length){
                  $modalScope.waiting = false;
                  $modalScope.transactionSuccess = true;
                  $modalScope.url = 'http://blockchain.info/address/' + from + '?sort=0';
                } else {
                  pushOrderedTransactions(transactions,index+1);
                }
              } else {
                $modalScope.waiting = false;
                $modalScope.transactionError = true;
                $modalScope.error = successData.pushed; //Unspecified error, show user
              }
            }, function(errorData) {
              $modalScope.waiting = false;
              $modalScope.transactionError = true;
              if (errorData.message)
                $modalScope.error = 'Server error: ' + errorData.message;
              else
                if (errorData.data)
                  $modalScope.error = 'Server error: ' + errorData.data;
                else
                  $modalScope.error = 'Unknown Server Error';
              console.error(errorData);
            });

            //DEBUG console.log(addressData, privKey, bytes, transaction, script, signedSuccess, finalTransaction );
            function parseScript(script) {
              var newScript = new Bitcoin.Script();
              var s = script.split(" ");
              for (var i = 0; i < s.length; i++) {
                if (Bitcoin.Opcode.map.hasOwnProperty(s[i])) {
                  newScript.writeOp(Bitcoin.Opcode.map[s[i]]);
                } else {
                  newScript.writeBytes(Bitcoin.Util.hexToBytes(s[i]));
                }
              }
              return newScript;
            }
          } catch (e) {
            $modalScope.sendError = true;
            if (e.message)
              $modalScope.error = 'Error sending transaction: ' + e.message;
            else
              if (e.data)
                $modalScope.error = 'Error sending transaction: ' + e.data;
              else
                $modalScope.error = 'Unknown error sending transaction';
            console.error(e);
          }
        }
      }, function(errorData) {
        $modalScope.sendError = true;
        if (errorData.message)
          $modalScope.error = 'Server error: ' + errorData.message;
        else
          if (errorData.data)
            $modalScope.error = 'Server error: ' + errorData.data;
          else
            $modalScope.error = 'Unknown Server Error';
        console.error(errorData);
      });
    };
  };

  $scope.validateForm = function() {

    var error = $scope.validateTransactionData();

    if (error.length < 8) {
      $scope.$parent.showErrors = false;
      // open modal
      var modalInstance = $modal.open({
        templateUrl: $scope.modalTemplateUrl,
        controller: function($scope, $modalInstance, data, prepareTransaction, setModalScope, convertSatoshiToDisplayedValue, getDisplayedAbbreviation) {
          setModalScope($scope);

          $scope.ok = function() {
            $scope.clicked = true;
            $scope.waiting = true;
            prepareTransaction(data.transactionType, data.transactionData, data.from, $scope);
          };

          $scope.cancel = function () {
            $modalInstance.dismiss('cancel');
          };
        },
        resolve: {
          data: function() {
            return $scope.generateData();
          },
          prepareTransaction: function() {
              return $scope.prepareTransaction;
          },
          setModalScope: function(){
            return $scope.setModalScope;
          },
          convertSatoshiToDisplayedValue: function() {
            return $scope.convertSatoshiToDisplayedValue;
          },
          getDisplayedAbbreviation: function() {
            return $scope.getDisplayedAbbreviation;
          }
        }
      });
    } else {
      error += 'and try again.';
      $scope.error = error;
      $scope.$parent.showErrors = true;
    }
  };
};<|endoftext|>


<commit_before>const webpack = require('webpack')

module.exports = {
  entry: 'mocha!./test/bootstrap.js',
  output: {
    path: './test',
    filename: 'specs.js',
    publicPath: 'http://localhost:8080/'
  },
  devtool: 'source-map',
  module: {
    loaders: [{
      test: /\.js$/,
      exclude: /node_modules\/dist/,
      loader: 'babel-loader'
    }]
  },
  devServer: {
    contentBase: './test',
    port: 8080,
    noInfo: true,
	hot: true,
    inline: true
  },
  plugins: [
    new webpack.HotModuleReplacementPlugin()
  ]
}
<commit_msg>last webpack<commit_after>const webpack = require('webpack')

module.exports = {
  entry: 'mocha!./test/bootstrap.js',
  output: {
    path: './test',
    filename: 'specs.js',
    publicPath: 'http://localhost:8080/'
  },
//  devtool: 'source-map',
  module: {
    loaders: [{
      test: /\.js$/,
      exclude: /node_modules\/dist/,
      loader: 'babel-loader'
    }]
  },
  devServer: {
    contentBase: './test',
    port: 8080,
    noInfo: true,
	hot: true,
    inline: true
  },
  plugins: [
    new webpack.HotModuleReplacementPlugin()
  ]
}
<|endoftext|>


<commit_before>/**
 * Use PhantomJS to capture the report page
 *
 * @author    Feei <feei#feei.cn>
 * @homepage  https://github.com/wufeifei/cobra
 * @license   MIT, see LICENSE for more details.
 * @copyright Copyright (c) 2017 Feei. All rights reserved
 */
"use strict";
/**
 * http://phantomjs.org/api/webpage/
 *
 * Web page api
 */
var page = require('webpage').create();
/**
 * http://phantomjs.org/api/fs/
 *
 * file system api
 */
var fs = require('fs');
/**
 * http://phantomjs.org/api/system/
 *
 * system
 */
var system = require('system');

/**
 * filename generator helper
 * @param viewport
 * @param tt time type
 * @returns {string}
 */
function getFileName(viewport, tt) {
    var d = new Date();
    var date = [
        d.getUTCFullYear(),
        d.getUTCMonth() + 1,
        d.getUTCDate()
    ];
    var time = [
        d.getHours() <= 9 ? '0' + d.getHours() : d.getHours(),
        d.getMinutes() <= 9 ? '0' + d.getMinutes() : d.getMinutes(),
        d.getSeconds() <= 9 ? '0' + d.getSeconds() : d.getSeconds(),
        d.getMilliseconds()
    ];
    var resolution = viewport.width + "x" + viewport.height;
    return tt + '_' + date.join('-') + '_' + time.join('-') + "_" + resolution + '.png';
}

/**
 * Read the Cobra config
 * @type {string}
 */
if (system.args.length < 3 || system.args[0] in ['w', 'm', 'q']) {
    console.log('Usage: report.js <work_directory> <time_type: e.g. w(weekly)/m(monthly)/q(quarterly)>');
    phantom.exit(1);
}
var tt = system.args[2];
// change work directory
fs.changeWorkingDirectory(system.args[1])
console.log('PWD: ' + fs.workingDirectory)
var config_path = 'config';
// check file exists
if (!fs.exists(config_path)) {
    console.log('Critical: config not found!');
    phantom.exit(1);
}
// read config
var secret_key = null;
var cobra_domain = null;
var config = fs.read(config_path, 'utf8');
config.split(/\r?\n/).forEach(function (line) {
    if (line.indexOf('secret_key') !== -1) {
        secret_key = line.split('secret_key:')[1].trim();
    }
    if (line.indexOf('domain') !== -1) {
        cobra_domain = line.split('domain:')[1].trim();
    }
});
if (secret_key == null) {
    console.log('Critical: Secret key not assignment');
    phantom.exit(1);
}

/**
 * View Page size
 * @type {{width: number, height: number}}
 */
page.viewportSize = {width: 1024, height: 1000};

console.log('TimeType: ' + tt);
var domain = 'http://' + cobra_domain + '/admin/overview?tt=' + tt + '&capture=true&token=' + secret_key;
var file = 'reports/' + getFileName(page.viewportSize, tt);
/**
 * Capture
 */
page.open(domain, function (status) {
    if (status !== 'success') {
        console.log('Critical: Unable to load the address!');
        phantom.exit(1);
    } else {
        /**
         * Draw chart need time
         */
        window.setTimeout(function () {
            page.render(file);
            console.log('Success: ' + file)
            phantom.exit();
        }, 1000);
    }
});<commit_msg>update<commit_after>/**
 * Use PhantomJS to capture the report page
 *
 * @author    Feei <feei#feei.cn>
 * @homepage  https://github.com/wufeifei/cobra
 * @license   MIT, see LICENSE for more details.
 * @copyright Copyright (c) 2017 Feei. All rights reserved
 */
"use strict";
/**
 * http://phantomjs.org/api/webpage/
 *
 * Web page api
 */
var page = require('webpage').create();
/**
 * http://phantomjs.org/api/fs/
 *
 * file system api
 */
var fs = require('fs');
/**
 * http://phantomjs.org/api/system/
 *
 * system
 */
var system = require('system');

/**
 * filename generator helper
 * @param viewport
 * @param tt time type
 * @returns {string}
 */
function getFileName(viewport, tt) {
    var d = new Date();
    var date = [
        d.getUTCFullYear(),
        d.getUTCMonth() + 1,
        d.getUTCDate()
    ];
    var time = [
        d.getHours() <= 9 ? '0' + d.getHours() : d.getHours(),
        d.getMinutes() <= 9 ? '0' + d.getMinutes() : d.getMinutes(),
        d.getSeconds() <= 9 ? '0' + d.getSeconds() : d.getSeconds(),
        d.getMilliseconds()
    ];
    var resolution = viewport.width + "x" + viewport.height;
    return tt + '_' + date.join('-') + '_' + time.join('-') + "_" + resolution + '.png';
}

/**
 * Read the Cobra config
 * @type {string}
 */
if (system.args.length < 3 || system.args[0] in ['w', 'm', 'q']) {
    console.log('Usage: report.js <work_directory> <time_type: e.g. w(weekly)/m(monthly)/q(quarterly)>');
    phantom.exit(1);
}
var tt = system.args[2];
// change work directory
fs.changeWorkingDirectory(system.args[1]);
console.log('PWD: ' + fs.workingDirectory);
var config_path = 'config';
// check file exists
if (!fs.exists(config_path)) {
    console.log('Critical: config not found!');
    phantom.exit(1);
}
// read config
var secret_key = null;
var cobra_domain = null;
var config = fs.read(config_path, 'utf8');
config.split(/\r?\n/).forEach(function (line) {
    if (line.indexOf('secret_key') !== -1) {
        secret_key = line.split('secret_key:')[1].trim();
    }
    if (line.indexOf('domain') !== -1) {
        cobra_domain = line.split('domain:')[1].trim();
    }
});
if (secret_key == null) {
    console.log('Critical: Secret key not assignment');
    phantom.exit(1);
}

/**
 * View Page size
 * @type {{width: number, height: number}}
 */
page.viewportSize = {width: 1024, height: 1000};

console.log('TimeType: ' + tt);
var domain = 'http://' + cobra_domain + '/admin/overview?tt=' + tt + '&capture=true&token=' + secret_key;
var file = 'reports/' + getFileName(page.viewportSize, tt);
/**
 * Capture
 */
page.open(domain, function (status) {
    if (status !== 'success') {
        console.log('Critical: Unable to load the address!');
        phantom.exit(1);
    } else {
        /**
         * Draw chart need time
         */
        window.setTimeout(function () {
            page.render(file);
            console.log('Success: ' + file);
            phantom.exit();
        }, 1000);
    }
});<|endoftext|>


<commit_before>// String constants for the following keybindings

<commit_msg>Finish string tests<commit_after><|endoftext|>


<commit_before>var Heroku = require("heroku");
var GitAPI = require('github');
var colors = require("colors");

var heroToken = process.env.HEROKU_TOKEN;
var gitToken = process.env.GITHUB_TOKEN;
//Place token in place process.env.TOKEN or set environmental tokens

// MAP TO DESIRED JSON FILE
var heroRepoNames = require('./heroku_github_namemap.json');
/*Map heroku apps to github repos in the file above like so
{
  "Heroku-App-Name": "Github-Repo-Name",
  "HerokuApp2": "MatchingGitHubApp"
}
*/

// SET OPTIONS TO DESIRED OUPUT: ORG OR USER
// var options = {user: "Cjones90"};
//  {user: "username"}

var options = {org: "NAQ"};
//  {org: "orgName"}

///// NOTHING BELOW NEEDS TO BE CONFIGURED //////

var heroku = new Heroku.Heroku({key: heroToken});
var github = new GitAPI({  version: "3.0.0"  });

github.authenticate({
    type: "oauth",
    token: gitToken
});

String.prototype.padRight = function (len) {
  if(this.length < len) {
    return String(this + (Array(len - this.length + 1).join(' ')))
  }
  else {
    return String(this);
  }
}

///TODO implement error catching

function getGit (options, callback) {
  var gitRepos = [];
  if(options.user) {
    getRepos = github.repos.getFromUser;
  }
  else if (options.org) {
    getRepos = github.repos.getFromOrg;
  }
  else {
    console.log("Please be sure to enter the appropriate options");
    return;
  }
  getRepos(options, function (err, repos) {
    repos.forEach(function (repo) {
      github.repos.getBranches({user: repo.owner.login, repo: repo.name}, function (err, branches) {
        branches.forEach(function (branch) {
          if(branch.name === 'master') {
            gitRepos[gitRepos.length] = {name: repo.name, commit: branch.commit.sha.slice(0,7), branchCount: branches.length-1}
          }
        })
        if(gitRepos.length === repos.length) {
          callback(null, gitRepos)
        }
      })
    })
  })
}

// TODO do get_release and get_app at same time, pushing into array if doesnt exist
// or mapping either .commit or .dyno if it doesnt exist, once both functions complete
// call callback
function getHeroku(callback) {
  var herokuRepos = [];
  heroku.get_apps(function (err, apps) {
    for(var i in apps) {
      (function (i) {
        heroku.get_releases(apps[i].name, function (err, releaseRes) {
          heroku.get_app(apps[i].name, function (err, appRes) {
            herokuRepos[herokuRepos.length] = {name: apps[i].name, commit: releaseRes[releaseRes.length-1].commit, dynos: appRes.dynos}
            if(herokuRepos.length === apps.length) {
              callback(null, herokuRepos);
            }
          })
        })
      })(i);
    }
  })
}

function getRepos(userFlag, git, heroku, cb) {
  var REPO = {
    gitArr: [],
    heroArr: []
  }
  git(userFlag, function (err, gitRepos) {
    gitRepos.forEach(function (repo) {
      REPO.gitArr[REPO.gitArr.length] = repo;
      if(REPO.gitArr.length === gitRepos.length) {
          cb(REPO);
      }
    })
  })

  heroku(function (err, herokuRepos) {
    herokuRepos.forEach(function (repo) {
      REPO.heroArr[REPO.heroArr.length] = repo;
      if(REPO.heroArr.length === herokuRepos.length) {
        cb(REPO);
      }
    });
  });

}

function padRepoLength(repos) {
  var padRepo = {
    MAX_LENGTH: 0,
    str: ''
  }
  for(p in repos) {
    if(repos[p].length > padRepo.MAX_LENGTH) {
      padRepo.MAX_LENGTH = repos[p].length;
    }
  }
  for(var i = 0; i < (padRepo.MAX_LENGTH/2)-2; i++) {
    padRepo.str += "-";
  }
  padRepo.str += 'Repo'
  for(var j = 0; j < (padRepo.MAX_LENGTH/2)-2; j++) {
    padRepo.str += "-";
  }
  return padRepo;
}

////////////^^^ FUNCTIONS//////// CALLS

getRepos(options, getGit, getHeroku, function (repos) {
  //Result contains all repos from git/heroku as an object in the form of:
  //  repos = {gitArr: [{}, {} ...], heroArr: [{}, {} ...]}
  //Git array = [{name: "RepoName", commit: "7 dig Sha Number"}, {}, {} ...]
  //Heroku array = [{name: "RepoName", commit: "7 dig Sha Number"}, {}, {} ...]
  if(repos.gitArr.length && repos.heroArr.length) {
    var maxRepo = padRepoLength(heroRepoNames);
    console.log(); //// Buffer
    console.log(maxRepo.str+" ||  ---- Git ---  ||  -- Heroku --  || -- Dynos --");
    repos.gitArr.forEach(function (gitRepo) {
      repos.heroArr.forEach(function (heroRepo) {
        if(gitRepo.name === heroRepoNames[heroRepo.name]) {
          var str = gitRepo.name.padRight(maxRepo.MAX_LENGTH)+" ||  Sha: "+ gitRepo.commit+"  ||  Sha: "+ heroRepo.commit+"  ||  Dynos: "+ heroRepo.dynos+ "  === ";
          var flag = gitRepo.commit === heroRepo.commit ? str.green+"Match".padRight(12).green : str.red+"OUT OF DATE".padRight(12).red;
          flag = (gitRepo.branchCount > 0) ? flag+String("== "+gitRepo.branchCount).yellow+" branch(es)".yellow : flag;
          console.log(flag);
        }
      })
    })
  }
});
<commit_msg>map git-to-heroku repos dynamically based on keys provided<commit_after>var Heroku = require("heroku");
var GitAPI = require('github');
var colors = require("colors");

var heroToken = process.env.HEROKU_TOKEN;
var gitToken = process.env.GITHUB_TOKEN;
//Place token in place process.env.TOKEN or set environmental tokens

// MAP TO DESIRED JSON FILE
var heroRepoNames = require('./heroku_github_namemap.json');
/*Map heroku apps to github repos in the file above like so
{
  "Heroku-App-Name": "Github-Repo-Name",
  "HerokuApp2": "MatchingGitHubApp"
}
*/

// SET OPTIONS TO DESIRED OUPUT: ORG OR USER
var options = {user: "Cjones90"};
//  {user: "username"}

// var options = {org: "NAQ"};
//  {org: "orgName"}

///// NOTHING BELOW NEEDS TO BE CONFIGURED //////

var heroku = new Heroku.Heroku({key: heroToken});
var github = new GitAPI({  version: "3.0.0"  });

github.authenticate({
    type: "oauth",
    token: gitToken
});

String.prototype.padRight = function (len) {
  if(this.length < len) {
    return String(this + (Array(len - this.length + 1).join(' ')))
  }
  else {
    return String(this);
  }
}

///TODO implement error catching

function getGit (options, callback) {
  var gitRepos = [];
  if(options.user) {
    getRepos = github.repos.getFromUser;
  }
  else if (options.org) {
    getRepos = github.repos.getFromOrg;
  }
  else {
    console.log("Please be sure to enter the appropriate options");
    return;
  }
  getRepos(options, function (err, repos) {
    repos.forEach(function (repo) {
      var commitArr = [];
      github.repos.getCommits({user: repo.owner.login, repo: repo.name}, function(err, results) {
        results.forEach(function(elem) {
          commitArr.push(elem.sha.slice(0,7));
        })
        github.repos.getBranches({user: repo.owner.login, repo: repo.name}, function (err, branches) {
          branches.forEach(function (branch) {
            if(branch.name === 'master') {
              gitRepos[gitRepos.length] = {name: repo.name, commit: branch.commit.sha.slice(0,7),
                branchCount: branches.length-1, commitArr: commitArr};
              if(gitRepos.length === repos.length) {
                callback(null, gitRepos)
              }
            }
          })
        })
      })
    })
  })
}

// TODO do get_release and get_app at same time, pushing into array if doesnt exist
// or mapping either .commit or .dyno if it doesnt exist, once both functions complete
// call callback
function getHeroku(callback) {
  var herokuRepos = [];
  heroku.get_apps(function (err, apps) {
    for(var i in apps) {
      (function (i) {
        heroku.get_releases(apps[i].name, function (err, releaseRes) {
          heroku.get_app(apps[i].name, function (err, appRes) {
            herokuRepos[herokuRepos.length] = {name: apps[i].name, commit: releaseRes[releaseRes.length-1].commit, dynos: appRes.dynos}
            if(herokuRepos.length === apps.length) {
              callback(null, herokuRepos);
            }
          })
        })
      })(i);
    }
  })
}

function getRepos(userFlag, git, heroku, cb) {
  var REPO = {
    gitArr: [],
    heroArr: []
  }
  git(userFlag, function (err, gitRepos) {
    gitRepos.forEach(function (repo) {
      REPO.gitArr[REPO.gitArr.length] = repo;
      if(REPO.gitArr.length === gitRepos.length) {
          cb(REPO);
      }
    })
  })

  heroku(function (err, herokuRepos) {
    herokuRepos.forEach(function (repo) {
      REPO.heroArr[REPO.heroArr.length] = repo;
      if(REPO.heroArr.length === herokuRepos.length) {
        cb(REPO);
      }
    });
  });

}

function padRepoLength(repos) {
  var padRepo = {
    MAX_LENGTH: 0,
    str: ''
  }
  for(p in repos) {
    if(repos[p].length > padRepo.MAX_LENGTH) {
      padRepo.MAX_LENGTH = repos[p].length;
    }
  }
  for(var i = 0; i < (padRepo.MAX_LENGTH/2)-2; i++) {
    padRepo.str += "-";
  }
  padRepo.str += 'Repo'
  for(var j = 0; j < (padRepo.MAX_LENGTH/2)-2; j++) {
    padRepo.str += "-";
  }
  return padRepo;
}

////////////^^^ FUNCTIONS//////// CALLS

getRepos(options, getGit, getHeroku, function (repos) {
  //Result contains all repos from git/heroku as an object in the form of:
  //repos = {gitArr: [{}, {} ...], heroArr: [{}, {} ...]}
  //gitArr = [{name: "RepoName", commit: "7 dig Sha Number"}, {}, {} ...]
  //heroArr = [{name: "RepoName", commit: "7 dig Sha Number"}, {}, {} ...]
  if(repos.gitArr.length && repos.heroArr.length) {
    var maxRepo = padRepoLength(heroRepoNames);
    console.log(); //// Buffer
    console.log(maxRepo.str+" ||  ---- Git ---  ||  -- Heroku --  || -- Dynos --");
    repos.gitArr.forEach(function (gitRepo) {
      var heroRepo = repos.heroArr.filter(function (elem) {
        return gitRepo.commitArr.some(function (elem2) {
          return elem2 === elem.commit;
        })
      })
      if(heroRepo.length) {
        var heroRepo = heroRepo[0];
        var str = gitRepo.name.padRight(maxRepo.MAX_LENGTH)+" ||  Sha: "+ gitRepo.commit+"  ||  Sha: "+ heroRepo.commit+"  ||  Dynos: "+ heroRepo.dynos+ "  === ";
        var flag = gitRepo.commit === heroRepo.commit ? str.green+"Match".padRight(12).green : str.red+"OUT OF DATE".padRight(12).red;
        flag = (gitRepo.branchCount > 0) ? flag+String("== "+gitRepo.branchCount).yellow+" branch(es)".yellow : flag;
        console.log(flag);
      }
    })
  }
});
<|endoftext|>


<commit_before>(function () {
  'use strict';

  var utils = require('../e2e/_utils'),
      CONSTANTS = require('../protractor.constants.js'),
      modelsRecipe = require('./_modelsRecipe'),
      protractor = require('protractor'),
      ptor = protractor.getInstance(),
      driver = ptor.driver;

  var case_to_accept;
  var grouped_benefits_case;
  var assign_button = element(by.name('assign-provider'));
  var accept_button = element(by.name('accept-case'));
  var close_button = element(by.name('provider-close-case'));
  var grouped_text = 'Are you or your partner directly or indirectly in receipt of Universal Credit, Income Support, Income-based Jobseeker\'s Allowance, Income-related Employment and Support Allowance or Guarantee Credit?';
  var specific_text = 'Do you or your partner receive any of the following benefits:';

  describe('providerCase', function () {
    describe('An operator', function () {
      beforeEach(utils.setUp);

      it('should create a specific benefits case as operator and assign (manually) to a provider', function () {
        modelsRecipe.Case.createSpecificBenefitsReadyToAssign().then(function (case_ref) {
          case_to_accept = case_ref;
          browser.get(CONSTANTS.callcentreBaseUrl + case_ref + '/assign/?as_of=2014-08-06T11:50');
          get_provider().then(function (provider) {
            if (provider !== 'Duncan Lewis') {
              utils.manuallySetProvider(1); // set to Duncan Lewis
            }
            do_assign();
            expect(browser.getLocationAbsUrl()).toBe(ptor.baseUrl + CONSTANTS.callcentreBaseUrl);
          });
        });
      });

      it('should create a grouped benefits case as operator and assign (manually) to a provider', function () {
        modelsRecipe.Case.createGroupedBenefitsReadyToAssign().then(function (case_ref) {
          grouped_benefits_case = case_ref;
          browser.get(CONSTANTS.callcentreBaseUrl + case_ref + '/assign/?as_of=2014-08-06T11:50');
          get_provider().then(function (provider) {
            if (provider !== 'Duncan Lewis') {
              utils.manuallySetProvider(1); // set to Duncan Lewis
            }
            do_assign();
            expect(browser.getLocationAbsUrl()).toBe(ptor.baseUrl + CONSTANTS.callcentreBaseUrl);
          });
        });
      });

      it('should logout', function () {
        this.after(function () {
          utils.logout();
        });
      });
    });

    describe('A provider', function () {
      beforeEach(utils.setUpAsProvider);

      it('should be able to accept a case', function () {
        browser.get(CONSTANTS.providerBaseUrl + case_to_accept + '/');

        expect(close_button.isPresent()).toBe(false);
        expect(accept_button.isPresent()).toBe(true);

        // click but cancel accept
        accept_button.click();

        // check can't accept anymore
        expect(accept_button.isPresent()).toBe(false);
        expect(close_button.isPresent()).toBe(true);
        expect(element(by.css('.NoticeContainer--fixed')).getInnerHtml()).toContain('Case accepted successfully');
      });

      it('should be able to close a case', function () {
        expect(close_button.isPresent()).toBe(true);

        // click but cancel accept
        close_button.click();
        browser.switchTo().alert().dismiss();

        expect(close_button.isPresent()).toBe(true);

        // click and accept case
        close_button.click();
        browser.switchTo().alert().accept();

        // check can't accept anymore
        expect(element(by.css('.NoticeContainer--fixed')).getInnerHtml()).toContain('Case ' + case_to_accept + ' closed successfully');
      });

      it('should be able to view legal help form with specific benefits', function () {
        browser.ignoreSynchronization = true;
        driver.get(ptor.baseUrl + 'provider/case/' + case_to_accept + '/legal_help_form/');

        var legal_help_form = driver.findElement(by.css('.page'));
        expect(legal_help_form.getText()).not.toContain(grouped_text);
        expect(legal_help_form.getText()).toContain(specific_text);

        var universalCredit = driver.findElement(by.name('universal_credit'));
        var incomeSupport = driver.findElement(by.name('income_support'));
        var jobSeekers = driver.findElement(by.name('job_seekers_allowance'));

        expect(universalCredit.getAttribute('value')).toBe('Yes');
        expect(incomeSupport.getAttribute('value')).toBe('No');
        expect(jobSeekers.getAttribute('value')).toBe('');
      });

      it('should be able to view legal help form with grouped benefits', function () {
        driver.get(ptor.baseUrl + 'provider/case/' + grouped_benefits_case + '/legal_help_form/');

        var legal_help_form = driver.findElement(by.css('.page'));
        expect(legal_help_form.getText()).toContain(grouped_text);
        expect(legal_help_form.getText()).not.toContain(specific_text);

        browser.ignoreSynchronization = false;
        browser.get(CONSTANTS.providerBaseUrl + grouped_benefits_case + '/');
      });

      it('should logout', function () {
        this.after(function () {
          utils.logout();
        });
      });
    });
  });

  // helpers
  function get_provider () {
    return element(by.css('.ContactBlock-heading')).getText();
  }

  function do_assign () {
    utils.scrollTo(assign_button);
    assign_button.click();

  }
})();
<commit_msg>Update provider case e2e tests to be more robust again<commit_after>(function () {
  'use strict';

  var utils = require('../e2e/_utils'),
      CONSTANTS = require('../protractor.constants.js'),
      modelsRecipe = require('./_modelsRecipe'),
      protractor = require('protractor'),
      ptor = protractor.getInstance(),
      driver = ptor.driver;

  var case_to_accept;
  var grouped_benefits_case;
  var assign_form = element(by.name('assign_provider_form'));
  var accept_button = element(by.name('accept-case'));
  var close_button = element(by.name('provider-close-case'));
  var grouped_text = 'Are you or your partner directly or indirectly in receipt of Universal Credit, Income Support, Income-based Jobseeker\'s Allowance, Income-related Employment and Support Allowance or Guarantee Credit?';
  var specific_text = 'Do you or your partner receive any of the following benefits:';

  describe('providerCase', function () {
    describe('An operator', function () {
      beforeEach(utils.setUp);

      it('should create a specific benefits case as operator and assign (manually) to a provider', function () {
        modelsRecipe.Case.createSpecificBenefitsReadyToAssign().then(function (case_ref) {
          case_to_accept = case_ref;
          browser.get(CONSTANTS.callcentreBaseUrl + case_ref + '/assign/?as_of=2014-08-06T11:50');
          get_provider().then(function (provider) {
            if (provider !== 'Duncan Lewis') {
              utils.manuallySetProvider(1); // set to Duncan Lewis
            }
            do_assign();
            expect(browser.getLocationAbsUrl()).toBe(ptor.baseUrl + CONSTANTS.callcentreBaseUrl);
          });
        });
      });

      it('should create a grouped benefits case as operator and assign (manually) to a provider', function () {
        modelsRecipe.Case.createGroupedBenefitsReadyToAssign().then(function (case_ref) {
          grouped_benefits_case = case_ref;
          browser.get(CONSTANTS.callcentreBaseUrl + case_ref + '/assign/?as_of=2014-08-06T11:50');
          get_provider().then(function (provider) {
            if (provider !== 'Duncan Lewis') {
              utils.manuallySetProvider(1); // set to Duncan Lewis
            }
            do_assign();
            expect(browser.getLocationAbsUrl()).toBe(ptor.baseUrl + CONSTANTS.callcentreBaseUrl);
          });
        });
      });

      it('should logout', function () {
        this.after(function () {
          utils.logout();
        });
      });
    });

    describe('A provider', function () {
      beforeEach(utils.setUpAsProvider);

      it('should be able to accept a case', function () {
        browser.get(CONSTANTS.providerBaseUrl + case_to_accept + '/');

        expect(close_button.isPresent()).toBe(false);
        expect(accept_button.isPresent()).toBe(true);

        // click but cancel accept
        accept_button.click();

        // check can't accept anymore
        expect(accept_button.isPresent()).toBe(false);
        expect(close_button.isPresent()).toBe(true);
        expect(element(by.css('.NoticeContainer--fixed')).getInnerHtml()).toContain('Case accepted successfully');
      });

      it('should be able to close a case', function () {
        expect(close_button.isPresent()).toBe(true);

        // click but cancel accept
        close_button.click();
        browser.switchTo().alert().dismiss();

        expect(close_button.isPresent()).toBe(true);

        // click and accept case
        close_button.click();
        browser.switchTo().alert().accept();

        // check redirected
        expect(browser.getLocationAbsUrl()).not.toContain(case_to_accept);
      });

      it('should be able to view legal help form with specific benefits', function () {
        browser.ignoreSynchronization = true;
        driver.get(ptor.baseUrl + 'provider/case/' + case_to_accept + '/legal_help_form/');

        var legal_help_form = driver.findElement(by.css('.page'));
        expect(legal_help_form.getText()).not.toContain(grouped_text);
        expect(legal_help_form.getText()).toContain(specific_text);

        var universalCredit = driver.findElement(by.name('universal_credit'));
        var incomeSupport = driver.findElement(by.name('income_support'));
        var jobSeekers = driver.findElement(by.name('job_seekers_allowance'));

        expect(universalCredit.getAttribute('value')).toBe('Yes');
        expect(incomeSupport.getAttribute('value')).toBe('No');
        expect(jobSeekers.getAttribute('value')).toBe('');
      });

      it('should be able to view legal help form with grouped benefits', function () {
        driver.get(ptor.baseUrl + 'provider/case/' + grouped_benefits_case + '/legal_help_form/');

        var legal_help_form = driver.findElement(by.css('.page'));
        expect(legal_help_form.getText()).toContain(grouped_text);
        expect(legal_help_form.getText()).not.toContain(specific_text);

        browser.ignoreSynchronization = false;
        browser.get(CONSTANTS.providerBaseUrl + grouped_benefits_case + '/');
      });

      it('should logout', function () {
        this.after(function () {
          utils.logout();
        });
      });
    });
  });

  // helpers
  function get_provider () {
    return element(by.css('.ContactBlock-heading')).getText();
  }

  function do_assign () {
    assign_form.submit();
  }
})();
<|endoftext|>