def test_reimburses_offerer_if_he_has_more_than_20000_euros_in_bookings_on_several_venues( self, app): # Given offerer1 = create_offerer(siren="123456789") repository.save(offerer1) bank_information = create_bank_information( bic="BDFEFR2LCCB", iban="FR7630006000011234567890189", offerer=offerer1) venue1 = create_venue(offerer1, siret="12345678912345") venue2 = create_venue(offerer1, siret="98765432154321") venue3 = create_venue(offerer1, siret="98123432154321") offer1 = create_offer_with_thing_product(venue1) offer2 = create_offer_with_thing_product(venue2) offer3 = create_offer_with_thing_product(venue3) paying_stock1 = create_stock_from_offer(offer1, price=10000) paying_stock2 = create_stock_from_offer(offer2, price=10000) paying_stock3 = create_stock_from_offer(offer3, price=10000) user = create_user() deposit = create_deposit(user, amount=50000) booking1 = create_booking(user=user, stock=paying_stock1, venue=venue1, is_used=True, quantity=1) booking2 = create_booking(user=user, stock=paying_stock2, venue=venue2, is_used=True, quantity=1) booking3 = create_booking(user=user, stock=paying_stock3, venue=venue3, is_used=True, quantity=1) repository.save(deposit, booking1, booking2, booking3, bank_information) # When pending, not_processable = generate_new_payments() # Then assert len(pending) == 3 assert len(not_processable) == 0 assert sum(p.amount for p in pending) == 30000
def test_returns_a_tuple_of_pending_and_not_processable_payments( self, app): # Given offerer1 = create_offerer(siren="123456789") offerer2 = create_offerer(siren="987654321") repository.save(offerer1) bank_information = create_bank_information( bic="BDFEFR2LCCB", iban="FR7630006000011234567890189", offerer=offerer1) venue1 = create_venue(offerer1, siret="12345678912345") venue2 = create_venue(offerer2, siret="98765432154321") offer1 = create_offer_with_thing_product(venue1) offer2 = create_offer_with_thing_product(venue2) paying_stock1 = create_stock_from_offer(offer1) paying_stock2 = create_stock_from_offer(offer2) free_stock1 = create_stock_from_offer(offer1, price=0) user = create_user() deposit = create_deposit(user, amount=500) booking1 = create_booking(user=user, stock=paying_stock1, venue=venue1, is_used=True) booking2 = create_booking(user=user, stock=paying_stock1, venue=venue1, is_used=True) booking3 = create_booking(user=user, stock=paying_stock2, venue=venue2, is_used=True) booking4 = create_booking(user=user, stock=free_stock1, venue=venue1, is_used=True) repository.save(deposit, booking1, booking2, booking3, booking4, bank_information) # When pending, not_processable = generate_new_payments() # Then assert len(pending) == 2 assert len(not_processable) == 1
def test_send_transactions_set_status_to_error_with_details_if_email_was_not_sent_properly( app): # given offerer1 = create_offerer(name="first offerer") user = create_user() venue1 = create_venue(offerer1) stock1 = create_stock_from_offer(create_offer_with_thing_product(venue1)) booking1 = create_booking(user=user, stock=stock1) booking2 = create_booking(user=user, stock=stock1) booking3 = create_booking(user=user, stock=stock1) deposit = create_deposit(user, amount=500) payments = [ create_payment(booking1, offerer1, 10, iban="CF13QSDFGH456789", bic="QSDFGH8Z555"), create_payment(booking2, offerer1, 20, iban="CF13QSDFGH456789", bic="QSDFGH8Z555"), create_payment(booking3, offerer1, 20, iban="CF13QSDFGH456789", bic="QSDFGH8Z555"), ] repository.save(deposit) repository.save(*payments) app.mailjet_client.send.create.return_value = Mock(status_code=400) # when send_transactions(payments, "BD12AZERTY123456", "AZERTY9Q666", "0000", ["*****@*****.**"]) # then updated_payments = Payment.query.all() for payment in updated_payments: assert len(payment.statuses) == 2 assert payment.currentStatus.status == TransactionStatus.ERROR assert payment.currentStatus.detail == "Erreur d'envoi à MailJet"
def test_send_transactions_creates_a_new_payment_transaction_if_email_was_sent_properly( app): # given@ offerer1 = create_offerer(name="first offerer") user = create_user() venue1 = create_venue(offerer1) stock1 = create_stock_from_offer(create_offer_with_thing_product(venue1)) booking1 = create_booking(user=user, stock=stock1) booking2 = create_booking(user=user, stock=stock1) booking3 = create_booking(user=user, stock=stock1) deposit = create_deposit(user, amount=500) payments = [ create_payment(booking1, offerer1, 10, iban="CF13QSDFGH456789", bic="QSDFGH8Z555"), create_payment(booking2, offerer1, 20, iban="CF13QSDFGH456789", bic="QSDFGH8Z555"), create_payment(booking3, offerer1, 20, iban="CF13QSDFGH456789", bic="QSDFGH8Z555"), ] repository.save(deposit) repository.save(*payments) app.mailjet_client.send.create.return_value = Mock(status_code=200) # when send_transactions(payments, "BD12AZERTY123456", "AZERTY9Q666", "0000", ["*****@*****.**"]) # then updated_payments = Payment.query.all() assert all(p.paymentMessageName == "passCulture-SCT-20181015-092134" for p in updated_payments) assert all(p.paymentMessageChecksum == payments[0].paymentMessageChecksum for p in updated_payments)
def test_update_booking_used_when_booking_is_on_thing_product(self, app): # Given user = create_user() deposit = create_deposit(user) offerer = create_offerer() venue = create_venue(offerer) offer = create_offer_with_thing_product(venue) stock = create_stock(beginning_datetime=None, offer=offer) booking = create_booking(user=user, is_used=False, stock=stock) repository.save(user, deposit, booking, stock) # When update_booking_used_after_stock_occurrence() # Then updated_booking = Booking.query.first() assert not updated_booking.isUsed assert not updated_booking.dateUsed
def test_send_payment_details_sends_a_csv_attachment(app): # given offerer1 = create_offerer(name="first offerer") user = create_user() venue1 = create_venue(offerer1) stock1 = create_stock_from_offer(create_offer_with_thing_product(venue1)) booking1 = create_booking(user=user, stock=stock1) booking2 = create_booking(user=user, stock=stock1) booking3 = create_booking(user=user, stock=stock1) deposit = create_deposit(user, amount=500) payments = [ create_payment(booking1, offerer1, 10, iban="CF13QSDFGH456789", bic="QSDFGH8Z555"), create_payment(booking2, offerer1, 20, iban="CF13QSDFGH456789", bic="QSDFGH8Z555"), create_payment(booking3, offerer1, 20, iban="CF13QSDFGH456789", bic="QSDFGH8Z555"), ] repository.save(deposit) repository.save(*payments) app.mailjet_client.send.create.return_value = Mock(status_code=200) # when send_payments_details(payments, ["*****@*****.**"]) # then app.mailjet_client.send.create.assert_called_once() args = app.mailjet_client.send.create.call_args assert len(args[1]["data"]["Attachments"]) == 1 assert args[1]["data"]["Attachments"][0][ "ContentType"] == "application/zip"
def test_should_return_one_payment_info_with_error_status(self, app): # Given user = create_user(last_name="User", first_name="Plus") deposit = create_deposit(user) offerer = create_offerer(address="7 rue du livre") venue = create_venue(offerer) stock = create_stock_with_thing_offer(offerer=offerer, venue=venue, price=10) now = datetime.utcnow() booking = create_booking(user=user, stock=stock, is_used=True, date_used=now, token="ABCDEF", venue=venue) payment = create_payment( booking, offerer, transaction_label="pass Culture Pro - remboursement 1ère quinzaine 07-2019", status=TransactionStatus.ERROR, amount=50, detail="Iban non fourni", ) repository.save(deposit, payment) # When payments = find_all_offerer_payments(offerer.id) # Then assert len(payments) == 1 assert payments[0] == ( "User", "Plus", "ABCDEF", now, "Test Book", "7 rue du livre", "La petite librairie", "12345678912345", "123 rue de Paris", Decimal("50.00"), None, "pass Culture Pro - remboursement 1ère quinzaine 07-2019", TransactionStatus.ERROR, "Iban non fourni", )
def test_update_booking_used_when_event_date_is_3_days_before(self, app): # Given user = create_user() deposit = create_deposit(user) offerer = create_offerer() venue = create_venue(offerer) offer = create_offer_with_event_product(venue) stock = create_stock(beginning_datetime=datetime( 2019, 10, 9, 10, 20, 00), offer=offer) booking = create_booking(user=user, is_used=False, stock=stock) repository.save(user, deposit, booking, stock) # When update_booking_used_after_stock_occurrence() # Then updated_booking = Booking.query.first() assert updated_booking.isUsed assert updated_booking.dateUsed == datetime(2019, 10, 13)
def test_records_new_payment_lines_in_database(self, app): # Given offerer = create_offerer() venue = create_venue(offerer) offer = create_offer_with_thing_product(venue) paying_stock = create_stock_from_offer(offer) free_stock = create_stock_from_offer(offer, price=0) user = create_user() deposit = create_deposit(user, amount=500) booking1 = create_booking(user=user, stock=paying_stock, venue=venue, is_used=True) booking2 = create_booking(user=user, stock=paying_stock, venue=venue, is_used=True) booking3 = create_booking(user=user, stock=paying_stock, venue=venue, is_used=True) booking4 = create_booking(user=user, stock=free_stock, venue=venue, is_used=True) payment1 = create_payment(booking2, offerer, 10, payment_message_name="ABCD123") repository.save(payment1) repository.save(deposit, booking1, booking3, booking4) initial_payment_count = Payment.query.count() # When generate_new_payments() # Then assert Payment.query.count() - initial_payment_count == 2
def create_industrial_deposits(users_by_name): logger.info("create_industrial_deposits") deposits_by_name = {} for (user_name, user) in users_by_name.items(): user_has_no_deposit = (user.firstName != "PC Test Jeune" or "has-signed-up" in user_name or "has-booked-activation" in user_name) if user_has_no_deposit: continue deposits_by_name["{} / public / 500".format( user_name)] = create_deposit(user, amount=500) repository.save(*deposits_by_name.values()) logger.info("created %d deposits", len(deposits_by_name)) return deposits_by_name
def test_send_transactions_should_send_an_email_with_xml_attachment(app): # given offerer1 = create_offerer(name="first offerer") user = create_user() venue1 = create_venue(offerer1) stock1 = create_stock_from_offer(create_offer_with_thing_product(venue1)) booking1 = create_booking(user=user, stock=stock1) booking2 = create_booking(user=user, stock=stock1) booking3 = create_booking(user=user, stock=stock1) deposit = create_deposit(user, amount=500) repository.save(deposit) payments = [ create_payment(booking1, offerer1, 10, iban="FR7630007000111234567890144", bic="BDFEFR2LCCB"), create_payment(booking2, offerer1, 20, iban="FR7630007000111234567890144", bic="BDFEFR2LCCB"), create_payment(booking3, offerer1, 20, iban="FR7630007000111234567890144", bic="BDFEFR2LCCB"), ] app.mailjet_client.send.create.return_value = Mock(status_code=200) # when send_transactions(payments, "BD12AZERTY123456", "AZERTY9Q666", "0000", ["*****@*****.**"]) # then app.mailjet_client.send.create.assert_called_once() args = app.mailjet_client.send.create.call_args assert len(args[1]["data"]["Attachments"]) == 1
def test_should_send_booking_cancellation_email_only_to_administration_when_no_booking_email_provided( self, mock_feature_send_mail_to_users_enabled, app): # Given user = create_user(email="*****@*****.**") offerer = create_offerer() deposit = create_deposit(user, amount=500) venue = create_venue(offerer) stock = create_stock_with_event_offer(offerer, venue) stock.offer.bookingEmail = None booking = create_booking(user=user, stock=stock) mocked_send_email = Mock() repository.save(deposit, stock) # When send_user_driven_cancellation_email_to_offerer(booking, mocked_send_email) # Then mocked_send_email.assert_called_once() args = mocked_send_email.call_args_list assert args[0][1]["data"]["To"] == "*****@*****.**"
def test_full_reimburses_book_product_when_bookings_are_below_20000_euros( self, app): # Given offerer1 = create_offerer(siren="123456789") repository.save(offerer1) bank_information = create_bank_information( bic="BDFEFR2LCCB", iban="FR7630006000011234567890189", offerer=offerer1) venue1 = create_venue(offerer1, siret="12345678912345") venue2 = create_venue(offerer1, siret="98765432154321") offer1 = create_offer_with_thing_product( venue1, thing_type=ThingType.LIVRE_EDITION, url=None) offer2 = create_offer_with_thing_product( venue2, thing_type=ThingType.LIVRE_EDITION, url=None) paying_stock1 = create_stock_from_offer(offer1, price=10000) paying_stock2 = create_stock_from_offer(offer2, price=19990) user = create_user() deposit = create_deposit(user, amount=50000) booking1 = create_booking(user=user, stock=paying_stock1, venue=venue1, is_used=True, quantity=1) booking2 = create_booking(user=user, stock=paying_stock2, venue=venue2, is_used=True, quantity=1) repository.save(deposit, booking1, booking2, bank_information) # When pending, not_processable = generate_new_payments() # Then assert len(pending) == 2 assert len(not_processable) == 0 assert sum(p.amount for p in pending) == 29990
def test_a_list_of_payments_is_returned_with_statuses_in_error_or_retry_or_pending( self, app): # Given user = create_user() booking = create_booking(user=user) deposit = create_deposit(user) offerer = booking.stock.offer.venue.managingOfferer error_payment = create_payment(booking, offerer, 10) retry_payment = create_payment(booking, offerer, 10) pending_payment = create_payment(booking, offerer, 10) not_processable_payment = create_payment(booking, offerer, 10) error_status = PaymentStatus() error_status.status = TransactionStatus.ERROR error_payment.statuses.append(error_status) retry_status = PaymentStatus() retry_status.status = TransactionStatus.RETRY retry_payment.statuses.append(retry_status) not_processable_status = PaymentStatus() not_processable_status.status = TransactionStatus.NOT_PROCESSABLE not_processable_payment.statuses.append(not_processable_status) repository.save(error_payment, retry_payment, pending_payment, deposit) # When payments = concatenate_payments_with_errors_and_retries( [pending_payment]) # Then assert len(payments) == 3 allowed_statuses = (TransactionStatus.RETRY, TransactionStatus.ERROR, TransactionStatus.PENDING) assert all( map(lambda p: p.currentStatus.status in allowed_statuses, payments))
def test_cancel_bookings_of_offers_from_rows(self): beneficiary = create_user() create_deposit(user=beneficiary) offerer_to_cancel = create_offerer( name="Librairie les petits parapluies gris", siren="123456789") offerer_to_not_cancel = create_offerer( name="L'amicale du club de combat", siren="987654321") venue_to_cancel = create_venue(offerer=offerer_to_cancel, siret="12345678912345") venue_to_not_cancel = create_venue(offerer=offerer_to_not_cancel, siret="54321987654321") offer_to_cancel = create_offer_with_event_product( venue=venue_to_cancel, event_name="Dédicace de la Joie des Visiteurs") offer_to_not_cancel = create_offer_with_event_product( venue=venue_to_not_cancel, event_name="Règle numéro une, ne pas du club de combat") stock_to_cancel = create_stock(offer=offer_to_cancel) stock_to_not_cancel = create_stock(offer=offer_to_not_cancel) self.booking_to_cancel = create_booking(stock=stock_to_cancel, user=beneficiary, is_used=True, date_used=datetime.utcnow()) self.booking_to_not_cancel = create_booking(stock=stock_to_not_cancel, user=beneficiary) self.booking_2QLYYA_not_to_cancel = create_booking( stock=stock_to_cancel, user=beneficiary, token="2QLYYA") self.booking_BMTUME_not_to_cancel = create_booking( stock=stock_to_cancel, user=beneficiary, token="BMTUME") self.booking_LUJ9AM_not_to_cancel = create_booking( stock=stock_to_cancel, user=beneficiary, token="LUJ9AM") self.booking_DA8YLU_not_to_cancel = create_booking( stock=stock_to_cancel, user=beneficiary, token="DA8YLU") self.booking_Q46YHM_not_to_cancel = create_booking( stock=stock_to_cancel, user=beneficiary, token="Q46YHM") repository.save(self.booking_to_cancel, self.booking_to_not_cancel) self.csv_rows = [ [ "id offre", "Structure", "Département", "Offre", "Date de l'évènement", "Nb Réservations", "A annuler ?", "Commentaire", ], [ offer_to_cancel.id, offer_to_cancel.name, "75000", offer_to_cancel.name, "2020-06-19 18:00:48", 1, "Oui", "", ], [ offer_to_not_cancel.id, offerer_to_not_cancel.name, offer_to_not_cancel.name, "93000", "2020-06-20 18:00:12", 1, "Non", "", ], ] _cancel_bookings_of_offers_from_rows(self.csv_rows) # Then saved_booking = Booking.query.get(self.booking_to_cancel.id) assert saved_booking.isCancelled is True assert saved_booking.cancellationDate is not None assert saved_booking.isUsed is False assert saved_booking.dateUsed is None saved_booking = Booking.query.get(self.booking_to_not_cancel.id) assert saved_booking.isCancelled is False assert saved_booking.cancellationDate is None saved_2QLYYA_booking = Booking.query.get( self.booking_2QLYYA_not_to_cancel.id) assert saved_2QLYYA_booking.isCancelled is False assert saved_2QLYYA_booking.cancellationDate is None saved_BMTUME_booking = Booking.query.get( self.booking_BMTUME_not_to_cancel.id) assert saved_BMTUME_booking.isCancelled is False assert saved_BMTUME_booking.cancellationDate is None saved_LUJ9AM_booking = Booking.query.get( self.booking_LUJ9AM_not_to_cancel.id) assert saved_LUJ9AM_booking.isCancelled is False assert saved_LUJ9AM_booking.cancellationDate is None saved_DA8YLU_booking = Booking.query.get( self.booking_DA8YLU_not_to_cancel.id) assert saved_DA8YLU_booking.isCancelled is False assert saved_DA8YLU_booking.cancellationDate is None saved_Q46YHM_booking = Booking.query.get( self.booking_Q46YHM_not_to_cancel.id) assert saved_Q46YHM_booking.isCancelled is False assert saved_Q46YHM_booking.cancellationDate is None
def test_should_return_last_matching_status_based_on_date_for_each_payment(self, app): # Given user = create_user(last_name="User", first_name="Plus") deposit = create_deposit(user) offerer = create_offerer(address="7 rue du livre") venue = create_venue(offerer) stock = create_stock_with_thing_offer(offerer=offerer, venue=venue, price=10) now = datetime.utcnow() booking1 = create_booking(user=user, stock=stock, is_used=True, date_used=now, token="ABCDEF", venue=venue) booking2 = create_booking(user=user, stock=stock, is_used=True, date_used=now, token="ABCDFE", venue=venue) payment1 = create_payment( booking1, offerer, transaction_label="pass Culture Pro - remboursement 1ère quinzaine 07-2019", status=TransactionStatus.PENDING, amount=50, status_date=now - timedelta(days=2), ) payment2 = create_payment( booking2, offerer, transaction_label="pass Culture Pro - remboursement 2ème quinzaine 07-2019", status=TransactionStatus.PENDING, amount=75, status_date=now - timedelta(days=4), ) repository.save(deposit, payment1, payment2) last_status_for_payment1 = create_payment_status( payment1, detail="All good", status=TransactionStatus.SENT, date=now ) last_status_for_payment2 = create_payment_status(payment2, detail=None, status=TransactionStatus.SENT, date=now) repository.save(last_status_for_payment1, last_status_for_payment2) first_status_for_payment1 = create_payment_status( payment1, detail="Retry", status=TransactionStatus.RETRY, date=now - timedelta(days=1) ) first_status_for_payment2 = create_payment_status( payment2, detail="Iban non fournis", status=TransactionStatus.ERROR, date=now - timedelta(days=3) ) repository.save(first_status_for_payment1, first_status_for_payment2) # When payments = find_all_offerer_payments(offerer.id) # Then assert len(payments) == 2 assert payments[0] == ( "User", "Plus", "ABCDFE", now, "Test Book", "7 rue du livre", "La petite librairie", "12345678912345", "123 rue de Paris", Decimal("75.00"), None, "pass Culture Pro - remboursement 2ème quinzaine 07-2019", TransactionStatus.SENT, None, ) assert payments[1] == ( "User", "Plus", "ABCDEF", now, "Test Book", "7 rue du livre", "La petite librairie", "12345678912345", "123 rue de Paris", Decimal("50.00"), None, "pass Culture Pro - remboursement 1ère quinzaine 07-2019", TransactionStatus.SENT, "All good", )