fix: add SidecarRoundtrip tests for D2-6

This commit is contained in:
2026-05-30 19:10:40 +02:00
parent ab6a03dc54
commit 60acda3fee
2 changed files with 76 additions and 1 deletions

View File

@@ -143,7 +143,7 @@ All reconciled to follow code. Specs must be self-consistent and match code.
| ~~D2-3~~ | ~~CreateAndPublishScript rule~~ | ~~script.allium:160~~ | **Resolved:** `create_and_publish_script/1` implemented in scripts.ex, 4 tests added (happy path with file assertions + macro entrypoint default + invalid Lua rejection + slug dedup on title conflict) |
| ~~D2-4~~ | ~~UniqueScriptSlug dedup~~ | ~~script.allium:115~~ | **Resolved:** test added asserting two scripts with same title produce unique slugs (`dup-slug``dup-slug-2`) |
| D2-5 | ~~FrontmatterRoundtrip invariant~~ | post.allium:223 | **Resolved:** test added — creates post with all fields, publishes, parses file back via `Frontmatter.parse_document`, asserts every field (id, title, slug, excerpt, status, author, language, doNotTranslate, templateSlug, tags, categories, createdAt, updatedAt, publishedAt, body) matches the published DB record |
| D2-6 | SidecarRoundtrip invariant | media.allium:198 | Write test: write sidecar, read back, assert all fields match |
| ~~D2-6~~ | ~~SidecarRoundtrip invariant~~ | ~~media.allium:198~~ | **Resolved:** 2 tests added — full roundtrip (write sidecar, parse via `Sidecar.parse_document/1`, assert all fields match DB) + nil conditional fields absent from parsed sidecar |
| D2-7 | ConditionalPostFields: nil fields absent from frontmatter | frontmatter.allium:398 | Write test: post with nil excerpt/author/language → fields not in file |
| D2-8 | ConditionalMediaFields: nil fields absent from sidecar | frontmatter.allium:417 | Write test: media with nil title/alt → fields not in sidecar |
| D2-9 | max_posts_per_page 1..500 constraint | metadata.allium:75-77 | Write test: values outside range rejected |

View File

@@ -642,6 +642,81 @@ defmodule BDS.MediaTest do
assert %{language: ["has already been taken"]} = errors_on(changeset)
end
test "SidecarRoundtrip: writing then parsing a sidecar yields matching DB metadata", %{
project: project,
temp_dir: temp_dir
} do
source_path = Path.join(temp_dir, "roundtrip.txt")
File.write!(source_path, "hello media")
assert {:ok, media} =
BDS.Media.import_media(%{
project_id: project.id,
source_path: source_path,
title: "Roundtrip Title",
alt: "Roundtrip Alt",
caption: "Roundtrip Caption",
author: "Tester",
language: "en",
tags: ["alpha", "beta"]
})
sidecar_path = Path.join(temp_dir, media.sidecar_path)
{:ok, contents} = File.read(sidecar_path)
{:ok, parsed} = BDS.Sidecar.parse_document(contents)
assert parsed["title"] == media.title
assert parsed["alt"] == media.alt
assert parsed["caption"] == media.caption
assert parsed["tags"] == media.tags
assert parsed["id"] == media.id
assert parsed["originalName"] == media.original_name
assert parsed["mimeType"] == media.mime_type
assert parsed["size"] == media.size
assert parsed["author"] == media.author
assert parsed["language"] == media.language
assert parsed["createdAt"] == media.created_at
assert parsed["updatedAt"] == media.updated_at
end
test "SidecarRoundtrip: conditional fields are absent from parsed sidecar when nil", %{
project: project,
temp_dir: temp_dir
} do
source_path = Path.join(temp_dir, "minimal.txt")
File.write!(source_path, "hello media")
assert {:ok, media} =
BDS.Media.import_media(%{
project_id: project.id,
source_path: source_path
})
assert media.title == nil
assert media.alt == nil
assert media.caption == nil
assert media.author == nil
assert media.language == nil
sidecar_path = Path.join(temp_dir, media.sidecar_path)
{:ok, contents} = File.read(sidecar_path)
{:ok, parsed} = BDS.Sidecar.parse_document(contents)
refute Map.has_key?(parsed, "title")
refute Map.has_key?(parsed, "alt")
refute Map.has_key?(parsed, "caption")
refute Map.has_key?(parsed, "author")
refute Map.has_key?(parsed, "language")
assert Map.has_key?(parsed, "id")
assert Map.has_key?(parsed, "originalName")
assert Map.has_key?(parsed, "mimeType")
assert Map.has_key?(parsed, "size")
assert Map.has_key?(parsed, "tags")
assert Map.has_key?(parsed, "createdAt")
assert Map.has_key?(parsed, "updatedAt")
end
defp errors_on(changeset) do
Ecto.Changeset.traverse_errors(changeset, fn {message, opts} ->
Regex.replace(~r"%{(\w+)}", message, fn _, key ->