fix: update_project_metadata keeps fields absent from attrs instead of resetting them
This commit is contained in:
2
API.md
2
API.md
@@ -3443,7 +3443,7 @@ local result = bds.meta.sync_on_startup()
|
|||||||
|
|
||||||
### meta.update_project_metadata
|
### meta.update_project_metadata
|
||||||
|
|
||||||
Update metadata for the current project.
|
Update metadata for the current project. Keys omitted from updates keep their current values.
|
||||||
|
|
||||||
**Parameters**
|
**Parameters**
|
||||||
|
|
||||||
|
|||||||
@@ -318,6 +318,8 @@ defmodule BDS.Metadata do
|
|||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Keys absent from attrs are left out entirely, so the merge in
|
||||||
|
# update_project_metadata/2 keeps their current values (partial update).
|
||||||
defp normalize_project_metadata_attrs(attrs, project) do
|
defp normalize_project_metadata_attrs(attrs, project) do
|
||||||
%{
|
%{
|
||||||
name: attr(attrs, :name) || project.name,
|
name: attr(attrs, :name) || project.name,
|
||||||
@@ -333,6 +335,26 @@ defmodule BDS.Metadata do
|
|||||||
semantic_similarity_enabled: attr(attrs, :semantic_similarity_enabled) || false,
|
semantic_similarity_enabled: attr(attrs, :semantic_similarity_enabled) || false,
|
||||||
blog_languages: normalize_language_list(attr(attrs, :blog_languages) || [])
|
blog_languages: normalize_language_list(attr(attrs, :blog_languages) || [])
|
||||||
}
|
}
|
||||||
|
|> Map.take(present_attr_keys(attrs))
|
||||||
|
end
|
||||||
|
|
||||||
|
defp present_attr_keys(attrs) do
|
||||||
|
Enum.filter(
|
||||||
|
[
|
||||||
|
:name,
|
||||||
|
:description,
|
||||||
|
:public_url,
|
||||||
|
:main_language,
|
||||||
|
:default_author,
|
||||||
|
:max_posts_per_page,
|
||||||
|
:image_import_concurrency,
|
||||||
|
:blogmark_category,
|
||||||
|
:pico_theme,
|
||||||
|
:semantic_similarity_enabled,
|
||||||
|
:blog_languages
|
||||||
|
],
|
||||||
|
fn key -> Map.has_key?(attrs, key) or Map.has_key?(attrs, Atom.to_string(key)) end
|
||||||
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
defp normalize_category_settings(settings) do
|
defp normalize_category_settings(settings) do
|
||||||
|
|||||||
@@ -762,7 +762,8 @@ defmodule BDS.Scripting.ApiDocs do
|
|||||||
%{
|
%{
|
||||||
module: "meta",
|
module: "meta",
|
||||||
name: "update_project_metadata",
|
name: "update_project_metadata",
|
||||||
description: "Update metadata for the current project.",
|
description:
|
||||||
|
"Update metadata for the current project. Keys omitted from updates keep their current values.",
|
||||||
params: [%{name: "updates", type: "table", required: true}],
|
params: [%{name: "updates", type: "table", required: true}],
|
||||||
returns: "ProjectMetadata | nil"
|
returns: "ProjectMetadata | nil"
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -388,30 +388,8 @@ defmodule BDS.UI.SettingsForm do
|
|||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
# Project, technology and style all live in the same metadata record;
|
|
||||||
# `Metadata.update_project_metadata/2` treats missing keys as nil, so the
|
|
||||||
# current values are always passed along and only the edits override them.
|
|
||||||
defp save_project_metadata(project_id, overrides) do
|
defp save_project_metadata(project_id, overrides) do
|
||||||
{:ok, metadata} = Metadata.get_project_metadata(project_id)
|
case Metadata.update_project_metadata(project_id, overrides) do
|
||||||
|
|
||||||
attrs =
|
|
||||||
metadata
|
|
||||||
|> Map.take([
|
|
||||||
:name,
|
|
||||||
:description,
|
|
||||||
:public_url,
|
|
||||||
:main_language,
|
|
||||||
:default_author,
|
|
||||||
:max_posts_per_page,
|
|
||||||
:image_import_concurrency,
|
|
||||||
:blogmark_category,
|
|
||||||
:pico_theme,
|
|
||||||
:semantic_similarity_enabled,
|
|
||||||
:blog_languages
|
|
||||||
])
|
|
||||||
|> Map.merge(overrides)
|
|
||||||
|
|
||||||
case Metadata.update_project_metadata(project_id, attrs) do
|
|
||||||
{:ok, _metadata} -> :ok
|
{:ok, _metadata} -> :ok
|
||||||
{:error, reason} -> {:error, reason}
|
{:error, reason} -> {:error, reason}
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -54,6 +54,27 @@ defmodule BDS.MetadataTest do
|
|||||||
assert loaded.blog_languages == ["de", "fr"]
|
assert loaded.blog_languages == ["de", "fr"]
|
||||||
end
|
end
|
||||||
|
|
||||||
|
test "update_project_metadata keeps fields that are absent from the attrs", %{
|
||||||
|
project: project
|
||||||
|
} do
|
||||||
|
assert {:ok, _metadata} =
|
||||||
|
BDS.Metadata.update_project_metadata(project.id, %{
|
||||||
|
description: "Keep me",
|
||||||
|
public_url: "https://example.com",
|
||||||
|
default_author: "Writer",
|
||||||
|
blog_languages: ["de"]
|
||||||
|
})
|
||||||
|
|
||||||
|
assert {:ok, metadata} =
|
||||||
|
BDS.Metadata.update_project_metadata(project.id, %{pico_theme: "blue"})
|
||||||
|
|
||||||
|
assert metadata.pico_theme == "blue"
|
||||||
|
assert metadata.description == "Keep me"
|
||||||
|
assert metadata.public_url == "https://example.com"
|
||||||
|
assert metadata.default_author == "Writer"
|
||||||
|
assert metadata.blog_languages == ["de"]
|
||||||
|
end
|
||||||
|
|
||||||
test "update_project_metadata keeps committed database changes when filesystem flush fails", %{
|
test "update_project_metadata keeps committed database changes when filesystem flush fails", %{
|
||||||
project: project,
|
project: project,
|
||||||
temp_dir: temp_dir
|
temp_dir: temp_dir
|
||||||
|
|||||||
Reference in New Issue
Block a user