...
 
Commits (1)
......@@ -7,18 +7,21 @@
# Generated on crash by the VM
erl_crash.dump
# Generated on crash by NPM
npm-debug.log
# Static artifacts
/node_modules
/assets/node_modules
# Since we are building assets from web/static,
# Since we are building assets from assets/,
# we ignore priv/static. You may want to comment
# this depending on your deployment strategy.
/priv/static/
# The config/prod.secret.exs file by default contains sensitive
# data and you should not commit it into version control.
# Files matching config/*.secret.exs pattern contain sensitive
# data and you should not commit them into version control.
#
# Alternatively, you may comment the line below and commit the
# secrets file as long as you replace its contents by environment
# secrets files as long as you replace their contents by environment
# variables.
/config/prod.secret.exs
/config/*.secret.exs
# Maldon
To start your Phoenix app:
To start your Phoenix server:
* Install dependencies with `mix deps.get`
* Create and migrate your database with `mix ecto.create && mix ecto.migrate`
* Install Node.js dependencies with `npm install`
* Start Phoenix endpoint with `mix phoenix.server`
* Install Node.js dependencies with `cd assets && yarn install`
* Start Phoenix endpoint with `mix phx.server`
Now you can visit [`localhost:4000`](http://localhost:4000) from your browser.
......
......@@ -7,23 +7,20 @@ exports.config = {
// To use a separate vendor.js bundle, specify two files path
// http://brunch.io/docs/config#-files-
// joinTo: {
// "js/app.js": /^(web\/static\/js)/,
// "js/vendor.js": /^(web\/static\/vendor)|(deps)/
// "js/app.js": /^js/,
// "js/vendor.js": /^(?!js)/
// }
//
// To change the order of concatenation of files, explicitly mention here
// order: {
// before: [
// "web/static/vendor/js/jquery-2.1.1.js",
// "web/static/vendor/js/bootstrap.min.js"
// "vendor/js/jquery-2.1.1.js",
// "vendor/js/bootstrap.min.js"
// ]
// }
},
stylesheets: {
joinTo: "css/app.css",
order: {
after: ["web/static/css/app.css"] // concat app.css last
}
joinTo: "css/app.css"
},
templates: {
joinTo: "js/app.js"
......@@ -32,34 +29,30 @@ exports.config = {
conventions: {
// This option sets where we should place non-css and non-js assets in.
// By default, we set this to "/web/static/assets". Files in this directory
// By default, we set this to "/assets/static". Files in this directory
// will be copied to `paths.public`, which is "priv/static" by default.
assets: /^(web\/static\/assets)/
assets: /^(static)/
},
// Phoenix paths configuration
paths: {
// Dependencies and current project directories to watch
watched: [
"web/static",
"test/static"
],
watched: ["static", "css", "js", "vendor"],
// Where to compile files to
public: "priv/static"
public: "../priv/static"
},
// Configure your plugins
plugins: {
babel: {
// Do not use ES6 compiler in vendor code
ignore: [/web\/static\/vendor/]
ignore: [/vendor/]
}
},
modules: {
autoRequire: {
"js/app.js": ["web/static/js/app"]
"js/app.js": ["js/app"]
}
},
......
......@@ -17,11 +17,6 @@ body, form, ul, table {
/* Phoenix flash messages */
.alert:empty { display: none; }
/* Phoenix inline forms in links and buttons */
form.link, form.button {
display: inline;
}
/* Custom page header */
.header {
border-bottom: 1px solid #e5e5e5;
......@@ -79,4 +74,4 @@ form.link, form.button {
.jumbotron {
border-bottom: 0;
}
}
\ No newline at end of file
}
// NOTE: The contents of this file will only be executed if
// you uncomment its entry in "web/static/js/app.js".
// you uncomment its entry in "assets/js/app.js".
// To use Phoenix channels, the first step is to import Socket
// and connect at the socket path in "lib/my_app/endpoint.ex":
// and connect at the socket path in "lib/web/endpoint.ex":
import {Socket} from "phoenix"
let socket = new Socket("/socket", {params: {token: window.userToken}})
......@@ -13,7 +13,7 @@ let socket = new Socket("/socket", {params: {token: window.userToken}})
// If the current user exists you can assign the user's token in
// the connection for use in the layout.
//
// In your "web/router.ex":
// In your "lib/web/router.ex":
//
// pipeline :browser do
// ...
......@@ -31,12 +31,12 @@ let socket = new Socket("/socket", {params: {token: window.userToken}})
// end
//
// Now you need to pass this token to JavaScript. You can do so
// inside a script tag in "web/templates/layout/app.html.eex":
// inside a script tag in "lib/web/templates/layout/app.html.eex":
//
// <script>window.userToken = "<%= assigns[:user_token] %>";</script>
//
// You will need to verify the user token in the "connect/2" function
// in "web/channels/user_socket.ex":
// in "lib/web/channels/user_socket.ex":
//
// def connect(%{"token" => token}, socket) do
// # max_age: 1209600 is equivalent to two weeks in seconds
......
{
{
"repository": {},
"license": "MIT",
"scripts": {
......@@ -6,15 +6,13 @@
"watch": "brunch watch --stdin"
},
"dependencies": {
"phoenix": "file:deps/phoenix",
"phoenix_html": "file:deps/phoenix_html"
"phoenix": "file:../deps/phoenix",
"phoenix_html": "file:../deps/phoenix_html"
},
"devDependencies": {
"babel-brunch": "~6.0.0",
"brunch": "2.7.4",
"clean-css-brunch": "~2.0.0",
"css-brunch": "~2.0.0",
"javascript-brunch": "~2.0.0",
"uglify-js-brunch": "~2.0.1"
"babel-brunch": "6.1.1",
"brunch": "2.10.9",
"clean-css-brunch": "2.10.0",
"uglify-js-brunch": "2.10.0"
}
}
This diff is collapsed.
......@@ -10,10 +10,10 @@ config :maldon,
ecto_repos: [Maldon.Repo]
# Configures the endpoint
config :maldon, Maldon.Endpoint,
config :maldon, MaldonWeb.Endpoint,
url: [host: "localhost"],
secret_key_base: "eZa8aF+sGEZsj2vZU6QGu0fpucMUfG9cD7NbGU+s78E86HpMhHflrtTsM+L6I6Pk",
render_errors: [view: Maldon.ErrorView, accepts: ~w(html json)],
render_errors: [view: MaldonWeb.ErrorView, accepts: ~w(html json)],
pubsub: [name: Maldon.PubSub,
adapter: Phoenix.PubSub.PG2]
......
......@@ -6,23 +6,38 @@ use Mix.Config
# The watchers configuration can be used to run external
# watchers to your application. For example, we use it
# with brunch.io to recompile .js and .css sources.
config :maldon, Maldon.Endpoint,
config :maldon, MaldonWeb.Endpoint,
http: [port: 4000],
debug_errors: true,
code_reloader: true,
check_origin: false,
watchers: [node: ["node_modules/brunch/bin/brunch", "watch", "--stdin",
cd: Path.expand("../", __DIR__)]]
cd: Path.expand("../assets", __DIR__)]]
# ## SSL Support
#
# In order to use HTTPS in development, a self-signed
# certificate can be generated by running the following
# command from your terminal:
#
# openssl req -new -newkey rsa:4096 -days 365 -nodes -x509 -subj "/C=US/ST=Denial/L=Springfield/O=Dis/CN=www.example.com" -keyout priv/server.key -out priv/server.pem
#
# The `http:` config above can be replaced with:
#
# https: [port: 4000, keyfile: "priv/server.key", certfile: "priv/server.pem"],
#
# If desired, both `http:` and `https:` keys can be
# configured to run both http and https servers on
# different ports.
# Watch static and templates for browser reloading.
config :maldon, Maldon.Endpoint,
config :maldon, MaldonWeb.Endpoint,
live_reload: [
patterns: [
~r{priv/static/.*(js|css|png|jpeg|jpg|gif|svg)$},
~r{priv/gettext/.*(po)$},
~r{web/views/.*(ex)$},
~r{web/templates/.*(eex)$}
~r{lib/maldon_web/views/.*(ex)$},
~r{lib/maldon_web/templates/.*(eex)$}
]
]
......
use Mix.Config
# For production, we configure the host to read the PORT
# from the system environment. Therefore, you will need
# to set PORT=80 before running your server.
# For production, we often load configuration from external
# sources, such as your system environment. For this reason,
# you won't find the :http configuration below, but set inside
# MaldonWeb.Endpoint.init/2 when load_from_system_env is
# true. Any dynamic configuration should be done there.
#
# You should also configure the url host to something
# meaningful, we use this information when generating URLs.
# Don't forget to configure the url host to something meaningful,
# Phoenix uses this information when generating URLs.
#
# Finally, we also include the path to a manifest
# Finally, we also include the path to a cache manifest
# containing the digested version of static files. This
# manifest is generated by the mix phoenix.digest task
# manifest is generated by the mix phx.digest task
# which you typically run after static files are built.
config :maldon, Maldon.Endpoint,
http: [port: {:system, "PORT"}],
config :maldon, MaldonWeb.Endpoint,
load_from_system_env: true,
url: [host: "example.com", port: 80],
cache_static_manifest: "priv/static/manifest.json"
cache_static_manifest: "priv/static/cache_manifest.json"
# Do not print debug messages in production
config :logger, level: :info
......@@ -27,7 +29,8 @@ config :logger, level: :info
# config :maldon, Maldon.Endpoint,
# ...
# url: [host: "example.com", port: 443],
# https: [port: 443,
# https: [:inet6,
# port: 443,
# keyfile: System.get_env("SOME_APP_SSL_KEY_PATH"),
# certfile: System.get_env("SOME_APP_SSL_CERT_PATH")]
#
......@@ -38,7 +41,7 @@ config :logger, level: :info
# We also recommend setting `force_ssl`, ensuring no data is
# ever sent via http, always redirecting to https:
#
# config :maldon, Maldon.Endpoint,
# config :maldon, MaldonWeb.Endpoint,
# force_ssl: [hsts: true]
#
# Check `Plug.SSL` for all available options in `force_ssl`.
......@@ -53,7 +56,7 @@ config :logger, level: :info
# Alternatively, you can configure exactly which server to
# start per endpoint:
#
# config :maldon, Maldon.Endpoint, server: true
# config :maldon, MaldonWeb.Endpoint, server: true
#
# Finally import the config/prod.secret.exs
......
......@@ -10,7 +10,7 @@ config :maldon, Maldon.Endpoint,
config :logger, level: :warn
# Configure your database
config :maldon, Maldon.Repo,
config :maldon, MaldonWeb.Repo,
adapter: Ecto.Adapters.Postgres,
username: "postgres",
password: "postgres",
......
defmodule Maldon do
use Application
@moduledoc """
SampleApp keeps the contexts that define your domain
and business logic.
# See http://elixir-lang.org/docs/stable/elixir/Application.html
# for more information on OTP Applications
def start(_type, _args) do
import Supervisor.Spec
# Define workers and child supervisors to be supervised
children = [
# Start the Ecto repository
supervisor(Maldon.Repo, []),
# Start the endpoint when the application starts
supervisor(Maldon.Endpoint, []),
# Start your own worker by calling: Maldon.Worker.start_link(arg1, arg2, arg3)
# worker(Maldon.Worker, [arg1, arg2, arg3]),
]
# See http://elixir-lang.org/docs/stable/elixir/Supervisor.html
# for other strategies and supported options
opts = [strategy: :one_for_one, name: Maldon.Supervisor]
Supervisor.start_link(children, opts)
end
# Tell Phoenix to update the endpoint configuration
# whenever the application is updated.
def config_change(changed, _new, removed) do
Maldon.Endpoint.config_change(changed, removed)
:ok
end
Contexts are also responsible for managing your data, regardless
if it comes from the database, an external API or others.
"""
end
defmodule Maldon.Application do
use Application
# See https://hexdocs.pm/elixir/Application.html
# for more information on OTP Applications
def start(_type, _args) do
import Supervisor.Spec
# Define workers and child supervisors to be supervised
children = [
# Start the Ecto repository
supervisor(Maldon.Repo, []),
# Start the endpoint when the application starts
supervisor(MaldonWeb.Endpoint, []),
# Start your own worker by calling: Maldon.Worker.start_link(arg1, arg2, arg3)
# worker(Maldon.Worker, [arg1, arg2, arg3]),
]
# See https://hexdocs.pm/elixir/Supervisor.html
# for other strategies and supported options
opts = [strategy: :one_for_one, name: Maldon.Supervisor]
Supervisor.start_link(children, opts)
end
# Tell Phoenix to update the endpoint configuration
# whenever the application is updated.
def config_change(changed, _new, removed) do
MaldonWeb.Endpoint.config_change(changed, removed)
:ok
end
end
defmodule Maldon.Repo do
use Ecto.Repo, otp_app: :maldon
@moduledoc """
In memory repository
"""
@doc """
Dynamically loads the repository url from the
DATABASE_URL environment variable.
"""
def init(_, opts) do
{:ok, Keyword.put(opts, :url, System.get_env("DATABASE_URL"))}
end
#
# # def all(MaldonWeb.User) do
# # [%MaldonWeb.User{id: "1", name: "Rémy Coutable", username: "rymai", password: "secure"}]
# # end
# def all(_module), do: []
#
# def get(module, id) do
# Enum.find all(module), fn map -> map.id == id end
# end
#
# def get_by(module, params) do
# Enum.find all(module), fn map ->
# Enum.all?(params, fn {key, val} -> Map.get(map, key) == val end)
# end
# end
end
defmodule Maldon.Web do
defmodule MaldonWeb do
@moduledoc """
A module that keeps using definitions for controllers,
views and so on.
The entrypoint for defining your web interface, such
as controllers, views, channels and so on.
This can be used in your application as:
use Maldon.Web, :controller
use Maldon.Web, :view
use MaldonWeb, :controller
use MaldonWeb, :view
The definitions below will be executed for every view,
controller, etc, so keep them short and clean, focused
on imports, uses and aliases.
Do NOT define functions inside the quoted expressions
below.
below. Instead, define any helper function in modules
and import those modules here.
"""
def model do
quote do
use Ecto.Schema
import Ecto
import Ecto.Changeset
import Ecto.Query
end
end
# def model do
# quote do
# use Ecto.Schema
#
# import Ecto
# import Ecto.Changeset
# import Ecto.Query
# end
# end
def controller do
quote do
use Phoenix.Controller
use Phoenix.Controller, namespace: MaldonWeb
import Plug.Conn
alias Maldon.Repo
import Ecto
import Ecto.Query
import Maldon.Router.Helpers
import Maldon.Gettext
import MaldonWeb.Router.Helpers
import MaldonWeb.Gettext
end
end
def view do
quote do
use Phoenix.View, root: "web/templates"
use Phoenix.View, root: "lib/maldon_web/templates",
namespace: MaldonWeb
# Import convenience functions from controllers
import Phoenix.Controller, only: [get_csrf_token: 0, get_flash: 2, view_module: 1]
import Phoenix.Controller, only: [get_flash: 2, view_module: 1]
# Use all HTML functionality (forms, tags, etc)
use Phoenix.HTML
import Maldon.Router.Helpers
import Maldon.ErrorHelpers
import Maldon.Gettext
import MaldonWeb.Router.Helpers
import MaldonWeb.ErrorHelpers
import MaldonWeb.Gettext
end
end
def router do
quote do
use Phoenix.Router
import Plug.Conn
import Phoenix.Controller
end
end
......@@ -68,7 +73,7 @@ defmodule Maldon.Web do
alias Maldon.Repo
import Ecto
import Ecto.Query
import Maldon.Gettext
import MaldonWeb.Gettext
end
end
......
defmodule Maldon.UserSocket do
defmodule MaldonWeb.UserSocket do
use Phoenix.Socket
## Channels
# channel "room:*", Maldon.RoomChannel
# channel "room:*", MaldonWeb.RoomChannel
## Transports
transport :websocket, Phoenix.Transports.WebSocket
......@@ -25,12 +25,12 @@ defmodule Maldon.UserSocket do
# Socket id's are topics that allow you to identify all sockets for a given user:
#
# def id(socket), do: "users_socket:#{socket.assigns.user_id}"
# def id(socket), do: "user_socket:#{socket.assigns.user_id}"
#
# Would allow you to broadcast a "disconnect" event and terminate
# all active sockets and channels for a given user:
#
# Maldon.Endpoint.broadcast("users_socket:#{user.id}", "disconnect", %{})
# MaldonWeb.Endpoint.broadcast("user_socket:#{user.id}", "disconnect", %{})
#
# Returning `nil` makes this socket anonymous.
def id(_socket), do: nil
......
defmodule Maldon.PageController do
use Maldon.Web, :controller
defmodule MaldonWeb.PageController do
use MaldonWeb, :controller
def index(conn, _params) do
render conn, "index.html"
......
defmodule Maldon.Endpoint do
defmodule MaldonWeb.Endpoint do
use Phoenix.Endpoint, otp_app: :maldon
socket "/socket", Maldon.UserSocket
socket "/socket", MaldonWeb.UserSocket
# Serve at "/" the static files from "priv/static" directory.
#
......@@ -38,5 +38,20 @@ defmodule Maldon.Endpoint do
key: "_maldon_key",
signing_salt: "QsmSzY3G"
plug Maldon.Router
plug MaldonWeb.Router
@doc """
Callback invoked for dynamically configuring the endpoint.
It receives the endpoint configuration and checks if
configuration should be loaded from the system environment.
"""
def init(_key, config) do
if config[:load_from_system_env] do
port = System.get_env("PORT") || raise "expected the PORT environment variable to be set"
{:ok, Keyword.put(config, :http, [:inet6, port: port])}
else
{:ok, config}
end
end
end
defmodule Maldon.Gettext do
defmodule MaldonWeb.Gettext do
@moduledoc """
A module providing Internationalization with a gettext-based API.
By using [Gettext](https://hexdocs.pm/gettext),
your module gains a set of macros for translations, for example:
import Maldon.Gettext
import MaldonWeb.Gettext
# Simple translation
gettext "Here is the string to translate"
......
defmodule Maldon.Router do
use Maldon.Web, :router
defmodule MaldonWeb.Router do
use MaldonWeb, :router
pipeline :browser do
plug :accepts, ["html"]
......@@ -13,14 +13,16 @@ defmodule Maldon.Router do
plug :accepts, ["json"]
end
scope "/", Maldon do
scope "/", MaldonWeb do
pipe_through :browser # Use the default browser stack
get "/users", UserController, :index
get "/users/:id", UserController, :show
get "/", PageController, :index
end
# Other scopes may use custom stacks.
# scope "/api", Maldon do
# scope "/api", MaldonWeb do
# pipe_through :api
# end
end
<div class="jumbotron">
<h2><%= gettext "Welcome to %{name}", name: "Phoenix!" %></h2>
<h2><%= gettext "Welcome to %{name}!", name: "Phoenix" %></h2>
<p class="lead">A productive web framework that<br />does not compromise speed and maintainability.</p>
</div>
......
defmodule Maldon.ErrorHelpers do
defmodule MaldonWeb.ErrorHelpers do
@moduledoc """
Conveniences for translating and building error messages.
"""
......@@ -9,9 +9,9 @@ defmodule Maldon.ErrorHelpers do
Generates tag for inlined form input errors.
"""
def error_tag(form, field) do
if error = form.errors[field] do
Enum.map(Keyword.get_values(form.errors, field), fn (error) ->
content_tag :span, translate_error(error), class: "help-block"
end
end)
end
@doc """
......@@ -32,9 +32,9 @@ defmodule Maldon.ErrorHelpers do
# dgettext "errors", "is invalid"
#
if count = opts[:count] do
Gettext.dngettext(Maldon.Gettext, "errors", msg, msg, count, opts)
Gettext.dngettext(MaldonWeb.Gettext, "errors", msg, msg, count, opts)
else
Gettext.dgettext(Maldon.Gettext, "errors", msg, opts)
Gettext.dgettext(MaldonWeb.Gettext, "errors", msg, opts)
end
end
end
defmodule Maldon.ErrorView do
use Maldon.Web, :view
defmodule MaldonWeb.ErrorView do
use MaldonWeb, :view
def render("404.html", _assigns) do
"Page not found"
......
defmodule MaldonWeb.LayoutView do
use MaldonWeb, :view
end
defmodule MaldonWeb.PageView do
use MaldonWeb, :view
end
......@@ -2,42 +2,47 @@ defmodule Maldon.Mixfile do
use Mix.Project
def project do
[app: :maldon,
version: "0.0.1",
elixir: "~> 1.2",
elixirc_paths: elixirc_paths(Mix.env),
compilers: [:phoenix, :gettext] ++ Mix.compilers,
build_embedded: Mix.env == :prod,
start_permanent: Mix.env == :prod,
aliases: aliases(),
deps: deps()]
[
app: :maldon,
version: "0.0.1",
elixir: "~> 1.4",
elixirc_paths: elixirc_paths(Mix.env),
compilers: [:phoenix, :gettext] ++ Mix.compilers,
build_embedded: Mix.env == :prod,
start_permanent: Mix.env == :prod,
aliases: aliases(),
deps: deps()
]
end
# Configuration for the OTP application.
#
# Type `mix help compile.app` for more information.
def application do
[mod: {Maldon, []},
applications: [:phoenix, :phoenix_pubsub, :phoenix_html, :cowboy, :logger, :gettext,
:phoenix_ecto, :postgrex]]
[
mod: {Maldon.Application, []},
extra_applications: [:logger, :runtime_tools]
]
end
# Specifies which paths to compile per environment.
defp elixirc_paths(:test), do: ["lib", "web", "test/support"]
defp elixirc_paths(_), do: ["lib", "web"]
defp elixirc_paths(:test), do: ["lib", "test/support"]
defp elixirc_paths(_), do: ["lib"]
# Specifies your project dependencies.
#
# Type `mix help deps` for examples and options.
defp deps do
[{:phoenix, "~> 1.2.1"},
{:phoenix_pubsub, "~> 1.0"},
{:phoenix_ecto, "~> 3.0"},
{:postgrex, ">= 0.0.0"},
{:phoenix_html, "~> 2.6"},
{:phoenix_live_reload, "~> 1.0", only: :dev},
{:gettext, "~> 0.11"},
{:cowboy, "~> 1.0"}]
[
{: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"}
]
end
# Aliases are shortcuts or tasks specific to the current project.
......@@ -47,8 +52,10 @@ defmodule Maldon.Mixfile do
#
# See the documentation for `Mix` for more info on aliases.
defp aliases do
["ecto.setup": ["ecto.create", "ecto.migrate", "run priv/repo/seeds.exs"],
"ecto.reset": ["ecto.drop", "ecto.setup"],
"test": ["ecto.create --quiet", "ecto.migrate", "test"]]
[
"ecto.setup": ["ecto.create", "ecto.migrate", "run priv/repo/seeds.exs"],
"ecto.reset": ["ecto.drop", "ecto.setup"],
"test": ["ecto.create --quiet", "ecto.migrate", "test"]
]
end
end
%{"connection": {:hex, :connection, "1.0.4", "a1cae72211f0eef17705aaededacac3eb30e6625b04a6117c1b2db6ace7d5976", [:mix], []},
"cowboy": {:hex, :cowboy, "1.0.4", "a324a8df9f2316c833a470d918aaf73ae894278b8aa6226ce7a9bf699388f878", [:rebar, :make], [{:cowlib, "~> 1.0.0", [hex: :cowlib, optional: false]}, {:ranch, "~> 1.0", [hex: :ranch, optional: false]}]},
"cowboy": {:hex, :cowboy, "1.1.2", "61ac29ea970389a88eca5a65601460162d370a70018afe6f949a29dca91f3bb0", [:rebar3], [{: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", [:make], []},
"db_connection": {:hex, :db_connection, "1.0.0-rc.5", "1d9ab6e01387bdf2de7a16c56866971f7c2f75aea7c69cae2a0346e4b537ae0d", [:mix], [{:connection, "~> 1.0.2", [hex: :connection, optional: false]}, {:poolboy, "~> 1.5", [hex: :poolboy, optional: true]}, {:sbroker, "~> 1.0.0-beta.3", [hex: :sbroker, optional: true]}]},
"decimal": {:hex, :decimal, "1.2.0", "462960fd71af282e570f7b477f6be56bf8968e68277d4d0b641a635269bf4b0d", [:mix], []},
"ecto": {:hex, :ecto, "2.0.5", "7f4c79ac41ffba1a4c032b69d7045489f0069c256de606523c65d9f8188e502d", [:mix], [{:db_connection, "~> 1.0-rc.4", [hex: :db_connection, optional: true]}, {:decimal, "~> 1.1.2 or ~> 1.2", [hex: :decimal, optional: false]}, {:mariaex, "~> 0.7.7", [hex: :mariaex, optional: true]}, {:poison, "~> 1.5 or ~> 2.0", [hex: :poison, optional: true]}, {:poolboy, "~> 1.5", [hex: :poolboy, optional: false]}, {:postgrex, "~> 0.12.0", [hex: :postgrex, optional: true]}, {:sbroker, "~> 1.0-beta", [hex: :sbroker, optional: true]}]},
"db_connection": {:hex, :db_connection, "1.1.2", "2865c2a4bae0714e2213a0ce60a1b12d76a6efba0c51fbda59c9ab8d1accc7a8", [: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.4.1", "ad9e501edf7322f122f7fc151cce7c2a0c9ada96f2b0155b8a09a795c2029770", [:mix], [], "hexpm"},
"ecto": {:hex, :ecto, "2.2.6", "3fd1067661d6d64851a0d4db9acd9e884c00d2d1aa41cc09da687226cf894661", [: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"},
"fs": {:hex, :fs, "0.9.2", "ed17036c26c3f70ac49781ed9220a50c36775c6ca2cf8182d123b6566e49ec59", [:rebar], []},
"gettext": {:hex, :gettext, "0.11.0", "80c1dd42d270482418fa158ec5ba073d2980e3718bacad86f3d4ad71d5667679", [:mix], []},
"mime": {:hex, :mime, "1.0.1", "05c393850524767d13a53627df71beeebb016205eb43bfbd92d14d24ec7a1b51", [:mix], []},
"phoenix": {:hex, :phoenix, "1.2.1", "6dc592249ab73c67575769765b66ad164ad25d83defa3492dc6ae269bd2a68ab", [:mix], [{:cowboy, "~> 1.0", [hex: :cowboy, optional: true]}, {:phoenix_pubsub, "~> 1.0", [hex: :phoenix_pubsub, optional: false]}, {:plug, "~> 1.1", [hex: :plug, optional: false]}, {:poison, "~> 1.5 or ~> 2.0", [hex: :poison, optional: false]}]},
"phoenix_ecto": {:hex, :phoenix_ecto, "3.0.1", "42eb486ef732cf209d0a353e791806721f33ff40beab0a86f02070a5649ed00a", [:mix], [{:ecto, "~> 2.0", [hex: :ecto, optional: false]}, {:phoenix_html, "~> 2.6", [hex: :phoenix_html, optional: true]}, {:plug, "~> 1.0", [hex: :plug, optional: false]}]},
"phoenix_html": {:hex, :phoenix_html, "2.7.0", "19e12e2044340c2e43df206a06d059677c59ea1868bd1c35165438d592cd420b", [:mix], [{:plug, "~> 1.0", [hex: :plug, optional: false]}]},
"mime": {:hex, :mime, "1.1.0", "01c1d6f4083d8aa5c7b8c246ade95139620ef8effb009edde934e0ec3b28090a", [:mix], [], "hexpm"},
"phoenix": {:hex, :phoenix, "1.3.0", "1c01124caa1b4a7af46f2050ff11b267baa3edb441b45dbf243e979cd4c5891b", [: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.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.0.5", "829218c4152ba1e9848e2bf8e161fcde6b4ec679a516259442561d21fde68d0b", [:mix], [{:fs, "~> 0.9.1", [hex: :fs, optional: false]}, {:phoenix, "~> 1.0 or ~> 1.2-rc", [hex: :phoenix, optional: false]}]},
"phoenix_pubsub": {:hex, :phoenix_pubsub, "1.0.1", "c10ddf6237007c804bf2b8f3c4d5b99009b42eca3a0dfac04ea2d8001186056a", [:mix], []},
"plug": {:hex, :plug, "1.2.1", "dc878eb303099c945465b3f7811200e7dc0a4e2b1b6f3e26dc749011f3ed27ad", [:mix], [{:cowboy, "~> 1.0", [hex: :cowboy, optional: true]}, {:mime, "~> 1.0", [hex: :mime, optional: false]}]},
"poison": {:hex, :poison, "2.2.0", "4763b69a8a77bd77d26f477d196428b741261a761257ff1cf92753a0d4d24a63", [:mix], []},
"phoenix_pubsub": {:hex, :phoenix_pubsub, "1.0.2", "bfa7fd52788b5eaa09cb51ff9fcad1d9edfeb68251add458523f839392f034c1", [:mix], [], "hexpm"},
"plug": {:hex, :plug, "1.4.3", "236d77ce7bf3e3a2668dc0d32a9b6f1f9b1f05361019946aae49874904be4aed", [:mix], [{: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", [:mix], [], "hexpm"},
"poolboy": {:hex, :poolboy, "1.5.1", "6b46163901cfd0a1b43d692657ed9d7e599853b3b21b95ae5ae0a777cf9b6ca8", [:rebar], []},
"postgrex": {:hex, :postgrex, "0.12.1", "2f8b46cb3a44dcd42f42938abedbfffe7e103ba4ce810ccbeee8dcf27ca0fb06", [:mix], [{:connection, "~> 1.0", [hex: :connection, optional: false]}, {:db_connection, "~> 1.0-rc.4", [hex: :db_connection, optional: false]}, {:decimal, "~> 1.0", [hex: :decimal, optional: false]}]},
"ranch": {:hex, :ranch, "1.2.1", "a6fb992c10f2187b46ffd17ce398ddf8a54f691b81768f9ef5f461ea7e28c762", [:make], []}}
"postgrex": {:hex, :postgrex, "0.13.3", "c277cfb2a9c5034d445a722494c13359e361d344ef6f25d604c2353185682bfc", [: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"}}
......@@ -22,6 +22,10 @@ msgstr ""
msgid "is invalid"
msgstr ""
## From Ecto.Changeset.validate_acceptance/3
msgid "must be accepted"
msgstr ""
## From Ecto.Changeset.validate_format/3
msgid "has invalid format"
msgstr ""
......@@ -39,10 +43,10 @@ msgid "does not match confirmation"
msgstr ""
## From Ecto.Changeset.no_assoc_constraint/3
msgid "is still associated to this entry"
msgid "is still associated with this entry"
msgstr ""
msgid "are still associated to this entry"
msgid "are still associated with this entry"
msgstr ""
## From Ecto.Changeset.validate_length/3
......
......@@ -20,6 +20,10 @@ msgstr ""
msgid "is invalid"
msgstr ""
## From Ecto.Changeset.validate_acceptance/3
msgid "must be accepted"
msgstr ""
## From Ecto.Changeset.validate_format/3
msgid "has invalid format"
msgstr ""
......@@ -37,10 +41,10 @@ msgid "does not match confirmation"
msgstr ""
## From Ecto.Changeset.no_assoc_constraint/3
msgid "is still associated to this entry"
msgid "is still associated with this entry"
msgstr ""
msgid "are still associated to this entry"
msgid "are still associated with this entry"
msgstr ""
## From Ecto.Changeset.validate_length/3
......
......@@ -5,7 +5,7 @@
# Inside the script, you can read and write to any of your
# repositories directly:
#
# Maldon.Repo.insert!(%Maldon.SomeModel{})
# Maldon.Repo.insert!(%Maldon.SomeSchema{})
#
# We recommend using the bang functions (`insert!`, `update!`
# and so on) as they will fail if something goes wrong.
defmodule Maldon.PageControllerTest do
use Maldon.ConnCase
defmodule MaldonWeb.PageControllerTest do
use MaldonWeb.ConnCase
test "GET /", %{conn: conn} do
conn = get conn, "/"
......
defmodule Maldon.ErrorViewTest do
use Maldon.ConnCase, async: true
defmodule MaldonWeb.ErrorViewTest do
use MaldonWeb.ConnCase, async: true
# Bring render/3 and render_to_string/3 for testing custom views
import Phoenix.View
test "renders 404.html" do
assert render_to_string(Maldon.ErrorView, "404.html", []) ==
assert render_to_string(MaldonWeb.ErrorView, "404.html", []) ==
"Page not found"
end
test "render 500.html" do
assert render_to_string(Maldon.ErrorView, "500.html", []) ==
assert render_to_string(MaldonWeb.ErrorView, "500.html", []) ==
"Internal server error"
end
test "render any other" do
assert render_to_string(Maldon.ErrorView, "505.html", []) ==
assert render_to_string(MaldonWeb.ErrorView, "505.html", []) ==
"Internal server error"
end
end
defmodule MaldonWeb.LayoutViewTest do
use MaldonWeb.ConnCase, async: true
end
defmodule MaldonWeb.PageViewTest do
use MaldonWeb.ConnCase, async: true
end
defmodule Maldon.ChannelCase do
defmodule MaldonWeb.ChannelCase do
@moduledoc """
This module defines the test case to be used by
channel tests.
Such tests rely on `Phoenix.ChannelTest` and also
import other functionality to make it easier
to build and query models.
to build common datastructures and query the data layer.
Finally, if the test case interacts with the database,
it cannot be async. For this reason, every test runs
......@@ -20,24 +20,16 @@ defmodule Maldon.ChannelCase do
# Import conveniences for testing with channels
use Phoenix.ChannelTest
alias Maldon.Repo
import Ecto
import Ecto.Changeset
import Ecto.Query
# The default endpoint for testing
@endpoint Maldon.Endpoint
@endpoint MaldonWeb.Endpoint
end
end
setup tags do
:ok = Ecto.Adapters.SQL.Sandbox.checkout(Maldon.Repo)
unless tags[:async] do
Ecto.Adapters.SQL.Sandbox.mode(Maldon.Repo, {:shared, self()})
end
:ok
end
end
defmodule Maldon.ConnCase do
defmodule MaldonWeb.ConnCase do
@moduledoc """
This module defines the test case to be used by
tests that require setting up a connection.
Such tests rely on `Phoenix.ConnTest` and also
import other functionality to make it easier
to build and query models.
to build common datastructures and query the data layer.
Finally, if the test case interacts with the database,
it cannot be async. For this reason, every test runs
......@@ -20,25 +20,18 @@ defmodule Maldon.ConnCase do
# Import conveniences for testing with connections
use Phoenix.ConnTest
alias Maldon.Repo
import Ecto
import Ecto.Changeset
import Ecto.Query
import Maldon.Router.Helpers
import MaldonWeb.Router.Helpers
# The default endpoint for testing
@endpoint Maldon.Endpoint
@endpoint MaldonWeb.Endpoint
end
end
setup tags do
:ok = Ecto.Adapters.SQL.Sandbox.checkout(Maldon.Repo)
unless tags[:async] do
Ecto.Adapters.SQL.Sandbox.mode(Maldon.Repo, {:shared, self()})
end
{:ok, conn: Phoenix.ConnTest.build_conn()}
end
end
defmodule Maldon.ModelCase do
defmodule Maldon.DataCase do
@moduledoc """
This module defines the test case to be used by
model tests.
This module defines the setup for tests requiring
access to the application's data layer.
You may define functions here to be used as helpers in
your model tests. See `errors_on/2`'s definition as reference.
your tests.
Finally, if the test case interacts with the database,
it cannot be async. For this reason, every test runs
......@@ -21,7 +21,7 @@ defmodule Maldon.ModelCase do
import Ecto
import Ecto.Changeset
import Ecto.Query
import Maldon.ModelCase
import Maldon.DataCase
end
end
......@@ -36,30 +36,18 @@ defmodule Maldon.ModelCase do
end
@doc """
Helper for returning list of errors in a struct when given certain data.
A helper that transform changeset errors to a map of messages.
## Examples
assert {:error, changeset} = Accounts.create_user(%{password: "short"})
assert "password is too short" in errors_on(changeset).password
assert %{password: ["password is too short"]} = errors_on(changeset)
Given a User schema that lists `:name` as a required field and validates
`:password` to be safe, it would return:
iex> errors_on(%User{}, %{password: "password"})
[password: "is unsafe", name: "is blank"]
You could then write your assertion like:
assert {:password, "is unsafe"} in errors_on(%User{}, %{password: "password"})
You can also create the changeset manually and retrieve the errors
field directly:
iex> changeset = User.changeset(%User{}, password: "password")
iex> {:password, "is unsafe"} in changeset.errors
true
"""
def errors_on(struct, data) do
struct.__struct__.changeset(struct, data)
|> Ecto.Changeset.traverse_errors(&Maldon.ErrorHelpers.translate_error/1)
|> Enum.flat_map(fn {key, errors} -> for msg <- errors, do: {key, msg} end)
def errors_on(changeset) do
Ecto.Changeset.traverse_errors(changeset, fn {message, opts} ->
Enum.reduce(opts, message, fn {key, value}, acc ->
String.replace(acc, "%{#{key}}", to_string(value))
end)
end)
end
end
ExUnit.start
ExUnit.start()
Ecto.Adapters.SQL.Sandbox.mode(Maldon.Repo, :manual)
defmodule Maldon.LayoutViewTest do
use Maldon.ConnCase, async: true
end
defmodule Maldon.PageViewTest do
use Maldon.ConnCase, async: true
end
defmodule Maldon.LayoutView do
use Maldon.Web, :view
end
defmodule Maldon.PageView do
use Maldon.Web, :view
end