Merge "Add status field to settings view"

This commit is contained in:
Wyatt Allen
2017-02-07 23:12:48 +00:00
committed by Gerrit Code Review
6 changed files with 103 additions and 27 deletions

View File

@@ -138,13 +138,13 @@
return loading || !this._changes || this._changes.length < changesPerPage; return loading || !this._changes || this._changes.length < changesPerPage;
}, },
_handleNextPage() { _handleNextPage: function() {
if (this._hideNextArrow(this._offset)) { return; } if (this._hideNextArrow(this._offset)) { return; }
page.show(this._computeNavLink( page.show(this._computeNavLink(
this._query, this._offset, 1, this._changesPerPage)); this._query, this._offset, 1, this._changesPerPage));
}, },
_handlePreviousPage() { _handlePreviousPage: function() {
if (this._hidePrevArrow(this._offset)) { return; } if (this._hidePrevArrow(this._offset)) { return; }
page.show(this._computeNavLink( page.show(this._computeNavLink(
this._query, this._offset, -1, this._changesPerPage)); this._query, this._offset, -1, this._changesPerPage));

View File

@@ -54,11 +54,23 @@ limitations under the License.
class="value"> class="value">
<input <input
is="iron-input" is="iron-input"
id="nameInput"
disabled="[[_saving]]" disabled="[[_saving]]"
on-keydown="_handleNameKeydown" on-keydown="_handleKeydown"
bind-value="{{_account.name}}"> bind-value="{{_account.name}}">
</span> </span>
</section> </section>
<section>
<span class="title">Status</span>
<span class="value">
<input
is="iron-input"
id="statusInput"
disabled="[[_saving]]"
on-keydown="_handleKeydown"
bind-value="{{_account.status}}">
</span>
</section>
</div> </div>
<gr-rest-api-interface id="restAPI"></gr-rest-api-interface> <gr-rest-api-interface id="restAPI"></gr-rest-api-interface>
</template> </template>

View File

@@ -48,7 +48,7 @@
}, },
observers: [ observers: [
'_nameChanged(_account.name)', '_accountChanged(_account.*)',
], ],
loadData: function() { loadData: function() {
@@ -75,7 +75,10 @@
} }
this._saving = true; this._saving = true;
return this.$.restAPI.setAccountName(this._account.name).then(function() { return Promise.all([
this.$.restAPI.setAccountName(this._account.name),
this.$.restAPI.setAccountStatus(this._account.status),
]).then(function() {
this.hasUnsavedChanges = false; this.hasUnsavedChanges = false;
this._saving = false; this._saving = false;
this.fire('account-detail-update'); this.fire('account-detail-update');
@@ -86,12 +89,12 @@
return config.auth.editable_account_fields.indexOf('FULL_NAME') !== -1; return config.auth.editable_account_fields.indexOf('FULL_NAME') !== -1;
}, },
_nameChanged: function() { _accountChanged: function() {
if (this._loading) { return; } if (this._loading) { return; }
this.hasUnsavedChanges = true; this.hasUnsavedChanges = true;
}, },
_handleNameKeydown: function(e) { _handleKeydown: function(e) {
if (e.keyCode === 13) { // Enter if (e.keyCode === 13) { // Enter
e.stopPropagation(); e.stopPropagation();
this.save(); this.save();

View File

@@ -35,7 +35,7 @@ limitations under the License.
var element; var element;
var account; var account;
var config; var config;
var nameInput; var sandbox;
function valueOf(title) { function valueOf(title) {
var sections = Polymer.dom(element.root).querySelectorAll('section'); var sections = Polymer.dom(element.root).querySelectorAll('section');
@@ -49,6 +49,7 @@ limitations under the License.
} }
setup(function(done) { setup(function(done) {
sandbox = sinon.sandbox.create();
account = { account = {
_account_id: 123, _account_id: 123,
name: 'user name', name: 'user name',
@@ -66,13 +67,14 @@ limitations under the License.
}, },
}); });
element = fixture('basic'); element = fixture('basic');
nameInput = element.$.nameSection.querySelector('.value input');
// Allow the element to render. // Allow the element to render.
element.loadData().then(function() { flush(done); }); element.loadData().then(function() { flush(done); });
}); });
teardown(function() {
sandbox.restore();
});
test('basic account info render', function() { test('basic account info render', function() {
assert.isFalse(element._loading); assert.isFalse(element._loading);
@@ -102,34 +104,62 @@ limitations under the License.
assert.isTrue(element.mutable); assert.isTrue(element.mutable);
assert.isTrue(displaySpan.hasAttribute('hidden')); assert.isTrue(displaySpan.hasAttribute('hidden'));
assert.equal(nameInput.bindValue, account.name); assert.equal(element.$.nameInput.bindValue, account.name);
assert.isFalse(inputSpan.hasAttribute('hidden')); assert.isFalse(inputSpan.hasAttribute('hidden'));
}); });
test('account info edit', function(done) { suite('account info edit', function() {
var accountChangedSpy;
var nameStub;
var statusStub;
setup(function() {
accountChangedSpy = sandbox.spy(element, '_accountChanged');
element.set('_serverConfig', element.set('_serverConfig',
{auth: {editable_account_fields: ['FULL_NAME']}}); {auth: {editable_account_fields: ['FULL_NAME']}});
var setStub = sinon.stub(element.$.restAPI, 'setAccountName', nameStub = sandbox.stub(element.$.restAPI, 'setAccountName',
function(name) { return Promise.resolve(); }); function(name) { return Promise.resolve(); });
statusStub = sandbox.stub(element.$.restAPI, 'setAccountStatus',
function(status) { return Promise.resolve(); });
});
var nameChangedSpy = sinon.spy(element, '_nameChanged'); test('name', function(done) {
assert.isTrue(element.mutable); assert.isTrue(element.mutable);
assert.isFalse(element.hasUnsavedChanges); assert.isFalse(element.hasUnsavedChanges);
element.set('_account.name', 'new name'); element.set('_account.name', 'new name');
assert.isTrue(nameChangedSpy.called); assert.isTrue(accountChangedSpy.called);
assert.isTrue(element.hasUnsavedChanges); assert.isTrue(element.hasUnsavedChanges);
MockInteractions.pressAndReleaseKeyOn(nameInput, 13); MockInteractions.pressAndReleaseKeyOn(element.$.nameInput, 13);
assert.isTrue(setStub.called); assert.isTrue(nameStub.called);
setStub.lastCall.returnValue.then(function() { nameStub.lastCall.returnValue.then(function() {
assert.equal(setStub.lastCall.args[0], 'new name'); assert.equal(nameStub.lastCall.args[0], 'new name');
done();
});
});
test('status', function(done) {
assert.isTrue(element.mutable);
assert.isFalse(element.hasUnsavedChanges);
element.set('_account.status', 'new status');
assert.isTrue(accountChangedSpy.called);
assert.isTrue(element.hasUnsavedChanges);
MockInteractions.pressAndReleaseKeyOn(element.$.statusInput, 13);
flushAsynchronousOperations();
assert.isTrue(statusStub.called);
statusStub.lastCall.returnValue.then(function() {
assert.equal(statusStub.lastCall.args[0], 'new status');
done(); done();
}); });
}); });
}); });
});
</script> </script>

