Files
bDS2/test/bds/projects_test.exs

161 lines
5.9 KiB
Elixir

defmodule BDS.ProjectsTest do
use ExUnit.Case, async: false
import Ecto.Query
alias BDS.Projects.Project
alias BDS.Repo
alias BDS.Templates.Template
setup do
:ok = Ecto.Adapters.SQL.Sandbox.checkout(BDS.Repo)
temp_root = Path.join(System.tmp_dir!(), "bds-projects-#{System.unique_integer([:positive])}")
File.mkdir_p!(temp_root)
on_exit(fn -> File.rm_rf(temp_root) end)
%{temp_root: temp_root}
end
test "create_project slugifies names, keeps new projects inactive, and deduplicates slugs", %{
temp_root: temp_root
} do
first_dir = Path.join(temp_root, "first")
second_dir = Path.join(temp_root, "second")
File.mkdir_p!(first_dir)
File.mkdir_p!(second_dir)
assert {:ok, first} =
BDS.Projects.create_project(%{name: "Föö Bär Blog", data_path: first_dir})
assert first.name == "Föö Bär Blog"
assert first.slug == "foo-bar-blog"
assert first.data_path == first_dir
assert first.is_active == false
assert is_integer(first.created_at)
assert is_integer(first.updated_at)
assert {:ok, second} =
BDS.Projects.create_project(%{name: "Föö Bär Blog", data_path: second_dir})
assert second.slug == "foo-bar-blog-2"
assert second.is_active == false
end
test "create_project leaves the project templates directory empty by default", %{
temp_root: temp_root
} do
temp_dir = Path.join(temp_root, "starter")
File.mkdir_p!(temp_dir)
assert {:ok, project} =
BDS.Projects.create_project(%{name: "Starter Blog", data_path: temp_dir})
refute File.exists?(Path.join([temp_dir, "templates", "single-post.liquid"]))
refute File.exists?(Path.join([temp_dir, "templates", "post-list.liquid"]))
refute File.exists?(Path.join([temp_dir, "templates", "not-found.liquid"]))
refute File.exists?(Path.join([temp_dir, "templates", "partials", "head.liquid"]))
refute File.exists?(Path.join([temp_dir, "templates", "partials", "menu-items.liquid"]))
refute File.exists?(Path.join([temp_dir, "templates", "macros", "gallery.liquid"]))
starter_slugs =
Repo.all(
from template in Template,
where: template.project_id == ^project.id,
select: {template.slug, template.kind}
)
refute {"single-post", :post} in starter_slugs
refute {"post-list", :list} in starter_slugs
refute {"not-found", :not_found} in starter_slugs
end
test "set_active_project clears the previous active project and activates the target", %{
temp_root: temp_root
} do
first_dir = Path.join(temp_root, "active-first")
second_dir = Path.join(temp_root, "active-second")
File.mkdir_p!(first_dir)
File.mkdir_p!(second_dir)
assert {:ok, first} = BDS.Projects.create_project(%{name: "First", data_path: first_dir})
assert {:ok, second} = BDS.Projects.create_project(%{name: "Second", data_path: second_dir})
assert {:ok, active_first} = BDS.Projects.set_active_project(first.id)
assert active_first.is_active == true
assert {:ok, active_second} = BDS.Projects.set_active_project(second.id)
assert active_second.is_active == true
refetched_first = BDS.Projects.get_project!(first.id)
refetched_second = BDS.Projects.get_project!(second.id)
assert refetched_first.is_active == false
assert refetched_second.is_active == true
assert Enum.count(BDS.Projects.list_projects(), & &1.is_active) == 1
end
test "ensure_default_project creates the default project once and keeps it active" do
Repo.delete_all(Project)
assert {:ok, default_project} = BDS.Projects.ensure_default_project()
assert default_project.id == "default"
assert default_project.name == "My Blog"
assert default_project.slug == "my-blog"
assert default_project.is_active == true
assert {:ok, same_project} = BDS.Projects.ensure_default_project()
assert same_project.id == default_project.id
assert Repo.aggregate(Project, :count, :id) == 1
end
test "delete_project rejects the default and active projects", %{temp_root: temp_root} do
Repo.delete_all(Project)
assert {:ok, default_project} = BDS.Projects.ensure_default_project()
assert {:error, :cannot_delete_default_project} = BDS.Projects.delete_project(default_project.id)
temp_dir = Path.join(temp_root, "active-delete")
File.mkdir_p!(temp_dir)
assert {:ok, project} = BDS.Projects.create_project(%{name: "Delete Me", data_path: temp_dir})
assert {:ok, _active_project} = BDS.Projects.set_active_project(project.id)
assert {:error, :cannot_delete_active_project} = BDS.Projects.delete_project(project.id)
project_id = project.id
assert %Project{id: ^project_id} = BDS.Projects.get_project(project.id)
end
test "delete_project removes internal project data but preserves external data paths", %{temp_root: temp_root} do
assert {:ok, internal_project} = BDS.Projects.create_project(%{name: "Internal Project"})
internal_dir = BDS.Projects.project_data_dir(internal_project)
on_exit(fn ->
_ = File.rm_rf(internal_dir)
end)
refute File.exists?(Path.join(internal_dir, "templates/single-post.liquid"))
assert {:ok, deleted_internal_project} = BDS.Projects.delete_project(internal_project.id)
assert deleted_internal_project.id == internal_project.id
assert BDS.Projects.get_project(internal_project.id) == nil
refute File.exists?(internal_dir)
external_dir = Path.join(temp_root, "external-delete")
File.mkdir_p!(external_dir)
assert {:ok, external_project} =
BDS.Projects.create_project(%{name: "External Project", data_path: external_dir})
marker_path = Path.join(external_dir, "keep.txt")
File.write!(marker_path, "preserve me")
assert {:ok, deleted_external_project} = BDS.Projects.delete_project(external_project.id)
assert deleted_external_project.id == external_project.id
assert BDS.Projects.get_project(external_project.id) == nil
assert File.read!(marker_path) == "preserve me"
end
end