From 2ba8be2fc6a4e70a1ea6690b37d2b60268153f40 Mon Sep 17 00:00:00 2001 From: Chili Palmer Date: Sat, 30 May 2026 20:02:36 +0200 Subject: [PATCH] Resolve D4-3: add WelcomeScreen/CSP/chart-surface tests for editor_chat.allium --- SPECGAPS.md | 6 +- test/bds/desktop/shell_live_test.exs | 95 ++++++++++++++++++++++++++++ 2 files changed, 98 insertions(+), 3 deletions(-) diff --git a/SPECGAPS.md b/SPECGAPS.md index ee2190a..3210020 100644 --- a/SPECGAPS.md +++ b/SPECGAPS.md @@ -178,7 +178,7 @@ All reconciled to follow code. Specs must be self-consistent and match code. |---|---|---|---| | ~~D4-1~~ | ~~editor_media.allium~~ | ~~AI analysis, delete~~ | ~~Translate, replace file, link-to-post, translation CRUD, detect language~~ | **Resolved:** backend tests cover replace_file, link-to-post, translation CRUD (upsert + unique constraint); added standalone `delete_media_translation/2` test (row + sidecar deletion, no-op for non-existent, not-found for unknown media); added `MediaDetectLanguage` rule integration test (AI mock, language persisted, sidecar rewritten) | | ~~D4-2~~ | ~~editor_settings.allium~~ | ~~AI endpoints, airplane toggle, rebuild~~ | ~~Protected categories~~ (resolved D1-17), ~~MCP agents~~ (6 `mcp_rows` + 3 `toggle_mcp_agent` tests), ~~style/theme~~ (19 `build_style` + 4 select/change/apply/display tests), ~~search filter~~ (9 `build_settings` visibility tests), ~~categories CRUD~~ (7 `category_rows` + 2 update + 3 add + 2 save + 4 reset tests) | **Resolved:** 3 new test files (mcp_config_test.exs, style_editor_test.exs, settings_search_test.exs) + expanded managed_categories_test.exs cover all untested areas. Total 56 tests added across MCP agents, style/theme, search filter, and categories CRUD. | -| D4-3 | editor_chat.allium | Chat creation, pinned tab | API key screen, message rendering, input area, model selector, inline surfaces | +| D4-3 | ~~editor_chat.allium~~ | ~~Chat creation, pinned tab~~ | ~~API key screen, message rendering, input area, model selector, inline surfaces~~ | **Resolved:** 3 tests added — WelcomeScreen assertions (robot icon, title, 5 tips), CSP external image rewriting in markdown, chart inline surface rendering with series labels/values | | D4-4 | editor_script.allium | Editor layout, create defaults | Save, syntax check, run, delete | | D4-5 | editor_template.allium | Editor layout, create defaults | Save with validation, validate, delete with references | | D4-6 | editor_tags.allium | Sync/discover, merge | Cloud sizing, color picker, delete confirmation, create form | @@ -198,5 +198,5 @@ All reconciled to follow code. Specs must be self-consistent and match code. 6. ~~**D2-1 through D2-17**~~ — all resolved: `max_posts_per_page` constraint, sandboxed execution, transform toast budget, progress throttle, archived→draft/published transitions, AppNoopNotifier, validate_media implementation+tests, content_hash skip on reindex 7. ~~**D3-1 through D3-11**~~ — all resolved: content=null assertion, old-file-deletion, DNT guard, validation prerequisites (already tested), macro failure degrades to empty, template roundtrip, default categories, FTS multi-language, canonical URL format, German transliteration expansion 8. ~~**B2-1 through B2-9**~~ — all resolved: editor_body resolver, single-post reimport, orphan import, dashboard data, missing-thumbnail regen, cache dir, stale-template prune, render labels, generation progress reporting -9. **D4-1 through D4-2** — ~~UI test coverage~~ **Resolved (D4-1 via standalone delete_media_translation + MediaDetectLanguage tests; D4-2 via 3 new test files + expanded managed_categories — 56 tests added)** - **D4-3 through D4-7** — remaining UI test coverage +9. **D4-1 through D4-3** — ~~UI test coverage~~ **Resolved (D4-1 via standalone delete_media_translation + MediaDetectLanguage tests; D4-2 via 3 new test files + expanded managed_categories — 56 tests added; D4-3 via WelcomeScreen/CSP/chart surface tests)** + **D4-4 through D4-7** — remaining UI test coverage diff --git a/test/bds/desktop/shell_live_test.exs b/test/bds/desktop/shell_live_test.exs index 72dc8dc..ef6bac8 100644 --- a/test/bds/desktop/shell_live_test.exs +++ b/test/bds/desktop/shell_live_test.exs @@ -5279,6 +5279,101 @@ defmodule BDS.Desktop.ShellLiveTest do run_git!(project_dir, ["commit", "-m", message]) end + test "chat editor renders welcome screen with robot icon and tips when no messages exist" do + html = + render_component( + &BDS.Desktop.ShellLive.ChatEditor.render/1, + phase3_chat_editor_assigns() + ) + + assert html =~ "🤖" + assert html =~ "Welcome to the AI Assistant" + assert html =~ "Search for posts about a specific topic" + assert html =~ "Show a chart of posts published per month" + assert html =~ "Compare my recent posts in a table" + assert html =~ "Update metadata for posts or media" + assert html =~ "Show post statistics by year in tabs with charts" + end + + test "chat editor rewrites external image URLs in markdown to text links" do + {:safe, html} = + BDS.Desktop.ShellLive.ChatEditor.markdown_html( + "![test](https://example.com/img.jpg)" + ) + + assert html =~ ~s( "call-chart", + "name" => "render_chart", + "arguments" => %{ + "title" => "Posts per Month", + "chart_type" => "bar", + "series" => [%{"label" => "May", "value" => 5}, %{"label" => "Jun", "value" => 3}] + } + } + ]), + created_at: now + 1 + }) + ) + + Repo.insert!( + BDS.AI.ChatMessage.changeset(%BDS.AI.ChatMessage{}, %{ + conversation_id: conversation.id, + role: :tool, + tool_call_id: "call-chart", + content: + Jason.encode!(%{ + "type" => "chart", + "title" => "Posts per Month", + "chart_type" => "bar", + "series" => [%{"label" => "May", "value" => 5}, %{"label" => "Jun", "value" => 3}] + }), + created_at: now + 2 + }) + ) + + {:ok, view, _html} = live_isolated(build_conn(), BDS.Desktop.ShellLive) + + html = + render_click(view, "pin_sidebar_item", %{ + "route" => "chat", + "id" => conversation.id, + "title" => conversation.title, + "subtitle" => conversation.model || "chat" + }) + + assert html =~ ~s(data-testid="chat-inline-surface") + assert html =~ "Posts per Month" + assert html =~ "bar" + assert html =~ "May" + assert html =~ "Jun" + assert length(:binary.matches(html, ~s(class="chat-surface-chart-row"))) == 2 + end + # Sends a message to the LiveView and blocks until it has been processed. # Uses a test ping/pong to guarantee the message was handled before returning. defp send_and_await(view, message) do