clean invalid items from eboutic baskets

This commit is contained in:
imperosol
2026-05-22 14:46:40 +02:00
parent 839e1883f9
commit 140d1ec81f
3 changed files with 34 additions and 23 deletions
+17 -11
View File
@@ -11,7 +11,7 @@ const BASKET_CACHE_KEY = "basket";
const BASKET_CACHE_VERSION = 1;
document.addEventListener("alpine:init", () => {
Alpine.data("basket", (lastPurchaseTime?: number) => ({
Alpine.data("basket", (validPrices: number[], lastPurchaseTime?: number) => ({
basket: [] as BasketItem[],
init() {
@@ -19,15 +19,6 @@ document.addEventListener("alpine:init", () => {
this.$watch("basket", () => {
this.saveBasket();
});
// Invalidate basket if a purchase was made
if (lastPurchaseTime !== null && localStorage.basketTimestamp !== undefined) {
if (
new Date(lastPurchaseTime) >=
new Date(Number.parseInt(localStorage.basketTimestamp, 10))
) {
this.basket = [];
}
}
document
.getElementById("id_form-TOTAL_FORMS")
.setAttribute(":value", "basket.length");
@@ -37,7 +28,22 @@ document.addEventListener("alpine:init", () => {
const cached = versionedLocalStorage.getItem<BasketItem[]>(BASKET_CACHE_KEY, {
version: BASKET_CACHE_VERSION,
});
return cached ?? [];
if (!cached) {
return [];
}
if (
lastPurchaseTime !== null &&
localStorage.basketTimestamp !== undefined &&
new Date(lastPurchaseTime) >=
new Date(Number.parseInt(localStorage.basketTimestamp, 10))
) {
// Invalidate basket if a purchase was made
return [];
}
// The basket is cached and not expired, so return it,
// but without items that are invalid
// (e.g. because the product is archived, or sold out)
return cached.filter((item) => validPrices.includes(item.priceId));
},
saveBasket() {
+11 -1
View File
@@ -30,7 +30,17 @@
{% block content %}
<h1 id="eboutic-title">{% trans %}Eboutic{% endtrans %}</h1>
<div id="eboutic" x-data="basket({{ last_purchase_time }})">
<div
id="eboutic"
x-data="basket(
[{%- for prices in categories -%}
{%- for p in prices -%}
{% if not p.sold_out %}{{ p.id }},{% endif %}
{%- endfor -%}
{%- endfor -%}],
{{ last_purchase_time }},
)"
>
<div id="basket">
<h3>Panier</h3>
<form method="post" action="">
+6 -11
View File
@@ -1,6 +1,8 @@
import re
from datetime import datetime, timezone
import pytest
from bs4 import BeautifulSoup
from django.http import HttpResponse
from django.test import TestCase
from django.test.client import Client
@@ -130,9 +132,11 @@ def test_eboutic_basket_expiry(
_bulk_create=True,
)
soup = BeautifulSoup(client.get(reverse("eboutic:main")).text, "lxml")
assert (
f'x-data="basket({int(expected.timestamp() * 1000) if expected else "null"})"'
in client.get(reverse("eboutic:main")).text
# remove any space from the value before asserting
re.sub(r"\s+", "", soup.find(id="eboutic").attrs["x-data"])
== f"basket([],{int(expected.timestamp() * 1000) if expected else 'null'},)"
)
@@ -243,15 +247,6 @@ class TestEboutic(TestCase):
assert response.status_code == 200
assert Basket.objects.first() is None
self.client.force_login(self.new_customer)
response = self.submit_basket([BasketItem(self.cotiz.id, 1)])
assert response.status_code == 200
assert Basket.objects.first() is None
response = self.submit_basket([BasketItem(self.not_in_counter.id, 1)])
assert response.status_code == 200
assert Basket.objects.first() is None
def test_create_basket(self):
self.client.force_login(self.new_customer)
assertRedirects(