Exemplo n.º 1
0
    def test_should_not_create_educational_booking_when_stock_does_not_exist(
            self):
        # Given
        offers_factories.EducationalEventStockFactory(
            beginningDatetime=datetime.datetime(2021, 5, 15))
        educational_institution = educational_factories.EducationalInstitutionFactory(
        )
        educational_factories.EducationalYearFactory()
        educational_redactor = educational_factories.EducationalRedactorFactory(
            email="*****@*****.**")
        requested_stock_id = 4875
        redactor_informations = AuthenticatedInformation(
            email=educational_redactor.email,
            civility=educational_redactor.civility,
            firstname=educational_redactor.firstName,
            lastname=educational_redactor.lastName,
            uai=educational_institution.institutionId,
        )

        # When
        with pytest.raises(offers_exceptions.StockDoesNotExist):
            educational_api.book_educational_offer(
                redactor_informations=redactor_informations,
                stock_id=requested_stock_id,
            )

        # Then
        saved_bookings = EducationalBooking.query.all()
        assert len(saved_bookings) == 0
Exemplo n.º 2
0
 def test_raise_if_offer_is_educational(self):
     with pytest.raises(exceptions.EducationalOfferCannotBeBooked):
         api.book_offer(
             beneficiary=users_factories.BeneficiaryGrant18Factory(),
             stock_id=offers_factories.EducationalEventStockFactory(offer__isEducational=True).id,
             quantity=2,
         )
    def test_should_not_allow_booking_when_stock_has_no_remaining_quantity(
            self, test_data, app):
        # Given
        _, educational_institution, educational_redactor = test_data
        stock = offer_factories.EducationalEventStockFactory(
            beginningDatetime=stock_date, quantity=0)
        adage_jwt_fake_valid_token = _create_adage_valid_token_with_email(
            email=educational_redactor.email,
            uai=educational_institution.institutionId)
        test_client = TestClient(app.test_client())
        test_client.auth_header = {
            "Authorization": f"Bearer {adage_jwt_fake_valid_token}"
        }

        # When
        response = test_client.post(
            "/adage-iframe/bookings",
            json={
                "stockId": stock.id,
            },
        )

        # Then
        assert response.status_code == 400
        assert response.json == {
            "stock": "Cette offre n'est pas disponible à la réservation"
        }
Exemplo n.º 4
0
    def test_should_not_create_educational_booking_when_educational_institution_unknown(
            self):
        # Given
        stock = offers_factories.EducationalEventStockFactory(
            beginningDatetime=datetime.datetime(2021, 5, 15))
        educational_factories.EducationalInstitutionFactory()
        educational_factories.EducationalYearFactory()
        educational_redactor = educational_factories.EducationalRedactorFactory(
            email="*****@*****.**")
        provided_institution_id = "AU3568Unknown"
        redactor_informations = AuthenticatedInformation(
            email=educational_redactor.email,
            civility=educational_redactor.civility,
            firstname=educational_redactor.firstName,
            lastname=educational_redactor.lastName,
            uai=provided_institution_id,
        )

        # When
        with pytest.raises(exceptions.EducationalInstitutionUnknown) as error:
            educational_api.book_educational_offer(
                redactor_informations=redactor_informations,
                stock_id=stock.id,
            )

        # Then
        assert error.value.errors == {
            "educationalInstitution": ["Cette institution est inconnue"]
        }

        saved_bookings = EducationalBooking.query.join(Booking).filter(
            Booking.stockId == stock.id).all()
        assert len(saved_bookings) == 0
Exemplo n.º 5
0
    def test_should_send_email_on_educational_booking_creation(self):
        # Given
        stock = offers_factories.EducationalEventStockFactory(
            beginningDatetime=datetime.datetime(2021, 5, 15),
            offer__bookingEmail="*****@*****.**",
        )
        educational_institution = educational_factories.EducationalInstitutionFactory(
        )
        educational_factories.EducationalYearFactory(
            beginningDate=datetime.datetime(2020, 9, 1),
            expirationDate=datetime.datetime(2021, 8, 31))
        educational_factories.EducationalYearFactory(
            beginningDate=datetime.datetime(2021, 9, 1),
            expirationDate=datetime.datetime(2022, 8, 31))
        educational_redactor = educational_factories.EducationalRedactorFactory(
            email="*****@*****.**",
            firstName="Georges",
            lastName="Moustaki",
        )
        redactor_informations = AuthenticatedInformation(
            email=educational_redactor.email,
            civility=educational_redactor.civility,
            firstname=educational_redactor.firstName,
            lastname=educational_redactor.lastName,
            uai=educational_institution.institutionId,
        )

        # When
        educational_api.book_educational_offer(
            redactor_informations=redactor_informations,
            stock_id=stock.id,
        )

        # Then
        assert len(mails_testing.outbox) == 1
        sent_data = mails_testing.outbox[0].sent_data
        offer = stock.offer
        assert sent_data == {
            "FromEmail": "*****@*****.**",
            "MJ-TemplateID": 3174424,
            "MJ-TemplateLanguage": True,
            "To": "*****@*****.**",
            "Vars": {
                "departement": "75",
                "lien_offre_pcpro":
                f"http://*****:*****@example.com",
                "is_event": 1,
            },
        }
 def test_data(self):
     stock = offer_factories.EducationalEventStockFactory(
         beginningDatetime=stock_date)
     educational_institution = educational_factories.EducationalInstitutionFactory(
     )
     educational_factories.EducationalYearFactory(
         beginningDate=educational_year_dates["start"],
         expirationDate=educational_year_dates["end"])
     educational_redactor = educational_factories.EducationalRedactorFactory(
         email="*****@*****.**")
     return (stock, educational_institution, educational_redactor)
