fix: A1-17 route bds2://new-post deep links into transform pipeline and draft creation
This commit is contained in:
126
test/bds/blogmark_test.exs
Normal file
126
test/bds/blogmark_test.exs
Normal file
@@ -0,0 +1,126 @@
|
||||
defmodule BDS.BlogmarkTest do
|
||||
use ExUnit.Case, async: false
|
||||
|
||||
alias BDS.Blogmark
|
||||
alias BDS.Scripts
|
||||
|
||||
setup do
|
||||
:ok = Ecto.Adapters.SQL.Sandbox.checkout(BDS.Repo)
|
||||
Ecto.Adapters.SQL.Sandbox.mode(BDS.Repo, {:shared, self()})
|
||||
|
||||
temp_dir =
|
||||
Path.join(System.tmp_dir!(), "bds-blogmark-#{System.unique_integer([:positive])}")
|
||||
|
||||
File.mkdir_p!(temp_dir)
|
||||
on_exit(fn -> File.rm_rf(temp_dir) end)
|
||||
|
||||
{:ok, project} = BDS.Projects.create_project(%{name: "Blogmark", data_path: temp_dir})
|
||||
|
||||
%{project: project}
|
||||
end
|
||||
|
||||
describe "parse_deep_link/1" do
|
||||
test "parses a new-post deep link into a candidate" do
|
||||
url =
|
||||
"bds2://new-post?title=" <>
|
||||
URI.encode_www_form("Hello World") <>
|
||||
"&url=" <> URI.encode_www_form("https://example.com/page")
|
||||
|
||||
assert {:ok, candidate} = Blogmark.parse_deep_link(url)
|
||||
assert candidate["title"] == "Hello World"
|
||||
assert candidate["url"] == "https://example.com/page"
|
||||
assert candidate["content"] == nil
|
||||
assert candidate["tags"] == []
|
||||
assert candidate["categories"] == []
|
||||
end
|
||||
|
||||
test "parses optional content, tags and categories" do
|
||||
url =
|
||||
"bds2://new-post?title=T&url=https://x&content=" <>
|
||||
URI.encode_www_form("body text") <>
|
||||
"&tags=" <>
|
||||
URI.encode_www_form("a, b ,c") <>
|
||||
"&categories=" <> URI.encode_www_form("news")
|
||||
|
||||
assert {:ok, candidate} = Blogmark.parse_deep_link(url)
|
||||
assert candidate["content"] == "body text"
|
||||
assert candidate["tags"] == ["a", "b", "c"]
|
||||
assert candidate["categories"] == ["news"]
|
||||
end
|
||||
|
||||
test "rejects an unsupported scheme" do
|
||||
assert {:error, :unsupported_scheme} =
|
||||
Blogmark.parse_deep_link("bds://new-post?title=T")
|
||||
end
|
||||
|
||||
test "rejects an unsupported action" do
|
||||
assert {:error, :unsupported_action} =
|
||||
Blogmark.parse_deep_link("bds2://open-thing?id=1")
|
||||
end
|
||||
end
|
||||
|
||||
describe "receive_deep_link/3" do
|
||||
test "creates a draft post from the deep link", %{project: project} do
|
||||
url =
|
||||
"bds2://new-post?title=" <>
|
||||
URI.encode_www_form("A Bookmarked Page") <>
|
||||
"&url=" <> URI.encode_www_form("https://example.com/a")
|
||||
|
||||
assert {:ok, %{post: post, toasts: [], errors: []}} =
|
||||
Blogmark.receive_deep_link(project.id, url)
|
||||
|
||||
assert post.title == "A Bookmarked Page"
|
||||
assert post.status == :draft
|
||||
assert post.project_id == project.id
|
||||
end
|
||||
|
||||
test "runs enabled transforms on the candidate before creating the post", %{project: project} do
|
||||
{:ok, _script} =
|
||||
Scripts.create_script(%{
|
||||
project_id: project.id,
|
||||
title: "Prefix",
|
||||
kind: :transform,
|
||||
content: """
|
||||
function main(data, ctx)
|
||||
data.title = "[" .. ctx.source .. "] " .. data.title
|
||||
return { data = data, toasts = { "transformed" } }
|
||||
end
|
||||
""",
|
||||
entrypoint: "main"
|
||||
})
|
||||
|
||||
url = "bds2://new-post?title=Page&url=https://x"
|
||||
|
||||
assert {:ok, %{post: post, toasts: toasts}} =
|
||||
Blogmark.receive_deep_link(project.id, url)
|
||||
|
||||
assert post.title == "[blogmark] Page"
|
||||
assert toasts == ["transformed"]
|
||||
end
|
||||
|
||||
test "defaults the category from blogmark_category when none provided", %{project: project} do
|
||||
{:ok, _meta} =
|
||||
BDS.Metadata.update_project_metadata(project.id, %{blogmark_category: "aside"})
|
||||
|
||||
url = "bds2://new-post?title=Page&url=https://x"
|
||||
|
||||
assert {:ok, %{post: post}} = Blogmark.receive_deep_link(project.id, url)
|
||||
assert post.categories == ["aside"]
|
||||
end
|
||||
|
||||
test "keeps explicit categories over the blogmark default", %{project: project} do
|
||||
{:ok, _meta} =
|
||||
BDS.Metadata.update_project_metadata(project.id, %{blogmark_category: "aside"})
|
||||
|
||||
url = "bds2://new-post?title=Page&url=https://x&categories=article"
|
||||
|
||||
assert {:ok, %{post: post}} = Blogmark.receive_deep_link(project.id, url)
|
||||
assert post.categories == ["article"]
|
||||
end
|
||||
|
||||
test "returns an error for an invalid deep link", %{project: project} do
|
||||
assert {:error, :unsupported_scheme} =
|
||||
Blogmark.receive_deep_link(project.id, "bds://new-post?title=T")
|
||||
end
|
||||
end
|
||||
end
|
||||
34
test/bds/desktop/deep_link_test.exs
Normal file
34
test/bds/desktop/deep_link_test.exs
Normal file
@@ -0,0 +1,34 @@
|
||||
defmodule BDS.Desktop.DeepLinkTest do
|
||||
use ExUnit.Case, async: false
|
||||
|
||||
alias BDS.Desktop.DeepLink
|
||||
|
||||
setup do
|
||||
topic = "deep-link-test:#{System.unique_integer([:positive])}"
|
||||
Phoenix.PubSub.subscribe(BDS.PubSub, topic)
|
||||
|
||||
{:ok, pid} = DeepLink.start_link(name: nil, pubsub: BDS.PubSub, topic: topic)
|
||||
on_exit(fn -> if Process.alive?(pid), do: GenServer.stop(pid) end)
|
||||
|
||||
%{pid: pid, topic: topic}
|
||||
end
|
||||
|
||||
test "broadcasts a bds2:// open_url event to the shell topic", %{pid: pid} do
|
||||
url = "bds2://new-post?title=Hello&url=https://example.com"
|
||||
send(pid, {:open_url, [url]})
|
||||
|
||||
assert_receive {:blogmark_deep_link, ^url}, 500
|
||||
end
|
||||
|
||||
test "ignores non-bds2 open_url events", %{pid: pid} do
|
||||
send(pid, {:open_url, ["https://example.com"]})
|
||||
|
||||
refute_receive {:blogmark_deep_link, _url}, 200
|
||||
end
|
||||
|
||||
test "ignores unrelated messages", %{pid: pid} do
|
||||
send(pid, {:open_file, ["/tmp/x"]})
|
||||
|
||||
refute_receive {:blogmark_deep_link, _url}, 200
|
||||
end
|
||||
end
|
||||
@@ -846,6 +846,27 @@ defmodule BDS.Desktop.ShellLiveTest do
|
||||
assert html =~ ~s(data-tab-id="#{created_definition.id}")
|
||||
end
|
||||
|
||||
test "blogmark deep link creates a draft post and opens it in the editor", %{project: project} do
|
||||
{:ok, view, _html} = live_isolated(build_conn(), BDS.Desktop.ShellLive)
|
||||
post_count_before = Repo.aggregate(Post, :count, :id)
|
||||
|
||||
url =
|
||||
"bds2://new-post?title=" <>
|
||||
URI.encode_www_form("Saved From Browser") <>
|
||||
"&url=" <> URI.encode_www_form("https://example.com/article")
|
||||
|
||||
send(view.pid, {:blogmark_deep_link, url})
|
||||
html = render(view)
|
||||
|
||||
assert Repo.aggregate(Post, :count, :id) == post_count_before + 1
|
||||
|
||||
created_post = Repo.get_by!(Post, title: "Saved From Browser")
|
||||
assert created_post.project_id == project.id
|
||||
assert created_post.status == :draft
|
||||
assert html =~ ~s(data-tab-type="post")
|
||||
assert html =~ ~s(data-tab-id="#{created_post.id}")
|
||||
end
|
||||
|
||||
test "settings sidebar selections expose a scroll target for the preferences editor" do
|
||||
{:ok, view, _html} = live_isolated(build_conn(), BDS.Desktop.ShellLive)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user