Merge "Fix assignee autocomplete behavior"

This commit is contained in:
Andrew Bonventre
2017-01-11 22:58:53 +00:00
committed by Gerrit Code Review
6 changed files with 117 additions and 52 deletions

View File

@@ -28,6 +28,16 @@
change: Object,
filter: Function,
placeholder: String,
/**
* When true, account-entry uses the account suggest API endpoint, which
* suggests any account in that Gerrit instance (and does not suggest
* groups).
*
* When false/undefined, account-entry uses the suggest_reviewers API
* endpoint, which suggests any account or group in that Gerrit instance
* that is not already a reviewer (or is not CCed) on that change.
*/
allowAnyUser: Boolean,
suggestFrom: {
type: Number,
@@ -60,21 +70,34 @@
_makeSuggestion: function(reviewer) {
if (reviewer.account) {
// Reviewer is an account suggestion from getChangeSuggestedReviewers.
return {
name: reviewer.account.name + ' (' + reviewer.account.email + ')',
value: reviewer,
};
} else if (reviewer.group) {
// Reviewer is a group suggestion from getChangeSuggestedReviewers.
return {
name: reviewer.group.name + ' (group)',
value: reviewer,
};
} else if (reviewer._account_id) {
// Reviewer is an account suggestion from getSuggestedAccounts.
return {
name: reviewer.name + ' (' + reviewer.email + ')',
value: {
account: reviewer,
count: 1,
},
};
}
},
_getReviewerSuggestions: function(input) {
var xhr = this.$.restAPI.getChangeSuggestedReviewers(
this.change._number, input);
var api = this.$.restAPI;
var xhr = this.allowAnyUser ?
api.getSuggestedAccounts(input) :
api.getChangeSuggestedReviewers(this.change._number, input);
return xhr.then(function(reviewers) {
if (!reviewers) { return []; }

View File

@@ -33,6 +33,7 @@ limitations under the License.
<script>
suite('gr-account-entry tests', function() {
var sandbox;
var _nextAccountId = 0;
var makeAccount = function() {
var accountId = ++_nextAccountId;
@@ -72,49 +73,85 @@ limitations under the License.
REVIEWER: [existingReviewer2],
},
};
stub('gr-rest-api-interface', {
getChangeSuggestedReviewers: function() {
var redundantSuggestion1 = {account: existingReviewer1};
var redundantSuggestion2 = {account: existingReviewer2};
var redundantSuggestion3 = {account: owner};
return Promise.resolve([redundantSuggestion1, redundantSuggestion2,
redundantSuggestion3, suggestion1, suggestion2, suggestion3]);
},
});
sandbox = sinon.sandbox.create();
});
test('_makeSuggestion formats account or group accordingly', function() {
var account = makeAccount();
var suggestion = element._makeSuggestion({account: account});
assert.deepEqual(suggestion, {
name: account.name + ' (' + account.email + ')',
value: {account: account},
});
var group = {name: 'test'};
suggestion = element._makeSuggestion({group: group});
assert.deepEqual(suggestion, {
name: group.name + ' (group)',
value: {group: group},
});
teardown(function() {
sandbox.restore();
});
test('_getReviewerSuggestions excludes owner+reviewers', function(done) {
element._getReviewerSuggestions().then(function(reviewers) {
// Default is no filtering.
assert.equal(reviewers.length, 6);
suite('stubbed values for _getReviewerSuggestions', function() {
setup(function() {
stub('gr-rest-api-interface', {
getChangeSuggestedReviewers: function() {
var redundantSuggestion1 = {account: existingReviewer1};
var redundantSuggestion2 = {account: existingReviewer2};
var redundantSuggestion3 = {account: owner};
return Promise.resolve([redundantSuggestion1, redundantSuggestion2,
redundantSuggestion3, suggestion1, suggestion2, suggestion3]);
},
});
});
// Set up filter that only accepts suggestion1.
var accountId = suggestion1.account._account_id;
element.filter = function(suggestion) {
return suggestion.account &&
suggestion.account._account_id === accountId;
};
test('_makeSuggestion formats account or group accordingly', function() {
var account = makeAccount();
var suggestion = element._makeSuggestion({account: account});
assert.deepEqual(suggestion, {
name: account.name + ' (' + account.email + ')',
value: {account: account},
});
var group = {name: 'test'};
suggestion = element._makeSuggestion({group: group});
assert.deepEqual(suggestion, {
name: group.name + ' (group)',
value: {group: group},
});
suggestion = element._makeSuggestion(account);
assert.deepEqual(suggestion, {
name: account.name + ' (' + account.email + ')',
value: {account: account, count: 1},
});
});
test('_getReviewerSuggestions excludes owner+reviewers', function(done) {
element._getReviewerSuggestions().then(function(reviewers) {
assert.deepEqual(reviewers, [element._makeSuggestion(suggestion1)]);
}).then(done);
// Default is no filtering.
assert.equal(reviewers.length, 6);
// Set up filter that only accepts suggestion1.
var accountId = suggestion1.account._account_id;
element.filter = function(suggestion) {
return suggestion.account &&
suggestion.account._account_id === accountId;
};
element._getReviewerSuggestions().then(function(reviewers) {
assert.deepEqual(reviewers, [element._makeSuggestion(suggestion1)]);
}).then(done);
});
});
});
test('allowAnyUser', function(done) {
var suggestReviewerStub =
sandbox.stub(element.$.restAPI, 'getChangeSuggestedReviewers')
.returns(Promise.resolve([]));
var suggestAccountStub =
sandbox.stub(element.$.restAPI, 'getSuggestedAccounts')
.returns(Promise.resolve([]));
element._getReviewerSuggestions('').then(function() {
assert.isTrue(suggestReviewerStub.calledOnce);
assert.isFalse(suggestAccountStub.called);
element.allowAnyUser = true;
element._getReviewerSuggestions('').then(function() {
assert.isTrue(suggestReviewerStub.calledOnce);
assert.isTrue(suggestAccountStub.calledOnce);
done();
});
});
});
});

View File

@@ -55,7 +55,8 @@ limitations under the License.
filter="[[filter]]"
placeholder="[[placeholder]]"
on-add="_handleAdd"
on-input-keydown="_handleInputKeydown">
on-input-keydown="_handleInputKeydown"
allow-any-user="[[allowAnyUser]]">
</gr-account-entry>
</template>
<script src="gr-account-list.js"></script>

View File

@@ -35,6 +35,19 @@
type: Boolean,
value: false,
},
/**
* When true, the account-entry autocomplete uses the account suggest API
* endpoint, which suggests any account in that Gerrit instance (and does
* not suggest groups).
*
* When false/undefined, account-entry uses the suggest_reviewers API
* endpoint, which suggests any account or group in that Gerrit instance
* that is not already a reviewer (or is not CCed) on that change.
*/
allowAnyUser: {
type: Boolean,
value: false,
},
/**
* Array of values (groups/accounts) that are removable. When this prop is
* undefined, all values are removable.

View File

@@ -114,9 +114,9 @@ limitations under the License.
id="assigneeValue"
placeholder="Add assignee..."
accounts="{{_assignee}}"
filter="[[_filterAssigneeSuggestion]]"
change="[[change]]"
readonly="[[!mutable]]"></gr-account-list>
readonly="[[!mutable]]"
allow-any-user></gr-account-list>
</span>
</section>
<section>
@@ -147,9 +147,9 @@ limitations under the License.
id="assigneeValue"
placeholder="Add assignee..."
accounts="{{_assignee}}"
filter="[[_filterAssigneeSuggestion]]"
change="[[change]]"
readonly="[[!mutable]]"></gr-account-list>
readonly="[[!mutable]]"
allow-any-user></gr-account-list>
</span>
</section>
<section>

View File

@@ -41,15 +41,6 @@
type: Boolean,
computed: '_computeShowLabelStatus(change)',
},
/**
* Groups are not valid assignees.
*/
_filterAssigneeSuggestion: {
type: Function,
value: function() {
return function(suggestion) { return suggestion.account; };
},
},
_assignee: Array,
},