fix(style): replace Map.get with dot access and pattern matching where keys are guaranteed (CSM-032)

This commit is contained in:
2026-05-27 18:33:42 +02:00
parent d18e0ef7f2
commit f2b340ba86
19 changed files with 216 additions and 79 deletions

View File

@@ -468,10 +468,35 @@
--- ---
### CSM-032 — `Map.get` with Default Instead of Pattern Matching ### ~~CSM-032 — `Map.get` with Default Instead of Pattern Matching~~ ✅ FIXED
- **Files:** Widespread - **Fixed:** 2026-05-27
- **What:** `Map.get(map, key, default)` when the key is expected to exist. - **What was done:**
- **Fix:** Use pattern matching (`%{key: value} = map`) or `Map.fetch!/2` if the key is required. - **Metadata struct access** — Replaced `Map.get(metadata, :key)` / `Map.get(metadata, :key, default)` with dot access (`metadata.key`) across 10 files that consume the well-defined metadata map from `Metadata.load_state()`:
- `lib/bds/posts/translation_validation.ex``:main_language`, `:blog_languages`
- `lib/bds/posts/auto_translation.ex``:main_language`, `:blog_languages`
- `lib/bds/desktop/shell_commands.ex``:main_language`, `:blog_languages`
- `lib/bds/desktop/shell_live/settings_editor/project_settings.ex` — all 10 metadata fields
- `lib/bds/desktop/shell_live/settings_editor/style_editor.ex``:pico_theme`
- `lib/bds/desktop/shell_live/settings_editor/managed_categories.ex``:categories`, `:category_settings`
- `lib/bds/desktop/shell_live/settings_editor/publishing_settings.ex``:publishing_preferences`
- `lib/bds/desktop/shell_live/import_editor/taxonomy_editing.ex``:categories`
- `lib/bds/desktop/shell_live/import_editor/analysis_state.ex``:default_author`
- `lib/bds/import_execution.ex``:default_author`
- **Overlay context maps** — Replaced `Map.get(delete_details, :key, default)` and `Map.get(merge, :key, default)` with pattern matching in `lib/bds/desktop/overlay.ex`:
- `open(:media, :confirm_delete, ...)` — pattern matches `%{title:, entity_name:, entity_type:, reference_list:}` from `context.delete_details`
- `open(:tags, :confirm_merge, ...)` — pattern matches `%{title:, message:}` from `context.merge_details`
- `normalize_ai_fields/1` — pattern matches `%{key:, label:, current_value:, suggested_value:, locked:}` from each field
- `language_picker/2` — extracts `existing_translations`, `language_names`, `language_flags` into local bindings before the loop, eliminating nested `Map.get(Map.get(...))` calls
- **Overlay media/post maps** — Replaced `Map.get(media, :field)` with dot access in `to_insert_media_result`, `to_gallery_image`, `gallery_images`, search filtering, and `to_insert_link_result` (media/post maps are built with known keys by `overlay_components.ex`)
- **Generation pipeline** — Replaced `Map.get(post, :field)` with `post.field` for Post struct fields across:
- `lib/bds/generation/data.ex``:author`, `:tags`, `:categories`, `:template_slug`, `:do_not_translate`, `:language` in `build_published_translation_variant` and `resolve_posts_for_language`
- `lib/bds/generation/outputs.ex``:language` (all occurrences)
- `lib/bds/generation/validation.ex``:file_path`
- `lib/bds/generation/sitemap.ex``:do_not_translate`
- `lib/bds/preview.ex``:template_slug`
- Kept `Map.get` where appropriate: dynamic field access (`Map.get(post, field)` with variable keys), truly optional keys (`:translation_source_slug` on mixed struct/map lists), external data lookups (string-keyed JSON, form params), and hash-map lookups with defaults.
- Updated `test/bds/desktop/overlay_test.exs` to provide complete `delete_details` and `merge_details` maps matching the real contract from `overlay_components.ex`.
- Added 18 tests in `test/bds/csm032_map_get_pattern_match_test.exs`: source-level assertions that metadata consumers use dot access, overlay uses pattern matching for known structures, and generation pipeline uses dot access for Post struct fields.
--- ---

