From 34b4e5ecd8468129cb97e870987fc8bb8d27d6e2 Mon Sep 17 00:00:00 2001 From: Craig Jennings Date: Wed, 27 May 2026 16:52:07 -0500 Subject: fix(save): detect comment edits with a rendered-Org hash, not the md round-trip A comment whose markdown doesn't survive md->org->md (a heading, single-asterisk italics) was flagged changed on every save, because the dirty scan compared org-to-md of the rendered body against the stored markdown hash. When the comment was authored by someone else, that surfaced as "1 read-only comment skipped" on every save even though nothing had been edited. Descriptions already dodge this: 9424b84 gave them LINEAR-DESC-ORG-SHA256 and compared Org-to-Org. I did the same for comments. pearl--format-comment now writes LINEAR-COMMENT-ORG-SHA256 (the rendered body hash), and a new pearl--comment-dirty-p compares the current body against it, falling back to the old markdown hash for comments rendered before the baseline existed. Both detection sites use it: the save scan and the edit-current-comment no-op check. The markdown hash stays for the remote-conflict gate. --- tests/test-pearl-comment-editing.el | 52 +++++++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) (limited to 'tests/test-pearl-comment-editing.el') diff --git a/tests/test-pearl-comment-editing.el b/tests/test-pearl-comment-editing.el index 32b194d..4853548 100644 --- a/tests/test-pearl-comment-editing.el +++ b/tests/test-pearl-comment-editing.el @@ -365,5 +365,57 @@ adds the comment there rather than refusing." (re-search-forward "see :note:") (should (string= "see :note: below\nand more text" (pearl--entry-body-at-point))))) +;;; round-trip stability of the dirty check (the read-only-every-save fix) + +(defun test-pearl-comment-editing--commented-issue (body) + "An issue subtree whose one comment (by another user) has BODY." + (concat "** TODO ENG-1: x\n:PROPERTIES:\n:LINEAR-ID: i\n:END:\nissue body\n" + (pearl--format-comment + (list :id "c1" :author "Eric" :author-id "u-eric" + :created-at "2026-01-01T00:00:00.000Z" :body body)))) + +(ert-deftest test-pearl-comment-dirty-p-stable-for-lossy-markdown () + "A freshly rendered comment whose markdown does not survive md->org->md +(a heading, single-asterisk italics) is not seen as dirty." + (test-pearl--in-org (test-pearl-comment-editing--commented-issue + "# Heading\n\nsome *italic* words") + (re-search-forward "LINEAR-COMMENT-ID") + (org-back-to-heading t) + (should-not (pearl--comment-dirty-p)))) + +(ert-deftest test-pearl-comment-dirty-p-detects-a-real-edit () + "An actual edit to the comment body is detected as dirty." + (test-pearl--in-org (test-pearl-comment-editing--commented-issue "original text") + (re-search-forward "LINEAR-COMMENT-ID") + (org-back-to-heading t) + (should-not (pearl--comment-dirty-p)) + (goto-char (point-max)) + (insert " EDITED") + (org-back-to-heading t) + (should (pearl--comment-dirty-p)))) + +(ert-deftest test-pearl-changed-comment-candidates-ignores-unedited-lossy-comment () + "The save scan does not flag an unedited comment with lossy markdown, so a +non-viewer comment is no longer reported read-only on every save." + (test-pearl--in-org (test-pearl-comment-editing--commented-issue + "## A heading\n\n*emphasis* and text") + (re-search-forward "^\\*\\* ") + (org-back-to-heading t) + (should-not (pearl--changed-comment-candidates)))) + +(ert-deftest test-pearl-comment-dirty-p-legacy-falls-back-to-md-hash () + "A comment rendered before the Org baseline existed (no LINEAR-COMMENT-ORG-SHA256) +falls back to the markdown-hash comparison, so a clean legacy comment is not dirty." + (test-pearl--in-org + (concat "** TODO ENG-1: x\n:PROPERTIES:\n:LINEAR-ID: i\n:END:\n" + "**** Eric — 2026-01-01T00:00:00.000Z\n:PROPERTIES:\n" + ":LINEAR-COMMENT-ID: c1\n" + ":LINEAR-COMMENT-AUTHOR-ID: u-eric\n" + (format ":LINEAR-COMMENT-SHA256: %s\n" (secure-hash 'sha256 "plain body")) + ":END:\nplain body\n") + (re-search-forward "LINEAR-COMMENT-ID") + (org-back-to-heading t) + (should-not (pearl--comment-dirty-p)))) + (provide 'test-pearl-comment-editing) ;;; test-pearl-comment-editing.el ends here -- cgit v1.2.3