feat: TUI tags panels (cloud, manage, merge) wired to the shared tags backend (issue #34)
This commit is contained in:
@@ -966,6 +966,143 @@ defmodule BDS.TUITest do
|
||||
do: Enum.at(state.settings_form.fields, state.settings_form.selected)
|
||||
end
|
||||
|
||||
describe "tags panel (issue #34)" do
|
||||
defp open_tags_section(state, section) do
|
||||
state = press(state, "5")
|
||||
|
||||
index =
|
||||
Enum.find_index(state.items, fn
|
||||
{:item, %{id: id}} -> id == "tags-" <> section
|
||||
_other -> false
|
||||
end)
|
||||
|
||||
assert index != nil
|
||||
press(%{state | selected: index}, "enter")
|
||||
end
|
||||
|
||||
defp type_text(state, text) do
|
||||
text
|
||||
|> String.graphemes()
|
||||
|> Enum.reduce(state, fn char, acc -> press(acc, char) end)
|
||||
end
|
||||
|
||||
defp tag_names(project_id) do
|
||||
project_id |> BDS.Tags.list_tags() |> Enum.map(& &1.name)
|
||||
end
|
||||
|
||||
test "the sidebar entries open the panel sections in the main area", %{project: project} do
|
||||
{:ok, _tag} = BDS.Tags.create_tag(%{project_id: project.id, name: "elixir"})
|
||||
|
||||
state = open_tags_section(mount!(), "cloud")
|
||||
assert state.tags_panel.section == "cloud"
|
||||
assert screen_text(state) =~ "elixir (0)"
|
||||
|
||||
state = press(state, "esc")
|
||||
assert state.tags_panel == nil
|
||||
|
||||
state = open_tags_section(state, "manage")
|
||||
assert state.tags_panel.section == "manage"
|
||||
|
||||
state = open_tags_section(press(state, "esc"), "merge")
|
||||
assert state.tags_panel.section == "merge"
|
||||
assert screen_text(state) =~ "[ ] elixir (0)"
|
||||
end
|
||||
|
||||
test "manage creates a tag through the n prompt", %{project: project} do
|
||||
state = open_tags_section(mount!(), "manage")
|
||||
|
||||
state = press(state, "n")
|
||||
assert state.tags_panel.input.kind == :new
|
||||
|
||||
state = state |> type_text("neu") |> press("enter")
|
||||
|
||||
assert "neu" in tag_names(project.id)
|
||||
assert state.tags_panel.input == nil
|
||||
assert state.status =~ "neu"
|
||||
end
|
||||
|
||||
test "manage renames the selected tag through the enter prompt", %{project: project} do
|
||||
{:ok, _tag} = BDS.Tags.create_tag(%{project_id: project.id, name: "alpha"})
|
||||
|
||||
state = open_tags_section(mount!(), "manage")
|
||||
state = press(state, "enter")
|
||||
assert state.tags_panel.input.kind == :rename
|
||||
assert state.tags_panel.input.value == "alpha"
|
||||
|
||||
state =
|
||||
Enum.reduce(1..5, state, fn _n, acc -> press(acc, "backspace") end)
|
||||
|
||||
_state = state |> type_text("beta") |> press("enter")
|
||||
|
||||
assert tag_names(project.id) == ["beta"]
|
||||
end
|
||||
|
||||
test "manage cycles the tag colour with c", %{project: project} do
|
||||
{:ok, tag} = BDS.Tags.create_tag(%{project_id: project.id, name: "colored"})
|
||||
|
||||
state = open_tags_section(mount!(), "manage")
|
||||
_state = press(state, "c")
|
||||
|
||||
updated = BDS.Repo.get!(BDS.Tags.Tag, tag.id)
|
||||
assert updated.color == List.first(BDS.UI.TagsPanel.colour_presets())
|
||||
end
|
||||
|
||||
test "manage deletes only after y confirmation", %{project: project} do
|
||||
{:ok, _tag} = BDS.Tags.create_tag(%{project_id: project.id, name: "doomed"})
|
||||
|
||||
state = open_tags_section(mount!(), "manage")
|
||||
|
||||
# Any other key cancels the pending delete.
|
||||
state = state |> press("d") |> press("x")
|
||||
assert state.tags_panel.confirm_delete == nil
|
||||
assert "doomed" in tag_names(project.id)
|
||||
|
||||
state = state |> press("d")
|
||||
assert state.tags_panel.confirm_delete == "doomed"
|
||||
|
||||
state = press(state, "y")
|
||||
assert tag_names(project.id) == []
|
||||
assert state.status =~ "doomed"
|
||||
end
|
||||
|
||||
test "merge marks tags with space and merges them into the selection", %{project: project} do
|
||||
{:ok, _one} = BDS.Tags.create_tag(%{project_id: project.id, name: "one"})
|
||||
{:ok, _two} = BDS.Tags.create_tag(%{project_id: project.id, name: "two"})
|
||||
|
||||
{:ok, tagged_post} =
|
||||
BDS.Posts.create_post(%{
|
||||
project_id: project.id,
|
||||
title: "Tagged",
|
||||
content: "body",
|
||||
tags: ["one"]
|
||||
})
|
||||
|
||||
state = open_tags_section(mount!(), "merge")
|
||||
|
||||
# Mark "one", move to "two", merge — "one" is folded into "two".
|
||||
_state = state |> press(" ") |> press("down") |> press("m")
|
||||
|
||||
assert tag_names(project.id) == ["two"]
|
||||
assert BDS.Posts.get_post!(tagged_post.id).tags == ["two"]
|
||||
end
|
||||
|
||||
test "manage syncs tags from post tags with s", %{project: project} do
|
||||
{:ok, _post} =
|
||||
BDS.Posts.create_post(%{
|
||||
project_id: project.id,
|
||||
title: "With Tags",
|
||||
content: "body",
|
||||
tags: ["from-post"]
|
||||
})
|
||||
|
||||
state = open_tags_section(mount!(), "manage")
|
||||
state = press(state, "s")
|
||||
|
||||
assert "from-post" in tag_names(project.id)
|
||||
assert Enum.any?(state.tags_panel.tags, &(&1.name == "from-post"))
|
||||
end
|
||||
end
|
||||
|
||||
test "local tui mode stops the VM when the app exits" do
|
||||
parent = self()
|
||||
state = mount!(stop_vm_on_exit: true, stop_fun: fn -> send(parent, :vm_stopped) end)
|
||||
|
||||
Reference in New Issue
Block a user