chore: added more @spec

This commit is contained in:
2026-05-01 17:49:50 +02:00
parent abcae1dad7
commit 881056eb61
157 changed files with 6223 additions and 1647 deletions

View File

@@ -121,6 +121,7 @@ defmodule BDS.UI.ShellTest do
test "desktop shell assets persist workbench layout per project" do
live_js = File.read!("/Users/gb/Projects/bDS2/priv/ui/live.js")
live_ex = File.read!("/Users/gb/Projects/bDS2/lib/bds/desktop/shell_live.ex")
session_util_ex =
File.read!("/Users/gb/Projects/bDS2/lib/bds/desktop/shell_live/session_util.ex")
@@ -214,7 +215,10 @@ defmodule BDS.UI.ShellTest do
refute live_js =~ "syncTitlebarMenuAnchor"
refute live_js =~ "handleTitlebarMenuKeyDown"
refute live_js =~ "keyboardMenuIndex"
assert template =~ "phx-window-keydown={if(@titlebar_menu_group, do: \"titlebar_menu_keydown\")}"
assert template =~
"phx-window-keydown={if(@titlebar_menu_group, do: \"titlebar_menu_keydown\")}"
assert template =~ "window-titlebar-menu-group"
assert live_ex =~ ~s(def handle_event("titlebar_menu_keydown")
assert live_ex =~ "titlebar_menu_item_index"
@@ -222,7 +226,11 @@ defmodule BDS.UI.ShellTest do
test "desktop shell css keeps the old media editor layout contract" do
css = File.read!("/Users/gb/Projects/bDS2/priv/ui/app.css")
template = File.read!("/Users/gb/Projects/bDS2/lib/bds/desktop/shell_live/media_editor_html/media_editor.html.heex")
template =
File.read!(
"/Users/gb/Projects/bDS2/lib/bds/desktop/shell_live/media_editor_html/media_editor.html.heex"
)
assert css =~ ".media-preview {"
assert css =~ "min-height: 300px;"
@@ -246,10 +254,20 @@ defmodule BDS.UI.ShellTest do
assert css =~ "padding: 6px 10px;"
assert css =~ ".linked-post-item:hover .unlink-btn {"
assert css =~ "opacity: 1;"
assert Regex.match?(~r/class="secondary quick-actions-btn".*?<span class="quick-actions-btn-icon">⚡<\/span>\s*<span class="quick-actions-btn-label"><%= translated\("Quick Actions"\) %><\/span>/s, template)
assert Regex.match?(
~r/class="secondary quick-actions-btn".*?<span class="quick-actions-btn-icon">⚡<\/span>\s*<span class="quick-actions-btn-label"><%= translated\("Quick Actions"\) %><\/span>/s,
template
)
assert template =~ ~s(class="quick-action-text")
assert template =~ ~s(class="quick-action-icon">🤖</span>)
assert Regex.match?(~r/class="quick-action-text">\s*<strong><%= translated\("AI Suggestions"\) %><\/strong>.*?<\/span>\s*<span class="quick-action-icon">🤖<\/span>/s, template)
assert Regex.match?(
~r/class="quick-action-text">\s*<strong><%= translated\("AI Suggestions"\) %><\/strong>.*?<\/span>\s*<span class="quick-action-icon">🤖<\/span>/s,
template
)
refute template =~ ~s|<span class="quick-action-icon">🤖</span>
<span class="quick-action-text">|
end
@@ -310,8 +328,14 @@ defmodule BDS.UI.ShellTest do
css = File.read!("/Users/gb/Projects/bDS2/priv/ui/app.css")
live_ex = File.read!("/Users/gb/Projects/bDS2/lib/bds/desktop/shell_live.ex")
template = File.read!("/Users/gb/Projects/bDS2/lib/bds/desktop/shell_live/index.html.heex")
overlay_ex = File.read!("/Users/gb/Projects/bDS2/lib/bds/desktop/shell_live/overlay_components.ex")
overlay_template = File.read!("/Users/gb/Projects/bDS2/lib/bds/desktop/shell_live/overlay_html/shell_overlay.html.heex")
overlay_ex =
File.read!("/Users/gb/Projects/bDS2/lib/bds/desktop/shell_live/overlay_components.ex")
overlay_template =
File.read!(
"/Users/gb/Projects/bDS2/lib/bds/desktop/shell_live/overlay_html/shell_overlay.html.heex"
)
assert template =~ "render_editor_toolbar(assigns)"
assert template =~ "<ShellOverlayComponents.shell_overlay"
@@ -339,12 +363,22 @@ defmodule BDS.UI.ShellTest do
test "desktop shell keeps post editor logic in the feature slice" do
live_ex = File.read!("/Users/gb/Projects/bDS2/lib/bds/desktop/shell_live.ex")
template = File.read!("/Users/gb/Projects/bDS2/lib/bds/desktop/shell_live/index.html.heex")
post_editor_ex = File.read!("/Users/gb/Projects/bDS2/lib/bds/desktop/shell_live/post_editor.ex")
post_template = File.read!("/Users/gb/Projects/bDS2/lib/bds/desktop/shell_live/post_editor_html/post_editor.html.heex")
post_editor_ex =
File.read!("/Users/gb/Projects/bDS2/lib/bds/desktop/shell_live/post_editor.ex")
post_template =
File.read!(
"/Users/gb/Projects/bDS2/lib/bds/desktop/shell_live/post_editor_html/post_editor.html.heex"
)
assert template =~ "<PostEditor.post_editor"
assert post_editor_ex =~ "def build(%{current_tab: %{type: :post, id: post_id}} = assigns)"
assert Regex.match?(~r/class="secondary quick-actions-btn".*?<span class="quick-actions-btn-icon">⚡<\/span>\s*<span class="quick-actions-btn-label"><%= translated\("Quick Actions"\) %><\/span>/s, post_template)
assert Regex.match?(
~r/class="secondary quick-actions-btn".*?<span class="quick-actions-btn-icon">⚡<\/span>\s*<span class="quick-actions-btn-label"><%= translated\("Quick Actions"\) %><\/span>/s,
post_template
)
refute live_ex =~ "defp update_post_editor("
refute live_ex =~ "defp persist_post_editor("
@@ -356,7 +390,9 @@ defmodule BDS.UI.ShellTest do
test "desktop shell keeps media editor logic in the feature slice" do
live_ex = File.read!("/Users/gb/Projects/bDS2/lib/bds/desktop/shell_live.ex")
template = File.read!("/Users/gb/Projects/bDS2/lib/bds/desktop/shell_live/index.html.heex")
media_editor_ex = File.read!("/Users/gb/Projects/bDS2/lib/bds/desktop/shell_live/media_editor.ex")
media_editor_ex =
File.read!("/Users/gb/Projects/bDS2/lib/bds/desktop/shell_live/media_editor.ex")
assert template =~ "<MediaEditor.media_editor"
assert media_editor_ex =~ "def build(%{current_tab: %{type: :media, id: media_id}} = assigns)"
@@ -369,8 +405,12 @@ defmodule BDS.UI.ShellTest do
test "desktop shell keeps sidebar logic in its own slice" do
live_ex = File.read!("/Users/gb/Projects/bDS2/lib/bds/desktop/shell_live.ex")
template = File.read!("/Users/gb/Projects/bDS2/lib/bds/desktop/shell_live/index.html.heex")
sidebar_ex = File.read!("/Users/gb/Projects/bDS2/lib/bds/desktop/shell_live/sidebar_components.ex")
sidebar_state_ex = File.read!("/Users/gb/Projects/bDS2/lib/bds/desktop/shell_live/sidebar_state.ex")
sidebar_ex =
File.read!("/Users/gb/Projects/bDS2/lib/bds/desktop/shell_live/sidebar_components.ex")
sidebar_state_ex =
File.read!("/Users/gb/Projects/bDS2/lib/bds/desktop/shell_live/sidebar_state.ex")
assert template =~ "<ShellSidebarComponents.sidebar_content"
assert sidebar_ex =~ "def sidebar_content(assigns)"

View File

@@ -26,13 +26,24 @@ defmodule BDS.UI.SidebarTest do
%{project: project, temp_dir: temp_dir}
end
test "database-backed sidebar views follow the old app ordering keys", %{project: project, temp_dir: temp_dir} do
test "database-backed sidebar views follow the old app ordering keys", %{
project: project,
temp_dir: temp_dir
} do
assert {:ok, draft_old} = Posts.create_post(%{project_id: project.id, title: "Draft Old"})
assert {:ok, draft_new} = Posts.create_post(%{project_id: project.id, title: "Draft New"})
assert {:ok, published_old} = Posts.create_post(%{project_id: project.id, title: "Published Old"})
assert {:ok, published_new} = Posts.create_post(%{project_id: project.id, title: "Published New"})
assert {:ok, archived_old} = Posts.create_post(%{project_id: project.id, title: "Archived Old"})
assert {:ok, archived_new} = Posts.create_post(%{project_id: project.id, title: "Archived New"})
assert {:ok, published_old} =
Posts.create_post(%{project_id: project.id, title: "Published Old"})
assert {:ok, published_new} =
Posts.create_post(%{project_id: project.id, title: "Published New"})
assert {:ok, archived_old} =
Posts.create_post(%{project_id: project.id, title: "Archived Old"})
assert {:ok, archived_new} =
Posts.create_post(%{project_id: project.id, title: "Archived New"})
update_post_sidebar_row(draft_old.id, created_at: 1_000, updated_at: 9_000)
update_post_sidebar_row(draft_new.id, created_at: 2_000, updated_at: 1_000)
@@ -55,26 +66,77 @@ defmodule BDS.UI.SidebarTest do
file_path: "posts/published-new.md"
)
update_post_sidebar_row(archived_old.id, status: :archived, created_at: 5_000, updated_at: 9_000)
update_post_sidebar_row(archived_new.id, status: :archived, created_at: 6_000, updated_at: 1_000)
update_post_sidebar_row(archived_old.id,
status: :archived,
created_at: 5_000,
updated_at: 9_000
)
update_post_sidebar_row(archived_new.id,
status: :archived,
created_at: 6_000,
updated_at: 1_000
)
old_media_path = Path.join(temp_dir, "old-media.txt")
new_media_path = Path.join(temp_dir, "new-media.txt")
File.write!(old_media_path, "old media")
File.write!(new_media_path, "new media")
assert {:ok, old_media} = Media.import_media(%{project_id: project.id, source_path: old_media_path, title: "Old Media"})
assert {:ok, new_media} = Media.import_media(%{project_id: project.id, source_path: new_media_path, title: "New Media"})
assert {:ok, old_media} =
Media.import_media(%{
project_id: project.id,
source_path: old_media_path,
title: "Old Media"
})
assert {:ok, new_media} =
Media.import_media(%{
project_id: project.id,
source_path: new_media_path,
title: "New Media"
})
update_media_sidebar_row(old_media.id, created_at: 7_000, updated_at: 9_000)
update_media_sidebar_row(new_media.id, created_at: 8_000, updated_at: 1_000)
assert {:ok, old_script} = Scripts.create_script(%{project_id: project.id, title: "Old Script", kind: :utility, content: "print('old')", entrypoint: "main"})
assert {:ok, new_script} = Scripts.create_script(%{project_id: project.id, title: "New Script", kind: :utility, content: "print('new')", entrypoint: "main"})
assert {:ok, old_script} =
Scripts.create_script(%{
project_id: project.id,
title: "Old Script",
kind: :utility,
content: "print('old')",
entrypoint: "main"
})
assert {:ok, new_script} =
Scripts.create_script(%{
project_id: project.id,
title: "New Script",
kind: :utility,
content: "print('new')",
entrypoint: "main"
})
update_script_sidebar_row(old_script.id, 9_000)
update_script_sidebar_row(new_script.id, 10_000)
assert {:ok, old_template} = Templates.create_template(%{project_id: project.id, title: "Old Template", kind: :post, content: "old"})
assert {:ok, new_template} = Templates.create_template(%{project_id: project.id, title: "New Template", kind: :post, content: "new"})
assert {:ok, old_template} =
Templates.create_template(%{
project_id: project.id,
title: "Old Template",
kind: :post,
content: "old"
})
assert {:ok, new_template} =
Templates.create_template(%{
project_id: project.id,
title: "New Template",
kind: :post,
content: "new"
})
update_template_sidebar_row(old_template.id, 11_000)
update_template_sidebar_row(new_template.id, 12_000)
@@ -83,8 +145,12 @@ defmodule BDS.UI.SidebarTest do
update_chat_sidebar_row(old_chat.id, 13_000)
update_chat_sidebar_row(new_chat.id, 14_000)
assert {:ok, old_definition} = ImportDefinitions.create_definition(%{project_id: project.id, name: "Old Import"})
assert {:ok, new_definition} = ImportDefinitions.create_definition(%{project_id: project.id, name: "New Import"})
assert {:ok, old_definition} =
ImportDefinitions.create_definition(%{project_id: project.id, name: "Old Import"})
assert {:ok, new_definition} =
ImportDefinitions.create_definition(%{project_id: project.id, name: "New Import"})
update_import_sidebar_row(old_definition.id, 15_000)
update_import_sidebar_row(new_definition.id, 16_000)
@@ -125,18 +191,28 @@ defmodule BDS.UI.SidebarTest do
end
defp update_script_sidebar_row(script_id, updated_at) do
Repo.update_all(from(script in BDS.Scripts.Script, where: script.id == ^script_id), set: [updated_at: updated_at])
Repo.update_all(from(script in BDS.Scripts.Script, where: script.id == ^script_id),
set: [updated_at: updated_at]
)
end
defp update_template_sidebar_row(template_id, updated_at) do
Repo.update_all(from(template in BDS.Templates.Template, where: template.id == ^template_id), set: [updated_at: updated_at])
Repo.update_all(from(template in BDS.Templates.Template, where: template.id == ^template_id),
set: [updated_at: updated_at]
)
end
defp update_chat_sidebar_row(conversation_id, updated_at) do
Repo.update_all(from(conversation in BDS.AI.ChatConversation, where: conversation.id == ^conversation_id), set: [updated_at: updated_at])
Repo.update_all(
from(conversation in BDS.AI.ChatConversation, where: conversation.id == ^conversation_id),
set: [updated_at: updated_at]
)
end
defp update_import_sidebar_row(definition_id, updated_at) do
Repo.update_all(from(definition in BDS.ImportDefinitions.ImportDefinition, where: definition.id == ^definition_id), set: [updated_at: updated_at])
Repo.update_all(
from(definition in BDS.ImportDefinitions.ImportDefinition,
where: definition.id == ^definition_id
), set: [updated_at: updated_at])
end
end

View File

@@ -156,12 +156,18 @@ defmodule BDS.UI.WorkbenchTest do
)
assert status.right.post_status == nil
assert status.right.token_usage == %{input_tokens: 10, output_tokens: 20, cache_read_tokens: 3}
assert status.right.token_usage == %{
input_tokens: 10,
output_tokens: 20,
cache_read_tokens: 3
}
end
test "menu commands expose generic shell controls through a shared command model" do
state = Workbench.new(sidebar_visible: false, panel_visible: false)
groups = MenuBar.default_groups(dev_mode?: false)
item_ids = fn items ->
items
|> Enum.reject(&Map.get(&1, :separator, false))
@@ -221,6 +227,10 @@ defmodule BDS.UI.WorkbenchTest do
assert Enum.any?(final_state.tabs, &(&1.type == :settings and &1.id == "settings"))
assert Enum.any?(final_state.tabs, &(&1.type == :menu_editor and &1.id == "menu_editor"))
assert Enum.any?(final_state.tabs, &(&1.type == :find_duplicates and &1.id == "find_duplicates"))
assert Enum.any?(
final_state.tabs,
&(&1.type == :find_duplicates and &1.id == "find_duplicates")
)
end
end