Compare commits

...

10 Commits

36 changed files with 893 additions and 191 deletions

View File

@ -22,7 +22,7 @@ config :beet_round_server, BeetRoundServerWeb.Endpoint,
http: [ip: {127, 0, 0, 1}, port: String.to_integer(System.get_env("PORT") || "4000")],
check_origin: false,
code_reloader: true,
debug_errors: true,
debug_errors: false,
secret_key_base: "ha7k0JD3LvWrZgupXaVbXq6SQhvTwc6R/HyqCJIpANEtcSni88QELgaYgvr5I49M",
watchers: [
esbuild: {Esbuild, :install_and_run, [:beet_round_server, ~w(--sourcemap=inline --watch)]},

View File

@ -10,6 +10,19 @@ defmodule BeetRoundServer.Accounts do
## Database getters
@doc """
Returns the list of users.
## Examples
iex> list_users()
[%User{}, ...]
"""
def list_users do
Repo.all(User)
end
@doc """
Gets a user by email.

View File

@ -0,0 +1,147 @@
defmodule BeetRoundServer.Biddings do
@moduledoc """
The Biddings context.
"""
import Ecto.Query, warn: false
alias BeetRoundServer.Repo
alias BeetRoundServer.Biddings.Bidding
alias BeetRoundServer.Accounts.Scope
@doc """
Subscribes to scoped notifications about any bidding changes.
The broadcasted messages match the pattern:
* {:created, %Bidding{}}
* {:updated, %Bidding{}}
* {:deleted, %Bidding{}}
"""
def subscribe_biddings(%Scope{} = scope) do
key = scope.user.id
Phoenix.PubSub.subscribe(BeetRoundServer.PubSub, "user:#{key}:biddings")
end
defp broadcast_bidding(%Scope{} = scope, message) do
key = scope.user.id
Phoenix.PubSub.broadcast(BeetRoundServer.PubSub, "user:#{key}:biddings", message)
end
@doc """
Returns the list of biddings.
## Examples
iex> list_biddings(scope)
[%Bidding{}, ...]
"""
def list_biddings(%Scope{} = scope) do
Repo.all_by(Bidding, user_id: scope.user.id)
end
@doc """
Gets a single bidding.
Raises `Ecto.NoResultsError` if the Bidding does not exist.
## Examples
iex> get_bidding!(scope, 123)
%Bidding{}
iex> get_bidding!(scope, 456)
** (Ecto.NoResultsError)
"""
def get_bidding!(%Scope{} = scope, id) do
Repo.get_by!(Bidding, id: id, user_id: scope.user.id)
end
@doc """
Creates a bidding.
## Examples
iex> create_bidding(scope, %{field: value})
{:ok, %Bidding{}}
iex> create_bidding(scope, %{field: bad_value})
{:error, %Ecto.Changeset{}}
"""
def create_bidding(%Scope{} = scope, attrs) do
with {:ok, bidding = %Bidding{}} <-
%Bidding{}
|> Bidding.changeset(attrs, scope)
|> Repo.insert() do
broadcast_bidding(scope, {:created, bidding})
{:ok, bidding}
end
end
@doc """
Updates a bidding.
## Examples
iex> update_bidding(scope, bidding, %{field: new_value})
{:ok, %Bidding{}}
iex> update_bidding(scope, bidding, %{field: bad_value})
{:error, %Ecto.Changeset{}}
"""
def update_bidding(%Scope{} = scope, %Bidding{} = bidding, attrs) do
true = bidding.user_id == scope.user.id
with {:ok, bidding = %Bidding{}} <-
bidding
|> Bidding.changeset(attrs, scope)
|> Repo.update() do
broadcast_bidding(scope, {:updated, bidding})
{:ok, bidding}
end
end
@doc """
Deletes a bidding.
## Examples
iex> delete_bidding(scope, bidding)
{:ok, %Bidding{}}
iex> delete_bidding(scope, bidding)
{:error, %Ecto.Changeset{}}
"""
def delete_bidding(%Scope{} = scope, %Bidding{} = bidding) do
true = bidding.user_id == scope.user.id
with {:ok, bidding = %Bidding{}} <-
Repo.delete(bidding) do
broadcast_bidding(scope, {:deleted, bidding})
{:ok, bidding}
end
end
@doc """
Returns an `%Ecto.Changeset{}` for tracking bidding changes.
## Examples
iex> change_bidding(scope, bidding)
%Ecto.Changeset{data: %Bidding{}}
"""
def change_bidding(%Scope{} = scope, %Bidding{} = bidding, attrs \\ %{}) do
true = bidding.user_id == scope.user.id
Bidding.changeset(bidding, attrs, scope)
end
end

View File

@ -0,0 +1,24 @@
defmodule BeetRoundServer.Biddings.Bidding do
use Ecto.Schema
import Ecto.Changeset
@primary_key {:id, :binary_id, autogenerate: true}
@foreign_key_type :binary_id
schema "biddings" do
field :bidding_round, :integer
field :amount, :integer
field :depot_wish_one, :string
field :depot_wish_two, :string
field :user_id, :binary_id
timestamps(type: :utc_datetime)
end
@doc false
def changeset(bidding, attrs, user_scope) do
bidding
|> cast(attrs, [:bidding_round, :amount, :depot_wish_one, :depot_wish_two])
|> validate_required([:bidding_round, :amount, :depot_wish_one, :depot_wish_two])
|> put_change(:user_id, user_scope.user.id)
end
end

View File

@ -17,7 +17,9 @@ defmodule BeetRoundServerWeb do
those modules here.
"""
def static_paths, do: ~w(assets fonts images favicon.ico robots.txt)
def static_paths,
do:
~w(assets fonts images favicon.ico apple-touch-icon.png favicon-32x32.png favicon-16x16.png manifest.json robots.txt)
def router do
quote do

View File

@ -35,29 +35,25 @@ defmodule BeetRoundServerWeb.Layouts do
def app(assigns) do
~H"""
<link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png" />
<link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png" />
<link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png" />
<link rel="manifest" href="/manifest.json" />
<header class="navbar px-4 sm:px-6 lg:px-8">
<div class="flex-1">
<a href="/" class="flex-1 flex w-fit items-center gap-2">
<img src={~p"/images/logo.svg"} width="36" />
<span class="text-sm font-semibold">v{Application.spec(:phoenix, :vsn)}</span>
<img src={~p"/images/BeetRound.png"} width="36" />
<span class="text-sm font-semibold">
BeetRound v{Application.spec(:beet_round_server, :vsn)} | Das grüne Zebra
</span>
</a>
</div>
<div class="flex-none">
<ul class="flex flex-column px-1 space-x-4 items-center">
<li>
<a href="https://phoenixframework.org/" class="btn btn-ghost">Website</a>
</li>
<li>
<a href="https://github.com/phoenixframework/phoenix" class="btn btn-ghost">GitHub</a>
</li>
<li>
<.theme_toggle />
</li>
<li>
<a href="https://hexdocs.pm/phoenix/overview.html" class="btn btn-primary">
Get Started <span aria-hidden="true">&rarr;</span>
</a>
</li>
</ul>
</div>
</header>

View File

@ -4,7 +4,7 @@
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="csrf-token" content={get_csrf_token()} />
<.live_title default="BeetRoundServer" suffix=" · Phoenix Framework">
<.live_title default="BeetRound" suffix=" · Das grüne Zebra">
{assigns[:page_title]}
</.live_title>
<link phx-track-static rel="stylesheet" href={~p"/assets/css/app.css"} />

View File

@ -0,0 +1,7 @@
defmodule BeetRoundServerWeb.DefaultApiController do
use BeetRoundServerWeb, :controller
def index(conn, _params) do
text(conn, "The Beet Round API (#{Mix.env()}) is running.")
end
end

View File

@ -1,188 +1,42 @@
<Layouts.flash_group flash={@flash} />
<div class="left-[40rem] fixed inset-y-0 right-0 z-0 hidden lg:block xl:left-[50rem]">
<svg
viewBox="0 0 1480 957"
fill="none"
aria-hidden="true"
class="absolute inset-0 h-full w-full"
preserveAspectRatio="xMinYMid slice"
>
<path fill="#EE7868" d="M0 0h1480v957H0z" />
<path
d="M137.542 466.27c-582.851-48.41-988.806-82.127-1608.412 658.2l67.39 810 3083.15-256.51L1535.94-49.622l-98.36 8.183C1269.29 281.468 734.115 515.799 146.47 467.012l-8.928-.742Z"
fill="#FF9F92"
/>
<path
d="M371.028 528.664C-169.369 304.988-545.754 149.198-1361.45 665.565l-182.58 792.025 3014.73 694.98 389.42-1689.25-96.18-22.171C1505.28 697.438 924.153 757.586 379.305 532.09l-8.277-3.426Z"
fill="#FA8372"
/>
<path
d="M359.326 571.714C-104.765 215.795-428.003-32.102-1349.55 255.554l-282.3 1224.596 3047.04 722.01 312.24-1354.467C1411.25 1028.3 834.355 935.995 366.435 577.166l-7.109-5.452Z"
fill="#E96856"
fill-opacity=".6"
/>
<path
d="M1593.87 1236.88c-352.15 92.63-885.498-145.85-1244.602-613.557l-5.455-7.105C-12.347 152.31-260.41-170.8-1225-131.458l-368.63 1599.048 3057.19 704.76 130.31-935.47Z"
fill="#C42652"
fill-opacity=".2"
/>
<path
d="M1411.91 1526.93c-363.79 15.71-834.312-330.6-1085.883-863.909l-3.822-8.102C72.704 125.95-101.074-242.476-1052.01-408.907l-699.85 1484.267 2837.75 1338.01 326.02-886.44Z"
fill="#A41C42"
fill-opacity=".2"
/>
<path
d="M1116.26 1863.69c-355.457-78.98-720.318-535.27-825.287-1115.521l-1.594-8.816C185.286 163.833 112.786-237.016-762.678-643.898L-1822.83 608.665 571.922 2635.55l544.338-771.86Z"
fill="#A41C42"
fill-opacity=".2"
/>
</svg>
</div>
<div class="px-4 py-10 sm:px-6 sm:py-28 lg:px-8 xl:px-28 xl:py-32">
<div class="mx-auto max-w-xl lg:mx-0">
<svg viewBox="0 0 71 48" class="h-12" aria-hidden="true">
<path
d="m26.371 33.477-.552-.1c-3.92-.729-6.397-3.1-7.57-6.829-.733-2.324.597-4.035 3.035-4.148 1.995-.092 3.362 1.055 4.57 2.39 1.557 1.72 2.984 3.558 4.514 5.305 2.202 2.515 4.797 4.134 8.347 3.634 3.183-.448 5.958-1.725 8.371-3.828.363-.316.761-.592 1.144-.886l-.241-.284c-2.027.63-4.093.841-6.205.735-3.195-.16-6.24-.828-8.964-2.582-2.486-1.601-4.319-3.746-5.19-6.611-.704-2.315.736-3.934 3.135-3.6.948.133 1.746.56 2.463 1.165.583.493 1.143 1.015 1.738 1.493 2.8 2.25 6.712 2.375 10.265-.068-5.842-.026-9.817-3.24-13.308-7.313-1.366-1.594-2.7-3.216-4.095-4.785-2.698-3.036-5.692-5.71-9.79-6.623C12.8-.623 7.745.14 2.893 2.361 1.926 2.804.997 3.319 0 4.149c.494 0 .763.006 1.032 0 2.446-.064 4.28 1.023 5.602 3.024.962 1.457 1.415 3.104 1.761 4.798.513 2.515.247 5.078.544 7.605.761 6.494 4.08 11.026 10.26 13.346 2.267.852 4.591 1.135 7.172.555ZM10.751 3.852c-.976.246-1.756-.148-2.56-.962 1.377-.343 2.592-.476 3.897-.528-.107.848-.607 1.306-1.336 1.49Zm32.002 37.924c-.085-.626-.62-.901-1.04-1.228-1.857-1.446-4.03-1.958-6.333-2-1.375-.026-2.735-.128-4.031-.61-.595-.22-1.26-.505-1.244-1.272.015-.78.693-1 1.31-1.184.505-.15 1.026-.247 1.6-.382-1.46-.936-2.886-1.065-4.787-.3-2.993 1.202-5.943 1.06-8.926-.017-1.684-.608-3.179-1.563-4.735-2.408l-.043.03a2.96 2.96 0 0 0 .04-.029c-.038-.117-.107-.12-.197-.054l.122.107c1.29 2.115 3.034 3.817 5.004 5.271 3.793 2.8 7.936 4.471 12.784 3.73A66.714 66.714 0 0 1 37 40.877c1.98-.16 3.866.398 5.753.899Zm-9.14-30.345c-.105-.076-.206-.266-.42-.069 1.745 2.36 3.985 4.098 6.683 5.193 4.354 1.767 8.773 2.07 13.293.51 3.51-1.21 6.033-.028 7.343 3.38.19-3.955-2.137-6.837-5.843-7.401-2.084-.318-4.01.373-5.962.94-5.434 1.575-10.485.798-15.094-2.553Zm27.085 15.425c.708.059 1.416.123 2.124.185-1.6-1.405-3.55-1.517-5.523-1.404-3.003.17-5.167 1.903-7.14 3.972-1.739 1.824-3.31 3.87-5.903 4.604.043.078.054.117.066.117.35.005.699.021 1.047.005 3.768-.17 7.317-.965 10.14-3.7.89-.86 1.685-1.817 2.544-2.71.716-.746 1.584-1.159 2.645-1.07Zm-8.753-4.67c-2.812.246-5.254 1.409-7.548 2.943-1.766 1.18-3.654 1.738-5.776 1.37-.374-.066-.75-.114-1.124-.17l-.013.156c.135.07.265.151.405.207.354.14.702.308 1.07.395 4.083.971 7.992.474 11.516-1.803 2.221-1.435 4.521-1.707 7.013-1.336.252.038.503.083.756.107.234.022.479.255.795.003-2.179-1.574-4.526-2.096-7.094-1.872Zm-10.049-9.544c1.475.051 2.943-.142 4.486-1.059-.452.04-.643.04-.827.076-2.126.424-4.033-.04-5.733-1.383-.623-.493-1.257-.974-1.889-1.457-2.503-1.914-5.374-2.555-8.514-2.5.05.154.054.26.108.315 3.417 3.455 7.371 5.836 12.369 6.008Zm24.727 17.731c-2.114-2.097-4.952-2.367-7.578-.537 1.738.078 3.043.632 4.101 1.728.374.388.763.768 1.182 1.106 1.6 1.29 4.311 1.352 5.896.155-1.861-.726-1.861-.726-3.601-2.452Zm-21.058 16.06c-1.858-3.46-4.981-4.24-8.59-4.008a9.667 9.667 0 0 1 2.977 1.39c.84.586 1.547 1.311 2.243 2.055 1.38 1.473 3.534 2.376 4.962 2.07-.656-.412-1.238-.848-1.592-1.507Zm17.29-19.32c0-.023.001-.045.003-.068l-.006.006.006-.006-.036-.004.021.018.012.053Zm-20 14.744a7.61 7.61 0 0 0-.072-.041.127.127 0 0 0 .015.043c.005.008.038 0 .058-.002Zm-.072-.041-.008-.034-.008.01.008-.01-.022-.006.005.026.024.014Z"
fill="#FD4F00"
/>
</svg>
<a href="/">
<img src={~p"/images/BeetRound.png"} width="64" />
</a>
<div class="mt-10 flex justify-between items-center">
<h1 class="flex items-center text-sm font-semibold leading-6">
Phoenix Framework
BeetRound
<small class="badge badge-warning badge-sm ml-3">
v{Application.spec(:phoenix, :vsn)}
v{Application.spec(:beet_round_server, :vsn)}
</small>
</h1>
<Layouts.theme_toggle />
</div>
<p class="text-[2rem] mt-4 font-semibold leading-10 tracking-tighter text-balance">
Peace of mind from prototype to production.
Digitales Bieten in einer SoLaWi.
</p>
<p class="mt-4 leading-7 text-base-content/70">
Build rich, interactive web applications quickly, with less code and fewer moving parts. Join our growing community of developers using Phoenix to craft APIs, HTML5 apps and more, for fun or at scale.
Server zum Sammeln der digital abgegeben Gebote.
</p>
<%= if true do %>
<br />
<a
href={~p"/biddings"}
class="group text-brand -mx-2 -my-0.5 inline-flex items-center gap-3 rounded-lg px-2 py-0.5 hover:bg-zinc-50 hover:text-zinc-900"
>
Zu meinen Geboten
</a>
<% end %>
<div class="flex">
<div class="w-full sm:w-auto">
<div class="mt-10 grid grid-cols-1 gap-x-6 gap-y-4 sm:grid-cols-3">
<a
href="https://hexdocs.pm/phoenix/overview.html"
class="group relative rounded-box px-6 py-4 text-sm font-semibold leading-6 sm:py-6"
>
<span class="absolute inset-0 rounded-box bg-base-200 transition group-hover:bg-base-300 sm:group-hover:scale-105">
</span>
<span class="relative flex items-center gap-4 sm:flex-col">
<svg viewBox="0 0 24 24" fill="none" aria-hidden="true" class="h-6 w-6">
<path d="m12 4 10-2v18l-10 2V4Z" fill="currentColor" fill-opacity=".15" />
<path
d="M12 4 2 2v18l10 2m0-18v18m0-18 10-2v18l-10 2"
stroke="currentColor"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
/>
</svg>
Guides &amp; Docs
</span>
</a>
<a
href="https://github.com/phoenixframework/phoenix"
class="group relative rounded-box px-6 py-4 text-sm font-semibold leading-6 sm:py-6"
>
<span class="absolute inset-0 rounded-box bg-base-200 transition group-hover:bg-base-300 sm:group-hover:scale-105">
</span>
<span class="relative flex items-center gap-4 sm:flex-col">
<svg viewBox="0 0 24 24" aria-hidden="true" class="h-6 w-6">
<path
fill="currentColor"
fill-rule="evenodd"
clip-rule="evenodd"
d="M12 0C5.37 0 0 5.506 0 12.303c0 5.445 3.435 10.043 8.205 11.674.6.107.825-.262.825-.585 0-.292-.015-1.261-.015-2.291C6 21.67 5.22 20.346 4.98 19.654c-.135-.354-.72-1.446-1.23-1.738-.42-.23-1.02-.8-.015-.815.945-.015 1.62.892 1.845 1.261 1.08 1.86 2.805 1.338 3.495 1.015.105-.8.42-1.338.765-1.645-2.67-.308-5.46-1.37-5.46-6.075 0-1.338.465-2.446 1.23-3.307-.12-.308-.54-1.569.12-3.26 0 0 1.005-.323 3.3 1.26.96-.276 1.98-.415 3-.415s2.04.139 3 .416c2.295-1.6 3.3-1.261 3.3-1.261.66 1.691.24 2.952.12 3.26.765.861 1.23 1.953 1.23 3.307 0 4.721-2.805 5.767-5.475 6.075.435.384.81 1.122.81 2.276 0 1.645-.015 2.968-.015 3.383 0 .323.225.707.825.585a12.047 12.047 0 0 0 5.919-4.489A12.536 12.536 0 0 0 24 12.304C24 5.505 18.63 0 12 0Z"
/>
</svg>
Source Code
</span>
</a>
<a
href={"https://github.com/phoenixframework/phoenix/blob/v#{Application.spec(:phoenix, :vsn)}/CHANGELOG.md"}
class="group relative rounded-box px-6 py-4 text-sm font-semibold leading-6 sm:py-6"
>
<span class="absolute inset-0 rounded-box bg-base-200 transition group-hover:bg-base-300 sm:group-hover:scale-105">
</span>
<span class="relative flex items-center gap-4 sm:flex-col">
<svg viewBox="0 0 24 24" fill="none" aria-hidden="true" class="h-6 w-6">
<path
d="M12 1v6M12 17v6"
stroke="currentColor"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
/>
<circle
cx="12"
cy="12"
r="4"
fill="currentColor"
fill-opacity=".15"
stroke="currentColor"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
/>
</svg>
Changelog
</span>
</a>
</div>
<div class="mt-10 grid grid-cols-1 gap-y-4 text-sm leading-6 text-base-content/80 sm:grid-cols-2">
<div>
<a
href="https://elixirforum.com"
class="group -mx-2 -my-0.5 inline-flex items-center gap-3 rounded-lg px-2 py-0.5 hover:bg-base-200 hover:text-base-content"
>
<svg
viewBox="0 0 16 16"
aria-hidden="true"
class="h-4 w-4 fill-base-content/40 group-hover:fill-base-content"
>
<path d="M8 13.833c3.866 0 7-2.873 7-6.416C15 3.873 11.866 1 8 1S1 3.873 1 7.417c0 1.081.292 2.1.808 2.995.606 1.05.806 2.399.086 3.375l-.208.283c-.285.386-.01.905.465.85.852-.098 2.048-.318 3.137-.81a3.717 3.717 0 0 1 1.91-.318c.263.027.53.041.802.041Z" />
</svg>
Discuss on the Elixir Forum
</a>
</div>
<div>
<a
href="https://discord.gg/elixir"
class="group -mx-2 -my-0.5 inline-flex items-center gap-3 rounded-lg px-2 py-0.5 hover:bg-base-200 hover:text-base-content"
>
<svg
viewBox="0 0 16 16"
aria-hidden="true"
class="h-4 w-4 fill-base-content/40 group-hover:fill-base-content"
>
<path d="M13.545 2.995c-1.02-.46-2.114-.8-3.257-.994a.05.05 0 0 0-.052.024c-.141.246-.297.567-.406.82a12.377 12.377 0 0 0-3.658 0 8.238 8.238 0 0 0-.412-.82.052.052 0 0 0-.052-.024 13.315 13.315 0 0 0-3.257.994.046.046 0 0 0-.021.018C.356 6.063-.213 9.036.066 11.973c.001.015.01.029.02.038a13.353 13.353 0 0 0 3.996 1.987.052.052 0 0 0 .056-.018c.308-.414.582-.85.818-1.309a.05.05 0 0 0-.028-.069 8.808 8.808 0 0 1-1.248-.585.05.05 0 0 1-.005-.084c.084-.062.168-.126.248-.191a.05.05 0 0 1 .051-.007c2.619 1.176 5.454 1.176 8.041 0a.05.05 0 0 1 .053.006c.08.065.164.13.248.192a.05.05 0 0 1-.004.084c-.399.23-.813.423-1.249.585a.05.05 0 0 0-.027.07c.24.457.514.893.817 1.307a.051.051 0 0 0 .056.019 13.31 13.31 0 0 0 4.001-1.987.05.05 0 0 0 .021-.037c.334-3.396-.559-6.345-2.365-8.96a.04.04 0 0 0-.021-.02Zm-8.198 7.19c-.789 0-1.438-.712-1.438-1.587 0-.874.637-1.586 1.438-1.586.807 0 1.45.718 1.438 1.586 0 .875-.637 1.587-1.438 1.587Zm5.316 0c-.788 0-1.438-.712-1.438-1.587 0-.874.637-1.586 1.438-1.586.807 0 1.45.718 1.438 1.586 0 .875-.63 1.587-1.438 1.587Z" />
</svg>
Join our Discord server
</a>
</div>
<div>
<a
href="https://elixir-slack.community/"
class="group -mx-2 -my-0.5 inline-flex items-center gap-3 rounded-lg px-2 py-0.5 hover:bg-base-200 hover:text-base-content"
>
<svg
viewBox="0 0 16 16"
aria-hidden="true"
class="h-4 w-4 fill-base-content/40 group-hover:fill-base-content"
>
<path d="M3.361 10.11a1.68 1.68 0 1 1-1.68-1.681h1.68v1.682ZM4.209 10.11a1.68 1.68 0 1 1 3.361 0v4.21a1.68 1.68 0 1 1-3.361 0v-4.21ZM5.89 3.361a1.68 1.68 0 1 1 1.681-1.68v1.68H5.89ZM5.89 4.209a1.68 1.68 0 1 1 0 3.361H1.68a1.68 1.68 0 1 1 0-3.361h4.21ZM12.639 5.89a1.68 1.68 0 1 1 1.68 1.681h-1.68V5.89ZM11.791 5.89a1.68 1.68 0 1 1-3.361 0V1.68a1.68 1.68 0 0 1 3.361 0v4.21ZM10.11 12.639a1.68 1.68 0 1 1-1.681 1.68v-1.68h1.682ZM10.11 11.791a1.68 1.68 0 1 1 0-3.361h4.21a1.68 1.68 0 1 1 0 3.361h-4.21Z" />
</svg>
Join us on Slack
</a>
</div>
<div>
<a
href="https://fly.io/docs/elixir/getting-started/"
href="https://working-copy.org/projects/beetround/"
class="group -mx-2 -my-0.5 inline-flex items-center gap-3 rounded-lg px-2 py-0.5 hover:bg-base-200 hover:text-base-content"
>
<svg
@ -192,7 +46,7 @@
>
<path d="M1 12.5A4.5 4.5 0 005.5 17H15a4 4 0 001.866-7.539 3.504 3.504 0 00-4.504-4.272A4.5 4.5 0 004.06 8.235 4.502 4.502 0 001 12.5z" />
</svg>
Deploy your application
by Working-Copy Collective
</a>
</div>
</div>

View File

@ -0,0 +1,43 @@
defmodule BeetRoundServerWeb.UserController do
use BeetRoundServerWeb, :controller
alias BeetRoundServer.Accounts
alias BeetRoundServer.Accounts.User
action_fallback BeetRoundServerWeb.FallbackController
def index(conn, _params) do
users = Accounts.list_users()
render(conn, :index, users: users)
end
def create(conn, %{"user" => user_params}) do
with {:ok, %User{} = user} <- Accounts.register_user(user_params) do
conn
|> put_status(:created)
|> put_resp_header("location", ~p"/api/users/#{user}")
|> render(:show, user: user)
end
end
def show(conn, %{"id" => id}) do
user = Accounts.get_user!(id)
render(conn, :show, user: user)
end
# def update(conn, %{"id" => id, "user" => user_params}) do
# user = Accounts.get_user!(id)
# with {:ok, %User{} = user} <- Accounts.update_user(user, user_params) do
# render(conn, :show, user: user)
# end
# end
# def delete(conn, %{"id" => id}) do
# user = Accounts.get_user!(id)
# with {:ok, %User{}} <- Accounts.delete_user(user) do
# send_resp(conn, :no_content, "")
# end
# end
end

View File

@ -0,0 +1,24 @@
defmodule BeetRoundServerWeb.UserJSON do
alias BeetRoundServer.Accounts.User
@doc """
Renders a list of users.
"""
def index(%{users: users}) do
%{data: for(user <- users, do: data(user))}
end
@doc """
Renders a single user.
"""
def show(%{user: user}) do
%{data: data(user)}
end
defp data(%User{} = user) do
%{
id: user.id,
email: user.email
}
end
end

View File

@ -0,0 +1,101 @@
defmodule BeetRoundServerWeb.BiddingLive.Form do
use BeetRoundServerWeb, :live_view
alias BeetRoundServer.Biddings
alias BeetRoundServer.Biddings.Bidding
@impl true
def render(assigns) do
~H"""
<Layouts.app flash={@flash} current_scope={@current_scope}>
<.header>
{@page_title}
<:subtitle>Use this form to manage bidding records in your database.</:subtitle>
</.header>
<.form for={@form} id="bidding-form" phx-change="validate" phx-submit="save">
<.input field={@form[:bidding_round]} type="number" label="Bidding round" />
<.input field={@form[:amount]} type="number" label="Amount" />
<.input field={@form[:depot_wish_one]} type="text" label="Depot wish one" />
<.input field={@form[:depot_wish_two]} type="text" label="Depot wish two" />
<footer>
<.button phx-disable-with="Saving..." variant="primary">Save Bidding</.button>
<.button navigate={return_path(@current_scope, @return_to, @bidding)}>Cancel</.button>
</footer>
</.form>
</Layouts.app>
"""
end
@impl true
def mount(params, _session, socket) do
{:ok,
socket
|> assign(:return_to, return_to(params["return_to"]))
|> apply_action(socket.assigns.live_action, params)}
end
defp return_to("show"), do: "show"
defp return_to(_), do: "index"
defp apply_action(socket, :edit, %{"id" => id}) do
bidding = Biddings.get_bidding!(socket.assigns.current_scope, id)
socket
|> assign(:page_title, "Edit Bidding")
|> assign(:bidding, bidding)
|> assign(:form, to_form(Biddings.change_bidding(socket.assigns.current_scope, bidding)))
end
defp apply_action(socket, :new, _params) do
bidding = %Bidding{user_id: socket.assigns.current_scope.user.id}
socket
|> assign(:page_title, "New Bidding")
|> assign(:bidding, bidding)
|> assign(:form, to_form(Biddings.change_bidding(socket.assigns.current_scope, bidding)))
end
@impl true
def handle_event("validate", %{"bidding" => bidding_params}, socket) do
changeset = Biddings.change_bidding(socket.assigns.current_scope, socket.assigns.bidding, bidding_params)
{:noreply, assign(socket, form: to_form(changeset, action: :validate))}
end
def handle_event("save", %{"bidding" => bidding_params}, socket) do
save_bidding(socket, socket.assigns.live_action, bidding_params)
end
defp save_bidding(socket, :edit, bidding_params) do
case Biddings.update_bidding(socket.assigns.current_scope, socket.assigns.bidding, bidding_params) do
{:ok, bidding} ->
{:noreply,
socket
|> put_flash(:info, "Bidding updated successfully")
|> push_navigate(
to: return_path(socket.assigns.current_scope, socket.assigns.return_to, bidding)
)}
{:error, %Ecto.Changeset{} = changeset} ->
{:noreply, assign(socket, form: to_form(changeset))}
end
end
defp save_bidding(socket, :new, bidding_params) do
case Biddings.create_bidding(socket.assigns.current_scope, bidding_params) do
{:ok, bidding} ->
{:noreply,
socket
|> put_flash(:info, "Bidding created successfully")
|> push_navigate(
to: return_path(socket.assigns.current_scope, socket.assigns.return_to, bidding)
)}
{:error, %Ecto.Changeset{} = changeset} ->
{:noreply, assign(socket, form: to_form(changeset))}
end
end
defp return_path(_scope, "index", _bidding), do: ~p"/biddings"
defp return_path(_scope, "show", bidding), do: ~p"/biddings/#{bidding}"
end

View File

@ -0,0 +1,76 @@
defmodule BeetRoundServerWeb.BiddingLive.Index do
use BeetRoundServerWeb, :live_view
alias BeetRoundServer.Biddings
@impl true
def render(assigns) do
~H"""
<Layouts.app flash={@flash} current_scope={@current_scope}>
<.header>
Listing Biddings
<:actions>
<.button variant="primary" navigate={~p"/biddings/new"}>
<.icon name="hero-plus" /> New Bidding
</.button>
</:actions>
</.header>
<.table
id="biddings"
rows={@streams.biddings}
row_click={fn {_id, bidding} -> JS.navigate(~p"/biddings/#{bidding}") end}
>
<:col :let={{_id, bidding}} label="Bidding round">{bidding.bidding_round}</:col>
<:col :let={{_id, bidding}} label="Amount">{bidding.amount}</:col>
<:col :let={{_id, bidding}} label="Depot wish one">{bidding.depot_wish_one}</:col>
<:col :let={{_id, bidding}} label="Depot wish two">{bidding.depot_wish_two}</:col>
<:action :let={{_id, bidding}}>
<div class="sr-only">
<.link navigate={~p"/biddings/#{bidding}"}>Show</.link>
</div>
<.link navigate={~p"/biddings/#{bidding}/edit"}>Edit</.link>
</:action>
<:action :let={{id, bidding}}>
<.link
phx-click={JS.push("delete", value: %{id: bidding.id}) |> hide("##{id}")}
data-confirm="Are you sure?"
>
Delete
</.link>
</:action>
</.table>
</Layouts.app>
"""
end
@impl true
def mount(_params, _session, socket) do
if connected?(socket) do
Biddings.subscribe_biddings(socket.assigns.current_scope)
end
{:ok,
socket
|> assign(:page_title, "Listing Biddings")
|> stream(:biddings, list_biddings(socket.assigns.current_scope))}
end
@impl true
def handle_event("delete", %{"id" => id}, socket) do
bidding = Biddings.get_bidding!(socket.assigns.current_scope, id)
{:ok, _} = Biddings.delete_bidding(socket.assigns.current_scope, bidding)
{:noreply, stream_delete(socket, :biddings, bidding)}
end
@impl true
def handle_info({type, %BeetRoundServer.Biddings.Bidding{}}, socket)
when type in [:created, :updated, :deleted] do
{:noreply, stream(socket, :biddings, list_biddings(socket.assigns.current_scope), reset: true)}
end
defp list_biddings(current_scope) do
Biddings.list_biddings(current_scope)
end
end

View File

@ -0,0 +1,67 @@
defmodule BeetRoundServerWeb.BiddingLive.Show do
use BeetRoundServerWeb, :live_view
alias BeetRoundServer.Biddings
@impl true
def render(assigns) do
~H"""
<Layouts.app flash={@flash} current_scope={@current_scope}>
<.header>
Bidding {@bidding.id}
<:subtitle>This is a bidding record from your database.</:subtitle>
<:actions>
<.button navigate={~p"/biddings"}>
<.icon name="hero-arrow-left" />
</.button>
<.button variant="primary" navigate={~p"/biddings/#{@bidding}/edit?return_to=show"}>
<.icon name="hero-pencil-square" /> Edit bidding
</.button>
</:actions>
</.header>
<.list>
<:item title="Bidding round">{@bidding.bidding_round}</:item>
<:item title="Amount">{@bidding.amount}</:item>
<:item title="Depot wish one">{@bidding.depot_wish_one}</:item>
<:item title="Depot wish two">{@bidding.depot_wish_two}</:item>
</.list>
</Layouts.app>
"""
end
@impl true
def mount(%{"id" => id}, _session, socket) do
if connected?(socket) do
Biddings.subscribe_biddings(socket.assigns.current_scope)
end
{:ok,
socket
|> assign(:page_title, "Show Bidding")
|> assign(:bidding, Biddings.get_bidding!(socket.assigns.current_scope, id))}
end
@impl true
def handle_info(
{:updated, %BeetRoundServer.Biddings.Bidding{id: id} = bidding},
%{assigns: %{bidding: %{id: id}}} = socket
) do
{:noreply, assign(socket, :bidding, bidding)}
end
def handle_info(
{:deleted, %BeetRoundServer.Biddings.Bidding{id: id}},
%{assigns: %{bidding: %{id: id}}} = socket
) do
{:noreply,
socket
|> put_flash(:error, "The current bidding was deleted.")
|> push_navigate(to: ~p"/biddings")}
end
def handle_info({type, %BeetRoundServer.Biddings.Bidding{}}, socket)
when type in [:created, :updated, :deleted] do
{:noreply, socket}
end
end

View File

@ -27,7 +27,10 @@ defmodule BeetRoundServerWeb.Router do
scope "/api", BeetRoundServerWeb do
pipe_through :api
get "/", DefaultApiController, :index
resources "/bidding_rounds", BiddingRoundController, except: [:new, :edit]
resources "/users", UserController, except: [:new, :edit]
end
# Enable LiveDashboard and Swoosh mailbox preview in development
@ -56,6 +59,11 @@ defmodule BeetRoundServerWeb.Router do
on_mount: [{BeetRoundServerWeb.UserAuth, :require_authenticated}] do
live "/users/settings", UserLive.Settings, :edit
live "/users/settings/confirm-email/:token", UserLive.Settings, :confirm_email
live "/biddings", BiddingLive.Index, :index
live "/biddings/new", BiddingLive.Form, :new
live "/biddings/:id", BiddingLive.Show, :show
live "/biddings/:id/edit", BiddingLive.Form, :edit
end
post "/users/update-password", UserSessionController, :update_password

View File

@ -262,7 +262,7 @@ defmodule BeetRoundServerWeb.UserAuth do
~p"/users/settings"
end
def signed_in_path(_), do: ~p"/"
def signed_in_path(_), do: ~p"/biddings"
@doc """
Plug for routes that require the user to be authenticated.

View File

@ -0,0 +1,18 @@
defmodule BeetRoundServer.Repo.Migrations.CreateBiddings do
use Ecto.Migration
def change do
create table(:biddings, primary_key: false) do
add :id, :binary_id, primary_key: true
add :bidding_round, :integer
add :amount, :integer
add :depot_wish_one, :string
add :depot_wish_two, :string
add :user_id, references(:users, type: :binary_id, on_delete: :delete_all)
timestamps(type: :utc_datetime)
end
create index(:biddings, [:user_id])
end
end

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 42 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 791 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 152 B

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 35 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 42 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 791 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

View File

@ -1,6 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 71 48" fill="currentColor" aria-hidden="true">
<path
d="m26.371 33.477-.552-.1c-3.92-.729-6.397-3.1-7.57-6.829-.733-2.324.597-4.035 3.035-4.148 1.995-.092 3.362 1.055 4.57 2.39 1.557 1.72 2.984 3.558 4.514 5.305 2.202 2.515 4.797 4.134 8.347 3.634 3.183-.448 5.958-1.725 8.371-3.828.363-.316.761-.592 1.144-.886l-.241-.284c-2.027.63-4.093.841-6.205.735-3.195-.16-6.24-.828-8.964-2.582-2.486-1.601-4.319-3.746-5.19-6.611-.704-2.315.736-3.934 3.135-3.6.948.133 1.746.56 2.463 1.165.583.493 1.143 1.015 1.738 1.493 2.8 2.25 6.712 2.375 10.265-.068-5.842-.026-9.817-3.24-13.308-7.313-1.366-1.594-2.7-3.216-4.095-4.785-2.698-3.036-5.692-5.71-9.79-6.623C12.8-.623 7.745.14 2.893 2.361 1.926 2.804.997 3.319 0 4.149c.494 0 .763.006 1.032 0 2.446-.064 4.28 1.023 5.602 3.024.962 1.457 1.415 3.104 1.761 4.798.513 2.515.247 5.078.544 7.605.761 6.494 4.08 11.026 10.26 13.346 2.267.852 4.591 1.135 7.172.555ZM10.751 3.852c-.976.246-1.756-.148-2.56-.962 1.377-.343 2.592-.476 3.897-.528-.107.848-.607 1.306-1.336 1.49Zm32.002 37.924c-.085-.626-.62-.901-1.04-1.228-1.857-1.446-4.03-1.958-6.333-2-1.375-.026-2.735-.128-4.031-.61-.595-.22-1.26-.505-1.244-1.272.015-.78.693-1 1.31-1.184.505-.15 1.026-.247 1.6-.382-1.46-.936-2.886-1.065-4.787-.3-2.993 1.202-5.943 1.06-8.926-.017-1.684-.608-3.179-1.563-4.735-2.408l-.077.057c1.29 2.115 3.034 3.817 5.004 5.271 3.793 2.8 7.936 4.471 12.784 3.73A66.714 66.714 0 0 1 37 40.877c1.98-.16 3.866.398 5.753.899Zm-9.14-30.345c-.105-.076-.206-.266-.42-.069 1.745 2.36 3.985 4.098 6.683 5.193 4.354 1.767 8.773 2.07 13.293.51 3.51-1.21 6.033-.028 7.343 3.38.19-3.955-2.137-6.837-5.843-7.401-2.084-.318-4.01.373-5.962.94-5.434 1.575-10.485.798-15.094-2.553Zm27.085 15.425c.708.059 1.416.123 2.124.185-1.6-1.405-3.55-1.517-5.523-1.404-3.003.17-5.167 1.903-7.14 3.972-1.739 1.824-3.31 3.87-5.903 4.604.043.078.054.117.066.117.35.005.699.021 1.047.005 3.768-.17 7.317-.965 10.14-3.7.89-.86 1.685-1.817 2.544-2.71.716-.746 1.584-1.159 2.645-1.07Zm-8.753-4.67c-2.812.246-5.254 1.409-7.548 2.943-1.766 1.18-3.654 1.738-5.776 1.37-.374-.066-.75-.114-1.124-.17l-.013.156c.135.07.265.151.405.207.354.14.702.308 1.07.395 4.083.971 7.992.474 11.516-1.803 2.221-1.435 4.521-1.707 7.013-1.336.252.038.503.083.756.107.234.022.479.255.795.003-2.179-1.574-4.526-2.096-7.094-1.872Zm-10.049-9.544c1.475.051 2.943-.142 4.486-1.059-.452.04-.643.04-.827.076-2.126.424-4.033-.04-5.733-1.383-.623-.493-1.257-.974-1.889-1.457-2.503-1.914-5.374-2.555-8.514-2.5.05.154.054.26.108.315 3.417 3.455 7.371 5.836 12.369 6.008Zm24.727 17.731c-2.114-2.097-4.952-2.367-7.578-.537 1.738.078 3.043.632 4.101 1.728a13 13 0 0 0 1.182 1.106c1.6 1.29 4.311 1.352 5.896.155-1.861-.726-1.861-.726-3.601-2.452Zm-21.058 16.06c-1.858-3.46-4.981-4.24-8.59-4.008a9.667 9.667 0 0 1 2.977 1.39c.84.586 1.547 1.311 2.243 2.055 1.38 1.473 3.534 2.376 4.962 2.07-.656-.412-1.238-.848-1.592-1.507Zl-.006.006-.036-.004.021.018.012.053Za.127.127 0 0 0 .015.043c.005.008.038 0 .058-.002Zl-.008.01.005.026.024.014Z"
fill="#FD4F00"
/>
</svg>

Before

Width:  |  Height:  |  Size: 3.0 KiB

View File

@ -1,5 +1,5 @@
# See https://www.robotstxt.org/robotstxt.html for documentation on how to use the robots.txt file
#
# To ban all spiders from the entire site uncomment the next two lines:
# User-agent: *
# Disallow: /
User-agent: *
Disallow: /

View File

@ -0,0 +1,97 @@
defmodule BeetRoundServer.BiddingsTest do
use BeetRoundServer.DataCase
alias BeetRoundServer.Biddings
describe "biddings" do
alias BeetRoundServer.Biddings.Bidding
import BeetRoundServer.AccountsFixtures, only: [user_scope_fixture: 0]
import BeetRoundServer.BiddingsFixtures
@invalid_attrs %{amount: nil, bidding_round: nil, depot_wish_one: nil, depot_wish_two: nil}
test "list_biddings/1 returns all scoped biddings" do
scope = user_scope_fixture()
other_scope = user_scope_fixture()
bidding = bidding_fixture(scope)
other_bidding = bidding_fixture(other_scope)
assert Biddings.list_biddings(scope) == [bidding]
assert Biddings.list_biddings(other_scope) == [other_bidding]
end
test "get_bidding!/2 returns the bidding with given id" do
scope = user_scope_fixture()
bidding = bidding_fixture(scope)
other_scope = user_scope_fixture()
assert Biddings.get_bidding!(scope, bidding.id) == bidding
assert_raise Ecto.NoResultsError, fn -> Biddings.get_bidding!(other_scope, bidding.id) end
end
test "create_bidding/2 with valid data creates a bidding" do
valid_attrs = %{amount: 42, bidding_round: 42, depot_wish_one: "some depot_wish_one", depot_wish_two: "some depot_wish_two"}
scope = user_scope_fixture()
assert {:ok, %Bidding{} = bidding} = Biddings.create_bidding(scope, valid_attrs)
assert bidding.amount == 42
assert bidding.bidding_round == 42
assert bidding.depot_wish_one == "some depot_wish_one"
assert bidding.depot_wish_two == "some depot_wish_two"
assert bidding.user_id == scope.user.id
end
test "create_bidding/2 with invalid data returns error changeset" do
scope = user_scope_fixture()
assert {:error, %Ecto.Changeset{}} = Biddings.create_bidding(scope, @invalid_attrs)
end
test "update_bidding/3 with valid data updates the bidding" do
scope = user_scope_fixture()
bidding = bidding_fixture(scope)
update_attrs = %{amount: 43, bidding_round: 43, depot_wish_one: "some updated depot_wish_one", depot_wish_two: "some updated depot_wish_two"}
assert {:ok, %Bidding{} = bidding} = Biddings.update_bidding(scope, bidding, update_attrs)
assert bidding.amount == 43
assert bidding.bidding_round == 43
assert bidding.depot_wish_one == "some updated depot_wish_one"
assert bidding.depot_wish_two == "some updated depot_wish_two"
end
test "update_bidding/3 with invalid scope raises" do
scope = user_scope_fixture()
other_scope = user_scope_fixture()
bidding = bidding_fixture(scope)
assert_raise MatchError, fn ->
Biddings.update_bidding(other_scope, bidding, %{})
end
end
test "update_bidding/3 with invalid data returns error changeset" do
scope = user_scope_fixture()
bidding = bidding_fixture(scope)
assert {:error, %Ecto.Changeset{}} = Biddings.update_bidding(scope, bidding, @invalid_attrs)
assert bidding == Biddings.get_bidding!(scope, bidding.id)
end
test "delete_bidding/2 deletes the bidding" do
scope = user_scope_fixture()
bidding = bidding_fixture(scope)
assert {:ok, %Bidding{}} = Biddings.delete_bidding(scope, bidding)
assert_raise Ecto.NoResultsError, fn -> Biddings.get_bidding!(scope, bidding.id) end
end
test "delete_bidding/2 with invalid scope raises" do
scope = user_scope_fixture()
other_scope = user_scope_fixture()
bidding = bidding_fixture(scope)
assert_raise MatchError, fn -> Biddings.delete_bidding(other_scope, bidding) end
end
test "change_bidding/2 returns a bidding changeset" do
scope = user_scope_fixture()
bidding = bidding_fixture(scope)
assert %Ecto.Changeset{} = Biddings.change_bidding(scope, bidding)
end
end
end

View File

@ -0,0 +1,84 @@
defmodule BeetRoundServerWeb.UserControllerTest do
use BeetRoundServerWeb.ConnCase
import BeetRoundServer.AccountsFixtures
alias BeetRoundServer.Accounts.User
@create_attrs %{
email: "some email"
}
@update_attrs %{
email: "some updated email"
}
@invalid_attrs %{email: nil}
setup %{conn: conn} do
{:ok, conn: put_req_header(conn, "accept", "application/json")}
end
describe "index" do
test "lists all users", %{conn: conn} do
conn = get(conn, ~p"/api/users")
assert json_response(conn, 200)["data"] == []
end
end
describe "create user" do
test "renders user when data is valid", %{conn: conn} do
conn = post(conn, ~p"/api/users", user: @create_attrs)
assert %{"id" => id} = json_response(conn, 201)["data"]
conn = get(conn, ~p"/api/users/#{id}")
assert %{
"id" => ^id,
"email" => "some email"
} = json_response(conn, 200)["data"]
end
test "renders errors when data is invalid", %{conn: conn} do
conn = post(conn, ~p"/api/users", user: @invalid_attrs)
assert json_response(conn, 422)["errors"] != %{}
end
end
describe "update user" do
setup [:create_user]
test "renders user when data is valid", %{conn: conn, user: %User{id: id} = user} do
conn = put(conn, ~p"/api/users/#{user}", user: @update_attrs)
assert %{"id" => ^id} = json_response(conn, 200)["data"]
conn = get(conn, ~p"/api/users/#{id}")
assert %{
"id" => ^id,
"email" => "some updated email"
} = json_response(conn, 200)["data"]
end
test "renders errors when data is invalid", %{conn: conn, user: user} do
conn = put(conn, ~p"/api/users/#{user}", user: @invalid_attrs)
assert json_response(conn, 422)["errors"] != %{}
end
end
describe "delete user" do
setup [:create_user]
test "deletes chosen user", %{conn: conn, user: user} do
conn = delete(conn, ~p"/api/users/#{user}")
assert response(conn, 204)
assert_error_sent 404, fn ->
get(conn, ~p"/api/users/#{user}")
end
end
end
defp create_user(_) do
user = user_fixture()
%{user: user}
end
end

View File

@ -0,0 +1,125 @@
defmodule BeetRoundServerWeb.BiddingLiveTest do
use BeetRoundServerWeb.ConnCase
import Phoenix.LiveViewTest
import BeetRoundServer.BiddingsFixtures
@create_attrs %{amount: 42, bidding_round: 42, depot_wish_one: "some depot_wish_one", depot_wish_two: "some depot_wish_two"}
@update_attrs %{amount: 43, bidding_round: 43, depot_wish_one: "some updated depot_wish_one", depot_wish_two: "some updated depot_wish_two"}
@invalid_attrs %{amount: nil, bidding_round: nil, depot_wish_one: nil, depot_wish_two: nil}
setup :register_and_log_in_user
defp create_bidding(%{scope: scope}) do
bidding = bidding_fixture(scope)
%{bidding: bidding}
end
describe "Index" do
setup [:create_bidding]
test "lists all biddings", %{conn: conn, bidding: bidding} do
{:ok, _index_live, html} = live(conn, ~p"/biddings")
assert html =~ "Listing Biddings"
assert html =~ bidding.depot_wish_one
end
test "saves new bidding", %{conn: conn} do
{:ok, index_live, _html} = live(conn, ~p"/biddings")
assert {:ok, form_live, _} =
index_live
|> element("a", "New Bidding")
|> render_click()
|> follow_redirect(conn, ~p"/biddings/new")
assert render(form_live) =~ "New Bidding"
assert form_live
|> form("#bidding-form", bidding: @invalid_attrs)
|> render_change() =~ "can&#39;t be blank"
assert {:ok, index_live, _html} =
form_live
|> form("#bidding-form", bidding: @create_attrs)
|> render_submit()
|> follow_redirect(conn, ~p"/biddings")
html = render(index_live)
assert html =~ "Bidding created successfully"
assert html =~ "some depot_wish_one"
end
test "updates bidding in listing", %{conn: conn, bidding: bidding} do
{:ok, index_live, _html} = live(conn, ~p"/biddings")
assert {:ok, form_live, _html} =
index_live
|> element("#biddings-#{bidding.id} a", "Edit")
|> render_click()
|> follow_redirect(conn, ~p"/biddings/#{bidding}/edit")
assert render(form_live) =~ "Edit Bidding"
assert form_live
|> form("#bidding-form", bidding: @invalid_attrs)
|> render_change() =~ "can&#39;t be blank"
assert {:ok, index_live, _html} =
form_live
|> form("#bidding-form", bidding: @update_attrs)
|> render_submit()
|> follow_redirect(conn, ~p"/biddings")
html = render(index_live)
assert html =~ "Bidding updated successfully"
assert html =~ "some updated depot_wish_one"
end
test "deletes bidding in listing", %{conn: conn, bidding: bidding} do
{:ok, index_live, _html} = live(conn, ~p"/biddings")
assert index_live |> element("#biddings-#{bidding.id} a", "Delete") |> render_click()
refute has_element?(index_live, "#biddings-#{bidding.id}")
end
end
describe "Show" do
setup [:create_bidding]
test "displays bidding", %{conn: conn, bidding: bidding} do
{:ok, _show_live, html} = live(conn, ~p"/biddings/#{bidding}")
assert html =~ "Show Bidding"
assert html =~ bidding.depot_wish_one
end
test "updates bidding and returns to show", %{conn: conn, bidding: bidding} do
{:ok, show_live, _html} = live(conn, ~p"/biddings/#{bidding}")
assert {:ok, form_live, _} =
show_live
|> element("a", "Edit")
|> render_click()
|> follow_redirect(conn, ~p"/biddings/#{bidding}/edit?return_to=show")
assert render(form_live) =~ "Edit Bidding"
assert form_live
|> form("#bidding-form", bidding: @invalid_attrs)
|> render_change() =~ "can&#39;t be blank"
assert {:ok, show_live, _html} =
form_live
|> form("#bidding-form", bidding: @update_attrs)
|> render_submit()
|> follow_redirect(conn, ~p"/biddings/#{bidding}")
html = render(show_live)
assert html =~ "Bidding updated successfully"
assert html =~ "some updated depot_wish_one"
end
end
end

View File

@ -0,0 +1,22 @@
defmodule BeetRoundServer.BiddingsFixtures do
@moduledoc """
This module defines test helpers for creating
entities via the `BeetRoundServer.Biddings` context.
"""
@doc """
Generate a bidding.
"""
def bidding_fixture(scope, attrs \\ %{}) do
attrs =
Enum.into(attrs, %{
amount: 42,
bidding_round: 42,
depot_wish_one: "some depot_wish_one",
depot_wish_two: "some depot_wish_two"
})
{:ok, bidding} = BeetRoundServer.Biddings.create_bidding(scope, attrs)
bidding
end
end