Conversation
WalkthroughReplaces direct Lexical markdown conversion with a new normalization/export pipeline, adds blank-line placeholder utilities, updates create/edit components to use exportDropMarkdown/normalizeDropMarkdown, adjusts view newline consolidation, and updates tests to mock and cover the new normalization/export behavior. Changes
Sequence Diagram(s)sequenceDiagram
autonumber
actor User
participant Editor as Lexical Editor
participant Norm as normalizeDropMarkdown / exportDropMarkdown
participant BL as blankLinePlaceholders
participant View as Renderer
User->>Editor: Edit content
Editor->>Norm: exportDropMarkdown(editorState, transformers)
Note over Norm: Insert blank-paragraph sentinels\nRun transformers\nCollapse placeholders\nNormalize line endings
Norm-->>Editor: Markdown string
Editor->>BL: removeBlankLinePlaceholders(markdown) (if needed)
BL-->>Editor: sanitized markdown
Editor->>View: Render/process content
Note over View: Consolidate runs of ≥3 newlines\nGenerate filler using
View-->>User: Rendered output
sequenceDiagram
autonumber
actor User
participant Edit as EditDropLexical
participant Norm as normalizeDropMarkdown
participant BL as blankLinePlaceholders
Edit->>Norm: normalizeDropMarkdown(initialContent)
Norm-->>Edit: normalizedInitialContent
Edit->>BL: addBlankLinePlaceholders(normalizedInitialContent)
BL-->>Edit: editorInitialContent (with placeholders)
User->>Edit: Save / keyboard shortcut
Edit->>Norm: exportDropMarkdown(editorState, transformers)
Norm-->>Edit: exportedMarkdown (with sentinels)
Edit->>BL: removeBlankLinePlaceholders(exportedMarkdown)
BL-->>Edit: sanitizedMarkdown
Edit->>Edit: Compare sanitizedMarkdown to sanitizedInitialContent -> decide save/cancel
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Suggested reviewers
Poem
Pre-merge checks and finishing touches❌ Failed checks (1 inconclusive)
✅ Passed checks (2 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (2)
__tests__/components/waves/drops/normalizeDropMarkdown.test.ts (1)
64-68: Add test coverage for empty/falsy inputs.The test only covers CRLF normalization but doesn't verify the empty/falsy input handling that's implemented in the source (lines 92-94 of normalizeDropMarkdown.ts).
Add this test case:
describe("normalizeDropMarkdown", () => { it("normalizes CRLF to LF", () => { expect(normalizeDropMarkdown("line1\r\nline2")).toBe("line1\nline2"); }); + + it("returns empty strings unchanged", () => { + expect(normalizeDropMarkdown("")).toBe(""); + }); });components/waves/drops/normalizeDropMarkdown.ts (1)
64-78: Consider adding documentation for complex marker collapsing logic.The logic correctly handles blank paragraph markers but could benefit from inline documentation explaining the two-pass approach (collapsing runs, then handling individual tokens).
const collapseBlankParagraphMarkers = (markdown: string): string => { if (!markdown) { return markdown; } + const collapsedRuns = markdown.replaceAll(BLANK_RUN_REGEX, (match) => { const markerCount = match.split(BLANK_PARAGRAPH_SENTINEL).length - 1; return "\n".repeat(markerCount); }); + return collapsedRuns.replaceAll( BLANK_PARAGRAPH_TOKEN_REGEX, (_match, trailingNewline: string) => `\n${trailingNewline}` ); };
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (12)
__tests__/components/CreateDropWrapper.test.tsx(1 hunks)__tests__/components/drops/create/utils/CreateDropContent.component.test.tsx(1 hunks)__tests__/components/drops/create/utils/CreateDropWrapper.test.tsx(2 hunks)__tests__/components/waves/drops/EditDropLexical.test.tsx(6 hunks)__tests__/components/waves/drops/normalizeDropMarkdown.test.ts(1 hunks)components/drops/create/utils/CreateDropContent.tsx(2 hunks)components/drops/create/utils/CreateDropWrapper.tsx(2 hunks)components/drops/view/part/dropPartMarkdown/content.tsx(1 hunks)components/waves/CreateDropContent.tsx(2 hunks)components/waves/drops/EditDropLexical.tsx(10 hunks)components/waves/drops/blankLinePlaceholders.ts(1 hunks)components/waves/drops/normalizeDropMarkdown.ts(1 hunks)
🧰 Additional context used
📓 Path-based instructions (7)
**/*.{ts,tsx}
📄 CodeRabbit inference engine (.cursorrules)
**/*.{ts,tsx}: Do not include any comments in the code
Use react-query for data fetching
Always add readonly before propsFollow existing code style and naming conventions
Files:
components/drops/view/part/dropPartMarkdown/content.tsxcomponents/drops/create/utils/CreateDropWrapper.tsx__tests__/components/drops/create/utils/CreateDropContent.component.test.tsxcomponents/waves/drops/normalizeDropMarkdown.ts__tests__/components/waves/drops/normalizeDropMarkdown.test.ts__tests__/components/drops/create/utils/CreateDropWrapper.test.tsxcomponents/drops/create/utils/CreateDropContent.tsx__tests__/components/CreateDropWrapper.test.tsxcomponents/waves/CreateDropContent.tsxcomponents/waves/drops/blankLinePlaceholders.ts__tests__/components/waves/drops/EditDropLexical.test.tsxcomponents/waves/drops/EditDropLexical.tsx
**/*.tsx
📄 CodeRabbit inference engine (.cursorrules)
**/*.tsx: Use FontAwesome for icons
Use TailwindCSS for stylingUse React functional components with hooks for UI components
Files:
components/drops/view/part/dropPartMarkdown/content.tsxcomponents/drops/create/utils/CreateDropWrapper.tsx__tests__/components/drops/create/utils/CreateDropContent.component.test.tsx__tests__/components/drops/create/utils/CreateDropWrapper.test.tsxcomponents/drops/create/utils/CreateDropContent.tsx__tests__/components/CreateDropWrapper.test.tsxcomponents/waves/CreateDropContent.tsx__tests__/components/waves/drops/EditDropLexical.test.tsxcomponents/waves/drops/EditDropLexical.tsx
__tests__/**
📄 CodeRabbit inference engine (tests/AGENTS.md)
Place Jest test suites under the
__tests__directory mirroring source folders (e.g., components, contexts, hooks, utils)
Files:
__tests__/components/drops/create/utils/CreateDropContent.component.test.tsx__tests__/components/waves/drops/normalizeDropMarkdown.test.ts__tests__/components/drops/create/utils/CreateDropWrapper.test.tsx__tests__/components/CreateDropWrapper.test.tsx__tests__/components/waves/drops/EditDropLexical.test.tsx
__tests__/components/**/*.{ts,tsx,js,jsx}
📄 CodeRabbit inference engine (tests/AGENTS.md)
Use
@testing-library/reactand@testing-library/user-eventfor React component tests
Files:
__tests__/components/drops/create/utils/CreateDropContent.component.test.tsx__tests__/components/waves/drops/normalizeDropMarkdown.test.ts__tests__/components/drops/create/utils/CreateDropWrapper.test.tsx__tests__/components/CreateDropWrapper.test.tsx__tests__/components/waves/drops/EditDropLexical.test.tsx
{**/__tests__/**,**/*.test.{ts,tsx}}
📄 CodeRabbit inference engine (AGENTS.md)
{**/__tests__/**,**/*.test.{ts,tsx}}: If coverage on a modified file is below 80%, add meaningful tests to raise it to at least 80%
Mock external dependencies and APIs in tests
Files:
__tests__/components/drops/create/utils/CreateDropContent.component.test.tsx__tests__/components/waves/drops/normalizeDropMarkdown.test.ts__tests__/components/drops/create/utils/CreateDropWrapper.test.tsx__tests__/components/CreateDropWrapper.test.tsx__tests__/components/waves/drops/EditDropLexical.test.tsx
**/__tests__/**
📄 CodeRabbit inference engine (AGENTS.md)
Place tests in
__tests__/directories when organizing standalone test suites
Files:
__tests__/components/drops/create/utils/CreateDropContent.component.test.tsx__tests__/components/waves/drops/normalizeDropMarkdown.test.ts__tests__/components/drops/create/utils/CreateDropWrapper.test.tsx__tests__/components/CreateDropWrapper.test.tsx__tests__/components/waves/drops/EditDropLexical.test.tsx
**/*.test.tsx
📄 CodeRabbit inference engine (AGENTS.md)
When co-locating tests with components, name them
ComponentName.test.tsx
Files:
__tests__/components/drops/create/utils/CreateDropContent.component.test.tsx__tests__/components/drops/create/utils/CreateDropWrapper.test.tsx__tests__/components/CreateDropWrapper.test.tsx__tests__/components/waves/drops/EditDropLexical.test.tsx
🧠 Learnings (5)
📚 Learning: 2025-09-28T12:33:07.561Z
Learnt from: CR
PR: 6529-Collections/6529seize-frontend#0
File: __mocks__/AGENTS.md:0-0
Timestamp: 2025-09-28T12:33:07.561Z
Learning: Applies to __mocks__/**/__mocks__/**/*.{js,jsx,ts,tsx} : Keep mock implementations minimal—only what’s necessary for the test scenarios
Applied to files:
__tests__/components/drops/create/utils/CreateDropContent.component.test.tsx__tests__/components/drops/create/utils/CreateDropWrapper.test.tsx__tests__/components/CreateDropWrapper.test.tsx
📚 Learning: 2025-10-07T14:38:41.233Z
Learnt from: CR
PR: 6529-Collections/6529seize-frontend#0
File: AGENTS.md:0-0
Timestamp: 2025-10-07T14:38:41.233Z
Learning: Applies to {**/__tests__/**,**/*.test.{ts,tsx}} : Mock external dependencies and APIs in tests
Applied to files:
__tests__/components/drops/create/utils/CreateDropContent.component.test.tsx
📚 Learning: 2025-09-28T12:33:07.561Z
Learnt from: CR
PR: 6529-Collections/6529seize-frontend#0
File: __mocks__/AGENTS.md:0-0
Timestamp: 2025-09-28T12:33:07.561Z
Learning: Applies to __mocks__/**/__mocks__/**/*.{js,jsx,ts,tsx} : Document non-obvious expected behaviour directly in the mock file
Applied to files:
__tests__/components/drops/create/utils/CreateDropContent.component.test.tsx__tests__/components/drops/create/utils/CreateDropWrapper.test.tsx__tests__/components/waves/drops/EditDropLexical.test.tsx
📚 Learning: 2025-09-28T12:33:07.561Z
Learnt from: CR
PR: 6529-Collections/6529seize-frontend#0
File: __mocks__/AGENTS.md:0-0
Timestamp: 2025-09-28T12:33:07.561Z
Learning: Applies to __mocks__/**/__mocks__/**/*.{js,jsx,ts,tsx} : Keep mocks up to date with the real implementations they represent
Applied to files:
__tests__/components/drops/create/utils/CreateDropWrapper.test.tsx__tests__/components/CreateDropWrapper.test.tsx
📚 Learning: 2025-09-28T12:33:07.561Z
Learnt from: CR
PR: 6529-Collections/6529seize-frontend#0
File: __mocks__/AGENTS.md:0-0
Timestamp: 2025-09-28T12:33:07.561Z
Learning: Applies to __mocks__/**/__mocks__/**/*.{js,jsx,ts,tsx} : Mock only external dependencies or heavy functionality; avoid over-mocking internal logic
Applied to files:
__tests__/components/drops/create/utils/CreateDropWrapper.test.tsx__tests__/components/waves/drops/EditDropLexical.test.tsx
🧬 Code graph analysis (5)
components/drops/create/utils/CreateDropWrapper.tsx (5)
components/waves/drops/normalizeDropMarkdown.ts (1)
exportDropMarkdown(80-89)components/drops/create/lexical/transformers/markdownTransformers.ts (1)
SAFE_MARKDOWN_TRANSFORMERS(42-42)components/drops/create/lexical/transformers/MentionTransformer.ts (1)
MENTION_TRANSFORMER(4-32)components/drops/create/lexical/transformers/HastagTransformer.ts (1)
HASHTAG_TRANSFORMER(4-32)components/drops/create/lexical/transformers/ImageTransformer.ts (1)
IMAGE_TRANSFORMER(4-22)
__tests__/components/waves/drops/normalizeDropMarkdown.test.ts (1)
components/waves/drops/normalizeDropMarkdown.ts (2)
exportDropMarkdown(80-89)normalizeDropMarkdown(91-97)
components/drops/create/utils/CreateDropContent.tsx (5)
components/waves/drops/normalizeDropMarkdown.ts (1)
exportDropMarkdown(80-89)components/drops/create/lexical/transformers/markdownTransformers.ts (1)
SAFE_MARKDOWN_TRANSFORMERS(42-42)components/drops/create/lexical/transformers/MentionTransformer.ts (1)
MENTION_TRANSFORMER(4-32)components/drops/create/lexical/transformers/HastagTransformer.ts (1)
HASHTAG_TRANSFORMER(4-32)components/drops/create/lexical/transformers/ImageTransformer.ts (1)
IMAGE_TRANSFORMER(4-22)
components/waves/CreateDropContent.tsx (6)
components/waves/drops/normalizeDropMarkdown.ts (1)
exportDropMarkdown(80-89)components/drops/create/lexical/transformers/markdownTransformers.ts (1)
SAFE_MARKDOWN_TRANSFORMERS(42-42)components/drops/create/lexical/transformers/MentionTransformer.ts (1)
MENTION_TRANSFORMER(4-32)components/drops/create/lexical/transformers/HastagTransformer.ts (1)
HASHTAG_TRANSFORMER(4-32)components/drops/create/lexical/transformers/ImageTransformer.ts (1)
IMAGE_TRANSFORMER(4-22)components/drops/create/lexical/transformers/EmojiTransformer.ts (1)
EMOJI_TRANSFORMER(6-27)
components/waves/drops/EditDropLexical.tsx (2)
components/waves/drops/normalizeDropMarkdown.ts (2)
normalizeDropMarkdown(91-97)exportDropMarkdown(80-89)components/waves/drops/blankLinePlaceholders.ts (2)
removeBlankLinePlaceholders(19-25)addBlankLinePlaceholders(4-17)
🪛 ast-grep (0.39.6)
components/waves/drops/normalizeDropMarkdown.ts
[warning] 16-19: Regular expression constructed from variable input detected. This can lead to Regular Expression Denial of Service (ReDoS) attacks if the variable contains malicious patterns. Use libraries like 'recheck' to validate regex safety or use static patterns.
Context: new RegExp(
(?:${BLANK_PARAGRAPH_SENTINEL}\\n\\n)+,
"g"
)
Note: [CWE-1333] Inefficient Regular Expression Complexity [REFERENCES]
- https://owasp.org/www-community/attacks/Regular_expression_Denial_of_Service_-_ReDoS
- https://cwe.mitre.org/data/definitions/1333.html
(regexp-from-variable)
[warning] 20-23: Regular expression constructed from variable input detected. This can lead to Regular Expression Denial of Service (ReDoS) attacks if the variable contains malicious patterns. Use libraries like 'recheck' to validate regex safety or use static patterns.
Context: new RegExp(
${BLANK_PARAGRAPH_SENTINEL}(\\n?),
"g"
)
Note: [CWE-1333] Inefficient Regular Expression Complexity [REFERENCES]
- https://owasp.org/www-community/attacks/Regular_expression_Denial_of_Service_-_ReDoS
- https://cwe.mitre.org/data/definitions/1333.html
(regexp-from-variable)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: Analyze (javascript-typescript)
🔇 Additional comments (20)
components/drops/view/part/dropPartMarkdown/content.tsx (1)
248-254: LGTM! Blank line consolidation logic updated correctly.The threshold change from 4+ to 3+ consecutive newlines and the updated filler generation align with the new markdown normalization workflow introduced in this PR.
components/waves/drops/blankLinePlaceholders.ts (1)
9-16: Verify placeholder segment formatting consistency.The placeholder segment uses single newlines between placeholders (
"\u200B\n"), whilecomponents/drops/view/part/dropPartMarkdown/content.tsx(lines 248-254) uses double newlines between fillers (" \n\n "). This difference in formatting could lead to inconsistent blank line handling.For 5 consecutive newlines:
- This function produces:
"\n\n\u200B\n\u200B\n\u200B\n"(single\nbetween placeholders)- content.tsx produces:
"\n\n \n\n \n\n \n\n"(double\n\nbetween fillers)Confirm whether this formatting difference is intentional or if both should use the same pattern.
__tests__/components/drops/create/utils/CreateDropContent.component.test.tsx (1)
31-36: LGTM! Mock implementation follows testing guidelines.The mock is minimal and appropriate for isolating the component under test.
Based on learnings
__tests__/components/drops/create/utils/CreateDropWrapper.test.tsx (1)
19-25: LGTM! Mock implementation is appropriate.The mock setup correctly isolates the normalization module for testing purposes.
Based on learnings
components/drops/create/utils/CreateDropContent.tsx (2)
72-74: LGTM! Import added correctly.The import for
exportDropMarkdownfrom the new normalization module is appropriate.
198-209: LGTM! Markdown generation migrated to new normalization workflow.The replacement of Lexical's direct markdown conversion with
exportDropMarkdownaligns with the PR's objective to centralize markdown normalization.__tests__/components/CreateDropWrapper.test.tsx (1)
22-27: LGTM! Mock returns non-empty string for length checks.The mock's return value of
'text'is appropriate for testing length-based logic in the wrapper component.Based on learnings
components/drops/create/utils/CreateDropWrapper.tsx (2)
40-42: LGTM! Import added correctly.The import for
exportDropMarkdownfrom the normalization module is appropriate.
199-206: LGTM! Markdown generation updated consistently.The migration to
exportDropMarkdownis consistent with other components in this PR and correctly delegates to the new normalization workflow.components/waves/CreateDropContent.tsx (2)
61-61: LGTM! Import added correctly.The import for
exportDropMarkdownis appropriate for the new normalization workflow.
489-501: LGTM! Markdown computation updated with emoji support.The migration to
exportDropMarkdownincludesEMOJI_TRANSFORMERin the transformers array, which is appropriate for wave content. The memoization oneditorStateensures efficient recomputation.components/waves/drops/EditDropLexical.tsx (3)
57-61: LGTM!The imports correctly bring in the new normalization pipeline utilities and follow the coding guidelines.
354-361: LGTM!The memoization correctly:
- Normalizes initial content once
- Adds placeholders for the editor display
- Has proper dependency arrays
413-433: LGTM!The save handler correctly:
- Exports markdown using the new pipeline
- Removes placeholders before saving
- Compares sanitized values to detect actual changes
- Includes all necessary dependencies
components/waves/drops/normalizeDropMarkdown.ts (3)
17-24: ReDoS risk is not applicable here (false positive).Static analysis flagged potential ReDoS vulnerabilities, but these regex patterns are constructed from constant sentinel values (lines 14-16) that don't accept user input. The patterns are safe.
However, to verify the regex correctness and performance characteristics, you could add complexity comments or extract the patterns into named constants for clarity:
+const BLANK_RUN_PATTERN = `(?:${BLANK_PARAGRAPH_SENTINEL}\\n\\n)+`; +const BLANK_PARAGRAPH_TOKEN_PATTERN = `${BLANK_PARAGRAPH_SENTINEL}(\\n?)`; + const BLANK_RUN_REGEX = new RegExp( - `(?:${BLANK_PARAGRAPH_SENTINEL}\\n\\n)+`, + BLANK_RUN_PATTERN, "g" ); const BLANK_PARAGRAPH_TOKEN_REGEX = new RegExp( - `${BLANK_PARAGRAPH_SENTINEL}(\\n?)`, + BLANK_PARAGRAPH_TOKEN_PATTERN, "g" );
26-51: LGTM!The blank paragraph detection correctly handles all edge cases including line breaks, text nodes with zero-width spaces, and empty paragraphs.
80-97: LGTM!Both functions correctly implement the normalization pipeline:
exportDropMarkdownintegrates the blank paragraph transformer and collapses markersnormalizeDropMarkdownhandles line ending normalization with proper empty-value checks__tests__/components/waves/drops/EditDropLexical.test.tsx (3)
165-177: LGTM!The mock correctly:
- Provides all exports from the module (default, named exports)
- Uses passthrough for normalizeDropMarkdown (identity function)
- Provides a controlled return value for exportDropMarkdown
This follows the coding guidelines for mocking external dependencies.
As per coding guidelines.
209-217: LGTM!The beforeEach setup correctly initializes the new mocks with appropriate default behavior before each test.
265-299: LGTM!The test correctly verifies that the keyboard command handlers call
exportDropMarkdownin the new pipeline instead of the old Lexical conversion function.
|
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (3)
__tests__/components/waves/drops/normalizeDropMarkdown.test.ts (3)
12-12: Consider importing the sentinel constant.The
BLANK_PARAGRAPH_SENTINELis duplicated from the implementation. If this constant is also defined in the source file or a shared location, import it to avoid maintenance issues when the sentinel value changes.
33-64: Add test cases with non-empty transformers.All test cases pass an empty transformers array. Add at least one test case with actual transformers to verify they are correctly passed to
$convertToMarkdownString.Example test case:
it("passes transformers to markdown conversion", () => { const mockTransformer = { type: "text" } as any; convertToMarkdownStringMock.mockReturnValue("Content"); exportDropMarkdown(editorState, [mockTransformer]); expect(convertToMarkdownStringMock).toHaveBeenCalledWith( expect.arrayContaining([mockTransformer]) ); });
33-64: Add assertions to verify mock calls.The tests don't verify that
$convertToMarkdownStringwas called. Add assertions to confirm the mock was invoked with the expected parameters.Apply this pattern to existing tests:
it("returns markdown unchanged when no blank markers are present", () => { convertToMarkdownStringMock.mockReturnValue("First\n\nSecond"); expect(exportDropMarkdown(editorState, [])).toBe("First\n\nSecond"); + expect(convertToMarkdownStringMock).toHaveBeenCalledTimes(1); });
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
__tests__/components/waves/drops/normalizeDropMarkdown.test.ts(1 hunks)
🧰 Additional context used
📓 Path-based instructions (5)
**/*.{ts,tsx}
📄 CodeRabbit inference engine (.cursorrules)
**/*.{ts,tsx}: Do not include any comments in the code
Use react-query for data fetching
Always add readonly before propsFollow existing code style and naming conventions
Files:
__tests__/components/waves/drops/normalizeDropMarkdown.test.ts
__tests__/**
📄 CodeRabbit inference engine (tests/AGENTS.md)
Place Jest test suites under the
__tests__directory mirroring source folders (e.g., components, contexts, hooks, utils)
Files:
__tests__/components/waves/drops/normalizeDropMarkdown.test.ts
__tests__/components/**/*.{ts,tsx,js,jsx}
📄 CodeRabbit inference engine (tests/AGENTS.md)
Use
@testing-library/reactand@testing-library/user-eventfor React component tests
Files:
__tests__/components/waves/drops/normalizeDropMarkdown.test.ts
{**/__tests__/**,**/*.test.{ts,tsx}}
📄 CodeRabbit inference engine (AGENTS.md)
{**/__tests__/**,**/*.test.{ts,tsx}}: If coverage on a modified file is below 80%, add meaningful tests to raise it to at least 80%
Mock external dependencies and APIs in tests
Files:
__tests__/components/waves/drops/normalizeDropMarkdown.test.ts
**/__tests__/**
📄 CodeRabbit inference engine (AGENTS.md)
Place tests in
__tests__/directories when organizing standalone test suites
Files:
__tests__/components/waves/drops/normalizeDropMarkdown.test.ts
🧬 Code graph analysis (1)
__tests__/components/waves/drops/normalizeDropMarkdown.test.ts (1)
components/waves/drops/normalizeDropMarkdown.ts (2)
exportDropMarkdown(80-89)normalizeDropMarkdown(91-97)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: Analyze (javascript-typescript)
🔇 Additional comments (1)
__tests__/components/waves/drops/normalizeDropMarkdown.test.ts (1)
20-23: LGTM!The EditorState stub is appropriately minimal for unit testing the
read()method behavior.



Summary by CodeRabbit
Improvements
Bug Fixes