-
Notifications
You must be signed in to change notification settings - Fork 2
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Cart in socket #44
base: main
Are you sure you want to change the base?
Cart in socket #44
Changes from 12 commits
09814ac
f5db2d4
0145e70
4c9027d
9ad48f1
04d166b
5ce7e45
8bb60c1
e0af9fe
63bdb46
b91ae5a
4c9d73d
e596313
8466c02
5473e0a
82abdd5
fc93932
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,86 @@ | ||
defmodule ElixirConfAfrica.Cart do | ||
@moduledoc """ | ||
The cart module | ||
""" | ||
|
||
alias ElixirConfAfrica.TicketTypes | ||
|
||
@doc """ | ||
Returns the ids of all the cart items in a list | ||
|
||
|
||
|
||
""" | ||
def cart_list_ids(cart) do | ||
cart |> Enum.map(fn cart_item -> cart_item.id end) | ||
end | ||
|
||
@doc """ | ||
Increases the quantity of a cart item given the cart item and the quantity to increase by | ||
|
||
""" | ||
|
||
def increase_cart_item_quantity(cart_item, quantity) do | ||
cart_item | ||
|> Map.put(:quantity, quantity) | ||
end | ||
|
||
@doc """ | ||
Adds a cart item to the cart given the cart and the cart item id to add | ||
|
||
""" | ||
def add_to_cart(cart, cart_item_id) do | ||
cart_list_ids = cart_list_ids(cart) | ||
|
||
case Enum.member?(cart_list_ids, cart_item_id) do | ||
true -> | ||
ticket_type = Enum.find(cart, fn item -> item.id == cart_item_id end) | ||
updated_cart = get_updated_cart("in-cart", ticket_type, cart) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. you don't need to have a variable here There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thanks , I have made this change |
||
updated_cart | ||
|
||
false -> | ||
ticket_type = TicketTypes.get_ticket_type!(cart_item_id) | ||
updated_cart = get_updated_cart("out-of-cart", ticket_type, cart) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. you don't need this variable. The return value of the function is enough There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thanks , I have fixed this |
||
updated_cart | ||
end | ||
end | ||
|
||
@doc """ | ||
Returns the updated cart for when a cart item already in the cart or out of the cart given the cart item and the cart | ||
|
||
""" | ||
|
||
def get_updated_cart("in-cart", cart_item, cart) do | ||
cart_item_with_added_quantity = | ||
add_quantity_to_cart_item(cart, cart_item, cart_item.quantity + 1) | ||
|
||
cart | ||
|> Enum.filter(fn item -> item.id != cart_item.id end) | ||
|> Enum.concat([cart_item_with_added_quantity]) | ||
end | ||
|
||
def get_updated_cart("out-of-cart", cart_item, cart) do | ||
cart_item_with_default_quantity_of_one = | ||
add_quantity_to_cart_item(cart, cart_item, 1) | ||
|
||
[cart_item_with_default_quantity_of_one | cart] | ||
end | ||
|
||
@doc """ | ||
Returns the cart item with an increased quantity given the cart, the cart item and the quantity to increase by. | ||
It also checks if the cart item is already in the cart and increases the quantity if it is. | ||
|
||
""" | ||
def add_quantity_to_cart_item(cart, cart_item, quantity) do | ||
case cart |> Enum.filter(fn item -> item.id == cart_item.id end) do | ||
[] -> | ||
increase_cart_item_quantity(cart_item, quantity) | ||
|
||
_ -> | ||
cart | ||
|> Enum.filter(fn item -> item.id == cart_item.id end) | ||
|> Enum.map(fn item -> increase_cart_item_quantity(item, item.quantity + 1) end) | ||
|> List.first() | ||
end | ||
end | ||
end |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2,23 +2,45 @@ defmodule ElixirConfAfricaWeb.HomeLive.Index do | |
use ElixirConfAfricaWeb, :live_view | ||
alias ElixirConfAfrica.Events | ||
|
||
alias ElixirConfAfrica.Cart | ||
|
||
def mount(_params, _session, socket) do | ||
# these value are more static and we should find away of display this data to home page | ||
event_name = "ElixirConf Africa #{get_current_year()}" | ||
event_name = "ElixirConf Africa #{get_upcoming_year()}" | ||
|
||
event = | ||
Events.get_event_with_ticket_types_by_event_name(event_name) | ||
|
||
available_ticket = Events.get_total_number_of_available_tickets(event_name) | ||
available_tickets = Events.get_total_number_of_available_tickets(event_name) | ||
|
||
{:ok, | ||
socket | ||
|> assign(:event, event)} | ||
|> assign(available_ticket: available_ticket) | ||
|> assign(:event, event) | ||
|> assign(:cart, []) | ||
|> assign(available_tickets: available_tickets)} | ||
end | ||
|
||
defp get_current_year do | ||
defp get_upcoming_year do | ||
%{year: year} = DateTime.utc_now() | ||
year | ||
year + 1 | ||
end | ||
|
||
def handle_event("add_to_cart", %{"id" => id}, socket) do | ||
cart_item_ids = Cart.cart_list_ids(socket.assigns.cart) | ||
|
||
if Enum.member?(cart_item_ids, String.to_integer(id)) do | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. whats happening here? It seems whether this is true or false the item is still added to the cart and only the flash message is different There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. How @okothkongo suggested we handle this is such that , if there is an item in the cart , and someone adds the same item to the cart , it updates the quantity of that item in the cart and updates the user that the quantity has been added as opposed to disabling the add to cart for an item already in the cart |
||
updated_cart = Cart.add_to_cart(socket.assigns.cart, String.to_integer(id)) | ||
|
||
{:noreply, | ||
socket | ||
|> assign(:cart, updated_cart) | ||
|> put_flash(:info, "Ticket already in cart , quantity increased by 1")} | ||
else | ||
updated_cart = Cart.add_to_cart(socket.assigns.cart, String.to_integer(id)) | ||
|
||
{:noreply, | ||
socket | ||
|> put_flash(:info, "Ticket added to cart") | ||
|> assign(:cart, updated_cart)} | ||
end | ||
end | ||
end |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
defmodule ElixirConfAfrica.CartTest do | ||
use ElixirConfAfrica.DataCase | ||
alias ElixirConfAfrica.Cart | ||
|
||
describe "Cart Functionaity" do | ||
import ElixirConfAfrica.Factory | ||
|
||
setup do | ||
event = insert!(:elixir_conf_event) | ||
ticket_type = insert!(:elixir_conf_ticket_type, event_id: event.id) | ||
|
||
[ticket_type: ticket_type] | ||
end | ||
|
||
test "cart_list_ids/1 returns all ids from the carts in a list" do | ||
assert Cart.cart_list_ids([%{id: 1}, %{id: 2}]) == [1, 2] | ||
end | ||
|
||
test "increase_cart_item_quantity/2 increases the quantity of a cart item" do | ||
assert Cart.increase_cart_item_quantity(%{quantity: 1}, 2) == %{quantity: 2} | ||
end | ||
|
||
test "add quantity to cart_item/3 returns the cart item with an increased quantity " do | ||
assert Cart.add_quantity_to_cart_item([%{id: 1, quantity: 1}], %{id: 1, quantity: 1}, 2) == | ||
%{id: 1, quantity: 2} | ||
|
||
assert Cart.add_quantity_to_cart_item([%{id: 1, quantity: 1}], %{id: 2}, 1) == | ||
%{id: 2, quantity: 1} | ||
end | ||
|
||
test "get_updated_cart/3 returns the updated cart" do | ||
assert Cart.get_updated_cart("in-cart", %{id: 1, quantity: 1}, [%{id: 1, quantity: 1}]) == | ||
[%{id: 1, quantity: 2}] | ||
|
||
assert Cart.get_updated_cart("out-of-cart", %{id: 2}, [%{id: 1, quantity: 1}]) == | ||
[%{id: 2, quantity: 1}, %{id: 1, quantity: 1}] | ||
end | ||
|
||
test "add_to_cart/2 adds an item to the cart", %{ticket_type: ticket_type} do | ||
assert Cart.add_to_cart([%{id: 1, quantity: 1}, %{id: 2, quantity: 1}], 1) == | ||
[%{id: 2, quantity: 1}, %{id: 1, quantity: 2}] | ||
|
||
assert Cart.add_to_cart([%{id: 1, quantity: 1}, %{id: 2, quantity: 1}], ticket_type.id) == | ||
[ | ||
ticket_type |> Map.put(:quantity, 1), | ||
%{id: 1, quantity: 1}, | ||
%{id: 2, quantity: 1} | ||
] | ||
end | ||
end | ||
end |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
defmodule ElixirConfAfricaWeb.HomeLiveTest do | ||
use ElixirConfAfricaWeb.ConnCase | ||
|
||
import Phoenix.LiveViewTest | ||
import ElixirConfAfrica.Factory | ||
|
||
setup do | ||
event = insert!(:elixir_conf_event) | ||
ticket_type = insert!(:elixir_conf_ticket_type, event_id: event.id) | ||
%{ticket_type: ticket_type, event: event} | ||
end | ||
|
||
describe "Home Index" do | ||
test "Displays the elixir conf website details", %{conn: conn, event: event} do | ||
{:ok, _index_live, html} = live(conn, ~p"/home") | ||
|
||
assert html =~ "Event Information" | ||
assert html =~ event.name | ||
assert html =~ event.description | ||
assert html =~ event.location | ||
end | ||
|
||
test "Displays the tickets available", %{conn: conn, ticket_type: ticket_type} do | ||
{:ok, _index_live, html} = live(conn, ~p"/home") | ||
|
||
assert html =~ "Available Tickets" | ||
assert html =~ ticket_type.name | ||
assert html =~ ticket_type.description | ||
end | ||
|
||
test "There is an add to cart button", %{conn: conn} do | ||
{:ok, _index_live, html} = live(conn, ~p"/home") | ||
|
||
assert html =~ "Cart" | ||
end | ||
|
||
test "Clicking the add to cart button on a ticket type that is not in the cart adds it to the cart", | ||
%{conn: conn, ticket_type: ticket_type} do | ||
{:ok, index_live, _html} = live(conn, ~p"/home") | ||
|
||
assert index_live | ||
|> element("#ticket_type-#{ticket_type.id}") | ||
|> render_click() =~ "Ticket added to cart" | ||
end | ||
|
||
test "Clicking the add to cart button on a ticket type that is not in the cart adds a quantity of 1 to the ticket type", | ||
%{conn: conn, ticket_type: ticket_type} do | ||
{:ok, index_live, _html} = live(conn, ~p"/home") | ||
|
||
assert index_live | ||
|> element("#ticket_type-#{ticket_type.id}") | ||
|> render_click() | ||
|
||
assert index_live | ||
|> element("#ticket_type-#{ticket_type.id}") | ||
|> render_click() =~ "Ticket already in cart , quantity increased by 1" | ||
end | ||
end | ||
end |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A Case statement is overkill here. You can just use an if
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
True , since it is either true or false
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You need to introduce styler, it auto corrects such https://github.com/adobe/elixir-styler