|
28 | 28 | "frontmatter": {"title": "Test Note", "tags": ["test"]}, |
29 | 29 | } |
30 | 30 |
|
| 31 | +# With --include-frontmatter the API returns the LITERAL FILE as content |
| 32 | +# (frontmatter block included) alongside the parsed frontmatter dict. |
| 33 | +READ_NOTE_RESULT_WITH_FRONTMATTER = { |
| 34 | + "title": "Test Note", |
| 35 | + "permalink": "notes/test-note", |
| 36 | + "file_path": "notes/Test Note.md", |
| 37 | + "content": "---\ntitle: Test Note\ntags:\n- test\n---\n\n# Test Note\n\nhello world", |
| 38 | + "frontmatter": {"title": "Test Note", "tags": ["test"]}, |
| 39 | +} |
| 40 | + |
31 | 41 | SEARCH_RESULT = { |
32 | 42 | # Real SearchResponse.model_dump() uses "current_page", not "page". |
33 | 43 | # No "query" key in the response -- the query comes from the CLI argument. |
@@ -436,24 +446,29 @@ def test_recent_activity_non_tty_gives_json(mock_mcp): |
436 | 446 | @patch( |
437 | 447 | "basic_memory.cli.commands.tool.mcp_read_note", |
438 | 448 | new_callable=AsyncMock, |
439 | | - return_value=READ_NOTE_RESULT, |
| 449 | + return_value=READ_NOTE_RESULT_WITH_FRONTMATTER, |
440 | 450 | ) |
441 | 451 | def test_read_note_rich_include_frontmatter(mock_mcp): |
442 | | - """read-note --include-frontmatter renders frontmatter keys in Rich path. |
| 452 | + """read-note --include-frontmatter renders the panel once, not twice. |
443 | 453 |
|
444 | | - Regression: previously the Rich renderer silently dropped frontmatter even |
445 | | - when --include-frontmatter was passed, requiring --json to see the data. |
| 454 | + Regression 1: the Rich renderer silently dropped frontmatter even with the |
| 455 | + flag. Regression 2: with the flag, content is the LITERAL FILE, so the |
| 456 | + frontmatter block must be stripped from the Markdown body or it renders |
| 457 | + again under the panel. |
446 | 458 | """ |
447 | 459 | result = _tty_runner(["tool", "read-note", "test-note", "--include-frontmatter"]) |
448 | 460 |
|
449 | 461 | assert result.exit_code == 0, f"CLI failed: {result.output}" |
450 | | - # Frontmatter section header should appear |
| 462 | + # Frontmatter panel appears with key/value data |
451 | 463 | assert "frontmatter" in result.output |
452 | | - # The frontmatter key and value from READ_NOTE_RESULT should be visible |
453 | 464 | assert "tags" in result.output |
454 | 465 | assert "test" in result.output |
455 | | - # The note content should still appear |
| 466 | + # The note content still appears |
456 | 467 | assert "hello world" in result.output |
| 468 | + # The frontmatter block is NOT rendered a second time through Markdown: |
| 469 | + # the raw fence is stripped, and the title key appears only in the panel. |
| 470 | + assert "---" not in result.output |
| 471 | + assert result.output.count("title") == 1 |
457 | 472 |
|
458 | 473 |
|
459 | 474 | @patch( |
@@ -758,16 +773,22 @@ def test_read_note_plain_output(mock_mcp): |
758 | 773 | @patch( |
759 | 774 | "basic_memory.cli.commands.tool.mcp_read_note", |
760 | 775 | new_callable=AsyncMock, |
761 | | - return_value=READ_NOTE_RESULT, |
| 776 | + return_value=READ_NOTE_RESULT_WITH_FRONTMATTER, |
762 | 777 | ) |
763 | 778 | def test_read_note_plain_include_frontmatter(mock_mcp): |
764 | | - """read-note --plain --include-frontmatter renders key: value lines.""" |
| 779 | + """read-note --plain --include-frontmatter shows the literal file, once. |
| 780 | +
|
| 781 | + With the flag, content IS the file (frontmatter block included); plain mode |
| 782 | + prints it verbatim and must not prepend a synthesized key/value block. |
| 783 | + """ |
765 | 784 | result = _tty_runner(["tool", "read-note", "test-note", "--plain", "--include-frontmatter"]) |
766 | 785 |
|
767 | 786 | assert result.exit_code == 0, f"CLI failed: {result.output}" |
768 | | - assert "title: Test Note" in result.output |
769 | | - assert "tags:" in result.output |
| 787 | + # The literal file: fences and YAML lines exactly as stored |
| 788 | + assert "---\ntitle: Test Note\ntags:\n- test\n---" in result.output |
770 | 789 | assert "hello world" in result.output |
| 790 | + # No duplicated frontmatter from a synthesized block |
| 791 | + assert result.output.count("title: Test Note") == 1 |
771 | 792 |
|
772 | 793 |
|
773 | 794 | @patch( |
|
0 commit comments