def test_should_return_event_data_when_booking_is_an_event( self, mock_format_environment_for_email): # Given booking = factories.BookingFactory( user=UserFactory(email="*****@*****.**", firstName="Fabien"), isCancelled=True, stock=EventStockFactory( price=10.2, beginningDatetime=datetime.utcnow(), offer__name="Test event name", offer__id=123456, ), ) # When email_data = make_beneficiary_booking_cancellation_email_data(booking) # Then assert email_data == { "FromEmail": "*****@*****.**", "Mj-TemplateID": 1091464, "Mj-TemplateLanguage": True, "To": "*****@*****.**", "Vars": { "env": "-testing", "event_date": "26 novembre", "event_hour": "19h29", "is_event": 1, "is_free_offer": 0, "offer_id": "AHREA", "offer_name": "Test event name", "offer_price": "10.20", "user_first_name": "Fabien", }, }
def test_should_return_event_data_when_booking_is_an_event(self): # Given booking = factories.CancelledIndividualBookingFactory( individualBooking__user=BeneficiaryGrant18Factory( email="*****@*****.**", firstName="Fabien"), stock=EventStockFactory( price=10.2, beginningDatetime=datetime.utcnow(), offer__name="Test event name", offer__id=123456, ), ) # When email_data = make_beneficiary_booking_cancellation_email_data( booking.individualBooking) # Then assert email_data == { "Mj-TemplateID": 1091464, "Mj-TemplateLanguage": True, "Vars": { "can_book_again": 1, "event_date": "26 novembre 2019", "event_hour": "19h29", "is_event": 1, "is_free_offer": 0, "offer_id": "AHREA", "offer_name": "Test event name", "offer_price": "10.20", "user_first_name": "Fabien", }, }
def test_should_deactivate_thing_offers_that_are_higher_than_300e_and_non_educational( self): # Given ThingStockFactory(price=305) ThingStockFactory(price=315) ThingStockFactory(price=103) ThingStockFactory(price=300) educational_offer = EducationalThingOfferFactory() ThingStockFactory(offer=educational_offer, price=376) EventStockFactory(price=310) EventStockFactory(price=297) # When deactivate_300e_thing_offers() # Then deactivated_offers = Offer.query.filter_by(isActive=False).all() assert len(deactivated_offers) == 2
def test_should_not_return_activation_bookings(self, app): # Given beneficiary = BeneficiaryGrant18Factory() offer1 = EventOfferFactory(subcategoryId=subcategories.ACTIVATION_THING.id) offer2 = EventOfferFactory(subcategoryId=subcategories.ACTIVATION_THING.id) offer3 = EventOfferFactory(subcategoryId=subcategories.SUPPORT_PHYSIQUE_FILM.id) stock1 = EventStockFactory(offer=offer1) stock2 = EventStockFactory(offer=offer2) stock3 = EventStockFactory(offer=offer3) booking_factories.IndividualBookingFactory(individualBooking__user=beneficiary, stock=stock1) booking_factories.IndividualBookingFactory(individualBooking__user=beneficiary, stock=stock2) booking3 = booking_factories.IndividualBookingFactory(individualBooking__user=beneficiary, stock=stock3) # When result = BeneficiaryBookingsSQLRepository().get_beneficiary_bookings(beneficiary_id=beneficiary.id) # Then assert len(result.bookings) == 1 assert result.bookings[0].id == booking3.id
def test_get_expired_offer(self, app): stock = EventStockFactory(beginningDatetime=datetime.utcnow() - timedelta(days=1)) offer_id = stock.offer.id with assert_num_queries(1): response = TestClient( app.test_client()).get(f"/native/v1/offer/{offer_id}") assert response.json["isExpired"]
def test_pc_send_tomorrow_events_notifications_only_to_individual_bookings_users( ): """ Test that each stock that is linked to an offer that occurs tomorrow and creates a job that will send a notification to all of the stock's users with a valid (not cancelled) booking, for individual bookings only. """ tomorrow = datetime.now() + timedelta(days=1) stock_tomorrow = EventStockFactory(beginningDatetime=tomorrow, offer__name="my_offer") begin = datetime.now() + timedelta(days=7) stock_next_week = EventStockFactory(beginningDatetime=begin) bookings_tomorrow = IndividualBookingFactory.create_batch( 2, stock=stock_tomorrow, isCancelled=False) BookingFactory.create_batch(2, stock=stock_tomorrow, isCancelled=True, status=BookingStatus.CANCELLED) BookingFactory.create_batch(2, stock=stock_next_week, isCancelled=False) EducationalBookingFactory.create_batch(2, stock=stock_tomorrow, isCancelled=False) pc_send_tomorrow_events_notifications() assert len(testing.requests) == 1 assert all(data["message"]["title"] == "my_offer, c'est demain !" for data in testing.requests) user_ids = set() for data in testing.requests: for user_id in data["user_ids"]: user_ids.add(user_id) expected_user_ids = { booking.individualBooking.userId for booking in bookings_tomorrow } assert user_ids == expected_user_ids
def test_should_return_is_free_offer_when_offer_price_equals_to_zero(self): # Given booking = factories.BookingFactory( isCancelled=True, stock=EventStockFactory(price=0, ), ) # When email_data = make_beneficiary_booking_cancellation_email_data(booking) # Then assert email_data["Vars"]["is_free_offer"] == 1
def should_return_bookings(self, app): # Given now = datetime.utcnow() two_days = now + timedelta(days=2, hours=10) two_days_bis = now + timedelta(days=2, hours=20) three_days = now + timedelta(days=3) user = UserFactory() booking1 = factories.BookingFactory( user=user, stock=EventStockFactory( beginningDatetime=three_days, bookingLimitDatetime=now, ), ) booking2 = factories.BookingFactory( user=user, stock=EventStockFactory( beginningDatetime=two_days, bookingLimitDatetime=now, ), ) booking3 = factories.BookingFactory( user=user, stock=EventStockFactory( beginningDatetime=two_days_bis, bookingLimitDatetime=now, ), ) # When result = BeneficiaryBookingsSQLRepository().get_beneficiary_bookings( beneficiary_id=user.id) # Then assert len(result.bookings) == 3 assert set(booking.id for booking in result.bookings) == { booking1.id, booking2.id, booking3.id }
def test_should_return_bookings(self, app): # Given now = datetime.utcnow() two_days = now + timedelta(days=2, hours=10) two_days_bis = now + timedelta(days=2, hours=20) three_days = now + timedelta(days=3) beneficiary = BeneficiaryGrant18Factory() booking1 = booking_factories.IndividualBookingFactory( individualBooking__user=beneficiary, stock=EventStockFactory( beginningDatetime=three_days, bookingLimitDatetime=now, ), ) booking2 = booking_factories.IndividualBookingFactory( individualBooking__user=beneficiary, stock=EventStockFactory( beginningDatetime=two_days, bookingLimitDatetime=now, ), ) booking3 = booking_factories.IndividualBookingFactory( individualBooking__user=beneficiary, stock=EventStockFactory( beginningDatetime=two_days_bis, bookingLimitDatetime=now, ), ) # When result = BeneficiaryBookingsSQLRepository().get_beneficiary_bookings(beneficiary_id=beneficiary.id) # Then assert len(result.bookings) == 3 assert set(booking.id for booking in result.bookings) == {booking1.id, booking2.id, booking3.id}
def test_should_return_bookings_by_beneficiary_id(self, app): # Given beneficiary_1 = BeneficiaryGrant18Factory() beneficiary_2 = BeneficiaryGrant18Factory() offer = EventOfferFactory() stock = EventStockFactory(offer=offer) booking1 = booking_factories.IndividualBookingFactory(individualBooking__user=beneficiary_1, stock=stock) booking_factories.IndividualBookingFactory(individualBooking__user=beneficiary_2, stock=stock) # When result = BeneficiaryBookingsSQLRepository().get_beneficiary_bookings(beneficiary_id=beneficiary_1.id) # Then assert len(result.bookings) == 1 assert result.bookings[0].id == booking1.id
def test_should_return_only_most_recent_booking_when_two_cancelled_on_same_stock(self, app): # Given now = datetime.utcnow() two_days_ago = now - timedelta(days=2) three_days_ago = now - timedelta(days=3) beneficiary = BeneficiaryGrant18Factory() offer = EventOfferFactory() stock = EventStockFactory(offer=offer) booking1 = booking_factories.CancelledIndividualBookingFactory( individualBooking__user=beneficiary, stock=stock, dateCreated=two_days_ago ) booking_factories.CancelledIndividualBookingFactory( individualBooking__user=beneficiary, stock=stock, dateCreated=three_days_ago ) # When result = BeneficiaryBookingsSQLRepository().get_beneficiary_bookings(beneficiary_id=beneficiary.id) # Then assert len(result.bookings) == 1 assert result.bookings[0].id == booking1.id
def save_bookings_recap_sandbox(): yesterday = datetime.utcnow() - timedelta(days=1) today = datetime.utcnow() beneficiary1 = BeneficiaryGrant18Factory(publicName="Riri Duck", firstName="Riri", lastName="Duck", email="*****@*****.**") beneficiary2 = BeneficiaryGrant18Factory( publicName="Fifi Brindacier", firstName="Fifi", lastName="Brindacier", email="*****@*****.**", ) beneficiary3 = BeneficiaryGrant18Factory( publicName="LouLou Duck", firstName="Loulou", lastName="Duck", email="*****@*****.**", ) pro = ProFactory( publicName="Balthazar Picsou", firstName="Balthazar", lastName="Picsou", email="*****@*****.**", ) offerer = OffererFactory(siren="645389012") UserOffererFactory(user=pro, offerer=offerer) venue1 = VenueFactory(managingOfferer=offerer, name="Cinéma Le Monde Perdu", siret="64538901265877") venue2 = VenueFactory(managingOfferer=offerer, name="Librairie Atlantis", siret="64538901201379") venue3 = VenueFactory(managingOfferer=offerer, name="Théatre Mordor", siret="64538954601379") venue4_virtual = VenueFactory(managingOfferer=offerer, name="Un lieu virtuel", siret=None, isVirtual=True) product1_venue1 = EventProductFactory( name="Jurassic Park", subcategoryId=subcategories.SEANCE_CINE.id) offer1_venue1 = EventOfferFactory(product=product1_venue1, venue=venue1, isDuo=True) stock_1_offer1_venue1 = EventStockFactory(offer=offer1_venue1, beginningDatetime=yesterday, quantity=None, price=12.99) product2_venue1 = EventProductFactory( name="Matrix", subcategoryId=subcategories.SEANCE_CINE.id) offer2_venue1 = EventOfferFactory(product=product2_venue1, venue=venue1, isDuo=False) stock_2_offer2_venue1 = EventStockFactory(offer=offer2_venue1, beginningDatetime=today, quantity=None, price=0) product1_venue2 = ThingProductFactory( name="Fondation", subcategoryId=subcategories.LIVRE_PAPIER.id, extraData={"isbn": "9788804119135"}) offer1_venue2 = ThingOfferFactory(product=product1_venue2, venue=venue2) stock_1_offer1_venue2 = ThingStockFactory(offer=offer1_venue2, quantity=42, price=9.99) product2_venue2 = ThingProductFactory( name="Martine à la playa", subcategoryId=subcategories.LIVRE_PAPIER.id, extraData={"isbn": "9787605639121"}, ) offer2_venue2 = ThingOfferFactory(product=product2_venue2, venue=venue2) stock_1_offer2_venue2 = ThingStockFactory(offer=offer2_venue2, quantity=12, price=49.99) product1_venue3 = EventProductFactory( name="Danse des haricots", subcategoryId=subcategories.SPECTACLE_REPRESENTATION.id) offer1_venue3 = EventOfferFactory(product=product1_venue3, venue=venue3) stock_1_offer1_venue3 = EventStockFactory(offer=offer1_venue3, quantity=44, price=18.50) product1_venue4 = ThingProductFactory( name="Le livre des haricots", subcategoryId=subcategories.LIVRE_PAPIER.id) offer1_venue4 = ThingOfferFactory(product=product1_venue4, venue=venue4_virtual) stock_1_offer1_venue4 = ThingStockFactory(offer=offer1_venue4, quantity=70, price=10.99) IndividualBookingFactory( individualBooking__user=beneficiary1, stock=stock_1_offer1_venue1, dateCreated=datetime(2020, 3, 18, 14, 56, 12, 0), isUsed=True, dateUsed=datetime(2020, 3, 22, 17, 00, 10, 0), quantity=2, ) IndividualBookingFactory( individualBooking__user=beneficiary1, stock=stock_2_offer2_venue1, dateCreated=datetime(2020, 4, 22, 9, 17, 12, 0), ) IndividualBookingFactory( individualBooking__user=beneficiary2, stock=stock_1_offer1_venue1, dateCreated=datetime(2020, 3, 18, 12, 18, 12, 0), isUsed=True, dateUsed=datetime(2020, 5, 2), quantity=2, ) booking2_beneficiary2 = IndividualBookingFactory( individualBooking__user=beneficiary2, stock=stock_1_offer1_venue2, dateCreated=datetime(2020, 4, 12, 14, 31, 12, 0), isCancelled=False, ) booking1_beneficiary3 = IndividualBookingFactory( individualBooking__user=beneficiary3, stock=stock_2_offer2_venue1, dateCreated=datetime(2020, 1, 4, 19, 31, 12, 0), isCancelled=False, isUsed=True, dateUsed=datetime(2020, 1, 4, 23, 00, 10, 0), quantity=2, ) booking2_beneficiary3 = IndividualBookingFactory( individualBooking__user=beneficiary3, stock=stock_1_offer1_venue2, dateCreated=datetime(2020, 3, 21, 22, 9, 12, 0), isCancelled=False, ) booking3_beneficiary1 = UsedIndividualBookingFactory( individualBooking__user=beneficiary1, stock=stock_1_offer1_venue3, dateCreated=datetime(2020, 4, 12, 14, 31, 12, 0), ) payment_booking3_beneficiary1 = PaymentFactory( booking=booking3_beneficiary1) PaymentStatusFactory(payment=payment_booking3_beneficiary1, status=TransactionStatus.PENDING) booking3_beneficiary2 = UsedIndividualBookingFactory( individualBooking__user=beneficiary2, stock=stock_1_offer1_venue3, dateCreated=datetime(2020, 4, 12, 19, 31, 12, 0), dateUsed=datetime(2020, 4, 22, 17, 00, 10, 0), ) PaymentFactory(booking=booking3_beneficiary2) PaymentStatusFactory(payment=payment_booking3_beneficiary1, status=TransactionStatus.SENT) booking3_beneficiary3 = UsedIndividualBookingFactory( individualBooking__user=beneficiary3, stock=stock_1_offer1_venue3, dateCreated=datetime(2020, 4, 12, 22, 9, 12, 0), ) payment_booking3_beneficiary3 = PaymentFactory( booking=booking3_beneficiary3) PaymentStatusFactory(payment=payment_booking3_beneficiary3, status=TransactionStatus.ERROR) UsedIndividualBookingFactory( individualBooking__user=beneficiary3, stock=stock_1_offer1_venue2, dateCreated=datetime(2020, 3, 21, 22, 9, 12, 0), ) booking5_beneficiary3 = IndividualBookingFactory( individualBooking__user=beneficiary3, stock=stock_1_offer1_venue4, dateCreated=datetime(2020, 3, 21, 22, 9, 12, 0), isCancelled=False, ) booking6_beneficiary3 = UsedIndividualBookingFactory( individualBooking__user=beneficiary3, stock=stock_1_offer2_venue2, dateCreated=datetime(2020, 3, 21, 22, 9, 12, 0), dateUsed=datetime(2020, 4, 22, 21, 9, 12, 0), ) payment_booking6_beneficiary3 = PaymentFactory( booking=booking6_beneficiary3) PaymentStatusFactory(payment=payment_booking6_beneficiary3, status=TransactionStatus.SENT) booking7_beneficiary2 = UsedIndividualBookingFactory( individualBooking__user=beneficiary2, stock=stock_1_offer2_venue2, dateCreated=datetime(2020, 4, 21, 22, 6, 12, 0), dateUsed=datetime(2020, 4, 22, 22, 9, 12, 0), ) payment_booking7_beneficiary2 = PaymentFactory( booking=booking7_beneficiary2) PaymentStatusFactory(payment=payment_booking7_beneficiary2, status=TransactionStatus.RETRY) UsedIndividualBookingFactory( individualBooking__user=beneficiary1, stock=stock_1_offer2_venue2, dateCreated=datetime(2020, 2, 21, 22, 6, 12, 0), dateUsed=datetime(2020, 4, 22, 23, 9, 12, 0), ) payment_booking8_beneficiary1 = PaymentFactory( booking=booking7_beneficiary2) PaymentStatusFactory(payment=payment_booking8_beneficiary1, status=TransactionStatus.PENDING) bookings_to_cancel = [ booking2_beneficiary2, booking1_beneficiary3, booking2_beneficiary3, booking3_beneficiary2, booking5_beneficiary3, ] for booking in bookings_to_cancel: try: booking.cancel_booking() except (BookingIsAlreadyUsed, BookingIsAlreadyCancelled) as e: logger.info(str(e), extra={"booking": booking.id}) repository.save(*bookings_to_cancel)
def test_get_bookings(self, app): OFFER_URL = "https://demo.pass/some/path?token={token}&email={email}&offerId={offerId}" user = users_factories.BeneficiaryGrant18Factory(email=self.identifier) permanent_booking = booking_factories.UsedIndividualBookingFactory( individualBooking__user=user, stock__offer__subcategoryId=subcategories. TELECHARGEMENT_LIVRE_AUDIO.id, dateUsed=datetime(2021, 2, 3), ) event_booking = booking_factories.IndividualBookingFactory( individualBooking__user=user, stock=EventStockFactory(beginningDatetime=datetime(2021, 3, 14))) digital_stock = StockWithActivationCodesFactory() first_activation_code = digital_stock.activationCodes[0] second_activation_code = digital_stock.activationCodes[1] digital_booking = booking_factories.UsedIndividualBookingFactory( individualBooking__user=user, stock=digital_stock, activationCode=first_activation_code, ) ended_digital_booking = booking_factories.UsedIndividualBookingFactory( individualBooking__user=user, displayAsEnded=True, stock=digital_stock, activationCode=second_activation_code, ) expire_tomorrow = booking_factories.IndividualBookingFactory( individualBooking__user=user, dateCreated=datetime.now() - timedelta(days=29)) used_but_in_future = booking_factories.UsedIndividualBookingFactory( individualBooking__user=user, dateUsed=datetime(2021, 3, 11), stock=StockFactory(beginningDatetime=datetime(2021, 3, 15)), ) cancelled_permanent_booking = booking_factories.CancelledIndividualBookingFactory( individualBooking__user=user, stock__offer__subcategoryId=subcategories. TELECHARGEMENT_LIVRE_AUDIO.id, cancellation_date=datetime(2021, 3, 10), ) cancelled = booking_factories.CancelledIndividualBookingFactory( individualBooking__user=user, cancellation_date=datetime(2021, 3, 8)) used1 = booking_factories.UsedIndividualBookingFactory( individualBooking__user=user, dateUsed=datetime(2021, 3, 1)) used2 = booking_factories.UsedIndividualBookingFactory( individualBooking__user=user, displayAsEnded=True, dateUsed=datetime(2021, 3, 2), stock__offer__url=OFFER_URL, cancellation_limit_date=datetime(2021, 3, 2), ) mediation = MediationFactory(id=111, offer=used2.stock.offer, thumbCount=1, credit="street credit") access_token = create_access_token(identity=self.identifier) test_client = TestClient(app.test_client()) test_client.auth_header = {"Authorization": f"Bearer {access_token}"} # 1: get the user # 1: get the bookings # 1: get AUTO_ACTIVATE_DIGITAL_BOOKINGS feature # 1: rollback with assert_num_queries(4): response = test_client.get("/native/v1/bookings") assert response.status_code == 200 assert [b["id"] for b in response.json["ongoing_bookings"]] == [ expire_tomorrow.id, event_booking.id, used_but_in_future.id, digital_booking.id, permanent_booking.id, ] assert response.json["ongoing_bookings"][3]["activationCode"] assert [b["id"] for b in response.json["ended_bookings"]] == [ ended_digital_booking.id, cancelled_permanent_booking.id, cancelled.id, used2.id, used1.id, ] assert response.json["ended_bookings"][3] == { "activationCode": None, "cancellationDate": None, "cancellationReason": None, "confirmationDate": "2021-03-02T00:00:00Z", "completedUrl": f"https://demo.pass/some/path?token={used2.token}&[email protected]&offerId={humanize(used2.stock.offer.id)}", "dateUsed": "2021-03-02T00:00:00Z", "expirationDate": None, "quantity": 1, "qrCodeData": None, "id": used2.id, "stock": { "beginningDatetime": None, "id": used2.stock.id, "offer": { "category": { "categoryType": "Thing", "label": "Support physique (DVD, Blu-ray...)", "name": "FILM", }, "subcategoryId": subcategories.SUPPORT_PHYSIQUE_FILM.id, "extraData": None, "id": used2.stock.offer.id, "image": { "credit": "street credit", "url": mediation.thumbUrl }, "isDigital": True, "isPermanent": False, "name": used2.stock.offer.name, "url": f"https://demo.pass/some/path?token={used2.token}&[email protected]&offerId={humanize(used2.stock.offer.id)}", "venue": { "city": "Paris", "coordinates": { "latitude": 48.87004, "longitude": 2.3785 }, "id": used2.venue.id, "name": used2.venue.name, "publicName": used2.venue.publicName, }, "withdrawalDetails": None, }, }, "token": used2.token, "totalAmount": 1000, } for booking in response.json["ongoing_bookings"]: assert booking["qrCodeData"] is not None
def test_get_event_offer(self, app): offer_type = EventType.CINEMA extra_data = { "author": "mandibule", "isbn": "3838", "musicSubType": "502", "musicType": "501", "performer": "interprète", "showSubType": "101", "showType": "100", "stageDirector": "metteur en scène", "speaker": "intervenant", "visa": "vasi", } offer = OfferFactory( type=str(offer_type), isDuo=True, description="desk cryption", name="l'offre du siècle", withdrawalDetails="modalité de retrait", extraData=extra_data, durationMinutes=33, visualDisabilityCompliant=True, externalTicketOfficeUrl="https://url.com", venue__name="il est venu le temps des names", ) MediationFactory(id=111, offer=offer, thumbCount=1, credit="street credit") bookableStock = EventStockFactory(offer=offer, price=12.34) notBookableStock = EventStockFactory( offer=offer, price=45.68, beginningDatetime=datetime.utcnow() - timedelta(days=1)) response = TestClient( app.test_client()).get(f"/native/v1/offer/{offer.id}") assert response.status_code == 200 assert response.json == { "id": offer.id, "accessibility": { "audioDisability": False, "mentalDisability": False, "motorDisability": False, "visualDisability": True, }, "stocks": [ { "id": bookableStock.id, "price": 1234, "beginningDatetime": "2020-01-06T00:00:00", "bookingLimitDatetime": "2020-01-05T23:00:00", "cancellationLimitDatetime": "2020-01-03T00:00:00", "isBookable": True, }, { "id": notBookableStock.id, "price": 4568, "isBookable": False, "beginningDatetime": "2019-12-31T00:00:00", "bookingLimitDatetime": "2019-12-30T23:00:00", "cancellationLimitDatetime": "2020-01-01T00:00:00", }, ], "category": { "categoryType": "Event", "label": "Cinéma", "name": "CINEMA" }, "description": "desk cryption", "externalTicketOfficeUrl": "https://url.com", "extraData": { "author": "mandibule", "isbn": "3838", "durationMinutes": 33, "musicSubType": "Acid Jazz", "musicType": "Jazz", "performer": "interprète", "showSubType": "Carnaval", "showType": "Arts de la rue", "speaker": "intervenant", "stageDirector": "metteur en scène", "visa": "vasi", }, "image": { "url": "http://localhost/storage/thumbs/mediations/N4", "credit": "street credit" }, "isActive": True, "isDuo": True, "isDigital": False, "name": "l'offre du siècle", "venue": { "id": offer.venue.id, "address": "1 boulevard Poissonnière", "city": "Paris", "coordinates": { "latitude": 48.87004, "longitude": 2.3785, }, "name": "il est venu le temps des names", "offerer": { "name": offer.venue.managingOfferer.name }, "postalCode": "75000", "publicName": "il est venu le temps des names", }, "withdrawalDetails": "modalité de retrait", }
def test_refuse_prebooking(self, app) -> None: redactor = EducationalRedactorFactory( civility="M.", firstName="Jean", lastName="Doudou", email="*****@*****.**", ) stock: Stock = EventStockFactory(quantity=200, dnBookedQuantity=0) booking = EducationalBookingFactory( educationalBooking__educationalRedactor=redactor, status=BookingStatus.CONFIRMED, stock=stock, quantity=20, ) client = TestClient(app.test_client()).with_eac_token() response = client.post( f"/adage/v1/prebookings/{booking.educationalBookingId}/refuse") assert response.status_code == 200 booking = Booking.query.one() stock = booking.stock offer = stock.offer venue = offer.venue educational_booking = booking.educationalBooking assert response.json == { "address": venue.address, "beginningDatetime": format_into_utc_date(stock.beginningDatetime), "cancellationDate": "2022-11-17T15:00:00Z", "cancellationLimitDate": format_into_utc_date(booking.cancellationLimitDate), "city": venue.city, "confirmationDate": None, "confirmationLimitDate": format_into_utc_date(educational_booking.confirmationLimitDate), "coordinates": { "latitude": float(venue.latitude), "longitude": float(venue.longitude), }, "creationDate": format_into_utc_date(booking.dateCreated), "description": offer.description, "durationMinutes": offer.durationMinutes, "expirationDate": booking.expirationDate, "id": educational_booking.id, "image": None, "isDigital": offer.isDigital, "venueName": venue.name, "name": offer.name, "postalCode": venue.postalCode, "price": booking.amount, "quantity": booking.quantity, "redactor": { "email": "*****@*****.**", "redactorFirstName": "Jean", "redactorLastName": "Doudou", "redactorCivility": "M.", }, "UAICode": educational_booking.educationalInstitution.institutionId, "yearId": int(educational_booking.educationalYearId), "status": "REFUSED", "venueTimezone": venue.timezone, "totalAmount": booking.total_amount, "url": offer_webapp_link(offer), "withdrawalDetails": offer.withdrawalDetails, } # It should be 0 because on booking factory creation it goes to 20, then on cancellation it goes 20-20 assert stock.dnBookedQuantity == 0 assert booking.status == BookingStatus.CANCELLED assert booking.cancellationReason == BookingCancellationReasons.REFUSED_BY_INSTITUTE
def test_get_event_offer(self, app): offer_type = EventType.CINEMA extra_data = { "author": "mandibule", "isbn": "3838", "musicSubType": "502", "musicType": "501", "performer": "interprète", "showSubType": "101", "showType": "100", "stageDirector": "metteur en scène", "speaker": "intervenant", "visa": "vasi", } offer = OfferFactory( type=str(offer_type), isDuo=True, withdrawalDetails="modalité de retrait", extraData=extra_data, durationMinutes=33, visualDisabilityCompliant=True, externalTicketOfficeUrl="https://url.com", ) mediation = MediationFactory(offer=offer, thumbCount=1, credit="street credit") bookableStock = EventStockFactory(offer=offer, price=12.34) notBookableStock = EventStockFactory( offer=offer, price=45.68, beginningDatetime=datetime.utcnow() - timedelta(days=1)) response = TestClient( app.test_client()).get(f"/native/v1/offer/{offer.id}") assert response.status_code == 200 assert response.json == { "id": offer.id, "accessibility": { "audioDisability": None, "mentalDisability": None, "motorDisability": None, "visualDisability": True, }, "stocks": [ { "id": bookableStock.id, "price": 12.34, "beginningDatetime": bookableStock.beginningDatetime.strftime( "%Y-%m-%dT%H:%M:%S.%f"), "bookingLimitDatetime": bookableStock.bookingLimitDatetime.strftime( "%Y-%m-%dT%H:%M:%S.%f"), "isBookable": True, }, { "id": notBookableStock.id, "price": 45.68, "isBookable": False, "beginningDatetime": notBookableStock.beginningDatetime.strftime( "%Y-%m-%dT%H:%M:%S.%f"), "bookingLimitDatetime": notBookableStock.bookingLimitDatetime.strftime( "%Y-%m-%dT%H:%M:%S.%f"), }, ], "category": { "categoryType": "Event", "label": "Cinéma", "name": "CINEMA" }, "description": offer.description, "externalTicketOfficeUrl": "https://url.com", "extraData": { "author": "mandibule", "isbn": "3838", "durationMinutes": 33, "musicSubType": "Acid Jazz", "musicType": "Jazz", "performer": "interprète", "showSubType": "Carnaval", "showType": "Arts de la rue", "speaker": "intervenant", "stageDirector": "metteur en scène", "visa": "vasi", }, "image": { "url": mediation.thumbUrl, "credit": mediation.credit }, "isActive": True, "isDuo": True, "isDigital": offer.isDigital, "name": offer.name, "venue": { "id": offer.venue.id, "address": offer.venue.address, "city": offer.venue.city, "coordinates": { "latitude": float(offer.venue.latitude) if offer.venue.latitude else None, "longitude": float(offer.venue.longitude) if offer.venue.longitude else None, }, "name": offer.venue.name, "offerer": { "name": offer.venue.managingOfferer.name }, "postalCode": offer.venue.postalCode, "publicName": offer.venue.publicName, }, "withdrawalDetails": offer.withdrawalDetails, }