import csv
import datetime
from io import StringIO

import pytest
from django.contrib import auth
from django.contrib.auth import get_user
from django.forms.utils import to_current_timezone
from django.urls import reverse
from django.utils import timezone
from icalendar import Calendar, vText

from la_chariotte.order import models
from la_chariotte.tests.utils import create_grouped_order, order_items_in_grouped_order

pytestmark = pytest.mark.django_db


class TestGroupedOrderIndexView:
    def test_anonymous_user_gets_redirected(self, client):
        assert auth.get_user(client).is_anonymous
        response = client.get(reverse("order:index"))
        assert response.status_code == 302
        assert response.url.startswith(reverse("accounts:login"))
        assert response.url.endswith(reverse("order:index"))

    def test_no_grouped_orders_displays_a_message(self, client_log):
        response = client_log.get(reverse("order:index"))
        assert response.status_code == 200
        assert "Pas de commande groupée pour l'instant" in response.content.decode()
        assert len(response.context["grouped_order_list"]["old_grouped_orders"]) == 0
        assert (
            len(
                response.context["grouped_order_list"][
                    "crossed_deadline_grouped_orders"
                ]
            )
            == 0
        )
        assert (
            len(response.context["grouped_order_list"]["incoming_grouped_orders"]) == 0
        )

    def test_grouped_orders_appears_in_right_section(self, client_log):
        """
        According to their delivery date and deadline, grouped orders are placed
        in the correct section : several gr orders
        """
        future_grouped_order = create_grouped_order(
            days_before_delivery_date=5,
            days_before_deadline=2,
            name="future",
            orga_user=auth.get_user(client_log),
        )
        crossed_deadline_gr_order = create_grouped_order(
            days_before_delivery_date=2,
            days_before_deadline=-1,
            name="crossed deadline",
            orga_user=auth.get_user(client_log),
        )
        old_gr_order = create_grouped_order(
            days_before_delivery_date=-1,
            days_before_deadline=-3,
            name="old",
            orga_user=auth.get_user(client_log),
        )
        response = client_log.get(reverse("order:index"))
        assert response.status_code == 200
        assert "Pas de commande groupée pour l'instant" not in response.content.decode()
        assert "Commandes groupées à venir" in response.content.decode()
        assert "Livraison à venir" in response.content.decode()
        assert "Anciennes commandes" in response.content.decode()
        assert len(response.context["grouped_order_list"]["old_grouped_orders"]) == 1
        assert (
            len(
                response.context["grouped_order_list"][
                    "crossed_deadline_grouped_orders"
                ]
            )
            == 1
        )
        assert (
            len(response.context["grouped_order_list"]["incoming_grouped_orders"]) == 1
        )
        assert (
            response.context["grouped_order_list"]["old_grouped_orders"][0]
            == old_gr_order
        )
        assert (
            response.context["grouped_order_list"]["crossed_deadline_grouped_orders"][0]
            == crossed_deadline_gr_order
        )
        assert (
            response.context["grouped_order_list"]["incoming_grouped_orders"][0]
            == future_grouped_order
        )

    def test_grouped_orders_in_right_section__with_only_old(self, client_log):
        """
        According to their delivery date and deadline, grouped orders are placed in correct section : only old gr order
        """
        old_gr_order = create_grouped_order(
            days_before_delivery_date=-1,
            days_before_deadline=-3,
            name="passée",
            orga_user=auth.get_user(client_log),
        )
        response = client_log.get(reverse("order:index"))
        assert response.status_code == 200
        assert "Pas de commande groupée pour l'instant" not in response.content.decode()
        assert "Commandes groupées à venir" not in response.content.decode()
        assert "Livraison à venir" not in response.content.decode()
        assert "Anciennes commandes" in response.content.decode()
        assert len(response.context["grouped_order_list"]["old_grouped_orders"]) == 1
        assert (
            len(
                response.context["grouped_order_list"][
                    "crossed_deadline_grouped_orders"
                ]
            )
            == 0
        )
        assert (
            len(response.context["grouped_order_list"]["incoming_grouped_orders"]) == 0
        )
        assert (
            response.context["grouped_order_list"]["old_grouped_orders"][0]
            == old_gr_order
        )

    def test_grouped_orders_in_right_section__with_only_future(self, client_log):
        """
        According to their delivery date and deadline, grouped orders are placed in correct section : only incoming gr order
        """
        future_grouped_order = create_grouped_order(
            days_before_delivery_date=5,
            days_before_deadline=2,
            name="future",
            orga_user=auth.get_user(client_log),
        )
        response = client_log.get(reverse("order:index"))
        assert response.status_code == 200
        assert "Pas de commande groupée pour l'instant" not in response.content.decode()
        assert "Commandes groupées à venir" in response.content.decode()
        assert "Livraison à venir" not in response.content.decode()
        assert "Anciennes commandes" not in response.content.decode()
        assert len(response.context["grouped_order_list"]["old_grouped_orders"]) == 0
        assert (
            len(
                response.context["grouped_order_list"][
                    "crossed_deadline_grouped_orders"
                ]
            )
            == 0
        )
        assert (
            len(response.context["grouped_order_list"]["incoming_grouped_orders"]) == 1
        )
        assert (
            response.context["grouped_order_list"]["incoming_grouped_orders"][0]
            == future_grouped_order
        )

    def test_gr_order_not_organized_by_logged_user(self, client_log, other_user):
        """
        If the logged user is not the organizer of a grouped order they don't see it on IndexView
        """
        logged_user = auth.get_user(client_log)
        future_grouped_order = create_grouped_order(
            days_before_delivery_date=5,
            days_before_deadline=2,
            name="future",
            orga_user=other_user,
        )
        assert future_grouped_order.orga is not logged_user
        response = client_log.get(reverse("order:index"))
        assert response.status_code == 200
        assert "Pas de commande groupée pour l'instant" in response.content.decode()
        assert len(response.context["grouped_order_list"]["old_grouped_orders"]) == 0
        assert (
            len(
                response.context["grouped_order_list"][
                    "crossed_deadline_grouped_orders"
                ]
            )
            == 0
        )
        assert (
            len(response.context["grouped_order_list"]["incoming_grouped_orders"]) == 0
        )


