Exemple #1
0
        def when_email_has_special_characters_but_is_not_url_encoded(self, app):
            # Given
            user = create_user(email="*****@*****.**")
            user_admin = create_user(email="*****@*****.**")
            offerer = create_offerer()
            user_offerer = create_user_offerer(user_admin, offerer, is_admin=True)
            venue = create_venue(offerer)
            offer = create_offer_with_event_product(venue, event_name="Event Name")
            event_occurrence = create_event_occurrence(offer)
            stock = create_stock_from_event_occurrence(event_occurrence, price=0)
            booking = create_booking(user=user, stock=stock, venue=venue)

            repository.save(user_offerer, booking)
            url = "/bookings/token/{}?email={}".format(booking.token, user.email)

            # When
            response = TestClient(app.test_client()).with_auth("*****@*****.**").patch(url)
            # Then
            assert response.status_code == 404
    def when_expected_parameters_are_not_given(self, app):
        # Given
        user = users_factories.BeneficiaryGrant18Factory(
            email="*****@*****.**")
        offerer = create_offerer()
        venue = create_venue(offerer,
                             postal_code="29100",
                             siret="12345678912341")
        offer = create_offer_with_thing_product(venue, thumb_count=0)
        mediation = create_mediation(offer, is_active=True)
        favorite = create_favorite(mediation=mediation, offer=offer, user=user)
        repository.save(favorite)

        # When
        response = TestClient(app.test_client()).with_session_auth(
            user.email).delete("/favorites/1")

        # Then
        assert response.status_code == 404
Exemple #3
0
    def test_should_send_mail_to_offerer_and_pass_culture_administration_when_feature_send_mail_to_users_is_enabled(
        self, feature_send_mail_to_users_enabled
    ):
        # Given
        user = create_user()
        offerer = create_offerer()
        venue = create_venue(offerer)
        offer = create_offer_with_event_product(venue)
        event_occurrence = create_event_occurrence(offer)
        stock = create_stock_from_event_occurrence(event_occurrence)
        booking = create_booking(user=user, stock=stock)
        bookings = [booking]
        recipients = "[email protected], [email protected]"

        # When
        mailjet_data = retrieve_offerer_bookings_recap_email_data_after_offerer_cancellation(bookings, recipients)

        # Then
        assert mailjet_data["To"] == "[email protected], [email protected]"
Exemple #4
0
    def should_not_connect_venue_when_synchronization_is_not_allowed(
            self, app):
        # Given
        offerer = create_offerer()
        venue = create_venue(offerer, siret="12345678912345")
        provider = offerers_factories.APIProviderFactory(name="FNAC")

        repository.save(venue)

        self.find_by_id.return_value = venue
        stock_repository = MagicMock()
        stock_repository.can_be_synchronized.return_value = False

        # when
        with pytest.raises(VenueSiretNotRegistered):
            connect_venue_to_provider(venue, provider)

        # then
        assert not VenueProvider.query.first()
        def when_user_has_rights_and_regular_offer(self, app):
            # Given
            user = users_factories.UserFactory(email="*****@*****.**", publicName="John Doe")
            admin_user = create_user(email="*****@*****.**")
            offerer = create_offerer()
            create_user_offerer(admin_user, offerer)
            venue = create_venue(offerer, name="Venue name", address="Venue address")
            offer = create_offer_with_event_product(venue=venue, event_name="Event Name", event_type=EventType.CINEMA)
            four_days_from_now = datetime.utcnow() + timedelta(days=4)
            event_occurrence = create_event_occurrence(offer, beginning_datetime=four_days_from_now)
            stock = create_stock_from_event_occurrence(event_occurrence, price=12)
            unconfirmed_booking = create_booking(
                user=user, quantity=3, stock=stock, venue=venue, date_created=datetime.utcnow() - timedelta(hours=48)
            )
            repository.save(unconfirmed_booking)
            url = f"/v2/bookings/token/{unconfirmed_booking.token}"

            # When
            response = TestClient(app.test_client()).with_auth("*****@*****.**").get(url)

            # Then
            assert response.headers["Content-type"] == "application/json"
            assert response.status_code == 200
            assert response.json == {
                "bookingId": humanize(unconfirmed_booking.id),
                "dateOfBirth": "",
                "datetime": format_into_utc_date(stock.beginningDatetime),
                "ean13": "",
                "email": "*****@*****.**",
                "formula": "PLACE",
                "isUsed": False,
                "offerId": offer.id,
                "offerName": "Event Name",
                "offerType": "EVENEMENT",
                "phoneNumber": "",
                "price": 12.0,
                "publicOfferId": humanize(offer.id),
                "quantity": 3,
                "userName": "******",
                "venueAddress": "Venue address",
                "venueDepartementCode": "93",
                "venueName": "Venue name",
            }
