diff --git a/.circleci/config.yml b/.circleci/config.yml new file mode 100644 index 0000000..2f40eb0 --- /dev/null +++ b/.circleci/config.yml @@ -0,0 +1,20 @@ +# Elixir CircleCI 2.0 configuration file +# +# Check https://circleci.com/docs/2.0/language-elixir/ for more details +version: 2 +jobs: + build: + docker: + - image: elixir:1.5.2 + - image: postgres:9.4.1 + environment: + POSTGRES_USER: postgres + steps: + - checkout + + # specify any bash command here prefixed with `run: ` + - run: mix local.hex --force + - run: mix local.rebar + - run: mix deps.get + - run: mix ecto.create + - run: mix test diff --git a/.credo.exs b/.credo.exs new file mode 100644 index 0000000..dc7520b --- /dev/null +++ b/.credo.exs @@ -0,0 +1,131 @@ +# This file contains the configuration for Credo and you are probably reading +# this after creating it with `mix credo.gen.config`. +# +# If you find anything wrong or unclear in this file, please report an +# issue on GitHub: https://github.com/rrrene/credo/issues +# +%{ + # + # You can have as many configs as you like in the `configs:` field. + configs: [ + %{ + # + # Run any exec using `mix credo -C `. If no exec name is given + # "default" is used. + # + name: "default", + # + # These are the files included in the analysis: + files: %{ + # + # You can give explicit globs or simply directories. + # In the latter case `**/*.{ex,exs}` will be used. + # + included: ["lib/", "src/", "web/", "apps/"], + excluded: [~r"/_build/", ~r"/deps/"] + }, + # + # If you create your own checks, you must specify the source files for + # them here, so they can be loaded by Credo before running the analysis. + # + requires: [], + # + # If you want to enforce a style guide and need a more traditional linting + # experience, you can change `strict` to `true` below: + # + strict: false, + # + # If you want to use uncolored output by default, you can change `color` + # to `false` below: + # + color: true, + # + # You can customize the parameters of any check by adding a second element + # to the tuple. + # + # To disable a check put `false` as second element: + # + # {Credo.Check.Design.DuplicatedCode, false} + # + checks: [ + {Credo.Check.Consistency.ExceptionNames}, + {Credo.Check.Consistency.LineEndings}, + {Credo.Check.Consistency.ParameterPatternMatching}, + {Credo.Check.Consistency.SpaceAroundOperators}, + {Credo.Check.Consistency.SpaceInParentheses}, + {Credo.Check.Consistency.TabsOrSpaces}, + + {Credo.Check.Design.AliasUsage, false}, + {Credo.Check.Design.DuplicatedCode, excluded_macros: []}, + {Credo.Check.Design.TagTODO, exit_status: 2}, + {Credo.Check.Design.TagFIXME}, + + {Credo.Check.Readability.FunctionNames}, + {Credo.Check.Readability.LargeNumbers}, + {Credo.Check.Readability.MaxLineLength, false}, + {Credo.Check.Readability.ModuleAttributeNames}, + {Credo.Check.Readability.ModuleDoc}, + {Credo.Check.Readability.ModuleNames}, + {Credo.Check.Readability.ParenthesesOnZeroArityDefs}, + {Credo.Check.Readability.ParenthesesInCondition}, + {Credo.Check.Readability.PredicateFunctionNames}, + {Credo.Check.Readability.PreferImplicitTry}, + {Credo.Check.Readability.RedundantBlankLines}, + {Credo.Check.Readability.StringSigils}, + {Credo.Check.Readability.TrailingBlankLine}, + {Credo.Check.Readability.TrailingWhiteSpace}, + {Credo.Check.Readability.VariableNames}, + {Credo.Check.Readability.Semicolons}, + {Credo.Check.Readability.SpaceAfterCommas}, + + {Credo.Check.Refactor.DoubleBooleanNegation}, + {Credo.Check.Refactor.CondStatements}, + {Credo.Check.Refactor.CyclomaticComplexity}, + {Credo.Check.Refactor.FunctionArity}, + {Credo.Check.Refactor.LongQuoteBlocks}, + {Credo.Check.Refactor.MatchInCondition}, + {Credo.Check.Refactor.NegatedConditionsInUnless}, + {Credo.Check.Refactor.NegatedConditionsWithElse}, + {Credo.Check.Refactor.Nesting}, + {Credo.Check.Refactor.PipeChainStart}, + {Credo.Check.Refactor.UnlessWithElse}, + + {Credo.Check.Warning.BoolOperationOnSameValues}, + {Credo.Check.Warning.ExpensiveEmptyEnumCheck}, + {Credo.Check.Warning.IExPry}, + {Credo.Check.Warning.IoInspect}, + {Credo.Check.Warning.LazyLogging}, + {Credo.Check.Warning.OperationOnSameValues}, + {Credo.Check.Warning.OperationWithConstantResult}, + {Credo.Check.Warning.UnusedEnumOperation}, + {Credo.Check.Warning.UnusedFileOperation}, + {Credo.Check.Warning.UnusedKeywordOperation}, + {Credo.Check.Warning.UnusedListOperation}, + {Credo.Check.Warning.UnusedPathOperation}, + {Credo.Check.Warning.UnusedRegexOperation}, + {Credo.Check.Warning.UnusedStringOperation}, + {Credo.Check.Warning.UnusedTupleOperation}, + {Credo.Check.Warning.RaiseInsideRescue}, + + # Controversial and experimental checks (opt-in, just remove `, false`) + # + {Credo.Check.Refactor.ABCSize, false}, + {Credo.Check.Refactor.AppendSingleItem, false}, + {Credo.Check.Refactor.VariableRebinding, false}, + {Credo.Check.Warning.MapGetUnsafePass, false}, + {Credo.Check.Consistency.MultiAliasImportRequireUse, false}, + + # Deprecated checks (these will be deleted after a grace period) + # + {Credo.Check.Readability.Specs, false}, + {Credo.Check.Warning.NameRedeclarationByAssignment, false}, + {Credo.Check.Warning.NameRedeclarationByCase, false}, + {Credo.Check.Warning.NameRedeclarationByDef, false}, + {Credo.Check.Warning.NameRedeclarationByFn, false}, + + # Custom checks can be created using `mix credo.gen.check`. + # + ] + } + ] +} diff --git a/README.md b/README.md index 6de3c02..1afe78d 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,7 @@ # Platform +[![CircleCI](https://circleci.com/gh/elixir-elm-tutorial/platform.svg?style=svg)](https://circleci.com/gh/elixir-elm-tutorial/platform) + This repository contains the source code for [elixir-elm-tutorial.herokuapp.com](https://elixir-elm-tutorial.herokuapp.com), which is the demo application from the @@ -9,6 +11,7 @@ which is the demo application from the - Elixir 1.5 - Phoenix 1.3 +- Elm 0.18 ## Setup @@ -24,6 +27,7 @@ which is the demo application from the - Run the test suite with `mix test`. - Check for outdated dependencies with `mix hex.outdated`. +- Run static analysis with `mix credo --strict`. ## Deployment @@ -33,4 +37,3 @@ This app is deployed to Heroku at https://elixir-elm-tutorial.herokuapp.com. - Open a [GitHub Issue](https://github.com/elixir-elm-tutorial/platform/issues). - Email me at `bijanbwb@gmail.com`. - diff --git a/config/config.exs b/config/config.exs index ee9cc5e..316a1fc 100644 --- a/config/config.exs +++ b/config/config.exs @@ -11,6 +11,7 @@ config :platform, # Configures the endpoint config :platform, PlatformWeb.Endpoint, + instrumenters: [Appsignal.Phoenix.Instrumenter], url: [host: "localhost"], secret_key_base: "5WY2LoKih9wBLcSs1KJdSumLNMFDzgDYvhqwdZjFvSVgDDVIYjx+dHmikCho8/lm", render_errors: [view: PlatformWeb.ErrorView, accepts: ~w(html json)], @@ -22,6 +23,14 @@ config :logger, :console, format: "$time $metadata[$level] $message\n", metadata: [:request_id] +# AppSignal +config :phoenix, :template_engines, +eex: Appsignal.Phoenix.Template.EExEngine, +exs: Appsignal.Phoenix.Template.ExsEngine + +config :platform, Platform.Repo, +loggers: [Appsignal.Ecto, Ecto.LogEntry] + # Import environment specific config. This must remain at the bottom # of this file so it overrides the configuration defined above. import_config "#{Mix.env}.exs" diff --git a/lib/platform/accounts/player.ex b/lib/platform/accounts/player.ex index 51df7a3..113e3c8 100644 --- a/lib/platform/accounts/player.ex +++ b/lib/platform/accounts/player.ex @@ -1,11 +1,17 @@ defmodule Platform.Accounts.Player do + @moduledoc """ + Players equate to users on the platform. The player module allows for + creating player accounts that are usable for authentication, and once + players are authenticated they can play through the Elm front-end games + and track scores. + """ + use Ecto.Schema import Ecto.Changeset alias Platform.Accounts.Player alias Platform.Products.Game alias Platform.Products.Gameplay - schema "players" do many_to_many :games, Game, join_through: Gameplay diff --git a/lib/platform/application.ex b/lib/platform/application.ex index cec541e..d1685b4 100644 --- a/lib/platform/application.ex +++ b/lib/platform/application.ex @@ -1,4 +1,8 @@ defmodule Platform.Application do + @moduledoc """ + Phoenix OTP Application + """ + use Application # See https://hexdocs.pm/elixir/Application.html diff --git a/lib/platform/products/game.ex b/lib/platform/products/game.ex index e49a546..402ac32 100644 --- a/lib/platform/products/game.ex +++ b/lib/platform/products/game.ex @@ -1,11 +1,16 @@ defmodule Platform.Products.Game do + @moduledoc """ + This module allows for creating game metadata and records on the + platform's back-end, but all game development actually occurs in + the Elm front-end. + """ + use Ecto.Schema import Ecto.Changeset alias Platform.Products.Game alias Platform.Products.Gameplay alias Platform.Accounts.Player - schema "games" do many_to_many :players, Player, join_through: Gameplay diff --git a/lib/platform/products/gameplay.ex b/lib/platform/products/gameplay.ex index d28398f..d6adf32 100644 --- a/lib/platform/products/gameplay.ex +++ b/lib/platform/products/gameplay.ex @@ -1,4 +1,12 @@ defmodule Platform.Products.Gameplay do + @moduledoc """ + Gameplays connect players and games. They allow for tracking individual + player score "attempts", and can be aggregated for a player's total score. + + Player gameplay data should be accessible via `player.gameplays`, and game + data should be accessible via `game.gameplays`. + """ + use Ecto.Schema import Ecto.Changeset alias Platform.Products.Gameplay diff --git a/lib/platform_web/channels/score_channel.ex b/lib/platform_web/channels/score_channel.ex index 44470b8..fb3aef7 100644 --- a/lib/platform_web/channels/score_channel.ex +++ b/lib/platform_web/channels/score_channel.ex @@ -1,16 +1,28 @@ defmodule PlatformWeb.ScoreChannel do + @moduledoc """ + Track scores from Elm front-end games (via elm-phoenix-socket). + + Channel joins can use each game's slug so this should be reusable for + different games that send a `player_score` value. + + The "save_score" message should allow players to both save their score to + the database and also broadcast it to any other users connected to the + socket. + """ + use PlatformWeb, :channel + use Appsignal.Instrumentation.Decorators - alias Platform.Accounts alias Platform.Products - def join("score:" <> game_slug, payload, socket) do + def join("score:" <> game_slug, _payload, socket) do game = Products.get_game_by_slug!(game_slug) socket = assign(socket, :game_id, game.id) {:ok, socket} end - def handle_in("save_score", %{"player_score" => player_score} = payload, socket) do + @decorate channel_action() + def handle_in("save_score", %{"player_score" => player_score}, socket) do payload = %{ player_score: player_score, game_id: socket.assigns.game_id, diff --git a/lib/platform_web/channels/user_socket.ex b/lib/platform_web/channels/user_socket.ex index 1816565..3eea58a 100644 --- a/lib/platform_web/channels/user_socket.ex +++ b/lib/platform_web/channels/user_socket.ex @@ -21,7 +21,7 @@ defmodule PlatformWeb.UserSocket do # See `Phoenix.Token` documentation for examples in # performing token verification on connect. def connect(%{"token" => token}, socket) do - case Phoenix.Token.verify(socket, "user socket", token, max_age: 1209600) do + case Phoenix.Token.verify(socket, "user socket", token, max_age: 1_209_600) do {:ok, current_user_id} -> socket = assign(socket, :player_id, current_user_id) {:ok, socket} diff --git a/lib/platform_web/endpoint.ex b/lib/platform_web/endpoint.ex index 0c96eb4..c460274 100644 --- a/lib/platform_web/endpoint.ex +++ b/lib/platform_web/endpoint.ex @@ -38,6 +38,7 @@ defmodule PlatformWeb.Endpoint do key: "_platform_key", signing_salt: "ZlLKP/TE" + use Appsignal.Phoenix plug PlatformWeb.Router @doc """ diff --git a/lib/platform_web/templates/layout/app.html.eex b/lib/platform_web/templates/layout/app.html.eex index 46c55c3..fab492a 100644 --- a/lib/platform_web/templates/layout/app.html.eex +++ b/lib/platform_web/templates/layout/app.html.eex @@ -42,5 +42,34 @@ + + + + + + diff --git a/mix.exs b/mix.exs index e0dc4ef..d67fc96 100644 --- a/mix.exs +++ b/mix.exs @@ -5,7 +5,7 @@ defmodule Platform.Mixfile do [ app: :platform, version: "0.0.1", - elixir: "~> 1.4", + elixir: "~> 1.5", elixirc_paths: elixirc_paths(Mix.env), compilers: [:phoenix, :gettext] ++ Mix.compilers, start_permanent: Mix.env == :prod, @@ -20,7 +20,7 @@ defmodule Platform.Mixfile do def application do [ mod: {Platform.Application, []}, - extra_applications: [:logger, :runtime_tools] + extra_applications: [:appsignal, :logger, :runtime_tools] ] end @@ -33,16 +33,19 @@ defmodule Platform.Mixfile do # Type `mix help deps` for examples and options. defp deps do [ + {:appsignal, "~> 1.0"}, + {:bcrypt_elixir, "~> 1.0"}, + {:comeonin, "~> 4.0"}, + {:cowboy, "~> 1.0"}, + {:credo, "~> 0.8.0", only: [:dev, :test], runtime: false}, + {:ex_machina, "~> 2.1", only: :test}, + {:gettext, "~> 0.11"}, {:phoenix, "~> 1.3.0"}, - {:phoenix_pubsub, "~> 1.0"}, {:phoenix_ecto, "~> 3.2"}, - {:postgrex, ">= 0.0.0"}, {:phoenix_html, "~> 2.10"}, {:phoenix_live_reload, "~> 1.0", only: :dev}, - {:gettext, "~> 0.11"}, - {:cowboy, "~> 1.0"}, - {:comeonin, "~> 4.0"}, - {:bcrypt_elixir, "~> 0.12"} + {:phoenix_pubsub, "~> 1.0"}, + {:postgrex, ">= 0.0.0"}, ] end diff --git a/mix.lock b/mix.lock index 71d59c3..7a18958 100644 --- a/mix.lock +++ b/mix.lock @@ -1,22 +1,36 @@ -%{"bcrypt_elixir": {:hex, :bcrypt_elixir, "0.12.1", "41ff5a4739fcff365fe840637462dc9e22beac07a9dcf3cb5e79b127f5b3a099", [], [{:elixir_make, "~> 0.4", [hex: :elixir_make, repo: "hexpm", optional: false]}], "hexpm"}, - "comeonin": {:hex, :comeonin, "4.0.0", "a830a86c9e1646f6dab82b1c602681ec365135b75ea04638bdd5b3ed5221e39b", [], [{:argon2_elixir, "~> 1.2", [hex: :argon2_elixir, repo: "hexpm", optional: true]}, {:bcrypt_elixir, "~> 0.12", [hex: :bcrypt_elixir, repo: "hexpm", optional: true]}, {:pbkdf2_elixir, "~> 0.12", [hex: :pbkdf2_elixir, repo: "hexpm", optional: true]}], "hexpm"}, +%{"appsignal": {:hex, :appsignal, "1.4.5", "38309b8da51c728a282c1a8574deb2e7a9bb0a25c90624d85a93b4a98f136f7e", [], [{:decorator, "~> 1.2.2", [hex: :decorator, repo: "hexpm", optional: false]}, {:httpoison, "~> 0.11", [hex: :httpoison, repo: "hexpm", optional: false]}, {:phoenix, ">= 1.2.0", [hex: :phoenix, repo: "hexpm", optional: true]}, {:plug, ">= 1.1.0", [hex: :plug, repo: "hexpm", optional: true]}, {:poison, ">= 1.3.0", [hex: :poison, repo: "hexpm", optional: false]}], "hexpm"}, + "bcrypt_elixir": {:hex, :bcrypt_elixir, "1.0.5", "cca70b5c8d9a98a0151c2d2796c728719c9c4b3f8bd2de015758ef577ee5141e", [:make, :mix], [{:elixir_make, "~> 0.4", [hex: :elixir_make, repo: "hexpm", optional: false]}], "hexpm"}, + "bunt": {:hex, :bunt, "0.2.0", "951c6e801e8b1d2cbe58ebbd3e616a869061ddadcc4863d0a2182541acae9a38", [], [], "hexpm"}, + "certifi": {:hex, :certifi, "2.0.0", "a0c0e475107135f76b8c1d5bc7efb33cd3815cb3cf3dea7aefdd174dabead064", [], [], "hexpm"}, + "comeonin": {:hex, :comeonin, "4.0.3", "4e257dcb748ed1ca2651b7ba24fdbd1bd24efd12482accf8079141e3fda23a10", [: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", [], [], "hexpm"}, "cowboy": {:hex, :cowboy, "1.1.2", "61ac29ea970389a88eca5a65601460162d370a70018afe6f949a29dca91f3bb0", [], [{:cowlib, "~> 1.0.2", [hex: :cowlib, repo: "hexpm", optional: false]}, {:ranch, "~> 1.3.2", [hex: :ranch, repo: "hexpm", optional: false]}], "hexpm"}, "cowlib": {:hex, :cowlib, "1.0.2", "9d769a1d062c9c3ac753096f868ca121e2730b9a377de23dec0f7e08b1df84ee", [], [], "hexpm"}, + "credo": {:hex, :credo, "0.8.10", "261862bb7363247762e1063713bb85df2bbd84af8d8610d1272cd9c1943bba63", [], [{:bunt, "~> 0.2.0", [hex: :bunt, repo: "hexpm", optional: false]}], "hexpm"}, "db_connection": {:hex, :db_connection, "1.1.2", "2865c2a4bae0714e2213a0ce60a1b12d76a6efba0c51fbda59c9ab8d1accc7a8", [], [{: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.0", "fac965ce71a46aab53d3a6ce45662806bdd708a4a95a65cde8a12eb0124a1333", [], [], "hexpm"}, - "ecto": {:hex, :ecto, "2.1.6", "29b45f393c2ecd99f83e418ea9b0a2af6078ecb30f401481abac8a473c490f84", [], [{: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"}, + "decimal": {:hex, :decimal, "1.4.1", "ad9e501edf7322f122f7fc151cce7c2a0c9ada96f2b0155b8a09a795c2029770", [:mix], [], "hexpm"}, + "decorator": {:hex, :decorator, "1.2.3", "258681ae943e57bd92d821ea995e3994b4e0b62ae8404b5d892cb8b23b55b050", [], [], "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"}, "elixir_make": {:hex, :elixir_make, "0.4.0", "992f38fabe705bb45821a728f20914c554b276838433349d4f2341f7a687cddf", [], [], "hexpm"}, + "ex_machina": {:hex, :ex_machina, "2.1.0", "4874dc9c78e7cf2d429f24dc3c4005674d4e4da6a08be961ffccc08fb528e28b", [:mix], [{:ecto, "~> 2.1", [hex: :ecto, repo: "hexpm", optional: true]}], "hexpm"}, + "file_system": {:hex, :file_system, "0.2.4", "f0bdda195c0e46e987333e986452ec523aed21d784189144f647c43eaf307064", [], [], "hexpm"}, "fs": {:hex, :fs, "0.9.2", "ed17036c26c3f70ac49781ed9220a50c36775c6ca2cf8182d123b6566e49ec59", [], [], "hexpm"}, - "gettext": {:hex, :gettext, "0.13.1", "5e0daf4e7636d771c4c71ad5f3f53ba09a9ae5c250e1ab9c42ba9edccc476263", [], [], "hexpm"}, - "mime": {:hex, :mime, "1.1.0", "01c1d6f4083d8aa5c7b8c246ade95139620ef8effb009edde934e0ec3b28090a", [], [], "hexpm"}, + "gettext": {:hex, :gettext, "0.14.0", "1a019a2e51d5ad3d126efe166dcdf6563768e5d06c32a99ad2281a1fa94b4c72", [:mix], [], "hexpm"}, + "hackney": {:hex, :hackney, "1.10.1", "c38d0ca52ea80254936a32c45bb7eb414e7a96a521b4ce76d00a69753b157f21", [], [{:certifi, "2.0.0", [hex: :certifi, repo: "hexpm", optional: false]}, {:idna, "5.1.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.1", [hex: :ssl_verify_fun, repo: "hexpm", optional: false]}], "hexpm"}, + "httpoison": {:hex, :httpoison, "0.13.0", "bfaf44d9f133a6599886720f3937a7699466d23bb0cd7a88b6ba011f53c6f562", [], [{:hackney, "~> 1.8", [hex: :hackney, repo: "hexpm", optional: false]}], "hexpm"}, + "idna": {:hex, :idna, "5.1.0", "d72b4effeb324ad5da3cab1767cb16b17939004e789d8c0ad5b70f3cea20c89a", [], [{:unicode_util_compat, "0.3.1", [hex: :unicode_util_compat, repo: "hexpm", optional: false]}], "hexpm"}, + "metrics": {:hex, :metrics, "1.0.1", "25f094dea2cda98213cecc3aeff09e940299d950904393b2a29d191c346a8486", [], [], "hexpm"}, + "mime": {:hex, :mime, "1.2.0", "78adaa84832b3680de06f88f0997e3ead3b451a440d183d688085be2d709b534", [:mix], [], "hexpm"}, + "mimerl": {:hex, :mimerl, "1.0.2", "993f9b0e084083405ed8252b99460c4f0563e41729ab42d9074fd5e52439be88", [], [], "hexpm"}, "phoenix": {:hex, :phoenix, "1.3.0", "1c01124caa1b4a7af46f2050ff11b267baa3edb441b45dbf243e979cd4c5891b", [], [{: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.2.3", "450c749876ff1de4a78fdb305a142a76817c77a1cd79aeca29e5fc9a6c630b26", [], [{: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.10.3", "432dec9e04372eeb7a6dbf59a778cf43eb44518441932217371fa535f2bcfd80", [], [{:plug, "~> 1.0", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm"}, - "phoenix_live_reload": {:hex, :phoenix_live_reload, "1.0.8", "4333f9c74190f485a74866beff2f9304f069d53f047f5fbb0fb8d1ee4c495f73", [], [{:fs, "~> 0.9.1", [hex: :fs, repo: "hexpm", optional: false]}, {:phoenix, "~> 1.0 or ~> 1.2-rc", [hex: :phoenix, repo: "hexpm", optional: false]}], "hexpm"}, + "phoenix_ecto": {:hex, :phoenix_ecto, "3.3.0", "702f6e164512853d29f9d20763493f2b3bcfcb44f118af2bc37bb95d0801b480", [: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.10.5", "4f9df6b0fb7422a9440a73182a566cb9cbe0e3ffe8884ef9337ccf284fc1ef0a", [:mix], [{:plug, "~> 1.0", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm"}, + "phoenix_live_reload": {:hex, :phoenix_live_reload, "1.1.3", "1d178429fc8950b12457d09c6afec247bfe1fcb6f36209e18fbb0221bdfe4d41", [: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.0.2", "bfa7fd52788b5eaa09cb51ff9fcad1d9edfeb68251add458523f839392f034c1", [], [], "hexpm"}, "plug": {:hex, :plug, "1.4.3", "236d77ce7bf3e3a2668dc0d32a9b6f1f9b1f05361019946aae49874904be4aed", [], [{:cowboy, "~> 1.0.1 or ~> 1.1", [hex: :cowboy, repo: "hexpm", optional: true]}, {:mime, "~> 1.0", [hex: :mime, repo: "hexpm", optional: false]}], "hexpm"}, "poison": {:hex, :poison, "3.1.0", "d9eb636610e096f86f25d9a46f35a9facac35609a7591b3be3326e99a0484665", [], [], "hexpm"}, "poolboy": {:hex, :poolboy, "1.5.1", "6b46163901cfd0a1b43d692657ed9d7e599853b3b21b95ae5ae0a777cf9b6ca8", [], [], "hexpm"}, "postgrex": {:hex, :postgrex, "0.13.3", "c277cfb2a9c5034d445a722494c13359e361d344ef6f25d604c2353185682bfc", [], [{: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", [], [], "hexpm"}} + "ranch": {:hex, :ranch, "1.3.2", "e4965a144dc9fbe70e5c077c65e73c57165416a901bd02ea899cfd95aa890986", [], [], "hexpm"}, + "ssl_verify_fun": {:hex, :ssl_verify_fun, "1.1.1", "28a4d65b7f59893bc2c7de786dec1e1555bd742d336043fe644ae956c3497fbe", [], [], "hexpm"}, + "unicode_util_compat": {:hex, :unicode_util_compat, "0.3.1", "a1f612a7b512638634a603c8f401892afbf99b8ce93a45041f8aaca99cadb85e", [], [], "hexpm"}} diff --git a/test/support/factory.ex b/test/support/factory.ex new file mode 100644 index 0000000..4917871 --- /dev/null +++ b/test/support/factory.ex @@ -0,0 +1,29 @@ +defmodule Platform.Factory do + use ExMachina.Ecto, repo: Platform.Repo + + def player_factory do + %Platform.Accounts.Player{ + display_name: "José Valim", + username: "josevalim", + score: 0, + } + end + + def game_factory do + %Platform.Products.Game{ + description: "Platformer game example.", + featured: true, + slug: Enum.random(0..1000) |> Integer.to_string, + thumbnail: "https://i.imgur.com/L6ci0xL.png", + title: "Platformer", + } + end + + def gameplay_factory do + %Platform.Products.Gameplay{ + game_id: 1, + player_id: 1, + player_score: 1 + } + end +end diff --git a/test/test_helper.exs b/test/test_helper.exs index ce0dee4..a016a16 100644 --- a/test/test_helper.exs +++ b/test/test_helper.exs @@ -1,4 +1,5 @@ +{:ok, _} = Application.ensure_all_started(:ex_machina) + ExUnit.start() Ecto.Adapters.SQL.Sandbox.mode(Platform.Repo, :manual) -