Beispiel #1
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
Beispiel #2
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]
Beispiel #3
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)
Beispiel #4
0
    def test_fail_if_missing_dates(self):
        offer = factories.EventOfferFactory()

        with pytest.raises(api_errors.ApiErrors) as error:
            api.create_stock(offer=offer, price=10, beginning=None, booking_limit_datetime=None)

        assert "beginningDatetime" in error.value.errors
Beispiel #5
0
    def when_beginning_and_booking_limit_datetime_are_updated_for_event(
            self, app):
        # given
        offer = offers_factories.EventOfferFactory()
        offers_factories.UserOffererFactory(
            user__email="*****@*****.**",
            offerer=offer.venue.managingOfferer,
        )
        stock = offers_factories.StockFactory(
            offer=offer,
            price=100,
            quantity=10,
        )

        # when
        client = TestClient(app.test_client()).with_auth("*****@*****.**")
        beginning = datetime(2020, 1, 1, 12, 0, 0)
        booking_limit = datetime(2020, 1, 1, 10, 0, 0)
        data = {
            "price": 20,
            "quantity": 5,
            "beginningDatetime": beginning.isoformat(),
            "bookingLimitDatetime": booking_limit.isoformat(),
        }
        response = client.patch(f"/stocks/{humanize(stock.id)}", json=data)

        # then
        assert response.status_code == 200
        stock = Stock.query.one()
        assert stock.price == 20
        assert stock.quantity == 5
        assert stock.beginningDatetime == beginning
        assert stock.bookingLimitDatetime == booking_limit
Beispiel #6
0
 def test_event_offer(self):
     offer = factories.EventOfferFactory()
     first = datetime.datetime.now() + datetime.timedelta(days=1)
     last = datetime.datetime.now() + datetime.timedelta(days=5)
     factories.StockFactory(offer=offer, beginningDatetime=first)
     factories.StockFactory(offer=offer, beginningDatetime=last)
     assert offer.dateRange == DateTimes(first, last)
Beispiel #7
0
    def when_booking_limit_datetime_after_beginning_datetime(
            self, app, db_session):
        # Given
        user = users_factories.UserFactory(isAdmin=True)
        offer = offers_factories.EventOfferFactory()

        beginningDatetime = datetime(2019, 2, 14)

        data = {
            "price":
            1222,
            "offerId":
            humanize(offer.id),
            "beginningDatetime":
            serialize(beginningDatetime),
            "bookingLimitDatetime":
            serialize(beginningDatetime + timedelta(days=2)),
        }

        # When
        response = TestClient(app.test_client()).with_auth(user.email).post(
            "/stocks", json=data)

        # Then
        assert response.status_code == 400
        assert response.json == {
            "bookingLimitDatetime": [
                "La date limite de réservation pour cette offre est postérieure à la date de début de l'évènement"
            ]
        }
Beispiel #8
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"
            ]
        }
Beispiel #9
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
Beispiel #10
0
    def test_event_offer_ok_with_beginning_and_booking_limit_datetime(self):
        offer = factories.EventOfferFactory()

        validation.check_required_dates_for_stock(
            offer,
            beginning=datetime.datetime.now(),
            booking_limit_datetime=datetime.datetime.now(),
        )
    def test_event_prices(self):
        offer = offers_factories.EventOfferFactory()
        validation.check_stock_price(0, offer)
        validation.check_stock_price(1.5, offer)
        validation.check_stock_price(310.5, offer)

        with pytest.raises(ApiErrors) as error:
            validation.check_stock_price(-1.5, offer)
        assert error.value.errors["price"] == ["Le prix doit être positif"]
    def test_event_offer_must_have_booking_limit_datetime(self):
        offer = factories.EventOfferFactory()

        with pytest.raises(ApiErrors) as error:
            validation.check_required_dates_for_stock(
                offer,
                beginning=datetime.datetime.now(),
                booking_limit_datetime=None,
            )
        assert error.value.errors["bookingLimitDatetime"] == ["Ce paramètre est obligatoire"]