Exemplo n.º 7
0
    def test_no_op_when_educational_booking_already_refused(self, db_session):
        stock = offers_factories.EducationalEventStockFactory(
            dnBookedQuantity=20)
        booking = bookings_factories.EducationalBookingFactory(
            educationalBooking__status=EducationalBookingStatus.REFUSED,
            quantity=1,
            stock=stock,
        )

        educational_api.refuse_educational_booking(
            booking.educationalBookingId)

        assert stock.dnBookedQuantity == 21
Exemplo n.º 8
0
    def test_refuse_educational_booking(self, db_session):
        stock = offers_factories.EducationalEventStockFactory(
            quantity=200, dnBookedQuantity=0)
        booking = bookings_factories.EducationalBookingFactory(
            status=BookingStatus.CONFIRMED,
            stock=stock,
            quantity=20,
        )

        educational_api.refuse_educational_booking(
            booking.educationalBookingId)

        assert stock.dnBookedQuantity == 0
        assert booking.status == BookingStatus.CANCELLED
        assert booking.cancellationReason == BookingCancellationReasons.REFUSED_BY_INSTITUTE
    def test_post_educational_booking_with_less_redactor_information(
            self, app):
        # Given
        stock = offer_factories.EducationalEventStockFactory(
            beginningDatetime=stock_date)
        educational_institution = educational_factories.EducationalInstitutionFactory(
        )
        educational_year = educational_factories.EducationalYearFactory(
            beginningDate=educational_year_dates["start"],
            expirationDate=educational_year_dates["end"])

        adage_jwt_fake_valid_token = _create_adage_valid_token_with_email(
            email="*****@*****.**",
            uai=educational_institution.institutionId,
            civility=None,
            firstname=None,
            lastname=None,
        )
        test_client = TestClient(app.test_client())
        test_client.auth_header = {
            "Authorization": f"Bearer {adage_jwt_fake_valid_token}"
        }

        # When
        response = test_client.post(
            "/adage-iframe/bookings",
            json={
                "stockId": stock.id,
            },
        )

        # Then
        assert response.status_code == 200
        booking = Booking.query.filter(Booking.stockId == stock.id).first()
        assert booking.educationalBookingId is not None
        assert booking.individualBookingId is None
        assert booking.stock.id == stock.id
        educational_booking = booking.educationalBooking
        assert educational_booking.educationalInstitution.institutionId == educational_institution.institutionId
        assert educational_booking.educationalYear.adageId == educational_year.adageId
        educational_redactor = educational_booking.educationalRedactor
        assert educational_redactor.civility == None
        assert educational_redactor.firstName == None
        assert educational_redactor.lastName == None
        assert educational_redactor.email == "*****@*****.**"

        assert response.json["bookingId"] == booking.id
Exemplo n.º 10
0
    def test_should_create_educational_booking_on_requested_educational_offer(
            self):
        # Given
        stock = offers_factories.EducationalEventStockFactory(
            beginningDatetime=datetime.datetime(2021, 5, 15))
        educational_institution = educational_factories.EducationalInstitutionFactory(
        )
        educational_year = educational_factories.EducationalYearFactory(
            beginningDate=datetime.datetime(2020, 9, 1),
            expirationDate=datetime.datetime(2021, 8, 31))
        educational_factories.EducationalYearFactory(
            beginningDate=datetime.datetime(2021, 9, 1),
            expirationDate=datetime.datetime(2022, 8, 31))
        educational_redactor = educational_factories.EducationalRedactorFactory(
            email="*****@*****.**")
        redactor_informations = AuthenticatedInformation(
            email=educational_redactor.email,
            civility=educational_redactor.civility,
            firstname=educational_redactor.firstName,
            lastname=educational_redactor.lastName,
            uai=educational_institution.institutionId,
        )

        # When
        returned_booking = educational_api.book_educational_offer(
            redactor_informations=redactor_informations,
            stock_id=stock.id,
        )

        # Then
        saved_educational_booking = EducationalBooking.query.join(
            Booking).filter(Booking.stockId == stock.id).first()

        assert saved_educational_booking.booking.id == returned_booking.id
        assert saved_educational_booking.booking.stock.id == stock.id
        assert saved_educational_booking.booking.stock.dnBookedQuantity == 1
        assert saved_educational_booking.confirmationLimitDate == stock.bookingLimitDatetime
        assert saved_educational_booking.educationalInstitution.institutionId == educational_institution.institutionId
        assert saved_educational_booking.educationalYear.adageId == educational_year.adageId
        assert saved_educational_booking.booking.status == BookingStatus.PENDING
        # Assert we do not create an extra educational redactor when exist
        assert EducationalRedactor.query.count() == 1
