migrate from html template to json API template

This commit is contained in:
Tao Bror Bojlén 2019-06-24 13:25:12 +02:00
parent 79378cd9f4
commit 6e58e765aa
No known key found for this signature in database
GPG Key ID: C6EC7AAB905F9E6F
27 changed files with 110 additions and 365 deletions

View File

@ -13,15 +13,10 @@ config :backend,
# Configures the endpoint
config :backend, BackendWeb.Endpoint,
url: [host: "localhost"],
secret_key_base: "sLd5G49YdJ7oecs2f7i5h1FQnR80qkiLikqNIvx5XH3j5XjOcycMHG++n2GEIcFH",
render_errors: [view: BackendWeb.ErrorView, accepts: ~w(html json)],
secret_key_base: "XL4NKGBN9lZMrQbMEI1KJOlwAt8S7younVJl90TdAgzmwyapr3g7BRYSNYvX0sZ9",
render_errors: [view: BackendWeb.ErrorView, accepts: ~w(json)],
pubsub: [name: Backend.PubSub, adapter: Phoenix.PubSub.PG2]
config :backend, Backend.Crawler,
status_age_limit_days: 28,
status_count_limit: 5000,
personal_instance_threshold: 10
# Configures Elixir's Logger
config :logger, :console,
format: "$time $metadata[$level] $message\n",
@ -30,6 +25,11 @@ config :logger, :console,
# Use Jason for JSON parsing in Phoenix
config :phoenix, :json_library, Jason
config :backend, :crawler,
status_age_limit_days: 28,
status_count_limit: 5000,
personal_instance_threshold: 10
# 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"

View File

@ -37,17 +37,6 @@ config :backend, BackendWeb.Endpoint,
# configured to run both http and https servers on
# different ports.
# Watch static and templates for browser reloading.
config :backend, BackendWeb.Endpoint,
live_reload: [
patterns: [
~r"priv/static/.*(js|css|png|jpeg|jpg|gif|svg)$",
~r"priv/gettext/.*(po)$",
~r"lib/backend_web/{live,views}/.*(ex)$",
~r"lib/backend_web/templates/.*(eex)$"
]
]
# Do not include metadata nor timestamps in development logs
config :logger, :console, format: "[$level] $message\n"
@ -61,7 +50,7 @@ config :phoenix, :plug_init_mode, :runtime
# Configure your database
config :backend, Backend.Repo,
username: "postgres",
password: "6SKA0P0YQmWNqt1k4LkkBvqddV2FH04L",
password: "postgres",
database: "backend_dev",
hostname: "localhost",
pool_size: 10

View File

@ -1,104 +0,0 @@
defmodule Backend.Crawler do
@moduledoc """
The Crawler context.
"""
import Ecto.Query, warn: false
alias Backend.Repo
alias Backend.Crawler.Instance
@doc """
Returns the list of instances.
## Examples
iex> list_instances()
[%Instance{}, ...]
"""
def list_instances do
Repo.all(Instance)
end
@doc """
Gets a single instance.
Raises `Ecto.NoResultsError` if the Instance does not exist.
## Examples
iex> get_instance!(123)
%Instance{}
iex> get_instance!(456)
** (Ecto.NoResultsError)
"""
def get_instance!(id), do: Repo.get!(Instance, id)
@doc """
Creates a instance.
## Examples
iex> create_instance(%{field: value})
{:ok, %Instance{}}
iex> create_instance(%{field: bad_value})
{:error, %Ecto.Changeset{}}
"""
def create_instance(attrs \\ %{}) do
%Instance{}
|> Instance.changeset(attrs)
|> Repo.insert()
end
@doc """
Updates a instance.
## Examples
iex> update_instance(instance, %{field: new_value})
{:ok, %Instance{}}
iex> update_instance(instance, %{field: bad_value})
{:error, %Ecto.Changeset{}}
"""
def update_instance(%Instance{} = instance, attrs) do
instance
|> Instance.changeset(attrs)
|> Repo.update()
end
@doc """
Deletes a Instance.
## Examples
iex> delete_instance(instance)
{:ok, %Instance{}}
iex> delete_instance(instance)
{:error, %Ecto.Changeset{}}
"""
def delete_instance(%Instance{} = instance) do
Repo.delete(instance)
end
@doc """
Returns an `%Ecto.Changeset{}` for tracking instance changes.
## Examples
iex> change_instance(instance)
%Ecto.Changeset{source: %Instance{}}
"""
def change_instance(%Instance{} = instance) do
Instance.changeset(instance, %{})
end
end