Exemple #6
0
    def test_should_not_get_offer_with_a_date_between_today_and_the_15_04_and_another_after_15_04(
            self, app):
        # Given
        offerer = create_offerer()
        venue = create_venue(offerer)
        offer = create_offer_with_event_product(venue)
        stock1 = create_stock(beginning_datetime=datetime(2020, 4, 16),
                              offer=offer)
        stock2 = create_stock(beginning_datetime=datetime(2020, 4, 14),
                              offer=offer)

        repository.save(stock1, stock2)

        # When
        offers = build_query_offers_with_max_stock_date_between_today_and_end_of_quarantine(
            FIRST_DAY_AFTER_QUARANTINE, TODAY).all()

        # Then
        assert offers == []
Exemple #7
0
        def when_booking_is_not_provided_at_all(self, app):
            # Given
            user = create_user(email="*****@*****.**")
            offerer = create_offerer()
            venue = create_venue(offerer)
            offer = create_offer_with_event_product(venue,
                                                    event_name="Event Name")
            event_occurrence = create_event_occurrence(offer)
            stock = create_stock_from_event_occurrence(event_occurrence,
                                                       price=0)
            booking = create_booking(user=user, stock=stock, venue=venue)
            repository.save(booking)
            url = "/v2/bookings/token/"

            # When
            response = TestClient(app.test_client()).get(url)

            # Then
            assert response.status_code == 404
    def test_should_return_false_when_stock_booking_limit_is_past(self, app):
        # Given
        user = create_user()
        offerer = create_offerer()
        venue = create_venue(offerer)
        offer = create_offer_with_thing_product(venue, is_active=True)
        stock = create_stock_from_offer(offer,
                                        price=0,
                                        quantity=2,
                                        booking_limit_datetime=datetime.now() -
                                        timedelta(days=6))
        booking = create_booking(user=user, stock=stock, quantity=2)
        repository.save(booking)

        # When
        is_active = _is_offer_active_for_recap(stock)

        # Then
        assert not is_active
Exemple #9
0
    def test_should_return_event_data_when_booking_is_on_an_event(self):
        # Given
        beginning_datetime = datetime(2019,
                                      7,
                                      20,
                                      12,
                                      0,
                                      0,
                                      tzinfo=timezone.utc)

        user = create_user()
        offerer = create_offerer()
        venue = create_venue(offerer)
        offer = create_offer_with_event_product(venue)
        event_occurrence = create_event_occurrence(
            offer, beginning_datetime=beginning_datetime)
        stock = create_stock_from_event_occurrence(event_occurrence, price=20)
        booking = create_booking(user=user, stock=stock)

        # When
        mailjet_data = retrieve_data_to_warn_beneficiary_after_pro_booking_cancellation(
            booking)

        # Then
        assert mailjet_data == {
            "FromEmail": "*****@*****.**",
            "MJ-TemplateID": 1116690,
            "MJ-TemplateLanguage": True,
            "To": "*****@*****.**",
            "Vars": {
                "event_date": "samedi 20 juillet 2019",
                "event_hour": "14h",
                "is_event": 1,
                "is_free_offer": 0,
                "is_online": 0,
                "is_thing": 0,
                "offer_name": booking.stock.offer.name,
                "offer_price": "20",
                "offerer_name": booking.stock.offer.venue.managingOfferer.name,
                "user_first_name": user.firstName,
                "venue_name": booking.stock.offer.venue.name,
            },
        }
