diff options
author | Frank Borden <frankborden@google.com> | 2022-04-08 17:38:08 +0200 |
---|---|---|
committer | Paladox none <thomasmulhall410@yahoo.com> | 2022-04-12 15:07:27 +0000 |
commit | e92610e588ae722b15a2a7c6e1dfe3f2524eb91b (patch) | |
tree | 83b5c5e57e864d7dfef44567870fc95d469aa538 | |
parent | a6847da2207e7e7c6ee47d9db728094195e0d629 (diff) |
Convert gr-confirm-cherrypick-dialog to lit
Release-Notes: skip
Change-Id: Ic5bd9ec99f50de2454083bf7607467716e59423c
(cherry picked from commit 4f88a0fc8153c2cea1d21ab98115b3434cbd6062)
4 files changed, 373 insertions, 353 deletions
diff --git a/polygerrit-ui/app/elements/change/gr-change-actions/gr-change-actions_test.ts b/polygerrit-ui/app/elements/change/gr-change-actions/gr-change-actions_test.ts index 3ca7b0c2e3..50ab91c264 100644 --- a/polygerrit-ui/app/elements/change/gr-change-actions/gr-change-actions_test.ts +++ b/polygerrit-ui/app/elements/change/gr-change-actions/gr-change-actions_test.ts @@ -845,7 +845,7 @@ suite('gr-change-actions tests', () => { sinon.stub(window, 'alert'); }); - test('works', () => { + test('works', async () => { element._handleCherrypickTap(); const action = { __key: 'cherrypick', @@ -868,8 +868,10 @@ suite('gr-change-actions tests', () => { element.$.confirmCherrypick.commitMessage = 'foo message'; element.$.confirmCherrypick.changeStatus = ChangeStatus.NEW; element.$.confirmCherrypick.commitNum = '123' as CommitId; + await element.updateComplete; element._handleCherrypickConfirm(); + await element.updateComplete; const autogrowEl = queryAndAssert<IronAutogrowTextareaElement>( element.$.confirmCherrypick, @@ -890,7 +892,7 @@ suite('gr-change-actions tests', () => { ]); }); - test('cherry pick even with conflicts', () => { + test('cherry pick even with conflicts', async () => { element._handleCherrypickTap(); const action = { __key: 'cherrypick', @@ -908,8 +910,10 @@ suite('gr-change-actions tests', () => { element.$.confirmCherrypick.commitMessage = 'foo message'; element.$.confirmCherrypick.changeStatus = ChangeStatus.NEW; element.$.confirmCherrypick.commitNum = '123' as CommitId; + await element.updateComplete; element._handleCherrypickConflictConfirm(); + await element.updateComplete; assert.deepEqual(fireActionStub.lastCall.args, [ '/cherrypick', diff --git a/polygerrit-ui/app/elements/change/gr-confirm-cherrypick-dialog/gr-confirm-cherrypick-dialog.ts b/polygerrit-ui/app/elements/change/gr-confirm-cherrypick-dialog/gr-confirm-cherrypick-dialog.ts index c3ae19f981..828996ed44 100644 --- a/polygerrit-ui/app/elements/change/gr-confirm-cherrypick-dialog/gr-confirm-cherrypick-dialog.ts +++ b/polygerrit-ui/app/elements/change/gr-confirm-cherrypick-dialog/gr-confirm-cherrypick-dialog.ts @@ -19,8 +19,6 @@ import '@polymer/iron-input/iron-input'; import '../../../styles/shared-styles'; import '../../shared/gr-autocomplete/gr-autocomplete'; import '../../shared/gr-dialog/gr-dialog'; -import {PolymerElement} from '@polymer/polymer/polymer-element'; -import {htmlTemplate} from './gr-confirm-cherrypick-dialog_html'; import {GerritNav} from '../../core/gr-navigation/gr-navigation'; import {getAppContext} from '../../../services/app-context'; import { @@ -30,8 +28,13 @@ import { CommitId, ChangeInfoId, } from '../../../types/common'; -import {customElement, property, observe} from '@polymer/decorators'; -import {GrTypedAutocomplete} from '../../shared/gr-autocomplete/gr-autocomplete'; +import {customElement, property, query, state} from 'lit/decorators'; +import { + AutocompleteCommitEvent, + AutocompleteQuery, + AutocompleteSuggestion, + GrTypedAutocomplete, +} from '../../shared/gr-autocomplete/gr-autocomplete'; import { HttpMethod, ChangeStatus, @@ -39,6 +42,11 @@ import { } from '../../../constants/constants'; import {dom, EventApi} from '@polymer/polymer/lib/legacy/polymer.dom'; import {fireEvent} from '../../../utils/event-util'; +import {css, html, LitElement, PropertyValues} from 'lit'; +import {sharedStyles} from '../../../styles/shared-styles'; +import {choose} from 'lit/directives/choose'; +import {when} from 'lit/directives/when'; +import {BindValueChangeEvent} from '../../../types/events'; const SUGGESTIONS_LIMIT = 15; const CHANGE_SUBJECT_LIMIT = 50; @@ -60,18 +68,8 @@ declare global { } } -export interface GrConfirmCherrypickDialog { - $: { - branchInput: GrTypedAutocomplete<BranchName>; - }; -} - @customElement('gr-confirm-cherrypick-dialog') -export class GrConfirmCherrypickDialog extends PolymerElement { - static get template() { - return htmlTemplate; - } - +export class GrConfirmCherrypickDialog extends LitElement { /** * Fired when the confirm button is pressed. * @@ -108,27 +106,30 @@ export class GrConfirmCherrypickDialog extends PolymerElement { @property({type: Array}) changes: ChangeInfo[] = []; - @property({type: Object}) - _query?: (input: string) => Promise<{name: BranchName}[]>; + @state() + private query: AutocompleteQuery; - @property({type: Boolean}) - _showCherryPickTopic = false; + @state() + private showCherryPickTopic = false; - @property({type: Number}) - _changesCount?: number; + @state() + private changesCount?: number; - @property({type: Number}) - _cherryPickType = CherryPickType.SINGLE_CHANGE; + @state() + cherryPickType = CherryPickType.SINGLE_CHANGE; - @property({type: Boolean}) - _duplicateProjectChanges = false; + @state() + private duplicateProjectChanges = false; - @property({type: Object}) + @state() // Status of each change that is being cherry picked together - _statuses: Statuses; + private statuses: Statuses; + + @state() + private invalidBranch = false; - @property({type: Boolean}) - _invalidBranch = false; + @query('#branchInput') + branchInput!: GrTypedAutocomplete<BranchName>; private selectedChangeIds = new Set<ChangeInfoId>(); @@ -138,8 +139,254 @@ export class GrConfirmCherrypickDialog extends PolymerElement { constructor() { super(); - this._statuses = {}; - this._query = (text: string) => this._getProjectBranchesSuggestions(text); + this.statuses = {}; + this.query = (text: string) => this.getProjectBranchesSuggestions(text); + } + + override willUpdate(changedProperties: PropertyValues) { + if (changedProperties.has('branch')) { + this.updateBranch(); + } + if ( + changedProperties.has('changeStatus') || + changedProperties.has('commitNum') || + changedProperties.has('commitMessage') + ) { + this.computeMessage(); + } + } + + static override styles = [ + sharedStyles, + css` + :host { + display: block; + } + :host([disabled]) { + opacity: 0.5; + pointer-events: none; + } + label { + cursor: pointer; + } + .main { + display: flex; + flex-direction: column; + width: 100%; + } + .main label, + .main input[type='text'] { + display: block; + width: 100%; + } + iron-autogrow-textarea { + font-family: var(--monospace-font-family); + font-size: var(--font-size-mono); + line-height: var(--line-height-mono); + width: 73ch; /* Add a char to account for the border. */ + } + .cherryPickTopicLayout { + display: flex; + align-items: center; + margin-bottom: var(--spacing-m); + } + .cherryPickSingleChange, + .cherryPickTopic { + margin-left: var(--spacing-m); + } + .cherry-pick-topic-message { + margin-bottom: var(--spacing-m); + } + label[for='messageInput'], + label[for='baseInput'] { + margin-top: var(--spacing-m); + } + .title { + font-weight: var(--font-weight-bold); + } + tr > td { + padding: var(--spacing-m); + } + th { + color: var(--deemphasized-text-color); + } + table { + border-collapse: collapse; + } + tr { + border-bottom: 1px solid var(--border-color); + } + .error { + color: var(--error-text-color); + } + .error-message { + color: var(--error-text-color); + margin: var(--spacing-m) 0 var(--spacing-m) 0; + } + `, + ]; + + override render() { + return html` + <gr-dialog + confirm-label="Cherry Pick" + .cancelLabel=${this.computeCancelLabel()} + ?disabled=${this.computeDisableCherryPick( + this.cherryPickType, + this.duplicateProjectChanges, + this.statuses, + this.branch + )} + @confirm=${this.handleConfirmTap} + @cancel=${this.handleCancelTap} + > + <div class="header title" slot="header"> + Cherry Pick Change to Another Branch + </div> + <div class="main" slot="main"> + ${when(this.showCherryPickTopic, () => + this.renderCherrypickTopicLayout() + )} + <label for="branchInput"> Cherry Pick to branch </label> + <gr-autocomplete + id="branchInput" + .text=${this.branch} + .query=${this.query} + placeholder="Destination branch" + @commit=${(e: AutocompleteCommitEvent) => + (this.branch = e.detail.value as BranchName)} + > + </gr-autocomplete> + ${when( + this.invalidBranch, + () => html` + <span class="error" + >Branch name cannot contain space or commas.</span + > + ` + )} + ${choose(this.cherryPickType, [ + [ + CherryPickType.SINGLE_CHANGE, + () => this.renderCherrypickSingleChangeInputs(), + ], + [CherryPickType.TOPIC, () => this.renderCherrypickTopicTable()], + ])} + </div> + </gr-dialog> + `; + } + + private renderCherrypickTopicLayout() { + return html` + <div class="cherryPickTopicLayout"> + <input + name="cherryPickOptions" + type="radio" + id="cherryPickSingleChange" + @change=${this.handlecherryPickSingleChangeClicked} + checked + /> + <label for="cherryPickSingleChange" class="cherryPickSingleChange"> + Cherry Pick single change + </label> + </div> + <div class="cherryPickTopicLayout"> + <input + name="cherryPickOptions" + type="radio" + id="cherryPickTopic" + @change=${this.handlecherryPickTopicClicked} + /> + <label for="cherryPickTopic" class="cherryPickTopic"> + Cherry Pick entire topic (${this.changesCount} Changes) + </label> + </div> + `; + } + + private renderCherrypickSingleChangeInputs() { + return html` + <label for="baseInput"> Provide base commit sha1 for cherry-pick </label> + <iron-input + .bindValue=${this.baseCommit} + @bind-value-changed=${(e: BindValueChangeEvent) => + (this.baseCommit = e.detail.value)} + > + <input + is="iron-input" + id="baseCommitInput" + maxlength="40" + placeholder="(optional)" + /> + </iron-input> + <label for="messageInput"> Cherry Pick Commit Message </label> + <iron-autogrow-textarea + id="messageInput" + class="message" + autocomplete="on" + rows="4" + .maxRows=${15} + .bindValue=${this.message} + @bind-value-changed=${(e: BindValueChangeEvent) => + (this.message = e.detail.value)} + ></iron-autogrow-textarea> + `; + } + + private renderCherrypickTopicTable() { + return html` + <span class="error-message">${this.computeTopicErrorMessage()}</span> + <span class="cherry-pick-topic-message"> + Commit Message will be auto generated + </span> + <table> + <thead> + <tr> + <th></th> + <th>Change</th> + <th>Status</th> + <th>Subject</th> + <th>Project</th> + <th>Progress</th> + <!-- Error Message --> + <th></th> + </tr> + </thead> + <tbody> + ${this.changes.map( + item => html` + <tr> + <td> + <input + type="checkbox" + data-item=${item.id as string} + @change=${this.toggleChangeSelected} + ?checked=${this.isChangeSelected(item.id)} + /> + </td> + <td><span> ${this.getChangeId(item)} </span></td> + <td><span> ${item.status} </span></td> + <td> + <span> ${this.getTrimmedChangeSubject(item.subject)} </span> + </td> + <td><span> ${item.project} </span></td> + <td> + <span class=${this.computeStatusClass(item, this.statuses)}> + ${this.computeStatus(item, this.statuses)} + </span> + </td> + <td> + <span class="error"> + ${this.computeError(item, this.statuses)} + </span> + </td> + </tr> + ` + )} + </tbody> + </table> + `; } containsDuplicateProject(changes: ChangeInfo[]) { @@ -156,28 +403,27 @@ export class GrConfirmCherrypickDialog extends PolymerElement { updateChanges(changes: ChangeInfo[]) { this.changes = changes; - this._statuses = {}; + this.statuses = {}; changes.forEach(change => { this.selectedChangeIds.add(change.id); }); - this._duplicateProjectChanges = this.containsDuplicateProject(changes); - this._changesCount = changes.length; - this._showCherryPickTopic = changes.length > 1; + this.duplicateProjectChanges = this.containsDuplicateProject(changes); + this.changesCount = changes.length; + this.showCherryPickTopic = changes.length > 1; } - @observe('branch') - _updateBranch(branch: string) { + private updateBranch() { const invalidChars = [',', ' ']; - this._invalidBranch = !!( - branch && invalidChars.some(c => branch.includes(c)) + this.invalidBranch = !!( + this.branch && invalidChars.some(c => this.branch.includes(c)) ); } - _isChangeSelected(changeId: ChangeInfoId) { + private isChangeSelected(changeId: ChangeInfoId) { return this.selectedChangeIds.has(changeId); } - _toggleChangeSelected(e: Event) { + private toggleChangeSelected(e: Event) { const changeId = ((dom(e) as EventApi).localTarget as HTMLElement).dataset[ 'item' ]! as ChangeInfoId; @@ -187,32 +433,32 @@ export class GrConfirmCherrypickDialog extends PolymerElement { const changes = this.changes.filter(change => this.selectedChangeIds.has(change.id) ); - this._duplicateProjectChanges = this.containsDuplicateProject(changes); + this.duplicateProjectChanges = this.containsDuplicateProject(changes); } - _computeTopicErrorMessage(duplicateProjectChanges: boolean) { - if (duplicateProjectChanges) { + private computeTopicErrorMessage() { + if (this.duplicateProjectChanges) { return 'Two changes cannot be of the same project'; } return ''; } updateStatus(change: ChangeInfo, status: Status) { - this._statuses = {...this._statuses, [change.id]: status}; + this.statuses = {...this.statuses, [change.id]: status}; } - _computeStatus(change: ChangeInfo, statuses: Statuses) { + private computeStatus(change: ChangeInfo, statuses: Statuses) { if (!change || !statuses || !statuses[change.id]) return ProgressStatus.NOT_STARTED; return statuses[change.id].status; } - _computeStatusClass(change: ChangeInfo, statuses: Statuses) { + computeStatusClass(change: ChangeInfo, statuses: Statuses) { if (!change || !statuses || !statuses[change.id]) return ''; return statuses[change.id].status === ProgressStatus.FAILED ? 'error' : ''; } - _computeError(change: ChangeInfo, statuses: Statuses) { + private computeError(change: ChangeInfo, statuses: Statuses) { if (!change || !statuses || !statuses[change.id]) return ''; if (statuses[change.id].status === ProgressStatus.FAILED) { return statuses[change.id].msg; @@ -220,24 +466,24 @@ export class GrConfirmCherrypickDialog extends PolymerElement { return ''; } - _getChangeId(change: ChangeInfo) { + private getChangeId(change: ChangeInfo) { return change.change_id.substring(0, 10); } - _getTrimmedChangeSubject(subject: string) { + private getTrimmedChangeSubject(subject: string) { if (!subject) return ''; if (subject.length < CHANGE_SUBJECT_LIMIT) return subject; return subject.substring(0, CHANGE_SUBJECT_LIMIT) + '...'; } - _computeCancelLabel(statuses: Statuses) { - const isRunningChange = Object.values(statuses).some( + private computeCancelLabel() { + const isRunningChange = Object.values(this.statuses).some( v => v.status === ProgressStatus.RUNNING ); return isRunningChange ? 'Close' : 'Cancel'; } - _computeDisableCherryPick( + private computeDisableCherryPick( cherryPickType: CherryPickType, duplicateProjectChanges: boolean, statuses: Statuses, @@ -254,64 +500,54 @@ export class GrConfirmCherrypickDialog extends PolymerElement { return isRunningChange; } - _computeIfSinglecherryPick(cherryPickType: CherryPickType) { - return cherryPickType === CherryPickType.SINGLE_CHANGE; - } - - _computeIfCherryPickTopic(cherryPickType: CherryPickType) { - return cherryPickType === CherryPickType.TOPIC; - } - - _handlecherryPickSingleChangeClicked() { - this._cherryPickType = CherryPickType.SINGLE_CHANGE; + private handlecherryPickSingleChangeClicked() { + this.cherryPickType = CherryPickType.SINGLE_CHANGE; fireEvent(this, 'iron-resize'); } - _handlecherryPickTopicClicked() { - this._cherryPickType = CherryPickType.TOPIC; + private handlecherryPickTopicClicked() { + this.cherryPickType = CherryPickType.TOPIC; fireEvent(this, 'iron-resize'); } - @observe('changeStatus', 'commitNum', 'commitMessage') - _computeMessage( - changeStatus?: string, - commitNum?: number, - commitMessage?: string - ) { + private computeMessage() { // Polymer 2: check for undefined if ( - changeStatus === undefined || - commitNum === undefined || - commitMessage === undefined + this.changeStatus === undefined || + this.commitNum === undefined || + this.commitMessage === undefined ) { return; } - let newMessage = commitMessage; + let newMessage = this.commitMessage; - if (changeStatus === 'MERGED') { + if (this.changeStatus === 'MERGED') { if (!newMessage.endsWith('\n')) { newMessage += '\n'; } - newMessage += '(cherry picked from commit ' + commitNum.toString() + ')'; + newMessage += '(cherry picked from commit ' + this.commitNum + ')'; } this.message = newMessage; } - _generateRandomCherryPickTopic(change: ChangeInfo) { + private generateRandomCherryPickTopic(change: ChangeInfo) { const randomString = Math.random().toString(36).substr(2, 10); const message = `cherrypick-${change.topic}-${randomString}`; return message; } - _handleCherryPickFailed(change: ChangeInfo, response?: Response | null) { + private handleCherryPickFailed( + change: ChangeInfo, + response?: Response | null + ) { if (!response) return; response.text().then((errText: string) => { this.updateStatus(change, {status: ProgressStatus.FAILED, msg: errText}); }); } - _handleCherryPickTopic() { + private handleCherryPickTopic() { const changes = this.changes.filter(change => this.selectedChangeIds.has(change.id) ); @@ -320,7 +556,7 @@ export class GrConfirmCherrypickDialog extends PolymerElement { errorSpan!.innerHTML = 'No change selected'; return; } - const topic = this._generateRandomCherryPickTopic(changes[0]); + const topic = this.generateRandomCherryPickTopic(changes[0]); changes.forEach(change => { this.updateStatus(change, {status: ProgressStatus.RUNNING}); const payload = { @@ -331,7 +567,7 @@ export class GrConfirmCherrypickDialog extends PolymerElement { allow_empty: true, }; const handleError = (response?: Response | null) => { - this._handleCherryPickFailed(change, response); + this.handleCherryPickFailed(change, response); }; // revisions and current_revision must exist hence casting const patchNum = change.revisions![change.current_revision!]._number; @@ -346,7 +582,7 @@ export class GrConfirmCherrypickDialog extends PolymerElement { ) .then(() => { this.updateStatus(change, {status: ProgressStatus.SUCCESSFUL}); - const failedOrPending = Object.values(this._statuses).find( + const failedOrPending = Object.values(this.statuses).find( v => v.status !== ProgressStatus.SUCCESSFUL ); if (!failedOrPending) { @@ -358,12 +594,12 @@ export class GrConfirmCherrypickDialog extends PolymerElement { }); } - _handleConfirmTap(e: Event) { + private handleConfirmTap(e: Event) { e.preventDefault(); e.stopPropagation(); - if (this._cherryPickType === CherryPickType.TOPIC) { + if (this.cherryPickType === CherryPickType.TOPIC) { this.reporting.reportInteraction('cherry-pick-topic-clicked', {}); - this._handleCherryPickTopic(); + this.handleCherryPickTopic(); return; } // Cherry pick single change @@ -375,7 +611,7 @@ export class GrConfirmCherrypickDialog extends PolymerElement { ); } - _handleCancelTap(e: Event) { + private handleCancelTap(e: Event) { e.preventDefault(); e.stopPropagation(); this.dispatchEvent( @@ -387,10 +623,12 @@ export class GrConfirmCherrypickDialog extends PolymerElement { } resetFocus() { - this.$.branchInput.focus(); + this.branchInput.focus(); } - _getProjectBranchesSuggestions(input: string) { + async getProjectBranchesSuggestions( + input: string + ): Promise<AutocompleteSuggestion[]> { if (!this.project) return Promise.reject(new Error('Missing project')); if (input.startsWith('refs/heads/')) { input = input.substring('refs/heads/'.length); diff --git a/polygerrit-ui/app/elements/change/gr-confirm-cherrypick-dialog/gr-confirm-cherrypick-dialog_html.ts b/polygerrit-ui/app/elements/change/gr-confirm-cherrypick-dialog/gr-confirm-cherrypick-dialog_html.ts deleted file mode 100644 index d42f7e51f4..0000000000 --- a/polygerrit-ui/app/elements/change/gr-confirm-cherrypick-dialog/gr-confirm-cherrypick-dialog_html.ts +++ /dev/null @@ -1,223 +0,0 @@ -/** - * @license - * Copyright (C) 2020 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -import {html} from '@polymer/polymer/lib/utils/html-tag'; - -export const htmlTemplate = html` - <style include="shared-styles"> - :host { - display: block; - } - :host([disabled]) { - opacity: 0.5; - pointer-events: none; - } - label { - cursor: pointer; - } - .main { - display: flex; - flex-direction: column; - width: 100%; - } - .main label, - .main input[type='text'] { - display: block; - width: 100%; - } - iron-autogrow-textarea { - font-family: var(--monospace-font-family); - font-size: var(--font-size-mono); - line-height: var(--line-height-mono); - width: 73ch; /* Add a char to account for the border. */ - } - .cherryPickTopicLayout { - display: flex; - align-items: center; - margin-bottom: var(--spacing-m); - } - .cherryPickSingleChange, - .cherryPickTopic { - margin-left: var(--spacing-m); - } - .cherry-pick-topic-message { - margin-bottom: var(--spacing-m); - } - label[for='messageInput'], - label[for='baseInput'] { - margin-top: var(--spacing-m); - } - .title { - font-weight: var(--font-weight-bold); - } - tr > td { - padding: var(--spacing-m); - } - th { - color: var(--deemphasized-text-color); - } - table { - border-collapse: collapse; - } - tr { - border-bottom: 1px solid var(--border-color); - } - .error { - color: var(--error-text-color); - } - .error-message { - color: var(--error-text-color); - margin: var(--spacing-m) 0 var(--spacing-m) 0; - } - </style> - <gr-dialog - confirm-label="Cherry Pick" - cancel-label="[[_computeCancelLabel(_statuses)]]" - disabled$="[[_computeDisableCherryPick(_cherryPickType, _duplicateProjectChanges, _statuses, branch)]]" - on-confirm="_handleConfirmTap" - on-cancel="_handleCancelTap" - > - <div class="header title" slot="header"> - Cherry Pick Change to Another Branch - </div> - <div class="main" slot="main"> - <template is="dom-if" if="[[_showCherryPickTopic]]"> - <div class="cherryPickTopicLayout"> - <input - name="cherryPickOptions" - type="radio" - id="cherryPickSingleChange" - on-change="_handlecherryPickSingleChangeClicked" - checked="" - /> - <label for="cherryPickSingleChange" class="cherryPickSingleChange"> - Cherry Pick single change - </label> - </div> - <div class="cherryPickTopicLayout"> - <input - name="cherryPickOptions" - type="radio" - id="cherryPickTopic" - on-change="_handlecherryPickTopicClicked" - /> - <label for="cherryPickTopic" class="cherryPickTopic"> - Cherry Pick entire topic ([[_changesCount]] Changes) - </label> - </div></template - > - - <label for="branchInput"> Cherry Pick to branch </label> - <gr-autocomplete - id="branchInput" - text="{{branch}}" - query="[[_query]]" - placeholder="Destination branch" - > - </gr-autocomplete> - <template is="dom-if" if="[[_invalidBranch]]"> - <span class="error"> Branch name cannot contain space or commas. </span> - </template> - <template - is="dom-if" - if="[[_computeIfSinglecherryPick(_cherryPickType)]]" - > - <label for="baseInput"> - Provide base commit sha1 for cherry-pick - </label> - <iron-input - maxlength="40" - placeholder="(optional)" - bind-value="{{baseCommit}}" - > - <input - is="iron-input" - id="baseCommitInput" - maxlength="40" - placeholder="(optional)" - bind-value="{{baseCommit}}" - /> - </iron-input> - <label for="messageInput"> Cherry Pick Commit Message </label> - </template> - <template - is="dom-if" - if="[[_computeIfSinglecherryPick(_cherryPickType)]]" - > - <iron-autogrow-textarea - id="messageInput" - class="message" - autocomplete="on" - rows="4" - max-rows="15" - bind-value="{{message}}" - ></iron-autogrow-textarea> - </template> - <template is="dom-if" if="[[_computeIfCherryPickTopic(_cherryPickType)]]"> - <span class="error-message" - >[[_computeTopicErrorMessage(_duplicateProjectChanges)]]</span - > - <span class="cherry-pick-topic-message"> - Commit Message will be auto generated - </span> - <table> - <thead> - <tr> - <th></th> - <th>Change</th> - <th>Status</th> - <th>Subject</th> - <th>Project</th> - <th>Progress</th> - <!-- Error Message --> - <th></th> - </tr> - </thead> - <tbody> - <template is="dom-repeat" items="[[changes]]"> - <tr> - <td> - <input - type="checkbox" - data-item$="[[item.id]]" - on-change="_toggleChangeSelected" - checked="[[_isChangeSelected(item.id)]]" - /> - </td> - <td><span> [[_getChangeId(item)]] </span></td> - <td><span> [[item.status]] </span></td> - <td> - <span> [[_getTrimmedChangeSubject(item.subject)]] </span> - </td> - <td><span> [[item.project]] </span></td> - <td> - <span class$="[[_computeStatusClass(item, _statuses)]]"> - [[_computeStatus(item, _statuses)]] - </span> - </td> - <td> - <span class="error"> - [[_computeError(item, _statuses)]] - </span> - </td> - </tr> - </template> - </tbody> - </table> - </template> - </div> - </gr-dialog> -`; diff --git a/polygerrit-ui/app/elements/change/gr-confirm-cherrypick-dialog/gr-confirm-cherrypick-dialog_test.ts b/polygerrit-ui/app/elements/change/gr-confirm-cherrypick-dialog/gr-confirm-cherrypick-dialog_test.ts index 18a4feab3c..45e13b2628 100644 --- a/polygerrit-ui/app/elements/change/gr-confirm-cherrypick-dialog/gr-confirm-cherrypick-dialog_test.ts +++ b/polygerrit-ui/app/elements/change/gr-confirm-cherrypick-dialog/gr-confirm-cherrypick-dialog_test.ts @@ -36,8 +36,7 @@ import {createChange, createRevision} from '../../../test/test-data-generators'; import {GrDialog} from '../../shared/gr-dialog/gr-dialog.js'; import * as MockInteractions from '@polymer/iron-test-helpers/mock-interactions'; import {ProgressStatus} from '../../../constants/constants'; - -const basicFixture = fixtureFromElement('gr-confirm-cherrypick-dialog'); +import {fixture, html} from '@open-wc/testing-helpers'; const CHERRY_PICK_TYPES = { SINGLE_CHANGE: 1, @@ -46,7 +45,7 @@ const CHERRY_PICK_TYPES = { suite('gr-confirm-cherrypick-dialog tests', () => { let element: GrConfirmCherrypickDialog; - setup(() => { + setup(async () => { stubRestApi('getRepoBranches').callsFake(input => { if (input.startsWith('test')) { return Promise.resolve([ @@ -60,53 +59,59 @@ suite('gr-confirm-cherrypick-dialog tests', () => { return Promise.resolve([]); } }); - element = basicFixture.instantiate(); + element = await fixture( + html`<gr-confirm-cherrypick-dialog></gr-confirm-cherrypick-dialog>` + ); element.project = 'test-project' as RepoName; }); - test('with message missing newline', () => { + test('with message missing newline', async () => { element.changeStatus = ChangeStatus.MERGED; element.commitMessage = 'message'; element.commitNum = '123' as CommitId; element.branch = 'master' as BranchName; - flush(); + await element.updateComplete; const expectedMessage = 'message\n(cherry picked from commit 123)'; assert.equal(element.message, expectedMessage); }); - test('with merged change', () => { + test('with merged change', async () => { element.changeStatus = ChangeStatus.MERGED; element.commitMessage = 'message\n'; element.commitNum = '123' as CommitId; element.branch = 'master' as BranchName; - flush(); + await element.updateComplete; const expectedMessage = 'message\n(cherry picked from commit 123)'; assert.equal(element.message, expectedMessage); }); - test('with unmerged change', () => { + test('with unmerged change', async () => { element.changeStatus = ChangeStatus.NEW; element.commitMessage = 'message\n'; element.commitNum = '123' as CommitId; element.branch = 'master' as BranchName; - flush(); + await element.updateComplete; + const expectedMessage = 'message\n'; assert.equal(element.message, expectedMessage); }); - test('with updated commit message', () => { + test('with updated commit message', async () => { element.changeStatus = ChangeStatus.NEW; element.commitMessage = 'message\n'; element.commitNum = '123' as CommitId; element.branch = 'master' as BranchName; + await element.updateComplete; + const myNewMessage = 'updated commit message'; element.message = myNewMessage; - flush(); + await element.updateComplete; + assert.equal(element.message, myNewMessage); }); - test('_getProjectBranchesSuggestions empty', async () => { - const branches = await element._getProjectBranchesSuggestions('asdf'); + test('getProjectBranchesSuggestions empty', async () => { + const branches = await element.getProjectBranchesSuggestions('asdf'); assert.isEmpty(branches); }); @@ -141,20 +146,18 @@ suite('gr-confirm-cherrypick-dialog tests', () => { ]; setup(async () => { element.updateChanges(changes); - element._cherryPickType = CHERRY_PICK_TYPES.TOPIC; - await flush(); + element.cherryPickType = CHERRY_PICK_TYPES.TOPIC; + await element.updateComplete; }); test('cherry pick topic submit', async () => { element.branch = 'master' as BranchName; - await flush(); + await element.updateComplete; const executeChangeActionStub = stubRestApi( 'executeChangeAction' ).returns(Promise.resolve(new Response())); - MockInteractions.tap( - queryAndAssert<GrDialog>(element, 'gr-dialog').confirmButton! - ); - await flush(); + queryAndAssert<GrDialog>(element, 'gr-dialog').confirmButton!.click(); + await element.updateComplete; const args = executeChangeActionStub.args[0]; assert.equal(args[0], 1); assert.equal(args[1], 'POST' as HttpMethod); @@ -170,7 +173,7 @@ suite('gr-confirm-cherrypick-dialog tests', () => { 'containsDuplicateProject' ); element.branch = 'master' as BranchName; - await flush(); + await element.updateComplete; const executeChangeActionStub = stubRestApi( 'executeChangeAction' ).returns(Promise.resolve(new Response())); @@ -181,17 +184,15 @@ suite('gr-confirm-cherrypick-dialog tests', () => { assert.equal(checkboxes.length, 2); assert.isTrue(checkboxes[0].checked); MockInteractions.tap(checkboxes[0]); - MockInteractions.tap( - queryAndAssert<GrDialog>(element, 'gr-dialog').confirmButton! - ); - await flush(); + queryAndAssert<GrDialog>(element, 'gr-dialog').confirmButton!.click(); + await element.updateComplete; assert.equal(executeChangeActionStub.callCount, 1); assert.isTrue(duplicateChangesStub.called); }); test('deselecting all change shows error message', async () => { element.branch = 'master' as BranchName; - await flush(); + await element.updateComplete; const executeChangeActionStub = stubRestApi( 'executeChangeAction' ).returns(Promise.resolve(new Response())); @@ -205,7 +206,7 @@ suite('gr-confirm-cherrypick-dialog tests', () => { MockInteractions.tap( queryAndAssert<GrDialog>(element, 'gr-dialog').confirmButton! ); - await flush(); + await element.updateComplete; assert.equal(executeChangeActionStub.callCount, 0); assert.equal( queryAndAssert<HTMLElement>(element, '.error-message').innerText, @@ -213,16 +214,16 @@ suite('gr-confirm-cherrypick-dialog tests', () => { ); }); - test('_computeStatusClass', () => { + test('computeStatusClass', async () => { assert.equal( - element._computeStatusClass( + element.computeStatusClass( {...createChange(), id: '1' as ChangeInfoId}, {1: {status: ProgressStatus.RUNNING}} ), '' ); assert.equal( - element._computeStatusClass( + element.computeStatusClass( {...createChange(), id: '1' as ChangeInfoId}, {1: {status: ProgressStatus.FAILED}} ), @@ -237,24 +238,24 @@ suite('gr-confirm-cherrypick-dialog tests', () => { ).confirmButton; assert.isTrue(confirmButton!.hasAttribute('disabled')); element.branch = 'b' as BranchName; - await flush(); + await element.updateComplete; assert.isFalse(confirmButton!.hasAttribute('disabled')); element.updateStatus(changes[0], {status: ProgressStatus.RUNNING}); - await flush(); + await element.updateComplete; assert.isTrue(confirmButton!.hasAttribute('disabled')); }); }); - test('resetFocus', () => { - const focusStub = sinon.stub(element.$.branchInput, 'focus'); + test('resetFocus', async () => { + const focusStub = sinon.stub(element.branchInput, 'focus'); element.resetFocus(); + await element.updateComplete; + assert.isTrue(focusStub.called); }); - test('_getProjectBranchesSuggestions non-empty', async () => { - const branches = await element._getProjectBranchesSuggestions( - 'test-branch' - ); + test('getProjectBranchesSuggestions non-empty', async () => { + const branches = await element.getProjectBranchesSuggestions('test-branch'); assert.equal(branches.length, 1); assert.equal(branches[0].name, 'test-branch'); }); |