Beispiel #13
0
def create_event_booking(quantity=1, price=10, user=None, date_created=None):
    booking_kwargs = {}
    if user:
        booking_kwargs["user"] = user
    if date_created:
        booking_kwargs["dateCreated"] = date_created
    user = user or users_factories.UserFactory()
    stock = offers_factories.StockFactory(
        price=price,
        offer=offers_factories.EventOfferFactory(),
    )
    return bookings_factories.BookingFactory(stock=stock, quantity=quantity, **booking_kwargs)
Beispiel #14
0
    def test_when_user_has_rights_and_regular_offer(self, client):
        # Given
        past = datetime.now() - timedelta(days=2)
        booking = bookings_factories.IndividualBookingFactory(
            individualBooking__user__email="*****@*****.**",
            stock__beginningDatetime=past,
            stock__offer=offers_factories.EventOfferFactory(
                extraData={
                    "theater": {
                        "allocine_movie_id": 165,
                        "allocine_room_id": 987,
                    },
                },
                subcategoryId=subcategories.CARTE_CINE_MULTISEANCES.id,
                product__name="An offer you cannot refuse",
                venue__name="Le Petit Rintintin",
            ),
        )
        user_offerer = offers_factories.UserOffererFactory(offerer=booking.offerer)
        pro_user = user_offerer.user

        # When
        client = client.with_basic_auth(pro_user.email)
        response = client.get(f"/v2/bookings/token/{booking.token}")

        # Then
        assert response.headers["Content-type"] == "application/json"
        assert response.status_code == 200
        assert response.json == {
            "bookingId": humanize(booking.id),
            "dateOfBirth": "",
            "datetime": format_into_utc_date(booking.stock.beginningDatetime),
            "ean13": None,
            "email": "*****@*****.**",
            "formula": "ABO",
            "isUsed": False,
            "offerId": booking.stock.offerId,
            "offerName": "An offer you cannot refuse",
            "offerType": "EVENEMENT",
            "phoneNumber": "",
            "price": 10.0,
            "publicOfferId": humanize(booking.stock.offerId),
            "quantity": 1,
            "theater": {
                "allocine_movie_id": 165,
                "allocine_room_id": 987,
            },
            "userName": "******",
            "venueAddress": "1 boulevard Poissonnière",
            "venueDepartmentCode": "75",
            "venueName": "Le Petit Rintintin",
        }
def create_event_booking(quantity=1, price=10, user=None, date_used=None):
    booking_kwargs = {}
    if user:
        booking_kwargs["user"] = user
    booking_kwargs["dateUsed"] = date_used or datetime.now()
    user = user or users_factories.BeneficiaryGrant18Factory()
    stock = offers_factories.StockFactory(
        price=price,
        offer=offers_factories.EventOfferFactory(),
    )
    return bookings_factories.UsedBookingFactory(stock=stock,
                                                 quantity=quantity,
                                                 **booking_kwargs)
Beispiel #16
0
    def test_with_virtual_offer(self):
        # Given
        author = users_factories.ProFactory()
        offer = offers_factories.EventOfferFactory(
            author=author,
            product=offers_factories.DigitalProductFactory(
                name="Les lièvres pas malins"),
            venue=offers_factories.VirtualVenueFactory(),
        )

        # When
        email = make_offer_creation_notification_email(offer)

        # Then
        assert email[
            "Subject"] == "[Création d’offre - numérique] Les lièvres pas malins"
Beispiel #17
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"]
        }
def get_existing_pro_validated_user_with_validated_offerer_with_iban_validated_user_offerer_with_event_offer_with_no_stock(
):
    user_offerer = offers_factories.UserOffererFactory(
        validationToken=None,
        offerer__validationToken=None,
        user__validationToken=None,
    )
    offers_factories.BankInformationFactory(offerer=user_offerer.offerer)
    venue = offers_factories.VirtualVenueFactory(
        managingOfferer=user_offerer.offerer)
    offer = offers_factories.EventOfferFactory(venue=venue, isActive=True)

    return {
        "offer": get_offer_helper(offer),
        "offerer": get_offerer_helper(user_offerer.offerer),
        "user": get_pro_helper(user_offerer.user),
        "venue": get_venue_helper(venue),
    }