def test_should_not_delete_stock_from_allocine_when_not_sof_deleted(app):
    # Given
    offerer = create_offerer()
    venue = create_venue(offerer)
    allocine_provider = get_provider_by_local_class("AllocineStocks")
    offer = create_offer_with_thing_product(venue)
    stock = create_stock(
        id_at_providers="TW92aWU6MjczNjU5%38986972800011-1",
        is_soft_deleted=False,
        last_provider_id=allocine_provider.id,
        offer=offer,
    )
    repository.save(stock)

    # When
    delete_corrupted_allocine_stocks()

    # Then
    assert Stock.query.count() == 1
    def test_should_return_mailjet_data_with_no_ongoing_booking(
            self, mock_is_offer_active, mock_build_pc_pro_offer_link):
        # Given
        user = create_user(email="*****@*****.**",
                           public_name="Jean Dupont")
        offerer = create_offerer()
        venue = create_venue(offerer, name="Venue name", departement_code="75")
        offer = create_offer_with_event_product(venue, event_name="My Event")
        stock = create_stock_from_offer(offer,
                                        price=12.52,
                                        beginning_datetime=datetime(
                                            2019, 10, 9, 10, 20, 00))
        booking = create_booking(user=user,
                                 stock=stock,
                                 venue=venue,
                                 is_cancelled=True,
                                 quantity=2)

        # When
        mailjet_data = retrieve_offerer_booking_recap_email_data_after_user_cancellation(
            booking)

        # Then
        assert mailjet_data == {
            "MJ-TemplateID": 780015,
            "MJ-TemplateLanguage": True,
            "Vars": {
                "departement": "75",
                "nom_offre": "My Event",
                "lien_offre_pcpro": "http://pc_pro.com/offer_link",
                "nom_lieu": "Venue name",
                "prix": "12.52",
                "is_event": 1,
                "date": "09-Oct-2019",
                "heure": "12h20",
                "quantite": 2,
                "user_name": "Jean Dupont",
                "user_email": "*****@*****.**",
                "is_active": 1,
                "nombre_resa": 0,
                "users": [],
            },
        }
def test_should_not_delete_stock_from_other_provider_than_allocine(app):
    # Given
    offerer = create_offerer()
    venue = create_venue(offerer)
    provider = ProviderFactory(localClass="not allociné")
    offer = create_offer_with_thing_product(venue)
    stock = create_stock(
        id_at_providers="TW92aWU6MjczNjU5%38986972800011-1",
        is_soft_deleted=True,
        last_provider_id=provider.id,
        offer=offer,
    )
    repository.save(stock)

    # When
    delete_corrupted_allocine_stocks()

    # Then
    assert Stock.query.count() == 1
def test_should_not_delete_stock_from_allocine_with_new_id_format(app):
    # Given
    offerer = create_offerer()
    venue = create_venue(offerer)
    allocine_provider = get_provider_by_local_class("AllocineStocks")
    offer = create_offer_with_thing_product(venue)
    stock = create_stock(
        id_at_providers="TW92aWU6MjczNTc5%31940406700021#LOCAL/2020-01-18T14:00:00",
        is_soft_deleted=True,
        last_provider_id=allocine_provider.id,
        offer=offer,
    )
    repository.save(stock)

    # When
    delete_corrupted_allocine_stocks()

    # Then
    assert Stock.query.count() == 1
Exemple #14
0
    def test_should_call_run_process_in_one_off_container_function(
            self, mock_run_process_in_one_off_container, app):
        # Given
        mock_run_process_in_one_off_container.return_value = "azertyTE7898RTYUIZERTYUI"
        titelive_provider = activate_provider("TiteLiveStocks")
        offerer = create_offerer()
        venue1 = create_venue(offerer)
        venue_provider = create_venue_provider(venue1, titelive_provider)
        repository.save(venue_provider)
        update_venue_provider_command = (
            f"python src/pcapi/scripts/pc.py update_providables"
            f" --venue-provider-id {venue_provider.id}")

        # When
        do_sync_venue_provider(venue_provider)

        # Then
        mock_run_process_in_one_off_container.assert_called_once_with(
            update_venue_provider_command)
    def test_should_update_venue_type_whith_type_from_read_file_when_id_match(
            self, stub_read_venue_type_from_file, app, capsys):
        # Given
        offerer = create_offerer()
        old_venue_type = create_venue_type("old_type", 1)
        new_venue_type = create_venue_type("new_type", 2)
        venue = create_venue(offerer, idx=121, venue_type_id=1)
        repository.save(venue, old_venue_type, new_venue_type)

        stub_read_venue_type_from_file.return_value = [("121", "new_type")]

        # When
        update_venue_type("fake/path")

        # Then
        captured = capsys.readouterr()
        updated_venue = Venue.query.one()
        assert updated_venue.venueTypeId == 2
        assert "1 venues have been updated" in captured.out
