Skip to content
This repository has been archived by the owner on May 12, 2021. It is now read-only.

Hooked up UI interactions for new inspector scale-up view #425

Merged
merged 1 commit into from Jul 9, 2014
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
6 changes: 4 additions & 2 deletions app/templates/scale-up.handlebars
Expand Up @@ -28,8 +28,10 @@
</div>
<div class="constraints">
Scale up with these constraints?
Default CPU, default Mem, default Arch.
<span class="edit link">Edit</span>
<span class="constraints-defaults">
Default CPU, default Mem, default Arch.
<span class="edit link">Edit</span>
</span>
</div>
<div class="edit-constraints">
<form>
Expand Down
86 changes: 85 additions & 1 deletion app/views/viewlets/scale-up.js
Expand Up @@ -22,11 +22,19 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
YUI.add('scale-up-view', function(Y) {

var ns = Y.namespace('juju.viewlets'),
utils = Y.namespace('juju.views.utils'),
templates = Y.namespace('juju.views').Templates;

ns.ScaleUp = Y.Base.create(name, Y.View, [], {
template: templates['scale-up'],
events: {},
events: {
'.add.button': { click: '_showScaleUp' },
'.placement .cancel.button': { click: '_hideScaleUp' },
'input[name="placement"]': { change: '_toggleConstraints' },
'.edit.link': { click: '_toggleEditConstraints' },
'.inspector-buttons .cancel': { click: '_hideScaleUp' },
'.inspector-buttons .confirm': { click: '_submitScaleUp' }
},

/**
Renders the views template into the container
Expand All @@ -38,12 +46,88 @@ YUI.add('scale-up-view', function(Y) {
var container = this.get('container');
container.append(this.template());
return container;
},

/**
Updates the state class on the viewlet templates container. See
scale-up.less for available classes.

@method updateStateClass
@param {object} className The class name to set on the container via the
utils setStateClass method.
*/
updateStateClass: function(className) {
utils.setStateClass(
this.get('container').one('.view-container'),
className);
},

/**
Calls to set the class on the container to show the scale-up UI.

@method _showScaleUp
@param {Object} e The click event facade.
*/
_showScaleUp: function(e) {
e.preventDefault();
this.updateStateClass('per-machine');
},

/**
Calls to set the class on the container to hide the scale-up UI.

@method _hideScaleUp
@param {Object} e The click event facade.
*/
_hideScaleUp: function(e) {
e.preventDefault();
this.updateStateClass('default');
},

/**
Calls to set the class on the container to show the constraints
information based on which radio button is selected in the UI.

@method _toggleConstraints
@param {Object} e The click event facade.
*/
_toggleConstraints: function(e) {
var state;
if (e.currentTarget.get('id') === 'manually-place') {
state = 'manual';
} else {
state = 'per-machine';
}
this.updateStateClass(state);
},

/**
Calls to set the class on the container to show the edit-constraints
inputs.

@method _toggleEditConstraints
@param {Object} e The click event facade.
*/
_toggleEditConstraints: function(e) {
e.preventDefault();
this.updateStateClass('constraints');
},

/**
handles submitting the new scale up information to Juju.

@method _submitScaleUp
@param {Object} e The click event facade.
*/
_submitScaleUp: function(e) {
e.preventDefault();
}
});

}, '0.0.1', {
requires: [
'node',
'juju-view-utils',
'juju-templates',
'viewlet-view-base'
]
Expand Down
6 changes: 6 additions & 0 deletions lib/views/inspector/scale-up.less
Expand Up @@ -5,6 +5,10 @@
border-top: 1px solid @inspector-divider-top;
border-bottom: 1px solid @inspector-divider-bottom;

/*
If you modify these state classes you will also need to modify the
classes set in scale-up.js
*/
&.state-default {
.add-units {
display: block;
Expand All @@ -13,6 +17,7 @@
&.state-per-machine {
.placement,
.constraints,
.constraints-defaults,
.inspector-buttons {
display: block;
}
Expand All @@ -33,6 +38,7 @@
.add-units,
.placement,
.constraints,
.constraints-defaults,
.edit-constraints,
.inspector-buttons {
display: none;
Expand Down
135 changes: 129 additions & 6 deletions test/test_scale_up_view.js
Expand Up @@ -20,12 +20,13 @@ with this program. If not, see <http://www.gnu.org/licenses/>.

describe('scale-up view', function() {

var Y, utils, view, View;
var container, utils, view, View, Y;

before(function(done) {
Y = YUI(GlobalConfig).use(
'scale-up-view',
'juju-tests-utils',
'node-event-simulate',
function() {
utils = Y.namespace('juju-tests').utils;
View = Y.namespace('juju.viewlets').ScaleUp;
Expand All @@ -34,20 +35,142 @@ describe('scale-up view', function() {
});

beforeEach(function() {
view = new View();
container = utils.makeContainer(this);
});

afterEach(function() {
view.destroy();
afterEach(function(done) {
if (view) {
view.destroy();
}
});

function instantiateView() {
view = new View({
container: container
});
return view;
}

function testEventBinding(options, context) {
var stub = utils.makeStubMethod(View.prototype, options.stubMethod);
context._cleanups.push(stub.reset);
instantiateView().render();
var button = container.one(options.buttonSelector);
// Open the scale-up view.
button.simulate('click');
assert.equal(stub.calledOnce(), true, options.stubMethod + ' not called');
}

function testSetStateClass(options, context) {
instantiateView().render();
var update = utils.makeStubMethod(view, 'updateStateClass');
context._cleanups.push(update.reset);
var prevent = utils.makeStubFunction();
var event = options.customEvent || { preventDefault: prevent };
view[options.method](event);
if (typeof event.preventDefault === 'function') {
assert.equal(prevent.calledOnce(), true);
}
assert.equal(update.calledOnce(), true);
assert.equal(update.lastArguments()[0], options.className);
}

it('can be instantiated', function() {
instantiateView();
assert.equal(view instanceof View, true);
});

it('can render its template to its container', function() {
var container = view.render();
assert.deepEqual(container, view.get('container'));
instantiateView().render();
assert.isNotNull(view.get('container').one('.view-container'));
});

it('clicking the + calls to open the scale up options', function() {
testEventBinding({
stubMethod: '_showScaleUp',
buttonSelector: '.add.button'
}, this);
});

it('clicking the x calls to close the scale up options', function() {
testEventBinding({
stubMethod: '_hideScaleUp',
buttonSelector: '.placement .cancel.button'
}, this);
});

it('changing the radio button calls to change constraints visibility',
function() {
testEventBinding({
stubMethod: '_toggleConstraints',
buttonSelector: 'input#manually-place'
}, this);
});

it('clicking the constraints Edit calls to show the constraints inputs',
function() {
testEventBinding({
stubMethod: '_toggleEditConstraints',
buttonSelector: '.edit.link'
}, this);
});

it('clicking the cancel button calls to close the scale-up UI', function() {
testEventBinding({
stubMethod: '_hideScaleUp',
buttonSelector: '.inspector-buttons .cancel'
}, this);
});

it('clicking the confirm button calls to submit scale-up data', function() {
testEventBinding({
stubMethod: '_submitScaleUp',
buttonSelector: '.inspector-buttons .confirm'
}, this);
});

it('_showScaleUp calls to set the proper state class', function() {
testSetStateClass({
method: '_showScaleUp',
className: 'per-machine'
}, this);
});

it('_hideScaleUp calls to the proper state class', function() {
testSetStateClass({
method: '_hideScaleUp',
className: 'default'
}, this);
});

it('_toggleEditConstraints calls to set the proper state class', function() {
testSetStateClass({
method: '_toggleEditConstraints',
className: 'constraints'
}, this);
});

it('_toggleConstraints sets the proper state data(manual place)', function() {
testSetStateClass({
method: '_toggleConstraints',
customEvent: {
currentTarget: {
get: function() { return 'manually-place'; }
}
},
className: 'manual'
}, this);
});

it('_toggleConstraints sets the proper state data(auto place)', function() {
testSetStateClass({
method: '_toggleConstraints',
customEvent: {
currentTarget: {
get: function() { return 'unit-per-machine'; }
}
},
className: 'per-machine'
}, this);
});
});