class TestJoinGroupedOrderView:
    def test_correct_code_redirects_properly(self, client, client_log):
        logged_user = auth.get_user(client_log)
        grouped_order = create_grouped_order(
            days_before_delivery_date=5,
            days_before_deadline=2,
            name="test",
            orga_user=logged_user,
        )
        join_url = reverse("dashboard")
        response = client.post(join_url, {"code": grouped_order.code})

        expected_url = reverse(
            "order:grouped_order_detail", kwargs={"code": grouped_order.code}
        )
        assert response.status_code == 302
        assert response.url == expected_url

    def test_incorrect_code_errors_out(self, client):
        assert len(models.GroupedOrder.objects.all()) == 0

        join_url = reverse("dashboard")
        response = client.post(join_url, {"code": "123456"})

        assert (
            "Désolé, nous ne trouvons aucune commande avec ce code"
            in response.content.decode()
        )


class TestGroupedOrderDetailView:
    def test_order_item_with_authenticated_user(self, client, connected_grouped_order):
        detail_url = reverse(
            "order:grouped_order_detail",
            kwargs={
                "code": connected_grouped_order.code,
            },
        )
        response = client.get(detail_url)

        assert response.status_code == 200

        order_author = response.context[0]["order_author"]
        current_user = get_user(client)

        assert order_author is not None

        assert order_author.first_name == current_user.first_name
        assert order_author.email == current_user.username
        assert order_author.last_name == current_user.last_name

    def test_order_item(self, client, other_user):
        """
        From the OrderDetailView, we order an item using the order form, and it creates an models.Order with an Ordered_item inside
        """
        grouped_order = create_grouped_order(
            days_before_delivery_date=5,
            days_before_deadline=2,
            name="gr order test",
            orga_user=other_user,
        )
        item = models.Item.objects.create(
            name="test item 1", grouped_order=grouped_order, price=1, max_limit=20
        )
        item2 = models.Item.objects.create(
            name="test item 2", grouped_order=grouped_order, price=5
        )
        item3 = models.Item.objects.create(
            name="test item 3", grouped_order=grouped_order, price=5
        )
        detail_url = reverse(
            "order:grouped_order_detail",
            kwargs={
                "code": grouped_order.code,
            },
        )
        response = client.get(detail_url)
        assert response.status_code == 200
        assert "test item" in response.content.decode()
        assert "gr order test" in response.content.decode()
        assert "20 disponibles" in response.content.decode()
        assert item.ordered_nb == 0
        assert item2.ordered_nb == 0
        assert item3.ordered_nb == 0
        assert models.OrderedItem.objects.count() == 0
        order_url = reverse(
            "order:order",
            kwargs={
                "code": grouped_order.code,
            },
        )
        response = client.post(
            order_url,
            {
                f"quantity_{item.pk}": [4, 0],
                f"quantity_{item2.pk}": [1, 0],
                f"quantity_{item3.pk}": [0, 0],
                "first_name": "Prénom",
                "last_name": "Nom",
                "phone": "0645632569",
                "email": "test@mail.fr",
                "note": "note test",
            },
        )
        assert response.status_code == 302
        order = models.Order.objects.get(grouped_order=grouped_order.pk)
        assert response.url == reverse(
            "order:order_confirm",
            kwargs={
                "code": grouped_order.code,
                "pk": order.pk,
            },
        )
        item.refresh_from_db()
        item2.refresh_from_db()
        author = models.OrderAuthor.objects.first()
        order = models.Order.objects.first()
        assert author.first_name == "Prénom"
        assert author.email == "test@mail.fr"
        assert author.phone == "0645632569"
        assert order.note == "note test"
        assert order.created_date.date() == timezone.now().date()
        assert item.ordered_nb == 4
        assert item2.ordered_nb == 1
        assert order.ordered_items.count() == 2
        assert order.articles_nb == 5
        assert order.price == 9
        assert item.get_remaining_nb() == 16
        # OrderedItems are not created when the ordered quantity is 0
        assert models.OrderedItem.objects.count() == 2

    def test_order_item__no_articles_ordered(
        self, client, authenticated_user_with_name
    ):
        """
        From the OrderDetailView, we order without having changed any item quantity.
        An error is raised.
        The order is deleted, and the form is displayed without deleting entered values
        """
        grouped_order = create_grouped_order(
            days_before_delivery_date=5,
            days_before_deadline=2,
            name="gr order test",
            orga_user=authenticated_user_with_name,
        )
        item = models.Item.objects.create(
            name="test item 1", grouped_order=grouped_order, price=1
        )
        detail_url = reverse(
            "order:grouped_order_detail",
            kwargs={
                "code": grouped_order.code,
            },
        )
        response = client.get(detail_url)
        assert response.status_code == 200
        assert "test item" in response.content.decode()
        assert "gr order test" in response.content.decode()
        assert item.ordered_nb == 0
        order_url = reverse(
            "order:order",
            kwargs={
                "code": grouped_order.code,
            },
        )
        response = client.post(
            order_url,
            {
                f"quantity_{item.pk}": [0, 0],
                "first_name": {authenticated_user_with_name.first_name},
                "last_name": {authenticated_user_with_name.last_name},
                "phone": "0645632569",
                "email": {authenticated_user_with_name.email},
                "note": "test note",
            },
        )
        assert response.status_code == 200
        assert (
            response.context["error_message"]
            == "Veuillez commander au moins un produit"
        )
        assert (
            response.context["author"].first_name
            == authenticated_user_with_name.first_name
        )
        content = response.content.decode()
        assert authenticated_user_with_name.first_name in content
        assert authenticated_user_with_name.last_name in content
        assert authenticated_user_with_name.email in content
        assert "test note" in content
        assert not models.Order.objects.first()
        assert not models.OrderAuthor.objects.first()

    def test_deadline_passed(self, client, other_user):
        """
        If the deadline is passed, the user sees a message but cannot order
        """
        grouped_order = create_grouped_order(
            days_before_delivery_date=5,
            days_before_deadline=-1,
            name="gr order test",
            orga_user=other_user,
        )
        item = models.Item.objects.create(
            name="test item 1", grouped_order=grouped_order, price=1
        )
        item2 = models.Item.objects.create(
            name="test item 2", grouped_order=grouped_order, price=5
        )
        detail_url = reverse(
            "order:grouped_order_detail",
            kwargs={
                "code": grouped_order.code,
            },
        )
        response = client.get(detail_url)
        assert response.status_code == 200
        assert "test item" not in response.content.decode()
        assert "gr order test" in response.content.decode()
        assert "La période de commande est terminée" in response.content.decode()

    def test_delivery_passed(self, client, other_user):
        """
        If the delivery date is passed, the user sees a message but cannot order
        """
        grouped_order = create_grouped_order(
            days_before_delivery_date=-1,
            days_before_deadline=-2,
            name="gr order test",
            orga_user=other_user,
        )
        item = models.Item.objects.create(
            name="test item 1", grouped_order=grouped_order, price=1
        )
        item2 = models.Item.objects.create(
            name="test item 2", grouped_order=grouped_order, price=5
        )
        detail_url = reverse(
            "order:grouped_order_detail",
            kwargs={
                "code": grouped_order.code,
            },
        )
        response = client.get(detail_url)
        assert response.status_code == 200
        assert "test item" not in response.content.decode()
        assert "gr order test" in response.content.decode()
        assert "Cette commande groupée est terminée" in response.content.decode()

    def test_order_too_many_items(self, client, other_user):
        """a user orders more items than what is available. They get an error"""
        grouped_order = create_grouped_order(
            days_before_delivery_date=5,
            days_before_deadline=2,
            name="gr order test",
            orga_user=other_user,
        )
        item = models.Item.objects.create(
            name="test item 1", grouped_order=grouped_order, price=1, max_limit=1
        )
        detail_url = reverse(
            "order:grouped_order_detail",
            kwargs={
                "code": grouped_order.code,
            },
        )
        response = client.get(detail_url)
        assert response.status_code == 200
        assert "test item" in response.content.decode()
        assert "gr order test" in response.content.decode()
        assert item.ordered_nb == 0
        order_url = reverse(
            "order:order",
            kwargs={
                "code": grouped_order.code,
            },
        )
        response = client.post(
            order_url,
            {
                f"quantity_{item.pk}": [2, 0],
                "first_name": "Prénom",
                "last_name": "Nom",
                "phone": "0645632569",
                "email": "test@mail.fr",
                "note": "",
            },
        )
        assert response.status_code == 200
        assert (
            response.context["error_message"]
            == "Trop de test item 1 commandés pour la quantité disponible"
        )
        assert not models.Order.objects.first()
        assert not models.OrderAuthor.objects.first()

    def test_order_no_item_available(self, client, other_user):
        """a user an item that is not available. They get an error"""
        grouped_order = create_grouped_order(
            days_before_delivery_date=5,
            days_before_deadline=2,
            name="gr order test",
            orga_user=other_user,
        )
        item = models.Item.objects.create(
            name="test item 1", grouped_order=grouped_order, price=1, max_limit=0
        )
        detail_url = reverse(
            "order:grouped_order_detail",
            kwargs={
                "code": grouped_order.code,
            },
        )
        response = client.get(detail_url)
        assert response.status_code == 200
        assert "test item" in response.content.decode()
        assert "gr order test" in response.content.decode()
        assert item.ordered_nb == 0
        order_url = reverse(
            "order:order",
            kwargs={
                "code": grouped_order.code,
            },
        )
        response = client.post(
            order_url,
            {
                f"quantity_{item.pk}": [0, 1],
                "first_name": "Prénom",
                "last_name": "Nom",
                "phone": "0645632569",
                "email": "test@mail.fr",
                "note": "",
            },
        )
        assert response.status_code == 200
        assert (
            response.context["error_message"]
            == "Trop de test item 1 commandés pour la quantité disponible"
        )
        assert not models.Order.objects.first()
        assert not models.OrderAuthor.objects.first()

    def test_order_no_item_available_anymore(self, client, other_user):
        """a user an item that is not available anymore. They get an error"""
        grouped_order = create_grouped_order(
            days_before_delivery_date=5,
            days_before_deadline=2,
            name="gr order test",
            orga_user=other_user,
        )
        item = models.Item.objects.create(
            name="test item 1", grouped_order=grouped_order, price=1, max_limit=2
        )
        detail_url = reverse(
            "order:grouped_order_detail",
            kwargs={
                "code": grouped_order.code,
            },
        )
        response = client.get(detail_url)
        assert response.status_code == 200
        assert "test item" in response.content.decode()
        assert "gr order test" in response.content.decode()
        assert item.ordered_nb == 0
        order_url = reverse(
            "order:order",
            kwargs={
                "code": grouped_order.code,
            },
        )
        response = client.post(
            order_url,
            {
                f"quantity_{item.pk}": [2, 0],
                "first_name": "Prénom",
                "last_name": "Nom",
                "phone": "0645632569",
                "email": "test@mail.fr",
                "note": "",
            },
        )
        assert response.status_code == 302  # success : first order
        response = client.post(
            order_url,
            {
                f"quantity_{item.pk}": [1, 0],
                "first_name": "Prénom",
                "last_name": "Nom",
                "phone": "0645632569",
                "email": "test@mail.fr",
                "note": "",
            },
        )
        assert response.status_code == 200  # error
        assert (
            response.context["error_message"]
            == "Trop de test item 1 commandés pour la quantité disponible"
        )

    def test_order_item_no_ordered_item_created_for_empty_order(
        self, client, other_user
    ):
        """
        when a user does not order all items, those that are not ordered don't have a related OrderedItem
        """
        grouped_order = create_grouped_order(
            days_before_delivery_date=5,
            days_before_deadline=2,
            name="gr order test",
            orga_user=other_user,
        )
        item = models.Item.objects.create(
            name="test item 1", grouped_order=grouped_order, price=1, max_limit=20
        )
        item2 = models.Item.objects.create(
            name="test item 2", grouped_order=grouped_order, price=5
        )
        detail_url = reverse(
            "order:grouped_order_detail",
            kwargs={
                "code": grouped_order.code,
            },
        )
        response = client.get(detail_url)
        assert response.status_code == 200
        assert "test item" in response.content.decode()
        assert "gr order test" in response.content.decode()
        assert "20 disponibles" in response.content.decode()
        assert item.ordered_nb == 0
        assert item2.ordered_nb == 0
        order_url = reverse(
            "order:order",
            kwargs={
                "code": grouped_order.code,
            },
        )
        response = client.post(
            order_url,
            {
                f"quantity_{item.pk}": [4, 0],
                f"quantity_{item2.pk}": [0, 0],
                "first_name": "Prénom",
                "last_name": "Nom",
                "phone": "0645632569",
                "email": "test@mail.fr",
                "note": "",
            },
        )
        assert response.status_code == 302
        order = models.Order.objects.get(grouped_order=grouped_order.pk)
        assert response.url == reverse(
            "order:order_confirm",
            kwargs={
                "code": grouped_order.code,
                "pk": order.pk,
            },
        )
        item.refresh_from_db()
        item2.refresh_from_db()
        assert models.OrderAuthor.objects.first().first_name == "Prénom"
        assert models.OrderAuthor.objects.first().email == "test@mail.fr"
        assert models.OrderAuthor.objects.first().phone == "0645632569"
        assert item.ordered_nb == 4
        assert item2.ordered_nb == 0
        order = models.Order.objects.first()
        assert order.ordered_items.count() == 1
        assert models.OrderedItem.objects.filter(item=item2.pk).count() == 0
        assert order.articles_nb == 4
        assert order.price == 4
        assert item.get_remaining_nb() == 16

    def test_phone_not_required_display(self, client, other_user):
        """a user orders something without entering phone when it is required"""
        grouped_order = create_grouped_order(
            days_before_delivery_date=5,
            days_before_deadline=2,
            name="gr order test",
            orga_user=other_user,
        )
        assert grouped_order.is_phone_mandatory == True
        item = models.Item.objects.create(
            name="test item 1", grouped_order=grouped_order, price=1, max_limit=2
        )
        detail_url = reverse(
            "order:grouped_order_detail",
            kwargs={
                "code": grouped_order.code,
            },
        )
        response = client.get(detail_url)
        assert response.status_code == 200
        assert "gr order test" in response.content.decode()
        assert (
            "Numéro de téléphone <em>(facultatif)</em>" not in response.content.decode()
        )
        grouped_order.is_phone_mandatory = False
        grouped_order.save()
        response = client.get(detail_url)
        assert "gr order test" in response.content.decode()
        assert "Numéro de téléphone <em>(facultatif)</em>" in response.content.decode()