View File

@@ -48,29 +48,32 @@ defmodule BDS.Desktop.Overlay do
end end
def open(:media, :confirm_delete, context) do def open(:media, :confirm_delete, context) do
delete_details = Map.get(context, :delete_details, %{}) %{
title: title,
entity_name: entity_name,
entity_type: entity_type,
reference_list: reference_list
} = context.delete_details
%{ %{
kind: :confirm_delete, kind: :confirm_delete,
title: Map.get(delete_details, :title, "Delete"), title: title,
entity_name: Map.get(delete_details, :entity_name, ""), entity_name: entity_name,
entity_type: Map.get(delete_details, :entity_type, "media"), entity_type: entity_type,
reference_count: length(Map.get(delete_details, :reference_list, [])), reference_count: length(reference_list),
reference_list: Map.get(delete_details, :reference_list, []) reference_list: reference_list
} }
end end
def open(:tags, :confirm_delete, context), do: open(:media, :confirm_delete, context) def open(:tags, :confirm_delete, context), do: open(:media, :confirm_delete, context)
def open(:tags, :confirm_merge, context) do def open(:tags, :confirm_merge, context) do
merge = Map.get(context, :merge_details, %{}) %{title: title, message: message} = context.merge_details
target = Map.get(merge, :target, "")
count = Map.get(merge, :count, 0)
%{ %{
kind: :confirm_dialog, kind: :confirm_dialog,
title: Map.get(merge, :title, "Merge #{count} tags into #{target}?"), title: title,
message: Map.get(merge, :message, "Cannot be undone.") message: message
} }
end end
@@ -115,8 +118,8 @@ defmodule BDS.Desktop.Overlay do
|> Map.get(:all_media, []) |> Map.get(:all_media, [])
|> Enum.filter(fn media -> |> Enum.filter(fn media ->
normalized == "" or normalized == "" or
search_matches?(Map.get(media, :title, ""), normalized) or search_matches?(media.title, normalized) or
search_matches?(Map.get(media, :original_name, ""), normalized) search_matches?(media.original_name, normalized)
end) end)
|> Enum.map(&to_insert_media_result/1) |> Enum.map(&to_insert_media_result/1)
@@ -203,18 +206,22 @@ defmodule BDS.Desktop.Overlay do
def insert_media_result(_overlay, _media_id), do: nil def insert_media_result(_overlay, _media_id), do: nil
defp language_picker(context, source_language) do defp language_picker(context, source_language) do
existing_translations = Map.get(context, :existing_translations, %{})
language_names = Map.get(context, :language_names, %{})
language_flags = Map.get(context, :language_flags, %{})
targets = targets =
context context
|> Map.get(:blog_languages, []) |> Map.get(:blog_languages, [])
|> Enum.uniq() |> Enum.uniq()
|> Enum.reject(&(&1 == source_language)) |> Enum.reject(&(&1 == source_language))
|> Enum.map(fn code -> |> Enum.map(fn code ->
existing_status = Map.get(Map.get(context, :existing_translations, %{}), code) existing_status = Map.get(existing_translations, code)
%{ %{
code: code, code: code,
name: Map.get(Map.get(context, :language_names, %{}), code, String.upcase(code)), name: Map.get(language_names, code, String.upcase(code)),
flag_emoji: Map.get(Map.get(context, :language_flags, %{}), code, code), flag_emoji: Map.get(language_flags, code, code),
has_existing_translation: not is_nil(existing_status), has_existing_translation: not is_nil(existing_status),
existing_status: existing_status existing_status: existing_status
} }
@@ -255,14 +262,15 @@ defmodule BDS.Desktop.Overlay do
def set_ai_suggestions_error(overlay, _error_message), do: overlay def set_ai_suggestions_error(overlay, _error_message), do: overlay
defp normalize_ai_fields(fields) do defp normalize_ai_fields(fields) do
Enum.map(fields, fn field -> Enum.map(fields, fn %{key: key, label: label, current_value: current,
suggested_value: suggested, locked: locked} = field ->
%{ %{
key: to_string(Map.get(field, :key, "")), key: to_string(key),
label: Map.get(field, :label, ""), label: label,
current_value: Map.get(field, :current_value, ""), current_value: current,
suggested_value: Map.get(field, :suggested_value, ""), suggested_value: suggested,
accepted: not Map.get(field, :locked, false), accepted: not locked,
locked: Map.get(field, :locked, false), locked: locked,
loading: Map.get(field, :loading, false) loading: Map.get(field, :loading, false)
} }
end) end)
@@ -276,7 +284,7 @@ defmodule BDS.Desktop.Overlay do
end end
defp gallery_images(context) do defp gallery_images(context) do
images = Enum.filter(Map.get(context, :media, []), &Map.get(&1, :is_image, false)) images = Enum.filter(Map.get(context, :media, []), & &1.is_image)
post_media_ids = Map.get(context, :post_media_ids, []) post_media_ids = Map.get(context, :post_media_ids, [])
case Enum.filter(images, &(&1.id in post_media_ids)) do case Enum.filter(images, &(&1.id in post_media_ids)) do
@@ -289,29 +297,29 @@ defmodule BDS.Desktop.Overlay do
%{ %{
post_id: post.id, post_id: post.id,
title: post.title, title: post.title,
status: to_string(Map.get(post, :status, "draft")), status: post.status,
canonical_url: Map.get(post, :canonical_url, "/posts/#{post.id}"), canonical_url: post.canonical_url,
similarity_score: Map.get(post, :similarity_score) similarity_score: nil
} }
end end
defp to_insert_media_result(media) do defp to_insert_media_result(media) do
%{ %{
media_id: media.id, media_id: media.id,
title: Map.get(media, :title, ""), title: media.title,
original_name: Map.get(media, :original_name, media.id), original_name: media.original_name,
is_image: Map.get(media, :is_image, false), is_image: media.is_image,
thumbnail_url: Map.get(media, :thumbnail_url) thumbnail_url: media.thumbnail_url
} }
end end
defp to_gallery_image(media) do defp to_gallery_image(media) do
%{ %{
media_id: media.id, media_id: media.id,
thumbnail_url: Map.get(media, :thumbnail_url), thumbnail_url: media.thumbnail_url,
image_url: Map.get(media, :image_url, Map.get(media, :thumbnail_url)), image_url: media.image_url,
alt_text: Map.get(media, :alt_text), alt_text: media.alt_text,
title: Map.get(media, :title, Map.get(media, :original_name, media.id)) title: media.title
} }
end end

View File

@@ -449,7 +449,7 @@ defmodule BDS.Desktop.ShellCommands do
end end
defp translation_fill_enabled?(metadata) do defp translation_fill_enabled?(metadata) do
([Map.get(metadata, :main_language)] ++ Map.get(metadata, :blog_languages, [])) ([metadata.main_language] ++ metadata.blog_languages)
|> Enum.map(fn language -> |> Enum.map(fn language ->
language language
|> to_string() |> to_string()

View File

@@ -266,7 +266,7 @@ defmodule BDS.Desktop.ShellLive.ImportEditor.AnalysisState do
@spec default_author(term()) :: term() @spec default_author(term()) :: term()
def default_author(project_id) do def default_author(project_id) do
{:ok, metadata} = Metadata.get_project_metadata(project_id) {:ok, metadata} = Metadata.get_project_metadata(project_id)
Map.get(metadata, :default_author) metadata.default_author
end end
@spec suggested_definition_name(term()) :: term() @spec suggested_definition_name(term()) :: term()

View File

@@ -222,7 +222,7 @@ defmodule BDS.Desktop.ShellLive.ImportEditor.TaxonomyEditing do
{:ok, metadata} = Metadata.get_project_metadata(project_id) {:ok, metadata} = Metadata.get_project_metadata(project_id)
%{ %{
categories: Enum.uniq(Map.get(metadata, :categories, []) || []), categories: Enum.uniq(metadata.categories || []),
tags: project_id |> Tags.list_tags() |> Enum.map(& &1.name) |> Enum.uniq() tags: project_id |> Tags.list_tags() |> Enum.map(& &1.name) |> Enum.uniq()
} }
end end

View File

@@ -22,8 +22,8 @@ defmodule BDS.Desktop.ShellLive.SettingsEditor.ManagedCategories do
@spec category_rows(term()) :: term() @spec category_rows(term()) :: term()
def category_rows(metadata) do def category_rows(metadata) do
categories = Map.get(metadata, :categories, []) categories = metadata.categories
settings = Map.get(metadata, :category_settings, %{}) settings = metadata.category_settings
Enum.map(categories, fn category -> Enum.map(categories, fn category ->
category_settings = Map.get(settings, category, %{}) category_settings = Map.get(settings, category, %{})
@@ -167,7 +167,7 @@ defmodule BDS.Desktop.ShellLive.SettingsEditor.ManagedCategories do
end end
end end
defp category_names(metadata), do: Map.get(metadata, :categories, []) defp category_names(metadata), do: metadata.categories
defp ensure_default_categories(project_id) do defp ensure_default_categories(project_id) do
Enum.reduce_while(Map.keys(@default_category_settings), :ok, fn category, _acc -> Enum.reduce_while(Map.keys(@default_category_settings), :ok, fn category, _acc ->

View File

@@ -16,17 +16,17 @@ defmodule BDS.Desktop.ShellLive.SettingsEditor.ProjectSettings do
@spec project_form(term()) :: term() @spec project_form(term()) :: term()
def project_form(metadata) do def project_form(metadata) do
%{ %{
"name" => Map.get(metadata, :name, ""), "name" => metadata.name || "",
"description" => Map.get(metadata, :description, ""), "description" => metadata.description || "",
"public_url" => Map.get(metadata, :public_url, ""), "public_url" => metadata.public_url || "",
"main_language" => Map.get(metadata, :main_language) || "en", "main_language" => metadata.main_language || "en",
"default_author" => Map.get(metadata, :default_author, ""), "default_author" => metadata.default_author || "",
"max_posts_per_page" => Integer.to_string(Map.get(metadata, :max_posts_per_page, 50)), "max_posts_per_page" => Integer.to_string(metadata.max_posts_per_page),
"blogmark_category" => "blogmark_category" =>
Map.get(metadata, :blogmark_category) || metadata.blogmark_category ||
List.first(Map.get(metadata, :categories, [])) || "article", List.first(metadata.categories) || "article",
"blog_languages" => Map.get(metadata, :blog_languages, []), "blog_languages" => metadata.blog_languages,
"semantic_similarity_enabled" => Map.get(metadata, :semantic_similarity_enabled, false) "semantic_similarity_enabled" => metadata.semantic_similarity_enabled
} }
end end

View File

@@ -8,7 +8,7 @@ defmodule BDS.Desktop.ShellLive.SettingsEditor.PublishingSettings do
@spec publishing_form(term()) :: term() @spec publishing_form(term()) :: term()
def publishing_form(metadata) do def publishing_form(metadata) do
prefs = Map.get(metadata, :publishing_preferences, %{}) prefs = metadata.publishing_preferences
%{ %{
"ssh_host" => Map.get(prefs, "ssh_host", ""), "ssh_host" => Map.get(prefs, "ssh_host", ""),

View File

@@ -88,7 +88,7 @@ defmodule BDS.Desktop.ShellLive.SettingsEditor.StyleEditor do
def current_theme(assigns) do def current_theme(assigns) do
case Metadata.get_project_metadata(assigns.projects.active_project_id) do case Metadata.get_project_metadata(assigns.projects.active_project_id) do
{:ok, metadata} -> {:ok, metadata} ->
case Map.get(metadata, :pico_theme) do case metadata.pico_theme do
nil -> "default" nil -> "default"
"" -> "default" "" -> "default"
theme -> theme theme -> theme

View File

@@ -118,7 +118,7 @@ defmodule BDS.Generation.Data do
main = String.downcase(to_string(main_language || "")) main = String.downcase(to_string(main_language || ""))
Enum.map(posts, fn post -> Enum.map(posts, fn post ->
post_language = String.downcase(to_string(Map.get(post, :language) || "")) post_language = String.downcase(to_string(post.language || ""))
effective_language = if post_language == "", do: main, else: post_language effective_language = if post_language == "", do: main, else: post_language
cond do cond do
@@ -373,18 +373,18 @@ defmodule BDS.Generation.Data do
excerpt: translation.excerpt, excerpt: translation.excerpt,
content: nil, content: nil,
status: :published, status: :published,
author: Map.get(post, :author), author: post.author,
created_at: post.created_at, created_at: post.created_at,
updated_at: translation.updated_at, updated_at: translation.updated_at,
published_at: translation.published_at || post.published_at, published_at: translation.published_at || post.published_at,
file_path: translation.file_path, file_path: translation.file_path,
tags: Map.get(post, :tags, []), tags: post.tags,
categories: Map.get(post, :categories, []), categories: post.categories,
template_slug: Map.get(post, :template_slug), template_slug: post.template_slug,
language: translation.language, language: translation.language,
do_not_translate: Map.get(post, :do_not_translate, false), do_not_translate: post.do_not_translate,
translation_source_slug: post.slug, translation_source_slug: post.slug,
translation_canonical_language: Map.get(post, :language), translation_canonical_language: post.language,
translation_file_path: translation.file_path translation_file_path: translation.file_path
} }
end end

View File

@@ -21,7 +21,7 @@ defmodule BDS.Generation.Outputs do
Enum.reject(route_posts, fn post -> Enum.reject(route_posts, fn post ->
is_binary(Map.get(post, :translation_source_slug)) and is_binary(Map.get(post, :translation_source_slug)) and
MapSet.member?(subtree_languages, to_string(Map.get(post, :language))) MapSet.member?(subtree_languages, to_string(post.language))
end) end)
end end
@@ -432,11 +432,11 @@ defmodule BDS.Generation.Outputs do
title: post.title, title: post.title,
content: body, content: body,
slug: post.slug, slug: post.slug,
language: Map.get(post, :language), language: post.language,
excerpt: post.excerpt, excerpt: post.excerpt,
_post_record: post _post_record: post
}, },
fn -> render_post_page(post.title, body, post.slug, Map.get(post, :language)) end fn -> render_post_page(post.title, body, post.slug, post.language) end
)} )}
end) end)
end) end)
@@ -560,11 +560,11 @@ defmodule BDS.Generation.Outputs do
title: post.title, title: post.title,
content: body, content: body,
slug: post.slug, slug: post.slug,
language: Map.get(post, :language), language: post.language,
excerpt: post.excerpt, excerpt: post.excerpt,
_post_record: post _post_record: post
}, },
fn -> render_post_page(post.title, body, post.slug, Map.get(post, :language)) end fn -> render_post_page(post.title, body, post.slug, post.language) end
)} )}
end) end)
end) end)

