import struct from datetime import timedelta from decimal import Decimal from io import BytesIO from pathlib import Path from unittest.mock import patch from django.conf import settings from django.contrib.auth import get_user_model from django.core import mail from django.core.files.storage import default_storage from django.core.files.storage.memory import InMemoryStorage from django.core.files.uploadedfile import SimpleUploadedFile, TemporaryUploadedFile from django.db import models from django.test import Client, TestCase, override_settings from django.urls import reverse from django.utils import timezone from PIL import Image from core.models import StoredFile from shop.models import Order, OrderItem, Product, ProductColor, ProductImage from shop.services import ( ShopError, add_to_cart, adjust_stock, available_qty, create_checkout_session, create_order_from_cart, looks_like_stl, mark_paid, next_order_number, store_product_image, store_product_stl, ) from shop.stats import sales_dashboard def _tiny_png() -> bytes: image = Image.new("RGBA", (8, 8), (200, 40, 40, 255)) buf = BytesIO() image.save(buf, format="PNG") return buf.getvalue() def _tiny_stl() -> bytes: header = b"tiny" + b"\x00" * 76 count = struct.pack("