Exemplo n.º 1
0
 def test_raise_if_trying_to_cancel_someone_else_s_booking(self):
     booking = factories.BookingFactory()
     other_user = users_factories.UserFactory()
     with pytest.raises(exceptions.BookingDoesntExist):
         api.cancel_booking_by_beneficiary(other_user, booking)
     assert not booking.isCancelled
     assert not booking.cancellationReason
Exemplo n.º 2
0
    def test_raise_if_booking_is_already_used(self):
        booking = booking_factories.UsedIndividualBookingFactory()

        with pytest.raises(exceptions.BookingIsAlreadyUsed):
            api.cancel_booking_by_beneficiary(booking.individualBooking.user, booking)
        assert not booking.isCancelled
        assert booking.status is not BookingStatus.CANCELLED
Exemplo n.º 3
0
    def test_cancel_booking(self):
        stock = offers_factories.StockFactory(offer__bookingEmail="*****@*****.**")
        booking = booking_factories.IndividualBookingFactory.create_batch(20, stock=stock)[0]

        queries = 1  # select booking
        queries += 1  # select stock for update
        queries += 1  # refresh booking
        queries += 3  # update stock ; update booking ; release savepoint
        queries += 8  # (update batch attributes): select booking ; individualBooking ; user ; user.bookings ; deposit ; user_offerer ; favorites ; stock
        queries += 1  # select offer
        queries += 2  # insert email ; release savepoint
        queries += 4  # (TODO: optimize) select booking ; stock ; offer ; user
        queries += 1  # select bookings of same stock with users joinedloaded to avoid N+1 requests
        queries += 2  # select venue ; offerer
        queries += 2  # insert email ; release savepoint
        with assert_num_queries(queries):
            api.cancel_booking_by_beneficiary(booking.individualBooking.user, booking)

        # cancellation can trigger more than one request to Batch
        assert len(push_testing.requests) >= 1

        assert booking.isCancelled
        assert booking.status is BookingStatus.CANCELLED
        assert booking.cancellationReason == BookingCancellationReasons.BENEFICIARY
        assert len(mails_testing.outbox) == 2
        email_data1 = mails_testing.outbox[0].sent_data
        assert email_data1["Mj-TemplateID"] == 1091464  # to beneficiary
        email_data2 = mails_testing.outbox[1].sent_data
        assert email_data2["MJ-TemplateID"] == 780015  # to offerer
Exemplo n.º 4
0
 def test_raise_if_trying_to_cancel_someone_else_s_booking(self):
     booking = booking_factories.IndividualBookingFactory()
     other_beneficiary = users_factories.BeneficiaryGrant18Factory()
     with pytest.raises(exceptions.BookingDoesntExist):
         api.cancel_booking_by_beneficiary(other_beneficiary, booking)
     assert not booking.isCancelled
     assert booking.status is not BookingStatus.CANCELLED
     assert not booking.cancellationReason
Exemplo n.º 5
0
    def test_cancel_booking(self, mocked_send_raw_email):
        booking = factories.BookingFactory()

        api.cancel_booking_by_beneficiary(booking.user, booking)

        assert booking.isCancelled
        assert booking.cancellationReason == BookingCancellationReasons.BENEFICIARY
        email_data1 = mocked_send_raw_email.call_args_list[0][1]["data"]
        assert email_data1["Mj-TemplateID"] == 1091464  # to beneficiary
        email_data2 = mocked_send_raw_email.call_args_list[1][1]["data"]
        assert email_data2["MJ-TemplateID"] == 780015  # to offerer
Exemplo n.º 6
0
    def test_user_can_cancel_even_if_expired_deposit(self):
        # The user once booked.
        booking = factories.BookingFactory()
        user = booking.user
        booking_to_cancel = factories.BookingFactory(user=user)

        # But now their deposit expired.
        self._expire_deposit(user)

        # They should be able to cancel their booking.
        api.cancel_booking_by_beneficiary(user, booking_to_cancel)
        assert booking_to_cancel.isCancelled
Exemplo n.º 7
0
    def test_cancel_booking(self):
        booking = factories.BookingFactory()

        api.cancel_booking_by_beneficiary(booking.user, booking)

        assert booking.isCancelled
        assert booking.cancellationReason == BookingCancellationReasons.BENEFICIARY
        assert len(mails_testing.outbox) == 2
        email_data1 = mails_testing.outbox[0].sent_data
        assert email_data1["Mj-TemplateID"] == 1091464  # to beneficiary
        email_data2 = mails_testing.outbox[1].sent_data
        assert email_data2["MJ-TemplateID"] == 780015  # to offerer
Exemplo n.º 8
0
 def test_raise_if_event_too_close(self):
     event_date_too_close_to_cancel_booking = datetime.now() + timedelta(
         days=1)
     booking = factories.BookingFactory(
         stock__beginningDatetime=event_date_too_close_to_cancel_booking, )
     with pytest.raises(exceptions.CannotCancelConfirmedBooking) as exc:
         api.cancel_booking_by_beneficiary(booking.user, booking)
     assert not booking.isCancelled
     assert not booking.cancellationReason
     assert exc.value.errors["booking"] == [
         "Impossible d'annuler une réservation plus de 48h après l'avoir "
         "réservée et moins de 48h avant le début de l'événement"
     ]
