diff options
| author | Paul Buetow <paul@buetow.org> | 2026-04-27 08:37:20 +0300 |
|---|---|---|
| committer | Paul Buetow <paul@buetow.org> | 2026-04-27 08:37:20 +0300 |
| commit | 8defd48636eeebb3916809fc3f21c2e3d7c9ef5b (patch) | |
| tree | 3fba5ec27f49a788d5c753fcd4a3417a58c73ef5 /internal/processor/processor_test.go | |
| parent | 257057748a2cf2070fbeb722a94772857b5d014f (diff) | |
processor: reject two markdown files claiming the same inbox image
The pre-scan claimedByMarkdown used to mark an image as claimed by any
markdown that referenced it, but it did not prevent two different markdown
files from referencing the same image. When that happened, the first file
processed would copy the image into its post directory and then delete it
from the inbox. The second file then failed because the source image was
already gone.
Fix: make image claiming exclusive. claimedByMarkdown now tracks the
owning markdown filename for each claimed image and returns an error
immediately during the pre-scan if a conflict is detected. This way no
sources are removed and no partial posts are created.
Also add tests:
- twoMarkdownsClaimingSameImageFails (negative)
- duplicateImageClaimsInSameMarkdownAllowed (positive)
Diffstat (limited to 'internal/processor/processor_test.go')
| -rw-r--r-- | internal/processor/processor_test.go | 79 |
1 files changed, 79 insertions, 0 deletions
diff --git a/internal/processor/processor_test.go b/internal/processor/processor_test.go index 3b34675..418fb95 100644 --- a/internal/processor/processor_test.go +++ b/internal/processor/processor_test.go @@ -5,6 +5,7 @@ import ( "image/png" "os" "path/filepath" + "strings" "testing" "time" @@ -236,3 +237,81 @@ text` t.Fatal(err) } } + +func TestRun_twoMarkdownsClaimingSameImageFails(t *testing.T) { + t.Parallel() + + in := t.TempDir() + out := t.TempDir() + + // Shared image in the inbox. + pngPath := filepath.Join(in, "pic.png") + f, err := os.Create(pngPath) + if err != nil { + t.Fatal(err) + } + if err := png.Encode(f, image.NewRGBA(image.Rect(0, 0, 2, 2))); err != nil { + f.Close() + t.Fatal(err) + } + f.Close() + + // Two markdown files both reference the same image. + if err := os.WriteFile(filepath.Join(in, "a.md"), []byte("\n"), 0o644); err != nil { + t.Fatal(err) + } + if err := os.WriteFile(filepath.Join(in, "b.md"), []byte("\n"), 0o644); err != nil { + t.Fatal(err) + } + + _, err = Run(&config.Config{InputDir: in, OutputDir: out, BaseURL: "https://x"}) + if err == nil { + t.Fatal("expected error when two markdowns claim the same image") + } + if !strings.Contains(err.Error(), "pic.png") { + t.Fatalf("error should mention the conflicting image, got: %v", err) + } + + // Verify that no post directories were created and no source files deleted. + entries, _ := os.ReadDir(filepath.Join(out, "posts")) + if len(entries) != 0 { + t.Fatalf("expected no posts created, got %d", len(entries)) + } + for _, name := range []string{"pic.png", "a.md", "b.md"} { + if _, err := os.Stat(filepath.Join(in, name)); err != nil { + t.Fatalf("source %s should still exist: %v", name, err) + } + } +} + +func TestRun_duplicateImageClaimsInSameMarkdownAllowed(t *testing.T) { + t.Parallel() + + in := t.TempDir() + out := t.TempDir() + + pngPath := filepath.Join(in, "pic.png") + f, err := os.Create(pngPath) + if err != nil { + t.Fatal(err) + } + if err := png.Encode(f, image.NewRGBA(image.Rect(0, 0, 2, 2))); err != nil { + f.Close() + t.Fatal(err) + } + f.Close() + + // Same markdown references the same image twice — should not be treated as a conflict. + md := "\n\n" + if err := os.WriteFile(filepath.Join(in, "post.md"), []byte(md), 0o644); err != nil { + t.Fatal(err) + } + + n, err := Run(&config.Config{InputDir: in, OutputDir: out, BaseURL: "https://x"}) + if err != nil { + t.Fatalf("Run: %v", err) + } + if n != 1 { + t.Fatalf("n=%d; want 1", n) + } +} |