class TestGroupedOrderOverview:
    def test_get_overview(self, client_log):
        """
        From the OrderDetailView, we order an item using the order form, and it creates an models.Order with an Ordered_item inside
        """
        grouped_order = create_grouped_order(
            days_before_delivery_date=5,
            days_before_deadline=2,
            name="gr order test",
            orga_user=auth.get_user(client_log),
        )
        item = models.Item.objects.create(
            name="test item 1", grouped_order=grouped_order, price=2
        )

        overview_url = reverse(
            "order:grouped_order_overview",
            kwargs={
                "code": grouped_order.code,
            },
        )
        # some items are ordered
        order_url = reverse(
            "order:order",
            kwargs={
                "code": grouped_order.code,
            },
        )
        client_log.post(
            order_url,
            {
                f"quantity_{item.pk}": [4, 0],
                "first_name": "Prénom",
                "last_name": "Nom",
                "phone": "0645632569",
                "email": "test@mail.fr",
                "note": "",
            },
        )
        response = client_log.get(overview_url)
        assert response.status_code == 200
        assert "test item" in response.content.decode()
        assert {"test@mail.fr"} == response.context["emails_list"]
        assert 4 == response.context["total_ordered_items"]
        assert "gr order test" in response.content.decode()
        item.refresh_from_db()
        assert item.get_total_price() == 8
        assert "8" in response.content.decode()

    def test_user_not_logged_gets_redirected(self, client, other_user):
        """
        A user that is not logged cannot see the GroupedOrderOverview. They get redirected to the login view
        """
        grouped_order = create_grouped_order(
            days_before_delivery_date=5,
            days_before_deadline=2,
            name="gr order test",
            orga_user=other_user,
        )
        orga_view_url = reverse(
            "order:grouped_order_overview",
            kwargs={
                "code": grouped_order.code,
            },
        )
        assert auth.get_user(client).is_anonymous
        response = client.get(orga_view_url)
        assert response.status_code == 302
        assert response.url.startswith(reverse("accounts:login"))
        assert response.url.endswith(
            reverse(
                "order:grouped_order_overview",
                kwargs={
                    "code": grouped_order.code,
                },
            )
        )

    def test_user_not_orga_gets_redirected(self, client_log, other_user):
        """
        A user that is not orga cannot see the GroupedOrderOverview.
        They get a 403 forbidden error
        """
        grouped_order = create_grouped_order(
            days_before_delivery_date=5,
            days_before_deadline=2,
            name="gr order test",
            orga_user=other_user,
        )
        orga_view_url = reverse(
            "order:grouped_order_overview",
            kwargs={
                "code": grouped_order.code,
            },
        )
        response = client_log.get(orga_view_url)
        assert response.status_code == 403

    def test_superuser_can_access_overview(self, other_user, admin_client):
        """
        A superuser that is not orga can get the GroupedOrderOverview
        """
        grouped_order = create_grouped_order(
            days_before_delivery_date=5,
            days_before_deadline=2,
            name="gr order test",
            orga_user=other_user,
        )
        orga_view_url = reverse(
            "order:grouped_order_overview",
            kwargs={
                "code": grouped_order.code,
            },
        )
        response = admin_client.get(orga_view_url)
        assert response.status_code == 200

    def test_deadline_passed(self, client_log):
        """
        If the deadline is passed, the user sees a message but cannot share link
        """
        grouped_order = create_grouped_order(
            days_before_delivery_date=5,
            days_before_deadline=-1,
            name="gr order test",
            orga_user=auth.get_user(client_log),
        )
        item = models.Item.objects.create(
            name="test item 1", grouped_order=grouped_order, price=1
        )
        item2 = models.Item.objects.create(
            name="test item 2", grouped_order=grouped_order, price=5
        )
        orga_view_url = reverse(
            "order:grouped_order_overview",
            kwargs={
                "code": grouped_order.code,
            },
        )
        response = client_log.get(orga_view_url)
        assert response.status_code == 200
        assert "Pour partager cette commande" not in response.content.decode()
        assert "gr order test" in response.content.decode()
        assert "La période de commande est terminée" in response.content.decode()

    def test_delivery_passed(self, client_log):
        """
        If the delivery date is passed, the user sees a message but cannot share link
        """
        grouped_order = create_grouped_order(
            days_before_delivery_date=-1,
            days_before_deadline=-2,
            name="gr order test",
            orga_user=auth.get_user(client_log),
        )
        item = models.Item.objects.create(
            name="test item 1", grouped_order=grouped_order, price=1
        )
        item2 = models.Item.objects.create(
            name="test item 2", grouped_order=grouped_order, price=5
        )
        orga_view_url = reverse(
            "order:grouped_order_overview",
            kwargs={
                "code": grouped_order.code,
            },
        )
        response = client_log.get(orga_view_url)
        assert response.status_code == 200
        assert "Pour partager cette commande" not in response.content.decode()
        assert "gr order test" in response.content.decode()
        assert "Cette commande groupée est terminée" in response.content.decode()