Beispiel #19
0
    def test_create_event_offer(self):
        offer = factories.EventOfferFactory()
        beginning = datetime.datetime(2024, 1, 1, 12, 0, 0)
        booking_limit = datetime.datetime(2024, 1, 1, 9, 0, 0)

        stock = api.create_stock(
            offer=offer,
            price=10,
            quantity=7,
            beginning=beginning,
            booking_limit_datetime=booking_limit,
        )

        assert stock.offer == offer
        assert stock.price == 10
        assert stock.quantity == 7
        assert stock.beginningDatetime == beginning
        assert stock.bookingLimitDatetime == booking_limit
Beispiel #20
0
    def test_should_only_index_bookable_offers_stock(self):
        offer = offers_factories.EventOfferFactory()
        _not_bookable_stock = offers_factories.EventStockFactory(
            beginningDatetime=datetime(2019, 1, 5),
            bookingLimitDatetime=datetime(2019, 1, 3),
            offer=offer,
            quantity=1,
        )
        bookable_stock = offers_factories.EventStockFactory(
            beginningDatetime=datetime(2019, 1, 12),
            bookingLimitDatetime=datetime(2019, 1, 10),
            offer=offer,
            quantity=1,
        )

        data = _build_offer_details_to_be_indexed(offer)
        assert data["dates"] == [
            datetime.timestamp(bookable_stock.beginningDatetime)
        ]
    def test_should_return_mailjet_data_with_correct_information_when_offer_is_an_event(self, build_pc_pro_offer_link):
        # Given
        beneficiary = users_factories.BeneficiaryGrant18Factory(
            publicName="John Doe", firstName="John", lastName="Doe", email="*****@*****.**"
        )
        offer = offer_factories.EventOfferFactory(
            venue__name="Venue name",
            product__name="My Event",
        )
        booking = booking_factories.IndividualBookingFactory(
            user=beneficiary,
            individualBooking__user=beneficiary,
            stock__offer=offer,
            stock__beginningDatetime=datetime(2019, 10, 9, 10, 20, 00),
            stock__price=12.52,
            quantity=2,
            token="12345",
        )
        bookings = [booking]

        # When
        mailjet_data = retrieve_offerer_bookings_recap_email_data_after_offerer_cancellation(bookings)

        # Then
        assert mailjet_data == {
            "MJ-TemplateID": 1116333,
            "MJ-TemplateLanguage": True,
            "Vars": {
                "offer_name": "My Event",
                "lien_offre_pcpro": "http://pc_pro.com/offer_link",
                "venue_name": "Venue name",
                "price": "12.52",
                "is_event": 1,
                "event_date": "09-Oct-2019",
                "event_hour": "12h20",
                "quantity": 2,
                "reservations_number": 1,
                "users": [
                    {"countermark": "12345", "email": "*****@*****.**", "firstName": "John", "lastName": "Doe"}
                ],
            },
        }
Beispiel #22
0
    def when_invalid_format_for_booking_limit_datetime(self, app, db_session):
        # Given
        user = users_factories.UserFactory(isAdmin=True)
        offer = offers_factories.EventOfferFactory()

        data = {
            "price": 0,
            "offerId": humanize(offer.id),
            "beginningDatetime": "2020-10-11T00:00:00Z",
            "bookingLimitDatetime": "zbbopbjeo",
        }

        # When
        response = TestClient(app.test_client()).with_auth(user.email).post(
            "/stocks", json=data)

        # Then
        assert response.status_code == 400
        assert response.json == {
            "bookingLimitDatetime": ["Format de date invalide"]
        }
Beispiel #23
0
    def when_booking_limit_datetime_is_none_for_event(self, app, db_session):
        # Given
        user = users_factories.UserFactory(isAdmin=True)
        offer = offers_factories.EventOfferFactory()

        beginningDatetime = datetime(2019, 2, 14)
        data = {
            "price": 0,
            "offerId": humanize(offer.id),
            "bookingLimitDatetime": None,
            "beginningDatetime": serialize(beginningDatetime),
        }

        # When
        response = TestClient(app.test_client()).with_auth(user.email).post(
            "/stocks", json=data)

        # Then
        assert response.status_code == 400
        assert response.json == {
            "bookingLimitDatetime": ["Ce paramètre est obligatoire"]
        }
