Skip to content

Commit

Permalink
Merge pull request #187 from dainst/deletion-interface
Browse files Browse the repository at this point in the history
  • Loading branch information
dersmon authored Dec 19, 2023
2 parents b3d2bdb + 3ff931e commit 461b54c
Show file tree
Hide file tree
Showing 6 changed files with 227 additions and 10 deletions.
5 changes: 5 additions & 0 deletions server/assets/css/phoenix.css
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,11 @@ select {
width: auto;
}

label {
font-weight:300;
display:inline;
}

/* Phoenix promo and logo */
.phx-hero {
text-align: center;
Expand Down
3 changes: 2 additions & 1 deletion server/lib/field_hub/project.ex
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,8 @@ defmodule FieldHub.Project do
__Parameters__
- `project_identifier` the project's name.
"""
def exists?(project_identifier) do
def exists?(project_identifier)
when project_identifier != "" and not is_nil(project_identifier) do
CouchService.get_db_infos(project_identifier)
|> case do
%{status_code: 200} ->
Expand Down
12 changes: 8 additions & 4 deletions server/lib/field_hub_web/controllers/api/project_controller.ex
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@ defmodule FieldHubWeb.Api.ProjectController do

@identifier_length Application.compile_env(:field_hub, :max_project_identifier_length)

@moduledoc """
This API controller module handles the HTTP requests for listing, creating or deleting projects.
"""

def index(%{assigns: %{current_user: user_name}} = conn, _params) do
render(conn, "list.json", %{projects: Project.get_all_for_user(user_name)})
end
Expand Down Expand Up @@ -86,12 +90,12 @@ defmodule FieldHubWeb.Api.ProjectController do
end

def delete(conn, %{"project" => id}) do
project = Project.delete(id)
user = User.delete(id)
project_deletion_result = Project.delete(id)
user_deletion_result = User.delete(id)

response_payload = %{
status_project: project,
status_user: user
status_project: project_deletion_result,
status_user: user_deletion_result
}

conn
Expand Down
60 changes: 60 additions & 0 deletions server/lib/field_hub_web/live/project_show_live.ex
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
defmodule FieldHubWeb.ProjectShowLive do
alias FieldHub.Project

alias FieldHubWeb.{
Router.Helpers,
UserAuth,
Expand Down Expand Up @@ -42,6 +44,8 @@ defmodule FieldHubWeb.ProjectShowLive do
|> assign(:project, project)
|> assign(:current_user, user_name)
|> assign(:new_password, "")
|> assign(:confirm_project_name, "")
|> assign(:delete_files, false)
|> read_project_doc()
}

Expand Down Expand Up @@ -112,6 +116,62 @@ defmodule FieldHubWeb.ProjectShowLive do
{:noreply, assign(socket, :new_password, password)}
end

def handle_event(
"delete_form_change",
%{
"repeat_project_name_input" => repeated_project_name,
"delete_files_radio" => delete_files
} = _values,
socket
) do
delete_files =
case delete_files do
"delete_files" ->
true

"keep_files" ->
false
end

socket = assign(socket, :confirm_project_name, repeated_project_name)
socket = assign(socket, :delete_files, delete_files)
{:noreply, socket}
end

def handle_event(
"delete",
_values,
%{assigns: %{project: project, current_user: user_name, delete_files: delete_files}} =
socket
) do
socket =
case User.is_admin?(user_name) do
true ->
%{database: :deleted} = Project.delete(project, delete_files)
:deleted = User.delete(project)

if delete_files == false do
{:ok, "Project database`#{project}` has been deleted successfully."}
else
{:ok, "Project database`#{project}` and images have been deleted successfully."}
end

false ->
{:error, "You are not authorized to delete the project."}
end
|> case do
{:ok, msg} ->
socket
|> put_flash(:info, msg)

{:error, msg} ->
socket
|> put_flash(:error, msg)
end

{:noreply, redirect(socket, to: "/")}
end

def handle_event("generate_password", _values, socket) do
{:noreply, assign(socket, :new_password, CouchService.create_password())}
end
Expand Down
32 changes: 31 additions & 1 deletion server/lib/field_hub_web/live/project_show_live.html.heex
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@
<%= if User.is_admin?(@current_user) do %>
<hr>
<h2>Password change</h2>
<form phx-change="update">
<form id="pwd_form" phx-change="update">
<div class="row">
<div class="column">
<input
Expand All @@ -153,5 +153,35 @@
</form>

<hr>
<h2>Delete project</h2>
<form id="del_form" phx-change="delete_form_change">
<div class="row">
<div class="column">
<input
type="text"
placeholder="Repeat the project name to delete"
name="repeat_project_name_input"
value={@confirm_project_name}
/>
</div>
</div>

<div class="row">
<div class="column">
<input type="radio" name="delete_files_radio" id="delete_database" value="keep_files" checked={not @delete_files}>
<label for="delete_database">Delete database only</label><br>
<input type="radio" name="delete_files_radio" id="delete_database_and_files" value="delete_files" checked={@delete_files}>
<label for="delete_database_and_files">Delete database and image files</label>

</div>
</div>
<div class="row">
<div class="column">
<button type="button" class="button" phx-click="delete" disabled={@confirm_project_name != @project} style="width:100%">
Delete
</button>
</div>
</div>
</form>
<% end %>
</div>
125 changes: 121 additions & 4 deletions server/test/field_hub_web/live/project_show_live_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -341,7 +341,7 @@ defmodule FieldHubWeb.ProjectShowLiveTest do
{:ok, %{conn: conn}}
end

test "admin has passwort setting interface", %{conn: conn} do
test "admin has password setting interface", %{conn: conn} do
{:ok, view, _html_on_mount} = live(conn, "/ui/projects/show/#{@project}")

html = render(view)
Expand All @@ -362,7 +362,7 @@ defmodule FieldHubWeb.ProjectShowLiveTest do

html =
view
|> element("form")
|> element("#pwd_form")
|> render_change(%{password: "typed_in_password"})

assert html =~
Expand Down Expand Up @@ -397,7 +397,7 @@ defmodule FieldHubWeb.ProjectShowLiveTest do
new_password = "updated_password"

view
|> element("form")
|> element("#pwd_form")
|> render_change(%{password: new_password})

html =
Expand All @@ -422,6 +422,123 @@ defmodule FieldHubWeb.ProjectShowLiveTest do
})
end

test "admin is able to delete a project's database", %{conn: conn} do
{:ok, view, _html_on_mount} = live(conn, "/ui/projects/show/#{@project}")

# Check if the system knows the project currently
assert true == FieldHub.Project.exists?(@project)

assert FieldHub.FileStore.file_index(@project) |> Enum.count() > 0

# Simulate the repeated project name input
view
|> element("#del_form")
|> render_change(%{repeat_project_name_input: @project})

# Check if we are beeing redirected to the landing page
{:error, {:redirect, %{to: "/"}}} =
view
|> element("button", "Delete")
|> render_click()

# Check if the project got deleted.
assert false == FieldHub.Project.exists?(@project)

assert FieldHub.FileStore.file_index(@project) |> Enum.count() > 0
end

test "admin is able to delete a project's database and files still exist after having changed the radio button selection",
%{conn: conn} do
{:ok, view, _html_on_mount} = live(conn, "/ui/projects/show/#{@project}")

# Check if the system knows the project.
assert true == FieldHub.Project.exists?(@project)

# Check if the project's file directory exists.
assert File.exists?("test/tmp/#{@project}/")

# Simulate the repeated project name input
view
|> element("#del_form")
|> render_change(%{repeat_project_name_input: @project})

view
|> element("#del_form")
|> render_change(%{delete_files_radio: "delete_files"})

html =
view
|> element("#del_form")
|> render_change(%{delete_files_radio: "keep_files"})

assert html =~ "value=\"keep_files\" checked"

# Check if we are beeing redirected to the landing page
{:error, {:redirect, %{to: "/"}}} =
view
|> element("button", "Delete")
|> render_click()

# Check if the project got deleted.
assert false == FieldHub.Project.exists?(@project)

# Check if files have been deleted.
assert File.exists?("test/tmp/#{@project}/")
end

test "admin is able to delete a project's database and its files", %{conn: conn} do
{:ok, view, _html_on_mount} = live(conn, "/ui/projects/show/#{@project}")

# Check if the system knows the project.
assert true == FieldHub.Project.exists?(@project)

# Check if the project's file directory exists.
assert File.exists?("test/tmp/#{@project}/")

# Simulate the repeated project name input
view
|> element("#del_form")
|> render_change(%{repeat_project_name_input: @project})

html =
view
|> element("#del_form")
|> render_change(%{delete_files_radio: "delete_files"})

assert html =~ "value=\"delete_files\" checked"

# Check if we are beeing redirected to the landing page
{:error, {:redirect, %{to: "/"}}} =
view
|> element("button", "Delete")
|> render_click()

# Check if the project got deleted.
assert false == FieldHub.Project.exists?(@project)

# Check if files have been deleted.
assert not File.exists?("test/tmp/#{@project}/")
end

test "project deletion button is disabled until project name is repeated", %{conn: conn} do
{:ok, view, _html_on_mount} = live(conn, "/ui/projects/show/#{@project}")

assert true == FieldHub.Project.exists?(@project)

html = render(view)

# The "Delete" button should be disabled as long as the repeated project name does not match.
assert html =~ "phx-click=\"delete\" disabled=\"disabled\""

html =
view
|> element("#del_form")
|> render_change(%{repeat_project_name_input: @project})

# The "Delete" button should be enabled now.
assert not (html =~ "phx-click=\"delete\" disabled=\"disabled\"")
end

test "throws warning if default user is missing", %{conn: conn} do
# This case is highly unlikely, but is checked by the view nonetheless for completeness sake.

Expand All @@ -430,7 +547,7 @@ defmodule FieldHubWeb.ProjectShowLiveTest do
User.delete(@user_name)

view
|> element("form")
|> element("#pwd_form")
|> render_change(%{password: "updated_password"})

html =
Expand Down

0 comments on commit 461b54c

Please sign in to comment.