Exemplo n.º 9
0
    def test_cancel_booking(self, app):
        booking = booking_factories.IndividualBookingFactory(stock__dnBookedQuantity=1)

        # open a second connection on purpose and lock the stock
        engine = create_engine(app.config["SQLALCHEMY_DATABASE_URI"])
        with engine.connect() as connection:
            connection.execute(
                text("""SELECT * FROM stock WHERE stock.id = :stock_id FOR UPDATE"""), stock_id=booking.stockId
            )

            with pytest.raises(sqlalchemy.exc.OperationalError):
                api.cancel_booking_by_beneficiary(booking.individualBooking.user, booking)

        assert models.Booking.query.filter().count() == 1
        assert models.Booking.query.filter(models.Booking.isCancelled == True).count() == 0
Exemplo n.º 10
0
 def test_raise_if_event_too_close_and_booked_long_ago(self):
     booking_date_too_long_ago_to_cancel_booking = datetime.utcnow() - timedelta(days=2, minutes=1)
     event_date_too_close_to_cancel_booking = datetime.now() + timedelta(days=1)
     booking = booking_factories.IndividualBookingFactory(
         stock__beginningDatetime=event_date_too_close_to_cancel_booking,
         dateCreated=booking_date_too_long_ago_to_cancel_booking,
     )
     with pytest.raises(exceptions.CannotCancelConfirmedBooking) as exc:
         api.cancel_booking_by_beneficiary(booking.individualBooking.user, booking)
     assert not booking.isCancelled
     assert booking.status is not BookingStatus.CANCELLED
     assert not booking.cancellationReason
     assert exc.value.errors["booking"] == [
         "Impossible d'annuler une réservation plus de 48h après l'avoir "
         "réservée et moins de 48h avant le début de l'événement"
     ]
def test_offer_indexation_on_booking_cycle(app):
    beneficiary = users_factories.BeneficiaryGrant18Factory()
    stock = offers_factories.StockFactory(quantity=1)
    offer = stock.offer
    assert search_testing.search_store["offers"] == {}

    search.async_index_offer_ids([offer.id])
    assert search_testing.search_store["offers"] == {}

    search.index_offers_in_queue()
    assert offer.id in search_testing.search_store["offers"]

    booking = bookings_api.book_offer(beneficiary, stock.id, quantity=1)
    search.index_offers_in_queue()
    assert offer.id not in search_testing.search_store["offers"]

    bookings_api.cancel_booking_by_beneficiary(beneficiary, booking)
    search.index_offers_in_queue()
    assert offer.id in search_testing.search_store["offers"]
Exemplo n.º 12
0
    def test_cancel_booking_twice(self):
        booking = booking_factories.IndividualBookingFactory()
        initial_quantity = booking.stock.dnBookedQuantity

        api.cancel_booking_by_beneficiary(booking.individualBooking.user, booking)

        # cancellation can trigger more than one request to Batch
        assert len(push_testing.requests) >= 1

        assert booking.isCancelled
        assert booking.status is BookingStatus.CANCELLED
        assert booking.stock.dnBookedQuantity == (initial_quantity - 1)

        api.cancel_booking_by_beneficiary(booking.individualBooking.user, booking)

        # cancellation can trigger more than one request to Batch
        assert len(push_testing.requests) >= 1

        assert booking.isCancelled
        assert booking.status is BookingStatus.CANCELLED
        assert booking.stock.dnBookedQuantity == (initial_quantity - 1)
Exemplo n.º 13
0
def cancel_booking(user: User, booking_id: int) -> None:
    booking = (Booking.query.join(IndividualBooking).filter(
        Booking.id == booking_id,
        IndividualBooking.userId == user.id).first_or_404())
    try:
        bookings_api.cancel_booking_by_beneficiary(user, booking)
    except exceptions.BookingIsAlreadyUsed:
        raise ApiErrors({
            "code": "ALREADY_USED",
            "message": "La réservation a déjà été utilisée."
        })
    except exceptions.CannotCancelConfirmedBooking:
        raise ApiErrors({
            "code": "CONFIRMED_BOOKING",
            "message": "La date limite d'annulation est dépassée."
        })
    except RuntimeError:
        logger.error(
            "Unexpected call to cancel_booking_by_beneficiary with non-beneficiary user %s",
            user.id)
        raise ApiErrors()
Exemplo n.º 14
0
def cancel_booking(booking_id: str):
    booking = Booking.query.filter_by(id=dehumanize(booking_id)).first_or_404()

    bookings_api.cancel_booking_by_beneficiary(current_user, booking)

    return jsonify(serialize_booking_minimal(booking)), 200
Exemplo n.º 15
0
    def test_raise_if_booking_is_already_used(self):
        booking = factories.BookingFactory(isUsed=True)

        with pytest.raises(exceptions.BookingIsAlreadyUsed):
            api.cancel_booking_by_beneficiary(booking.user, booking)
        assert not booking.isCancelled
Exemplo n.º 16
0
 def test_do_not_sync_algolia_if_feature_is_disabled(
         self, mocked_add_offer_id):
     booking = factories.BookingFactory()
     api.cancel_booking_by_beneficiary(booking.user, booking)
     mocked_add_offer_id.assert_not_called()