Esempio n. 1
0
    def should_not_invalidate_booking_token_when_event_is_reported_in_less_than_48_hours(
            self, mock_mark_as_unused, mock_update_confirmation_dates):
        # Given
        now = datetime.now()
        date_used_in_48_hours = datetime.now() + timedelta(days=2)
        event_in_3_days = now + timedelta(days=3)
        event_reported_in_less_48_hours = now + timedelta(days=1)
        offer = factories.EventOfferFactory()
        existing_stock = factories.StockFactory(
            offer=offer, beginningDatetime=event_in_3_days)
        booking = bookings_factories.BookingFactory(
            stock=existing_stock,
            dateCreated=now,
            isUsed=True,
            dateUsed=date_used_in_48_hours)
        edited_stock_data = StockEditionBodyModel(
            id=existing_stock.id,
            beginningDatetime=event_reported_in_less_48_hours,
            bookingLimitDatetime=existing_stock.bookingLimitDatetime,
            price=2,
        )

        # When
        api.upsert_stocks(offer_id=offer.id,
                          stock_data_list=[edited_stock_data])

        # Then
        updated_booking = Booking.query.get(booking.id)
        assert updated_booking.isUsed is True
        assert updated_booking.dateUsed == date_used_in_48_hours
Esempio n. 2
0
    def test_does_not_allow_edition_of_beginningDateTime_for_stocks_of_offers_synchronized_with_allocine(
            self, mock_update_confirmation_dates):
        # Given
        offer = factories.EventOfferFactory(
            lastProvider=offerers_factories.ProviderFactory(
                localClass="AllocineStocks"))
        date_in_the_future = datetime.utcnow() + timedelta(days=4)
        other_date_in_the_future = datetime.utcnow() + timedelta(days=6)
        existing_stock = factories.StockFactory(
            offer=offer, price=10, beginningDatetime=date_in_the_future)
        edited_stock_data = StockEditionBodyModel(
            id=existing_stock.id,
            beginningDatetime=other_date_in_the_future,
            bookingLimitDatetime=other_date_in_the_future,
            price=10,
        )

        # When
        with pytest.raises(api_errors.ApiErrors) as error:
            api.upsert_stocks(offer_id=offer.id,
                              stock_data_list=[edited_stock_data])

        # Then
        assert error.value.errors == {
            "global": [
                "Pour les offres importées, certains champs ne sont pas modifiables"
            ]
        }
Esempio n. 3
0
    def should_invalidate_booking_token_when_event_is_reported(
            self, mock_update_confirmation_dates):
        # Given
        now = datetime.now()
        booking_made_3_days_ago = now - timedelta(days=3)
        event_in_4_days = now + timedelta(days=4)
        event_reported_in_10_days = now + timedelta(days=10)
        offer = factories.EventOfferFactory()
        existing_stock = factories.StockFactory(
            offer=offer, beginningDatetime=event_in_4_days)
        booking = bookings_factories.BookingFactory(
            stock=existing_stock,
            dateCreated=booking_made_3_days_ago,
            isUsed=True)
        edited_stock_data = StockEditionBodyModel(
            id=existing_stock.id,
            beginningDatetime=event_reported_in_10_days,
            bookingLimitDatetime=existing_stock.bookingLimitDatetime,
            price=2,
        )

        # When
        api.upsert_stocks(offer_id=offer.id,
                          stock_data_list=[edited_stock_data])

        # Then
        updated_booking = Booking.query.get(booking.id)
        assert updated_booking.isUsed is False
        assert updated_booking.dateUsed is None
        assert updated_booking.confirmationDate == booking.confirmationDate
