mirror of
https://github.com/danbee/chess
synced 2025-03-04 08:39:06 +00:00
Fix up specs for opponent finder
This commit is contained in:
parent
ecf87aa632
commit
41c9e28457
@ -40,19 +40,20 @@ exports.config = {
|
||||
mode: "native",
|
||||
},
|
||||
babel: {
|
||||
plugins: [
|
||||
"transform-object-rest-spread",
|
||||
"transform-class-properties",
|
||||
],
|
||||
presets: [
|
||||
[
|
||||
"env", {
|
||||
"browsers": ["> 5% in US"],
|
||||
"useBuiltIns": true,
|
||||
"@babel/preset-env", {
|
||||
useBuiltIns: "entry",
|
||||
targets: {
|
||||
firefox: "60",
|
||||
chrome: "67",
|
||||
safari: "11",
|
||||
edge: "17",
|
||||
phantomjs: "2.1.1",
|
||||
},
|
||||
},
|
||||
],
|
||||
"es2015",
|
||||
"react",
|
||||
"@babel/preset-react",
|
||||
],
|
||||
ignore: [/vendor/],
|
||||
},
|
||||
|
||||
@ -49,6 +49,7 @@
|
||||
@import "components/game-info";
|
||||
@import "components/move-list";
|
||||
@import "components/game-state";
|
||||
@import "components/player-finder";
|
||||
|
||||
// 7. Utilities – utilities and helper classes with ability to override
|
||||
// anything which goes before in the triangle, eg. hide helper class
|
||||
|
||||
@ -14,15 +14,15 @@
|
||||
width: 15%;
|
||||
}
|
||||
|
||||
&.game-state--check,
|
||||
&.game-state--checkmate,
|
||||
&.game-state--stalemate {
|
||||
.game-state--check,
|
||||
.game-state--checkmate,
|
||||
.game-state--stalemate {
|
||||
display: block; // So PhantomJS will display it.
|
||||
display: flex;
|
||||
}
|
||||
|
||||
&.game-state--checkmate,
|
||||
&.game-state--stalemate {
|
||||
.game-state--checkmate,
|
||||
.game-state--stalemate {
|
||||
font-size: calc(var(--board-size) / 30);
|
||||
height: 7.5%;
|
||||
left: calc(50% - 15%);
|
||||
|
||||
22
assets/css/components/_player-finder.scss
Normal file
22
assets/css/components/_player-finder.scss
Normal file
@ -0,0 +1,22 @@
|
||||
.opponent-finder__result {
|
||||
border-bottom: 1px dotted $black;
|
||||
border-bottom-left-radius: $base-border-radius;
|
||||
border-bottom-right-radius: $base-border-radius;
|
||||
border-left: 1px dotted $black;
|
||||
border-right: 1px dotted $black;
|
||||
margin-top: -$small-spacing;
|
||||
padding: $small-spacing / 3;
|
||||
}
|
||||
|
||||
.opponent-finder__result-item {
|
||||
border-radius: $base-border-radius / 2;
|
||||
cursor: pointer;
|
||||
display: block;
|
||||
padding: $small-spacing / 3 $base-spacing / 2;
|
||||
|
||||
&:hover,
|
||||
&:focus {
|
||||
background: $black;
|
||||
color: $white;
|
||||
}
|
||||
}
|
||||
@ -51,6 +51,10 @@ textarea {
|
||||
border: $base-border;
|
||||
}
|
||||
}
|
||||
|
||||
&::placeholder {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
textarea {
|
||||
|
||||
@ -1,78 +1,34 @@
|
||||
"use strict";
|
||||
|
||||
import "babel-polyfill";
|
||||
import "@babel/polyfill";
|
||||
import "phoenix_html";
|
||||
|
||||
import React from "react";
|
||||
import ReactDOM from "react-dom";
|
||||
import { createStore } from "redux";
|
||||
|
||||
import Channel from "./services/channel";
|
||||
import Notifications from "./services/notifications";
|
||||
|
||||
import Game from "./components/game";
|
||||
import OpponentFinder from "./components/opponent-finder";
|
||||
import chessBoardReducer from "./reducers/chess-board";
|
||||
import { setGameId } from "./store/actions";
|
||||
import Listeners from "./store/listeners";
|
||||
|
||||
import ChessBoard from "./components/chess-board";
|
||||
import MoveList from "./components/move-list";
|
||||
import GameInfo from "./components/game-info";
|
||||
|
||||
const store = createStore(chessBoardReducer);
|
||||
const notifications = new Notifications();
|
||||
|
||||
class App extends React.Component {
|
||||
componentWillMount() {
|
||||
const { gameId, store } = this.props;
|
||||
const gameContainer = document.getElementById("game");
|
||||
|
||||
store.dispatch(setGameId(gameId));
|
||||
|
||||
this.listeners = new Listeners(store);
|
||||
this.listeners.setListeners(notifications);
|
||||
|
||||
this.channel = new Channel(store, gameId);
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
this.channel.leave();
|
||||
}
|
||||
|
||||
get moves() {
|
||||
const { store } = this.props;
|
||||
return store.getState().moves;
|
||||
}
|
||||
|
||||
get opponent() {
|
||||
const { store } = this.props;
|
||||
return store.getState().opponent;
|
||||
}
|
||||
|
||||
render() {
|
||||
const { store, gameId } = this.props;
|
||||
|
||||
return (
|
||||
<div className="game-grid">
|
||||
<ChessBoard
|
||||
gameId={gameId}
|
||||
store={store}
|
||||
channel={this.channel}
|
||||
/>
|
||||
|
||||
<GameInfo store={store} />
|
||||
|
||||
<MoveList store={store} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
const container = document.getElementById("app");
|
||||
|
||||
if (container != undefined) {
|
||||
const gameId = container.getAttribute("data-game-id");
|
||||
if (gameContainer != undefined) {
|
||||
const gameId = gameContainer.getAttribute("data-game-id");
|
||||
|
||||
ReactDOM.render(
|
||||
<App store={store} gameId={gameId} />,
|
||||
container
|
||||
<Game store={store} gameId={gameId} />,
|
||||
gameContainer
|
||||
);
|
||||
}
|
||||
|
||||
const opponentFinderContainer = document.getElementById("opponent-finder");
|
||||
|
||||
if (opponentFinderContainer != undefined) {
|
||||
ReactDOM.render(
|
||||
<OpponentFinder store={store} />,
|
||||
opponentFinderContainer
|
||||
);
|
||||
}
|
||||
|
||||
65
assets/js/components/game.js
Normal file
65
assets/js/components/game.js
Normal file
@ -0,0 +1,65 @@
|
||||
"use strict";
|
||||
|
||||
import "phoenix_html";
|
||||
|
||||
import React from "react";
|
||||
import ReactDOM from "react-dom";
|
||||
|
||||
import Channel from "../services/channel";
|
||||
import Notifications from "../services/notifications";
|
||||
|
||||
import { setGameId } from "../store/actions";
|
||||
import Listeners from "../store/listeners";
|
||||
|
||||
import ChessBoard from "./chess-board";
|
||||
import MoveList from "./move-list";
|
||||
import GameInfo from "./game-info";
|
||||
|
||||
const notifications = new Notifications();
|
||||
|
||||
class Game extends React.Component {
|
||||
componentWillMount() {
|
||||
const { gameId, store } = this.props;
|
||||
|
||||
store.dispatch(setGameId(gameId));
|
||||
|
||||
this.listeners = new Listeners(store);
|
||||
this.listeners.setListeners(notifications);
|
||||
|
||||
this.channel = new Channel(store, gameId);
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
this.channel.leave();
|
||||
}
|
||||
|
||||
get moves() {
|
||||
const { store } = this.props;
|
||||
return store.getState().moves;
|
||||
}
|
||||
|
||||
get opponent() {
|
||||
const { store } = this.props;
|
||||
return store.getState().opponent;
|
||||
}
|
||||
|
||||
render() {
|
||||
const { store, gameId } = this.props;
|
||||
|
||||
return (
|
||||
<div className="game-grid">
|
||||
<ChessBoard
|
||||
gameId={gameId}
|
||||
store={store}
|
||||
channel={this.channel}
|
||||
/>
|
||||
|
||||
<GameInfo store={store} />
|
||||
|
||||
<MoveList store={store} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default Game;
|
||||
122
assets/js/components/opponent-finder.js
Normal file
122
assets/js/components/opponent-finder.js
Normal file
@ -0,0 +1,122 @@
|
||||
"use strict";
|
||||
|
||||
import "phoenix_html";
|
||||
|
||||
import React from "react";
|
||||
import ReactDOM from "react-dom";
|
||||
import _ from "lodash";
|
||||
|
||||
import API from "../services/api";
|
||||
|
||||
class OpponentFinder extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
this.state = {
|
||||
queryString: "",
|
||||
foundOpponents: [],
|
||||
selectedOpponent: "",
|
||||
selectedOpponentId: "",
|
||||
};
|
||||
|
||||
this.debouncedSearch = _.debounce(this.search.bind(this), 250);
|
||||
}
|
||||
|
||||
search() {
|
||||
if (this.state.queryString != "") {
|
||||
API.findOpponent(this.state.queryString)
|
||||
.then((response) => {
|
||||
this.setState({ foundOpponents: response.data.opponents });
|
||||
});
|
||||
} else {
|
||||
this.setState({ foundOpponents: [] });
|
||||
}
|
||||
}
|
||||
|
||||
handleChange(event) {
|
||||
this.setState({ queryString: event.target.value });
|
||||
this.debouncedSearch();
|
||||
}
|
||||
|
||||
handleFocus(event) {
|
||||
if (this.state.selectedOpponent) {
|
||||
this.setState({ queryString: "" });
|
||||
}
|
||||
}
|
||||
|
||||
handleBlur(event) {
|
||||
if (this.state.selectedOpponent) {
|
||||
this.setState({ queryString: this.state.selectedOpponent.name });
|
||||
}
|
||||
}
|
||||
|
||||
selectOpponent(event) {
|
||||
event.preventDefault();
|
||||
|
||||
const selectedOpponentId = event.target.attributes["data-id"].value;
|
||||
const selectedOpponent = _.find(this.state.foundOpponents, (opponent) => {
|
||||
return opponent.id == selectedOpponentId;
|
||||
});
|
||||
|
||||
this.setState({
|
||||
selectedOpponentId,
|
||||
selectedOpponent,
|
||||
foundOpponents: [],
|
||||
queryString: selectedOpponent.name,
|
||||
});
|
||||
}
|
||||
|
||||
renderOpponents() {
|
||||
return _.map(this.state.foundOpponents, (opponent) => {
|
||||
return (
|
||||
<li key={opponent.id}>
|
||||
<a
|
||||
className="opponent-finder__result-item"
|
||||
data-id={opponent.id}
|
||||
href="#"
|
||||
onClick={this.selectOpponent.bind(this)}
|
||||
>{opponent.name}</a>
|
||||
</li>
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
renderOpponentsResult() {
|
||||
if (this.state.foundOpponents.length) {
|
||||
return (
|
||||
<ul className="opponent-finder__result">
|
||||
{this.renderOpponents()}
|
||||
</ul>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
const { store, gameId } = this.props;
|
||||
|
||||
return (
|
||||
<div className="form-field opponent-finder">
|
||||
<label htmlFor="query-string">Find opponent</label>
|
||||
<input
|
||||
id="query-string"
|
||||
name="q"
|
||||
value={this.state.queryString}
|
||||
onChange={this.handleChange.bind(this)}
|
||||
onFocus={this.handleFocus.bind(this)}
|
||||
onBlur={this.handleBlur.bind(this)}
|
||||
type="text"
|
||||
autoComplete="off"
|
||||
/>
|
||||
<input
|
||||
name="game[opponent_id]"
|
||||
type="hidden"
|
||||
value={this.state.selectedOpponentId}
|
||||
/>
|
||||
|
||||
{this.renderOpponentsResult()}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default OpponentFinder;
|
||||
@ -1,12 +1,8 @@
|
||||
import axios from "axios";
|
||||
|
||||
const API = {
|
||||
getGame: (gameId) => {
|
||||
return axios.get(`/api/games/${gameId}`);
|
||||
},
|
||||
|
||||
updateGame: (gameId, move) => {
|
||||
return axios.patch(`/api/games/${gameId}`, { move });
|
||||
findOpponent: (queryString) => {
|
||||
return axios.get("/api/opponents", { params: { q: queryString } });
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
@ -51,6 +51,8 @@ let socket = new Socket("/socket", { params: { token: window.userToken } });
|
||||
// Finally, pass the token on connect as below. Or remove it
|
||||
// from connect if you don't care about authentication.
|
||||
|
||||
socket.connect();
|
||||
if (window.userToken) {
|
||||
socket.connect();
|
||||
}
|
||||
|
||||
export default socket;
|
||||
|
||||
@ -7,6 +7,7 @@
|
||||
"watch": "brunch watch --stdin"
|
||||
},
|
||||
"dependencies": {
|
||||
"@babel/polyfill": "^7.0.0",
|
||||
"axios": "^0.18.0",
|
||||
"classnames": "^2.2.5",
|
||||
"gettext.js": "^0.5.3",
|
||||
@ -21,11 +22,9 @@
|
||||
"redux-watch": "^1.1.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"babel-brunch": "^6.1.1",
|
||||
"babel-plugin-transform-class-properties": "^6.24.1",
|
||||
"babel-plugin-transform-object-rest-spread": "^6.23.0",
|
||||
"babel-preset-env": "^1.4.0",
|
||||
"babel-preset-react": "^6.24.1",
|
||||
"@babel/preset-env": "^7.1.0",
|
||||
"@babel/preset-react": "^7.0.0",
|
||||
"babel-brunch": "^7.0.0",
|
||||
"brunch": "~2.10.0",
|
||||
"clean-css-brunch": "~2.10.0",
|
||||
"core-js": "~2.5.3",
|
||||
|
||||
3287
assets/yarn.lock
3287
assets/yarn.lock
File diff suppressed because it is too large
Load Diff
@ -3,6 +3,7 @@ use Mix.Config
|
||||
# We don't run a server during test. If one is required,
|
||||
# you can enable the server option below.
|
||||
config :chess, ChessWeb.Endpoint,
|
||||
check_origin: false,
|
||||
http: [port: 4001],
|
||||
server: true
|
||||
|
||||
|
||||
@ -52,6 +52,11 @@ defmodule Chess.Store.User do
|
||||
|> unique_constraint(:email)
|
||||
end
|
||||
|
||||
def find_by_name(name) do
|
||||
from user in __MODULE__,
|
||||
where: user.name == ^name
|
||||
end
|
||||
|
||||
def opponents(user) do
|
||||
from user in __MODULE__,
|
||||
where: user.id != ^user.id
|
||||
|
||||
17
lib/chess_web/controllers/api/opponent_controller.ex
Normal file
17
lib/chess_web/controllers/api/opponent_controller.ex
Normal file
@ -0,0 +1,17 @@
|
||||
defmodule ChessWeb.Api.OpponentsController do
|
||||
use ChessWeb, :controller
|
||||
|
||||
import Chess.Auth, only: [current_user: 1]
|
||||
alias Chess.Repo
|
||||
alias Chess.Repo.Queries
|
||||
|
||||
def index(conn, %{"q" => query_string}) do
|
||||
opponents =
|
||||
conn
|
||||
|> current_user()
|
||||
|> Queries.opponents(query_string)
|
||||
|> Repo.all
|
||||
|
||||
render conn, "index.json", %{opponents: opponents}
|
||||
end
|
||||
end
|
||||
@ -26,14 +26,8 @@ defmodule ChessWeb.GameController do
|
||||
def new(conn, _params) do
|
||||
changeset = Game.changeset(%Game{})
|
||||
|
||||
opponents =
|
||||
conn
|
||||
|> current_user()
|
||||
|> User.opponents()
|
||||
|> Repo.all
|
||||
|
||||
conn
|
||||
|> render("new.html", changeset: changeset, opponents: opponents)
|
||||
|> render("new.html", changeset: changeset)
|
||||
end
|
||||
|
||||
def create(conn, %{"game" => game}) do
|
||||
|
||||
@ -50,7 +50,7 @@ defmodule ChessWeb.Router do
|
||||
scope "/api", as: :api do
|
||||
pipe_through [:api, :auth, :ensure_auth]
|
||||
|
||||
resources "/games", ChessWeb.Api.GameController, only: [:show, :update]
|
||||
resources "/opponents", ChessWeb.Api.OpponentsController, only: [:index]
|
||||
end
|
||||
|
||||
if Mix.env == :dev do
|
||||
|
||||
@ -4,11 +4,7 @@
|
||||
<%= form_for @changeset, game_path(@conn, :create), [class: "create-game"],
|
||||
fn form -> %>
|
||||
<div class="form-group">
|
||||
<%= label form, :opponent_id %>
|
||||
<%= select form,
|
||||
:opponent_id,
|
||||
@opponents,
|
||||
prompt: gettext("Choose an opponent") %>
|
||||
<div id="opponent-finder"></div>
|
||||
<%= error_tag form, :opponent_id %>
|
||||
</div>
|
||||
|
||||
|
||||
@ -1,2 +1,2 @@
|
||||
<div id="app" data-game-id="<%= @game.id %>">
|
||||
<div id="game" data-game-id="<%= @game.id %>">
|
||||
</div>
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
<div class="form">
|
||||
<h2><%= gettext "Register" %></h2>
|
||||
|
||||
<%= form_for @changeset, registration_path(@conn, :create), [class: "create-registration"], fn f -> %>
|
||||
<%= form_for @changeset, registration_path(@conn, :create), [class: "create-registration", novalidate: "novalidate"], fn f -> %>
|
||||
<%= if @changeset.action do %>
|
||||
<div class="alert alert-danger">
|
||||
<p>
|
||||
|
||||
18
lib/chess_web/views/api/opponents_view.ex
Normal file
18
lib/chess_web/views/api/opponents_view.ex
Normal file
@ -0,0 +1,18 @@
|
||||
defmodule ChessWeb.Api.OpponentsView do
|
||||
use ChessWeb, :view
|
||||
|
||||
def render("index.json", %{opponents: opponents}) do
|
||||
%{
|
||||
opponents: Enum.map(opponents, fn opponent ->
|
||||
opponent_attrs(opponent)
|
||||
end)
|
||||
}
|
||||
end
|
||||
|
||||
def opponent_attrs(opponent) do
|
||||
%{
|
||||
id: opponent.id,
|
||||
name: opponent.name,
|
||||
}
|
||||
end
|
||||
end
|
||||
3
mix.exs
3
mix.exs
@ -34,7 +34,7 @@ defmodule Chess.Mixfile do
|
||||
# Type `mix help deps` for examples and options.
|
||||
defp deps do
|
||||
[
|
||||
{:argon2_elixir, "~> 1.2"},
|
||||
{:argon2_elixir, "~> 1.3"},
|
||||
{:bamboo, "~> 1.0"},
|
||||
{:comeonin, "~> 4.0"},
|
||||
{:cowboy, "~> 1.0"},
|
||||
@ -49,6 +49,7 @@ defmodule Chess.Mixfile do
|
||||
{:phoenix_live_reload, "~> 1.0", only: :dev},
|
||||
{:phoenix_pubsub, "~> 1.0"},
|
||||
{:postgrex, ">= 0.0.0"},
|
||||
{:secure_random, "~> 0.5"},
|
||||
{:timex_ecto, "~> 3.2"},
|
||||
{:wallaby, "~> 0.20.0", [runtime: false, only: :test]},
|
||||
]
|
||||
|
||||
21
mix.lock
21
mix.lock
@ -4,7 +4,7 @@
|
||||
"bamboo": {:hex, :bamboo, "1.1.0", "ecbdc851d0127d369957e5ca7bcfb4c7fe7dbfaf4fa0b2e5cc2493dd8a9a600e", [:mix], [{:hackney, ">= 1.13.0", [hex: :hackney, repo: "hexpm", optional: false]}, {:plug, "~> 1.0", [hex: :plug, repo: "hexpm", optional: false]}, {:poison, ">= 1.5.0", [hex: :poison, repo: "hexpm", optional: false]}], "hexpm"},
|
||||
"base64url": {:hex, :base64url, "0.0.1", "36a90125f5948e3afd7be97662a1504b934dd5dac78451ca6e9abf85a10286be", [:rebar], [], "hexpm"},
|
||||
"bunt": {:hex, :bunt, "0.2.0", "951c6e801e8b1d2cbe58ebbd3e616a869061ddadcc4863d0a2182541acae9a38", [:mix], [], "hexpm"},
|
||||
"certifi": {:hex, :certifi, "2.3.1", "d0f424232390bf47d82da8478022301c561cf6445b5b5fb6a84d49a9e76d2639", [:rebar3], [{:parse_trans, "3.2.0", [hex: :parse_trans, repo: "hexpm", optional: false]}], "hexpm"},
|
||||
"certifi": {:hex, :certifi, "2.4.2", "75424ff0f3baaccfd34b1214184b6ef616d89e420b258bb0a5ea7d7bc628f7f0", [:rebar3], [{:parse_trans, "~>3.3", [hex: :parse_trans, repo: "hexpm", optional: false]}], "hexpm"},
|
||||
"combine": {:hex, :combine, "0.10.0", "eff8224eeb56498a2af13011d142c5e7997a80c8f5b97c499f84c841032e429f", [:mix], [], "hexpm"},
|
||||
"comeonin": {:hex, :comeonin, "4.1.1", "c7304fc29b45b897b34142a91122bc72757bc0c295e9e824999d5179ffc08416", [:mix], [{:argon2_elixir, "~> 1.2", [hex: :argon2_elixir, repo: "hexpm", optional: true]}, {:bcrypt_elixir, "~> 0.12.1 or ~> 1.0", [hex: :bcrypt_elixir, repo: "hexpm", optional: true]}, {:pbkdf2_elixir, "~> 0.12", [hex: :pbkdf2_elixir, repo: "hexpm", optional: true]}], "hexpm"},
|
||||
"connection": {:hex, :connection, "1.0.4", "a1cae72211f0eef17705aaededacac3eb30e6625b04a6117c1b2db6ace7d5976", [:mix], [], "hexpm"},
|
||||
@ -14,35 +14,36 @@
|
||||
"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.5.0", "b0433a36d0e2430e3d50291b1c65f53c37d56f83665b43d79963684865beab68", [:mix], [], "hexpm"},
|
||||
"distillery": {:hex, :distillery, "2.0.10", "e9f1f1d3f4a89996a3e1a555872feed8a3a73e3d10b51886941382d29ca58f99", [:mix], [{:artificery, "~> 0.2", [hex: :artificery, repo: "hexpm", optional: false]}], "hexpm"},
|
||||
"ecto": {:hex, :ecto, "2.2.10", "e7366dc82f48f8dd78fcbf3ab50985ceeb11cb3dc93435147c6e13f2cda0992e", [: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"},
|
||||
"ecto": {:hex, :ecto, "2.2.11", "4bb8f11718b72ba97a2696f65d247a379e739a0ecabf6a13ad1face79844791c", [: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"},
|
||||
"elixir_make": {:hex, :elixir_make, "0.4.2", "332c649d08c18bc1ecc73b1befc68c647136de4f340b548844efc796405743bf", [:mix], [], "hexpm"},
|
||||
"file_system": {:hex, :file_system, "0.2.6", "fd4dc3af89b9ab1dc8ccbcc214a0e60c41f34be251d9307920748a14bf41f1d3", [:mix], [], "hexpm"},
|
||||
"formulator": {:hex, :formulator, "0.1.7", "feb3e4131c729535b3ad91ead282866870c1e76f343d3bb7c6937f99a5243961", [:mix], [{:gettext, ">= 0.11.0", [hex: :gettext, repo: "hexpm", optional: false]}, {:phoenix_html, "~> 2.4", [hex: :phoenix_html, repo: "hexpm", optional: false]}], "hexpm"},
|
||||
"gettext": {:hex, :gettext, "0.16.0", "4a7e90408cef5f1bf57c5a39e2db8c372a906031cc9b1466e963101cb927dafc", [:mix], [], "hexpm"},
|
||||
"guardian": {:hex, :guardian, "1.1.1", "be14c4007eaf05268251ae114030cb7237ed9a9631c260022f020164ff4ed733", [:mix], [{:jose, "~> 1.8", [hex: :jose, repo: "hexpm", optional: false]}, {:phoenix, "~> 1.0 or ~> 1.2 or ~> 1.3", [hex: :phoenix, repo: "hexpm", optional: true]}, {:plug, "~> 1.3.3 or ~> 1.4", [hex: :plug, repo: "hexpm", optional: true]}, {:poison, "~> 2.2 or ~> 3.0", [hex: :poison, repo: "hexpm", optional: false]}], "hexpm"},
|
||||
"hackney": {:hex, :hackney, "1.13.0", "24edc8cd2b28e1c652593833862435c80661834f6c9344e84b6a2255e7aeef03", [:rebar3], [{:certifi, "2.3.1", [hex: :certifi, repo: "hexpm", optional: false]}, {:idna, "5.1.2", [hex: :idna, repo: "hexpm", optional: false]}, {:metrics, "1.0.1", [hex: :metrics, repo: "hexpm", optional: false]}, {:mimerl, "1.0.2", [hex: :mimerl, repo: "hexpm", optional: false]}, {:ssl_verify_fun, "1.1.1", [hex: :ssl_verify_fun, repo: "hexpm", optional: false]}], "hexpm"},
|
||||
"hackney": {:hex, :hackney, "1.14.3", "b5f6f5dcc4f1fba340762738759209e21914516df6be440d85772542d4a5e412", [:rebar3], [{:certifi, "2.4.2", [hex: :certifi, repo: "hexpm", optional: false]}, {:idna, "6.0.0", [hex: :idna, repo: "hexpm", optional: false]}, {:metrics, "1.0.1", [hex: :metrics, repo: "hexpm", optional: false]}, {:mimerl, "1.0.2", [hex: :mimerl, repo: "hexpm", optional: false]}, {:ssl_verify_fun, "1.1.4", [hex: :ssl_verify_fun, repo: "hexpm", optional: false]}], "hexpm"},
|
||||
"httpoison": {:hex, :httpoison, "0.13.0", "bfaf44d9f133a6599886720f3937a7699466d23bb0cd7a88b6ba011f53c6f562", [:mix], [{:hackney, "~> 1.8", [hex: :hackney, repo: "hexpm", optional: false]}], "hexpm"},
|
||||
"idna": {:hex, :idna, "5.1.2", "e21cb58a09f0228a9e0b95eaa1217f1bcfc31a1aaa6e1fdf2f53a33f7dbd9494", [:rebar3], [{:unicode_util_compat, "0.3.1", [hex: :unicode_util_compat, repo: "hexpm", optional: false]}], "hexpm"},
|
||||
"idna": {:hex, :idna, "6.0.0", "689c46cbcdf3524c44d5f3dde8001f364cd7608a99556d8fbd8239a5798d4c10", [:rebar3], [{:unicode_util_compat, "0.4.1", [hex: :unicode_util_compat, repo: "hexpm", optional: false]}], "hexpm"},
|
||||
"jason": {:hex, :jason, "1.1.1", "d3ccb840dfb06f2f90a6d335b536dd074db748b3e7f5b11ab61d239506585eb2", [:mix], [{:decimal, "~> 1.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm"},
|
||||
"jose": {:hex, :jose, "1.8.4", "7946d1e5c03a76ac9ef42a6e6a20001d35987afd68c2107bcd8f01a84e75aa73", [:mix, :rebar3], [{:base64url, "~> 0.0.1", [hex: :base64url, repo: "hexpm", optional: false]}], "hexpm"},
|
||||
"metrics": {:hex, :metrics, "1.0.1", "25f094dea2cda98213cecc3aeff09e940299d950904393b2a29d191c346a8486", [:rebar3], [], "hexpm"},
|
||||
"mime": {:hex, :mime, "1.3.0", "5e8d45a39e95c650900d03f897fbf99ae04f60ab1daa4a34c7a20a5151b7a5fe", [:mix], [], "hexpm"},
|
||||
"mimerl": {:hex, :mimerl, "1.0.2", "993f9b0e084083405ed8252b99460c4f0563e41729ab42d9074fd5e52439be88", [:rebar3], [], "hexpm"},
|
||||
"parse_trans": {:hex, :parse_trans, "3.2.0", "2adfa4daf80c14dc36f522cf190eb5c4ee3e28008fc6394397c16f62a26258c2", [:rebar3], [], "hexpm"},
|
||||
"parse_trans": {:hex, :parse_trans, "3.3.0", "09765507a3c7590a784615cfd421d101aec25098d50b89d7aa1d66646bc571c1", [:rebar3], [], "hexpm"},
|
||||
"phoenix": {:hex, :phoenix, "1.3.4", "aaa1b55e5523083a877bcbe9886d9ee180bf2c8754905323493c2ac325903dc5", [:mix], [{:cowboy, "~> 1.0", [hex: :cowboy, repo: "hexpm", optional: true]}, {:phoenix_pubsub, "~> 1.0", [hex: :phoenix_pubsub, repo: "hexpm", optional: false]}, {:plug, "~> 1.3.3 or ~> 1.4", [hex: :plug, repo: "hexpm", optional: false]}, {:poison, "~> 2.2 or ~> 3.0", [hex: :poison, repo: "hexpm", optional: false]}], "hexpm"},
|
||||
"phoenix_ecto": {:hex, :phoenix_ecto, "3.4.0", "91cd39427006fe4b5588d69f0941b9c3d3d8f5e6477c563a08379de7de2b0c58", [:mix], [{:ecto, "~> 2.1", [hex: :ecto, repo: "hexpm", optional: false]}, {:phoenix_html, "~> 2.9", [hex: :phoenix_html, repo: "hexpm", optional: true]}, {:plug, "~> 1.0", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm"},
|
||||
"phoenix_html": {:hex, :phoenix_html, "2.12.0", "1fb3c2e48b4b66d75564d8d63df6d53655469216d6b553e7e14ced2b46f97622", [:mix], [{:plug, "~> 1.5", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm"},
|
||||
"phoenix_live_reload": {:hex, :phoenix_live_reload, "1.1.5", "8d4c9b1ef9ca82deee6deb5a038d6d8d7b34b9bb909d99784a49332e0d15b3dc", [:mix], [{:file_system, "~> 0.2.1 or ~> 0.3", [hex: :file_system, repo: "hexpm", optional: false]}, {:phoenix, "~> 1.0 or ~> 1.2 or ~> 1.3", [hex: :phoenix, repo: "hexpm", optional: false]}], "hexpm"},
|
||||
"phoenix_live_reload": {:hex, :phoenix_live_reload, "1.1.6", "7280f4dd88d38ee07ca70a2974ca12b9bfdbb9fa8137e4692889cf097c1bb232", [:mix], [{:file_system, "~> 0.2.1 or ~> 0.3", [hex: :file_system, repo: "hexpm", optional: false]}, {:phoenix, "~> 1.0 or ~> 1.2 or ~> 1.3", [hex: :phoenix, repo: "hexpm", optional: false]}], "hexpm"},
|
||||
"phoenix_pubsub": {:hex, :phoenix_pubsub, "1.1.0", "d55e25ff1ff8ea2f9964638366dfd6e361c52dedfd50019353598d11d4441d14", [:mix], [], "hexpm"},
|
||||
"plug": {:hex, :plug, "1.6.2", "e06a7bd2bb6de5145da0dd950070110dce88045351224bd98e84edfdaaf5ffee", [:mix], [{:cowboy, "~> 1.0.1 or ~> 1.1 or ~> 2.4", [hex: :cowboy, repo: "hexpm", optional: true]}, {:mime, "~> 1.0", [hex: :mime, repo: "hexpm", optional: false]}], "hexpm"},
|
||||
"plug": {:hex, :plug, "1.6.4", "35618dd2cc009b69b000f785452f6b370f76d099ece199733fea27bc473f809d", [:mix], [{:cowboy, "~> 1.0.1 or ~> 1.1 or ~> 2.4", [hex: :cowboy, repo: "hexpm", optional: true]}, {:mime, "~> 1.0", [hex: :mime, repo: "hexpm", optional: false]}], "hexpm"},
|
||||
"poison": {:hex, :poison, "3.1.0", "d9eb636610e096f86f25d9a46f35a9facac35609a7591b3be3326e99a0484665", [:mix], [], "hexpm"},
|
||||
"poolboy": {:hex, :poolboy, "1.5.1", "6b46163901cfd0a1b43d692657ed9d7e599853b3b21b95ae5ae0a777cf9b6ca8", [:rebar], [], "hexpm"},
|
||||
"postgrex": {:hex, :postgrex, "0.13.5", "3d931aba29363e1443da167a4b12f06dcd171103c424de15e5f3fc2ba3e6d9c5", [:mix], [{:connection, "~> 1.0", [hex: :connection, repo: "hexpm", optional: false]}, {:db_connection, "~> 1.1", [hex: :db_connection, repo: "hexpm", optional: false]}, {:decimal, "~> 1.0", [hex: :decimal, repo: "hexpm", optional: false]}], "hexpm"},
|
||||
"ranch": {:hex, :ranch, "1.3.2", "e4965a144dc9fbe70e5c077c65e73c57165416a901bd02ea899cfd95aa890986", [:rebar3], [], "hexpm"},
|
||||
"ssl_verify_fun": {:hex, :ssl_verify_fun, "1.1.1", "28a4d65b7f59893bc2c7de786dec1e1555bd742d336043fe644ae956c3497fbe", [:make, :rebar], [], "hexpm"},
|
||||
"timex": {:hex, :timex, "3.3.0", "e0695aa0ddb37d460d93a2db34d332c2c95a40c27edf22fbfea22eb8910a9c8d", [:mix], [{:combine, "~> 0.10", [hex: :combine, repo: "hexpm", optional: false]}, {:gettext, "~> 0.10", [hex: :gettext, repo: "hexpm", optional: false]}, {:tzdata, "~> 0.1.8 or ~> 0.5", [hex: :tzdata, repo: "hexpm", optional: false]}], "hexpm"},
|
||||
"secure_random": {:hex, :secure_random, "0.5.1", "c5532b37c89d175c328f5196a0c2a5680b15ebce3e654da37129a9fe40ebf51b", [:mix], [], "hexpm"},
|
||||
"ssl_verify_fun": {:hex, :ssl_verify_fun, "1.1.4", "f0eafff810d2041e93f915ef59899c923f4568f4585904d010387ed74988e77b", [:make, :mix, :rebar3], [], "hexpm"},
|
||||
"timex": {:hex, :timex, "3.4.1", "e63fc1a37453035e534c3febfe9b6b9e18583ec7b37fd9c390efdef97397d70b", [:mix], [{:combine, "~> 0.10", [hex: :combine, repo: "hexpm", optional: false]}, {:gettext, "~> 0.10", [hex: :gettext, repo: "hexpm", optional: false]}, {:tzdata, "~> 0.1.8 or ~> 0.5", [hex: :tzdata, repo: "hexpm", optional: false]}], "hexpm"},
|
||||
"timex_ecto": {:hex, :timex_ecto, "3.3.0", "d5bdef09928e7a60f10a0baa47ce653f29b43d6fee87b30b236b216d0e36b98d", [:mix], [{:ecto, "~> 2.2", [hex: :ecto, repo: "hexpm", optional: false]}, {:timex, "~> 3.1", [hex: :timex, repo: "hexpm", optional: false]}], "hexpm"},
|
||||
"tzdata": {:hex, :tzdata, "0.5.19", "7962a3997bf06303b7d1772988ede22260f3dae1bf897408ebdac2b4435f4e6a", [:mix], [{:hackney, "~> 1.0", [hex: :hackney, repo: "hexpm", optional: false]}], "hexpm"},
|
||||
"unicode_util_compat": {:hex, :unicode_util_compat, "0.3.1", "a1f612a7b512638634a603c8f401892afbf99b8ce93a45041f8aaca99cadb85e", [:rebar3], [], "hexpm"},
|
||||
"unicode_util_compat": {:hex, :unicode_util_compat, "0.4.1", "d869e4c68901dd9531385bb0c8c40444ebf624e60b6962d95952775cac5e90cd", [:rebar3], [], "hexpm"},
|
||||
"wallaby": {:hex, :wallaby, "0.20.0", "cc6663555ff7b05afbebb2a8b461d18a5b321658b9017f7bc77d494b7063266a", [:mix], [{:httpoison, "~> 0.12", [hex: :httpoison, repo: "hexpm", optional: false]}, {:poison, ">= 1.4.0", [hex: :poison, repo: "hexpm", optional: false]}, {:poolboy, "~> 1.5", [hex: :poolboy, repo: "hexpm", optional: false]}], "hexpm"},
|
||||
}
|
||||
|
||||
@ -11,8 +11,8 @@ defmodule Chess.Store.GameTest do
|
||||
import Chess.Factory
|
||||
|
||||
test "game is valid with a board and user" do
|
||||
user = insert(:user, %{email: "link@hyrule.com"})
|
||||
opponent = insert(:user, %{email: "zelda@hyrule.com"})
|
||||
user = insert(:user)
|
||||
opponent = insert(:opponent)
|
||||
|
||||
attrs = %{
|
||||
board: %{},
|
||||
@ -40,8 +40,8 @@ defmodule Chess.Store.GameTest do
|
||||
end
|
||||
|
||||
test "game is invalid without a board" do
|
||||
user = insert(:user, %{email: "link@hyrule.com"})
|
||||
opponent = insert(:user, %{email: "zelda@hyrule.com"})
|
||||
user = insert(:user)
|
||||
opponent = insert(:opponent)
|
||||
|
||||
attrs = %{board: nil, user_id: user.id, opponent_id: opponent.id}
|
||||
changeset = Game.changeset(%Game{}, attrs)
|
||||
@ -51,7 +51,7 @@ defmodule Chess.Store.GameTest do
|
||||
end
|
||||
|
||||
test "game is invalid without a user" do
|
||||
opponent = insert(:user, %{email: "zelda@hyrule.com"})
|
||||
opponent = insert(:user)
|
||||
|
||||
attrs = %{board: %{}, opponent_id: opponent.id}
|
||||
changeset = Game.changeset(%Game{}, attrs)
|
||||
@ -61,7 +61,7 @@ defmodule Chess.Store.GameTest do
|
||||
end
|
||||
|
||||
test "game is invalid without an opponent" do
|
||||
user = insert(:user, %{email: "link@hyrule.com"})
|
||||
user = insert(:user)
|
||||
|
||||
attrs = %{board: %{}, user_id: user.id}
|
||||
changeset = Game.changeset(%Game{}, attrs)
|
||||
@ -78,8 +78,8 @@ defmodule Chess.Store.GameTest do
|
||||
end
|
||||
|
||||
test "moving a piece changes the turn" do
|
||||
user = insert(:user, %{email: "link@hyrule.com"})
|
||||
opponent = insert(:user, %{email: "zelda@hyrule.com"})
|
||||
user = insert(:user)
|
||||
opponent = insert(:opponent)
|
||||
|
||||
game = insert(:game, %{
|
||||
board: Board.default,
|
||||
|
||||
@ -11,8 +11,8 @@ defmodule Chess.Store.MoveTest do
|
||||
|
||||
describe "move" do
|
||||
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"})
|
||||
user = insert(:user)
|
||||
opponent = insert(:opponent)
|
||||
|
||||
game = insert(:game, %{
|
||||
board: Board.default,
|
||||
@ -42,8 +42,8 @@ defmodule Chess.Store.MoveTest do
|
||||
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"})
|
||||
user = insert(:user)
|
||||
opponent = insert(:opponent)
|
||||
|
||||
game = insert(:game, %{
|
||||
board: Board.default,
|
||||
@ -60,8 +60,8 @@ defmodule Chess.Store.MoveTest do
|
||||
end
|
||||
|
||||
test "move is invalid without a piece" do
|
||||
user = insert(:user, %{email: "link@hyrule.com"})
|
||||
opponent = insert(:user, %{email: "zelda@hyrule.com"})
|
||||
user = insert(:user)
|
||||
opponent = insert(:opponent)
|
||||
|
||||
game = insert(:game, %{
|
||||
board: Board.default,
|
||||
|
||||
@ -19,7 +19,7 @@ defmodule ChessWeb.GameControllerTest do
|
||||
end
|
||||
|
||||
test "creates game and redirects when data is valid", %{conn: conn} do
|
||||
opponent = insert(:user, %{email: "daruk@goron.city"})
|
||||
opponent = insert(:user, %{email: "daruk@goron.city", name: "Daruk"})
|
||||
attrs = %{"opponent_id" => opponent.id}
|
||||
|
||||
user = insert(:user)
|
||||
@ -35,7 +35,7 @@ defmodule ChessWeb.GameControllerTest do
|
||||
end
|
||||
|
||||
test "sends an email when game is created", %{conn: conn} do
|
||||
opponent = insert(:user, %{name: "Daruk", email: "daruk@goron.city"})
|
||||
opponent = insert(:user, %{email: "daruk@goron.city", name: "Daruk"})
|
||||
attrs = %{"opponent_id" => opponent.id}
|
||||
|
||||
user = insert(:user)
|
||||
@ -52,7 +52,7 @@ defmodule ChessWeb.GameControllerTest do
|
||||
|
||||
test "shows chosen game", %{conn: conn} do
|
||||
user = insert(:user)
|
||||
opponent = insert(:user, %{email: "revali@rito.village"})
|
||||
opponent = insert(:user, %{email: "revali@rito.village", name: "Revali"})
|
||||
game = insert(:game, %{user_id: user.id, opponent_id: opponent.id})
|
||||
|
||||
conn =
|
||||
@ -60,15 +60,15 @@ defmodule ChessWeb.GameControllerTest do
|
||||
|> login(user)
|
||||
|> get(game_path(conn, :show, game))
|
||||
|
||||
assert html_response(conn, 200) =~ "<div id=\"app\" data-game-id=\"#{game.id}\">"
|
||||
assert html_response(conn, 200) =~ "<div id=\"game\" data-game-id=\"#{game.id}\">"
|
||||
end
|
||||
|
||||
test "does not show a game if the user is not a player", %{conn: conn} do
|
||||
user = insert(:user)
|
||||
opponent = insert(:user, %{email: "revali@rito.village"})
|
||||
opponent = insert(:user, %{email: "revali@rito.village", name: "Revali"})
|
||||
game = insert(:game, %{user_id: user.id, opponent_id: opponent.id})
|
||||
|
||||
other_user = insert(:user, %{email: "mipha@zora.domain"})
|
||||
other_user = insert(:user, %{email: "mipha@zora.domain", name: "Mipha"})
|
||||
|
||||
conn =
|
||||
conn
|
||||
|
||||
@ -24,7 +24,7 @@ defmodule Chess.Features.GamesTest do
|
||||
|> create_user_and_login()
|
||||
|> visit("/games")
|
||||
|> click(link("New game"))
|
||||
|> select("game[opponent_id]", option: "Zelda")
|
||||
|> select_opponent("Zelda")
|
||||
|> click(button("Create game"))
|
||||
|
||||
session
|
||||
@ -62,7 +62,7 @@ defmodule Chess.Features.GamesTest do
|
||||
|> create_user_and_login()
|
||||
|> visit("/games")
|
||||
|> click(link("New game"))
|
||||
|> select("game[opponent_id]", option: "Urbosa")
|
||||
|> select_opponent("Urbosa")
|
||||
|> click(button("Create game"))
|
||||
|> click(link("64squares"))
|
||||
|
||||
|
||||
@ -20,7 +20,7 @@ defmodule Chess.Features.MovesTest do
|
||||
|> create_user_and_login()
|
||||
|> visit("/games")
|
||||
|> click(link("New game"))
|
||||
|> select("game[opponent_id]", option: "Zelda")
|
||||
|> select_opponent("Zelda")
|
||||
|> click(button("Create game"))
|
||||
|
||||
|> click(css("#f4-r1"))
|
||||
@ -48,7 +48,7 @@ defmodule Chess.Features.MovesTest do
|
||||
|> login("link@hyrule.com", "ilovezelda")
|
||||
|> visit("/games")
|
||||
|> click(link("New game"))
|
||||
|> select("game[opponent_id]", option: "Zelda")
|
||||
|> select_opponent("Zelda")
|
||||
|> click(button("Create game"))
|
||||
|
||||
assert_email_delivered_with(to: [{opponent.name, opponent.email}])
|
||||
@ -74,7 +74,7 @@ defmodule Chess.Features.MovesTest do
|
||||
|> create_user_and_login()
|
||||
|> visit("/games")
|
||||
|> click(link("New game"))
|
||||
|> select("game[opponent_id]", option: "Zelda")
|
||||
|> select_opponent("Zelda")
|
||||
|> click(button("Create game"))
|
||||
|
||||
session
|
||||
@ -98,7 +98,7 @@ defmodule Chess.Features.MovesTest do
|
||||
|> login("link@hyrule.com", "ilovezelda")
|
||||
|> visit("/games")
|
||||
|> click(link("New game"))
|
||||
|> select("game[opponent_id]", option: "Zelda")
|
||||
|> select_opponent("Zelda")
|
||||
|> click(button("Create game"))
|
||||
|
||||
{:ok, session2} = Wallaby.start_session
|
||||
@ -127,7 +127,7 @@ defmodule Chess.Features.MovesTest do
|
||||
|> login("link@hyrule.com", "ilovezelda")
|
||||
|> visit("/games")
|
||||
|> click(link("New game"))
|
||||
|> select("game[opponent_id]", option: "Zelda")
|
||||
|> select_opponent("Zelda")
|
||||
|> click(button("Create game"))
|
||||
|
||||
{:ok, session2} = Wallaby.start_session
|
||||
|
||||
@ -12,4 +12,10 @@ defmodule Chess.FormHelpers do
|
||||
|
||||
session
|
||||
end
|
||||
|
||||
def select_opponent(session, name) do
|
||||
session
|
||||
|> fill_in(text_field("Find opponent"), with: name)
|
||||
|> click(link(name))
|
||||
end
|
||||
end
|
||||
|
||||
@ -7,22 +7,30 @@ defmodule Chess.Factory do
|
||||
|
||||
def insert(_resource, _params \\ %{})
|
||||
|
||||
def insert(:user, params) do
|
||||
%User{
|
||||
name: "Zelda",
|
||||
email: "zelda@hyrule.com",
|
||||
password: "ganonsucks"
|
||||
}
|
||||
def insert(:user, new_params) do
|
||||
params =
|
||||
%{
|
||||
name: "Link",
|
||||
email: "link@hyrule.com",
|
||||
password: "ilovezelda"
|
||||
}
|
||||
|> Map.merge(new_params)
|
||||
|
||||
%User{}
|
||||
|> User.changeset(params)
|
||||
|> Repo.insert!
|
||||
end
|
||||
|
||||
def insert(:opponent, params) do
|
||||
%User{
|
||||
name: "Link",
|
||||
email: "link@hyrule.com",
|
||||
password: "ilovezelda"
|
||||
}
|
||||
def insert(:opponent, new_params) do
|
||||
params =
|
||||
%{
|
||||
name: "Zelda",
|
||||
email: "zelda@hyrule.com",
|
||||
password: "ganonsucks"
|
||||
}
|
||||
|> Map.merge(new_params)
|
||||
|
||||
%User{}
|
||||
|> User.changeset(params)
|
||||
|> Repo.insert!
|
||||
end
|
||||
|
||||
Loading…
Reference in New Issue
Block a user