View File

@@ -75,7 +75,7 @@ defmodule BDS.Generation.Sitemap do
page_path = Paths.relative_path_to_url_path(Paths.page_output_path(post.slug, nil)) page_path = Paths.relative_path_to_url_path(Paths.page_output_path(post.slug, nil))
languages = languages =
if Paths.truthy_flag?(Map.get(post, :do_not_translate)), if Paths.truthy_flag?(post.do_not_translate),
do: [plan.language], do: [plan.language],
else: all_languages else: all_languages

View File

@@ -34,7 +34,7 @@ defmodule BDS.Generation.Validation do
post_file_path: post_file_path:
source_full_path( source_full_path(
project_data_dir, project_data_dir,
Map.get(post, :translation_file_path) || Map.get(post, :file_path) Map.get(post, :translation_file_path) || post.file_path
), ),
generated_updated_at_ms: Map.get(generated_file_updated_at, relative_path, 0) generated_updated_at_ms: Map.get(generated_file_updated_at, relative_path, 0)
} }
@@ -53,7 +53,7 @@ defmodule BDS.Generation.Validation do
%{ %{
post_url_path: relative_path_to_url_path(relative_path), post_url_path: relative_path_to_url_path(relative_path),
post_file_path: source_full_path(project_data_dir, Map.get(post, :file_path)), post_file_path: source_full_path(project_data_dir, post.file_path),
generated_updated_at_ms: Map.get(generated_file_updated_at, relative_path, 0) generated_updated_at_ms: Map.get(generated_file_updated_at, relative_path, 0)
} }
end) end)