Esempio n. 4
0
    def should_update_bookings_confirmation_date_if_report_of_event(
            self, mock_update_confirmation_dates):
        # Given
        now = datetime.now()
        event_in_4_days = now + timedelta(days=4)
        event_reported_in_10_days = now + timedelta(days=10)
        offer = factories.EventOfferFactory()
        existing_stock = factories.StockFactory(
            offer=offer, beginningDatetime=event_in_4_days)
        booking = bookings_factories.BookingFactory(stock=existing_stock,
                                                    dateCreated=now)
        edited_stock_data = StockEditionBodyModel(
            id=existing_stock.id,
            beginningDatetime=event_reported_in_10_days,
            bookingLimitDatetime=existing_stock.bookingLimitDatetime,
            price=2,
        )

        # When
        api.upsert_stocks(offer_id=offer.id,
                          stock_data_list=[edited_stock_data])

        # Then
        mock_update_confirmation_dates.assert_called_once_with(
            [booking], event_reported_in_10_days)
Esempio n. 5
0
    def test_does_not_allow_beginning_datetime_on_thing_offer_on_creation_and_edition(
            self, mock_update_confirmation_dates):
        # Given
        offer = factories.ThingOfferFactory()
        beginning_date = datetime.utcnow() + timedelta(days=4)
        existing_stock = factories.StockFactory(offer=offer, price=10)
        created_stock_data = StockCreationBodyModel(
            price=-1,
            beginningDatetime=beginning_date,
            bookingLimitDatetime=beginning_date)
        edited_stock_data = StockEditionBodyModel(
            id=existing_stock.id,
            price=0,
            beginningDatetime=beginning_date,
            bookingLimitDatetime=beginning_date)

        # When
        with pytest.raises(api_errors.ApiErrors) as error:
            api.upsert_stocks(
                offer_id=offer.id,
                stock_data_list=[created_stock_data, edited_stock_data])

        # Then
        assert error.value.errors == {
            "global": [
                "Impossible de mettre une date de début si l'offre ne porte pas sur un événement"
            ],
        }
Esempio n. 6
0
    def test_sends_email_if_beginning_date_changes_on_edition(
            self, mocked_send_email):
        # Given
        offer = factories.EventOfferFactory()
        existing_stock = factories.StockFactory(offer=offer, price=10)
        beginning = datetime.now() + timedelta(days=10)
        edited_stock_data = StockEditionBodyModel(
            id=existing_stock.id,
            beginningDatetime=beginning,
            bookingLimitDatetime=existing_stock.bookingLimitDatetime,
            price=2,
        )
        booking = bookings_factories.BookingFactory(stock=existing_stock)
        bookings_factories.BookingFactory(stock=existing_stock,
                                          isCancelled=True)

        # When
        api.upsert_stocks(offer_id=offer.id,
                          stock_data_list=[edited_stock_data])

        # Then
        stock = models.Stock.query.one()
        assert stock.beginningDatetime == beginning
        notified_bookings = mocked_send_email.call_args_list[0][0][0]
        assert notified_bookings == [booking]
Esempio n. 7
0
    def test_do_not_sync_algolia_if_feature_is_disabled(
            self, mocked_add_offer_id, mock_update_confirmation_dates):
        # Given
        offer = factories.ThingOfferFactory()
        created_stock_data = StockCreationBodyModel(price=10)

        # When
        api.upsert_stocks(offer_id=offer.id,
                          stock_data_list=[created_stock_data])

        # Then
        mocked_add_offer_id.assert_not_called()
Esempio n. 8
0
    def test_upsert_multiple_stocks(self, mocked_add_offer_id,
                                    mock_update_confirmation_dates):
        # Given
        offer = factories.ThingOfferFactory()
        existing_stock = factories.StockFactory(offer=offer, price=10)
        created_stock_data = StockCreationBodyModel(price=10, quantity=7)
        edited_stock_data = StockEditionBodyModel(id=existing_stock.id,
                                                  price=5,
                                                  quantity=7)

        # When
        stocks_upserted = api.upsert_stocks(
            offer_id=offer.id,
            stock_data_list=[created_stock_data, edited_stock_data])

        # Then
        created_stock = Stock.query.filter_by(id=stocks_upserted[0].id).first()
        assert created_stock.offer == offer
        assert created_stock.price == 10
        assert created_stock.quantity == 7
        edited_stock = Stock.query.filter_by(id=existing_stock.id).first()
        assert edited_stock.price == 5
        assert edited_stock.quantity == 7
        mocked_add_offer_id.assert_called_once_with(client=app.redis_client,
                                                    offer_id=offer.id)
