mirror of
https://github.com/danbee/chess
synced 2025-03-04 08:39:06 +00:00
Games are now associated to a user
This commit is contained in:
parent
ac33ed49aa
commit
ea79ba962a
@ -10,6 +10,8 @@ defmodule Chess.Auth.User do
|
|||||||
field :password_hash, :string
|
field :password_hash, :string
|
||||||
field :username, :string
|
field :username, :string
|
||||||
|
|
||||||
|
has_many :games, Chess.Store.Game
|
||||||
|
|
||||||
timestamps()
|
timestamps()
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@ -5,35 +5,39 @@ defmodule Chess.Store.Game do
|
|||||||
import Ecto.Changeset
|
import Ecto.Changeset
|
||||||
import Ecto.Query
|
import Ecto.Query
|
||||||
|
|
||||||
|
alias Chess.Board
|
||||||
|
|
||||||
schema "games" do
|
schema "games" do
|
||||||
field :board, :map
|
field :board, :map
|
||||||
|
|
||||||
|
belongs_to :user, Chess.Auth.User
|
||||||
|
|
||||||
timestamps()
|
timestamps()
|
||||||
end
|
end
|
||||||
|
|
||||||
@doc """
|
@doc """
|
||||||
Builds a changeset based on the `struct` and `params`.
|
Builds a changeset based on the `struct` and `params`.
|
||||||
"""
|
"""
|
||||||
def changeset(struct) do
|
def create_changeset(struct, params \\ %{}) do
|
||||||
struct
|
struct
|
||||||
|> cast(%{}, [:board])
|
|> cast(params, [:board, :user_id])
|
||||||
|> set_default_board
|
|> put_change(:board, Board.default)
|
||||||
|> validate_required([:board])
|
|> validate_required([:board, :user_id])
|
||||||
end
|
end
|
||||||
|
|
||||||
def changeset(struct, params) do
|
def changeset(struct, params \\ %{}) do
|
||||||
struct
|
struct
|
||||||
|> cast(params, [:board])
|
|> cast(params, [:board, :user_id])
|
||||||
|> validate_required([:board])
|
|> validate_required([:board, :user_id])
|
||||||
|
end
|
||||||
|
|
||||||
|
def for_user(query, user) do
|
||||||
|
query
|
||||||
|
|> where([game], user_id: ^user.id)
|
||||||
end
|
end
|
||||||
|
|
||||||
def ordered(query) do
|
def ordered(query) do
|
||||||
query
|
query
|
||||||
|> order_by([game], desc: game.inserted_at)
|
|> order_by([game], desc: game.inserted_at)
|
||||||
end
|
end
|
||||||
|
|
||||||
def set_default_board(changeset) do
|
|
||||||
changeset
|
|
||||||
|> put_change(:board, Chess.Board.default)
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|||||||
@ -5,12 +5,18 @@ defmodule ChessWeb.GameController do
|
|||||||
|
|
||||||
def index(conn, _params) do
|
def index(conn, _params) do
|
||||||
changeset = Game.changeset(%Game{})
|
changeset = Game.changeset(%Game{})
|
||||||
games = Game |> Game.ordered |> Repo.all
|
games = Game
|
||||||
|
|> Game.for_user(current_user(conn))
|
||||||
|
|> Game.ordered
|
||||||
|
|> Repo.all
|
||||||
render(conn, "index.html", games: games, changeset: changeset)
|
render(conn, "index.html", games: games, changeset: changeset)
|
||||||
end
|
end
|
||||||
|
|
||||||
def create(conn, _params) do
|
def create(conn, _params) do
|
||||||
changeset = Game.changeset(%Game{})
|
changeset = Game.create_changeset(
|
||||||
|
%Game{},
|
||||||
|
%{user_id: current_user(conn).id}
|
||||||
|
)
|
||||||
|
|
||||||
case Repo.insert(changeset) do
|
case Repo.insert(changeset) do
|
||||||
{:ok, game} ->
|
{:ok, game} ->
|
||||||
@ -38,4 +44,8 @@ defmodule ChessWeb.GameController do
|
|||||||
|> put_flash(:info, "Game deleted successfully.")
|
|> put_flash(:info, "Game deleted successfully.")
|
||||||
|> redirect(to: game_path(conn, :index))
|
|> redirect(to: game_path(conn, :index))
|
||||||
end
|
end
|
||||||
|
|
||||||
|
defp current_user(conn) do
|
||||||
|
Guardian.Plug.current_resource(conn)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@ -0,0 +1,9 @@
|
|||||||
|
defmodule Chess.Repo.Migrations.AddUserIdToGames do
|
||||||
|
use Ecto.Migration
|
||||||
|
|
||||||
|
def change do
|
||||||
|
alter table("games") do
|
||||||
|
add :user_id, references(:users)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
@ -4,16 +4,30 @@ defmodule Chess.GameTest do
|
|||||||
describe "game" do
|
describe "game" do
|
||||||
alias Chess.Store.Game
|
alias Chess.Store.Game
|
||||||
|
|
||||||
@valid_attrs %{board: %{}}
|
test "game is valid with a board and user" do
|
||||||
@invalid_attrs %{}
|
attrs = %{board: %{}, user_id: 1}
|
||||||
|
changeset = Game.changeset(%Game{}, attrs)
|
||||||
|
|
||||||
test "changeset with valid attributes" do
|
|
||||||
changeset = Game.changeset(%Game{}, @valid_attrs)
|
|
||||||
assert changeset.valid?
|
assert changeset.valid?
|
||||||
end
|
end
|
||||||
|
|
||||||
test "changeset with invalid attributes" do
|
test "game is invalid without a board" do
|
||||||
changeset = Game.changeset(%Game{}, @invalid_attrs)
|
attrs = %{user_id: 1}
|
||||||
|
changeset = Game.changeset(%Game{}, attrs)
|
||||||
|
|
||||||
|
refute changeset.valid?
|
||||||
|
end
|
||||||
|
|
||||||
|
test "game is invalid without a user" do
|
||||||
|
attrs = %{board: %{}}
|
||||||
|
changeset = Game.changeset(%Game{}, attrs)
|
||||||
|
|
||||||
|
refute changeset.valid?
|
||||||
|
end
|
||||||
|
|
||||||
|
test "game is invalid without a board or user" do
|
||||||
|
changeset = Game.changeset(%Game{}, %{})
|
||||||
|
|
||||||
refute changeset.valid?
|
refute changeset.valid?
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@ -1,8 +1,14 @@
|
|||||||
defmodule Chess.GamesTest do
|
defmodule Chess.GamesTest do
|
||||||
use ChessWeb.FeatureCase
|
use ChessWeb.FeatureCase
|
||||||
|
|
||||||
import Wallaby.Query, only: [css: 1, css: 2, button: 1, text_field: 1]
|
import Wallaby.Query, only: [
|
||||||
import Chess.Factory, only: [create_user: 2]
|
css: 1,
|
||||||
|
css: 2,
|
||||||
|
button: 1,
|
||||||
|
text_field: 1,
|
||||||
|
link: 1,
|
||||||
|
]
|
||||||
|
import Chess.Factory, only: [create_user: 2, create_game_for: 1]
|
||||||
|
|
||||||
test "visit homepage", %{session: session} do
|
test "visit homepage", %{session: session} do
|
||||||
session
|
session
|
||||||
@ -13,11 +19,21 @@ defmodule Chess.GamesTest do
|
|||||||
test "can create a new game", %{session: session} do
|
test "can create a new game", %{session: session} do
|
||||||
session
|
session
|
||||||
|> login()
|
|> login()
|
||||||
|> take_screenshot()
|
|
||||||
|> create_game()
|
|> create_game()
|
||||||
|> assert_has(css(".board"))
|
|> assert_has(css(".board"))
|
||||||
end
|
end
|
||||||
|
|
||||||
|
test "can only see own games", %{session: session} do
|
||||||
|
user = create_user("zelda@hyrule.kingdom", "ganonsucks")
|
||||||
|
create_game_for(user)
|
||||||
|
|
||||||
|
session
|
||||||
|
|> login()
|
||||||
|
|> create_game()
|
||||||
|
|> click(link("Back to games"))
|
||||||
|
|> assert_has(css(".table tr", count: 1))
|
||||||
|
end
|
||||||
|
|
||||||
test "can move a piece", %{session: session} do
|
test "can move a piece", %{session: session} do
|
||||||
session
|
session
|
||||||
|> login()
|
|> login()
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
defmodule Chess.Factory do
|
defmodule Chess.Factory do
|
||||||
alias Chess.Auth.User
|
alias Chess.Auth.User
|
||||||
|
alias Chess.Store.Game
|
||||||
alias Chess.Repo
|
alias Chess.Repo
|
||||||
|
|
||||||
def create_user(username \\ "zelda", password \\ "password") do
|
def create_user(username \\ "zelda", password \\ "password") do
|
||||||
@ -9,4 +10,12 @@ defmodule Chess.Factory do
|
|||||||
)
|
)
|
||||||
|> Repo.insert!
|
|> Repo.insert!
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def create_game_for(user) do
|
||||||
|
Game.create_changeset(
|
||||||
|
%Game{},
|
||||||
|
%{user_id: user.id}
|
||||||
|
)
|
||||||
|
|> Repo.insert!
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@ -2,6 +2,6 @@
|
|||||||
|
|
||||||
ExUnit.start()
|
ExUnit.start()
|
||||||
|
|
||||||
Ecto.Adapters.SQL.Sandbox.mode(Chess.Repo, :manual)
|
Ecto.Adapters.SQL.Sandbox.mode(Chess.Repo, {:shared, self()})
|
||||||
|
|
||||||
Application.put_env(:wallaby, :base_url, ChessWeb.Endpoint.url)
|
Application.put_env(:wallaby, :base_url, ChessWeb.Endpoint.url)
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user