View File

@@ -605,6 +605,6 @@ defmodule BDS.ImportExecution do
defp project_default_author(project_id) do defp project_default_author(project_id) do
{:ok, metadata} = Metadata.get_project_metadata(project_id) {:ok, metadata} = Metadata.get_project_metadata(project_id)
Map.get(metadata, :default_author) metadata.default_author
end end
end end

View File

@@ -252,7 +252,7 @@ defmodule BDS.Posts.AutoTranslation do
end end
defp configured_languages(metadata) do defp configured_languages(metadata) do
([Map.get(metadata, :main_language)] ++ Map.get(metadata, :blog_languages, [])) ([metadata.main_language] ++ metadata.blog_languages)
|> Enum.map(&normalize_language/1) |> Enum.map(&normalize_language/1)
|> Enum.reject(&(&1 in [nil, ""])) |> Enum.reject(&(&1 in [nil, ""]))
|> Enum.uniq() |> Enum.uniq()

View File

@@ -312,7 +312,7 @@ defmodule BDS.Posts.TranslationValidation do
defp legacy_missing_entries(source_posts, translation_rows, metadata) do defp legacy_missing_entries(source_posts, translation_rows, metadata) do
configured_languages = configured_languages =
([Map.get(metadata, :main_language)] ++ Map.get(metadata, :blog_languages, [])) ([metadata.main_language] ++ metadata.blog_languages)
|> Enum.map(&do_normalize_language/1) |> Enum.map(&do_normalize_language/1)
|> Enum.reject(&(&1 in [nil, ""])) |> Enum.reject(&(&1 in [nil, ""]))
|> Enum.uniq() |> Enum.uniq()
@@ -444,7 +444,7 @@ defmodule BDS.Posts.TranslationValidation do
language = do_normalize_language(source_post.language) language = do_normalize_language(source_post.language)
if language == "" do if language == "" do
do_normalize_language(Map.get(metadata, :main_language)) do_normalize_language(metadata.main_language)
else else
language language
end end