Esempio n. 9
0
def upsert_stocks(body: StocksUpsertBodyModel) -> StockIdsResponseModel:
    offerer = offerer_queries.get_by_offer_id(body.offer_id)
    check_user_has_access_to_offerer(current_user, offerer.id)

    stocks = offers_api.upsert_stocks(body.offer_id, body.stocks)
    return StockIdsResponseModel(
        stockIds=[StockIdResponseModel.from_orm(stock) for stock in stocks],
    )
Esempio n. 10
0
    def test_does_not_allow_upsert_stocks_on_a_synchronized_offer(
            self, mock_update_confirmation_dates):
        # Given
        offer = factories.ThingOfferFactory(
            lastProvider=offerers_factories.ProviderFactory(
                localClass="TiteLiveStocks"))
        created_stock_data = StockCreationBodyModel(price=10)

        # When
        with pytest.raises(api_errors.ApiErrors) as error:
            api.upsert_stocks(offer_id=offer.id,
                              stock_data_list=[created_stock_data])

        # Then
        assert error.value.errors == {
            "global": ["Les offres importées ne sont pas modifiables"]
        }
Esempio n. 11
0
    def test_does_not_allow_missing_dates_for_an_event_offer_on_creation_and_edition(
            self, mock_update_confirmation_dates):
        # Given
        offer = factories.EventOfferFactory()
        created_stock_data = StockCreationBodyModel(price=10,
                                                    beginningDatetime=None,
                                                    bookingLimitDatetime=None)

        # When
        with pytest.raises(api_errors.ApiErrors) as error:
            api.upsert_stocks(offer_id=offer.id,
                              stock_data_list=[created_stock_data])

        # Then
        assert error.value.errors == {
            "beginningDatetime": ["Ce paramètre est obligatoire"]
        }
Esempio n. 12
0
    def test_does_not_allow_invalid_price_on_creation_and_edition(
            self, mock_update_confirmation_dates):
        # Given
        offer = factories.ThingOfferFactory()
        existing_stock = factories.StockFactory(offer=offer, price=10)
        created_stock_data = StockCreationBodyModel(price=-1)
        edited_stock_data = StockEditionBodyModel(id=existing_stock.id,
                                                  price=-3)

        # When
        with pytest.raises(api_errors.ApiErrors) as error:
            api.upsert_stocks(
                offer_id=offer.id,
                stock_data_list=[created_stock_data, edited_stock_data])

        # Then
        assert error.value.errors == {
            "price": ["Le prix doit être positif"],
        }
Esempio n. 13
0
    def test_does_not_allow_edition_of_a_past_event_stock(
            self, mock_update_confirmation_dates):
        # Given
        offer = factories.ThingOfferFactory()
        date_in_the_past = datetime.utcnow() - timedelta(days=4)
        existing_stock = factories.StockFactory(
            offer=offer, price=10, beginningDatetime=date_in_the_past)
        edited_stock_data = StockEditionBodyModel(id=existing_stock.id,
                                                  price=4)

        # When
        with pytest.raises(api_errors.ApiErrors) as error:
            api.upsert_stocks(offer_id=offer.id,
                              stock_data_list=[edited_stock_data])

        # Then
        assert error.value.errors == {
            "global": ["Les événements passés ne sont pas modifiables"]
        }
