Clean up Jira rich text in Webex approval card details.
Convert wiki markup to readable text and render each detail field in its own card block. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
parent
d0e1e20843
commit
98dd33a20e
5 changed files with 281 additions and 51 deletions
|
|
@ -55,6 +55,7 @@
|
||||||
{ "fieldId": "customfield_10287", "label": "Change category", "format": "option" },
|
{ "fieldId": "customfield_10287", "label": "Change category", "format": "option" },
|
||||||
{ "fieldId": "customfield_10259", "label": "Impact level", "format": "option" },
|
{ "fieldId": "customfield_10259", "label": "Impact level", "format": "option" },
|
||||||
{ "fieldId": "customfield_10257", "label": "Implementation date", "format": "datetime" },
|
{ "fieldId": "customfield_10257", "label": "Implementation date", "format": "datetime" },
|
||||||
|
{ "fieldId": "description", "label": "Implementation steps", "format": "textarea" },
|
||||||
{ "fieldId": "customfield_10252", "label": "Business justification", "format": "textarea" },
|
{ "fieldId": "customfield_10252", "label": "Business justification", "format": "textarea" },
|
||||||
{ "fieldId": "customfield_10256", "label": "Business impact / risk", "format": "textarea" },
|
{ "fieldId": "customfield_10256", "label": "Business impact / risk", "format": "textarea" },
|
||||||
{ "fieldId": "customfield_10253", "label": "Testing completed", "format": "textarea" },
|
{ "fieldId": "customfield_10253", "label": "Testing completed", "format": "textarea" },
|
||||||
|
|
@ -89,6 +90,7 @@
|
||||||
"includeCommon": true,
|
"includeCommon": true,
|
||||||
"displayFields": [
|
"displayFields": [
|
||||||
{ "fieldId": "customfield_10257", "label": "Production deploy date", "format": "datetime" },
|
{ "fieldId": "customfield_10257", "label": "Production deploy date", "format": "datetime" },
|
||||||
|
{ "fieldId": "description", "label": "Implementation steps", "format": "textarea" },
|
||||||
{ "fieldId": "customfield_10252", "label": "Business justification", "format": "textarea" },
|
{ "fieldId": "customfield_10252", "label": "Business justification", "format": "textarea" },
|
||||||
{ "fieldId": "customfield_10256", "label": "Impacted services", "format": "textarea" },
|
{ "fieldId": "customfield_10256", "label": "Impacted services", "format": "textarea" },
|
||||||
{ "fieldId": "customfield_10253", "label": "Testing completed", "format": "textarea" },
|
{ "fieldId": "customfield_10253", "label": "Testing completed", "format": "textarea" },
|
||||||
|
|
@ -104,6 +106,7 @@
|
||||||
"serviceDeskId": "135",
|
"serviceDeskId": "135",
|
||||||
"includeCommon": true,
|
"includeCommon": true,
|
||||||
"displayFields": [
|
"displayFields": [
|
||||||
|
{ "fieldId": "description", "label": "Implementation steps", "format": "textarea" },
|
||||||
{ "fieldId": "customfield_10309", "label": "Firewall request details", "format": "textarea" },
|
{ "fieldId": "customfield_10309", "label": "Firewall request details", "format": "textarea" },
|
||||||
{ "fieldId": "customfield_10252", "label": "End result / justification", "format": "textarea" },
|
{ "fieldId": "customfield_10252", "label": "End result / justification", "format": "textarea" },
|
||||||
{ "fieldId": "customfield_10242", "label": "Application(s)", "format": "cmdb" },
|
{ "fieldId": "customfield_10242", "label": "Application(s)", "format": "cmdb" },
|
||||||
|
|
|
||||||
101
lib/jiraRichText.js
Normal file
101
lib/jiraRichText.js
Normal file
|
|
@ -0,0 +1,101 @@
|
||||||
|
function adfNodeToText(node) {
|
||||||
|
if (!node) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Array.isArray(node)) {
|
||||||
|
return node.map(adfNodeToText).join('');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (typeof node === 'string') {
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (node.type) {
|
||||||
|
case 'text':
|
||||||
|
return node.text || '';
|
||||||
|
case 'hardBreak':
|
||||||
|
return '\n';
|
||||||
|
case 'paragraph':
|
||||||
|
case 'heading':
|
||||||
|
return `${(node.content || []).map(adfNodeToText).join('')}\n`;
|
||||||
|
case 'bulletList':
|
||||||
|
case 'orderedList':
|
||||||
|
return (node.content || [])
|
||||||
|
.map(item => adfNodeToText(item))
|
||||||
|
.join('');
|
||||||
|
case 'listItem':
|
||||||
|
return `• ${(node.content || []).map(adfNodeToText).join('').trim()}\n`;
|
||||||
|
case 'rule':
|
||||||
|
return '\n';
|
||||||
|
case 'codeBlock':
|
||||||
|
return `${(node.content || []).map(adfNodeToText).join('')}\n`;
|
||||||
|
case 'inlineCard':
|
||||||
|
case 'blockCard':
|
||||||
|
return node.attrs?.url || '';
|
||||||
|
default:
|
||||||
|
if (node.content) {
|
||||||
|
return node.content.map(adfNodeToText).join('');
|
||||||
|
}
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export function adfToPlainText(value) {
|
||||||
|
if (!value || typeof value !== 'object') {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
if (value.type !== 'doc' || !Array.isArray(value.content)) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
return value.content.map(adfNodeToText).join('').trim();
|
||||||
|
}
|
||||||
|
|
||||||
|
export function formatJiraWikiMarkup(text) {
|
||||||
|
if (text == null || text === '') {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
let output = String(text).replace(/\r\n/g, '\n');
|
||||||
|
|
||||||
|
output = output.replace(/\{noformat\}([\s\S]*?)\{noformat\}/gi, (_, body) => `\n${body.trim()}\n`);
|
||||||
|
output = output.replace(/\{code(?::[^}]*)?\}([\s\S]*?)\{code\}/gi, (_, body) => `\n${body.trim()}\n`);
|
||||||
|
output = output.replace(/\{color(?::[^}]*)?\}([\s\S]*?)\{color\}/gi, '$1');
|
||||||
|
output = output.replace(/\{quote\}([\s\S]*?)\{quote\}/gi, '$1');
|
||||||
|
output = output.replace(/![^!\n]+!/g, '');
|
||||||
|
output = output.replace(/\[~accountid:[^\]]+\]/gi, '');
|
||||||
|
output = output.replace(/\[([^\]|]+)\|([^\]]+?)(?:\|smart-link)?\]/gi, (_, label, url) => {
|
||||||
|
const cleanLabel = label.trim();
|
||||||
|
const cleanUrl = url.trim();
|
||||||
|
if (!cleanLabel || cleanLabel === cleanUrl) {
|
||||||
|
return cleanUrl;
|
||||||
|
}
|
||||||
|
return `${cleanLabel} (${cleanUrl})`;
|
||||||
|
});
|
||||||
|
output = output.replace(/\*\*([^*\n]+?)\*\*/g, '$1');
|
||||||
|
output = output.replace(/(?<!\*)\*([^*\n]+)\*(?!\*)/g, '$1');
|
||||||
|
output = output.replace(/^h([1-6])\.\s*(.+)$/gim, (_, __, title) => `${title.trim()}\n`);
|
||||||
|
output = output.replace(/^#{1,6}\s+(.+)$/gm, '$1\n');
|
||||||
|
output = output.replace(/^\s*[-*#]\s+/gm, '• ');
|
||||||
|
output = output.replace(/^-{4,}\s*$/gm, '\n');
|
||||||
|
output = output.replace(/[ \t]+\n/g, '\n');
|
||||||
|
output = output.replace(/\n{3,}/g, '\n\n');
|
||||||
|
|
||||||
|
return output.trim();
|
||||||
|
}
|
||||||
|
|
||||||
|
export function formatJiraRichText(value) {
|
||||||
|
if (value == null || value === '') {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (typeof value === 'object') {
|
||||||
|
const adfText = adfToPlainText(value);
|
||||||
|
if (adfText) {
|
||||||
|
return formatJiraWikiMarkup(adfText);
|
||||||
|
}
|
||||||
|
return value.displayName || value.value || value.name || '';
|
||||||
|
}
|
||||||
|
|
||||||
|
return formatJiraWikiMarkup(value);
|
||||||
|
}
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
import fs from 'fs';
|
import fs from 'fs';
|
||||||
|
import { formatJiraRichText } from './jiraRichText.js';
|
||||||
|
|
||||||
const SKIP_FIELD_IDS = new Set(['attachment']);
|
const SKIP_FIELD_IDS = new Set(['attachment']);
|
||||||
|
|
||||||
|
|
@ -89,9 +90,10 @@ export function formatFieldValue(value, format) {
|
||||||
case 'text':
|
case 'text':
|
||||||
default:
|
default:
|
||||||
if (typeof value === 'object') {
|
if (typeof value === 'object') {
|
||||||
return value.displayName || value.value || value.name || JSON.stringify(value);
|
const richText = formatJiraRichText(value);
|
||||||
|
return richText || value.displayName || value.value || value.name || null;
|
||||||
}
|
}
|
||||||
return String(value);
|
return formatJiraRichText(value) || null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,13 +2,6 @@ import { buildDetailLinesForRequestType } from '../lib/requestTypeFields.js';
|
||||||
|
|
||||||
const PORTAL_BASE_URL = 'https://aeo.atlassian.net/servicedesk/customer/portal/135';
|
const PORTAL_BASE_URL = 'https://aeo.atlassian.net/servicedesk/customer/portal/135';
|
||||||
|
|
||||||
function appendDetailLines(detailText, lines) {
|
|
||||||
for (const line of lines) {
|
|
||||||
detailText += ` - **${line.label}:** ${line.value}\n`;
|
|
||||||
}
|
|
||||||
return detailText;
|
|
||||||
}
|
|
||||||
|
|
||||||
function getRequestTypeId(jiraTicket) {
|
function getRequestTypeId(jiraTicket) {
|
||||||
return jiraTicket.issue.fields?.customfield_10010?.requestType?.id;
|
return jiraTicket.issue.fields?.customfield_10010?.requestType?.id;
|
||||||
}
|
}
|
||||||
|
|
@ -78,19 +71,84 @@ function buildPlainTextHeader(jiraTicket) {
|
||||||
return text;
|
return text;
|
||||||
}
|
}
|
||||||
|
|
||||||
function buildCardPayload({ jiraTicket, detailText, assignmentText = '' }) {
|
function buildDetailBlocks(detailLines) {
|
||||||
const body = [...buildHeaderBlocks(jiraTicket)];
|
if (!detailLines.length) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
if (detailText.trim()) {
|
const blocks = [
|
||||||
body.push({
|
{
|
||||||
type: 'TextBlock',
|
type: 'TextBlock',
|
||||||
wrap: true,
|
text: 'Details',
|
||||||
text: detailText.trim(),
|
weight: 'Bolder',
|
||||||
|
size: 'Medium',
|
||||||
separator: true,
|
separator: true,
|
||||||
spacing: 'Medium',
|
spacing: 'Medium',
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
for (const line of detailLines) {
|
||||||
|
blocks.push({
|
||||||
|
type: 'TextBlock',
|
||||||
|
text: line.label,
|
||||||
|
weight: 'Bolder',
|
||||||
|
spacing: 'Medium',
|
||||||
|
wrap: true,
|
||||||
|
});
|
||||||
|
blocks.push({
|
||||||
|
type: 'TextBlock',
|
||||||
|
text: line.value,
|
||||||
|
spacing: 'Small',
|
||||||
|
wrap: true,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return blocks;
|
||||||
|
}
|
||||||
|
|
||||||
|
function formatDetailLinesPlain(detailLines) {
|
||||||
|
let text = '**Details:**\n';
|
||||||
|
for (const line of detailLines) {
|
||||||
|
text += `\n**${line.label}:**\n${line.value}\n`;
|
||||||
|
}
|
||||||
|
return text;
|
||||||
|
}
|
||||||
|
|
||||||
|
function buildFallbackChangeDetailLines(jiraTicket) {
|
||||||
|
const lines = [];
|
||||||
|
const fields = jiraTicket.issue.fields;
|
||||||
|
|
||||||
|
if (fields.customfield_10080) {
|
||||||
|
lines.push({ label: 'Risk', value: fields.customfield_10080.value });
|
||||||
|
}
|
||||||
|
if (fields.customfield_10004) {
|
||||||
|
lines.push({ label: 'Impact', value: fields.customfield_10004.value });
|
||||||
|
}
|
||||||
|
if (fields.customfield_10256) {
|
||||||
|
lines.push({ label: 'Business impact', value: fields.customfield_10256 });
|
||||||
|
}
|
||||||
|
if (fields.customfield_10252) {
|
||||||
|
lines.push({ label: 'Business justification', value: fields.customfield_10252 });
|
||||||
|
}
|
||||||
|
if (fields.customfield_10257) {
|
||||||
|
const changeDate = new Date(fields.customfield_10257).toLocaleDateString();
|
||||||
|
const changeTime = new Date(fields.customfield_10257).toLocaleTimeString([], {
|
||||||
|
hour: '2-digit',
|
||||||
|
minute: '2-digit',
|
||||||
|
hour12: true,
|
||||||
|
});
|
||||||
|
lines.push({ label: 'Implementation date', value: `${changeDate} ${changeTime}` });
|
||||||
|
}
|
||||||
|
|
||||||
|
return lines;
|
||||||
|
}
|
||||||
|
|
||||||
|
function buildCardPayload({ jiraTicket, detailLines = [], assignmentText = '' }) {
|
||||||
|
const body = [
|
||||||
|
...buildHeaderBlocks(jiraTicket),
|
||||||
|
...buildDetailBlocks(detailLines),
|
||||||
|
];
|
||||||
|
|
||||||
if (assignmentText.trim()) {
|
if (assignmentText.trim()) {
|
||||||
body.push({
|
body.push({
|
||||||
type: 'TextBlock',
|
type: 'TextBlock',
|
||||||
|
|
@ -122,8 +180,8 @@ function buildCardPayload({ jiraTicket, detailText, assignmentText = '' }) {
|
||||||
};
|
};
|
||||||
|
|
||||||
let requestText = buildPlainTextHeader(jiraTicket);
|
let requestText = buildPlainTextHeader(jiraTicket);
|
||||||
if (detailText.trim()) {
|
if (detailLines.length) {
|
||||||
requestText += `---\n${detailText}`;
|
requestText += `---\n${formatDetailLinesPlain(detailLines)}`;
|
||||||
}
|
}
|
||||||
if (assignmentText.trim()) {
|
if (assignmentText.trim()) {
|
||||||
requestText += `---\n${assignmentText}`;
|
requestText += `---\n${assignmentText}`;
|
||||||
|
|
@ -134,49 +192,36 @@ function buildCardPayload({ jiraTicket, detailText, assignmentText = '' }) {
|
||||||
|
|
||||||
export function buildChangeApproval(jiraTicket, log) {
|
export function buildChangeApproval(jiraTicket, log) {
|
||||||
return new Promise(function (resolve) {
|
return new Promise(function (resolve) {
|
||||||
let detailText = '**Details:**\n';
|
|
||||||
if (jiraTicket.issue.fields.description) {
|
|
||||||
detailText += `**Description:** ${jiraTicket.issue.fields.description}\n`;
|
|
||||||
}
|
|
||||||
|
|
||||||
const requestTypeId = getRequestTypeId(jiraTicket);
|
const requestTypeId = getRequestTypeId(jiraTicket);
|
||||||
if (requestTypeId) {
|
const detailLines = requestTypeId
|
||||||
detailText = appendDetailLines(detailText, buildDetailLinesForRequestType(jiraTicket, requestTypeId));
|
? buildDetailLinesForRequestType(jiraTicket, requestTypeId)
|
||||||
} else {
|
: buildFallbackChangeDetailLines(jiraTicket);
|
||||||
if (jiraTicket.issue.fields.customfield_10080) { detailText += ` - **Risk:** ${jiraTicket.issue.fields.customfield_10080.value}\n`; }
|
|
||||||
if (jiraTicket.issue.fields.customfield_10004) { detailText += ` - **Impact:** ${jiraTicket.issue.fields.customfield_10004.value}\n`; }
|
|
||||||
if (jiraTicket.issue.fields.customfield_10256) { detailText += ` - **Business Impact:** ${jiraTicket.issue.fields.customfield_10256}\n`; }
|
|
||||||
if (jiraTicket.issue.fields.customfield_10252) { detailText += ` - **Business Justification:** ${jiraTicket.issue.fields.customfield_10252}\n`; }
|
|
||||||
if (jiraTicket.issue.fields.customfield_10257) {
|
|
||||||
const changeDate = new Date(jiraTicket.issue.fields.customfield_10257).toLocaleDateString();
|
|
||||||
const changeTime = new Date(jiraTicket.issue.fields.customfield_10257).toLocaleTimeString([], { hour: '2-digit', minute: '2-digit', hour12: true });
|
|
||||||
detailText += ` - **Implementation Date:** ${changeDate} ${changeTime}\n`;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const hasDetails = detailText.replace('**Details:**\n', '').trim().length > 0;
|
|
||||||
log.logDebug('buildChangeApproval', `Built card for ${jiraTicket.issue.key}`);
|
log.logDebug('buildChangeApproval', `Built card for ${jiraTicket.issue.key}`);
|
||||||
resolve(buildCardPayload({
|
resolve(buildCardPayload({ jiraTicket, detailLines }));
|
||||||
jiraTicket,
|
|
||||||
detailText: hasDetails ? detailText : '',
|
|
||||||
}));
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
export function buildRequestApproval(jiraTicket) {
|
export function buildRequestApproval(jiraTicket) {
|
||||||
return new Promise(function (resolve) {
|
return new Promise(function (resolve) {
|
||||||
let detailText = '**Details:**\n';
|
|
||||||
const requestTypeId = getRequestTypeId(jiraTicket);
|
const requestTypeId = getRequestTypeId(jiraTicket);
|
||||||
if (requestTypeId) {
|
let detailLines = [];
|
||||||
detailText = appendDetailLines(detailText, buildDetailLinesForRequestType(jiraTicket, requestTypeId));
|
|
||||||
} else if (jiraTicket.issue.fields.customfield_10314) {
|
|
||||||
detailText += ` - **Person:** ${jiraTicket.issue.fields.customfield_10346}, ${jiraTicket.issue.fields.customfield_10314}`;
|
|
||||||
if (jiraTicket.issue.fields.customfield_10310) { detailText += ` (${jiraTicket.issue.fields.customfield_10310.value})`; }
|
|
||||||
detailText += '\n';
|
|
||||||
if (jiraTicket.issue.fields.customfield_10318) { detailText += ` - **Position:** ${jiraTicket.issue.fields.customfield_10318}\n`; }
|
|
||||||
}
|
|
||||||
|
|
||||||
const hasDetails = detailText.replace('**Details:**\n', '').trim().length > 0;
|
if (requestTypeId) {
|
||||||
|
detailLines = buildDetailLinesForRequestType(jiraTicket, requestTypeId);
|
||||||
|
} else if (jiraTicket.issue.fields.customfield_10314) {
|
||||||
|
let person = `${jiraTicket.issue.fields.customfield_10346}, ${jiraTicket.issue.fields.customfield_10314}`;
|
||||||
|
if (jiraTicket.issue.fields.customfield_10310) {
|
||||||
|
person += ` (${jiraTicket.issue.fields.customfield_10310.value})`;
|
||||||
|
}
|
||||||
|
detailLines.push({ label: 'Person', value: person });
|
||||||
|
if (jiraTicket.issue.fields.customfield_10318) {
|
||||||
|
detailLines.push({
|
||||||
|
label: 'Position',
|
||||||
|
value: jiraTicket.issue.fields.customfield_10318,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
let assignmentText = '';
|
let assignmentText = '';
|
||||||
if (jiraTicket.issue.fields.reporter) {
|
if (jiraTicket.issue.fields.reporter) {
|
||||||
|
|
@ -185,7 +230,7 @@ export function buildRequestApproval(jiraTicket) {
|
||||||
|
|
||||||
resolve(buildCardPayload({
|
resolve(buildCardPayload({
|
||||||
jiraTicket,
|
jiraTicket,
|
||||||
detailText: hasDetails ? detailText : '',
|
detailLines,
|
||||||
assignmentText,
|
assignmentText,
|
||||||
}));
|
}));
|
||||||
});
|
});
|
||||||
|
|
|
||||||
79
test/jiraRichText.test.js
Normal file
79
test/jiraRichText.test.js
Normal file
|
|
@ -0,0 +1,79 @@
|
||||||
|
import { describe, it } from 'node:test';
|
||||||
|
import assert from 'node:assert/strict';
|
||||||
|
import { adfToPlainText, formatJiraRichText, formatJiraWikiMarkup } from '../lib/jiraRichText.js';
|
||||||
|
|
||||||
|
describe('formatJiraWikiMarkup', () => {
|
||||||
|
it('converts Jira wiki links to readable text', () => {
|
||||||
|
const input = '[Repo|https://code.ae.com/projects/SCL/repos/web-apps/browse]';
|
||||||
|
assert.equal(
|
||||||
|
formatJiraWikiMarkup(input),
|
||||||
|
'Repo (https://code.ae.com/projects/SCL/repos/web-apps/browse)'
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('converts duplicate-url smart links to a single URL', () => {
|
||||||
|
const input = '[https://aeo.atlassian.net/browse/CHANGE-1|https://aeo.atlassian.net/browse/CHANGE-1|smart-link]';
|
||||||
|
assert.equal(
|
||||||
|
formatJiraWikiMarkup(input),
|
||||||
|
'https://aeo.atlassian.net/browse/CHANGE-1'
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('normalizes bold markers and bullets', () => {
|
||||||
|
const input = '* Expected behavior\n** Current behavior';
|
||||||
|
assert.match(formatJiraWikiMarkup(input), /• Expected behavior/);
|
||||||
|
assert.match(formatJiraWikiMarkup(input), /Current behavior/);
|
||||||
|
assert.equal(formatJiraWikiMarkup('**Rollback** plan'), 'Rollback plan');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('adfToPlainText', () => {
|
||||||
|
it('extracts text from ADF documents', () => {
|
||||||
|
const adf = {
|
||||||
|
type: 'doc',
|
||||||
|
version: 1,
|
||||||
|
content: [
|
||||||
|
{
|
||||||
|
type: 'paragraph',
|
||||||
|
content: [{ type: 'text', text: 'Start approx 4am est' }],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'bulletList',
|
||||||
|
content: [
|
||||||
|
{
|
||||||
|
type: 'listItem',
|
||||||
|
content: [
|
||||||
|
{
|
||||||
|
type: 'paragraph',
|
||||||
|
content: [{ type: 'text', text: 'Deploy banner update' }],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
|
|
||||||
|
assert.match(adfToPlainText(adf), /Start approx 4am est/);
|
||||||
|
assert.match(adfToPlainText(adf), /Deploy banner update/);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('formatJiraRichText', () => {
|
||||||
|
it('formats wiki strings and ADF objects', () => {
|
||||||
|
assert.equal(formatJiraRichText('**Rollback** plan'), 'Rollback plan');
|
||||||
|
assert.equal(
|
||||||
|
formatJiraRichText({
|
||||||
|
type: 'doc',
|
||||||
|
version: 1,
|
||||||
|
content: [
|
||||||
|
{
|
||||||
|
type: 'paragraph',
|
||||||
|
content: [{ type: 'text', text: 'Ready for approval' }],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
'Ready for approval'
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
Loading…
Reference in a new issue