View File

@@ -101,7 +101,7 @@ defmodule BDS.Preview do
with :ok <- ensure_running(state.current, project_id), with :ok <- ensure_running(state.current, project_id),
{:ok, payload} <- load_draft_preview_payload(project_id, post_id, query_params) do {:ok, payload} <- load_draft_preview_payload(project_id, post_id, query_params) do
body = body =
case Rendering.render_post_page(project_id, Map.get(payload, :template_slug), payload) do case Rendering.render_post_page(project_id, payload.template_slug, payload) do
{:ok, rendered} -> rendered {:ok, rendered} -> rendered
{:error, _reason} -> render_draft(payload) {:error, _reason} -> render_draft(payload)
end end
@@ -178,7 +178,7 @@ defmodule BDS.Preview do
defp resolve_draft_request(project_id, post_id, query_params) do defp resolve_draft_request(project_id, post_id, query_params) do
with {:ok, payload} <- load_draft_preview_payload(project_id, post_id, query_params) do with {:ok, payload} <- load_draft_preview_payload(project_id, post_id, query_params) do
body = body =
case Rendering.render_post_page(project_id, Map.get(payload, :template_slug), payload) do case Rendering.render_post_page(project_id, payload.template_slug, payload) do
{:ok, rendered} -> rendered {:ok, rendered} -> rendered
{:error, _reason} -> render_draft(payload) {:error, _reason} -> render_draft(payload)
end end