View File

@ -0,0 +1,28 @@
defmodule Backend.Instance do
use Ecto.Schema
import Ecto.Changeset
schema "instances" do
field :description, :string
field :domain, :string
field :status_count, :integer
field :user_count, :integer
field :version, :string
many_to_many :peers, Backend.Instance,
join_through: "instances_peers",
join_keys: [from_id: :id, to_id: :id]
has_many :outgoing_interactions, Backend.Interaction, foreign_key: "from_instance"
has_many :incoming_interactions, Backend.Interaction, foreign_key: "to_instance"
timestamps()
end
@doc false
def changeset(instance, attrs) do
instance
|> cast(attrs, [:domain, :user_count, :status_count, :description, :version])
|> validate_required([:domain, :user_count, :status_count, :description, :version])
end
end

View File

@ -0,0 +1,19 @@
defmodule Backend.Interaction do
use Ecto.Schema
import Ecto.Changeset
schema "interactions" do
belongs_to :from_instance, Backend.Instance
belongs_to :to_instance, Backend.Instance
field :timestamp, :utc_datetime
timestamps()
end
@doc false
def changeset(interaction, attrs) do
interaction
|> cast(attrs, [])
|> validate_required([])
end
end

View File

@ -1,5 +1,6 @@
defmodule Backend.Repo do
use Ecto.Repo,
otp_app: :backend,
adapter: Ecto.Adapters.Postgres
adapter: Ecto.Adapters.Postgres,
migration_timestamps: [type: :utc_datetime]
end

View File

@ -36,9 +36,6 @@ defmodule BackendWeb do
# Import convenience functions from controllers
import Phoenix.Controller, only: [get_flash: 1, get_flash: 2, view_module: 1]
# Use all HTML functionality (forms, tags, etc)
use Phoenix.HTML
import BackendWeb.ErrorHelpers
import BackendWeb.Gettext
alias BackendWeb.Router.Helpers, as: Routes

View File

@ -1,7 +0,0 @@
defmodule BackendWeb.PageController do
use BackendWeb, :controller
def index(conn, _params) do
render(conn, "index.html")
end
end

View File

@ -18,8 +18,6 @@ defmodule BackendWeb.Endpoint do
# Code reloading can be explicitly enabled under the
# :code_reloader configuration of your endpoint.
if code_reloading? do
socket "/phoenix/live_reload/socket", Phoenix.LiveReloader.Socket
plug Phoenix.LiveReloader
plug Phoenix.CodeReloader
end
@ -40,7 +38,7 @@ defmodule BackendWeb.Endpoint do
plug Plug.Session,
store: :cookie,
key: "_backend_key",
signing_salt: "rLvIuUJN"
signing_salt: "HJa1j4FI"
plug BackendWeb.Router
end

View File

@ -1,26 +1,11 @@
defmodule BackendWeb.Router do
use BackendWeb, :router
pipeline :browser do
plug :accepts, ["html"]
plug :fetch_session
plug :fetch_flash
plug :protect_from_forgery
plug :put_secure_browser_headers
end
pipeline :api do
plug :accepts, ["json"]
end
scope "/", BackendWeb do
pipe_through :browser
get "/", PageController, :index
scope "/api", BackendWeb do
pipe_through :api
end
# Other scopes may use custom stacks.
# scope "/api", BackendWeb do
# pipe_through :api
# end
end

View File

@ -1,30 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=edge"/>
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<title>Backend · Phoenix Framework</title>
<link rel="stylesheet" href="<%= Routes.static_path(@conn, "/css/app.css") %>"/>
</head>
<body>
<header>
<section class="container">
<nav role="navigation">
<ul>
<li><a href="https://hexdocs.pm/phoenix/overview.html">Get Started</a></li>
</ul>
</nav>
<a href="http://phoenixframework.org/" class="phx-logo">
<img src="<%= Routes.static_path(@conn, "/images/phoenix.png") %>" alt="Phoenix Framework Logo"/>
</a>
</section>
</header>
<main role="main" class="container">
<p class="alert alert-info" role="alert"><%= get_flash(@conn, :info) %></p>
<p class="alert alert-danger" role="alert"><%= get_flash(@conn, :error) %></p>
<%= render @view_module, @view_template, assigns %>
</main>
<script type="text/javascript" src="<%= Routes.static_path(@conn, "/js/app.js") %>"></script>
</body>
</html>

View File