View File

@@ -288,6 +288,23 @@
}.bind(this)); }.bind(this));
}, },
setAccountStatus: function(status, opt_errFn, opt_ctx) {
return this.send('PUT', '/accounts/self/status', {status: status},
opt_errFn, opt_ctx).then(function(response) {
// If result of getAccount is in cache, update it in the cache
// so we don't have to invalidate it.
var cachedAccount = this._cache['/accounts/self/detail'];
if (cachedAccount) {
return this.getResponseObject(response).then(function(newStatus) {
// Replace object in cache with new object to force UI updates.
// TODO(logan): Polyfill for Object.assign in IE
this._cache['/accounts/self/detail'] = Object.assign(
{}, cachedAccount, {status: newStatus});
}.bind(this));
}
}.bind(this));
},
getAccountGroups: function() { getAccountGroups: function() {
return this._fetchSharedCacheURL('/accounts/self/groups'); return this._fetchSharedCacheURL('/accounts/self/groups');
}, },

View File

@@ -436,5 +436,19 @@ limitations under the License.
done(); done();
}); });
}); });
test('setAccountStatus', function(done) {
sandbox.stub(element, 'send').returns(Promise.resolve('OOO'));
sandbox.stub(element, 'getResponseObject')
.returns(Promise.resolve('OOO'));
element._cache['/accounts/self/detail'] = {};
element.setAccountStatus('OOO').then(function() {
assert.isTrue(element.send.calledWith('PUT', '/accounts/self/status',
{status: 'OOO'}));
assert.deepEqual(element._cache['/accounts/self/detail'],
{status: 'OOO'});
done();
});
});
}); });
</script> </script>