diff --git a/lib/chess/store/move.ex b/lib/chess/store/move.ex new file mode 100644 index 0000000..0a5bcfb --- /dev/null +++ b/lib/chess/store/move.ex @@ -0,0 +1,31 @@ +defmodule Chess.Store.Move do + @moduledoc false + + use Ecto.Schema + use Timex.Ecto.Timestamps + + import Ecto.Changeset + # import Ecto.Query + + alias Chess.Store.Game + + schema "moves" do + field :from, :map + field :to, :map + + field :piece, :map + field :piece_captured, :map + + belongs_to :game, Game + + timestamps() + end + + def changeset(struct, params \\ %{}) do + struct + |> cast(params, required_attrs()) + |> validate_required(required_attrs()) + end + + defp required_attrs, do: ~w[game_id from to piece]a +end diff --git a/priv/repo/migrations/20180504172433_create_moves.exs b/priv/repo/migrations/20180504172433_create_moves.exs new file mode 100644 index 0000000..1256e24 --- /dev/null +++ b/priv/repo/migrations/20180504172433_create_moves.exs @@ -0,0 +1,15 @@ +defmodule Chess.Repo.Migrations.CreateMoves do + use Ecto.Migration + + def change do + create table(:moves) do + add :game_id, references(:games) + add :from, :map + add :to, :map + add :piece, :map + add :piece_captured, :map + + timestamps() + end + end +end diff --git a/test/chess/store/move_test.exs b/test/chess/store/move_test.exs new file mode 100644 index 0000000..3265b1d --- /dev/null +++ b/test/chess/store/move_test.exs @@ -0,0 +1,81 @@ +defmodule Chess.MoveTest do + @moduledoc false + + use Chess.DataCase + + describe "move" do + alias Chess.Repo + alias Chess.Board + alias Chess.Store.Move + + import Chess.Factory + + test "move is valid with a game, a from, and a to" do + user = insert(:user, %{email: "link@hyrule.com"}) + opponent = insert(:user, %{email: "zelda@hyrule.com"}) + + game = insert(:game, %{ + board: Board.default, + user_id: user.id, + opponent_id: opponent.id, + }) + + changeset = Move.changeset(%Move{}, %{ + game_id: game.id, + from: %{file: 4, rank: 1}, + to: %{file: 4, rank: 3}, + piece: %{"type" => "pawn", "colour" => "white"}, + }) + + assert changeset.valid? + assert {:ok, _move} = Repo.insert(changeset) + end + + test "move is invalid without a game" do + changeset = Move.changeset(%Move{}, %{ + from: %{file: 4, rank: 1}, + to: %{file: 4, rank: 3}, + piece: %{"type" => "pawn", "colour" => "white"}, + }) + + refute changeset.valid? + end + + test "move is invalid without a from or to" do + user = insert(:user, %{email: "link@hyrule.com"}) + opponent = insert(:user, %{email: "zelda@hyrule.com"}) + + game = insert(:game, %{ + board: Board.default, + user_id: user.id, + opponent_id: opponent.id, + }) + + changeset = Move.changeset(%Move{}, %{ + game_id: game.id, + piece: %{"type" => "pawn", "colour" => "white"}, + }) + + refute changeset.valid? + end + + test "move is invalid without a piece" do + user = insert(:user, %{email: "link@hyrule.com"}) + opponent = insert(:user, %{email: "zelda@hyrule.com"}) + + game = insert(:game, %{ + board: Board.default, + user_id: user.id, + opponent_id: opponent.id, + }) + + changeset = Move.changeset(%Move{}, %{ + game_id: game.id, + from: %{file: 4, rank: 1}, + to: %{file: 4, rank: 3}, + }) + + refute changeset.valid? + end + end +end