@ -1,35 +0,0 @@
<section class="phx-hero">
<h1><%= gettext "Welcome to %{name}!", name: "Phoenix" %></h1>
<p>A productive web framework that<br/>does not compromise speed or maintainability.</p>
</section>
<section class="row">
<article class="column">
<h2>Resources</h2>
<ul>
<li>
<a href="https://hexdocs.pm/phoenix/overview.html">Guides &amp; Docs</a>
</li>
<li>
<a href="https://github.com/phoenixframework/phoenix">Source</a>
</li>
<li>
<a href="https://github.com/phoenixframework/phoenix/blob/v1.4/CHANGELOG.md">v1.4 Changelog</a>
</li>
</ul>
</article>
<article class="column">
<h2>Help</h2>
<ul>
<li>
<a href="https://elixirforum.com/c/phoenix-forum">Forum</a>
</li>
<li>
<a href="https://webchat.freenode.net/?channels=elixir-lang">#elixir-lang on Freenode IRC</a>
</li>
<li>
<a href="https://twitter.com/elixirphoenix">Twitter @elixirphoenix</a>
</li>
</ul>
</article>
</section>

View File

@ -3,17 +3,6 @@ defmodule BackendWeb.ErrorHelpers do
Conveniences for translating and building error messages.
"""
use Phoenix.HTML
@doc """
Generates tag for inlined form input errors.
"""
def error_tag(form, field) do
Enum.map(Keyword.get_values(form.errors, field), fn error ->
content_tag(:span, translate_error(error), class: "help-block")
end)
end
@doc """
Translates an error message using gettext.
"""

View File

@ -3,14 +3,14 @@ defmodule BackendWeb.ErrorView do
# If you want to customize a particular status code
# for a certain format, you may uncomment below.
# def render("500.html", _assigns) do
# "Internal Server Error"
# def render("500.json", _assigns) do
# %{errors: %{detail: "Internal Server Error"}}
# end
# By default, Phoenix returns the status message from
# the template name. For example, "404.html" becomes
# the template name. For example, "404.json" becomes
# "Not Found".
def template_not_found(template, _assigns) do
Phoenix.Controller.status_message_from_template(template)
%{errors: %{detail: Phoenix.Controller.status_message_from_template(template)}}
end
end

View File

@ -1,3 +0,0 @@
defmodule BackendWeb.LayoutView do
use BackendWeb, :view
end

View File

@ -1,3 +0,0 @@
defmodule BackendWeb.PageView do
use BackendWeb, :view
end

View File

@ -38,8 +38,6 @@ defmodule Backend.MixProject do
{:phoenix_ecto, "~> 4.0"},
{:ecto_sql, "~> 3.0"},
{:postgrex, ">= 0.0.0"},
{:phoenix_html, "~> 2.11"},
{:phoenix_live_reload, "~> 1.2", only: :dev},
{:gettext, "~> 0.11"},
{:jason, "~> 1.0"},
{:plug_cowboy, "~> 2.0"},

View File

@ -8,7 +8,6 @@
"decimal": {:hex, :decimal, "1.7.0", "30d6b52c88541f9a66637359ddf85016df9eb266170d53105f02e4a67e00c5aa", [:mix], [], "hexpm"},
"ecto": {:hex, :ecto, "3.1.6", "e890bf66c1d4d8e2b8e010f7cba092a08139b55437bc3382371f72a6ee40757e", [:mix], [{:decimal, "~> 1.6", [hex: :decimal, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}], "hexpm"},
"ecto_sql": {:hex, :ecto_sql, "3.1.5", "b5201fe99fa6bf6a93f64adb2d4976ded3d201f932b7c5bd4c44468642f4fb1f", [:mix], [{:db_connection, "~> 2.0", [hex: :db_connection, repo: "hexpm", optional: false]}, {:ecto, "~> 3.1.0", [hex: :ecto, repo: "hexpm", optional: false]}, {:mariaex, "~> 0.9.1", [hex: :mariaex, repo: "hexpm", optional: true]}, {:myxql, "~> 0.2.0", [hex: :myxql, repo: "hexpm", optional: true]}, {:postgrex, "~> 0.14.0 or ~> 0.15.0", [hex: :postgrex, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm"},
"file_system": {:hex, :file_system, "0.2.7", "e6f7f155970975789f26e77b8b8d8ab084c59844d8ecfaf58cbda31c494d14aa", [:mix], [], "hexpm"},
"gettext": {:hex, :gettext, "0.16.1", "e2130b25eebcbe02bb343b119a07ae2c7e28bd4b146c4a154da2ffb2b3507af2", [:mix], [], "hexpm"},
"hackney": {:hex, :hackney, "1.15.1", "9f8f471c844b8ce395f7b6d8398139e26ddca9ebc171a8b91342ee15a19963f4", [:rebar3], [{:certifi, "2.5.1", [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.1", [hex: :mimerl, repo: "hexpm", optional: false]}, {:ssl_verify_fun, "1.1.4", [hex: :ssl_verify_fun, repo: "hexpm", optional: false]}], "hexpm"},
"httpoison": {:hex, :httpoison, "1.5.1", "0f55b5b673b03c5c327dac7015a67cb571b99b631acc0bc1b0b98dcd6b9f2104", [:mix], [{:hackney, "~> 1.8", [hex: :hackney, repo: "hexpm", optional: false]}], "hexpm"},
@ -20,8 +19,6 @@
"parse_trans": {:hex, :parse_trans, "3.3.0", "09765507a3c7590a784615cfd421d101aec25098d50b89d7aa1d66646bc571c1", [:rebar3], [], "hexpm"},
"phoenix": {:hex, :phoenix, "1.4.8", "c72dc3adeb49c70eb963a0ea24f7a064ec1588e651e84e1b7ad5ed8253c0b4a2", [:mix], [{:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:phoenix_pubsub, "~> 1.1", [hex: :phoenix_pubsub, repo: "hexpm", optional: false]}, {:plug, "~> 1.8.1 or ~> 1.9", [hex: :plug, repo: "hexpm", optional: false]}, {:plug_cowboy, "~> 1.0 or ~> 2.0", [hex: :plug_cowboy, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm"},
"phoenix_ecto": {:hex, :phoenix_ecto, "4.0.0", "c43117a136e7399ea04ecaac73f8f23ee0ffe3e07acfcb8062fe5f4c9f0f6531", [:mix], [{:ecto, "~> 3.0", [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.13.3", "850e292ff6e204257f5f9c4c54a8cb1f6fbc16ed53d360c2b780a3d0ba333867", [:mix], [{:plug, "~> 1.5", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm"},
"phoenix_live_reload": {:hex, :phoenix_live_reload, "1.2.1", "274a4b07c4adbdd7785d45a8b0bb57634d0b4f45b18d2c508b26c0344bd59b8f", [:mix], [{:file_system, "~> 0.2.1 or ~> 0.3", [hex: :file_system, repo: "hexpm", optional: false]}, {:phoenix, "~> 1.4", [hex: :phoenix, repo: "hexpm", optional: false]}], "hexpm"},
"phoenix_pubsub": {:hex, :phoenix_pubsub, "1.1.2", "496c303bdf1b2e98a9d26e89af5bba3ab487ba3a3735f74bf1f4064d2a845a3e", [:mix], [], "hexpm"},
"plug": {:hex, :plug, "1.8.2", "0bcce1daa420f189a6491f3940cc77ea7fb1919761175c9c3b59800d897440fc", [:mix], [{:mime, "~> 1.0", [hex: :mime, repo: "hexpm", optional: false]}, {:plug_crypto, "~> 1.0", [hex: :plug_crypto, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4", [hex: :telemetry, repo: "hexpm", optional: true]}], "hexpm"},
"plug_cowboy": {:hex, :plug_cowboy, "2.0.2", "6055f16868cc4882b24b6e1d63d2bada94fb4978413377a3b32ac16c18dffba2", [:mix], [{:cowboy, "~> 2.5", [hex: :cowboy, repo: "hexpm", optional: false]}, {:plug, "~> 1.7", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm"},

View File

@ -1,15 +0,0 @@
defmodule Backend.Repo.Migrations.CreateInstances do
use Ecto.Migration
def change do
create table(:instances) do
add :domain, :string
add :version, :string
add :num_users, :integer
add :num_statuses, :integer
timestamps()
end
end
end

View File

@ -1,17 +0,0 @@
defmodule Backend.Repo.Migrations.CreateInteractions do
use Ecto.Migration
def change do
create table(:interactions) do
add :type, :string
add :time, :utc_datetime
add :source_id, references(:instances, on_delete: :nothing)
add :target_id, references(:instances, on_delete: :nothing)
timestamps()
end
create index(:interactions, [:source_id])
create index(:interactions, [:target_id])
end
end

View File

@ -0,0 +1,22 @@
defmodule Backend.Repo.Migrations.CreateInstances do
use Ecto.Migration
def change do
create table(:instances) do
add :domain, :string
add :user_count, :integer
add :status_count, :integer
add :description, :string
add :version, :string
timestamps()
end
create table(:instances_peers, primary_key: false) do
add :from_id, references(:instances)
add :to_id, references(:instances)
end
create index(:instances_peers, [:from_id, :to_id])
end
end

View File

@ -0,0 +1,19 @@
defmodule Backend.Repo.Migrations.CreateInteractions do
use Ecto.Migration
def change do
create table(:interactions) do
add :from_instance, references(:instances)
add :to_instance, references(:instances)
add :timestamp, :utc_datetime
timestamps()
end
alter table(:instances) do
add :outgoing_interactions, references(:interactions)
end
create index(:interactions, [:from_instance, :to_instance])
end
end

View File

@ -1,70 +0,0 @@
defmodule Backend.CrawlerTest do
use Backend.DataCase
alias Backend.Crawler
describe "instances" do
alias Backend.Crawler.Instance
@valid_attrs %{domain: "some domain", num_statuses: 42, num_users: 42, version: "some version"}
@update_attrs %{domain: "some updated domain", num_statuses: 43, num_users: 43, version: "some updated version"}
@invalid_attrs %{domain: nil, num_statuses: nil, num_users: nil, version: nil}
def instance_fixture(attrs \\ %{}) do
{:ok, instance} =
attrs
|> Enum.into(@valid_attrs)
|> Crawler.create_instance()
instance
end
test "list_instances/0 returns all instances" do
instance = instance_fixture()
assert Crawler.list_instances() == [instance]
end
test "get_instance!/1 returns the instance with given id" do
instance = instance_fixture()
assert Crawler.get_instance!(instance.id) == instance
end
test "create_instance/1 with valid data creates a instance" do
assert {:ok, %Instance{} = instance} = Crawler.create_instance(@valid_attrs)
assert instance.domain == "some domain"
assert instance.num_statuses == 42
assert instance.num_users == 42
assert instance.version == "some version"
end
test "create_instance/1 with invalid data returns error changeset" do
assert {:error, %Ecto.Changeset{}} = Crawler.create_instance(@invalid_attrs)
end
test "update_instance/2 with valid data updates the instance" do
instance = instance_fixture()
assert {:ok, %Instance{} = instance} = Crawler.update_instance(instance, @update_attrs)
assert instance.domain == "some updated domain"
assert instance.num_statuses == 43
assert instance.num_users == 43
assert instance.version == "some updated version"
end
test "update_instance/2 with invalid data returns error changeset" do
instance = instance_fixture()
assert {:error, %Ecto.Changeset{}} = Crawler.update_instance(instance, @invalid_attrs)
assert instance == Crawler.get_instance!(instance.id)
end
test "delete_instance/1 deletes the instance" do
instance = instance_fixture()
assert {:ok, %Instance{}} = Crawler.delete_instance(instance)
assert_raise Ecto.NoResultsError, fn -> Crawler.get_instance!(instance.id) end
end
test "change_instance/1 returns a instance changeset" do
instance = instance_fixture()
assert %Ecto.Changeset{} = Crawler.change_instance(instance)
end
end
end

View File

@ -1,8 +0,0 @@
defmodule BackendWeb.PageControllerTest do
use BackendWeb.ConnCase
test "GET /", %{conn: conn} do
conn = get(conn, "/")
assert html_response(conn, 200) =~ "Welcome to Phoenix!"
end
end

View File

@ -4,11 +4,12 @@ defmodule BackendWeb.ErrorViewTest do
# Bring render/3 and render_to_string/3 for testing custom views
import Phoenix.View
test "renders 404.html" do
assert render_to_string(BackendWeb.ErrorView, "404.html", []) == "Not Found"
test "renders 404.json" do
assert render(BackendWeb.ErrorView, "404.json", []) == %{errors: %{detail: "Not Found"}}
end
test "renders 500.html" do
assert render_to_string(BackendWeb.ErrorView, "500.html", []) == "Internal Server Error"
test "renders 500.json" do
assert render(BackendWeb.ErrorView, "500.json", []) ==
%{errors: %{detail: "Internal Server Error"}}
end
end

View File

@ -1,3 +0,0 @@
defmodule BackendWeb.LayoutViewTest do
use BackendWeb.ConnCase, async: true
end

View File

@ -1,3 +0,0 @@
defmodule BackendWeb.PageViewTest do
use BackendWeb.ConnCase, async: true
end