class TestGroupedOrderCreateView:
    def test_create_grouped_order(self, client_log):
        """
        A logged user gets the grouped order creation page, and creates a grouped order.
        They are redirected to the manage items page.
        """
        assert models.GroupedOrder.objects.count() == 0
        create_gorder_url = reverse("order:create_grouped_order")
        response = client_log.get(create_gorder_url)
        assert response.status_code == 200
        date = timezone.now().date() + datetime.timedelta(days=42)
        deadline = timezone.now() + datetime.timedelta(days=32)
        response = client_log.post(
            create_gorder_url,
            {
                "name": "titre test",
                "deadline_date": deadline.date(),
                "deadline_time": deadline.time().strftime("%H:%M"),
                "delivery_date": date,
            },
        )
        assert response.status_code == 302
        assert response.url.endswith("gerer-produits")
        assert models.GroupedOrder.objects.count() == 1
        assert models.GroupedOrder.objects.first().code != ""

    def test_create_grouped_order__anonymous_user(self, client):
        create_gorder_url = reverse("order:create_grouped_order")
        response = client.get(create_gorder_url)
        assert response.status_code == 302
        assert response.url.startswith(reverse("accounts:login"))
        assert response.url.endswith(
            reverse(
                "order:create_grouped_order",
            )
        )