Exemple #16
0
    def test_allocine_venue_provider_should_inherit_from_venue_provider(
            self, app):
        offerer = create_offerer()
        venue = create_venue(offerer)

        provider_allocine = activate_provider("AllocineStocks")

        allocine_venue_provider = create_allocine_venue_provider(
            venue, provider_allocine, is_duo=True)

        repository.save(allocine_venue_provider)

        assert VenueProvider.query.count() == 1
        assert AllocineVenueProvider.query.count() == 1
        allocine_vp = VenueProvider.query.filter(
            VenueProvider.providerId == provider_allocine.id).first()
        assert isinstance(allocine_vp, AllocineVenueProvider)
        assert allocine_vp.isDuo
        assert allocine_vp.isFromAllocineProvider
    def test_should_not_update_venue_type_whith_type_from_read_file_when_type_label_does_not_match(
            self, stub_read_venue_type_from_file, app, capsys):
        # Given
        offerer = create_offerer()
        old_venue_type = create_venue_type("old_type", 1)
        venue = create_venue(offerer, idx=121, venue_type_id=1)
        repository.save(venue, old_venue_type)

        stub_read_venue_type_from_file.return_value = [("121", "other_type")]

        # When
        update_venue_type("fake/path")

        # Then
        captured = capsys.readouterr()
        updated_venue = Venue.query.one()
        assert updated_venue.venueTypeId == 1
        assert "venue type id not found for label : other_type and venueId : 121" in captured.out
        assert "0 venues have been updated" in captured.out
    def test_should_raise_error_when_price_is_negative(self, app):
        # Given
        offerer = create_offerer()
        venue = create_venue(offerer)
        allocine_provider = get_provider_by_local_class("AllocineStocks")
        allocine_provider.isActive = True
        allocine_venue_provider = create_allocine_venue_provider(
            venue, allocine_provider)
        venue_provider_price_rule = create_allocine_venue_provider_price_rule(
            allocine_venue_provider, price_rule=PriceRule.default, price=-4)

        # When
        with pytest.raises(ApiErrors) as error:
            repository.save(venue_provider_price_rule)

        # Then
        assert error.value.errors["global"] == [
            "Vous ne pouvez renseigner un prix négatif"
        ]
Exemple #19
0
    def test_should_not_delete_objects_when_objects_are_not_eligible_and_were_not_indexed(
        self,
        mock_build_object,
        mock_add_objects,
        mock_delete_objects,
        mock_add_to_indexed_offers,
        mock_check_offer_exists,
        mock_delete_indexed_offers,
        app,
    ):
        # Given
        client = MagicMock()
        client.pipeline = MagicMock()
        client.pipeline.return_value = MagicMock()
        mock_pipeline = client.pipeline()
        mock_pipeline.execute = MagicMock()
        mock_pipeline.reset = MagicMock()
        offerer = create_offerer(is_active=True, validation_token=None)
        venue = create_venue(offerer=offerer, validation_token=None)
        offer1 = create_offer_with_thing_product(venue=venue, is_active=True)
        stock1 = create_stock(booking_limit_datetime=TOMORROW,
                              offer=offer1,
                              quantity=0)
        offer2 = create_offer_with_thing_product(venue=venue, is_active=True)
        stock2 = create_stock(booking_limit_datetime=TOMORROW,
                              offer=offer2,
                              quantity=0)
        repository.save(stock1, stock2)
        mock_check_offer_exists.side_effect = [False, False]

        # When
        process_eligible_offers(client=client,
                                offer_ids=[offer1.id, offer2.id],
                                from_provider_update=False)

        # Then
        mock_build_object.assert_not_called()
        mock_add_objects.assert_not_called()
        mock_add_to_indexed_offers.assert_not_called()
        mock_delete_objects.assert_not_called()
        mock_delete_indexed_offers.assert_not_called()
        mock_pipeline.execute.assert_not_called()
        mock_pipeline.reset.assert_not_called()
    def test_should_raise_error_when_saving_wrong_format_price(self, app):
        # Given
        offerer = create_offerer()
        venue = create_venue(offerer)
        allocine_provider = get_provider_by_local_class("AllocineStocks")
        allocine_venue_provider = create_allocine_venue_provider(
            venue, allocine_provider)
        price = "wrong_price_format"
        venue_provider_price_rule = create_allocine_venue_provider_price_rule(
            allocine_venue_provider, price_rule=PriceRule.default, price=price)

        # When
        with pytest.raises(ApiErrors) as error:
            repository.save(venue_provider_price_rule)

        # Then
        assert error.value.errors == {
            "global": ["Le prix doit être un nombre décimal"]
        }