Exemplo n.º 11
0
    def test_should_not_create_educational_booking_when_educational_year_not_found(
            self):
        # Given
        date_before_education_year_beginning = datetime.datetime(2018, 9, 20)
        stock = offers_factories.EducationalEventStockFactory(
            beginningDatetime=date_before_education_year_beginning)
        educational_institution = educational_factories.EducationalInstitutionFactory(
        )
        educational_factories.EducationalYearFactory()
        educational_redactor = educational_factories.EducationalRedactorFactory(
            email="*****@*****.**")
        redactor_informations = AuthenticatedInformation(
            email=educational_redactor.email,
            civility=educational_redactor.civility,
            firstname=educational_redactor.firstName,
            lastname=educational_redactor.lastName,
            uai=educational_institution.institutionId,
        )

        # When
        with pytest.raises(exceptions.EducationalYearNotFound) as error:
            educational_api.book_educational_offer(
                redactor_informations=redactor_informations,
                stock_id=stock.id,
            )

        # Then
        assert error.value.errors == {
            "educationalYear": [
                "Aucune année scolaire correspondant à la réservation demandée n'a été trouvée"
            ]
        }

        saved_bookings = EducationalBooking.query.join(Booking).filter(
            Booking.stockId == stock.id).all()
        assert len(saved_bookings) == 0
Exemplo n.º 12
0
    def test_should_create_educational_redactor_when_it_does_not_exist(self):
        # Given
        stock = offers_factories.EducationalEventStockFactory(
            beginningDatetime=datetime.datetime(2021, 5, 15))
        educational_institution = educational_factories.EducationalInstitutionFactory(
        )
        educational_factories.EducationalYearFactory(
            beginningDate=datetime.datetime(2020, 9, 1),
            expirationDate=datetime.datetime(2021, 8, 31))
        educational_factories.EducationalYearFactory(
            beginningDate=datetime.datetime(2021, 9, 1),
            expirationDate=datetime.datetime(2022, 8, 31))
        redactor_informations = AuthenticatedInformation(
            email="*****@*****.**",
            civility="Mme",
            firstname="Project",
            lastname="Redactor",
            uai=educational_institution.institutionId,
        )

        # When
        educational_api.book_educational_offer(
            redactor_informations=redactor_informations,
            stock_id=stock.id,
        )

        # Then
        saved_educational_booking = EducationalBooking.query.join(
            Booking).filter(Booking.stockId == stock.id).first()
        assert saved_educational_booking.educationalRedactor.email == redactor_informations.email
        educational_redactor: EducationalRedactor = EducationalRedactor.query.one(
        )
        assert educational_redactor.email == redactor_informations.email
        assert educational_redactor.firstName == "Project"
        assert educational_redactor.lastName == "Redactor"
        assert educational_redactor.civility == "Mme"
Exemplo n.º 13
0
    def test_get_offer(self, client):
        # Given
        offer = offer_factories.EducationalEventOfferFactory(
            name="offer name", description="offer description")
        stock1 = offer_factories.EducationalEventStockFactory(
            beginningDatetime=datetime(2021, 5, 15),
            offer=offer,
        )
        stock2 = offer_factories.EducationalEventStockFactory(
            beginningDatetime=datetime(2021, 5, 16),
            offer=offer,
            price=200,
        )

        adage_jwt_fake_valid_token = _create_adage_valid_token_with_email(
            email="*****@*****.**", uai="12890AI")
        client.auth_header = {
            "Authorization": f"Bearer {adage_jwt_fake_valid_token}"
        }
        offer_id = offer.id

        # When
        with assert_num_queries(1):
            response = client.get(f"/adage-iframe/offer/{offer_id}")

        # Then
        assert response.status_code == 200
        assert response.json == {
            "description":
            "offer description",
            "id":
            offer_id,
            "isExpired":
            False,
            "isSoldOut":
            False,
            "name":
            "offer name",
            "stocks": [
                {
                    "beginningDatetime": "2021-05-15T00:00:00Z",
                    "id": stock1.id,
                    "isBookable": True,
                    "price": 1000,
                },
                {
                    "beginningDatetime": "2021-05-16T00:00:00Z",
                    "id": stock2.id,
                    "isBookable": True,
                    "price": 20000,
                },
            ],
            "subcategoryLabel":
            "Séance de cinéma",
            "venue": {
                "address": "1 boulevard Poissonnière",
                "city": "Paris",
                "coordinates": {
                    "latitude": 48.87004,
                    "longitude": 2.3785
                },
                "id": offer.venue.id,
                "name": offer.venue.name,
                "postalCode": "75000",
                "publicName": offer.venue.publicName,
            },
        }