Merge "Add status field to settings view"
This commit is contained in:
		@@ -138,13 +138,13 @@
 | 
			
		||||
      return loading || !this._changes || this._changes.length < changesPerPage;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _handleNextPage() {
 | 
			
		||||
    _handleNextPage: function() {
 | 
			
		||||
      if (this._hideNextArrow(this._offset)) { return; }
 | 
			
		||||
      page.show(this._computeNavLink(
 | 
			
		||||
          this._query, this._offset, 1, this._changesPerPage));
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _handlePreviousPage() {
 | 
			
		||||
    _handlePreviousPage: function() {
 | 
			
		||||
      if (this._hidePrevArrow(this._offset)) { return; }
 | 
			
		||||
      page.show(this._computeNavLink(
 | 
			
		||||
          this._query, this._offset, -1, this._changesPerPage));
 | 
			
		||||
 
 | 
			
		||||
@@ -54,11 +54,23 @@ limitations under the License.
 | 
			
		||||
            class="value">
 | 
			
		||||
          <input
 | 
			
		||||
              is="iron-input"
 | 
			
		||||
              id="nameInput"
 | 
			
		||||
              disabled="[[_saving]]"
 | 
			
		||||
              on-keydown="_handleNameKeydown"
 | 
			
		||||
              on-keydown="_handleKeydown"
 | 
			
		||||
              bind-value="{{_account.name}}">
 | 
			
		||||
        </span>
 | 
			
		||||
      </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>
 | 
			
		||||
    <gr-rest-api-interface id="restAPI"></gr-rest-api-interface>
 | 
			
		||||
  </template>
 | 
			
		||||
 
 | 
			
		||||
@@ -48,7 +48,7 @@
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    observers: [
 | 
			
		||||
      '_nameChanged(_account.name)',
 | 
			
		||||
      '_accountChanged(_account.*)',
 | 
			
		||||
    ],
 | 
			
		||||
 | 
			
		||||
    loadData: function() {
 | 
			
		||||
@@ -75,7 +75,10 @@
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      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._saving = false;
 | 
			
		||||
        this.fire('account-detail-update');
 | 
			
		||||
@@ -86,12 +89,12 @@
 | 
			
		||||
      return config.auth.editable_account_fields.indexOf('FULL_NAME') !== -1;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _nameChanged: function() {
 | 
			
		||||
    _accountChanged: function() {
 | 
			
		||||
      if (this._loading) { return; }
 | 
			
		||||
      this.hasUnsavedChanges = true;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _handleNameKeydown: function(e) {
 | 
			
		||||
    _handleKeydown: function(e) {
 | 
			
		||||
      if (e.keyCode === 13) { // Enter
 | 
			
		||||
        e.stopPropagation();
 | 
			
		||||
        this.save();
 | 
			
		||||
 
 | 
			
		||||
@@ -35,7 +35,7 @@ limitations under the License.
 | 
			
		||||
    var element;
 | 
			
		||||
    var account;
 | 
			
		||||
    var config;
 | 
			
		||||
    var nameInput;
 | 
			
		||||
    var sandbox;
 | 
			
		||||
 | 
			
		||||
    function valueOf(title) {
 | 
			
		||||
      var sections = Polymer.dom(element.root).querySelectorAll('section');
 | 
			
		||||
@@ -49,6 +49,7 @@ limitations under the License.
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    setup(function(done) {
 | 
			
		||||
      sandbox = sinon.sandbox.create();
 | 
			
		||||
      account = {
 | 
			
		||||
        _account_id: 123,
 | 
			
		||||
        name: 'user name',
 | 
			
		||||
@@ -66,13 +67,14 @@ limitations under the License.
 | 
			
		||||
        },
 | 
			
		||||
      });
 | 
			
		||||
      element = fixture('basic');
 | 
			
		||||
 | 
			
		||||
      nameInput = element.$.nameSection.querySelector('.value input');
 | 
			
		||||
 | 
			
		||||
      // Allow the element to render.
 | 
			
		||||
      element.loadData().then(function() { flush(done); });
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    teardown(function() {
 | 
			
		||||
      sandbox.restore();
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    test('basic account info render', function() {
 | 
			
		||||
      assert.isFalse(element._loading);
 | 
			
		||||
 | 
			
		||||
@@ -102,33 +104,61 @@ limitations under the License.
 | 
			
		||||
 | 
			
		||||
      assert.isTrue(element.mutable);
 | 
			
		||||
      assert.isTrue(displaySpan.hasAttribute('hidden'));
 | 
			
		||||
      assert.equal(nameInput.bindValue, account.name);
 | 
			
		||||
      assert.equal(element.$.nameInput.bindValue, account.name);
 | 
			
		||||
      assert.isFalse(inputSpan.hasAttribute('hidden'));
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    test('account info edit', function(done) {
 | 
			
		||||
      element.set('_serverConfig',
 | 
			
		||||
    suite('account info edit', function() {
 | 
			
		||||
      var accountChangedSpy;
 | 
			
		||||
      var nameStub;
 | 
			
		||||
      var statusStub;
 | 
			
		||||
 | 
			
		||||
      setup(function() {
 | 
			
		||||
        accountChangedSpy = sandbox.spy(element, '_accountChanged');
 | 
			
		||||
        element.set('_serverConfig',
 | 
			
		||||
          {auth: {editable_account_fields: ['FULL_NAME']}});
 | 
			
		||||
 | 
			
		||||
      var setStub = sinon.stub(element.$.restAPI, 'setAccountName',
 | 
			
		||||
          function(name) { return Promise.resolve(); });
 | 
			
		||||
        nameStub = sandbox.stub(element.$.restAPI, 'setAccountName',
 | 
			
		||||
            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.isFalse(element.hasUnsavedChanges);
 | 
			
		||||
 | 
			
		||||
      assert.isTrue(element.mutable);
 | 
			
		||||
      assert.isFalse(element.hasUnsavedChanges);
 | 
			
		||||
        element.set('_account.name', 'new name');
 | 
			
		||||
 | 
			
		||||
      element.set('_account.name', 'new name');
 | 
			
		||||
        assert.isTrue(accountChangedSpy.called);
 | 
			
		||||
        assert.isTrue(element.hasUnsavedChanges);
 | 
			
		||||
 | 
			
		||||
      assert.isTrue(nameChangedSpy.called);
 | 
			
		||||
      assert.isTrue(element.hasUnsavedChanges);
 | 
			
		||||
        MockInteractions.pressAndReleaseKeyOn(element.$.nameInput, 13);
 | 
			
		||||
 | 
			
		||||
      MockInteractions.pressAndReleaseKeyOn(nameInput, 13);
 | 
			
		||||
        assert.isTrue(nameStub.called);
 | 
			
		||||
        nameStub.lastCall.returnValue.then(function() {
 | 
			
		||||
          assert.equal(nameStub.lastCall.args[0], 'new name');
 | 
			
		||||
          done();
 | 
			
		||||
        });
 | 
			
		||||
      });
 | 
			
		||||
 | 
			
		||||
      assert.isTrue(setStub.called);
 | 
			
		||||
      setStub.lastCall.returnValue.then(function() {
 | 
			
		||||
        assert.equal(setStub.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();
 | 
			
		||||
        });
 | 
			
		||||
      });
 | 
			
		||||
    });
 | 
			
		||||
  });
 | 
			
		||||
 
 | 
			
		||||
@@ -288,6 +288,23 @@
 | 
			
		||||
      }.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() {
 | 
			
		||||
      return this._fetchSharedCacheURL('/accounts/self/groups');
 | 
			
		||||
    },
 | 
			
		||||
 
 | 
			
		||||
@@ -436,5 +436,19 @@ limitations under the License.
 | 
			
		||||
        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>
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user