forked from shibao/cannery
add multiple ammo groups at one time
This commit is contained in:
parent
d79d0fa179
commit
a6b2c6181e
@ -3,6 +3,7 @@
|
|||||||
- Add prompt to create first container before first ammo group
|
- Add prompt to create first container before first ammo group
|
||||||
- Edit and delete shot groups from ammo group show page
|
- Edit and delete shot groups from ammo group show page
|
||||||
- Use today's date when adding new shot groups
|
- Use today's date when adding new shot groups
|
||||||
|
- Create multiple ammo groups at one time
|
||||||
|
|
||||||
# v0.2.3
|
# v0.2.3
|
||||||
- Fix modals with overflowing forms
|
- Fix modals with overflowing forms
|
||||||
|
@ -6,7 +6,9 @@ defmodule Cannery.Ammo do
|
|||||||
import Ecto.Query, warn: false
|
import Ecto.Query, warn: false
|
||||||
alias Cannery.{Accounts.User, Containers, Repo}
|
alias Cannery.{Accounts.User, Containers, Repo}
|
||||||
alias Cannery.Ammo.{AmmoGroup, AmmoType}
|
alias Cannery.Ammo.{AmmoGroup, AmmoType}
|
||||||
alias Ecto.Changeset
|
alias Ecto.{Changeset, Multi}
|
||||||
|
|
||||||
|
@ammo_group_create_limit 10_000
|
||||||
|
|
||||||
@doc """
|
@doc """
|
||||||
Returns the list of ammo_types.
|
Returns the list of ammo_types.
|
||||||
@ -327,36 +329,63 @@ defmodule Cannery.Ammo do
|
|||||||
end
|
end
|
||||||
|
|
||||||
@doc """
|
@doc """
|
||||||
Creates a ammo_group.
|
Creates multiple ammo_groups at once.
|
||||||
|
|
||||||
## Examples
|
## Examples
|
||||||
|
|
||||||
iex> create_ammo_group(%{field: value}, %User{id: 123})
|
iex> create_ammo_groups(%{field: value}, 3, %User{id: 123})
|
||||||
{:ok, %AmmoGroup{}}
|
{:ok, {3, [%AmmoGroup{}]}}
|
||||||
|
|
||||||
iex> create_ammo_group(%{field: bad_value}, %User{id: 123})
|
iex> create_ammo_groups(%{field: bad_value}, 3, %User{id: 123})
|
||||||
{:error, %Changeset{}}
|
{:error, %Changeset{}}
|
||||||
|
|
||||||
"""
|
"""
|
||||||
@spec create_ammo_group(attrs :: map(), User.t()) ::
|
@spec create_ammo_groups(attrs :: map(), multiplier :: non_neg_integer(), User.t()) ::
|
||||||
{:ok, AmmoGroup.t()} | {:error, Changeset.t(AmmoGroup.new_ammo_group())}
|
{:ok, {count :: non_neg_integer(), [AmmoGroup.t()] | nil}}
|
||||||
def create_ammo_group(
|
| {:error, Changeset.t(AmmoGroup.new_ammo_group()) | nil}
|
||||||
|
def create_ammo_groups(
|
||||||
%{"ammo_type_id" => ammo_type_id, "container_id" => container_id} = attrs,
|
%{"ammo_type_id" => ammo_type_id, "container_id" => container_id} = attrs,
|
||||||
|
multiplier,
|
||||||
%User{id: user_id} = user
|
%User{id: user_id} = user
|
||||||
) do
|
)
|
||||||
|
when multiplier >= 1 and multiplier <= @ammo_group_create_limit do
|
||||||
# validate ammo type and container ids belong to user
|
# validate ammo type and container ids belong to user
|
||||||
_valid_ammo_type = get_ammo_type!(ammo_type_id, user)
|
_valid_ammo_type = get_ammo_type!(ammo_type_id, user)
|
||||||
_valid_container = Containers.get_container!(container_id, user)
|
_valid_container = Containers.get_container!(container_id, user)
|
||||||
|
|
||||||
%AmmoGroup{}
|
now = NaiveDateTime.utc_now() |> NaiveDateTime.truncate(:second)
|
||||||
|> AmmoGroup.create_changeset(attrs |> Map.put("user_id", user_id))
|
|
||||||
|> Repo.insert()
|
changesets =
|
||||||
|
Enum.map(1..multiplier, fn _count ->
|
||||||
|
%AmmoGroup{} |> AmmoGroup.create_changeset(attrs |> Map.put("user_id", user_id))
|
||||||
|
end)
|
||||||
|
|
||||||
|
if changesets |> Enum.all?(fn %{valid?: valid} -> valid end) do
|
||||||
|
Multi.new()
|
||||||
|
|> Multi.insert_all(
|
||||||
|
:create_ammo_groups,
|
||||||
|
AmmoGroup,
|
||||||
|
changesets
|
||||||
|
|> Enum.map(fn changeset ->
|
||||||
|
changeset
|
||||||
|
|> Map.get(:changes)
|
||||||
|
|> Map.merge(%{inserted_at: now, updated_at: now})
|
||||||
|
end),
|
||||||
|
returning: true
|
||||||
|
)
|
||||||
|
|> Repo.transaction()
|
||||||
|
|> case do
|
||||||
|
{:ok, %{create_ammo_groups: {count, ammo_groups}}} -> {:ok, {count, ammo_groups}}
|
||||||
|
{:error, :create_ammo_groups, changeset, _changes_so_far} -> {:error, changeset}
|
||||||
|
{:error, _other_transaction, _value, _changes_so_far} -> {:error, nil}
|
||||||
|
end
|
||||||
|
else
|
||||||
|
{:error, changesets |> List.first()}
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def create_ammo_group(invalid_attrs, _user) do
|
def create_ammo_groups(invalid_attrs, _multiplier, _user) do
|
||||||
%AmmoGroup{}
|
{:error, %AmmoGroup{} |> AmmoGroup.create_changeset(invalid_attrs)}
|
||||||
|> AmmoGroup.create_changeset(invalid_attrs |> Map.put("user_id", "-1"))
|
|
||||||
|> Repo.insert()
|
|
||||||
end
|
end
|
||||||
|
|
||||||
@doc """
|
@doc """
|
||||||
|
@ -9,6 +9,8 @@ defmodule CanneryWeb.AmmoGroupLive.FormComponent do
|
|||||||
alias Ecto.Changeset
|
alias Ecto.Changeset
|
||||||
alias Phoenix.LiveView.Socket
|
alias Phoenix.LiveView.Socket
|
||||||
|
|
||||||
|
@ammo_group_create_limit 10_000
|
||||||
|
|
||||||
@impl true
|
@impl true
|
||||||
@spec update(
|
@spec update(
|
||||||
%{:ammo_group => AmmoGroup.t(), :current_user => User.t(), optional(any) => any},
|
%{:ammo_group => AmmoGroup.t(), :current_user => User.t(), optional(any) => any},
|
||||||
@ -22,6 +24,7 @@ defmodule CanneryWeb.AmmoGroupLive.FormComponent do
|
|||||||
def update(%{assigns: %{ammo_group: ammo_group, current_user: current_user}} = socket) do
|
def update(%{assigns: %{ammo_group: ammo_group, current_user: current_user}} = socket) do
|
||||||
socket =
|
socket =
|
||||||
socket
|
socket
|
||||||
|
|> assign(:ammo_group_create_limit, @ammo_group_create_limit)
|
||||||
|> assign(:changeset, Ammo.change_ammo_group(ammo_group))
|
|> assign(:changeset, Ammo.change_ammo_group(ammo_group))
|
||||||
|> assign(:ammo_types, Ammo.list_ammo_types(current_user))
|
|> assign(:ammo_types, Ammo.list_ammo_types(current_user))
|
||||||
|> assign_new(:containers, fn -> Containers.list_containers(current_user) end)
|
|> assign_new(:containers, fn -> Containers.list_containers(current_user) end)
|
||||||
@ -80,20 +83,68 @@ defmodule CanneryWeb.AmmoGroupLive.FormComponent do
|
|||||||
end
|
end
|
||||||
|
|
||||||
defp save_ammo_group(
|
defp save_ammo_group(
|
||||||
%{assigns: %{current_user: current_user, return_to: return_to}} = socket,
|
%{assigns: %{changeset: changeset}} = socket,
|
||||||
:new,
|
:new,
|
||||||
ammo_group_params
|
%{"multiplier" => multiplier_str} = ammo_group_params
|
||||||
) do
|
) do
|
||||||
socket =
|
socket =
|
||||||
case Ammo.create_ammo_group(ammo_group_params, current_user) do
|
case multiplier_str |> Integer.parse() do
|
||||||
{:ok, _ammo_group} ->
|
{multiplier, _remainder}
|
||||||
prompt = dgettext("prompts", "Ammo group created successfully")
|
when multiplier >= 1 and multiplier <= @ammo_group_create_limit ->
|
||||||
socket |> put_flash(:info, prompt) |> push_redirect(to: return_to)
|
socket |> create_multiple(ammo_group_params, multiplier)
|
||||||
|
|
||||||
{:error, %Changeset{} = changeset} ->
|
{multiplier, _remainder} ->
|
||||||
socket |> assign(changeset: changeset)
|
error_msg =
|
||||||
|
dgettext(
|
||||||
|
"errors",
|
||||||
|
"Invalid number of copies, must be between 1 and %{max}. Was %{multiplier}",
|
||||||
|
max: @ammo_group_create_limit,
|
||||||
|
multiplier: multiplier
|
||||||
|
)
|
||||||
|
|
||||||
|
{:error, changeset} =
|
||||||
|
changeset
|
||||||
|
|> Changeset.add_error(:multiplier, error_msg)
|
||||||
|
|> Changeset.apply_action(:insert)
|
||||||
|
|
||||||
|
socket |> assign(:changeset, changeset)
|
||||||
|
|
||||||
|
:error ->
|
||||||
|
error_msg = dgettext("errors", "Could not parse number of copies")
|
||||||
|
|
||||||
|
{:error, changeset} =
|
||||||
|
changeset
|
||||||
|
|> Changeset.add_error(:multiplier, error_msg)
|
||||||
|
|> Changeset.apply_action(:insert)
|
||||||
|
|
||||||
|
socket |> assign(:changeset, changeset)
|
||||||
end
|
end
|
||||||
|
|
||||||
{:noreply, socket}
|
{:noreply, socket}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
defp create_multiple(
|
||||||
|
%{assigns: %{current_user: current_user, return_to: return_to}} = socket,
|
||||||
|
ammo_group_params,
|
||||||
|
multiplier
|
||||||
|
) do
|
||||||
|
case Ammo.create_ammo_groups(ammo_group_params, multiplier, current_user) do
|
||||||
|
{:ok, {count, _ammo_groups}} ->
|
||||||
|
prompt =
|
||||||
|
dngettext(
|
||||||
|
"prompts",
|
||||||
|
"Ammo group created successfully",
|
||||||
|
"Ammo groups created successfully",
|
||||||
|
count
|
||||||
|
)
|
||||||
|
|
||||||
|
socket |> put_flash(:info, prompt) |> push_redirect(to: return_to)
|
||||||
|
|
||||||
|
{:error, %Changeset{} = changeset} ->
|
||||||
|
socket |> assign(changeset: changeset)
|
||||||
|
|
||||||
|
{:error, nil} ->
|
||||||
|
socket
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
@ -33,7 +33,7 @@
|
|||||||
|
|
||||||
<%= label(f, :price_paid, gettext("Price paid"), class: "title text-lg text-primary-600") %>
|
<%= label(f, :price_paid, gettext("Price paid"), class: "title text-lg text-primary-600") %>
|
||||||
<%= number_input(f, :price_paid,
|
<%= number_input(f, :price_paid,
|
||||||
step: "0.01",
|
step: 0.01,
|
||||||
class: "text-center col-span-2 input input-primary"
|
class: "text-center col-span-2 input input-primary"
|
||||||
) %>
|
) %>
|
||||||
<%= error_tag(f, :price_paid, "col-span-3 text-center") %>
|
<%= error_tag(f, :price_paid, "col-span-3 text-center") %>
|
||||||
@ -51,9 +51,29 @@
|
|||||||
) %>
|
) %>
|
||||||
<%= error_tag(f, :container_id, "col-span-3 text-center") %>
|
<%= error_tag(f, :container_id, "col-span-3 text-center") %>
|
||||||
|
|
||||||
|
<%= case @action do %>
|
||||||
|
<% :new -> %>
|
||||||
|
<hr class="hr col-span-3" />
|
||||||
|
|
||||||
|
<%= label(f, :multiplier, gettext("Copies"), class: "title text-lg text-primary-600") %>
|
||||||
|
<%= number_input(f, :multiplier,
|
||||||
|
max: @ammo_group_create_limit,
|
||||||
|
class: "text-center input input-primary",
|
||||||
|
value: 1,
|
||||||
|
phx_update: "ignore"
|
||||||
|
) %>
|
||||||
|
|
||||||
|
<%= submit(dgettext("actions", "Create"),
|
||||||
|
phx_disable_with: dgettext("prompts", "Creating..."),
|
||||||
|
class: "mx-auto btn btn-primary"
|
||||||
|
) %>
|
||||||
|
|
||||||
|
<%= error_tag(f, :multiplier, "col-span-3 text-center") %>
|
||||||
|
<% :edit -> %>
|
||||||
<%= submit(dgettext("actions", "Save"),
|
<%= submit(dgettext("actions", "Save"),
|
||||||
phx_disable_with: dgettext("prompts", "Saving..."),
|
phx_disable_with: dgettext("prompts", "Saving..."),
|
||||||
class: "mx-auto col-span-3 btn btn-primary"
|
class: "mx-auto col-span-3 btn btn-primary"
|
||||||
) %>
|
) %>
|
||||||
|
<% end %>
|
||||||
</.form>
|
</.form>
|
||||||
</div>
|
</div>
|
||||||
|
@ -125,7 +125,7 @@ msgstr ""
|
|||||||
|
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
#: lib/cannery_web/components/add_shot_group_component.html.heex:46
|
#: lib/cannery_web/components/add_shot_group_component.html.heex:46
|
||||||
#: lib/cannery_web/live/ammo_group_live/form_component.html.heex:54
|
#: lib/cannery_web/live/ammo_group_live/form_component.html.heex:73
|
||||||
#: lib/cannery_web/live/ammo_type_live/form_component.html.heex:156
|
#: lib/cannery_web/live/ammo_type_live/form_component.html.heex:156
|
||||||
#: lib/cannery_web/live/container_live/form_component.html.heex:50
|
#: lib/cannery_web/live/container_live/form_component.html.heex:50
|
||||||
#: lib/cannery_web/live/invite_live/form_component.html.heex:28
|
#: lib/cannery_web/live/invite_live/form_component.html.heex:28
|
||||||
@ -196,3 +196,8 @@ msgstr ""
|
|||||||
#: lib/cannery_web/live/ammo_group_live/index.html.heex:36
|
#: lib/cannery_web/live/ammo_group_live/index.html.heex:36
|
||||||
msgid "add a container first"
|
msgid "add a container first"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
#, elixir-autogen, elixir-format
|
||||||
|
#: lib/cannery_web/live/ammo_group_live/form_component.html.heex:66
|
||||||
|
msgid "Create"
|
||||||
|
msgstr ""
|
||||||
|
@ -834,3 +834,8 @@ msgstr ""
|
|||||||
#: lib/cannery_web/live/range_live/index.ex:28
|
#: lib/cannery_web/live/range_live/index.ex:28
|
||||||
msgid "Record Shots"
|
msgid "Record Shots"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
#, elixir-autogen, elixir-format
|
||||||
|
#: lib/cannery_web/live/ammo_group_live/form_component.html.heex:58
|
||||||
|
msgid "Copies"
|
||||||
|
msgstr ""
|
||||||
|
@ -157,3 +157,13 @@ msgstr ""
|
|||||||
#: lib/cannery_web/live/container_live/edit_tags_component.ex:52
|
#: lib/cannery_web/live/container_live/edit_tags_component.ex:52
|
||||||
msgid "Tag could not be removed"
|
msgid "Tag could not be removed"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
#, elixir-autogen, elixir-format
|
||||||
|
#: lib/cannery_web/live/ammo_group_live/form_component.ex:113
|
||||||
|
msgid "Could not parse number of copies"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#, elixir-autogen, elixir-format
|
||||||
|
#: lib/cannery_web/live/ammo_group_live/form_component.ex:98
|
||||||
|
msgid "Invalid number of copies, must be between 1 and %{max}. Was %{multiplier}"
|
||||||
|
msgstr ""
|
||||||
|
@ -61,11 +61,6 @@ msgstr ""
|
|||||||
msgid "A link to confirm your email change has been sent to the new address."
|
msgid "A link to confirm your email change has been sent to the new address."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#, elixir-autogen, elixir-format
|
|
||||||
#: lib/cannery_web/live/ammo_group_live/form_component.ex:90
|
|
||||||
msgid "Ammo group created successfully"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
#: lib/cannery_web/live/ammo_group_live/index.ex:56
|
#: lib/cannery_web/live/ammo_group_live/index.ex:56
|
||||||
#: lib/cannery_web/live/ammo_group_live/show.ex:52
|
#: lib/cannery_web/live/ammo_group_live/show.ex:52
|
||||||
@ -73,7 +68,7 @@ msgid "Ammo group deleted succesfully"
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
#: lib/cannery_web/live/ammo_group_live/form_component.ex:72
|
#: lib/cannery_web/live/ammo_group_live/form_component.ex:75
|
||||||
msgid "Ammo group updated successfully"
|
msgid "Ammo group updated successfully"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
@ -160,7 +155,7 @@ msgstr ""
|
|||||||
|
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
#: lib/cannery_web/components/add_shot_group_component.html.heex:48
|
#: lib/cannery_web/components/add_shot_group_component.html.heex:48
|
||||||
#: lib/cannery_web/live/ammo_group_live/form_component.html.heex:55
|
#: lib/cannery_web/live/ammo_group_live/form_component.html.heex:74
|
||||||
#: lib/cannery_web/live/ammo_type_live/form_component.html.heex:157
|
#: lib/cannery_web/live/ammo_type_live/form_component.html.heex:157
|
||||||
#: lib/cannery_web/live/container_live/form_component.html.heex:52
|
#: lib/cannery_web/live/container_live/form_component.html.heex:52
|
||||||
#: lib/cannery_web/live/invite_live/form_component.html.heex:30
|
#: lib/cannery_web/live/invite_live/form_component.html.heex:30
|
||||||
@ -251,3 +246,15 @@ msgstr ""
|
|||||||
#: lib/cannery_web/live/ammo_group_live/index.html.heex:33
|
#: lib/cannery_web/live/ammo_group_live/index.html.heex:33
|
||||||
msgid "You'll need to"
|
msgid "You'll need to"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
#, elixir-autogen, elixir-format
|
||||||
|
#: lib/cannery_web/live/ammo_group_live/form_component.html.heex:67
|
||||||
|
msgid "Creating..."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#, elixir-autogen, elixir-format
|
||||||
|
#: lib/cannery_web/live/ammo_group_live/form_component.ex:134
|
||||||
|
msgid "Ammo group created successfully"
|
||||||
|
msgid_plural "Ammo groups created successfully"
|
||||||
|
msgstr[0] ""
|
||||||
|
msgstr[1] ""
|
||||||
|
@ -20,8 +20,8 @@ defmodule Cannery.ActivityLogTest do
|
|||||||
container = container_fixture(current_user)
|
container = container_fixture(current_user)
|
||||||
ammo_type = ammo_type_fixture(current_user)
|
ammo_type = ammo_type_fixture(current_user)
|
||||||
|
|
||||||
%{id: ammo_group_id} =
|
{1, [%{id: ammo_group_id} = ammo_group]} =
|
||||||
ammo_group = ammo_group_fixture(%{"count" => 25}, ammo_type, container, current_user)
|
ammo_group_fixture(%{"count" => 25}, ammo_type, container, current_user)
|
||||||
|
|
||||||
shot_group =
|
shot_group =
|
||||||
%{"count" => 5, "date" => ~N[2022-02-13 03:17:00], "notes" => "some notes"}
|
%{"count" => 5, "date" => ~N[2022-02-13 03:17:00], "notes" => "some notes"}
|
||||||
|
@ -108,7 +108,7 @@ defmodule Cannery.AmmoTest do
|
|||||||
current_user = user_fixture()
|
current_user = user_fixture()
|
||||||
ammo_type = ammo_type_fixture(current_user)
|
ammo_type = ammo_type_fixture(current_user)
|
||||||
container = container_fixture(current_user)
|
container = container_fixture(current_user)
|
||||||
ammo_group = ammo_group_fixture(ammo_type, container, current_user)
|
{1, [ammo_group]} = ammo_group_fixture(ammo_type, container, current_user)
|
||||||
|
|
||||||
[
|
[
|
||||||
ammo_type: ammo_type,
|
ammo_type: ammo_type,
|
||||||
@ -129,28 +129,28 @@ defmodule Cannery.AmmoTest do
|
|||||||
ammo_group |> Repo.preload(:shot_groups)
|
ammo_group |> Repo.preload(:shot_groups)
|
||||||
end
|
end
|
||||||
|
|
||||||
test "create_ammo_group/1 with valid data creates a ammo_group",
|
test "create_ammo_groups/3 with valid data creates a ammo_group",
|
||||||
%{
|
%{
|
||||||
ammo_type: ammo_type,
|
ammo_type: ammo_type,
|
||||||
container: container,
|
container: container,
|
||||||
current_user: current_user
|
current_user: current_user
|
||||||
} do
|
} do
|
||||||
assert {:ok, %AmmoGroup{} = ammo_group} =
|
assert {:ok, {1, [%AmmoGroup{} = ammo_group]}} =
|
||||||
@valid_attrs
|
@valid_attrs
|
||||||
|> Map.merge(%{"ammo_type_id" => ammo_type.id, "container_id" => container.id})
|
|> Map.merge(%{"ammo_type_id" => ammo_type.id, "container_id" => container.id})
|
||||||
|> Ammo.create_ammo_group(current_user)
|
|> Ammo.create_ammo_groups(1, current_user)
|
||||||
|
|
||||||
assert ammo_group.count == 42
|
assert ammo_group.count == 42
|
||||||
assert ammo_group.notes == "some notes"
|
assert ammo_group.notes == "some notes"
|
||||||
assert ammo_group.price_paid == 120.5
|
assert ammo_group.price_paid == 120.5
|
||||||
end
|
end
|
||||||
|
|
||||||
test "create_ammo_group/1 with invalid data returns error changeset",
|
test "create_ammo_groups/3 with invalid data returns error changeset",
|
||||||
%{ammo_type: ammo_type, container: container, current_user: current_user} do
|
%{ammo_type: ammo_type, container: container, current_user: current_user} do
|
||||||
assert {:error, %Changeset{}} =
|
assert {:error, %Changeset{}} =
|
||||||
@invalid_attrs
|
@invalid_attrs
|
||||||
|> Map.merge(%{"ammo_type_id" => ammo_type.id, "container_id" => container.id})
|
|> Map.merge(%{"ammo_type_id" => ammo_type.id, "container_id" => container.id})
|
||||||
|> Ammo.create_ammo_group(current_user)
|
|> Ammo.create_ammo_groups(1, current_user)
|
||||||
end
|
end
|
||||||
|
|
||||||
test "update_ammo_group/2 with valid data updates the ammo_group",
|
test "update_ammo_group/2 with valid data updates the ammo_group",
|
||||||
|
@ -6,19 +6,20 @@ defmodule CanneryWeb.AmmoGroupLiveTest do
|
|||||||
use CanneryWeb.ConnCase
|
use CanneryWeb.ConnCase
|
||||||
import Phoenix.LiveViewTest
|
import Phoenix.LiveViewTest
|
||||||
import CanneryWeb.Gettext
|
import CanneryWeb.Gettext
|
||||||
alias Cannery.Repo
|
alias Cannery.{Ammo, Repo}
|
||||||
|
|
||||||
@moduletag :ammo_group_live_test
|
@moduletag :ammo_group_live_test
|
||||||
@shot_group_create_attrs %{"ammo_left" => 5, "notes" => "some notes"}
|
@shot_group_create_attrs %{"ammo_left" => 5, "notes" => "some notes"}
|
||||||
@shot_group_update_attrs %{"count" => 5, "notes" => "some updated notes"}
|
@shot_group_update_attrs %{"count" => 5, "notes" => "some updated notes"}
|
||||||
@create_attrs %{count: 42, notes: "some notes", price_paid: 120.5}
|
@create_attrs %{"count" => 42, "notes" => "some notes", "price_paid" => 120.5}
|
||||||
@update_attrs %{count: 43, notes: "some updated notes", price_paid: 456.7}
|
@update_attrs %{"count" => 43, "notes" => "some updated notes", "price_paid" => 456.7}
|
||||||
|
@ammo_group_create_limit 10_000
|
||||||
# @invalid_attrs %{count: -1, notes: nil, price_paid: nil}
|
# @invalid_attrs %{count: -1, notes: nil, price_paid: nil}
|
||||||
|
|
||||||
defp create_ammo_group(%{current_user: current_user}) do
|
defp create_ammo_group(%{current_user: current_user}) do
|
||||||
ammo_type = ammo_type_fixture(current_user)
|
ammo_type = ammo_type_fixture(current_user)
|
||||||
container = container_fixture(current_user)
|
container = container_fixture(current_user)
|
||||||
ammo_group = ammo_group_fixture(ammo_type, container, current_user)
|
{1, [ammo_group]} = ammo_group_fixture(ammo_type, container, current_user)
|
||||||
|
|
||||||
shot_group =
|
shot_group =
|
||||||
%{"count" => 5, "date" => ~N[2022-02-13 03:17:00], "notes" => "some notes"}
|
%{"count" => 5, "date" => ~N[2022-02-13 03:17:00], "notes" => "some notes"}
|
||||||
@ -38,7 +39,7 @@ defmodule CanneryWeb.AmmoGroupLiveTest do
|
|||||||
assert html =~ ammo_group.ammo_type.name
|
assert html =~ ammo_group.ammo_type.name
|
||||||
end
|
end
|
||||||
|
|
||||||
test "saves new ammo_group", %{conn: conn} do
|
test "saves a single new ammo_group", %{conn: conn} do
|
||||||
{:ok, index_live, _html} = live(conn, Routes.ammo_group_index_path(conn, :index))
|
{:ok, index_live, _html} = live(conn, Routes.ammo_group_index_path(conn, :index))
|
||||||
|
|
||||||
assert index_live |> element("a", dgettext("actions", "New Ammo group")) |> render_click() =~
|
assert index_live |> element("a", dgettext("actions", "New Ammo group")) |> render_click() =~
|
||||||
@ -60,6 +61,68 @@ defmodule CanneryWeb.AmmoGroupLiveTest do
|
|||||||
assert html =~ "42"
|
assert html =~ "42"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
test "saves multiple new ammo_groups", %{conn: conn, current_user: current_user} do
|
||||||
|
multiplier = 25
|
||||||
|
|
||||||
|
{:ok, index_live, _html} = live(conn, Routes.ammo_group_index_path(conn, :index))
|
||||||
|
|
||||||
|
assert index_live |> element("a", dgettext("actions", "New Ammo group")) |> render_click() =~
|
||||||
|
gettext("New Ammo group")
|
||||||
|
|
||||||
|
assert_patch(index_live, Routes.ammo_group_index_path(conn, :new))
|
||||||
|
|
||||||
|
# assert index_live
|
||||||
|
# |> form("#ammo_group-form", ammo_group: @invalid_attrs)
|
||||||
|
# |> render_change() =~ dgettext("errors", "can't be blank")
|
||||||
|
|
||||||
|
{:ok, _, html} =
|
||||||
|
index_live
|
||||||
|
|> form("#ammo_group-form",
|
||||||
|
ammo_group: @create_attrs |> Map.put("multiplier", to_string(multiplier))
|
||||||
|
)
|
||||||
|
|> render_submit()
|
||||||
|
|> follow_redirect(conn, Routes.ammo_group_index_path(conn, :index))
|
||||||
|
|
||||||
|
assert html =~ dgettext("prompts", "Ammo groups created successfully")
|
||||||
|
assert Ammo.list_ammo_groups(current_user) |> Enum.count() == multiplier + 1
|
||||||
|
end
|
||||||
|
|
||||||
|
test "does not save invalid number of new ammo_groups", %{conn: conn} do
|
||||||
|
{:ok, index_live, _html} = live(conn, Routes.ammo_group_index_path(conn, :index))
|
||||||
|
|
||||||
|
assert index_live |> element("a", dgettext("actions", "New Ammo group")) |> render_click() =~
|
||||||
|
gettext("New Ammo group")
|
||||||
|
|
||||||
|
assert_patch(index_live, Routes.ammo_group_index_path(conn, :new))
|
||||||
|
|
||||||
|
# assert index_live
|
||||||
|
# |> form("#ammo_group-form", ammo_group: @invalid_attrs)
|
||||||
|
# |> render_change() =~ dgettext("errors", "can't be blank")
|
||||||
|
|
||||||
|
assert index_live
|
||||||
|
|> form("#ammo_group-form", ammo_group: @create_attrs |> Map.put("multiplier", "0"))
|
||||||
|
|> render_submit() =~
|
||||||
|
dgettext(
|
||||||
|
"errors",
|
||||||
|
"Invalid number of copies, must be between 1 and %{max}. Was %{multiplier}",
|
||||||
|
multiplier: 0,
|
||||||
|
max: @ammo_group_create_limit
|
||||||
|
)
|
||||||
|
|
||||||
|
assert index_live
|
||||||
|
|> form("#ammo_group-form",
|
||||||
|
ammo_group:
|
||||||
|
@create_attrs |> Map.put("multiplier", to_string(@ammo_group_create_limit + 1))
|
||||||
|
)
|
||||||
|
|> render_submit() =~
|
||||||
|
dgettext(
|
||||||
|
"errors",
|
||||||
|
"Invalid number of copies, must be between 1 and %{max}. Was %{multiplier}",
|
||||||
|
multiplier: @ammo_group_create_limit + 1,
|
||||||
|
max: @ammo_group_create_limit
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
test "saves new shot_group", %{conn: conn, ammo_group: ammo_group} do
|
test "saves new shot_group", %{conn: conn, ammo_group: ammo_group} do
|
||||||
{:ok, index_live, _html} = live(conn, Routes.ammo_group_index_path(conn, :index))
|
{:ok, index_live, _html} = live(conn, Routes.ammo_group_index_path(conn, :index))
|
||||||
|
|
||||||
|
@ -16,7 +16,9 @@ defmodule CanneryWeb.RangeLiveTest do
|
|||||||
defp create_shot_group(%{current_user: current_user}) do
|
defp create_shot_group(%{current_user: current_user}) do
|
||||||
container = container_fixture(%{"staged" => true}, current_user)
|
container = container_fixture(%{"staged" => true}, current_user)
|
||||||
ammo_type = ammo_type_fixture(current_user)
|
ammo_type = ammo_type_fixture(current_user)
|
||||||
ammo_group = ammo_group_fixture(%{"staged" => true}, ammo_type, container, current_user)
|
|
||||||
|
{1, [ammo_group]} =
|
||||||
|
ammo_group_fixture(%{"staged" => true}, ammo_type, container, current_user)
|
||||||
|
|
||||||
shot_group =
|
shot_group =
|
||||||
%{"count" => 5, "date" => ~N[2022-02-13 03:17:00], "notes" => "some notes"}
|
%{"count" => 5, "date" => ~N[2022-02-13 03:17:00], "notes" => "some notes"}
|
||||||
|
@ -111,10 +111,20 @@ defmodule Cannery.Fixtures do
|
|||||||
@doc """
|
@doc """
|
||||||
Generate a AmmoGroup
|
Generate a AmmoGroup
|
||||||
"""
|
"""
|
||||||
@spec ammo_group_fixture(AmmoType.t(), Container.t(), User.t()) :: AmmoGroup.t()
|
@spec ammo_group_fixture(AmmoType.t(), Container.t(), User.t()) ::
|
||||||
@spec ammo_group_fixture(attrs :: map(), AmmoType.t(), Container.t(), User.t()) :: AmmoGroup.t()
|
{count :: non_neg_integer(), [AmmoGroup.t()]}
|
||||||
|
@spec ammo_group_fixture(attrs :: map(), AmmoType.t(), Container.t(), User.t()) ::
|
||||||
|
{count :: non_neg_integer(), [AmmoGroup.t()]}
|
||||||
|
@spec ammo_group_fixture(
|
||||||
|
attrs :: map(),
|
||||||
|
multiplier :: non_neg_integer(),
|
||||||
|
AmmoType.t(),
|
||||||
|
Container.t(),
|
||||||
|
User.t()
|
||||||
|
) :: {count :: non_neg_integer(), [AmmoGroup.t()]}
|
||||||
def ammo_group_fixture(
|
def ammo_group_fixture(
|
||||||
attrs \\ %{},
|
attrs \\ %{},
|
||||||
|
multiplier \\ 1,
|
||||||
%AmmoType{id: ammo_type_id},
|
%AmmoType{id: ammo_type_id},
|
||||||
%Container{id: container_id},
|
%Container{id: container_id},
|
||||||
%User{} = user
|
%User{} = user
|
||||||
@ -125,7 +135,7 @@ defmodule Cannery.Fixtures do
|
|||||||
"container_id" => container_id,
|
"container_id" => container_id,
|
||||||
"count" => 20
|
"count" => 20
|
||||||
})
|
})
|
||||||
|> Ammo.create_ammo_group(user)
|
|> Ammo.create_ammo_groups(multiplier, user)
|
||||||
|> unwrap_ok_tuple()
|
|> unwrap_ok_tuple()
|
||||||
end
|
end
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user