looooots of stuff
This commit is contained in:
parent
9457a05d55
commit
dda577fabe
|
@ -1,4 +1,4 @@
|
|||
defmodule Forum do
|
||||
defmodule ForumMain do
|
||||
@moduledoc """
|
||||
Forum keeps the contexts that define your domain
|
||||
and business logic.
|
||||
|
|
|
@ -0,0 +1,305 @@
|
|||
defmodule Forum do
|
||||
@moduledoc """
|
||||
The Forum context.
|
||||
"""
|
||||
|
||||
import Ecto.Query, warn: false
|
||||
alias Forum.Repo
|
||||
|
||||
alias Forum.User
|
||||
|
||||
@doc """
|
||||
Returns the list of users.
|
||||
|
||||
## Examples
|
||||
|
||||
iex> list_users()
|
||||
[%User{}, ...]
|
||||
|
||||
"""
|
||||
def list_users do
|
||||
Repo.all(User)
|
||||
end
|
||||
|
||||
@doc """
|
||||
Gets a single user.
|
||||
|
||||
Raises `Ecto.NoResultsError` if the User does not exist.
|
||||
|
||||
## Examples
|
||||
|
||||
iex> get_user!(123)
|
||||
%User{}
|
||||
|
||||
iex> get_user!(456)
|
||||
** (Ecto.NoResultsError)
|
||||
|
||||
"""
|
||||
def get_user!(id) do
|
||||
Repo.get!(User, id)
|
||||
end
|
||||
|
||||
@doc """
|
||||
Creates a user.
|
||||
|
||||
## Examples
|
||||
|
||||
iex> create_user(%{field: value})
|
||||
{:ok, %User{}}
|
||||
|
||||
iex> create_user(%{field: bad_value})
|
||||
{:error, %Ecto.Changeset{}}
|
||||
|
||||
"""
|
||||
def create_user(attrs \\ %{}) do
|
||||
%User{}
|
||||
|> User.changeset(attrs)
|
||||
|> Repo.insert()
|
||||
end
|
||||
|
||||
@doc """
|
||||
Updates a user.
|
||||
|
||||
## Examples
|
||||
|
||||
iex> update_user(user, %{field: new_value})
|
||||
{:ok, %User{}}
|
||||
|
||||
iex> update_user(user, %{field: bad_value})
|
||||
{:error, %Ecto.Changeset{}}
|
||||
|
||||
"""
|
||||
def update_user(%User{} = user, attrs) do
|
||||
user
|
||||
|> User.changeset(attrs)
|
||||
|> Repo.update()
|
||||
end
|
||||
|
||||
@doc """
|
||||
Deletes a User.
|
||||
|
||||
## Examples
|
||||
|
||||
iex> delete_user(user)
|
||||
{:ok, %User{}}
|
||||
|
||||
iex> delete_user(user)
|
||||
{:error, %Ecto.Changeset{}}
|
||||
|
||||
"""
|
||||
def delete_user(%User{} = user) do
|
||||
Repo.delete(user)
|
||||
end
|
||||
|
||||
@doc """
|
||||
Returns an `%Ecto.Changeset{}` for tracking user changes.
|
||||
|
||||
## Examples
|
||||
|
||||
iex> change_user(user)
|
||||
%Ecto.Changeset{source: %User{}}
|
||||
|
||||
"""
|
||||
def change_user(%User{} = user) do
|
||||
User.changeset(user, %{})
|
||||
end
|
||||
|
||||
alias Forum.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)
|
||||
|> Repo.preload(:thread)
|
||||
end
|
||||
|
||||
@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{source: %Post{}}
|
||||
|
||||
"""
|
||||
def change_post(%Post{} = post) do
|
||||
Post.changeset(post, %{})
|
||||
end
|
||||
|
||||
alias Forum.Thread
|
||||
|
||||
@doc """
|
||||
Returns the list of threads.
|
||||
|
||||
## Examples
|
||||
|
||||
iex> list_threads()
|
||||
[%Thread{}, ...]
|
||||
|
||||
"""
|
||||
def list_threads do
|
||||
Repo.all(Thread)
|
||||
end
|
||||
|
||||
@doc """
|
||||
Gets a single thread.
|
||||
|
||||
Raises `Ecto.NoResultsError` if the Thread does not exist.
|
||||
|
||||
## Examples
|
||||
|
||||
iex> get_thread!(123)
|
||||
%Thread{}
|
||||
|
||||
iex> get_thread!(456)
|
||||
** (Ecto.NoResultsError)
|
||||
|
||||
"""
|
||||
def get_thread!(id) do
|
||||
Repo.get!(Thread, id)
|
||||
|> Repo.preload(:posts)
|
||||
|> Repo.preload(:user)
|
||||
end
|
||||
|
||||
@doc """
|
||||
Creates a thread.
|
||||
|
||||
## Examples
|
||||
|
||||
iex> create_thread(%{field: value})
|
||||
{:ok, %Thread{}}
|
||||
|
||||
iex> create_thread(%{field: bad_value})
|
||||
{:error, %Ecto.Changeset{}}
|
||||
|
||||
"""
|
||||
def create_thread(attrs \\ %{}) do
|
||||
%Thread{}
|
||||
|> Thread.changeset(attrs)
|
||||
|> Repo.insert()
|
||||
end
|
||||
|
||||
@doc """
|
||||
Updates a thread.
|
||||
|
||||
## Examples
|
||||
|
||||
iex> update_thread(thread, %{field: new_value})
|
||||
{:ok, %Thread{}}
|
||||
|
||||
iex> update_thread(thread, %{field: bad_value})
|
||||
{:error, %Ecto.Changeset{}}
|
||||
|
||||
"""
|
||||
def update_thread(%Thread{} = thread, attrs) do
|
||||
thread
|
||||
|> Thread.changeset(attrs)
|
||||
|> Repo.update()
|
||||
end
|
||||
|
||||
@doc """
|
||||
Deletes a Thread.
|
||||
|
||||
## Examples
|
||||
|
||||
iex> delete_thread(thread)
|
||||
{:ok, %Thread{}}
|
||||
|
||||
iex> delete_thread(thread)
|
||||
{:error, %Ecto.Changeset{}}
|
||||
|
||||
"""
|
||||
def delete_thread(%Thread{} = thread) do
|
||||
Repo.delete(thread)
|
||||
end
|
||||
|
||||
@doc """
|
||||
Returns an `%Ecto.Changeset{}` for tracking thread changes.
|
||||
|
||||
## Examples
|
||||
|
||||
iex> change_thread(thread)
|
||||
%Ecto.Changeset{source: %Thread{}}
|
||||
|
||||
"""
|
||||
def change_thread(%Thread{} = thread) do
|
||||
Thread.changeset(thread, %{})
|
||||
end
|
||||
end
|
|
@ -0,0 +1,23 @@
|
|||
defmodule Forum.Post do
|
||||
use Ecto.Schema
|
||||
import Ecto.Changeset
|
||||
alias Forum.Post
|
||||
|
||||
|
||||
schema "posts" do
|
||||
field :content, :string
|
||||
field :sticky, :boolean, default: false
|
||||
|
||||
belongs_to :user, Forum.User
|
||||
belongs_to :thread, Forum.Thread
|
||||
|
||||
timestamps()
|
||||
end
|
||||
|
||||
@doc false
|
||||
def changeset(%Post{} = post, attrs) do
|
||||
post
|
||||
|> cast(attrs, [:content, :sticky, :thread_id])
|
||||
|> validate_required([:content, :sticky, :thread_id])
|
||||
end
|
||||
end
|
|
@ -0,0 +1,22 @@
|
|||
defmodule Forum.Thread do
|
||||
use Ecto.Schema
|
||||
import Ecto.Changeset
|
||||
alias Forum.Thread
|
||||
|
||||
|
||||
schema "threads" do
|
||||
field :name, :string
|
||||
|
||||
has_many :posts, Forum.Post
|
||||
belongs_to :user, Forum.User
|
||||
|
||||
timestamps()
|
||||
end
|
||||
|
||||
@doc false
|
||||
def changeset(%Thread{} = thread, attrs) do
|
||||
thread
|
||||
|> cast(attrs, [:name])
|
||||
|> validate_required([:name])
|
||||
end
|
||||
end
|
|
@ -0,0 +1,20 @@
|
|||
defmodule Forum.User do
|
||||
use Ecto.Schema
|
||||
import Ecto.Changeset
|
||||
alias Forum.User
|
||||
|
||||
|
||||
schema "users" do
|
||||
field :bio, :string
|
||||
field :name, :string
|
||||
|
||||
timestamps()
|
||||
end
|
||||
|
||||
@doc false
|
||||
def changeset(%User{} = user, attrs) do
|
||||
user
|
||||
|> cast(attrs, [:name, :bio])
|
||||
|> validate_required([:name, :bio])
|
||||
end
|
||||
end
|
|
@ -0,0 +1,33 @@
|
|||
defmodule ForumWeb.LoginController do
|
||||
use ForumWeb, :controller
|
||||
|
||||
def index(conn, _params) do
|
||||
render(conn, :index)
|
||||
end
|
||||
|
||||
def authenticate(conn, %{"username" => user, "password" => pw}) do
|
||||
resp = Tesla.get("https://auth.tilde.team/?user=" <> user <> "&pw=" <> pw)
|
||||
case resp.body do
|
||||
"0" ->
|
||||
conn
|
||||
|> Plug.Conn.put_session(:loggedin, false)
|
||||
|> put_flash(:error, "log in failed")
|
||||
|> redirect(to: login_path(conn, :index))
|
||||
"1" ->
|
||||
conn
|
||||
|> Plug.Conn.put_session(:loggedin, true)
|
||||
|> Plug.Conn.put_session(:current_user, user)
|
||||
|> put_flash(:info, "logged in as #{user}")
|
||||
|> redirect(to: thread_path(conn, :index))
|
||||
_ ->
|
||||
conn
|
||||
end
|
||||
end
|
||||
|
||||
def logout(conn, _params) do
|
||||
conn
|
||||
|> Plug.Conn.put_session(:loggedin, false)
|
||||
|> put_flash(:info, "logged out successfully")
|
||||
|> redirect(to: login_path(conn, :index))
|
||||
end
|
||||
end
|
|
@ -1,7 +0,0 @@
|
|||
defmodule ForumWeb.PageController do
|
||||
use ForumWeb, :controller
|
||||
|
||||
def index(conn, _params) do
|
||||
render conn, "index.html"
|
||||
end
|
||||
end
|
|
@ -0,0 +1,44 @@
|
|||
defmodule ForumWeb.PostController do
|
||||
use ForumWeb, :controller
|
||||
|
||||
def create(conn, %{"post" => post_params}) do
|
||||
case Forum.create_post(post_params) do
|
||||
{:ok, post} ->
|
||||
post = Forum.Repo.preload(post, :thread)
|
||||
conn
|
||||
|> put_flash(:info, "reply created successfully.")
|
||||
|> redirect(to: thread_path(conn, :show, post.thread.id))
|
||||
{:error, %Ecto.Changeset{} = changeset} ->
|
||||
render(conn, "new.html", changeset: changeset)
|
||||
end
|
||||
end
|
||||
|
||||
def edit(conn, %{"id" => id}) do
|
||||
post = Forum.get_post!(id)
|
||||
changeset = Forum.change_post(post)
|
||||
render(conn, "edit.html", post: post, changeset: changeset)
|
||||
end
|
||||
|
||||
def update(conn, %{"id" => id, "post" => post_params}) do
|
||||
post = Forum.get_post!(id)
|
||||
|
||||
case Forum.update_post(post, post_params) do
|
||||
{:ok, post} ->
|
||||
conn
|
||||
|> put_flash(:info, "reply updated successfully.")
|
||||
|> redirect(to: thread_path(conn, :show, post.thread.id))
|
||||
{:error, %Ecto.Changeset{} = changeset} ->
|
||||
render(conn, "edit.html", post: post, changeset: changeset)
|
||||
end
|
||||
end
|
||||
|
||||
def delete(conn, %{"id" => id}) do
|
||||
post = Forum.get_post!(id)
|
||||
thread_id = post.thread.id
|
||||
{:ok, _post} = Forum.delete_post(post)
|
||||
|
||||
conn
|
||||
|> put_flash(:info, "reply deleted successfully.")
|
||||
|> redirect(to: thread_path(conn, :show, thread_id))
|
||||
end
|
||||
end
|
|
@ -1,11 +1,59 @@
|
|||
defmodule ForumWeb.ThreadController do
|
||||
use ForumWeb, :controller
|
||||
use ForumWeb, :controller
|
||||
|
||||
def show_thread(conn, %{"thread" => thread}) do
|
||||
render conn, "index.html", thread: thread
|
||||
end
|
||||
alias Forum.Thread
|
||||
|
||||
def new_thread(conn, _params) do
|
||||
render conn, "new.html"
|
||||
def index(conn, _params) do
|
||||
threads = Forum.list_threads()
|
||||
render(conn, "index.html", threads: threads)
|
||||
end
|
||||
|
||||
def new(conn, _params) do
|
||||
changeset = Forum.change_thread(%Thread{})
|
||||
render(conn, "new.html", changeset: changeset)
|
||||
end
|
||||
|
||||
def create(conn, %{"thread" => thread_params}) do
|
||||
case Forum.create_thread(thread_params) do
|
||||
{:ok, thread} ->
|
||||
conn
|
||||
|> put_flash(:info, "thread created successfully.")
|
||||
|> redirect(to: thread_path(conn, :show, thread))
|
||||
{:error, %Ecto.Changeset{} = changeset} ->
|
||||
render(conn, "new.html", changeset: changeset)
|
||||
end
|
||||
end
|
||||
|
||||
def show(conn, %{"id" => id}) do
|
||||
thread = Forum.get_thread!(id)
|
||||
render(conn, "show.html", thread: thread)
|
||||
end
|
||||
|
||||
def edit(conn, %{"id" => id}) do
|
||||
thread = Forum.get_thread!(id)
|
||||
changeset = Forum.change_thread(thread)
|
||||
render(conn, "edit.html", thread: thread, changeset: changeset)
|
||||
end
|
||||
|
||||
def update(conn, %{"id" => id, "thread" => thread_params}) do
|
||||
thread = Forum.get_thread!(id)
|
||||
|
||||
case Forum.update_thread(thread, thread_params) do
|
||||
{:ok, thread} ->
|
||||
conn
|
||||
|> put_flash(:info, "thread updated successfully.")
|
||||
|> redirect(to: thread_path(conn, :show, thread))
|
||||
{:error, %Ecto.Changeset{} = changeset} ->
|
||||
render(conn, "edit.html", thread: thread, changeset: changeset)
|
||||
end
|
||||
end
|
||||
|
||||
def delete(conn, %{"id" => id}) do
|
||||
thread = Forum.get_thread!(id)
|
||||
{:ok, _thread} = Forum.delete_thread(thread)
|
||||
|
||||
conn
|
||||
|> put_flash(:info, "thread deleted successfully.")
|
||||
|> redirect(to: thread_path(conn, :index))
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,11 +1,59 @@
|
|||
defmodule ForumWeb.UserController do
|
||||
use ForumWeb, :controller
|
||||
use ForumWeb, :controller
|
||||
|
||||
def index(conn, %{"user" => user}) do
|
||||
render conn, "index.html", user: user
|
||||
end
|
||||
alias Forum.User
|
||||
|
||||
def my_profile(conn, _params) do
|
||||
render conn, "index.html"
|
||||
def index(conn, _params) do
|
||||
users = Forum.list_users()
|
||||
render(conn, "index.html", users: users)
|
||||
end
|
||||
|
||||
def new(conn, _params) do
|
||||
changeset = Forum.change_user(%User{})
|
||||
render(conn, "new.html", changeset: changeset)
|
||||
end
|
||||
|
||||
def create(conn, %{"user" => user_params}) do
|
||||
case Forum.create_user(user_params) do
|
||||
{:ok, user} ->
|
||||
conn
|
||||
|> put_flash(:info, "user created successfully.")
|
||||
|> redirect(to: user_path(conn, :show, user))
|
||||
{:error, %Ecto.Changeset{} = changeset} ->
|
||||
render(conn, "new.html", changeset: changeset)
|
||||
end
|
||||
end
|
||||
|
||||
def show(conn, %{"id" => id}) do
|
||||
user = Forum.get_user!(id)
|
||||
render(conn, "show.html", user: user)
|
||||
end
|
||||
|
||||
def edit(conn, %{"id" => id}) do
|
||||
user = Forum.get_user!(id)
|
||||
changeset = Forum.change_user(user)
|
||||
render(conn, "edit.html", user: user, changeset: changeset)
|
||||
end
|
||||
|
||||
def update(conn, %{"id" => id, "user" => user_params}) do
|
||||
user = Forum.get_user!(id)
|
||||
|
||||
case Forum.update_user(user, user_params) do
|
||||
{:ok, user} ->
|
||||
conn
|
||||
|> put_flash(:info, "user updated successfully.")
|
||||
|> redirect(to: user_path(conn, :show, user))
|
||||
{:error, %Ecto.Changeset{} = changeset} ->
|
||||
render(conn, "edit.html", user: user, changeset: changeset)
|
||||
end
|
||||
end
|
||||
|
||||
def delete(conn, %{"id" => id}) do
|
||||
user = Forum.get_user!(id)
|
||||
{:ok, _user} = Forum.delete_user(user)
|
||||
|
||||
conn
|
||||
|> put_flash(:info, "user deleted successfully.")
|
||||
|> redirect(to: user_path(conn, :index))
|
||||
end
|
||||
end
|
||||
|
|
|
@ -0,0 +1,16 @@
|
|||
defmodule ForumWeb.Plugs.RequireAuth do
|
||||
import Plug.Conn
|
||||
|
||||
def init(default), do: default
|
||||
|
||||
def call(conn, _params) do
|
||||
if conn |> get_session(:loggedin) do
|
||||
conn
|
||||
else
|
||||
conn
|
||||
|> put_session(:redirect_url, conn.request_path)
|
||||
|> Phoenix.Controller.put_flash(:info, "please log in or register to continue")
|
||||
|> Phoenix.Controller.redirect(to: "/auth")
|
||||
end
|
||||
end
|
||||
end
|
|
@ -9,20 +9,34 @@ defmodule ForumWeb.Router do
|
|||
plug :put_secure_browser_headers
|
||||
end
|
||||
|
||||
pipeline :restricted do
|
||||
plug :browser
|
||||
plug ForumWeb.Plugs.RequireAuth
|
||||
end
|
||||
|
||||
pipeline :api do
|
||||
plug :accepts, ["json"]
|
||||
end
|
||||
|
||||
scope "/", ForumWeb do
|
||||
pipe_through :browser # Use the default browser stack
|
||||
scope "/auth", ForumWeb do
|
||||
pipe_through :browser
|
||||
|
||||
get "/", PageController, :index
|
||||
get "/me", UserController, :my_profile
|
||||
get "/u/:user", UserController, :index
|
||||
get "/new", ThreadController, :new_thread
|
||||
get "/t/:thread", ThreadController, :show_thread
|
||||
get "/", LoginController, :index
|
||||
get "/logout", LoginController, :logout
|
||||
post "/", LoginController, :authenticate
|
||||
end
|
||||
|
||||
|
||||
scope "/", ForumWeb do
|
||||
pipe_through :restricted # Use the default browser stack
|
||||
|
||||
get "/", ThreadController, :index
|
||||
resources "/users", UserController
|
||||
resources "/threads", ThreadController
|
||||
resources "/posts", PostController, except: [:index, :new, :show]
|
||||
end
|
||||
|
||||
|
||||
# Other scopes may use custom stacks.
|
||||
# scope "/api", ForumWeb do
|
||||
# pipe_through :api
|
||||
|
|
|
@ -7,29 +7,50 @@
|
|||
<meta name="description" content="tilde.team discussion forum">
|
||||
<meta name="author" content="tilde.team">
|
||||
|
||||
<title>Hello Forum!</title>
|
||||
<title><%= assigns[:page_title] || "forum.tilde.team" %></title>
|
||||
<link rel="stylesheet" href="https://tilde.team/css/hacker.css">
|
||||
|
||||
<style>
|
||||
body { padding-top: 70px; }
|
||||
</style>
|
||||
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div class="container">
|
||||
<header class="header">
|
||||
<nav class="navbar navbar-default" role="navigation">
|
||||
<div class="container">
|
||||
<div class="navbar-header">
|
||||
<a class="navbar-brand" href="/"><img src="https://tilde.team/favicon-32x32.png" alt="tilde.team logo"></a>
|
||||
</div>
|
||||
<ul class="nav nav-pills pull-right">
|
||||
<li><a href="/">home</a></li>
|
||||
<li><a href="/new">new thread</a></li>
|
||||
<li><a href="/me">profile</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</nav>
|
||||
</header>
|
||||
<!-- Fixed navbar -->
|
||||
<nav class="navbar navbar-default navbar-fixed-top">
|
||||
<div class="container">
|
||||
<div class="navbar-header">
|
||||
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar" aria-expanded="false" aria-controls="navbar">
|
||||
<span class="sr-only">Toggle navigation</span>
|
||||
<span class="icon-bar"></span>
|
||||
<span class="icon-bar"></span>
|
||||
<span class="icon-bar"></span>
|
||||
</button>
|
||||
<a class="navbar-brand" href="<%= thread_path(@conn, :index) %>"><img src="https://tilde.team/favicon-32x32.png" alt="tilde.team logo"></a>
|
||||
</div>
|
||||
<div id="navbar" class="navbar-collapse collapse">
|
||||
<ul class="nav navbar-nav navbar-right">
|
||||
<%= if @conn |> Plug.Conn.get_session(:loggedin) do %>
|
||||
<li><%= link "home", to: thread_path(@conn, :index) %></li>
|
||||
<li><%= link "users", to: user_path(@conn, :index) %></li>
|
||||
<li><%= link "log out", to: login_path(@conn, :logout) %></li>
|
||||
<%= else %>
|
||||
<li><a href="https://tilde.team/signup/">register</a></li>
|
||||
<% end %>
|
||||
</ul>
|
||||
</div><!--/.nav-collapse -->
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<p class="alert alert-info" role="alert"><%= get_flash(@conn, :info) %></p>
|
||||
<p class="alert alert-danger" role="alert"><%= get_flash(@conn, :error) %></p>
|
||||
<%= if get_flash(@conn, :info) do %>
|
||||
<p class="alert alert-info" role="alert"><%= get_flash(@conn, :info) %></p>
|
||||
<% end %>
|
||||
|
||||
<%= if get_flash(@conn, :error) do %>
|
||||
<p class="alert alert-danger" role="alert"><%= get_flash(@conn, :error) %></p>
|
||||
<% end %>
|
||||
|
||||
<main role="main">
|
||||
<%= render @view_module, @view_template, assigns %>
|
||||
|
@ -37,5 +58,17 @@
|
|||
|
||||
</div> <!-- /container -->
|
||||
<script src="<%= static_path(@conn, "/js/app.js") %>"></script>
|
||||
<script>
|
||||
document.onreadystatechange = function () {
|
||||
if (document.readyState == "interactive") {
|
||||
var t = document.getElementsByTagName("textarea");
|
||||
for (var i = 0; i < t.length; i++) {
|
||||
t[i].addEventListener('keydown', function(e) {
|
||||
if (e.keyCode == 13 && e.ctrlKey) this.form.submit();
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -0,0 +1,11 @@
|
|||
<h2>login</h2>
|
||||
|
||||
<%= form_for @conn, login_path(@conn, :authenticate), fn f -> %>
|
||||
<%= label f, :username, "username" %>
|
||||
<%= text_input f, :username, class: "form-control" %>
|
||||
|
||||
<%= label f, :password, "password" %>
|
||||
<%= password_input f, :password, class: "form-control" %>
|
||||
<br>
|
||||
<%= submit "log in", class: "btn btn-primary" %>
|
||||
<% end %>
|
|
@ -1,36 +0,0 @@
|
|||
<div class="jumbotron">
|
||||
<h2><%= gettext "Welcome to %{name}!", name: "Phoenix" %></h2>
|
||||
<p class="lead">A productive web framework that<br />does not compromise speed and maintainability.</p>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-lg-6">
|
||||
<h4>Resources</h4>
|
||||
<ul>
|
||||
<li>
|
||||
<a href="http://phoenixframework.org/docs/overview">Guides</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="https://hexdocs.pm/phoenix">Docs</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="https://github.com/phoenixframework/phoenix">Source</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="col-lg-6">
|
||||
<h4>Help</h4>
|
||||
<ul>
|
||||
<li>
|
||||
<a href="http://groups.google.com/group/phoenix-talk">Mailing list</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="http://webchat.freenode.net/?channels=elixir-lang">#elixir-lang on freenode IRC</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="https://twitter.com/elixirphoenix">@elixirphoenix</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
|
@ -0,0 +1,5 @@
|
|||
<h2>edit post</h2>
|
||||
|
||||
<%= render "form.html", Map.put(assigns, :action, post_path(@conn, :update, @post)) %>
|
||||
|
||||
<span><%= link "back", to: thread_path(@conn, :show, @post.thread.id) %></span>
|
|
@ -0,0 +1,20 @@
|
|||
<%= form_for @changeset, @action, fn f -> %>
|
||||
<%= if @changeset.action do %>
|
||||
<div class="alert alert-danger">
|
||||
<p>oops, something went wrong! please check the errors below.</p>
|
||||
</div>
|
||||
<% end %>
|
||||
|
||||
<%= if assigns[:thread_id] do
|
||||
hidden_input f, :thread_id, value: assigns[:thread_id]
|
||||
end %>
|
||||
|
||||
<div class="form-group">
|
||||
<%= textarea f, :content, class: "form-control", rows: "10" %>
|
||||
<%= error_tag f, :content %>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<%= submit "reply", class: "btn btn-primary" %>
|
||||
</div>
|
||||
<% end %>
|
|
@ -0,0 +1,5 @@
|
|||
<h2>edit thread</h2>
|
||||
|
||||
<%= render "form.html", Map.put(assigns, :action, thread_path(@conn, :update, @thread)) %>
|
||||
|
||||
<span><%= link "back", to: thread_path(@conn, :index) %></span>
|
|
@ -0,0 +1,16 @@
|
|||
<%= form_for @changeset, @action, fn f -> %>
|
||||
<%= if @changeset.action do %>
|
||||
<div class="alert alert-danger">
|
||||
<p>Oops, something went wrong! Please check the errors below.</p>
|
||||
</div>
|
||||
<% end %>
|
||||
|
||||
<div class="form-group">
|
||||
<%= text_input f, :name, class: "form-control" %>
|
||||
<%= error_tag f, :name %>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<%= submit "submit", class: "btn btn-primary" %>
|
||||
</div>
|
||||
<% end %>
|
|
@ -1,3 +1,24 @@
|
|||
<div class="jumbotron">
|
||||
<h2>/t/<%= @thread %></h2>
|
||||
</div>
|
||||
<h2>forum.tilde.team</h2>
|
||||
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>threads</th>
|
||||
|
||||
<th></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<%= for thread <- @threads do %>
|
||||
<tr>
|
||||
<td><a href="<%= thread_path(@conn, :show, thread) %>"><%= thread.name %></a></td>
|
||||
|
||||
<td class="text-right">
|
||||
<span><%= link "delete", to: thread_path(@conn, :delete, thread), method: :delete, data: [confirm: "are you sure?"], class: "btn btn-danger btn-xs" %></span>
|
||||
</td>
|
||||
</tr>
|
||||
<% end %>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<span><%= link "new thread", to: thread_path(@conn, :new) %></span>
|
||||
|
|
|
@ -1 +1,5 @@
|
|||
<h2>new thread</h2>
|
||||
<h2>start new thread</h2>
|
||||
|
||||
<%= render "form.html", Map.put(assigns, :action, thread_path(@conn, :create)) %>
|
||||
|
||||
<span><%= link "back", to: thread_path(@conn, :index) %></span>
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
<div class="pull-right">
|
||||
<span><%= link "edit", to: thread_path(@conn, :edit, @thread) %></span>
|
||||
</div>
|
||||
<h2><%= @thread.name %></h2>
|
||||
<em><%= @thread.user %></em>
|
||||
|
||||
<%= for post <- @thread.posts do %>
|
||||
<div class="list-group">
|
||||
<div class="list-group-item">
|
||||
<%= link "edit", to: post_path(@conn, :edit, post), class: "btn btn-info btn-xs pull-right" %>
|
||||
<%= raw Earmark.as_html! post.content %>
|
||||
</div>
|
||||
</div>
|
||||
<% end %>
|
||||
|
||||
<%= render ForumWeb.PostView, "form.html",
|
||||
%{:action => post_path(@conn, :create),
|
||||
:thread_id => @thread.id,
|
||||
:changeset => Forum.change_post(%Forum.Post{})
|
||||
} %>
|
|
@ -0,0 +1,5 @@
|
|||
<h2>edit user</h2>
|
||||
|
||||
<%= render "form.html", Map.put(assigns, :action, user_path(@conn, :update, @user)) %>
|
||||
|
||||
<span><%= link "back", to: user_path(@conn, :index) %></span>
|
|
@ -0,0 +1,23 @@
|
|||
<%= form_for @changeset, @action, fn f -> %>
|
||||
<%= if @changeset.action do %>
|
||||
<div class="alert alert-danger">
|
||||
<p>Oops, something went wrong! Please check the errors below.</p>
|
||||
</div>
|
||||
<% end %>
|
||||
|
||||
<div class="form-group">
|
||||
<%= label f, :name, class: "control-label" %>
|
||||
<%= text_input f, :name, class: "form-control" %>
|
||||
<%= error_tag f, :name %>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<%= label f, :bio, class: "control-label" %>
|
||||
<%= textarea f, :bio, class: "form-control", rows: "15" %>
|
||||
<%= error_tag f, :bio %>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<%= submit "Submit", class: "btn btn-primary" %>
|
||||
</div>
|
||||
<% end %>
|
|
@ -1,3 +1,28 @@
|
|||
<div class="jumbotron">
|
||||
<h2>/u/<%= @user %></h2>
|
||||
</div>
|
||||
<h2>users</h2>
|
||||
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>name</th>
|
||||
<th>bio</th>
|
||||
|
||||
<th></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<%= for user <- @users do %>
|
||||
<tr>
|
||||
<td><%= user.name %></td>
|
||||
<td><%= user.bio %></td>
|
||||
|
||||
<td class="text-right">
|
||||
<span><%= link "show", to: user_path(@conn, :show, user), class: "btn btn-default btn-xs" %></span>
|
||||
<span><%= link "edit", to: user_path(@conn, :edit, user), class: "btn btn-default btn-xs" %></span>
|
||||
<span><%= link "delete", to: user_path(@conn, :delete, user), method: :delete, data: [confirm: "Are you sure?"], class: "btn btn-danger btn-xs" %></span>
|
||||
</td>
|
||||
</tr>
|
||||
<% end %>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<span><%= link "add user", to: user_path(@conn, :new) %></span>
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
<h2>New User</h2>
|
||||
|
||||
<%= render "form.html", Map.put(assigns, :action, user_path(@conn, :create)) %>
|
||||
|
||||
<span><%= link "Back", to: user_path(@conn, :index) %></span>
|
|
@ -0,0 +1,8 @@
|
|||
<h2><%= @user.name %></h2>
|
||||
<hr>
|
||||
|
||||
<%= raw Earmark.as_html!(@user.bio) %>
|
||||
|
||||
<hr>
|
||||
<span><%= link "edit", to: user_path(@conn, :edit, @user) %></span>
|
||||
<span><%= link "back", to: user_path(@conn, :index) %></span>
|
|
@ -0,0 +1,3 @@
|
|||
defmodule ForumWeb.LoginView do
|
||||
use ForumWeb, :view
|
||||
end
|
|
@ -0,0 +1,3 @@
|
|||
defmodule ForumWeb.PostView do
|
||||
use ForumWeb, :view
|
||||
end
|
|
@ -1,3 +1,3 @@
|
|||
defmodule ForumWeb.ThreadView do
|
||||
use ForumWeb, :view
|
||||
use ForumWeb, :view
|
||||
end
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
defmodule ForumWeb.UserView do
|
||||
use ForumWeb, :view
|
||||
use ForumWeb, :view
|
||||
end
|
||||
|
|
2
mix.exs
2
mix.exs
|
@ -36,7 +36,9 @@ defmodule Forum.Mixfile do
|
|||
{:phoenix, "~> 1.3.0"},
|
||||
{:phoenix_pubsub, "~> 1.0"},
|
||||
{:phoenix_ecto, "~> 3.2"},
|
||||
{:tesla, ">= 0.10.0"},
|
||||
{:mariaex, ">= 0.0.0"},
|
||||
{:earmark, ">= 1.2.4"},
|
||||
{:phoenix_html, "~> 2.10"},
|
||||
{:phoenix_live_reload, "~> 1.0", only: :dev},
|
||||
{:gettext, "~> 0.11"},
|
||||
|
|
2
mix.lock
2
mix.lock
|
@ -4,6 +4,7 @@
|
|||
"cowlib": {:hex, :cowlib, "1.0.2", "9d769a1d062c9c3ac753096f868ca121e2730b9a377de23dec0f7e08b1df84ee", [:make], [], "hexpm"},
|
||||
"db_connection": {:hex, :db_connection, "1.1.3", "89b30ca1ef0a3b469b1c779579590688561d586694a3ce8792985d4d7e575a61", [:mix], [{:connection, "~> 1.0.2", [hex: :connection, repo: "hexpm", optional: false]}, {:poolboy, "~> 1.5", [hex: :poolboy, repo: "hexpm", optional: true]}, {:sbroker, "~> 1.0", [hex: :sbroker, repo: "hexpm", optional: true]}], "hexpm"},
|
||||
"decimal": {:hex, :decimal, "1.4.1", "ad9e501edf7322f122f7fc151cce7c2a0c9ada96f2b0155b8a09a795c2029770", [:mix], [], "hexpm"},
|
||||
"earmark": {:hex, :earmark, "1.2.4", "99b637c62a4d65a20a9fb674b8cffb8baa771c04605a80c911c4418c69b75439", [:mix], [], "hexpm"},
|
||||
"ecto": {:hex, :ecto, "2.2.8", "a4463c0928b970f2cee722cd29aaac154e866a15882c5737e0038bbfcf03ec2c", [:mix], [{:db_connection, "~> 1.1", [hex: :db_connection, repo: "hexpm", optional: true]}, {:decimal, "~> 1.2", [hex: :decimal, repo: "hexpm", optional: false]}, {:mariaex, "~> 0.8.0", [hex: :mariaex, repo: "hexpm", optional: true]}, {:poison, "~> 2.2 or ~> 3.0", [hex: :poison, repo: "hexpm", optional: true]}, {:poolboy, "~> 1.5", [hex: :poolboy, repo: "hexpm", optional: false]}, {:postgrex, "~> 0.13.0", [hex: :postgrex, repo: "hexpm", optional: true]}, {:sbroker, "~> 1.0", [hex: :sbroker, repo: "hexpm", optional: true]}], "hexpm"},
|
||||
"file_system": {:hex, :file_system, "0.2.4", "f0bdda195c0e46e987333e986452ec523aed21d784189144f647c43eaf307064", [:mix], [], "hexpm"},
|
||||
"gettext": {:hex, :gettext, "0.14.1", "a666b6782fdb6ccb4736170ccb0928c0f773aa0e47c694d4b7d0338f724ff189", [:mix], [], "hexpm"},
|
||||
|
@ -18,4 +19,5 @@
|
|||
"poison": {:hex, :poison, "3.1.0", "d9eb636610e096f86f25d9a46f35a9facac35609a7591b3be3326e99a0484665", [:mix], [], "hexpm"},
|
||||
"poolboy": {:hex, :poolboy, "1.5.1", "6b46163901cfd0a1b43d692657ed9d7e599853b3b21b95ae5ae0a777cf9b6ca8", [:rebar], [], "hexpm"},
|
||||
"ranch": {:hex, :ranch, "1.3.2", "e4965a144dc9fbe70e5c077c65e73c57165416a901bd02ea899cfd95aa890986", [:rebar3], [], "hexpm"},
|
||||
"tesla": {:hex, :tesla, "0.10.0", "e588c7e7f1c0866c81eeed5c38f02a4a94d6309eede336c1e6ca08b0a95abd3f", [:mix], [{:exjsx, ">= 0.1.0", [hex: :exjsx, repo: "hexpm", optional: true]}, {:fuse, "~> 2.4", [hex: :fuse, repo: "hexpm", optional: true]}, {:hackney, "~> 1.6", [hex: :hackney, repo: "hexpm", optional: true]}, {:ibrowse, "~> 4.2", [hex: :ibrowse, repo: "hexpm", optional: true]}, {:mime, "~> 1.0", [hex: :mime, repo: "hexpm", optional: false]}, {:poison, ">= 1.0.0", [hex: :poison, repo: "hexpm", optional: true]}], "hexpm"},
|
||||
}
|
||||
|
|
|
@ -0,0 +1,13 @@
|
|||
defmodule Forum.Repo.Migrations.CreateUsers do
|
||||
use Ecto.Migration
|
||||
|
||||
def change do
|
||||
create table(:users) do
|
||||
add :name, :string
|
||||
add :bio, :string
|
||||
|
||||
timestamps()
|
||||
end
|
||||
|
||||
end
|
||||
end
|
|
@ -0,0 +1,13 @@
|
|||
defmodule Forum.Repo.Migrations.CreatePosts do
|
||||
use Ecto.Migration
|
||||
|
||||
def change do
|
||||
create table(:posts) do
|
||||
add :content, :string
|
||||
add :sticky, :boolean, default: false, null: false
|
||||
|
||||
timestamps()
|
||||
end
|
||||
|
||||
end
|
||||
end
|
|
@ -0,0 +1,12 @@
|
|||
defmodule Forum.Repo.Migrations.CreateThreads do
|
||||
use Ecto.Migration
|
||||
|
||||
def change do
|
||||
create table(:threads) do
|
||||
add :name, :string
|
||||
|
||||
timestamps()
|
||||
end
|
||||
|
||||
end
|
||||
end
|
|
@ -0,0 +1,13 @@
|
|||
defmodule Forum.Repo.Migrations.AddRelationships do
|
||||
use Ecto.Migration
|
||||
|
||||
def change do
|
||||
alter table(:threads) do
|
||||
add :user_id, references(:users)
|
||||
end
|
||||
alter table(:posts) do
|
||||
add :thread_id, references(:threads)
|
||||
add :user_id, references(:threads)
|
||||
end
|
||||
end
|
||||
end
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -0,0 +1,189 @@
|
|||
defmodule Forum.ForumTest do
|
||||
use Forum.DataCase
|
||||
|
||||
alias Forum.Forum
|
||||
|
||||
describe "users" do
|
||||
alias Forum.Forum.User
|
||||
|
||||
@valid_attrs %{bio: "some bio", name: "some name"}
|
||||
@update_attrs %{bio: "some updated bio", name: "some updated name"}
|
||||
@invalid_attrs %{bio: nil, name: nil}
|
||||
|
||||
def user_fixture(attrs \\ %{}) do
|
||||
{:ok, user} =
|
||||
attrs
|
||||
|> Enum.into(@valid_attrs)
|
||||
|> Forum.create_user()
|
||||
|
||||
user
|
||||
end
|
||||
|
||||
test "list_users/0 returns all users" do
|
||||
user = user_fixture()
|
||||
assert Forum.list_users() == [user]
|
||||
end
|
||||
|
||||
test "get_user!/1 returns the user with given id" do
|
||||
user = user_fixture()
|
||||
assert Forum.get_user!(user.id) == user
|
||||
end
|
||||
|
||||
test "create_user/1 with valid data creates a user" do
|
||||
assert {:ok, %User{} = user} = Forum.create_user(@valid_attrs)
|
||||
assert user.bio == "some bio"
|
||||
assert user.name == "some name"
|
||||
end
|
||||
|
||||
test "create_user/1 with invalid data returns error changeset" do
|
||||
assert {:error, %Ecto.Changeset{}} = Forum.create_user(@invalid_attrs)
|
||||
end
|
||||
|
||||
test "update_user/2 with valid data updates the user" do
|
||||
user = user_fixture()
|
||||
assert {:ok, user} = Forum.update_user(user, @update_attrs)
|
||||
assert %User{} = user
|
||||
assert user.bio == "some updated bio"
|
||||
assert user.name == "some updated name"
|
||||
end
|
||||
|
||||
test "update_user/2 with invalid data returns error changeset" do
|
||||
user = user_fixture()
|
||||
assert {:error, %Ecto.Changeset{}} = Forum.update_user(user, @invalid_attrs)
|
||||
assert user == Forum.get_user!(user.id)
|
||||
end
|
||||
|
||||
test "delete_user/1 deletes the user" do
|
||||
user = user_fixture()
|
||||
assert {:ok, %User{}} = Forum.delete_user(user)
|
||||
assert_raise Ecto.NoResultsError, fn -> Forum.get_user!(user.id) end
|
||||
end
|
||||
|
||||
test "change_user/1 returns a user changeset" do
|
||||
user = user_fixture()
|
||||
assert %Ecto.Changeset{} = Forum.change_user(user)
|
||||
end
|
||||
end
|
||||
|
||||
describe "posts" do
|
||||
alias Forum.Forum.Post
|
||||
|
||||
@valid_attrs %{content: "some content", sticky: true}
|
||||
@update_attrs %{content: "some updated content", sticky: false}
|
||||
@invalid_attrs %{content: nil, sticky: nil}
|
||||
|
||||
def post_fixture(attrs \\ %{}) do
|
||||
{:ok, post} =
|
||||
attrs
|
||||
|> Enum.into(@valid_attrs)
|
||||
|> Forum.create_post()
|
||||
|
||||
post
|
||||
end
|
||||
|
||||
test "list_posts/0 returns all posts" do
|
||||
post = post_fixture()
|
||||
assert Forum.list_posts() == [post]
|
||||
end
|
||||
|
||||
test "get_post!/1 returns the post with given id" do
|
||||
post = post_fixture()
|
||||
assert Forum.get_post!(post.id) == post
|
||||
end
|
||||
|
||||
test "create_post/1 with valid data creates a post" do
|
||||
assert {:ok, %Post{} = post} = Forum.create_post(@valid_attrs)
|
||||
assert post.content == "some content"
|
||||
assert post.sticky == true
|
||||
end
|
||||
|
||||
test "create_post/1 with invalid data returns error changeset" do
|
||||
assert {:error, %Ecto.Changeset{}} = Forum.create_post(@invalid_attrs)
|
||||
end
|
||||
|
||||
test "update_post/2 with valid data updates the post" do
|
||||
post = post_fixture()
|
||||
assert {:ok, post} = Forum.update_post(post, @update_attrs)
|
||||
assert %Post{} = post
|
||||
assert post.content == "some updated content"
|
||||
assert post.sticky == false
|
||||
end
|
||||
|
||||
test "update_post/2 with invalid data returns error changeset" do
|
||||
post = post_fixture()
|
||||
assert {:error, %Ecto.Changeset{}} = Forum.update_post(post, @invalid_attrs)
|
||||
assert post == Forum.get_post!(post.id)
|
||||
end
|
||||
|
||||
test "delete_post/1 deletes the post" do
|
||||
post = post_fixture()
|
||||
assert {:ok, %Post{}} = Forum.delete_post(post)
|
||||
assert_raise Ecto.NoResultsError, fn -> Forum.get_post!(post.id) end
|
||||
end
|
||||
|
||||
test "change_post/1 returns a post changeset" do
|
||||
post = post_fixture()
|
||||
assert %Ecto.Changeset{} = Forum.change_post(post)
|
||||
end
|
||||
end
|
||||
|
||||
describe "threads" do
|
||||
alias Forum.Forum.Thread
|
||||
|
||||
@valid_attrs %{name: "some name"}
|
||||
@update_attrs %{name: "some updated name"}
|
||||
@invalid_attrs %{name: nil}
|
||||
|
||||
def thread_fixture(attrs \\ %{}) do
|
||||
{:ok, thread} =
|
||||
attrs
|
||||
|> Enum.into(@valid_attrs)
|
||||
|> Forum.create_thread()
|
||||
|
||||
thread
|
||||
end
|
||||
|
||||
test "list_threads/0 returns all threads" do
|
||||
thread = thread_fixture()
|
||||
assert Forum.list_threads() == [thread]
|
||||
end
|
||||
|
||||
test "get_thread!/1 returns the thread with given id" do
|
||||
thread = thread_fixture()
|
||||
assert Forum.get_thread!(thread.id) == thread
|
||||
end
|
||||
|
||||
test "create_thread/1 with valid data creates a thread" do
|
||||
assert {:ok, %Thread{} = thread} = Forum.create_thread(@valid_attrs)
|
||||
assert thread.name == "some name"
|
||||
end
|
||||
|
||||
test "create_thread/1 with invalid data returns error changeset" do
|
||||
assert {:error, %Ecto.Changeset{}} = Forum.create_thread(@invalid_attrs)
|
||||
end
|
||||
|
||||
test "update_thread/2 with valid data updates the thread" do
|
||||
thread = thread_fixture()
|
||||
assert {:ok, thread} = Forum.update_thread(thread, @update_attrs)
|
||||
assert %Thread{} = thread
|
||||
assert thread.name == "some updated name"
|
||||
end
|
||||
|
||||
test "update_thread/2 with invalid data returns error changeset" do
|
||||
thread = thread_fixture()
|
||||
assert {:error, %Ecto.Changeset{}} = Forum.update_thread(thread, @invalid_attrs)
|
||||
assert thread == Forum.get_thread!(thread.id)
|
||||
end
|
||||
|
||||
test "delete_thread/1 deletes the thread" do
|
||||
thread = thread_fixture()
|
||||
assert {:ok, %Thread{}} = Forum.delete_thread(thread)
|
||||
assert_raise Ecto.NoResultsError, fn -> Forum.get_thread!(thread.id) end
|
||||
end
|
||||
|
||||
test "change_thread/1 returns a thread changeset" do
|
||||
thread = thread_fixture()
|
||||
assert %Ecto.Changeset{} = Forum.change_thread(thread)
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,88 @@
|
|||
defmodule ForumWeb.PostControllerTest do
|
||||
use ForumWeb.ConnCase
|
||||
|
||||
alias Forum.Forum
|
||||
|
||||
@create_attrs %{content: "some content", sticky: true}
|
||||
@update_attrs %{content: "some updated content", sticky: false}
|
||||
@invalid_attrs %{content: nil, sticky: nil}
|
||||
|
||||
def fixture(:post) do
|
||||
{:ok, post} = Forum.create_post(@create_attrs)
|
||||
post
|
||||
end
|
||||
|
||||
describe "index" do
|
||||
test "lists all posts", %{conn: conn} do
|
||||
conn = get conn, post_path(conn, :index)
|
||||
assert html_response(conn, 200) =~ "Listing Posts"
|
||||
end
|
||||
end
|
||||
|
||||
describe "new post" do
|
||||
test "renders form", %{conn: conn} do
|
||||
conn = get conn, post_path(conn, :new)
|
||||
assert html_response(conn, 200) =~ "New Post"
|
||||
end
|
||||
end
|
||||
|
||||
describe "create post" do
|
||||
test "redirects to show when data is valid", %{conn: conn} do
|
||||
conn = post conn, post_path(conn, :create), post: @create_attrs
|
||||
|
||||
assert %{id: id} = redirected_params(conn)
|
||||
assert redirected_to(conn) == post_path(conn, :show, id)
|
||||
|
||||
conn = get conn, post_path(conn, :show, id)
|
||||
assert html_response(conn, 200) =~ "Show Post"
|
||||
end
|
||||
|
||||
test "renders errors when data is invalid", %{conn: conn} do
|
||||
conn = post conn, post_path(conn, :create), post: @invalid_attrs
|
||||
assert html_response(conn, 200) =~ "New Post"
|
||||
end
|
||||
end
|
||||
|
||||
describe "edit post" do
|
||||
setup [:create_post]
|
||||
|
||||
test "renders form for editing chosen post", %{conn: conn, post: post} do
|
||||
conn = get conn, post_path(conn, :edit, post)
|
||||
assert html_response(conn, 200) =~ "Edit Post"
|
||||
end
|
||||
end
|
||||
|
||||
describe "update post" do
|
||||
setup [:create_post]
|
||||
|
||||
test "redirects when data is valid", %{conn: conn, post: post} do
|
||||
conn = put conn, post_path(conn, :update, post), post: @update_attrs
|
||||
assert redirected_to(conn) == post_path(conn, :show, post)
|
||||
|
||||
conn = get conn, post_path(conn, :show, post)
|
||||
assert html_response(conn, 200) =~ "some updated content"
|
||||
end
|
||||
|
||||
test "renders errors when data is invalid", %{conn: conn, post: post} do
|
||||
conn = put conn, post_path(conn, :update, post), post: @invalid_attrs
|
||||
assert html_response(conn, 200) =~ "Edit Post"
|
||||
end
|
||||
end
|
||||
|
||||
describe "delete post" do
|
||||
setup [:create_post]
|
||||
|
||||
test "deletes chosen post", %{conn: conn, post: post} do
|
||||
conn = delete conn, post_path(conn, :delete, post)
|
||||
assert redirected_to(conn) == post_path(conn, :index)
|
||||
assert_error_sent 404, fn ->
|
||||
get conn, post_path(conn, :show, post)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
defp create_post(_) do
|
||||
post = fixture(:post)
|
||||
{:ok, post: post}
|
||||
end
|
||||
end
|
|
@ -0,0 +1,88 @@
|
|||
defmodule ForumWeb.ThreadControllerTest do
|
||||
use ForumWeb.ConnCase
|
||||
|
||||
alias Forum.Forum
|
||||
|
||||
@create_attrs %{name: "some name"}
|
||||
@update_attrs %{name: "some updated name"}
|
||||
@invalid_attrs %{name: nil}
|
||||
|
||||
def fixture(:thread) do
|
||||
{:ok, thread} = Forum.create_thread(@create_attrs)
|
||||
thread
|
||||
end
|
||||
|
||||
describe "index" do
|
||||
test "lists all threads", %{conn: conn} do
|
||||
conn = get conn, thread_path(conn, :index)
|
||||
assert html_response(conn, 200) =~ "Listing Threads"
|
||||
end
|
||||
end
|
||||
|
||||
describe "new thread" do
|
||||
test "renders form", %{conn: conn} do
|
||||
conn = get conn, thread_path(conn, :new)
|
||||
assert html_response(conn, 200) =~ "New Thread"
|
||||
end
|
||||
end
|
||||
|
||||
describe "create thread" do
|
||||
test "redirects to show when data is valid", %{conn: conn} do
|
||||
conn = post conn, thread_path(conn, :create), thread: @create_attrs
|
||||
|
||||
assert %{id: id} = redirected_params(conn)
|
||||
assert redirected_to(conn) == thread_path(conn, :show, id)
|
||||
|
||||
conn = get conn, thread_path(conn, :show, id)
|
||||
assert html_response(conn, 200) =~ "Show Thread"
|
||||
end
|
||||
|
||||
test "renders errors when data is invalid", %{conn: conn} do
|
||||
conn = post conn, thread_path(conn, :create), thread: @invalid_attrs
|
||||
assert html_response(conn, 200) =~ "New Thread"
|
||||
end
|
||||
end
|
||||
|
||||
describe "edit thread" do
|
||||
setup [:create_thread]
|
||||
|
||||
test "renders form for editing chosen thread", %{conn: conn, thread: thread} do
|
||||
conn = get conn, thread_path(conn, :edit, thread)
|
||||
assert html_response(conn, 200) =~ "Edit Thread"
|
||||
end
|
||||
end
|
||||
|
||||
describe "update thread" do
|
||||
setup [:create_thread]
|
||||
|
||||
test "redirects when data is valid", %{conn: conn, thread: thread} do
|
||||
conn = put conn, thread_path(conn, :update, thread), thread: @update_attrs
|
||||
assert redirected_to(conn) == thread_path(conn, :show, thread)
|
||||
|
||||
conn = get conn, thread_path(conn, :show, thread)
|
||||
assert html_response(conn, 200) =~ "some updated name"
|
||||
end
|
||||
|
||||
test "renders errors when data is invalid", %{conn: conn, thread: thread} do
|
||||
conn = put conn, thread_path(conn, :update, thread), thread: @invalid_attrs
|
||||
assert html_response(conn, 200) =~ "Edit Thread"
|
||||
end
|
||||
end
|
||||
|
||||
describe "delete thread" do
|
||||
setup [:create_thread]
|
||||
|
||||
test "deletes chosen thread", %{conn: conn, thread: thread} do
|
||||
conn = delete conn, thread_path(conn, :delete, thread)
|
||||
assert redirected_to(conn) == thread_path(conn, :index)
|
||||
assert_error_sent 404, fn ->
|
||||
get conn, thread_path(conn, :show, thread)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
defp create_thread(_) do
|
||||
thread = fixture(:thread)
|
||||
{:ok, thread: thread}
|
||||
end
|
||||
end
|
|
@ -0,0 +1,88 @@
|
|||
defmodule ForumWeb.UserControllerTest do
|
||||
use ForumWeb.ConnCase
|
||||
|
||||
alias Forum.Forum
|
||||
|
||||
@create_attrs %{bio: "some bio", name: "some name"}
|
||||
@update_attrs %{bio: "some updated bio", name: "some updated name"}
|
||||
@invalid_attrs %{bio: nil, name: nil}
|
||||
|
||||
def fixture(:user) do
|
||||
{:ok, user} = Forum.create_user(@create_attrs)
|
||||
user
|
||||
end
|
||||
|
||||
describe "index" do
|
||||
test "lists all users", %{conn: conn} do
|
||||
conn = get conn, user_path(conn, :index)
|
||||
assert html_response(conn, 200) =~ "Listing Users"
|
||||
end
|
||||
end
|
||||
|
||||
describe "new user" do
|
||||
test "renders form", %{conn: conn} do
|
||||
conn = get conn, user_path(conn, :new)
|
||||
assert html_response(conn, 200) =~ "New User"
|
||||
end
|
||||
end
|
||||
|
||||
describe "create user" do
|
||||
test "redirects to show when data is valid", %{conn: conn} do
|
||||
conn = post conn, user_path(conn, :create), user: @create_attrs
|
||||
|
||||
assert %{id: id} = redirected_params(conn)
|
||||
assert redirected_to(conn) == user_path(conn, :show, id)
|
||||
|
||||
conn = get conn, user_path(conn, :show, id)
|
||||
assert html_response(conn, 200) =~ "Show User"
|
||||
end
|
||||
|
||||
test "renders errors when data is invalid", %{conn: conn} do
|
||||
conn = post conn, user_path(conn, :create), user: @invalid_attrs
|
||||
assert html_response(conn, 200) =~ "New User"
|
||||
end
|
||||
end
|
||||
|
||||
describe "edit user" do
|
||||
setup [:create_user]
|
||||
|
||||
test "renders form for editing chosen user", %{conn: conn, user: user} do
|
||||
conn = get conn, user_path(conn, :edit, user)
|
||||
assert html_response(conn, 200) =~ "Edit User"
|
||||
end
|
||||
end
|
||||
|
||||
describe "update user" do
|
||||
setup [:create_user]
|
||||
|
||||
test "redirects when data is valid", %{conn: conn, user: user} do
|
||||
conn = put conn, user_path(conn, :update, user), user: @update_attrs
|
||||
assert redirected_to(conn) == user_path(conn, :show, user)
|
||||
|
||||
conn = get conn, user_path(conn, :show, user)
|
||||
assert html_response(conn, 200) =~ "some updated bio"
|
||||
end
|
||||
|
||||
test "renders errors when data is invalid", %{conn: conn, user: user} do
|
||||
conn = put conn, user_path(conn, :update, user), user: @invalid_attrs
|
||||
assert html_response(conn, 200) =~ "Edit User"
|
||||
end
|
||||
end
|
||||
|
||||
describe "delete user" do
|
||||
setup [:create_user]
|
||||
|
||||
test "deletes chosen user", %{conn: conn, user: user} do
|
||||
conn = delete conn, user_path(conn, :delete, user)
|
||||
assert redirected_to(conn) == user_path(conn, :index)
|
||||
assert_error_sent 404, fn ->
|
||||
get conn, user_path(conn, :show, user)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
defp create_user(_) do
|
||||
user = fixture(:user)
|
||||
{:ok, user: user}
|
||||
end
|
||||
end
|
Reference in New Issue