-
Notifications
You must be signed in to change notification settings - Fork 45
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #42 from dwyl/code-examples
More Code Examples from the Programming Phoenix book
- Loading branch information
Showing
43 changed files
with
663 additions
and
103 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
language: elixir | ||
elixir: | ||
- 1.3.4 | ||
before_install: cd /home/travis/build/dwyl/learn-phoenix-framework/rumbl && pwd | ||
cache: | ||
directories: | ||
- _build | ||
- deps |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
# run this test using the following command: | ||
# elixir -e "ExUnit.start()" -r basic-test.exs | ||
|
||
defmodule MyTest do | ||
use ExUnit.Case, async: true | ||
|
||
setup do | ||
# run some tedious setup code | ||
:ok | ||
end | ||
|
||
test "pass" do | ||
assert true | ||
end | ||
|
||
test "fail" do | ||
refute false | ||
end | ||
end | ||
|
||
|
||
# thanks to @shouston3 in | ||
# https://github.com/dwyl/learn-phoenix-framework/issues/34#issuecomment-280930167 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
defmodule Rumbl.Permalink do | ||
@behaviour Ecto.Type | ||
|
||
def type, do: :id | ||
|
||
def cast(binary) when is_binary(binary) do | ||
case Integer.parse(binary) do | ||
{int, _} when int > 0 -> {:ok, int} | ||
_ -> :error | ||
end | ||
end | ||
|
||
def cast(integer) when is_integer(integer) do | ||
{:ok, integer} | ||
end | ||
|
||
def cast(_) do | ||
:error | ||
end | ||
|
||
def dump(integer) when is_integer(integer) do | ||
{:ok, integer} | ||
end | ||
|
||
def load(integer) when is_integer(integer) do | ||
{:ok, integer} | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -11,6 +11,5 @@ defmodule Rumbl.Repo.Migrations.CreateVideo do | |
timestamps() | ||
end | ||
create index(:videos, [:user_id]) | ||
|
||
end | ||
end |
13 changes: 13 additions & 0 deletions
13
rumbl/priv/repo/migrations/20170218093549_create_category.exs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
defmodule Rumbl.Repo.Migrations.CreateCategory do | ||
use Ecto.Migration | ||
|
||
def change do | ||
create table(:categories) do | ||
add :name, :string, null: false | ||
|
||
timestamps() # function call parenthesis not in book! | ||
end | ||
|
||
create unique_index(:categories, [:name]) | ||
end | ||
end |
9 changes: 9 additions & 0 deletions
9
rumbl/priv/repo/migrations/20170218111702_add_category_id_to_video.exs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
defmodule Rumbl.Repo.Migrations.AddCategoryIdToVideo do | ||
use Ecto.Migration | ||
|
||
def change do | ||
alter table(:videos) do | ||
add :category_id, references(:categories) | ||
end | ||
end | ||
end |
9 changes: 9 additions & 0 deletions
9
rumbl/priv/repo/migrations/20170305085721_add_slug_to_video.exs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
defmodule Rumbl.Repo.Migrations.AddSlugToVideo do | ||
use Ecto.Migration | ||
|
||
def change do | ||
alter table(:videos) do | ||
add :slug, :string | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
defmodule Rumb.AuthTest do | ||
use Rumbl.ConnCase | ||
alias Rumbl.Auth | ||
|
||
setup %{conn: conn} do | ||
conn = | ||
conn | ||
|> bypass_through(Rumbl.Router, :browser) | ||
|> get("/") | ||
|
||
{:ok, %{conn: conn}} | ||
end | ||
|
||
test "authenticate_user halts when no current_user exists", %{conn: conn} do | ||
conn = Auth.authenticate_user(conn, []) | ||
assert conn.halted | ||
end | ||
|
||
test "authenticate_user continues when the current_user exists", | ||
%{conn: conn} do | ||
|
||
conn = | ||
conn | ||
|> assign(:current_user, %Rumbl.User{}) | ||
|> Auth.authenticate_user([]) | ||
refute conn.halted | ||
end | ||
|
||
test "login puts the user in the session", %{conn: conn} do | ||
login_conn = | ||
conn | ||
|> Auth.login(%Rumbl.User{id: 123}) | ||
|> send_resp(:ok, "") | ||
|
||
next_conn = get(login_conn, "/") | ||
assert get_session(next_conn, :user_id) == 123 | ||
end | ||
|
||
test "logout drops the session", %{conn: conn} do | ||
logout_conn = | ||
conn | ||
|> put_session(:user_id, 123) | ||
|> Auth.logout() | ||
|> send_resp(:ok, "") | ||
|
||
next_conn = get(logout_conn, "/") | ||
refute get_session(next_conn, :user_id) | ||
end | ||
|
||
test "call places user from session into assigns", %{conn: conn} do | ||
user = insert_user() | ||
conn = | ||
conn | ||
|> put_session(:user_id, user.id) | ||
|> Auth.call(Repo) | ||
|
||
assert conn.assigns.current_user.id == user.id | ||
end | ||
|
||
test "call with no session sets current_user assign to nil", %{conn: conn} do | ||
conn = Auth.call(conn, Repo) | ||
assert conn.assigns.current_user == nil | ||
end | ||
|
||
test "login with a valid username and pass", %{conn: conn} do | ||
user = insert_user(username: "me", password: "secret") | ||
{:ok, conn} = | ||
Auth.login_by_username_and_pass(conn, "me", "secret", repo: Repo) | ||
|
||
assert conn.assigns.current_user.id == user.id | ||
end | ||
|
||
test "login with a not found user", %{conn: conn} do | ||
assert {:error, :not_found, _conn} = | ||
Auth.login_by_username_and_pass(conn, "me", "secret", repo: Repo) | ||
end | ||
|
||
test "login with password missmatch", %{conn: conn} do | ||
_ = insert_user(username: "me", password: "secret") | ||
assert {:error, :unauthorized, _conn} = | ||
Auth.login_by_username_and_pass(conn, "me", "wrong", repo: Repo) | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,66 +1,89 @@ | ||
defmodule Rumbl.VideoControllerTest do | ||
use Rumbl.ConnCase | ||
|
||
alias Rumbl.Video | ||
@valid_attrs %{description: "some content", title: "some content", url: "some content"} | ||
@invalid_attrs %{} | ||
|
||
test "lists all entries on index", %{conn: conn} do | ||
conn = get conn, video_path(conn, :index) | ||
assert html_response(conn, 200) =~ "Listing videos" | ||
setup %{conn: conn} = config do | ||
if username = config[:login_as] do | ||
user = insert_user(username: username) | ||
conn = assign(conn, :current_user, user) | ||
{:ok, conn: conn, user: user} | ||
else | ||
:ok | ||
end | ||
end | ||
|
||
test "renders form for new resources", %{conn: conn} do | ||
conn = get conn, video_path(conn, :new) | ||
assert html_response(conn, 200) =~ "New video" | ||
test "requires user authentication on all actions", %{conn: conn} do | ||
Enum.each([ | ||
get(conn, video_path(conn, :new)), | ||
get(conn, video_path(conn, :index)), | ||
get(conn, video_path(conn, :show, "123")), | ||
get(conn, video_path(conn, :edit, "123")), | ||
put(conn, video_path(conn, :update, "123", %{})), | ||
post(conn, video_path(conn, :create, %{})), | ||
delete(conn, video_path(conn, :delete, "123")), | ||
], fn conn -> | ||
assert html_response(conn, 302) | ||
assert conn.halted | ||
end) | ||
end | ||
|
||
test "creates resource and redirects when data is valid", %{conn: conn} do | ||
conn = post conn, video_path(conn, :create), video: @valid_attrs | ||
assert redirected_to(conn) == video_path(conn, :index) | ||
assert Repo.get_by(Video, @valid_attrs) | ||
end | ||
# setup do | ||
# user = insert_user(username: "max") | ||
# conn = assign(build_conn, :current_user, user) | ||
# {:ok, conn: conn, user: user} | ||
# end | ||
|
||
test "does not create resource and renders errors when data is invalid", %{conn: conn} do | ||
conn = post conn, video_path(conn, :create), video: @invalid_attrs | ||
assert html_response(conn, 200) =~ "New video" | ||
end | ||
@tag login_as: "max" | ||
test "lists all user's video on index", %{conn: conn, user: user} do | ||
user_video = insert_video(user, title: "funny cats") | ||
other_video = insert_video(insert_user(username: "other"), | ||
title: "another video") | ||
|
||
test "shows chosen resource", %{conn: conn} do | ||
video = Repo.insert! %Video{} | ||
conn = get conn, video_path(conn, :show, video) | ||
assert html_response(conn, 200) =~ "Show video" | ||
conn = get conn, video_path(conn, :index) | ||
assert html_response(conn, 200) =~ ~r/Listing videos/ | ||
assert String.contains?(conn.resp_body, user_video.title) | ||
refute String.contains?(conn.resp_body, other_video.title) | ||
end | ||
|
||
test "renders page not found when id is nonexistent", %{conn: conn} do | ||
assert_error_sent 404, fn -> | ||
get conn, video_path(conn, :show, -1) | ||
end | ||
end | ||
alias Rumbl.Video | ||
@valid_attrs %{url: "http://youtu.be", title: "vid", description: "a vid"} | ||
@invalid_attrs %{title: "invalid"} | ||
|
||
test "renders form for editing chosen resource", %{conn: conn} do | ||
video = Repo.insert! %Video{} | ||
conn = get conn, video_path(conn, :edit, video) | ||
assert html_response(conn, 200) =~ "Edit video" | ||
end | ||
defp video_count(query), do: Repo.one(from v in query, select: count(v.id)) | ||
|
||
test "updates chosen resource and redirects when data is valid", %{conn: conn} do | ||
video = Repo.insert! %Video{} | ||
conn = put conn, video_path(conn, :update, video), video: @valid_attrs | ||
assert redirected_to(conn) == video_path(conn, :show, video) | ||
assert Repo.get_by(Video, @valid_attrs) | ||
@tag login_as: "max" | ||
test "creates user video and redirects", %{conn: conn, user: user} do | ||
conn = post conn, video_path(conn, :create), video: @valid_attrs | ||
# assert redirected_to(conn) = video_path(conn, :index) # see: https://github.com/dwyl/learn-phoenix-framework/issues/40 | ||
assert Repo.get_by!(Video, @valid_attrs).user_id == user.id | ||
end | ||
|
||
test "does not update chosen resource and renders errors when data is invalid", %{conn: conn} do | ||
video = Repo.insert! %Video{} | ||
conn = put conn, video_path(conn, :update, video), video: @invalid_attrs | ||
assert html_response(conn, 200) =~ "Edit video" | ||
@tag login_as: "max" | ||
test "does not create video and renders errors when invalid", %{conn: conn} do | ||
count_before = video_count(Video) | ||
conn = post conn, video_path(conn, :create), video: @invalid_attrs | ||
assert html_response(conn, 200) =~ "check the errors" | ||
assert video_count(Video) == count_before | ||
end | ||
|
||
test "deletes chosen resource", %{conn: conn} do | ||
video = Repo.insert! %Video{} | ||
conn = delete conn, video_path(conn, :delete, video) | ||
assert redirected_to(conn) == video_path(conn, :index) | ||
refute Repo.get(Video, video.id) | ||
@tag login_as: "max" | ||
test "authorizes actions against access by other users", | ||
%{user: owner, conn: conn} do | ||
|
||
video = insert_video(owner, @valid_attrs) | ||
non_owner = insert_user(username: "sneaky") # https://youtu.be/_YQpbzQ6gzs?t=2m48s | ||
conn = assign(conn, :current_user, non_owner) | ||
|
||
assert_error_sent :not_found, fn -> | ||
get(conn, video_path(conn, :show, video)) | ||
end | ||
assert_error_sent :not_found, fn -> | ||
get(conn, video_path(conn, :edit, video)) | ||
end | ||
assert_error_sent :not_found, fn -> | ||
put(conn, video_path(conn, :update, video, video: @valid_attrs)) | ||
end | ||
assert_error_sent :not_found, fn -> | ||
delete(conn, video_path(conn, :delete, video)) | ||
end | ||
end | ||
end |
Oops, something went wrong.