Project import generated by Copybara.
GitOrigin-RevId: d9e9e3fb4e31372ec1fb43b178994ca78fa8fe70
diff --git a/static_src/elements/ezt/mr-bulk-approval-update/mr-bulk-approval-update.test.js b/static_src/elements/ezt/mr-bulk-approval-update/mr-bulk-approval-update.test.js
new file mode 100644
index 0000000..a0689e1
--- /dev/null
+++ b/static_src/elements/ezt/mr-bulk-approval-update/mr-bulk-approval-update.test.js
@@ -0,0 +1,185 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+import {assert} from 'chai';
+import sinon from 'sinon';
+import {fireEvent} from '@testing-library/react';
+
+import {MrBulkApprovalUpdate, NO_APPROVALS_MESSAGE,
+ NO_UPDATES_MESSAGE} from './mr-bulk-approval-update.js';
+import {prpcClient} from 'prpc-client-instance.js';
+
+let element;
+
+describe('mr-bulk-approval-update', () => {
+ beforeEach(() => {
+ element = document.createElement('mr-bulk-approval-update');
+ document.body.appendChild(element);
+
+ sinon.stub(prpcClient, 'call');
+ });
+
+ afterEach(() => {
+ document.body.removeChild(element);
+ prpcClient.call.restore();
+ });
+
+ it('initializes', () => {
+ assert.instanceOf(element, MrBulkApprovalUpdate);
+ });
+
+ it('_computeIssueRefs: missing information', () => {
+ element.projectName = 'chromium';
+ assert.equal(element.issueRefs.length, 0);
+
+ element.projectName = null;
+ element.localIdsStr = '1,2,3,5';
+ assert.equal(element.issueRefs.length, 0);
+
+ element.localIdsStr = null;
+ assert.equal(element.issueRefs.length, 0);
+ });
+
+ it('_computeIssueRefs: normal', () => {
+ const project = 'chromium';
+ element.projectName = project;
+ element.localIdsStr = '1,2,3';
+ assert.deepEqual(element.issueRefs, [
+ {projectName: project, localId: '1'},
+ {projectName: project, localId: '2'},
+ {projectName: project, localId: '3'},
+ ]);
+ });
+
+ it('fetchApprovals: applicable fields exist', async () => {
+ const responseFieldDefs = [
+ {fieldRef: {type: 'INT_TYPE'}},
+ {fieldRef: {type: 'APPROVAL_TYPE'}},
+ {fieldRef: {type: 'APPROVAL_TYPE'}},
+ ];
+ const promise = Promise.resolve({fieldDefs: responseFieldDefs});
+ prpcClient.call.returns(promise);
+
+ sinon.spy(element, 'fetchApprovals');
+
+ await element.updateComplete;
+
+ element.querySelector('.js-showApprovals').click();
+ assert.isTrue(element.fetchApprovals.calledOnce);
+
+ // Wait for promise in fetchApprovals to resolve.
+ await promise;
+
+ assert.deepEqual([
+ {fieldRef: {type: 'APPROVAL_TYPE'}},
+ {fieldRef: {type: 'APPROVAL_TYPE'}},
+ ], element.approvals);
+ assert.equal(null, element.errorMessage);
+ });
+
+ it('fetchApprovals: applicable fields dont exist', async () => {
+ const promise = Promise.resolve({fieldDefs: []});
+ prpcClient.call.returns(promise);
+
+ await element.updateComplete;
+
+ element.querySelector('.js-showApprovals').click();
+
+ await promise;
+
+ assert.equal(element.approvals.length, 0);
+ assert.equal(NO_APPROVALS_MESSAGE, element.errorMessage);
+ });
+
+ it('save: normal', async () => {
+ const promise =
+ Promise.resolve({issueRefs: [{localId: '1'}, {localId: '3'}]});
+ prpcClient.call.returns(promise);
+ const fieldDefs = [
+ {fieldRef: {fieldName: 'Approval-One', type: 'APPROVAL_TYPE'}},
+ {fieldRef: {fieldName: 'Approval-Two', type: 'APPROVAL_TYPE'}},
+ ];
+ element.approvals = fieldDefs;
+ element.projectName = 'chromium';
+ element.localIdsStr = '1,2,3';
+
+ await element.updateComplete;
+
+ fireEvent.change(element.querySelector('#commentText'), {target: {value: 'comment'}});
+ fireEvent.change(element.querySelector('#statusInput'), {target: {value: 'NotApproved'}});
+ element.querySelector('.js-save').click();
+
+ // Wait for promise in save() to resolve.
+ await promise;
+ await element.updateComplete;
+
+ // Assert messages correct
+ assert.equal(
+ true,
+ element.responseMessage.includes(
+ 'Updated Approval-One in issues: 1, 3 (2 of 3).'));
+ assert.equal('', element.errorMessage);
+
+ // Assert all inputs not disabled.
+ element.querySelectorAll('input, textarea, select').forEach((input) => {
+ assert.equal(input.disabled, false);
+ });
+
+ // Assert all inputs cleared.
+ element.querySelectorAll('input, textarea').forEach((input) => {
+ assert.equal(input.value, '');
+ });
+ element.querySelectorAll('select').forEach((select) => {
+ assert.equal(select.selectedIndex, 0);
+ });
+
+ // Assert BulkUpdateApprovals correctly called.
+ const expectedMessage = {
+ approvalDelta: {status: 'NOT_APPROVED'},
+ commentContent: 'comment',
+ fieldRef: fieldDefs[0].fieldRef,
+ issueRefs: element.issueRefs,
+ send_email: true,
+ };
+ sinon.assert.calledWith(
+ prpcClient.call,
+ 'monorail.Issues',
+ 'BulkUpdateApprovals',
+ expectedMessage);
+ });
+
+ it('save: no updates', async () => {
+ const promise = Promise.resolve({issueRefs: []});
+ prpcClient.call.returns(promise);
+ const fieldDefs = [
+ {fieldRef: {fieldName: 'Approval-One', type: 'APPROVAL_TYPE'}},
+ {fieldRef: {fieldName: 'Approval-Two', type: 'APPROVAL_TYPE'}},
+ ];
+ element.approvals = fieldDefs;
+ element.projectName = 'chromium';
+ element.localIdsStr = '1,2,3';
+
+ await element.updateComplete;
+
+ element.querySelector('#commentText').value = 'comment';
+ element.querySelector('#statusInput').value = 'NotApproved';
+ element.querySelector('.js-save').click();
+
+ // Wait for promise in save() to resolve
+ await promise;
+
+ // Assert messages correct.
+ assert.equal('', element.responseMessage);
+ assert.equal(NO_UPDATES_MESSAGE, element.errorMessage);
+
+ // Assert inputs not cleared.
+ assert.equal(element.querySelector('#commentText').value, 'comment');
+ assert.equal(element.querySelector('#statusInput').value, 'NotApproved');
+
+ // Assert inputs not disabled.
+ element.querySelectorAll('input, textarea, select').forEach((input) => {
+ assert.equal(input.disabled, false);
+ });
+ });
+});