def test_delete_basket_item_user_authenticated(self):

        User = get_user_model()
        user = User.objects.get(username='******')
        logged_in = self.client.login(username='******', password='******')
        basket = Basket.objects.create(owner=user)
        product = Product.objects.get(name="test_product")
        basket_item = BasketItem(basket=basket, product=product, quantity=1)
        basket_item.save()
        response = self.client.get(f"/basket/delete/{basket_item.id}")

        self.assertFalse(BasketItem.objects.filter(id=basket_item.id).exists())
    def test_adjust_quantity_user_authenticated_same_quantity(self):

        User = get_user_model()
        user = User.objects.get(username='******')
        logged_in = self.client.login(username='******', password='******')
        basket = Basket.objects.create(owner=user)
        product = Product.objects.get(name="test_product")
        basket_item = BasketItem(basket=basket, product=product, quantity=2)
        basket_item.save()
        response = self.client.post("/basket/adjust", {
            "quantity": "2",
            "item_id": basket_item.id
        })

        self.assertRedirects(response, "/basket/")
 def test_add_product_already_in_basket_as_authenticated_user(self):
     User = get_user_model()
     user = User.objects.get(username='******')
     logged_in = self.client.login(username='******', password='******')
     basket = Basket.objects.create(owner=user)
     product = Product.objects.get(name="test_product")
     basket_item = BasketItem(basket=basket, product=product, quantity=1)
     basket_item.save()
     response = self.client.post(
         f"/basket/add/{ product.id }", {
             "redirect_url": f"/products/{ product.id }",
             "has_colours": "False",
             "quantity": "1",
         })
     added_item = BasketItem.objects.get(id=basket_item.id)
     self.assertEqual(added_item.quantity, 2)
 def test_basket_item_deleted_when_basket_deleted(self):
     user = get_user_model().objects.create_user(username='******', email='*****@*****.**', password='******')
     basket = Basket(owner = user)
     basket.save()
     colour = Colour(hex_value = '#ffffff', name = "white", season = "summer")
     colour.save()
     category = Category(name = "test_category", display_name = "Test Category")
     category.save()
     brand = Brand(name = "test_brand", display_name = "Test Brand")
     brand.save()
     product = Product(brand = brand, name = "test name", price = 5.00, image_link = 'www.test.com', description = "test desc")
     product.save()
     product.category.add(category)
     product.product_colors.add(colour)
     item = BasketItem(basket = basket, product = product, quantity = 1, colour = colour)
     item.save()
     basket.delete()
     self.assertFalse(BasketItem.objects.filter(basket = basket).exists())
    def test_redirect_to_add_to_wishlist_if_add_to_wishlist_button_clicked(
            self):

        User = get_user_model()
        user = User.objects.get(username='******')
        logged_in = self.client.login(username='******', password='******')
        basket = Basket.objects.create(owner=user)
        product = Product.objects.get(name="test_product")
        basket_item = BasketItem(basket=basket, product=product, quantity=1)
        basket_item.save()
        response = self.client.post(
            f"/basket/add/{ product.id }", {
                "redirect_url": f"/products/{ product.id }",
                "has_colours": "False",
                "quantity": "1",
                "wishlist": "Add to wishlist"
            })
        self.assertRedirects(response,
                             f"/wishlist/add/{ product.id }",
                             fetch_redirect_response=False)
def add_to_basket(request, product_id):
    ''' add item to the basket, if user is logged in, save it in the database, otherwise save it in session '''

    product = get_object_or_404(Product, pk=product_id)
    all_colours = product.product_colors.all()
    redirect_url = request.POST.get('redirect_url')
    colour = request.POST.get('colour')
    colour_obj = None
    colour_name = 'clear or standard'
    colour_id = None

    # if product has colour, get it
    if Colour.objects.filter(hex_value=colour).exists():
        colour_obj = Colour.objects.get(hex_value=colour)
        colour_name = colour_obj.name
        colour_id = colour_obj.id

    # if 'add to wishlist' button was clicked, redirect to add_to_wishlist view
    if 'wishlist' in request.POST:
        request.session['redirect_url'] = redirect_url
        request.session['colour'] = colour
        return redirect(reverse('add_to_wishlist', args=[product_id]))
    else:

        # validate if colour should have been chosen for the product or not
        # and if the colour value is correct
        if request.POST.get('has_colours') == 'True':
            if not colour:
                messages.error(request, ("Please choose a colour first."))
                return redirect(redirect_url)
            elif not is_hex_color(colour):
                messages.error(request, (
                    "Invalid colour, please select a colour from the displayed ones"
                ))
                return redirect(redirect_url)
            elif not all_colours.filter(hex_value=colour).exists():
                messages.error(request, (
                    "This product is not available in this colour, please select a colour from the displayed ones"
                ))
                return redirect(redirect_url)
        elif request.POST.get('has_colours') == 'False' and colour:
            messages.error(request,
                           ("There are no colour options for this product."))
            return redirect(redirect_url)

        # valdidate quantity
        try:
            quantity = int(request.POST.get('quantity'))

            if not correct_quantity(quantity):
                messages.error(request,
                               ("You can add 1-99 products to the basket."))
                return redirect(redirect_url)
        except:
            messages.error(request, ("Quantity must be an integer."))
            return redirect(redirect_url)

        # for logged-in users save basket in the database
        if request.user.is_authenticated:
            basket = Basket.objects.get_or_create(owner=request.user)[0]
            basket_items = BasketItem.objects.filter(basket=basket)

            if basket_items.filter(product__id=product.id,
                                   colour__hex_value=colour).exists():
                basket_item = BasketItem.objects.get(product__id=product.id,
                                                     colour__hex_value=colour)
                basket_item.quantity += quantity
                basket_item.save()
                messages.add_message(request, settings.BASKET_MESSAGE, (
                    f"{quantity} more {product.name} in colour: {colour_name} added to the basket."
                ))

            else:
                basket_item = BasketItem(basket=basket,
                                         product=product,
                                         quantity=quantity,
                                         colour=colour_obj)
                basket_item.save()
                messages.add_message(request, settings.BASKET_MESSAGE, (
                    f"Added {quantity} {product.name} in colour: {colour_name} to the basket."
                ))

        # if no user is logged in use session to store basket items
        else:
            basket = request.session.get('basket', {})
            item_id = str(product_id) + str(colour_id)

            if item_id in list(basket.keys()):
                basket[item_id]['quantity'] += quantity
                messages.add_message(request, settings.BASKET_MESSAGE, (
                    f"{quantity} more {product.name} in colour: {colour_name} added to the basket."
                ))
            else:
                basket[item_id] = {
                    'product': product_id,
                    'quantity': quantity,
                    'colour': colour_id
                }
                messages.add_message(request, settings.BASKET_MESSAGE, (
                    f"Added {quantity} {product.name} in colour: {colour_name} to the basket."
                ))

            request.session['basket'] = basket

    return redirect(redirect_url, product_id=product_id)