Models for upload and post; generated liveview controller for posts
This commit is contained in:
parent
66d871e546
commit
4067339e8c
@ -108,4 +108,100 @@ defmodule Aggiedit.Rooms do
|
|||||||
nil -> create_room(%{domain: domain})
|
nil -> create_room(%{domain: domain})
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
alias Aggiedit.Rooms.Post
|
||||||
|
|
||||||
|
@doc """
|
||||||
|
Returns the list of posts.
|
||||||
|
|
||||||
|
## Examples
|
||||||
|
|
||||||
|
iex> list_posts()
|
||||||
|
[%Post{}, ...]
|
||||||
|
|
||||||
|
"""
|
||||||
|
def list_posts do
|
||||||
|
Repo.all(Post)
|
||||||
|
end
|
||||||
|
|
||||||
|
@doc """
|
||||||
|
Gets a single post.
|
||||||
|
|
||||||
|
Raises `Ecto.NoResultsError` if the Post does not exist.
|
||||||
|
|
||||||
|
## Examples
|
||||||
|
|
||||||
|
iex> get_post!(123)
|
||||||
|
%Post{}
|
||||||
|
|
||||||
|
iex> get_post!(456)
|
||||||
|
** (Ecto.NoResultsError)
|
||||||
|
|
||||||
|
"""
|
||||||
|
def get_post!(id), do: Repo.get!(Post, id)
|
||||||
|
|
||||||
|
@doc """
|
||||||
|
Creates a post.
|
||||||
|
|
||||||
|
## Examples
|
||||||
|
|
||||||
|
iex> create_post(%{field: value})
|
||||||
|
{:ok, %Post{}}
|
||||||
|
|
||||||
|
iex> create_post(%{field: bad_value})
|
||||||
|
{:error, %Ecto.Changeset{}}
|
||||||
|
|
||||||
|
"""
|
||||||
|
def create_post(attrs \\ %{}) do
|
||||||
|
%Post{}
|
||||||
|
|> Post.changeset(attrs)
|
||||||
|
|> Repo.insert()
|
||||||
|
end
|
||||||
|
|
||||||
|
@doc """
|
||||||
|
Updates a post.
|
||||||
|
|
||||||
|
## Examples
|
||||||
|
|
||||||
|
iex> update_post(post, %{field: new_value})
|
||||||
|
{:ok, %Post{}}
|
||||||
|
|
||||||
|
iex> update_post(post, %{field: bad_value})
|
||||||
|
{:error, %Ecto.Changeset{}}
|
||||||
|
|
||||||
|
"""
|
||||||
|
def update_post(%Post{} = post, attrs) do
|
||||||
|
post
|
||||||
|
|> Post.changeset(attrs)
|
||||||
|
|> Repo.update()
|
||||||
|
end
|
||||||
|
|
||||||
|
@doc """
|
||||||
|
Deletes a post.
|
||||||
|
|
||||||
|
## Examples
|
||||||
|
|
||||||
|
iex> delete_post(post)
|
||||||
|
{:ok, %Post{}}
|
||||||
|
|
||||||
|
iex> delete_post(post)
|
||||||
|
{:error, %Ecto.Changeset{}}
|
||||||
|
|
||||||
|
"""
|
||||||
|
def delete_post(%Post{} = post) do
|
||||||
|
Repo.delete(post)
|
||||||
|
end
|
||||||
|
|
||||||
|
@doc """
|
||||||
|
Returns an `%Ecto.Changeset{}` for tracking post changes.
|
||||||
|
|
||||||
|
## Examples
|
||||||
|
|
||||||
|
iex> change_post(post)
|
||||||
|
%Ecto.Changeset{data: %Post{}}
|
||||||
|
|
||||||
|
"""
|
||||||
|
def change_post(%Post{} = post, attrs \\ %{}) do
|
||||||
|
Post.changeset(post, attrs)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
21
lib/aggiedit/rooms/post.ex
Normal file
21
lib/aggiedit/rooms/post.ex
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
defmodule Aggiedit.Rooms.Post do
|
||||||
|
use Ecto.Schema
|
||||||
|
import Ecto.Changeset
|
||||||
|
|
||||||
|
schema "posts" do
|
||||||
|
field :body, :string
|
||||||
|
field :title, :string
|
||||||
|
field :user_id, :id
|
||||||
|
field :upload_id, :id
|
||||||
|
field :room_id, :id
|
||||||
|
|
||||||
|
timestamps()
|
||||||
|
end
|
||||||
|
|
||||||
|
@doc false
|
||||||
|
def changeset(post, attrs) do
|
||||||
|
post
|
||||||
|
|> cast(attrs, [:title, :body])
|
||||||
|
|> validate_required([:title, :body])
|
||||||
|
end
|
||||||
|
end
|
104
lib/aggiedit/uploads.ex
Normal file
104
lib/aggiedit/uploads.ex
Normal file
@ -0,0 +1,104 @@
|
|||||||
|
defmodule Aggiedit.Uploads do
|
||||||
|
@moduledoc """
|
||||||
|
The Uploads context.
|
||||||
|
"""
|
||||||
|
|
||||||
|
import Ecto.Query, warn: false
|
||||||
|
alias Aggiedit.Repo
|
||||||
|
|
||||||
|
alias Aggiedit.Uploads.Upload
|
||||||
|
|
||||||
|
@doc """
|
||||||
|
Returns the list of uploads.
|
||||||
|
|
||||||
|
## Examples
|
||||||
|
|
||||||
|
iex> list_uploads()
|
||||||
|
[%Upload{}, ...]
|
||||||
|
|
||||||
|
"""
|
||||||
|
def list_uploads do
|
||||||
|
Repo.all(Upload)
|
||||||
|
end
|
||||||
|
|
||||||
|
@doc """
|
||||||
|
Gets a single upload.
|
||||||
|
|
||||||
|
Raises `Ecto.NoResultsError` if the Upload does not exist.
|
||||||
|
|
||||||
|
## Examples
|
||||||
|
|
||||||
|
iex> get_upload!(123)
|
||||||
|
%Upload{}
|
||||||
|
|
||||||
|
iex> get_upload!(456)
|
||||||
|
** (Ecto.NoResultsError)
|
||||||
|
|
||||||
|
"""
|
||||||
|
def get_upload!(id), do: Repo.get!(Upload, id)
|
||||||
|
|
||||||
|
@doc """
|
||||||
|
Creates a upload.
|
||||||
|
|
||||||
|
## Examples
|
||||||
|
|
||||||
|
iex> create_upload(%{field: value})
|
||||||
|
{:ok, %Upload{}}
|
||||||
|
|
||||||
|
iex> create_upload(%{field: bad_value})
|
||||||
|
{:error, %Ecto.Changeset{}}
|
||||||
|
|
||||||
|
"""
|
||||||
|
def create_upload(attrs \\ %{}) do
|
||||||
|
%Upload{}
|
||||||
|
|> Upload.changeset(attrs)
|
||||||
|
|> Repo.insert()
|
||||||
|
end
|
||||||
|
|
||||||
|
@doc """
|
||||||
|
Updates a upload.
|
||||||
|
|
||||||
|
## Examples
|
||||||
|
|
||||||
|
iex> update_upload(upload, %{field: new_value})
|
||||||
|
{:ok, %Upload{}}
|
||||||
|
|
||||||
|
iex> update_upload(upload, %{field: bad_value})
|
||||||
|
{:error, %Ecto.Changeset{}}
|
||||||
|
|
||||||
|
"""
|
||||||
|
def update_upload(%Upload{} = upload, attrs) do
|
||||||
|
upload
|
||||||
|
|> Upload.changeset(attrs)
|
||||||
|
|> Repo.update()
|
||||||
|
end
|
||||||
|
|
||||||
|
@doc """
|
||||||
|
Deletes a upload.
|
||||||
|
|
||||||
|
## Examples
|
||||||
|
|
||||||
|
iex> delete_upload(upload)
|
||||||
|
{:ok, %Upload{}}
|
||||||
|
|
||||||
|
iex> delete_upload(upload)
|
||||||
|
{:error, %Ecto.Changeset{}}
|
||||||
|
|
||||||
|
"""
|
||||||
|
def delete_upload(%Upload{} = upload) do
|
||||||
|
Repo.delete(upload)
|
||||||
|
end
|
||||||
|
|
||||||
|
@doc """
|
||||||
|
Returns an `%Ecto.Changeset{}` for tracking upload changes.
|
||||||
|
|
||||||
|
## Examples
|
||||||
|
|
||||||
|
iex> change_upload(upload)
|
||||||
|
%Ecto.Changeset{data: %Upload{}}
|
||||||
|
|
||||||
|
"""
|
||||||
|
def change_upload(%Upload{} = upload, attrs \\ %{}) do
|
||||||
|
Upload.changeset(upload, attrs)
|
||||||
|
end
|
||||||
|
end
|
21
lib/aggiedit/uploads/upload.ex
Normal file
21
lib/aggiedit/uploads/upload.ex
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
defmodule Aggiedit.Uploads.Upload do
|
||||||
|
use Ecto.Schema
|
||||||
|
import Ecto.Changeset
|
||||||
|
|
||||||
|
schema "uploads" do
|
||||||
|
field :file, :string
|
||||||
|
field :mime, :string
|
||||||
|
field :size, :integer
|
||||||
|
|
||||||
|
belongs_to :user, Aggiedit.Accounts.User
|
||||||
|
|
||||||
|
timestamps()
|
||||||
|
end
|
||||||
|
|
||||||
|
@doc false
|
||||||
|
def changeset(upload, attrs) do
|
||||||
|
upload
|
||||||
|
|> cast(attrs, [:file, :mime, :size])
|
||||||
|
|> validate_required([:file, :mime, :size])
|
||||||
|
end
|
||||||
|
end
|
@ -91,6 +91,7 @@ defmodule AggieditWeb do
|
|||||||
|
|
||||||
# Import LiveView and .heex helpers (live_render, live_patch, <.form>, etc)
|
# Import LiveView and .heex helpers (live_render, live_patch, <.form>, etc)
|
||||||
import Phoenix.LiveView.Helpers
|
import Phoenix.LiveView.Helpers
|
||||||
|
import AggieditWeb.LiveHelpers
|
||||||
|
|
||||||
# Import basic rendering functionality (render, render_layout, etc)
|
# Import basic rendering functionality (render, render_layout, etc)
|
||||||
import Phoenix.View
|
import Phoenix.View
|
||||||
|
60
lib/aggiedit_web/live/live_helpers.ex
Normal file
60
lib/aggiedit_web/live/live_helpers.ex
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
defmodule AggieditWeb.LiveHelpers do
|
||||||
|
import Phoenix.LiveView
|
||||||
|
import Phoenix.LiveView.Helpers
|
||||||
|
|
||||||
|
alias Phoenix.LiveView.JS
|
||||||
|
|
||||||
|
@doc """
|
||||||
|
Renders a live component inside a modal.
|
||||||
|
|
||||||
|
The rendered modal receives a `:return_to` option to properly update
|
||||||
|
the URL when the modal is closed.
|
||||||
|
|
||||||
|
## Examples
|
||||||
|
|
||||||
|
<.modal return_to={Routes.post_index_path(@socket, :index)}>
|
||||||
|
<.live_component
|
||||||
|
module={AggieditWeb.PostLive.FormComponent}
|
||||||
|
id={@post.id || :new}
|
||||||
|
title={@page_title}
|
||||||
|
action={@live_action}
|
||||||
|
return_to={Routes.post_index_path(@socket, :index)}
|
||||||
|
post: @post
|
||||||
|
/>
|
||||||
|
</.modal>
|
||||||
|
"""
|
||||||
|
def modal(assigns) do
|
||||||
|
assigns = assign_new(assigns, :return_to, fn -> nil end)
|
||||||
|
|
||||||
|
~H"""
|
||||||
|
<div id="modal" class="phx-modal fade-in" phx-remove={hide_modal()}>
|
||||||
|
<div
|
||||||
|
id="modal-content"
|
||||||
|
class="phx-modal-content fade-in-scale"
|
||||||
|
phx-click-away={JS.dispatch("click", to: "#close")}
|
||||||
|
phx-window-keydown={JS.dispatch("click", to: "#close")}
|
||||||
|
phx-key="escape"
|
||||||
|
>
|
||||||
|
<%= if @return_to do %>
|
||||||
|
<%= live_patch "✖",
|
||||||
|
to: @return_to,
|
||||||
|
id: "close",
|
||||||
|
class: "phx-modal-close",
|
||||||
|
phx_click: hide_modal()
|
||||||
|
%>
|
||||||
|
<% else %>
|
||||||
|
<a id="close" href="#" class="phx-modal-close" phx-click={hide_modal()}>✖</a>
|
||||||
|
<% end %>
|
||||||
|
|
||||||
|
<%= render_slot(@inner_block) %>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
"""
|
||||||
|
end
|
||||||
|
|
||||||
|
defp hide_modal(js \\ %JS{}) do
|
||||||
|
js
|
||||||
|
|> JS.hide(to: "#modal", transition: "fade-out")
|
||||||
|
|> JS.hide(to: "#modal-content", transition: "fade-out-scale")
|
||||||
|
end
|
||||||
|
end
|
55
lib/aggiedit_web/live/post_live/form_component.ex
Normal file
55
lib/aggiedit_web/live/post_live/form_component.ex
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
defmodule AggieditWeb.PostLive.FormComponent do
|
||||||
|
use AggieditWeb, :live_component
|
||||||
|
|
||||||
|
alias Aggiedit.Rooms
|
||||||
|
|
||||||
|
@impl true
|
||||||
|
def update(%{post: post} = assigns, socket) do
|
||||||
|
changeset = Rooms.change_post(post)
|
||||||
|
|
||||||
|
{:ok,
|
||||||
|
socket
|
||||||
|
|> assign(assigns)
|
||||||
|
|> assign(:changeset, changeset)}
|
||||||
|
end
|
||||||
|
|
||||||
|
@impl true
|
||||||
|
def handle_event("validate", %{"post" => post_params}, socket) do
|
||||||
|
changeset =
|
||||||
|
socket.assigns.post
|
||||||
|
|> Rooms.change_post(post_params)
|
||||||
|
|> Map.put(:action, :validate)
|
||||||
|
|
||||||
|
{:noreply, assign(socket, :changeset, changeset)}
|
||||||
|
end
|
||||||
|
|
||||||
|
def handle_event("save", %{"post" => post_params}, socket) do
|
||||||
|
save_post(socket, socket.assigns.action, post_params)
|
||||||
|
end
|
||||||
|
|
||||||
|
defp save_post(socket, :edit, post_params) do
|
||||||
|
case Rooms.update_post(socket.assigns.post, post_params) do
|
||||||
|
{:ok, _post} ->
|
||||||
|
{:noreply,
|
||||||
|
socket
|
||||||
|
|> put_flash(:info, "Post updated successfully")
|
||||||
|
|> push_redirect(to: socket.assigns.return_to)}
|
||||||
|
|
||||||
|
{:error, %Ecto.Changeset{} = changeset} ->
|
||||||
|
{:noreply, assign(socket, :changeset, changeset)}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
defp save_post(socket, :new, post_params) do
|
||||||
|
case Rooms.create_post(post_params) do
|
||||||
|
{:ok, _post} ->
|
||||||
|
{:noreply,
|
||||||
|
socket
|
||||||
|
|> put_flash(:info, "Post created successfully")
|
||||||
|
|> push_redirect(to: socket.assigns.return_to)}
|
||||||
|
|
||||||
|
{:error, %Ecto.Changeset{} = changeset} ->
|
||||||
|
{:noreply, assign(socket, changeset: changeset)}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
24
lib/aggiedit_web/live/post_live/form_component.html.heex
Normal file
24
lib/aggiedit_web/live/post_live/form_component.html.heex
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
<div>
|
||||||
|
<h2><%= @title %></h2>
|
||||||
|
|
||||||
|
<.form
|
||||||
|
let={f}
|
||||||
|
for={@changeset}
|
||||||
|
id="post-form"
|
||||||
|
phx-target={@myself}
|
||||||
|
phx-change="validate"
|
||||||
|
phx-submit="save">
|
||||||
|
|
||||||
|
<%= label f, :title %>
|
||||||
|
<%= textarea f, :title %>
|
||||||
|
<%= error_tag f, :title %>
|
||||||
|
|
||||||
|
<%= label f, :body %>
|
||||||
|
<%= textarea f, :body %>
|
||||||
|
<%= error_tag f, :body %>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<%= submit "Save", phx_disable_with: "Saving..." %>
|
||||||
|
</div>
|
||||||
|
</.form>
|
||||||
|
</div>
|
46
lib/aggiedit_web/live/post_live/index.ex
Normal file
46
lib/aggiedit_web/live/post_live/index.ex
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
defmodule AggieditWeb.PostLive.Index do
|
||||||
|
use AggieditWeb, :live_view
|
||||||
|
|
||||||
|
alias Aggiedit.Rooms
|
||||||
|
alias Aggiedit.Rooms.Post
|
||||||
|
|
||||||
|
@impl true
|
||||||
|
def mount(_params, _session, socket) do
|
||||||
|
{:ok, assign(socket, :posts, list_posts())}
|
||||||
|
end
|
||||||
|
|
||||||
|
@impl true
|
||||||
|
def handle_params(params, _url, socket) do
|
||||||
|
{:noreply, apply_action(socket, socket.assigns.live_action, params)}
|
||||||
|
end
|
||||||
|
|
||||||
|
defp apply_action(socket, :edit, %{"id" => id}) do
|
||||||
|
socket
|
||||||
|
|> assign(:page_title, "Edit Post")
|
||||||
|
|> assign(:post, Rooms.get_post!(id))
|
||||||
|
end
|
||||||
|
|
||||||
|
defp apply_action(socket, :new, _params) do
|
||||||
|
socket
|
||||||
|
|> assign(:page_title, "New Post")
|
||||||
|
|> assign(:post, %Post{})
|
||||||
|
end
|
||||||
|
|
||||||
|
defp apply_action(socket, :index, _params) do
|
||||||
|
socket
|
||||||
|
|> assign(:page_title, "Listing Posts")
|
||||||
|
|> assign(:post, nil)
|
||||||
|
end
|
||||||
|
|
||||||
|
@impl true
|
||||||
|
def handle_event("delete", %{"id" => id}, socket) do
|
||||||
|
post = Rooms.get_post!(id)
|
||||||
|
{:ok, _} = Rooms.delete_post(post)
|
||||||
|
|
||||||
|
{:noreply, assign(socket, :posts, list_posts())}
|
||||||
|
end
|
||||||
|
|
||||||
|
defp list_posts do
|
||||||
|
Rooms.list_posts()
|
||||||
|
end
|
||||||
|
end
|
41
lib/aggiedit_web/live/post_live/index.html.heex
Normal file
41
lib/aggiedit_web/live/post_live/index.html.heex
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
<h1>Listing Posts</h1>
|
||||||
|
|
||||||
|
<%= if @live_action in [:new, :edit] do %>
|
||||||
|
<.modal return_to={Routes.post_index_path(@socket, :index)}>
|
||||||
|
<.live_component
|
||||||
|
module={AggieditWeb.PostLive.FormComponent}
|
||||||
|
id={@post.id || :new}
|
||||||
|
title={@page_title}
|
||||||
|
action={@live_action}
|
||||||
|
post={@post}
|
||||||
|
return_to={Routes.post_index_path(@socket, :index)}
|
||||||
|
/>
|
||||||
|
</.modal>
|
||||||
|
<% end %>
|
||||||
|
|
||||||
|
<table>
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Title</th>
|
||||||
|
<th>Body</th>
|
||||||
|
|
||||||
|
<th></th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody id="posts">
|
||||||
|
<%= for post <- @posts do %>
|
||||||
|
<tr id={"post-#{post.id}"}>
|
||||||
|
<td><%= post.title %></td>
|
||||||
|
<td><%= post.body %></td>
|
||||||
|
|
||||||
|
<td>
|
||||||
|
<span><%= live_redirect "Show", to: Routes.post_show_path(@socket, :show, post) %></span>
|
||||||
|
<span><%= live_patch "Edit", to: Routes.post_index_path(@socket, :edit, post) %></span>
|
||||||
|
<span><%= link "Delete", to: "#", phx_click: "delete", phx_value_id: post.id, data: [confirm: "Are you sure?"] %></span>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<% end %>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<span><%= live_patch "New Post", to: Routes.post_index_path(@socket, :new) %></span>
|
21
lib/aggiedit_web/live/post_live/show.ex
Normal file
21
lib/aggiedit_web/live/post_live/show.ex
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
defmodule AggieditWeb.PostLive.Show do
|
||||||
|
use AggieditWeb, :live_view
|
||||||
|
|
||||||
|
alias Aggiedit.Rooms
|
||||||
|
|
||||||
|
@impl true
|
||||||
|
def mount(_params, _session, socket) do
|
||||||
|
{:ok, socket}
|
||||||
|
end
|
||||||
|
|
||||||
|
@impl true
|
||||||
|
def handle_params(%{"id" => id}, _, socket) do
|
||||||
|
{:noreply,
|
||||||
|
socket
|
||||||
|
|> assign(:page_title, page_title(socket.assigns.live_action))
|
||||||
|
|> assign(:post, Rooms.get_post!(id))}
|
||||||
|
end
|
||||||
|
|
||||||
|
defp page_title(:show), do: "Show Post"
|
||||||
|
defp page_title(:edit), do: "Edit Post"
|
||||||
|
end
|
31
lib/aggiedit_web/live/post_live/show.html.heex
Normal file
31
lib/aggiedit_web/live/post_live/show.html.heex
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
<h1>Show Post</h1>
|
||||||
|
|
||||||
|
<%= if @live_action in [:edit] do %>
|
||||||
|
<.modal return_to={Routes.post_show_path(@socket, :show, @post)}>
|
||||||
|
<.live_component
|
||||||
|
module={AggieditWeb.PostLive.FormComponent}
|
||||||
|
id={@post.id}
|
||||||
|
title={@page_title}
|
||||||
|
action={@live_action}
|
||||||
|
post={@post}
|
||||||
|
return_to={Routes.post_show_path(@socket, :show, @post)}
|
||||||
|
/>
|
||||||
|
</.modal>
|
||||||
|
<% end %>
|
||||||
|
|
||||||
|
<ul>
|
||||||
|
|
||||||
|
<li>
|
||||||
|
<strong>Title:</strong>
|
||||||
|
<%= @post.title %>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<li>
|
||||||
|
<strong>Body:</strong>
|
||||||
|
<%= @post.body %>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<span><%= live_patch "Edit", to: Routes.post_show_path(@socket, :edit, @post), class: "button" %></span> |
|
||||||
|
<span><%= live_redirect "Back", to: Routes.post_index_path(@socket, :index) %></span>
|
@ -21,6 +21,13 @@ defmodule AggieditWeb.Router do
|
|||||||
pipe_through :browser
|
pipe_through :browser
|
||||||
|
|
||||||
get "/", PageController, :index
|
get "/", PageController, :index
|
||||||
|
|
||||||
|
live "/posts", PostLive.Index, :index
|
||||||
|
live "/posts/new", PostLive.Index, :new
|
||||||
|
live "/posts/:id/edit", PostLive.Index, :edit
|
||||||
|
|
||||||
|
live "/posts/:id", PostLive.Show, :show
|
||||||
|
live "/posts/:id/show/edit", PostLive.Show, :edit
|
||||||
end
|
end
|
||||||
|
|
||||||
# Other scopes may use custom stacks.
|
# Other scopes may use custom stacks.
|
||||||
|
16
priv/repo/migrations/20220406184635_create_uploads.exs
Normal file
16
priv/repo/migrations/20220406184635_create_uploads.exs
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
defmodule Aggiedit.Repo.Migrations.CreateUploads do
|
||||||
|
use Ecto.Migration
|
||||||
|
|
||||||
|
def change do
|
||||||
|
create table(:uploads) do
|
||||||
|
add :file, :text
|
||||||
|
add :mime, :text
|
||||||
|
add :size, :integer
|
||||||
|
add :user_id, references(:users, on_delete: :nothing)
|
||||||
|
|
||||||
|
timestamps()
|
||||||
|
end
|
||||||
|
|
||||||
|
create index(:uploads, [:user_id])
|
||||||
|
end
|
||||||
|
end
|
19
priv/repo/migrations/20220406185124_create_posts.exs
Normal file
19
priv/repo/migrations/20220406185124_create_posts.exs
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
defmodule Aggiedit.Repo.Migrations.CreatePosts do
|
||||||
|
use Ecto.Migration
|
||||||
|
|
||||||
|
def change do
|
||||||
|
create table(:posts) do
|
||||||
|
add :title, :text
|
||||||
|
add :body, :text
|
||||||
|
add :user_id, references(:users, on_delete: :nothing)
|
||||||
|
add :upload_id, references(:uploads, on_delete: :nothing)
|
||||||
|
add :room_id, references(:rooms, on_delete: :nothing)
|
||||||
|
|
||||||
|
timestamps()
|
||||||
|
end
|
||||||
|
|
||||||
|
create index(:posts, [:user_id])
|
||||||
|
create index(:posts, [:upload_id])
|
||||||
|
create index(:posts, [:room_id])
|
||||||
|
end
|
||||||
|
end
|
@ -56,4 +56,60 @@ defmodule Aggiedit.RoomsTest do
|
|||||||
assert %Ecto.Changeset{} = Rooms.change_room(room)
|
assert %Ecto.Changeset{} = Rooms.change_room(room)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
describe "posts" do
|
||||||
|
alias Aggiedit.Rooms.Post
|
||||||
|
|
||||||
|
import Aggiedit.RoomsFixtures
|
||||||
|
|
||||||
|
@invalid_attrs %{body: nil, title: nil}
|
||||||
|
|
||||||
|
test "list_posts/0 returns all posts" do
|
||||||
|
post = post_fixture()
|
||||||
|
assert Rooms.list_posts() == [post]
|
||||||
|
end
|
||||||
|
|
||||||
|
test "get_post!/1 returns the post with given id" do
|
||||||
|
post = post_fixture()
|
||||||
|
assert Rooms.get_post!(post.id) == post
|
||||||
|
end
|
||||||
|
|
||||||
|
test "create_post/1 with valid data creates a post" do
|
||||||
|
valid_attrs = %{body: "some body", title: "some title"}
|
||||||
|
|
||||||
|
assert {:ok, %Post{} = post} = Rooms.create_post(valid_attrs)
|
||||||
|
assert post.body == "some body"
|
||||||
|
assert post.title == "some title"
|
||||||
|
end
|
||||||
|
|
||||||
|
test "create_post/1 with invalid data returns error changeset" do
|
||||||
|
assert {:error, %Ecto.Changeset{}} = Rooms.create_post(@invalid_attrs)
|
||||||
|
end
|
||||||
|
|
||||||
|
test "update_post/2 with valid data updates the post" do
|
||||||
|
post = post_fixture()
|
||||||
|
update_attrs = %{body: "some updated body", title: "some updated title"}
|
||||||
|
|
||||||
|
assert {:ok, %Post{} = post} = Rooms.update_post(post, update_attrs)
|
||||||
|
assert post.body == "some updated body"
|
||||||
|
assert post.title == "some updated title"
|
||||||
|
end
|
||||||
|
|
||||||
|
test "update_post/2 with invalid data returns error changeset" do
|
||||||
|
post = post_fixture()
|
||||||
|
assert {:error, %Ecto.Changeset{}} = Rooms.update_post(post, @invalid_attrs)
|
||||||
|
assert post == Rooms.get_post!(post.id)
|
||||||
|
end
|
||||||
|
|
||||||
|
test "delete_post/1 deletes the post" do
|
||||||
|
post = post_fixture()
|
||||||
|
assert {:ok, %Post{}} = Rooms.delete_post(post)
|
||||||
|
assert_raise Ecto.NoResultsError, fn -> Rooms.get_post!(post.id) end
|
||||||
|
end
|
||||||
|
|
||||||
|
test "change_post/1 returns a post changeset" do
|
||||||
|
post = post_fixture()
|
||||||
|
assert %Ecto.Changeset{} = Rooms.change_post(post)
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
63
test/aggiedit/uploads_test.exs
Normal file
63
test/aggiedit/uploads_test.exs
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
defmodule Aggiedit.UploadsTest do
|
||||||
|
use Aggiedit.DataCase
|
||||||
|
|
||||||
|
alias Aggiedit.Uploads
|
||||||
|
|
||||||
|
describe "uploads" do
|
||||||
|
alias Aggiedit.Uploads.Upload
|
||||||
|
|
||||||
|
import Aggiedit.UploadsFixtures
|
||||||
|
|
||||||
|
@invalid_attrs %{file: nil, mime: nil, size: nil}
|
||||||
|
|
||||||
|
test "list_uploads/0 returns all uploads" do
|
||||||
|
upload = upload_fixture()
|
||||||
|
assert Uploads.list_uploads() == [upload]
|
||||||
|
end
|
||||||
|
|
||||||
|
test "get_upload!/1 returns the upload with given id" do
|
||||||
|
upload = upload_fixture()
|
||||||
|
assert Uploads.get_upload!(upload.id) == upload
|
||||||
|
end
|
||||||
|
|
||||||
|
test "create_upload/1 with valid data creates a upload" do
|
||||||
|
valid_attrs = %{file: "some file", mime: "some mime", size: 42}
|
||||||
|
|
||||||
|
assert {:ok, %Upload{} = upload} = Uploads.create_upload(valid_attrs)
|
||||||
|
assert upload.file == "some file"
|
||||||
|
assert upload.mime == "some mime"
|
||||||
|
assert upload.size == 42
|
||||||
|
end
|
||||||
|
|
||||||
|
test "create_upload/1 with invalid data returns error changeset" do
|
||||||
|
assert {:error, %Ecto.Changeset{}} = Uploads.create_upload(@invalid_attrs)
|
||||||
|
end
|
||||||
|
|
||||||
|
test "update_upload/2 with valid data updates the upload" do
|
||||||
|
upload = upload_fixture()
|
||||||
|
update_attrs = %{file: "some updated file", mime: "some updated mime", size: 43}
|
||||||
|
|
||||||
|
assert {:ok, %Upload{} = upload} = Uploads.update_upload(upload, update_attrs)
|
||||||
|
assert upload.file == "some updated file"
|
||||||
|
assert upload.mime == "some updated mime"
|
||||||
|
assert upload.size == 43
|
||||||
|
end
|
||||||
|
|
||||||
|
test "update_upload/2 with invalid data returns error changeset" do
|
||||||
|
upload = upload_fixture()
|
||||||
|
assert {:error, %Ecto.Changeset{}} = Uploads.update_upload(upload, @invalid_attrs)
|
||||||
|
assert upload == Uploads.get_upload!(upload.id)
|
||||||
|
end
|
||||||
|
|
||||||
|
test "delete_upload/1 deletes the upload" do
|
||||||
|
upload = upload_fixture()
|
||||||
|
assert {:ok, %Upload{}} = Uploads.delete_upload(upload)
|
||||||
|
assert_raise Ecto.NoResultsError, fn -> Uploads.get_upload!(upload.id) end
|
||||||
|
end
|
||||||
|
|
||||||
|
test "change_upload/1 returns a upload changeset" do
|
||||||
|
upload = upload_fixture()
|
||||||
|
assert %Ecto.Changeset{} = Uploads.change_upload(upload)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
110
test/aggiedit_web/live/post_live_test.exs
Normal file
110
test/aggiedit_web/live/post_live_test.exs
Normal file
@ -0,0 +1,110 @@
|
|||||||
|
defmodule AggieditWeb.PostLiveTest do
|
||||||
|
use AggieditWeb.ConnCase
|
||||||
|
|
||||||
|
import Phoenix.LiveViewTest
|
||||||
|
import Aggiedit.RoomsFixtures
|
||||||
|
|
||||||
|
@create_attrs %{body: "some body", title: "some title"}
|
||||||
|
@update_attrs %{body: "some updated body", title: "some updated title"}
|
||||||
|
@invalid_attrs %{body: nil, title: nil}
|
||||||
|
|
||||||
|
defp create_post(_) do
|
||||||
|
post = post_fixture()
|
||||||
|
%{post: post}
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "Index" do
|
||||||
|
setup [:create_post]
|
||||||
|
|
||||||
|
test "lists all posts", %{conn: conn, post: post} do
|
||||||
|
{:ok, _index_live, html} = live(conn, Routes.post_index_path(conn, :index))
|
||||||
|
|
||||||
|
assert html =~ "Listing Posts"
|
||||||
|
assert html =~ post.body
|
||||||
|
end
|
||||||
|
|
||||||
|
test "saves new post", %{conn: conn} do
|
||||||
|
{:ok, index_live, _html} = live(conn, Routes.post_index_path(conn, :index))
|
||||||
|
|
||||||
|
assert index_live |> element("a", "New Post") |> render_click() =~
|
||||||
|
"New Post"
|
||||||
|
|
||||||
|
assert_patch(index_live, Routes.post_index_path(conn, :new))
|
||||||
|
|
||||||
|
assert index_live
|
||||||
|
|> form("#post-form", post: @invalid_attrs)
|
||||||
|
|> render_change() =~ "can't be blank"
|
||||||
|
|
||||||
|
{:ok, _, html} =
|
||||||
|
index_live
|
||||||
|
|> form("#post-form", post: @create_attrs)
|
||||||
|
|> render_submit()
|
||||||
|
|> follow_redirect(conn, Routes.post_index_path(conn, :index))
|
||||||
|
|
||||||
|
assert html =~ "Post created successfully"
|
||||||
|
assert html =~ "some body"
|
||||||
|
end
|
||||||
|
|
||||||
|
test "updates post in listing", %{conn: conn, post: post} do
|
||||||
|
{:ok, index_live, _html} = live(conn, Routes.post_index_path(conn, :index))
|
||||||
|
|
||||||
|
assert index_live |> element("#post-#{post.id} a", "Edit") |> render_click() =~
|
||||||
|
"Edit Post"
|
||||||
|
|
||||||
|
assert_patch(index_live, Routes.post_index_path(conn, :edit, post))
|
||||||
|
|
||||||
|
assert index_live
|
||||||
|
|> form("#post-form", post: @invalid_attrs)
|
||||||
|
|> render_change() =~ "can't be blank"
|
||||||
|
|
||||||
|
{:ok, _, html} =
|
||||||
|
index_live
|
||||||
|
|> form("#post-form", post: @update_attrs)
|
||||||
|
|> render_submit()
|
||||||
|
|> follow_redirect(conn, Routes.post_index_path(conn, :index))
|
||||||
|
|
||||||
|
assert html =~ "Post updated successfully"
|
||||||
|
assert html =~ "some updated body"
|
||||||
|
end
|
||||||
|
|
||||||
|
test "deletes post in listing", %{conn: conn, post: post} do
|
||||||
|
{:ok, index_live, _html} = live(conn, Routes.post_index_path(conn, :index))
|
||||||
|
|
||||||
|
assert index_live |> element("#post-#{post.id} a", "Delete") |> render_click()
|
||||||
|
refute has_element?(index_live, "#post-#{post.id}")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "Show" do
|
||||||
|
setup [:create_post]
|
||||||
|
|
||||||
|
test "displays post", %{conn: conn, post: post} do
|
||||||
|
{:ok, _show_live, html} = live(conn, Routes.post_show_path(conn, :show, post))
|
||||||
|
|
||||||
|
assert html =~ "Show Post"
|
||||||
|
assert html =~ post.body
|
||||||
|
end
|
||||||
|
|
||||||
|
test "updates post within modal", %{conn: conn, post: post} do
|
||||||
|
{:ok, show_live, _html} = live(conn, Routes.post_show_path(conn, :show, post))
|
||||||
|
|
||||||
|
assert show_live |> element("a", "Edit") |> render_click() =~
|
||||||
|
"Edit Post"
|
||||||
|
|
||||||
|
assert_patch(show_live, Routes.post_show_path(conn, :edit, post))
|
||||||
|
|
||||||
|
assert show_live
|
||||||
|
|> form("#post-form", post: @invalid_attrs)
|
||||||
|
|> render_change() =~ "can't be blank"
|
||||||
|
|
||||||
|
{:ok, _, html} =
|
||||||
|
show_live
|
||||||
|
|> form("#post-form", post: @update_attrs)
|
||||||
|
|> render_submit()
|
||||||
|
|> follow_redirect(conn, Routes.post_show_path(conn, :show, post))
|
||||||
|
|
||||||
|
assert html =~ "Post updated successfully"
|
||||||
|
assert html =~ "some updated body"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
@ -17,4 +17,19 @@ defmodule Aggiedit.RoomsFixtures do
|
|||||||
|
|
||||||
room
|
room
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@doc """
|
||||||
|
Generate a post.
|
||||||
|
"""
|
||||||
|
def post_fixture(attrs \\ %{}) do
|
||||||
|
{:ok, post} =
|
||||||
|
attrs
|
||||||
|
|> Enum.into(%{
|
||||||
|
body: "some body",
|
||||||
|
title: "some title"
|
||||||
|
})
|
||||||
|
|> Aggiedit.Rooms.create_post()
|
||||||
|
|
||||||
|
post
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
22
test/support/fixtures/uploads_fixtures.ex
Normal file
22
test/support/fixtures/uploads_fixtures.ex
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
defmodule Aggiedit.UploadsFixtures do
|
||||||
|
@moduledoc """
|
||||||
|
This module defines test helpers for creating
|
||||||
|
entities via the `Aggiedit.Uploads` context.
|
||||||
|
"""
|
||||||
|
|
||||||
|
@doc """
|
||||||
|
Generate a upload.
|
||||||
|
"""
|
||||||
|
def upload_fixture(attrs \\ %{}) do
|
||||||
|
{:ok, upload} =
|
||||||
|
attrs
|
||||||
|
|> Enum.into(%{
|
||||||
|
file: "some file",
|
||||||
|
mime: "some mime",
|
||||||
|
size: 42
|
||||||
|
})
|
||||||
|
|> Aggiedit.Uploads.create_upload()
|
||||||
|
|
||||||
|
upload
|
||||||
|
end
|
||||||
|
end
|
Loading…
Reference in New Issue
Block a user