class TestGroupedOrderUpdateView:
    def test_get_update_grouped_order(self, client_log):
        """
        The grouped order orga updates a grouped order updates an incoming grouped order.
        """
        grouped_order = create_grouped_order(
            days_before_delivery_date=5,
            days_before_deadline=2,
            name="gr order test",
            orga_user=auth.get_user(client_log),
        )
        grouped_order.deadline = to_current_timezone(timezone.now())
        grouped_order.save()
        assert models.GroupedOrder.objects.count() == 1
        assert models.GroupedOrder.objects.first().name == "gr order test"
        assert models.GroupedOrder.objects.first().place == None

        # get the update form
        update_grouped_order_url = reverse(
            "order:update_grouped_order", kwargs={"code": grouped_order.code}
        )
        response = client_log.get(update_grouped_order_url)
        assert response.status_code == 200
        assert grouped_order.deadline.strftime("%H:%M") in response.content.decode()

    def test_post_update_grouped_order(self, client_log):
        """
        The grouped order orga updates a grouped order updates an incoming grouped order.
        """
        grouped_order = create_grouped_order(
            days_before_delivery_date=5,
            days_before_deadline=2,
            name="gr order test",
            orga_user=auth.get_user(client_log),
        )
        assert models.GroupedOrder.objects.count() == 1
        assert models.GroupedOrder.objects.first().name == "gr order test"
        assert models.GroupedOrder.objects.first().place == None

        # get the update form
        update_grouped_order_url = reverse(
            "order:update_grouped_order", kwargs={"code": grouped_order.code}
        )
        response = client_log.get(update_grouped_order_url)
        assert response.status_code == 200

        # post the update form
        date = timezone.now().date() + datetime.timedelta(days=42)
        deadline = timezone.now() + datetime.timedelta(days=32)
        response = client_log.post(
            update_grouped_order_url,
            {
                "name": "titre test modifié",
                "deadline_date": deadline.date(),
                "deadline_time": deadline.time().strftime("%H:%M"),
                "delivery_date": date,
                "place": "quelque part",
            },
        )
        assert response.status_code == 302
        assert response.url.endswith("gerer-produits")
        assert models.GroupedOrder.objects.count() == 1
        assert models.GroupedOrder.objects.first().name == "titre test modifié"
        assert models.GroupedOrder.objects.first().place == "quelque part"

    def test_update_grouped_order__delivery_date_passed(self, client_log):
        """
        The grouped order orga updates a grouped order.
        They can put an old delivery date.
        """
        grouped_order = create_grouped_order(
            days_before_delivery_date=5,
            days_before_deadline=2,
            name="gr order test",
            orga_user=auth.get_user(client_log),
        )
        assert models.GroupedOrder.objects.count() == 1
        assert models.GroupedOrder.objects.first().name == "gr order test"
        assert models.GroupedOrder.objects.first().place == None

        # get the update form
        update_grouped_order_url = reverse(
            "order:update_grouped_order", kwargs={"code": grouped_order.code}
        )
        response = client_log.get(update_grouped_order_url)
        assert response.status_code == 200

        # post the update form
        date = timezone.now().date() + datetime.timedelta(days=-1)
        deadline = timezone.now() + datetime.timedelta(days=-3)
        response = client_log.post(
            update_grouped_order_url,
            {
                "name": "titre test modifié",
                "deadline_date": deadline.date(),
                "deadline_time": deadline.time().strftime("%H:%M"),
                "delivery_date": date,
                "place": "quelque part",
            },
        )
        assert response.status_code == 302
        assert response.url.endswith("gerer-produits")
        assert models.GroupedOrder.objects.count() == 1
        assert models.GroupedOrder.objects.first().name == "titre test modifié"
        assert models.GroupedOrder.objects.first().place == "quelque part"

    def test_update_grouped_order__not_orga(self, client_log, other_user):
        """A user that is not organiszer of the GO accesses update page.
        They get a 403 error"""
        grouped_order = create_grouped_order(
            days_before_delivery_date=5,
            days_before_deadline=2,
            name="gr order test",
            orga_user=other_user,
        )

        # get the update form
        update_grouped_order_url = reverse(
            "order:update_grouped_order", kwargs={"code": grouped_order.code}
        )
        response = client_log.get(update_grouped_order_url)
        assert response.status_code == 403

    def test_update_grouped_order__anonymous(self, client, other_user):
        """An anonymous user accesses the update_page.
        They get redirected to login page"""
        grouped_order = create_grouped_order(
            days_before_delivery_date=5,
            days_before_deadline=2,
            name="gr order test",
            orga_user=other_user,
        )

        # get the update form
        update_grouped_order_url = reverse(
            "order:update_grouped_order", kwargs={"code": grouped_order.code}
        )
        response = client.get(update_grouped_order_url)
        assert response.status_code == 302
        assert (
            response.url
            == f"{reverse('accounts:login')}?next={update_grouped_order_url}"
        )