Esempio n. 14
0
def upsert_stocks(body: StocksUpsertBodyModel) -> StockIdsResponseModel:
    try:
        offerer = pcapi.core.offerers.repository.get_by_offer_id(body.offer_id)
    except offerers_exceptions.CannotFindOffererForOfferId:
        raise ApiErrors({"offerer": ["Aucune structure trouvée à partir de cette offre"]}, status_code=404)
    check_user_has_access_to_offerer(current_user, offerer.id)

    stocks = offers_api.upsert_stocks(body.offer_id, body.stocks, current_user)
    return StockIdsResponseModel(
        stockIds=[StockIdResponseModel.from_orm(stock) for stock in stocks],
    )
Esempio n. 15
0
    def test_does_not_allow_a_negative_remaining_quantity_on_edition(
            self, mock_update_confirmation_dates):
        # Given
        offer = factories.ThingOfferFactory()
        booking = bookings_factories.BookingFactory(stock__offer=offer,
                                                    stock__quantity=10)
        existing_stock = booking.stock
        edited_stock_data = StockEditionBodyModel(id=existing_stock.id,
                                                  quantity=0,
                                                  price=10)

        # When
        with pytest.raises(api_errors.ApiErrors) as error:
            api.upsert_stocks(offer_id=offer.id,
                              stock_data_list=[edited_stock_data])

        # Then
        assert error.value.errors == {
            "quantity": [
                "Le stock total ne peut être inférieur au nombre de réservations"
            ]
        }
Esempio n. 16
0
    def test_does_not_allow_edition_of_stock_of_another_offer_than_given(
            self, mock_update_confirmation_dates):
        # Given
        offer = factories.ThingOfferFactory()
        other_offer = factories.ThingOfferFactory()
        existing_stock_on_other_offer = factories.StockFactory(
            offer=other_offer, price=10)
        edited_stock_data = StockEditionBodyModel(
            id=existing_stock_on_other_offer.id, price=30)

        # When
        with pytest.raises(api_errors.ApiErrors) as error:
            api.upsert_stocks(offer_id=offer.id,
                              stock_data_list=[edited_stock_data])

        # Then
        assert error.value.status_code == 403
        assert error.value.errors == {
            "global": [
                "Vous n'avez pas les droits d'accès suffisant pour accéder à cette information."
            ]
        }
Esempio n. 17
0
    def test_does_not_allow_booking_limit_after_beginning_for_an_event_offer_on_creation_and_edition(
            self, mock_update_confirmation_dates):
        # Given
        offer = factories.EventOfferFactory()
        beginning_date = datetime.utcnow() + timedelta(days=4)
        booking_limit = beginning_date + timedelta(days=4)
        created_stock_data = StockCreationBodyModel(
            price=10,
            beginningDatetime=beginning_date,
            bookingLimitDatetime=booking_limit)

        # When
        with pytest.raises(api_errors.ApiErrors) as error:
            api.upsert_stocks(offer_id=offer.id,
                              stock_data_list=[created_stock_data])

        # Then
        assert error.value.errors == {
            "bookingLimitDatetime": [
                "La date limite de réservation pour cette offre est postérieure à la date de début de l'évènement"
            ]
        }
Esempio n. 18
0
    def test_allow_edition_of_price_and_quantity_for_stocks_of_offers_synchronized_with_allocine(
            self, mock_update_confirmation_dates):
        # Given
        offer = factories.EventOfferFactory(
            lastProvider=offerers_factories.ProviderFactory(
                localClass="AllocineStocks"))
        date_in_the_future = datetime.utcnow() + timedelta(days=4)
        existing_stock = factories.StockFactory(
            offer=offer, price=10, beginningDatetime=date_in_the_future)
        edited_stock_data = StockEditionBodyModel(
            id=existing_stock.id,
            beginningDatetime=existing_stock.beginningDatetime,
            bookingLimitDatetime=existing_stock.bookingLimitDatetime,
            price=4,
        )

        # When
        api.upsert_stocks(offer_id=offer.id,
                          stock_data_list=[edited_stock_data])

        # Then
        edited_stock = Stock.query.filter_by(id=existing_stock.id).first()
        assert edited_stock.price == 4