View File

@@ -0,0 +1,98 @@
defmodule BDS.CSM032MapGetPatternMatchTest do
use ExUnit.Case, async: true
@metadata_consumers [
"lib/bds/posts/translation_validation.ex",
"lib/bds/posts/auto_translation.ex",
"lib/bds/desktop/shell_commands.ex",
"lib/bds/desktop/shell_live/settings_editor/project_settings.ex",
"lib/bds/desktop/shell_live/settings_editor/style_editor.ex",
"lib/bds/desktop/shell_live/settings_editor/managed_categories.ex",
"lib/bds/desktop/shell_live/settings_editor/publishing_settings.ex",
"lib/bds/desktop/shell_live/import_editor/taxonomy_editing.ex",
"lib/bds/desktop/shell_live/import_editor/analysis_state.ex",
"lib/bds/import_execution.ex"
]
@metadata_atom_keys ~w(main_language blog_languages categories category_settings
publishing_preferences name description public_url default_author
max_posts_per_page blogmark_category pico_theme
semantic_similarity_enabled)
describe "source-level: no Map.get(metadata, :atom_key) on metadata struct" do
for file <- @metadata_consumers do
test "#{Path.basename(file)} uses dot access instead of Map.get for metadata atom keys" do
source = File.read!(unquote(file))
for key <- @metadata_atom_keys do
refute source =~ "Map.get(metadata, :#{key}",
"#{unquote(file)} should use metadata.#{key} instead of Map.get(metadata, :#{key})"
end
end
end
end
describe "source-level: overlay.ex uses pattern matching for known structures" do
test "delete_details uses pattern matching instead of Map.get" do
source = File.read!("lib/bds/desktop/overlay.ex")
refute source =~ "Map.get(delete_details,",
"overlay.ex should pattern match delete_details instead of using Map.get"
end
test "merge_details uses pattern matching instead of Map.get" do
source = File.read!("lib/bds/desktop/overlay.ex")
refute source =~ "Map.get(merge,",
"overlay.ex should pattern match merge_details instead of using Map.get"
end
test "media struct fields use dot access in to_insert_media_result" do
source = File.read!("lib/bds/desktop/overlay.ex")
refute source =~ ~r/to_insert_media_result.*Map\.get\(media/s &&
source =~ "defp to_insert_media_result",
"to_insert_media_result should use dot access for media fields"
end
test "media struct fields use dot access in to_gallery_image" do
source = File.read!("lib/bds/desktop/overlay.ex")
refute source =~ ~r/to_gallery_image.*Map\.get\(media/s &&
source =~ "defp to_gallery_image",
"to_gallery_image should use dot access for media fields"
end
end
describe "source-level: generation pipeline uses dot access for Post struct fields" do
test "outputs.ex uses post.language instead of Map.get(post, :language)" do
source = File.read!("lib/bds/generation/outputs.ex")
refute source =~ "Map.get(post, :language)",
"outputs.ex should use post.language"
end
test "data.ex uses dot access for Post struct fields in build_published_translation_variant" do
source = File.read!("lib/bds/generation/data.ex")
refute source =~ "Map.get(post, :author)",
"data.ex should use post.author"
refute source =~ "Map.get(post, :tags",
"data.ex should use post.tags"
refute source =~ "Map.get(post, :categories",
"data.ex should use post.categories"
refute source =~ "Map.get(post, :template_slug)",
"data.ex should use post.template_slug"
refute source =~ "Map.get(post, :do_not_translate",
"data.ex should use post.do_not_translate"
end
test "validation.ex uses post.file_path instead of Map.get(post, :file_path)" do
source = File.read!("lib/bds/generation/validation.ex")
refute source =~ "Map.get(post, :file_path)",
"validation.ex should use post.file_path"
end
test "sitemap.ex uses post.do_not_translate instead of Map.get" do
source = File.read!("lib/bds/generation/sitemap.ex")
refute source =~ "Map.get(post, :do_not_translate)",
"sitemap.ex should use post.do_not_translate"
end
end
end

View File

@@ -206,11 +206,17 @@ defmodule BDS.Desktop.OverlayTest do
} }
], ],
delete_details: %{ delete_details: %{
title: "Delete Media",
entity_name: "Street Scene", entity_name: "Street Scene",
entity_type: "media", entity_type: "media",
reference_list: ["Photo Walk", "Trip Notes"] reference_list: ["Photo Walk", "Trip Notes"]
}, },
merge_details: %{target: "travel", count: 3} merge_details: %{
target: "travel",
count: 3,
title: "Merge 3 tags into travel?",
message: "Cannot be undone."
}
} }
end end
end end