Beispiel #24
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"
            ]
        }
Beispiel #25
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
Beispiel #26
0
 def test_deleted_stock_is_ignored(self):
     offer = factories.EventOfferFactory()
     factories.StockFactory(offer=offer, isSoftDeleted=True)
     assert offer.dateRange == DateTimes()
Beispiel #27
0
 def test_no_stock(self):
     offer = factories.EventOfferFactory()
     assert offer.dateRange == DateTimes()
Beispiel #28
0
 def test_single_stock(self):
     offer = factories.EventOfferFactory()
     stock = factories.StockFactory(offer=offer)
     assert offer.dateRange == DateTimes(stock.beginningDatetime, stock.beginningDatetime)
    def test_find_filtered_offerers_with_keywords(self):
        offerer_with_only_virtual_venue_with_offer = offerers_factories.OffererFactory(siren="123456785")
        offerer_with_both_venues_offer_on_both = offerers_factories.OffererFactory(siren="123456782")
        offerer_with_both_venues_offer_on_virtual = offerers_factories.OffererFactory(siren="123456783")
        offerer_with_both_venues_offer_on_not_virtual = offerers_factories.OffererFactory(siren="123456784")

        virtual_venue_with_offer_1 = offers_factories.VenueFactory(
            managingOfferer=offerer_with_only_virtual_venue_with_offer, isVirtual=True, siret=None
        )
        virtual_venue_with_offer_3 = offers_factories.VenueFactory(
            managingOfferer=offerer_with_both_venues_offer_on_both,
            isVirtual=True,
            siret=None,
            publicName="Librairie des mots perdus",
        )
        venue_with_offer_3 = offers_factories.VenueFactory(
            managingOfferer=offerer_with_both_venues_offer_on_both,
            siret="12345678212345",
            publicName="Librairie des mots perdus",
        )
        virtual_venue_with_offer_4 = offers_factories.VenueFactory(
            managingOfferer=offerer_with_both_venues_offer_on_virtual,
            isVirtual=True,
            siret=None,
            publicName="Librairie des mots perdus",
        )
        venue_with_offer_5 = offers_factories.VenueFactory(
            managingOfferer=offerer_with_both_venues_offer_on_not_virtual,
            siret="12345678412345",
            publicName="Librairie des mots perdus",
        )
        offers_factories.VenueFactory(publicName="something else")

        offers_factories.ThingOfferFactory(venue=virtual_venue_with_offer_1, url="http://url.com")
        offers_factories.ThingOfferFactory(venue=virtual_venue_with_offer_3, url="http://url.com")
        offers_factories.ThingOfferFactory(venue=virtual_venue_with_offer_4, url="http://url.com")
        offers_factories.EventOfferFactory(venue=venue_with_offer_3)
        offers_factories.EventOfferFactory(venue=venue_with_offer_5)

        one_keyword_search = filter_offerers_with_keywords_string(Offerer.query.join(Venue), "perdus")
        partial_keyword_search = filter_offerers_with_keywords_string(Offerer.query.join(Venue), "Libr")
        two_keywords_search = filter_offerers_with_keywords_string(Offerer.query.join(Venue), "Librairie perd")
        two_partial_keywords_search = filter_offerers_with_keywords_string(Offerer.query.join(Venue), "Lib perd")

        assert {
            offerer_with_both_venues_offer_on_both,
            offerer_with_both_venues_offer_on_virtual,
            offerer_with_both_venues_offer_on_not_virtual,
        } == set(one_keyword_search)
        assert {
            offerer_with_both_venues_offer_on_both,
            offerer_with_both_venues_offer_on_virtual,
            offerer_with_both_venues_offer_on_not_virtual,
        } == set(partial_keyword_search)
        assert {
            offerer_with_both_venues_offer_on_both,
            offerer_with_both_venues_offer_on_virtual,
            offerer_with_both_venues_offer_on_not_virtual,
        } == set(two_keywords_search)
        assert {
            offerer_with_both_venues_offer_on_both,
            offerer_with_both_venues_offer_on_virtual,
            offerer_with_both_venues_offer_on_not_virtual,
        } == set(two_partial_keywords_search)