Exemple #21
0
    def should_connect_venue_when_synchronization_is_allowed(self, app):
        # Given
        offerer = create_offerer()

        venue = create_venue(offerer)
        provider = offerers_factories.APIProviderFactory()

        repository.save(venue)

        self.find_by_id.return_value = venue
        stock_repository = MagicMock()
        stock_repository.can_be_synchronized.return_value = True

        # When
        connect_venue_to_provider(venue, provider)

        # Then
        fnac_venue_provider = VenueProvider.query.one()
        assert fnac_venue_provider.venue == venue
        def when_user_is_not_attached_to_linked_offerer(self, app):
            # Given
            user = create_user()
            pro_user = create_user(email="*****@*****.**")
            offerer = create_offerer()
            venue = create_venue(offerer)
            stock = create_stock_with_event_offer(offerer, venue, price=0)

            booking = create_booking(user=user, stock=stock, venue=venue)
            repository.save(booking, pro_user)

            # When
            url = "/v2/bookings/keep/token/{}?email={}".format(booking.token, user.email)
            response = TestClient(app.test_client()).with_auth("*****@*****.**").patch(url)

            # Then
            assert response.status_code == 403
            assert response.json["user"] == ["Vous n'avez pas les droits suffisants pour valider cette contremarque."]
            assert Booking.query.get(booking.id).isUsed is False
        def when_user_doesnt_have_rights_and_token_exists(self, app):
            # Given
            user = create_user(email="*****@*****.**")
            querying_user = create_user(email="*****@*****.**")
            offerer = create_offerer()
            venue = create_venue(offerer)
            offer = create_offer_with_event_product(venue, event_name="Event Name")
            event_occurrence = create_event_occurrence(offer)
            stock = create_stock_from_event_occurrence(event_occurrence, price=0)
            booking = create_booking(user=user, stock=stock, venue=venue)
            repository.save(querying_user, booking)
            url = f"/v2/bookings/token/{booking.token}"

            # When
            response = TestClient(app.test_client()).with_auth("*****@*****.**").get(url)

            # Then
            assert response.status_code == 403
            assert response.json["user"] == ["Vous n'avez pas les droits suffisants pour valider cette contremarque."]
        def when_user_is_logged_in_and_booking_does_not_exist(self, app):
            # Given
            user = create_user()
            pro_user = create_user(email="*****@*****.**")
            offerer = create_offerer()
            user_offerer = create_user_offerer(pro_user, offerer)
            venue = create_venue(offerer)
            stock = create_stock_with_event_offer(offerer, venue, price=0)

            booking = create_booking(user=user, stock=stock, venue=venue)
            repository.save(booking, user_offerer)

            # When
            url = "/v2/bookings/keep/token/{}".format("123456")
            response = TestClient(app.test_client()).with_auth("*****@*****.**").patch(url)

            # Then
            assert response.status_code == 404
            assert response.json["global"] == ["Cette contremarque n'a pas été trouvée"]
Exemple #25
0
        def test_when_state_is_unknown(self, mock_application_details, app):
            # Given
            application_id = "8"
            offerer = create_offerer(siren="793875030")
            venue = create_venue(offerer, siret="79387503012345")
            repository.save(venue)
            unknown_status = "unknown_status"
            mock_application_details.return_value = venue_demarche_simplifiee_application_detail_response_with_siret(
                siret="79387503012345", bic="SOGEFRPP", iban="FR7630007000111234567890144", idx=8, state=unknown_status
            )

            # When
            with pytest.raises(CannotRegisterBankInformation) as error:
                self.save_venue_bank_informations.execute(application_id)

            # Then
            bank_information_count = BankInformation.query.count()
            assert bank_information_count == 0
            assert error.value.args == (f"Unknown Demarches Simplifiées state {unknown_status}",)
        def when_user_is_logged_in_and_booking_token_is_null(self, app):
            # Given
            user = create_user()
            pro_user = create_user(email="*****@*****.**")
            offerer = create_offerer()
            user_offerer = create_user_offerer(pro_user, offerer)
            venue = create_venue(offerer)
            stock = create_stock_with_event_offer(offerer, venue, price=0)

            booking = create_booking(user=user, stock=stock, venue=venue)

            repository.save(booking, user_offerer)

            # When
            url = "/v2/bookings/keep/token/"
            response = TestClient(app.test_client()).with_auth("*****@*****.**").patch(url)

            # Then
            assert response.status_code == 404
