def should_call_email_service_for_individual_bookings_which_will_expire_in_7_days( self, mocked_email_recap, app) -> None: # Given now = date.today() booking_date_23_days_ago = now - timedelta(days=23) booking_date_22_days_ago = now - timedelta(days=22) dvd = ProductFactory( subcategoryId=subcategories.SUPPORT_PHYSIQUE_FILM.id) expire_in_7_days_dvd_individual_booking = IndividualBookingFactory( stock__offer__product=dvd, dateCreated=booking_date_23_days_ago, isCancelled=False, ) non_expired_cd = ProductFactory( subcategoryId=subcategories.SUPPORT_PHYSIQUE_MUSIQUE.id) dont_expire_in_7_days_cd_individual_booking = IndividualBookingFactory( stock__offer__product=non_expired_cd, dateCreated=booking_date_22_days_ago, isCancelled=False, ) repository.save(dont_expire_in_7_days_cd_individual_booking) # When notify_users_of_soon_to_be_expired_individual_bookings() # Then mocked_email_recap.assert_called_once_with( expire_in_7_days_dvd_individual_booking.individualBooking.user, [expire_in_7_days_dvd_individual_booking])
def test_get_user_attributes(): user = BeneficiaryGrant18Factory(deposit__version=1) offer = OfferFactory(product__id=list(TRACKED_PRODUCT_IDS.keys())[0]) b1 = IndividualBookingFactory(individualBooking__user=user, amount=10, stock__offer=offer) b2 = IndividualBookingFactory(individualBooking__user=user, amount=10, dateUsed=datetime(2021, 5, 6), stock__offer=offer) IndividualBookingFactory( individualBooking__user=user, amount=100, status=BookingStatus.CANCELLED) # should be ignored last_date_created = max(booking.dateCreated for booking in [b1, b2]) n_query_get_user = 1 n_query_get_bookings = 1 n_query_get_deposit = 1 n_query_is_pro = 1 n_query_get_last_favorite = 1 with assert_num_queries(n_query_get_user + n_query_get_bookings + n_query_get_deposit + n_query_is_pro + n_query_get_last_favorite): attributes = get_user_attributes(user) assert attributes == UserAttributes( domains_credit=DomainsCredit( all=Credit(initial=Decimal("500"), remaining=Decimal("480.00")), digital=Credit(initial=Decimal("200"), remaining=Decimal("200")), physical=Credit(initial=200, remaining=Decimal("180.00")), ), booking_categories=["FILM"], date_created=user.dateCreated, date_of_birth=user.dateOfBirth, departement_code="75", deposit_expiration_date=user.deposit_expiration_date, eligibility=EligibilityType.AGE18, first_name="Jeanne", is_beneficiary=True, is_pro=False, last_booking_date=last_date_created, last_name="Doux", marketing_push_subscription=True, postal_code=None, products_use_date={"product_brut_x_use": datetime(2021, 5, 6, 0, 0)}, booking_count=2, booking_subcategories=["SUPPORT_PHYSIQUE_FILM"], deposit_activation_date=user.deposit_activation_date, has_completed_id_check=None, user_id=user.id, is_eligible=True, is_email_validated=True, last_favorite_creation_date=None, last_visit_date=None, marketing_email_subscription=True, )
def test_get_bookings_categories_and_subcategories(): user = BeneficiaryGrant18Factory() offer = OfferFactory(product__id=list(TRACKED_PRODUCT_IDS.keys())[0]) assert _get_bookings_categories_and_subcategories( _get_user_bookings(user)) == ([], []) IndividualBookingFactory(individualBooking__user=user, stock__offer=offer) IndividualBookingFactory(individualBooking__user=user, stock__offer=offer) IndividualBookingFactory(individualBooking__user=user, isCancelled=True) assert _get_bookings_categories_and_subcategories( _get_user_bookings(user)) == (["FILM"], ["SUPPORT_PHYSIQUE_FILM"])
def when_user_has_booked_some_offers(self, app): # Given user = BeneficiaryGrant18Factory(email="*****@*****.**", postalCode="93020", deposit__version=1) IndividualBookingFactory(individualBooking__user=user, amount=5) # When response = (TestClient(app.test_client()).with_session_auth( "*****@*****.**").get("/beneficiaries/current")) # Then assert response.json["wallet_balance"] == 495.0 assert response.json["domainsCredit"] == { "all": { "initial": 500.0, "remaining": 495.0 }, "digital": { "initial": 200.0, "remaining": 200.0 }, "physical": { "initial": 200.0, "remaining": 195.0 }, }
def when_current_user_has_rights_on_offer(self, app, db_session): # given offer = offers_factories.OfferFactory() offers_factories.UserOffererFactory( user__email="*****@*****.**", offerer=offer.venue.managingOfferer, ) stock = offers_factories.StockFactory(offer=offer) booking = IndividualBookingFactory(stock=stock) # when client = TestClient( app.test_client()).with_session_auth("*****@*****.**") response = client.delete(f"/stocks/{humanize(stock.id)}") # then assert response.status_code == 200 assert response.json == {"id": humanize(stock.id)} assert stock.isSoftDeleted assert push_testing.requests[-1] == { "group_id": "Cancel_booking", "message": { "body": f"""Ta commande "{offer.name}" a été annulée par l'offreur.""", "title": "Commande annulée", }, "user_ids": [booking.individualBooking.userId], }
def test_format_batch_user(): user = BeneficiaryGrant18Factory(deposit__version=1) booking = IndividualBookingFactory(individualBooking__user=user) res = format_batch_users([user]) assert len(res) == 1 assert res[0].attributes == { "date(u.date_created)": user.dateCreated.strftime(BATCH_DATETIME_FORMAT), "date(u.date_of_birth)": user.dateOfBirth.strftime(BATCH_DATETIME_FORMAT), "date(u.deposit_expiration_date)": user.deposit_expiration_date.strftime(BATCH_DATETIME_FORMAT), "date(u.last_booking_date)": booking.dateCreated.strftime(BATCH_DATETIME_FORMAT), "u.credit": 49000, "u.departement_code": "75", "u.is_beneficiary": True, "u.marketing_push_subscription": True, "u.postal_code": None, "ut.booking_categories": ["FILM"], }
def test_format_sendinblue_user(): user = BeneficiaryGrant18Factory(deposit__version=1) booking = IndividualBookingFactory(individualBooking__user=user) res = format_sendinblue_users([user]) assert len(res) == 1 assert res[0].email == user.email assert res[0].attributes == { "BOOKED_OFFER_CATEGORIES": "FILM", "BOOKED_OFFER_SUBCATEGORIES": "SUPPORT_PHYSIQUE_FILM", "BOOKING_COUNT": 1, "CREDIT": Decimal("490.00"), "DATE_CREATED": user.dateCreated, "DATE_OF_BIRTH": user.dateOfBirth, "DEPARTMENT_CODE": "75", "DEPOSIT_ACTIVATION_DATE": user.deposit_activation_date, "DEPOSIT_EXPIRATION_DATE": user.deposit_expiration_date, "ELIGIBILITY": user.eligibility, "FIRSTNAME": "Jeanne", "HAS_COMPLETED_ID_CHECK": None, "INITIAL_CREDIT": Decimal("500"), "IS_BENEFICIARY": True, "IS_ELIGIBLE": user.is_eligible, "IS_EMAIL_VALIDATED": user.isEmailValidated, "IS_PRO": False, "LASTNAME": "Doux", "LAST_BOOKING_DATE": booking.dateCreated, "LAST_FAVORITE_CREATION_DATE": None, "LAST_VISIT_DATE": None, "MARKETING_EMAIL_SUBSCRIPTION": True, "POSTAL_CODE": None, "PRODUCT_BRUT_X_USE_DATE": None, "USER_ID": user.id, }
def when_user_has_bookings_and_qr_code_feature_is_active( self, qr_code_is_active, app): # Given user1 = BeneficiaryGrant18Factory(email="*****@*****.**") user2 = BeneficiaryGrant18Factory(email="*****@*****.**") venue = VenueFactory(latitude=None, longitude=None) offer = ThingOfferFactory(venue=venue) offer2 = ThingOfferFactory() stock = ThingStockFactory(offer=offer, price=0, quantity=None) stock2 = ThingStockFactory(offer=offer2, price=0) IndividualBookingFactory(individualBooking__user=user1, stock=stock, token="ABCDEF") IndividualBookingFactory(individualBooking__user=user2, stock=stock, token="GHIJK") IndividualBookingFactory(individualBooking__user=user1, stock=stock2, token="BBBBB") # When response = TestClient(app.test_client()).with_session_auth( user1.email).get("/bookings") # Then all_bookings = response.json assert len(all_bookings) == 2 first_booking = all_bookings[0] assert response.status_code == 200 assert "qrCode" in first_booking assert "completedUrl" in first_booking assert "isEventExpired" in first_booking assert "offer" in first_booking["stock"] assert "isEventExpired" in first_booking["stock"] assert "isDigital" in first_booking["stock"]["offer"] assert "isEvent" in first_booking["stock"]["offer"] assert "thumbUrl" in first_booking["stock"]["offer"] assert "stocks" in first_booking["stock"]["offer"] assert "venue" in first_booking["stock"]["offer"] assert "validationToken" not in first_booking["stock"]["offer"][ "venue"]
def _create_has_booked_some_bookings(bookings_by_name, offers_by_name, user, user_name): for (offer_index, (offer_name, offer)) in enumerate(list(offers_by_name.items())): # FIXME (viconnex, 2020-12-22) trying to adapt previous code - not sure of the result and intention # FIXME (asaunier, 2021-01-22) UPDATE - We should replace the "ratio" mechanism by a more immutable data # construction. We currently pick among the list of available offers that may change. if offer_index % OFFER_WITH_BOOKINGS_RATIO != 0: continue domains_credit = get_domains_credit(user) digital_credit = domains_credit.digital all_credit = domains_credit.all if digital_credit and digital_credit.remaining < MAX_RATIO_OF_INITIAL_CREDIT * float( digital_credit.initial): break if all_credit.remaining < MAX_RATIO_OF_INITIAL_CREDIT * float( all_credit.initial): break is_activation_offer = offer.product.subcategoryId in ( subcategories.ACTIVATION_EVENT.id or subcategories.ACTIVATION_THING.id) stock = choice(offer.stocks) if is_activation_offer: is_used = True else: is_used = offer_index % BOOKINGS_USED_REMOVE_MODULO != 0 if is_used: stock.beginningDatetime = datetime.now() - timedelta(days=2) stock.bookingLimitDatetime = datetime.now() - timedelta(days=5) repository.save(stock) booking = IndividualBookingFactory( individualBooking__user=user, isUsed=is_used, status=BookingStatus.USED if is_used else BookingStatus.CONFIRMED, stock=stock, dateUsed=datetime.now() - timedelta(days=2) if is_used else None, ) booking_name = "{} / {} / {}".format(offer_name, user_name, booking.token) bookings_by_name[booking_name] = booking
def test_update_external_user(): user = BeneficiaryGrant18Factory() IndividualBookingFactory(individualBooking__user=user) n_query_get_user = 1 n_query_get_bookings = 1 n_query_get_deposit = 1 n_query_is_pro = 1 n_query_get_last_favorite = 1 with assert_num_queries(n_query_get_user + n_query_get_bookings + n_query_get_deposit + n_query_is_pro + n_query_get_last_favorite): update_external_user(user) assert len(batch_testing.requests) == 1 assert len(sendinblue_testing.sendinblue_requests) == 1
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 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_when_user_has_bookings_and_qr_code_feature_is_inactive_does_not_return_qr_code( self, qr_code_is_active, app): # Given user1 = BeneficiaryGrant18Factory(email="*****@*****.**") user2 = BeneficiaryGrant18Factory(email="*****@*****.**") venue = VenueFactory(latitude=None, longitude=None) offer = ThingOfferFactory(venue=venue) offer2 = ThingOfferFactory() stock = ThingStockFactory(offer=offer, price=0, quantity=None) stock2 = ThingStockFactory(offer=offer2, price=0) booking1 = IndividualBookingFactory(individualBooking__user=user1, stock=stock, token="ABCDEF") IndividualBookingFactory(individualBooking__user=user2, stock=stock, token="GHIJK") booking3 = IndividualBookingFactory(individualBooking__user=user1, stock=stock2, token="BBBBB") # When response = TestClient(app.test_client()).with_session_auth( user1.email).get("/bookings") # Then assert response.status_code == 200 bookings = response.json assert len(bookings) == 2 assert {b["id"] for b in bookings } == set(humanize(b.id) for b in {booking1, booking3}) assert "qrCode" not in bookings[0] assert "validationToken" not in bookings[0]["stock"]["offer"]["venue"] assert bookings[0]["id"] == humanize(booking1.id) assert bookings[0] == { "activationCode": None, "amount": 0.0, "cancellationDate": None, "completedUrl": None, "dateCreated": format_into_utc_date(booking1.dateCreated), "dateUsed": None, "displayAsEnded": None, "id": humanize(booking1.id), "isCancelled": False, "isEventExpired": False, "isUsed": False, "quantity": 1, "stock": { "beginningDatetime": None, "id": humanize(stock.id), "isEventExpired": False, "offer": { "description": offer.description, "durationMinutes": None, "extraData": offer.extraData, "id": humanize(offer.id), "isBookable": True, "isDigital": False, "isDuo": False, "isEvent": False, "isNational": False, "name": offer.product.name, "stocks": [{ "beginningDatetime": None, "bookingLimitDatetime": None, "dateCreated": format_into_utc_date(stock.dateCreated), "dateModified": format_into_utc_date(stock.dateModified), "id": humanize(stock.id), "isBookable": True, "offerId": humanize(offer.id), "price": 0.0, "quantity": None, "remainingQuantity": "unlimited", }], "thumbUrl": None, "venue": { "address": venue.address, "city": venue.city, "departementCode": venue.departementCode, "id": humanize(venue.id), "latitude": None, "longitude": None, "name": venue.name, "postalCode": venue.postalCode, }, "venueId": humanize(venue.id), "withdrawalDetails": None, }, "offerId": humanize(offer.id), "price": 0.0, }, "stockId": humanize(stock.id), "token": "ABCDEF", "userId": humanize(booking1.individualBooking.userId), }
def _create_bookings_for_other_beneficiaries(bookings_by_name, list_of_users_with_no_more_money, offers_by_name, token: int, user: User, user_name: str) -> int: user_should_have_no_more_money = "has-no-more-money" in user.email for (offer_index, (offer_name, offer)) in enumerate(list(offers_by_name.items())): # FIXME (viconnex, 2020-12-22) trying to adapt previous code - not sure of the result and intention if offer_index % OFFER_WITH_BOOKINGS_RATIO != 0: continue user_has_only_activation_booked = ( "has-booked-activation" in user.email or "has-confirmed-activation" in user.email) is_activation_offer = offer.product.subcategoryId in ( subcategories.ACTIVATION_EVENT.id, subcategories.ACTIVATION_THING.id, ) if user_has_only_activation_booked and not is_activation_offer: continue for (index, stock) in enumerate(offer.stocks): # every STOCK_MODULO RECO will have several stocks if index > 0 and offer_index % ( OFFER_WITH_SEVERAL_STOCKS_REMOVE_MODULO + index): continue booking_name = "{} / {} / {}".format(offer_name, user_name, str(token)) if is_activation_offer: is_used = ("has-confirmed-activation" in user.email or "has-booked-some" in user.email or "has-no-more-money" in user.email) else: is_used = offer_index % BOOKINGS_USED_REMOVE_MODULO != 0 if is_used: stock.beginningDatetime = datetime.now() - timedelta(days=2) stock.bookingLimitDatetime = datetime.now() - timedelta(days=5) repository.save(stock) if user_should_have_no_more_money and user not in list_of_users_with_no_more_money: booking_amount = user.deposit.amount list_of_users_with_no_more_money.append(user) elif user_should_have_no_more_money and user in list_of_users_with_no_more_money: booking_amount = 0 else: booking_amount = None bookings_by_name[booking_name] = IndividualBookingFactory( individualBooking__user=user, isUsed=is_used, status=BookingStatus.USED if is_used else BookingStatus.CONFIRMED, stock=stock, dateUsed=datetime.now() - timedelta(days=2) if is_used else None, amount=booking_amount, token=str(token), offerer=offer.venue.managingOfferer, venue=offer.venue, ) token = token + 1 return token
def test_expect_booking_to_have_completed_url(self, app): # Given user = BeneficiaryGrant18Factory(email="*****@*****.**") offerer = OffererFactory() product = ThingProductFactory() offer = ThingOfferFactory( url="https://host/path/{token}?offerId={offerId}&email={email}", audioDisabilityCompliant=None, bookingEmail="*****@*****.**", extraData={"author": "Test Author"}, mediaUrls=["test/urls"], mentalDisabilityCompliant=None, motorDisabilityCompliant=None, name="Test Book", venue__managingOfferer=offerer, product=product, ) stock = ThingStockFactory(offer=offer, price=0, quantity=None) booking = IndividualBookingFactory(individualBooking__user=user, stock=stock, token="ABCDEF") # When response = TestClient(app.test_client()).with_session_auth( user.email).get("/bookings/" + humanize(booking.id)) # Then assert response.status_code == 200 completed_url = "https://host/path/ABCDEF?offerId={}&[email protected]".format( humanize(offer.id)) assert "validationToken" not in response.json["stock"]["offer"] assert response.json == { "amount": 0.0, "cancellationDate": None, "cancellationReason": None, "completedUrl": completed_url, "cancellationLimitDate": None, "dateCreated": format_into_utc_date(booking.dateCreated), "dateUsed": None, "id": humanize(booking.id), "isCancelled": False, "isEventExpired": False, "isUsed": False, "mediation": None, "offererId": humanize(offer.venue.managingOffererId), "quantity": 1, "reimbursementDate": None, "stock": { "beginningDatetime": None, "bookingLimitDatetime": None, "dateCreated": format_into_utc_date(stock.dateCreated), "dateModified": format_into_utc_date(stock.dateModified), "dateModifiedAtLastProvider": format_into_utc_date(stock.dateModifiedAtLastProvider), "fieldsUpdated": [], "id": humanize(stock.id), "idAtProviders": None, "isBookable": True, "isEventExpired": False, "isSoftDeleted": False, "lastProviderId": None, "offer": { "ageMax": None, "ageMin": None, "audioDisabilityCompliant": None, "bookingEmail": "*****@*****.**", "conditions": None, "dateCreated": format_into_utc_date(offer.dateCreated), "dateModifiedAtLastProvider": format_into_utc_date(offer.dateModifiedAtLastProvider), "description": product.description, "durationMinutes": None, "externalTicketOfficeUrl": None, "extraData": { "author": "Test Author" }, "fieldsUpdated": [], "hasBookingLimitDatetimesPassed": False, "id": humanize(offer.id), "idAtProviders": offer.idAtProviders, "isActive": True, "isBookable": True, "isDigital": True, "isDuo": False, "isEducational": False, "isEvent": False, "isNational": False, "lastProviderId": None, "mediaUrls": ["test/urls"], "mentalDisabilityCompliant": None, "motorDisabilityCompliant": None, "name": "Test Book", "productId": humanize(offer.product.id), "stocks": [{ "beginningDatetime": None, "bookingLimitDatetime": None, "dateCreated": format_into_utc_date(stock.dateCreated), "dateModified": format_into_utc_date(stock.dateModified), "dateModifiedAtLastProvider": format_into_utc_date(stock.dateModifiedAtLastProvider), "fieldsUpdated": [], "id": humanize(stock.id), "idAtProviders": None, "isBookable": True, "isEventExpired": False, "isSoftDeleted": False, "lastProviderId": None, "offerId": humanize(offer.id), "price": 0.0, "quantity": None, "remainingQuantity": "unlimited", }], "subcategoryId": "SUPPORT_PHYSIQUE_FILM", "thumbUrl": None, "url": "https://host/path/{token}?offerId={offerId}&email={email}", "validation": "APPROVED", "venue": { "address": "1 boulevard Poissonnière", "audioDisabilityCompliant": False, "bannerMeta": None, "bannerUrl": None, "bookingEmail": None, "city": "Paris", "comment": None, "dateCreated": format_into_utc_date(offer.venue.dateCreated), "dateModifiedAtLastProvider": format_into_utc_date( offer.venue.dateModifiedAtLastProvider), "departementCode": "75", "description": offer.venue.description, "fieldsUpdated": [], "id": humanize(offer.venue.id), "idAtProviders": None, "isPermanent": False, "isVirtual": False, "lastProviderId": None, "latitude": 48.87004, "longitude": 2.3785, "managingOffererId": humanize(offer.venue.managingOffererId), "mentalDisabilityCompliant": False, "motorDisabilityCompliant": False, "name": offer.venue.name, "postalCode": "75000", "publicName": offer.venue.publicName, "siret": offer.venue.siret, "thumbCount": 0, "venueLabelId": None, "venueTypeId": None, "visualDisabilityCompliant": False, "venueTypeCode": offer.venue.venueTypeCode.value, "withdrawalDetails": None, }, "venueId": humanize(offer.venue.id), "visualDisabilityCompliant": False, "withdrawalDetails": None, }, "offerId": humanize(offer.id), "price": 0.0, "quantity": None, "remainingQuantity": "unlimited", }, "stockId": humanize(stock.id), "token": booking.token, "userId": humanize(user.id), "venueId": humanize(offer.venue.id), }