blob: b89720e50ee5f706d2b8566697994a67877fe827 [file] [log] [blame]
// Copyright 2019 The Chromium Authors
// 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 {MrEditMetadata} from './mr-edit-metadata.js';
import {ISSUE_EDIT_PERMISSION, ISSUE_EDIT_SUMMARY_PERMISSION,
ISSUE_EDIT_STATUS_PERMISSION, ISSUE_EDIT_OWNER_PERMISSION,
ISSUE_EDIT_CC_PERMISSION,
} from 'shared/consts/permissions.js';
import {FIELD_DEF_VALUE_EDIT} from 'reducers/permissions.js';
import {store, resetState} from 'reducers/base.js';
import {enterInput} from 'shared/test/helpers.js';
let element;
xdescribe('mr-edit-metadata', () => {
beforeEach(() => {
store.dispatch(resetState());
element = document.createElement('mr-edit-metadata');
document.body.appendChild(element);
element.issuePermissions = [ISSUE_EDIT_PERMISSION];
sinon.stub(store, 'dispatch');
});
afterEach(() => {
document.body.removeChild(element);
store.dispatch.restore();
});
it('initializes', () => {
assert.instanceOf(element, MrEditMetadata);
});
describe('updated sets initial values', () => {
it('updates owner', async () => {
element.ownerName = 'goose@bird.org';
await element.updateComplete;
assert.equal(element._values.owner, 'goose@bird.org');
});
it('updates cc', async () => {
element.cc = [
{displayName: 'initial-cc@bird.org', userId: '1234'},
];
await element.updateComplete;
assert.deepEqual(element._values.cc, ['initial-cc@bird.org']);
});
it('updates components', async () => {
element.components = [{path: 'Hello>World'}];
await element.updateComplete;
assert.deepEqual(element._values.components, ['Hello>World']);
});
it('updates labels', async () => {
element.labelNames = ['test-label'];
await element.updateComplete;
assert.deepEqual(element._values.labels, ['test-label']);
});
});
describe('saves edit form', () => {
let saveStub;
beforeEach(() => {
saveStub = sinon.stub();
element.addEventListener('save', saveStub);
});
it('saves on form submit', async () => {
await element.updateComplete;
element.querySelector('#editForm').dispatchEvent(
new Event('submit', {bubbles: true, cancelable: true}));
sinon.assert.calledOnce(saveStub);
});
it('saves when clicking the save button', async () => {
await element.updateComplete;
element.querySelector('.save-changes').click();
sinon.assert.calledOnce(saveStub);
});
it('does not save on random keydowns', async () => {
await element.updateComplete;
element.querySelector('#editForm').dispatchEvent(
new KeyboardEvent('keydown', {key: 'a', ctrlKey: true}));
element.querySelector('#editForm').dispatchEvent(
new KeyboardEvent('keydown', {key: 'b', ctrlKey: false}));
element.querySelector('#editForm').dispatchEvent(
new KeyboardEvent('keydown', {key: 'c', metaKey: true}));
sinon.assert.notCalled(saveStub);
});
it('does not save on Enter without Ctrl', async () => {
await element.updateComplete;
element.querySelector('#editForm').dispatchEvent(
new KeyboardEvent('keydown', {key: 'Enter', ctrlKey: false}));
sinon.assert.notCalled(saveStub);
});
it('saves on Ctrl+Enter', async () => {
await element.updateComplete;
element.querySelector('#editForm').dispatchEvent(
new KeyboardEvent('keydown', {key: 'Enter', ctrlKey: true}));
sinon.assert.calledOnce(saveStub);
});
it('saves on Ctrl+Meta', async () => {
await element.updateComplete;
element.querySelector('#editForm').dispatchEvent(
new KeyboardEvent('keydown', {key: 'Enter', metaKey: true}));
sinon.assert.calledOnce(saveStub);
});
});
it('disconnecting element reports form is not dirty', () => {
element.formName = 'test';
assert.isFalse(store.dispatch.calledOnce);
document.body.removeChild(element);
assert.isTrue(store.dispatch.calledOnce);
sinon.assert.calledWith(
store.dispatch,
{
type: 'REPORT_DIRTY_FORM',
name: 'test',
isDirty: false,
},
);
document.body.appendChild(element);
});
it('_processChanges fires change event', async () => {
await element.updateComplete;
const changeStub = sinon.stub();
element.addEventListener('change', changeStub);
element._processChanges();
sinon.assert.calledOnce(changeStub);
});
it('save button disabled when disabled is true', async () => {
// Check that save button is initially disabled.
await element.updateComplete;
const button = element.querySelector('.save-changes');
assert.isTrue(element.disabled);
assert.isTrue(button.disabled);
element.isDirty = true;
await element.updateComplete;
assert.isFalse(element.disabled);
assert.isFalse(button.disabled);
});
it('editing form sets isDirty to true or false', async () => {
await element.updateComplete;
assert.isFalse(element.isDirty);
// User makes some changes.
const comment = element.querySelector('#commentText');
comment.value = 'Value';
comment.dispatchEvent(new Event('keyup'));
assert.isTrue(element.isDirty);
// User undoes the changes.
comment.value = '';
comment.dispatchEvent(new Event('keyup'));
assert.isFalse(element.isDirty);
});
it('reseting form disables save button', async () => {
// Check that save button is initially disabled.
assert.isTrue(element.disabled);
// User makes some changes.
element.isDirty = true;
// Check that save button is not disabled.
assert.isFalse(element.disabled);
// Reset form.
await element.updateComplete;
await element.reset();
// Check that save button is still disabled.
assert.isTrue(element.disabled);
});
it('save button is enabled if request fails', async () => {
// Check that save button is initially disabled.
assert.isTrue(element.disabled);
// User makes some changes.
element.isDirty = true;
// Check that save button is not disabled.
assert.isFalse(element.disabled);
// User submits the change.
element.saving = true;
// Check that save button is disabled.
assert.isTrue(element.disabled);
// Request fails.
element.saving = false;
element.error = 'error';
// Check that save button is re-enabled.
assert.isFalse(element.disabled);
});
it('delta empty when no changes', async () => {
await element.updateComplete;
assert.deepEqual(element.delta, {});
});
it('toggling checkbox toggles sendEmail', async () => {
element.sendEmail = false;
await element.updateComplete;
const checkbox = element.querySelector('#sendEmail');
await checkbox.updateComplete;
checkbox.click();
await element.updateComplete;
assert.equal(checkbox.checked, true);
assert.equal(element.sendEmail, true);
checkbox.click();
await element.updateComplete;
assert.equal(checkbox.checked, false);
assert.equal(element.sendEmail, false);
checkbox.click();
await element.updateComplete;
assert.equal(checkbox.checked, true);
assert.equal(element.sendEmail, true);
});
it('changing status produces delta change (lit-element)', async () => {
element.statuses = [
{'status': 'New'},
{'status': 'Old'},
{'status': 'Test'},
];
element.status = 'New';
await element.updateComplete;
const statusComponent = element.querySelector('#statusInput');
statusComponent.status = 'Old';
await element.updateComplete;
assert.deepEqual(element.delta, {
status: 'Old',
});
});
it('changing owner produces delta change (React)', async () => {
element.ownerName = 'initial-owner@bird.org';
await element.updateComplete;
const input = element.querySelector('#ownerInput');
enterInput(input, 'new-owner@bird.org');
await element.updateComplete;
const expected = {ownerRef: {displayName: 'new-owner@bird.org'}};
assert.deepEqual(element.delta, expected);
});
it('adding CC produces delta change (React)', async () => {
element.cc = [
{displayName: 'initial-cc@bird.org', userId: '1234'},
];
await element.updateComplete;
const input = element.querySelector('#ccInput');
enterInput(input, 'another@bird.org');
await element.updateComplete;
const expected = {
ccRefsAdd: [{displayName: 'another@bird.org'}],
ccRefsRemove: [{displayName: 'initial-cc@bird.org'}],
};
assert.deepEqual(element.delta, expected);
});
it('invalid status throws', async () => {
element.statuses = [
{'status': 'New'},
{'status': 'Old'},
{'status': 'Duplicate'},
];
element.status = 'Duplicate';
await element.updateComplete;
const statusComponent = element.querySelector('#statusInput');
statusComponent.shadowRoot.querySelector('#mergedIntoInput').value = 'xx';
assert.deepEqual(element.delta, {});
assert.equal(
element.error,
'Invalid issue ref: xx. Expected [projectName:]issueId.');
});
it('cannot block an issue on itself', async () => {
element.projectName = 'proj';
element.issueRef = {projectName: 'proj', localId: 123};
await element.updateComplete;
for (const fieldName of ['blockedOn', 'blocking']) {
const input =
element.querySelector(`#${fieldName}Input`);
enterInput(input, '123');
await element.updateComplete;
assert.deepEqual(element.delta, {});
assert.equal(
element.error,
`Invalid issue ref: 123. Cannot merge or block an issue on itself.`);
fireEvent.keyDown(input, {key: 'Backspace', code: 'Backspace'});
await element.updateComplete;
enterInput(input, 'proj:123');
await element.updateComplete;
assert.deepEqual(element.delta, {});
assert.equal(
element.error,
`Invalid issue ref: proj:123. ` +
'Cannot merge or block an issue on itself.');
fireEvent.keyDown(input, {key: 'Backspace', code: 'Backspace'});
await element.updateComplete;
enterInput(input, 'proj2:123');
await element.updateComplete;
assert.notDeepEqual(element.delta, {});
assert.equal(element.error, '');
fireEvent.keyDown(input, {key: 'Backspace', code: 'Backspace'});
await element.updateComplete;
}
});
it('cannot merge an issue into itself', async () => {
element.statuses = [
{'status': 'New'},
{'status': 'Duplicate'},
];
element.status = 'New';
element.projectName = 'proj';
element.issueRef = {projectName: 'proj', localId: 123};
await element.updateComplete;
const statusComponent = element.querySelector('#statusInput');
const root = statusComponent.shadowRoot;
const statusInput = root.querySelector('#statusInput');
statusInput.value = 'Duplicate';
statusInput.dispatchEvent(new Event('change'));
await element.updateComplete;
root.querySelector('#mergedIntoInput').value = 'proj:123';
assert.deepEqual(element.delta, {});
assert.equal(
element.error,
`Invalid issue ref: proj:123. Cannot merge or block an issue on itself.`);
root.querySelector('#mergedIntoInput').value = '123';
assert.deepEqual(element.delta, {});
assert.equal(
element.error,
`Invalid issue ref: 123. Cannot merge or block an issue on itself.`);
root.querySelector('#mergedIntoInput').value = 'proj2:123';
assert.notDeepEqual(element.delta, {});
assert.equal(element.error, '');
});
it('cannot set invalid emails', async () => {
await element.updateComplete;
const ccInput = element.querySelector('#ccInput');
enterInput(ccInput, 'invalid!email');
await element.updateComplete;
assert.deepEqual(element.delta, {});
assert.equal(
element.error,
`Invalid email address: invalid!email`);
const input = element.querySelector('#ownerInput');
enterInput(input, 'invalid!email2');
await element.updateComplete;
assert.deepEqual(element.delta, {});
assert.equal(
element.error,
`Invalid email address: invalid!email2`);
});
it('can remove invalid values', async () => {
element.projectName = 'proj';
element.issueRef = {projectName: 'proj', localId: 123};
element.statuses = [
{'status': 'Duplicate'},
];
element.status = 'Duplicate';
element.mergedInto = element.issueRef;
element.blockedOn = [element.issueRef];
element.blocking = [element.issueRef];
await element.updateComplete;
const blockedOnInput = element.querySelector('#blockedOnInput');
const blockingInput = element.querySelector('#blockingInput');
const statusInput = element.querySelector('#statusInput');
await element.updateComplete;
const mergedIntoInput =
statusInput.shadowRoot.querySelector('#mergedIntoInput');
fireEvent.keyDown(blockedOnInput, {key: 'Backspace', code: 'Backspace'});
await element.updateComplete;
fireEvent.keyDown(blockingInput, {key: 'Backspace', code: 'Backspace'});
await element.updateComplete;
mergedIntoInput.value = 'proj:124';
await element.updateComplete;
assert.deepEqual(
element.delta,
{
blockedOnRefsRemove: [{projectName: 'proj', localId: 123}],
blockingRefsRemove: [{projectName: 'proj', localId: 123}],
mergedIntoRef: {projectName: 'proj', localId: 124},
});
assert.equal(element.error, '');
});
it('not changing status produces no delta', async () => {
element.statuses = [
{'status': 'Duplicate'},
];
element.status = 'Duplicate';
element.mergedInto = {
projectName: 'chromium',
localId: 1234,
};
element.projectName = 'chromium';
await element.updateComplete;
await element.updateComplete; // Merged input updates its value.
assert.deepEqual(element.delta, {});
});
it('changing status to duplicate produces delta change', async () => {
element.statuses = [
{'status': 'New'},
{'status': 'Duplicate'},
];
element.status = 'New';
await element.updateComplete;
const statusComponent = element.querySelector(
'#statusInput');
const root = statusComponent.shadowRoot;
const statusInput = root.querySelector('#statusInput');
statusInput.value = 'Duplicate';
statusInput.dispatchEvent(new Event('change'));
await element.updateComplete;
root.querySelector('#mergedIntoInput').value = 'chromium:1234';
assert.deepEqual(element.delta, {
status: 'Duplicate',
mergedIntoRef: {
projectName: 'chromium',
localId: 1234,
},
});
});
it('changing summary produces delta change', async () => {
element.summary = 'Old summary';
await element.updateComplete;
element.querySelector(
'#summaryInput').value = 'newfangled fancy summary';
assert.deepEqual(element.delta, {
summary: 'newfangled fancy summary',
});
});
it('custom fields the user cannot edit should be hidden', async () => {
element.projectName = 'proj';
const fieldName = 'projects/proj/fieldDefs/1';
const restrictedFieldName = 'projects/proj/fieldDefs/2';
element._permissions = {
[fieldName]: {permissions: [FIELD_DEF_VALUE_EDIT]},
[restrictedFieldName]: {permissions: []}};
element.fieldDefs = [
{
fieldRef: {
fieldName: 'normalFd',
fieldId: 1,
type: 'ENUM_TYPE',
},
},
{
fieldRef: {
fieldName: 'cantEditFd',
fieldId: 2,
type: 'ENUM_TYPE',
},
},
];
await element.updateComplete;
assert.isFalse(element.querySelector('#normalFdInput').hidden);
assert.isTrue(element.querySelector('#cantEditFdInput').hidden);
});
it('changing enum custom fields produces delta', async () => {
element.fieldValueMap = new Map([['fakefield', ['prev value']]]);
element.fieldDefs = [
{
fieldRef: {
fieldName: 'testField',
fieldId: 1,
type: 'ENUM_TYPE',
},
},
{
fieldRef: {
fieldName: 'fakeField',
fieldId: 2,
type: 'ENUM_TYPE',
},
},
];
await element.updateComplete;
const input1 = element.querySelector('#testFieldInput');
const input2 = element.querySelector('#fakeFieldInput');
input1.values = ['test value'];
input2.values = [];
await element.updateComplete;
assert.deepEqual(element.delta, {
fieldValsAdd: [
{
fieldRef: {
fieldName: 'testField',
fieldId: 1,
type: 'ENUM_TYPE',
},
value: 'test value',
},
],
fieldValsRemove: [
{
fieldRef: {
fieldName: 'fakeField',
fieldId: 2,
type: 'ENUM_TYPE',
},
value: 'prev value',
},
],
});
});
it('changing approvers produces delta', async () => {
element.isApproval = true;
element.hasApproverPrivileges = true;
element.approvers = [
{displayName: 'foo@example.com', userId: '1'},
{displayName: 'bar@example.com', userId: '2'},
{displayName: 'baz@example.com', userId: '3'},
];
await element.updateComplete;
await element.updateComplete;
element.querySelector('#approversInput').values =
['chicken@example.com', 'foo@example.com', 'dog@example.com'];
await element.updateComplete;
assert.deepEqual(element.delta, {
approverRefsAdd: [
{displayName: 'chicken@example.com'},
{displayName: 'dog@example.com'},
],
approverRefsRemove: [
{displayName: 'bar@example.com'},
{displayName: 'baz@example.com'},
],
});
});
it('changing blockedon produces delta change (React)', async () => {
element.blockedOn = [
{projectName: 'chromium', localId: '1234'},
{projectName: 'monorail', localId: '4567'},
];
element.projectName = 'chromium';
await element.updateComplete;
await element.updateComplete;
const input = element.querySelector('#blockedOnInput');
fireEvent.keyDown(input, {key: 'Backspace', code: 'Backspace'});
await element.updateComplete;
enterInput(input, 'v8:5678');
await element.updateComplete;
assert.deepEqual(element.delta, {
blockedOnRefsAdd: [{
projectName: 'v8',
localId: 5678,
}],
blockedOnRefsRemove: [{
projectName: 'monorail',
localId: 4567,
}],
});
});
it('_optionsForField computes options', () => {
const optionsPerEnumField = new Map([
['enumfield', [{optionName: 'one'}, {optionName: 'two'}]],
]);
assert.deepEqual(
element._optionsForField(optionsPerEnumField, new Map(), 'enumField'), [
{
optionName: 'one',
},
{
optionName: 'two',
},
]);
});
it('changing enum fields produces delta', async () => {
element.fieldDefs = [
{
fieldRef: {
fieldName: 'enumField',
fieldId: 1,
type: 'ENUM_TYPE',
},
isMultivalued: true,
},
];
element.optionsPerEnumField = new Map([
['enumfield', [{optionName: 'one'}, {optionName: 'two'}]],
]);
await element.updateComplete;
await element.updateComplete;
element.querySelector(
'#enumFieldInput').values = ['one', 'two'];
await element.updateComplete;
assert.deepEqual(element.delta, {
fieldValsAdd: [
{
fieldRef: {
fieldName: 'enumField',
fieldId: 1,
type: 'ENUM_TYPE',
},
value: 'one',
},
{
fieldRef: {
fieldName: 'enumField',
fieldId: 1,
type: 'ENUM_TYPE',
},
value: 'two',
},
],
});
});
it('changing multiple single valued enum fields', async () => {
element.fieldDefs = [
{
fieldRef: {
fieldName: 'enumField',
fieldId: 1,
type: 'ENUM_TYPE',
},
},
{
fieldRef: {
fieldName: 'enumField2',
fieldId: 2,
type: 'ENUM_TYPE',
},
},
];
element.optionsPerEnumField = new Map([
['enumfield', [{optionName: 'one'}, {optionName: 'two'}]],
['enumfield2', [{optionName: 'three'}, {optionName: 'four'}]],
]);
await element.updateComplete;
element.querySelector('#enumFieldInput').values = ['two'];
element.querySelector('#enumField2Input').values = ['three'];
await element.updateComplete;
assert.deepEqual(element.delta, {
fieldValsAdd: [
{
fieldRef: {
fieldName: 'enumField',
fieldId: 1,
type: 'ENUM_TYPE',
},
value: 'two',
},
{
fieldRef: {
fieldName: 'enumField2',
fieldId: 2,
type: 'ENUM_TYPE',
},
value: 'three',
},
],
});
});
it('adding components produces delta', async () => {
await element.updateComplete;
element.isApproval = false;
element.issuePermissions = [ISSUE_EDIT_PERMISSION];
element.components = [];
await element.updateComplete;
element._values.components = ['Hello>World'];
await element.updateComplete;
assert.deepEqual(element.delta, {
compRefsAdd: [
{path: 'Hello>World'},
],
});
element._values.components = ['Hello>World', 'Test', 'Multi'];
await element.updateComplete;
assert.deepEqual(element.delta, {
compRefsAdd: [
{path: 'Hello>World'},
{path: 'Test'},
{path: 'Multi'},
],
});
element._values.components = [];
await element.updateComplete;
assert.deepEqual(element.delta, {});
});
it('removing components produces delta', async () => {
await element.updateComplete;
element.isApproval = false;
element.issuePermissions = [ISSUE_EDIT_PERMISSION];
element.components = [{path: 'Hello>World'}];
await element.updateComplete;
element._values.components = [];
await element.updateComplete;
assert.deepEqual(element.delta, {
compRefsRemove: [
{path: 'Hello>World'},
],
});
});
it('approver input appears when user has privileges', async () => {
assert.isNull(element.querySelector('#approversInput'));
element.isApproval = true;
element.hasApproverPrivileges = true;
await element.updateComplete;
assert.isNotNull(element.querySelector('#approversInput'));
});
it('reset sets controlled values to default', async () => {
element.ownerName = 'burb@bird.com';
element.cc = [
{displayName: 'flamingo@bird.com', userId: '1234'},
{displayName: 'penguin@bird.com', userId: '5678'},
];
element.components = [{path: 'Bird>Penguin'}];
element.labelNames = ['chickadee-chirp'];
element.blockedOn = [{localId: 1234, projectName: 'project'}];
element.blocking = [{localId: 5678, projectName: 'other-project'}];
element.projectName = 'project';
// Update cycle is needed because <mr-edit-metadata> initializes
// this.values in updated().
await element.updateComplete;
const initialValues = {
owner: 'burb@bird.com',
cc: ['flamingo@bird.com', 'penguin@bird.com'],
components: ['Bird>Penguin'],
labels: ['chickadee-chirp'],
blockedOn: ['1234'],
blocking: ['other-project:5678'],
};
assert.deepEqual(element._values, initialValues);
element._values = {
owner: 'newburb@hello.com',
cc: ['noburbs@wings.com'],
};
element.reset();
assert.deepEqual(element._values, initialValues);
})
it('reset empties form values', async () => {
element.fieldDefs = [
{
fieldRef: {
fieldName: 'testField',
fieldId: 1,
type: 'ENUM_TYPE',
},
},
{
fieldRef: {
fieldName: 'fakeField',
fieldId: 2,
type: 'ENUM_TYPE',
},
},
];
await element.updateComplete;
const uploader = element.querySelector('mr-upload');
uploader.files = [
{name: 'test.png'},
{name: 'rutabaga.png'},
];
element.querySelector('#testFieldInput').values = 'testy test';
element.querySelector('#fakeFieldInput').values = 'hello world';
await element.reset();
assert.lengthOf(element.querySelector('#testFieldInput').value, 0);
assert.lengthOf(element.querySelector('#fakeFieldInput').value, 0);
assert.lengthOf(uploader.files, 0);
});
it('reset results in empty delta', async () => {
element.ownerName = 'goose@bird.org';
await element.updateComplete;
element._values.owner = 'penguin@bird.org';
const expected = {ownerRef: {displayName: 'penguin@bird.org'}};
assert.deepEqual(element.delta, expected);
await element.reset();
assert.deepEqual(element.delta, {});
});
it('edit issue permissions', async () => {
const allFields = ['summary', 'status', 'owner', 'cc'];
const testCases = [
{permissions: [], nonNull: []},
{permissions: [ISSUE_EDIT_PERMISSION], nonNull: allFields},
{permissions: [ISSUE_EDIT_SUMMARY_PERMISSION], nonNull: ['summary']},
{permissions: [ISSUE_EDIT_STATUS_PERMISSION], nonNull: ['status']},
{permissions: [ISSUE_EDIT_OWNER_PERMISSION], nonNull: ['owner']},
{permissions: [ISSUE_EDIT_CC_PERMISSION], nonNull: ['cc']},
];
element.statuses = [{'status': 'Foo'}];
for (const testCase of testCases) {
element.issuePermissions = testCase.permissions;
await element.updateComplete;
allFields.forEach((fieldName) => {
const field = element.querySelector(`#${fieldName}Input`);
if (testCase.nonNull.includes(fieldName)) {
assert.isNotNull(field);
} else {
assert.isNull(field);
}
});
}
});
it('duplicate issue is rendered correctly', async () => {
element.statuses = [
{'status': 'Duplicate'},
];
element.status = 'Duplicate';
element.projectName = 'chromium';
element.mergedInto = {
projectName: 'chromium',
localId: 1234,
};
await element.updateComplete;
await element.updateComplete;
const statusComponent = element.querySelector('#statusInput');
const root = statusComponent.shadowRoot;
assert.equal(
root.querySelector('#mergedIntoInput').value, '1234');
});
it('duplicate issue on different project is rendered correctly', async () => {
element.statuses = [
{'status': 'Duplicate'},
];
element.status = 'Duplicate';
element.projectName = 'chromium';
element.mergedInto = {
projectName: 'monorail',
localId: 1234,
};
await element.updateComplete;
await element.updateComplete;
const statusComponent = element.querySelector('#statusInput');
const root = statusComponent.shadowRoot;
assert.equal(
root.querySelector('#mergedIntoInput').value, 'monorail:1234');
});
it('filter out deleted users', async () => {
element.cc = [
{displayName: 'test@example.com', userId: '1234'},
{displayName: 'a_deleted_user'},
{displayName: 'someone@example.com', userId: '5678'},
];
await element.updateComplete;
assert.deepEqual(element._values.cc, [
'test@example.com',
'someone@example.com',
]);
});
it('renders valid markdown description with preview', async () => {
await element.updateComplete;
element.prefs = new Map([['render_markdown', true]]);
element.projectName = 'monkeyrail';
sinon.stub(element, 'getCommentContent').returns('# h1');
await element.updateComplete;
assert.isTrue(element._renderMarkdown);
const previewMarkdown = element.querySelector('.markdown-preview');
assert.isNotNull(previewMarkdown);
const headerText = previewMarkdown.querySelector('h1').textContent;
assert.equal(headerText, 'h1');
});
it('does not show preview when markdown is disabled', async () => {
element.prefs = new Map([['render_markdown', false]]);
element.projectName = 'monkeyrail';
sinon.stub(element, 'getCommentContent').returns('# h1');
await element.updateComplete;
const previewMarkdown = element.querySelector('.markdown-preview');
assert.isNull(previewMarkdown);
});
it('does not show preview when no input', async () => {
element.prefs = new Map([['render_markdown', true]]);
element.projectName = 'monkeyrail';
sinon.stub(element, 'getCommentContent').returns('');
await element.updateComplete;
const previewMarkdown = element.querySelector('.markdown-preview');
assert.isNull(previewMarkdown);
});
});