class TestGroupedOrderAddItemsView:
    def test_get_manage_items__user_not_orga(self, client_log, other_user):
        """
        A user that is not orga cannot see the GroupedOrderAddItemsView.
        They get a 403 forbidden error
        """
        grouped_order = create_grouped_order(
            days_before_delivery_date=5,
            days_before_deadline=2,
            name="gr order test",
            orga_user=other_user,
        )
        add_items_view_url = reverse(
            "order:manage_items",
            kwargs={
                "code": grouped_order.code,
            },
        )
        response = client_log.get(add_items_view_url)
        assert response.status_code == 403

    def test_get_manage_items__anonymous_user(self, client, other_user):
        """
        A user that is not logged cannot see the GroupedOrderOverview. They get redirected to the login view
        """
        grouped_order = create_grouped_order(
            days_before_delivery_date=5,
            days_before_deadline=2,
            name="gr order test",
            orga_user=other_user,
        )
        add_items_view_url = reverse(
            "order:manage_items",
            kwargs={
                "code": grouped_order.code,
            },
        )
        assert auth.get_user(client).is_anonymous
        response = client.get(add_items_view_url)
        assert response.status_code == 302
        assert response.url.startswith(reverse("accounts:login"))
        assert response.url.endswith(
            reverse(
                "order:manage_items",
                kwargs={"code": grouped_order.code},
            )
        )

    def test_delete_item(self, client_log):
        """
        A user on the manage item page creates and then deletes an item
        """
        assert models.GroupedOrder.objects.count() == 0
        create_gorder_url = reverse("order:create_grouped_order")
        response = client_log.get(create_gorder_url)
        assert response.status_code == 200
        date = timezone.now().date() + datetime.timedelta(days=42)
        deadline = timezone.now() + datetime.timedelta(days=32)
        response = client_log.post(
            create_gorder_url,
            {
                "name": "titre test",
                "deadline_date": deadline.date(),
                "deadline_time": deadline.time().strftime("%H:%M"),
                "delivery_date": date,
            },
        )
        assert response.status_code == 302
        assert response.url.endswith("gerer-produits")
        assert models.GroupedOrder.objects.count() == 1

        # Create an item
        grouped_order = models.GroupedOrder.objects.first()
        create_item_url = reverse("order:item_create", args=[grouped_order.code])
        response = client_log.post(create_item_url, {"name": "Pain test", "price": "2"})
        response.status_code == 302
        response.url == reverse("order:manage_items", args=[grouped_order.code])
        assert grouped_order.item_set.count() == 1

        # Delete the item
        item = grouped_order.item_set.first()
        delete_item_url = reverse("order:item_delete", args=[grouped_order.id, item.id])
        response = client_log.post(delete_item_url)
        assert response.status_code == 302
        assert response.url == reverse("order:manage_items", args=[grouped_order.code])
        assert grouped_order.item_set.count() == 0

    def test_create_or_delete_item__not_orga(self, client_log, other_user):
        """
        A user that is not orga delete or create an item
        They get a 403 forbidden error
        """
        grouped_order = create_grouped_order(
            days_before_delivery_date=5,
            days_before_deadline=2,
            name="gr order test",
            orga_user=other_user,
        )

        # Create an item
        grouped_order = models.GroupedOrder.objects.first()
        create_item_url = reverse("order:item_create", args=[grouped_order.id])
        response = client_log.post(create_item_url, {"name": "Pain test", "price": "2"})
        response.status_code == 403
        assert grouped_order.item_set.count() == 0

        # Delete an item
        item = grouped_order.item_set.create(name="Pain test", price="2")
        assert grouped_order.item_set.count() == 1
        delete_item_url = reverse("order:item_delete", args=[grouped_order.id, item.id])
        response = client_log.post(delete_item_url)
        assert response.status_code == 403
        assert grouped_order.item_set.count() == 1


class TestGroupedOrderDeleteView:
    def test_delete_grouped_order(self, client_log):
        """The orga of the GO deletes it.
        The GO and related Order, OrderAuthor, OrderedItems, Items are deleted."""
        grouped_order = create_grouped_order(
            days_before_delivery_date=5,
            days_before_deadline=2,
            name="gr order test",
            orga_user=auth.get_user(client_log),
        )
        assert models.GroupedOrder.objects.count() == 1
        order = order_items_in_grouped_order(grouped_order)

        assert models.Item.objects.count() == 2
        assert models.OrderedItem.objects.count() == 4
        assert models.OrderAuthor.objects.count() == 3

        # get the delete view
        delete_view_url = reverse(
            "order:delete_grouped_order", kwargs={"code": grouped_order.code}
        )
        response = client_log.get(delete_view_url)
        assert response.status_code == 200

        # post the delete view
        response = client_log.post(delete_view_url)
        assert response.status_code == 302
        assert response.url == reverse("order:index")

        # check everything is deleted
        assert models.GroupedOrder.objects.count() == 0
        assert models.Order.objects.count() == 0
        assert models.OrderedItem.objects.count() == 0
        assert models.OrderAuthor.objects.count() == 0
        assert models.Item.objects.count() == 0

    def test_delete_grouped_order__not_orga(self, client_log, other_user):
        """A user that is not orga gets or posts the delete view. They get a 403 error."""
        grouped_order = create_grouped_order(
            days_before_delivery_date=5,
            days_before_deadline=2,
            name="gr order test",
            orga_user=other_user,
        )
        assert models.GroupedOrder.objects.count() == 1

        # get the delete view
        delete_view_url = reverse(
            "order:delete_grouped_order", kwargs={"code": grouped_order.code}
        )
        response = client_log.get(delete_view_url)
        assert response.status_code == 403

        # post the delete view
        response = client_log.post(delete_view_url)
        assert response.status_code == 403

        assert models.GroupedOrder.objects.count() == 1

    def test_delete_grouped_order__anonymous(self, client, other_user):
        """An anonymous user gets the delete view. They get redirected to login page"""
        grouped_order = create_grouped_order(
            days_before_delivery_date=5,
            days_before_deadline=2,
            name="gr order test",
            orga_user=other_user,
        )
        assert models.GroupedOrder.objects.count() == 1

        # get the delete view
        delete_view_url = reverse(
            "order:delete_grouped_order", kwargs={"code": grouped_order.code}
        )
        response = client.get(delete_view_url)
        assert response.status_code == 302
        assert response.url == f"{reverse('accounts:login')}?next={delete_view_url}"

        # post the delete view
        response = client.post(delete_view_url)
        assert response.status_code == 302
        assert response.url == f"{reverse('accounts:login')}?next={delete_view_url}"

        assert models.GroupedOrder.objects.count() == 1


class TestGroupedOrderEventView:
    def test_get_event(self, client_log):
        # Setup
        grouped_order = create_grouped_order(
            days_before_delivery_date=5,
            days_before_deadline=2,
            name="gr order test",
            orga_user=auth.get_user(client_log),
        )

        event_url = reverse(
            "order:grouped_order_event",
            kwargs={
                "code": grouped_order.code,
            },
        )
        response = client_log.get(event_url)

        # Check the response
        assert response.status_code == 200
        assert response["Content-Type"] == "text/calendar"
        assert (
            response["Content-Disposition"]
            == f"attachment; filename={grouped_order.name}.ics"
        )
        # Parse the iCal data
        cal = Calendar.from_ical(response.content.decode())
        # Check the event details
        for component in cal.walk():
            if component.name == "VEVENT":
                assert component.get("summary") == grouped_order.name
                assert component.get("dtstart").dt == grouped_order.delivery_date
                assert (
                    component.get("organizer") == "MAILTO:" + grouped_order.orga.email
                )


