Skip to main content
Glama
formatted-comments.test.ts6.07 kB
import { test } from "node:test"; import assert from "node:assert/strict"; import { convertMarkdownToClickUpBlocks } from "../clickup-text"; test("convertMarkdownToClickUpBlocks handles headers", () => { const markdown = "# H1\n## H2\n### H3"; const blocks = convertMarkdownToClickUpBlocks(markdown); // Find header blocks const h1 = blocks.find(b => b.attributes?.header === 1); const h2 = blocks.find(b => b.attributes?.header === 2); const h3 = blocks.find(b => b.attributes?.header === 3); assert.ok(h1, "should have H1 block"); assert.ok(h2, "should have H2 block"); assert.ok(h3, "should have H3 block"); }); test("convertMarkdownToClickUpBlocks handles blockquotes", () => { const markdown = "> This is a quote"; const blocks = convertMarkdownToClickUpBlocks(markdown); const blockquote = blocks.find(b => b.attributes?.blockquote !== undefined); assert.ok(blockquote, "should have blockquote block"); }); test("convertMarkdownToClickUpBlocks handles lists", () => { const markdown = "- Item 1\n1. Item 2\n- [ ] Todo\n- [x] Done"; const blocks = convertMarkdownToClickUpBlocks(markdown); const bullet = blocks.find(b => b.attributes?.list?.list === 'bullet'); const ordered = blocks.find(b => b.attributes?.list?.list === 'ordered'); const unchecked = blocks.find(b => b.attributes?.list?.list === 'unchecked'); const checked = blocks.find(b => b.attributes?.list?.list === 'checked'); assert.ok(bullet, "should have bullet list"); assert.ok(ordered, "should have ordered list"); assert.ok(unchecked, "should have unchecked checkbox"); assert.ok(checked, "should have checked checkbox"); }); test("convertMarkdownToClickUpBlocks handles code blocks", () => { const markdown = "```\ncode here\n```"; const blocks = convertMarkdownToClickUpBlocks(markdown); const codeBlock = blocks.find(b => b.attributes?.['code-block'] !== undefined); assert.ok(codeBlock, "should have code block"); }); test("convertMarkdownToClickUpBlocks handles inline formatting", () => { const markdown = "**bold** *italic* `code` [link](https://example.com)"; const blocks = convertMarkdownToClickUpBlocks(markdown); const bold = blocks.find(b => b.attributes?.bold === true); const italic = blocks.find(b => b.attributes?.italic === true); const code = blocks.find(b => b.attributes?.code === true); const link = blocks.find(b => b.attributes?.link === 'https://example.com'); assert.ok(bold, "should have bold"); assert.ok(italic, "should have italic"); assert.ok(code, "should have code"); assert.ok(link, "should have link"); }); test("convertMarkdownToClickUpBlocks comprehensive test", () => { const markdown = `# Heading 1 This has **bold** and *italic*. > A quote - List item - [x] Done \`\`\` code \`\`\``; const blocks = convertMarkdownToClickUpBlocks(markdown); // Should have all formatting types assert.ok(blocks.find(b => b.attributes?.header === 1), "has header"); assert.ok(blocks.find(b => b.attributes?.bold === true), "has bold"); assert.ok(blocks.find(b => b.attributes?.italic === true), "has italic"); assert.ok(blocks.find(b => b.attributes?.blockquote !== undefined), "has blockquote"); assert.ok(blocks.find(b => b.attributes?.list?.list === 'bullet'), "has bullet list"); assert.ok(blocks.find(b => b.attributes?.list?.list === 'checked'), "has checkbox"); assert.ok(blocks.find(b => b.attributes?.['code-block'] !== undefined), "has code block"); }); test("convertMarkdownToClickUpBlocks handles nested bold+italic", () => { const markdown = "Text with ***bold and italic*** together"; const blocks = convertMarkdownToClickUpBlocks(markdown); const nested = blocks.find(b => b.attributes?.bold && b.attributes?.italic); assert.ok(nested, "should have block with both bold and italic"); assert.equal(nested?.text, "bold and italic"); }); test("convertMarkdownToClickUpBlocks handles nested lists with indent", () => { const markdown = `- Top level - Second level - Third level - Back to second - Another top`; const blocks = convertMarkdownToClickUpBlocks(markdown); // Find blocks with different indent levels const topLevel = blocks.filter(b => b.attributes?.list && !b.attributes?.indent); const secondLevel = blocks.filter(b => b.attributes?.list && b.attributes?.indent === 1); const thirdLevel = blocks.filter(b => b.attributes?.list && b.attributes?.indent === 2); assert.equal(topLevel.length, 2, "should have 2 top level items"); assert.equal(secondLevel.length, 2, "should have 2 second level items"); assert.equal(thirdLevel.length, 1, "should have 1 third level item"); }); test("convertMarkdownToClickUpBlocks handles nested numbered lists", () => { const markdown = `1. First 1. Nested first 2. Nested second 2. Second`; const blocks = convertMarkdownToClickUpBlocks(markdown); const topLevel = blocks.filter(b => b.attributes?.list?.list === 'ordered' && !b.attributes?.indent); const nested = blocks.filter(b => b.attributes?.list?.list === 'ordered' && b.attributes?.indent === 1); assert.equal(topLevel.length, 2, "should have 2 top level numbered items"); assert.equal(nested.length, 2, "should have 2 nested numbered items"); }); test("convertMarkdownToClickUpBlocks handles mixed nested lists", () => { const markdown = `- Bullet 1. Nested number - Deep bullet`; const blocks = convertMarkdownToClickUpBlocks(markdown); const bullet = blocks.find(b => b.attributes?.list?.list === 'bullet' && !b.attributes?.indent); const nestedNumber = blocks.find(b => b.attributes?.list?.list === 'ordered' && b.attributes?.indent === 1); // Mixed list types: the bullet inside the numbered list is at indent 1 (relative to its parent) const deepBullet = blocks.find(b => b.attributes?.list?.list === 'bullet' && b.attributes?.indent === 1 && b.text === "\n"); assert.ok(bullet, "should have top level bullet"); assert.ok(nestedNumber, "should have nested numbered item"); assert.ok(deepBullet, "should have nested bullet inside numbered list"); });

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/hauptsacheNet/clickup-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server