Exemple #27
0
    def test_should_return_mailjet_data_when_multiple_bookings_and_offer_is_a_thing(
        self, format_environment_for_email, build_pc_pro_offer_link, feature_send_mail_to_users_enabled
    ):
        # Given
        user = create_user(public_name="John Doe", first_name="John", last_name="Doe", email="*****@*****.**")
        offerer = create_offerer()
        venue = create_venue(offerer, name="La petite librairie", public_name="La grande librairie")
        thing_product = create_product_with_thing_type(thing_name="Le récit de voyage")
        offer = create_offer_with_thing_product(venue=venue, product=thing_product)
        stock = create_stock_from_offer(offer, price=0)
        booking = create_booking(user=user, stock=stock, token="12346", quantity=6)

        user2 = create_user(public_name="James Bond", first_name="James", last_name="Bond", email="*****@*****.**")
        booking2 = create_booking(user=user2, stock=stock, token="12345")
        recipients = "[email protected], [email protected]"
        bookings = [booking, booking2]

        # When
        mailjet_data = retrieve_offerer_bookings_recap_email_data_after_offerer_cancellation(bookings, recipients)

        # Then
        assert mailjet_data == {
            "FromEmail": "*****@*****.**",
            "MJ-TemplateID": 1116333,
            "MJ-TemplateLanguage": True,
            "To": "*****@*****.**",
            "Vars": {
                "offer_name": "Le récit de voyage",
                "lien_offre_pcpro": "http://pc_pro.com/offer_link",
                "venue_name": "La grande librairie",
                "price": "Gratuit",
                "is_event": 0,
                "event_date": "",
                "event_hour": "",
                "quantity": 7,
                "reservations_number": 2,
                "env": "-testing",
                "users": [
                    {"countermark": "12346", "email": "*****@*****.**", "firstName": "John", "lastName": "Doe"},
                    {"countermark": "12345", "email": "*****@*****.**", "firstName": "James", "lastName": "Bond"},
                ],
            },
        }
    def test_should_return_the_first_stock_price(self, app):
        # Given
        offerer = create_offerer()
        venue = create_venue(offerer=offerer)
        offer = create_offer_with_thing_product(venue=venue)
        stock1 = create_stock(offer=offer, price=7)
        stock2 = create_stock(offer=offer, price=5)
        stock3 = create_stock(offer=offer, price=10.3)
        repository.save(stock1, stock2, stock3)

        # When
        result = AlgoliaBackend.serialize_offer(offer)

        # Then
        assert result["offer"]["prices"] == [
            Decimal("5.00"),
            Decimal("7.00"),
            Decimal("10.30")
        ]
    def test_deactivate_offer_should_keep_booking_state(self, app):
        # given
        user = users_factories.UserFactory()
        offerer = create_offerer()
        venue = create_venue(offerer)
        existing_offer = create_offer_with_event_product(venue, is_active=True)
        stock = create_stock(offer=existing_offer)
        booking = create_booking(user=user, stock=stock)
        offers = [existing_offer]
        status = False

        # when
        updated_offers = update_is_active_status(offers, status)

        # then
        assert any(not updated_offer.isActive
                   for updated_offer in updated_offers)
        assert not booking.isCancelled
        assert booking.status is not BookingStatus.CANCELLED
Exemple #30
0
        def when_both_email_and_offer_id_are_missing(self, app):
            # Given
            user = create_user()
            offerer = create_offerer()
            venue = create_venue(offerer)
            stock = create_stock_with_event_offer(offerer, venue, price=0)
            booking = create_booking(user=user, stock=stock, venue=venue)
            repository.save(booking)
            url = "/bookings/token/{}".format(booking.token)

            # When
            response = TestClient(app.test_client()).patch(url)

            # Then
            assert response.status_code == 400
            assert response.json["offer_id"] == ["L'id de l'offre réservée est obligatoire dans l'URL [?offer_id=<id>]"]
            assert response.json["email"] == [
                "L'adresse email qui a servie à la réservation est obligatoire dans l'URL [?email=<email>]"
            ]