class TestGroupedOrderDuplicateView:
    def test_duplicate_grouped_order(self, client_log):
        """The orga of the GO duplicates it.
        A new GO is created without any order but with the same item_set.
        The user gets redirected to the update view. The old GO remains the same"""
        grouped_order = create_grouped_order(
            days_before_delivery_date=5,
            days_before_deadline=2,
            name="gr order test",
            orga_user=auth.get_user(client_log),
        )
        assert models.GroupedOrder.objects.count() == 1
        order = order_items_in_grouped_order(grouped_order)
        assert models.Item.objects.count() == 2
        assert models.OrderedItem.objects.count() == 4
        assert models.OrderAuthor.objects.count() == 3
        assert grouped_order.item_set.first().ordered_nb == 4

        # duplicate
        duplicate_view_url = reverse(
            "order:duplicate_grouped_order", kwargs={"code": grouped_order.code}
        )
        response = client_log.get(duplicate_view_url)
        assert models.GroupedOrder.objects.count() == 2
        new_grouped_order = models.GroupedOrder.objects.last()
        assert new_grouped_order.name == "gr order test - copie"
        assert new_grouped_order.delivery_date == grouped_order.delivery_date
        assert new_grouped_order.deadline == grouped_order.deadline
        assert new_grouped_order.place == grouped_order.place
        assert new_grouped_order.orga == auth.get_user(client_log)
        assert new_grouped_order.description == grouped_order.description
        assert new_grouped_order.item_set.count() == grouped_order.item_set.count()
        assert new_grouped_order.item_set.first().ordered_nb == 0
        assert models.GroupedOrder.objects.count() == 2

        # redirection
        assert response.status_code == 302
        assert response.url == reverse(
            "order:update_grouped_order", kwargs={"code": new_grouped_order.code}
        )

        # The initial grouped order did not change
        assert grouped_order.item_set.first().ordered_nb == 4

    def test_duplicate_grouped_order__not_orga(self, client_log, other_user):
        """A user that is not orga gets the duplicate view. They get a 403 error."""
        grouped_order = create_grouped_order(
            days_before_delivery_date=5,
            days_before_deadline=2,
            name="gr order test",
            orga_user=other_user,
        )
        assert models.GroupedOrder.objects.count() == 1

        # get the duplicate view
        duplicate_view_url = reverse(
            "order:duplicate_grouped_order", kwargs={"code": grouped_order.code}
        )
        response = client_log.get(duplicate_view_url)
        assert response.status_code == 403

        assert models.GroupedOrder.objects.count() == 1

    def test_duplicate_grouped_order__anonymous(self, client, other_user):
        """An anonymous user gets the duplicate view. They get redirected to login page"""
        grouped_order = create_grouped_order(
            days_before_delivery_date=5,
            days_before_deadline=2,
            name="gr order test",
            orga_user=other_user,
        )
        assert models.GroupedOrder.objects.count() == 1

        # get the duplicate view
        duplicate_view_url = reverse(
            "order:duplicate_grouped_order", kwargs={"code": grouped_order.code}
        )
        response = client.get(duplicate_view_url)
        assert response.status_code == 302
        assert response.url == f"{reverse('accounts:login')}?next={duplicate_view_url}"

        assert models.GroupedOrder.objects.count() == 1


class TestGroupedOrderSheetView:
    def test_get__not_orga(self, client_log, other_user):
        """A user that is not organizer of the GO accesses the sheet view.
        They get a 403 error"""
        grouped_order = create_grouped_order(
            days_before_delivery_date=5,
            days_before_deadline=2,
            name="gr order test",
            orga_user=other_user,
        )
        generate_sheet_url = reverse(
            "order:grouped_order_sheet",
            kwargs={
                "code": grouped_order.code,
            },
        )
        response = client_log.get(generate_sheet_url)
        assert response.status_code == 403

    def test_get__anonymous(self, client, other_user):
        """An anonymous user accesses the sheet view.
        They get redirected to login page"""
        grouped_order = create_grouped_order(
            days_before_delivery_date=5,
            days_before_deadline=2,
            name="gr order test",
            orga_user=other_user,
        )
        generate_sheet_url = reverse(
            "order:grouped_order_sheet",
            kwargs={
                "code": grouped_order.code,
            },
        )
        response = client.get(generate_sheet_url)
        assert response.status_code == 302
        assert response.url == f"{reverse('accounts:login')}?next={generate_sheet_url}"

    def test_get_pdf_sheet(self, client_log, other_user):
        """The orga of the grouped models.Order accesses the pdf sheet"""
        grouped_order = create_grouped_order(
            days_before_delivery_date=5,
            days_before_deadline=2,
            name="gr order test",
            orga_user=auth.get_user(client_log),
        )
        generate_sheet_url = reverse(
            "order:grouped_order_sheet",
            kwargs={
                "code": grouped_order.code,
            },
        )
        response = client_log.get(generate_sheet_url)
        assert response.status_code == 200
        assert response.context["grouped_order"] == grouped_order
        assert len(response.context["items"]) == 0
        assert len(response.context["orders_dict"]) == 0

        # we order some items in the grouped order
        order = order_items_in_grouped_order(grouped_order)
        response = client_log.get(generate_sheet_url)
        assert response.status_code == 200
        assert response.context["grouped_order"] == grouped_order
        assert len(response.context["items"]) == 2
        assert response.context["orders_dict"][order] == [3, 2]
        assert response.context["grouped_order"].total_price == 35

        # test if the orders are sorted by last names
        orders = list(response.context["orders_dict"].keys())
        assert orders[0].author.last_name == "alescargot"
        assert orders[0].author.first_name == "bob"
        assert orders[1].author.last_name == "alescargot"
        assert orders[1].author.first_name == "bobby"
        assert orders[2].author.last_name == "lescargot"


class TestExportGroupOrderEmailAdressesToDownloadView:
    def test_user_not_logged_gets_redirected(self, client, other_user):
        grouped_order = create_grouped_order(
            days_before_delivery_date=5,
            days_before_deadline=2,
            name="gr order test",
            orga_user=other_user,
        )
        email_list_view_url = reverse(
            "order:email_list",
            kwargs={
                "code": grouped_order.code,
            },
        )
        assert auth.get_user(client).is_anonymous
        response = client.get(email_list_view_url)
        assert response.status_code == 302
        assert response.url.startswith(reverse("accounts:login"))
        assert response.url.endswith(email_list_view_url)

    def test_user_not_orga_forbidden(self, client_log, other_user):
        grouped_order = create_grouped_order(
            days_before_delivery_date=5,
            days_before_deadline=2,
            name="gr order test",
            orga_user=other_user,
        )
        email_list_view_url = reverse(
            "order:email_list",
            kwargs={
                "code": grouped_order.code,
            },
        )
        response = client_log.get(email_list_view_url)
        assert response.status_code == 403

    def test_email_addresses(self, client_log):
        grouped_order = create_grouped_order(
            days_before_delivery_date=5,
            days_before_deadline=2,
            name="gr order test",
            orga_user=auth.get_user(client_log),
        )
        email_list_view_url = reverse(
            "order:email_list",
            kwargs={
                "code": grouped_order.code,
            },
        )
        response = client_log.get(email_list_view_url)
        assert response.status_code == 200
        assert response.content.decode() == ""

        email = order_items_in_grouped_order(grouped_order).author.email
        response = client_log.get(email_list_view_url)
        assert response.status_code == 200
        assert email in response.content.decode()

    def test_export_format_csv(self, client_log):
        grouped_order = create_grouped_order(
            days_before_delivery_date=5,
            days_before_deadline=2,
            name="gr order test",
            orga_user=auth.get_user(client_log),
        )
        item = models.Item.objects.create(
            name="test item 1", grouped_order=grouped_order, price=2
        )

        overview_url = reverse(
            "order:grouped_order_overview",
            kwargs={
                "code": grouped_order.code,
            },
        )
        order_url = reverse(
            "order:order",
            kwargs={
                "code": grouped_order.code,
            },
        )
        client_log.post(
            order_url,
            {
                f"quantity_{item.pk}": [4, 0],
                "first_name": "Prénom",
                "last_name": "Nom",
                "phone": "0645632569",
                "email": "test@mail.fr",
                "note": "",
            },
        )
        email_list_view_url = (
            reverse(
                "order:email_list",
                kwargs={
                    "code": grouped_order.code,
                },
            )
            + "?format=csv"
        )
        response = client_log.get(email_list_view_url)
        assert response.status_code == 200
        assert response["Content-Type"] == "text/csv"
        content = response.content.decode()
        assert "test@mail.fr\r\n" in content

    def test_export_format_default(self, client_log):
        grouped_order = create_grouped_order(
            days_before_delivery_date=5,
            days_before_deadline=2,
            name="gr order test",
            orga_user=auth.get_user(client_log),
        )
        item = models.Item.objects.create(
            name="test item 1", grouped_order=grouped_order, price=2
        )
        order_url = reverse(
            "order:order",
            kwargs={
                "code": grouped_order.code,
            },
        )
        client_log.post(
            order_url,
            {
                f"quantity_{item.pk}": [4, 0],
                "first_name": "Prénom",
                "last_name": "Nom",
                "phone": "0645632569",
                "email": "test@mail.fr",
                "note": "",
            },
        )
        email_list_view_url = reverse(
            "order:email_list",
            kwargs={
                "code": grouped_order.code,
            },
        )
        response = client_log.get(email_list_view_url)
        assert response.status_code == 200
        assert response["Content-Type"] == "text/html; charset=utf-8"
        content = response.content.decode()
        assert "test@mail.fr" in content


class TestExportGroupedOrderToCSVView:
    def test_user_not_logged_gets_redirected(self, client, other_user):
        """
        A user that is not logged accesses the csv view. They get redirected to the login view
        """
        grouped_order = create_grouped_order(
            days_before_delivery_date=5,
            days_before_deadline=2,
            name="gr order test",
            orga_user=other_user,
        )
        csv_view_url = reverse(
            "order:grouped_order_csv_export",
            kwargs={
                "code": grouped_order.code,
            },
        )
        assert auth.get_user(client).is_anonymous
        response = client.get(csv_view_url)
        assert response.status_code == 302
        assert response.url.startswith(reverse("accounts:login"))
        assert response.url.endswith(csv_view_url)

    def test_user_not_orga_forbidden(self, client_log, other_user):
        """
        A user that is not orga cannot accesses the csv view.
        They get a 403 forbidden error
        """
        grouped_order = create_grouped_order(
            days_before_delivery_date=5,
            days_before_deadline=2,
            name="gr order test",
            orga_user=other_user,
        )
        csv_view_url = reverse(
            "order:grouped_order_csv_export",
            kwargs={
                "code": grouped_order.code,
            },
        )
        response = client_log.get(csv_view_url)
        assert response.status_code == 403

    def test_csv_export(self, client_log):
        """
        The grouped order orga accesses the csv view
        """
        grouped_order = create_grouped_order(
            days_before_delivery_date=5,
            days_before_deadline=2,
            name="gr order test",
            orga_user=auth.get_user(client_log),
        )

        order = order_items_in_grouped_order(grouped_order)
        csv_view_url = reverse(
            "order:grouped_order_csv_export",
            kwargs={
                "code": grouped_order.code,
            },
        )
        response = client_log.get(csv_view_url)
        assert response.status_code == 200

        content = response.content.decode("utf-8")
        csv_reader = csv.reader(StringIO(content), delimiter=";")
        body = list(csv_reader)
        created_date = f"{timezone.now().strftime('%d/%m/%Y')}"
        created_time = f"{timezone.now().strftime('%H:%M')}"
        assert body == [
            [
                "",
                "",
                "test item",
                "test item 2",
                "Prix de la commande",
                "Mail",
                "Téléphone",
                "Note",
                "Date",
                "Heure",
            ],
            ["", "Prix unitaire TTC (€)", "2,00", "9,00"],
            ["Nom", "Prénom"],
            [
                "alescargot",
                "bob",
                "1",
                "0",
                "2,00",
                "bob2@escargot.fr",
                "'000",
                "",
                created_date,
                created_time,
            ],
            [
                "alescargot",
                "bobby",
                "0",
                "1",
                "9,00",
                "bob3@escargot.fr",
                "'000",
                "",
                created_date,
                created_time,
            ],
            [
                "lescargot",
                "bob",
                "3",
                "2",
                "24,00",
                "bob@escargot.fr",
                "'000",
                "",
                created_date,
                created_time,
            ],
            ["", "TOTAL", "4", "3", "35,00"],
        ]
