def when_identifier_is_unknown(self, app): # Given users_factories.BeneficiaryGrant18Factory() data = {"identifier": "*****@*****.**", "password": "******"} # When response = TestClient(app.test_client()).post("/beneficiaries/signin", json=data) # Then assert response.status_code == 401 assert response.json["signin"] == [ "Identifiant ou mot de passe incorrect" ]
def when_password_is_incorrect(self, app): # Given user = users_factories.BeneficiaryGrant18Factory() data = {"identifier": user.email, "password": "******"} # When response = TestClient(app.test_client()).post("/beneficiaries/signin", json=data) # Then assert response.status_code == 401 assert response.json["signin"] == [ "Identifiant ou mot de passe incorrect" ]
def test_should_send_email_to_beneficiary_when_expired_book_booking_cancelled( self, app): amnesiac_user = users_factories.BeneficiaryGrant18Factory( email="*****@*****.**") expired_today_book_booking = booking_factories.IndividualBookingFactory( user=amnesiac_user, stock__offer__subcategoryId=subcategories.LIVRE_PAPIER.id) send_expired_bookings_recap_email_to_beneficiary( amnesiac_user, [expired_today_book_booking]) assert len(mails_testing.outbox) == 1 assert mails_testing.outbox[0].sent_data["Mj-TemplateID"] == 3095107 assert mails_testing.outbox[0].sent_data["Vars"][ "withdrawal_period"] == 10
def when_account_is_known(self, app): # given user = users_factories.BeneficiaryGrant18Factory( civility="M.", departementCode="93", city=None, address=None, needsToFillCulturalSurvey=False, email="*****@*****.**", firstName="Jean", lastName="Smisse", phoneNumber="0612345678", postalCode="93020", publicName="Toto", lastConnectionDate=datetime.datetime(2019, 1, 1), ) data = {"identifier": user.email, "password": user.clearTextPassword} # when response = TestClient(app.test_client()).post("/users/signin", json=data) # then assert response.status_code == 200 assert not any("password" in field.lower() for field in response.json) assert response.json == { "activity": None, "address": None, "city": None, "civility": "M.", "dateCreated": format_into_utc_date(user.dateCreated), "dateOfBirth": format_into_utc_date(user.dateOfBirth), "departementCode": "93", "email": "*****@*****.**", "firstName": "Jean", "hasPhysicalVenues": False, "hasSeenProTutorials": True, "id": humanize(user.id), "isAdmin": False, "isBeneficiary": True, "isEmailValidated": True, "lastConnectionDate": format_into_utc_date(user.lastConnectionDate), "lastName": "Smisse", "needsToFillCulturalSurvey": False, "phoneNumber": "0612345678", "postalCode": "93020", "publicName": "Toto", "roles": ["BENEFICIARY"], }
def test_integration_toggle_visibility(self, app): user = users_factories.BeneficiaryGrant18Factory(email=self.identifier) access_token = create_access_token(identity=self.identifier) stock = StockWithActivationCodesFactory() activation_code = stock.activationCodes[0] booking = booking_factories.UsedIndividualBookingFactory( individualBooking__user=user, displayAsEnded=None, dateUsed=datetime.now(), stock=stock, activationCode=activation_code, ) test_client = TestClient(app.test_client()) test_client.auth_header = {"Authorization": f"Bearer {access_token}"} response = test_client.get("/native/v1/bookings") assert response.status_code == 200 assert [b["id"] for b in response.json["ongoing_bookings"]] == [booking.id] assert [b["id"] for b in response.json["ended_bookings"]] == [] response = test_client.post( f"/native/v1/bookings/{booking.id}/toggle_display", json={"ended": True}) assert response.status_code == 204 response = test_client.get("/native/v1/bookings") assert response.status_code == 200 assert [b["id"] for b in response.json["ongoing_bookings"]] == [] assert [b["id"] for b in response.json["ended_bookings"]] == [booking.id] response = test_client.post( f"/native/v1/bookings/{booking.id}/toggle_display", json={"ended": False}) assert response.status_code == 204 response = test_client.get("/native/v1/bookings") assert response.status_code == 200 assert [b["id"] for b in response.json["ongoing_bookings"]] == [booking.id] assert [b["id"] for b in response.json["ended_bookings"]] == []
def test_records_new_payment_lines_in_database(self): # Given cutoff = datetime.datetime.now() before_cutoff = cutoff - datetime.timedelta(days=1) beneficiary = users_factories.BeneficiaryGrant18Factory( email="*****@*****.**") offerer = offers_factories.OffererFactory() offer = offers_factories.ThingOfferFactory( venue__managingOfferer=offerer) paying_stock = offers_factories.ThingStockFactory(offer=offer) free_stock = offers_factories.ThingStockFactory(offer=offer, price=0) bookings_factories.UsedBookingFactory(user=beneficiary, stock=paying_stock, dateUsed=before_cutoff) bookings_factories.UsedBookingFactory(user=beneficiary, stock=paying_stock, dateUsed=before_cutoff) bookings_factories.UsedBookingFactory(user=beneficiary, stock=free_stock, dateUsed=before_cutoff) bookings_factories.UsedBookingFactory(user=beneficiary, stock=free_stock, dateUsed=before_cutoff) bookings_factories.UsedBookingFactory(user=beneficiary, stock=paying_stock, dateUsed=cutoff) payment_message = payments_factories.PaymentMessageFactory( name="ABCD123") payments_factories.PaymentFactory(paymentMessage=payment_message) initial_payment_count = Payment.query.count() # When n_queries = 1 # get_venue_ids_to_reimburse() n_queries += 1 # fetch custom reimbursement rules n_queries += 1 # find_bookings_eligible_for_payment_for_venue() n_queries += 1 # insert payments n_queries += 1 # release savepoint (commit) n_queries += 1 # insert PENDING payment statuses n_queries += 1 # release savepoint (commit) n_queries += 1 # insert NOT_PROCESSABLE payment statuses n_queries += 1 # release savepoint (commit) with assert_num_queries(n_queries): generate_new_payments(cutoff, batch_date=datetime.datetime.now()) # Then assert Payment.query.count() - initial_payment_count == 2
def test_balance(self): # given user = users_factories.BeneficiaryGrant18Factory(deposit__version=1) bookings_factories.UsedIndividualBookingFactory( individualBooking__user=user, quantity=1, amount=10) bookings_factories.UsedIndividualBookingFactory( individualBooking__user=user, quantity=2, amount=20) bookings_factories.IndividualBookingFactory( individualBooking__user=user, quantity=3, amount=30) bookings_factories.CancelledIndividualBookingFactory( individualBooking__user=user, quantity=4, amount=40) # then assert user.wallet_balance == 500 - (10 + 2 * 20 + 3 * 30) assert user.real_wallet_balance == 500 - (10 + 2 * 20)
def when_account_is_not_active(self, app): # Given user = users_factories.BeneficiaryGrant18Factory(isActive=False, password="******") data = {"identifier": user.email, "password": "******"} # When response = TestClient(app.test_client()).post("/beneficiaries/signin", json=data) # Then assert response.status_code == 401 assert response.json["signin"] == [ "Identifiant ou mot de passe incorrect" ]
def test_create_booking(self, app): beneficiary = users_factories.BeneficiaryGrant18Factory() stock = offers_factories.StockFactory(price=10, dnBookedQuantity=5) assert models.Booking.query.count() == 0 # open a second connection on purpose and lock the stock engine = create_engine(app.config["SQLALCHEMY_DATABASE_URI"]) with engine.connect() as connection: connection.execute(text("""SELECT * FROM stock WHERE stock.id = :stock_id FOR UPDATE"""), stock_id=stock.id) with pytest.raises(sqlalchemy.exc.OperationalError): api.book_offer(beneficiary=beneficiary, stock_id=stock.id, quantity=1) assert models.Booking.query.count() == 0 assert offers_models.Stock.query.filter_by(id=stock.id, dnBookedQuantity=5).count() == 1
def test_returns_true_when_a_beneficiary_import_exist_with_imported_status( self, valid_status): # given now = datetime.utcnow() beneficiary = users_factories.BeneficiaryGrant18Factory( dateCreated=now) users_factories.BeneficiaryImportStatusFactory( beneficiaryImport__applicationId=123, beneficiaryImport__beneficiary=beneficiary, status=valid_status) # when result = is_already_imported(123) # then assert result is True
def test_unsuspend_beneficiary(self, mocked_validate_csrf_token, app): admin = users_factories.AdminFactory(email="*****@*****.**") beneficiary = users_factories.BeneficiaryGrant18Factory( email="*****@*****.**", isActive=False) client = TestClient(app.test_client()).with_session_auth(admin.email) url = f"/pc/back-office/beneficiary_users/unsuspend?user_id={beneficiary.id}" data = { "reason": "fraud", "csrf_token": "token", } response = client.post(url, form=data) assert response.status_code == 302 assert beneficiary.isActive
def test_raise_when_activation_codes_are_expired(self): # Given beneficiary = users_factories.BeneficiaryGrant18Factory() stock = offers_factories.StockWithActivationCodesFactory( activationCodes__expirationDate=datetime(2000, 1, 1) ) # When with pytest.raises(exceptions.NoActivationCodeAvailable) as error: api.book_offer(beneficiary=beneficiary, stock_id=stock.id, quantity=1) # Then assert error.value.errors == { "noActivationCodeAvailable": ["Ce stock ne contient plus de code d'activation disponible."] }
def test_raises_if_email_already_taken_by_beneficiary(app): # Given email = "*****@*****.**" existing_user = users_factories.BeneficiaryGrant18Factory(email=email) beneficiary_pre_subcription = BeneficiaryPreSubscriptionFactory( email=email) # When with pytest.raises(BeneficiaryIsADuplicate) as error: validate(beneficiary_pre_subcription, preexisting_account=existing_user) # Then assert str(error.value) == f"Email {email} is already taken."
def test_too_many_bookings_postgresql_exception(): booking1 = factories.BookingFactory(stock__quantity=1) with db.session.no_autoflush: booking2 = models.Booking() booking2.user = users_factories.BeneficiaryGrant18Factory() booking2.stock = booking1.stock booking2.offerer = booking1.offerer booking2.venue = booking1.venue booking2.quantity = 1 booking2.amount = booking1.stock.price booking2.token = "123456" with pytest.raises(ApiErrors) as exc: repository.save(booking2) assert exc.value.errors["global"] == [ "La quantité disponible pour cette offre est atteinte." ]
def test_raise_when_no_activation_code_available(self): # Given beneficiary = users_factories.BeneficiaryGrant18Factory() booking = booking_factories.UsedIndividualBookingFactory(token="ABCDEF") stock = offers_factories.StockWithActivationCodesFactory(activationCodes=["code-vgya451afvyux"]) stock.activationCodes[0].booking = booking # When with pytest.raises(exceptions.NoActivationCodeAvailable) as error: api.book_offer(beneficiary=beneficiary, stock_id=stock.id, quantity=1) # Then assert Booking.query.count() == 1 assert error.value.errors == { "noActivationCodeAvailable": ["Ce stock ne contient plus de code d'activation disponible."] }
def test_payment_date_should_return_payment_date_for_status_sent(self, app): # Given beneficiary = users_factories.BeneficiaryGrant18Factory() booking = booking_factories.IndividualBookingFactory(individualBooking__user=beneficiary) today = datetime.utcnow() payment_message = create_payment_message(name="mon message") payment = create_payment(booking, booking.offerer, 5, payment_message=payment_message) payment_status = create_payment_status(payment, status=TransactionStatus.SENT, date=today) repository.save(payment_status) # When payment_from_query = Payment.query.with_entities(Payment.lastProcessedDate.label("payment_date")).first() # Then assert payment_from_query.payment_date == today
def test_cancel_booking(self, app): user = users_factories.BeneficiaryGrant18Factory(email=self.identifier) booking = booking_factories.IndividualBookingFactory( individualBooking__user=user) access_token = create_access_token(identity=self.identifier) test_client = TestClient(app.test_client()) test_client.auth_header = {"Authorization": f"Bearer {access_token}"} response = test_client.post(f"/native/v1/bookings/{booking.id}/cancel") assert response.status_code == 204 booking = Booking.query.get(booking.id) assert booking.isCancelled assert booking.cancellationReason == BookingCancellationReasons.BENEFICIARY
def when_account_is_not_validated(self, app): # Given user = users_factories.BeneficiaryGrant18Factory() client = TestClient(app.test_client()).with_session_auth(user.email) user.generate_validation_token() data = { "new_email": user.email, "password": users_factories.DEFAULT_PASSWORD } # When response = client.put("/beneficiaries/change_email_request", json=data) # Then assert response.status_code == 401 assert response.json["identifier"] == ["Ce compte n'est pas validé."]
def test_insufficient_credit(self, app): users_factories.BeneficiaryGrant18Factory(email=self.identifier) stock = StockFactory(price=501) access_token = create_access_token(identity=self.identifier) test_client = TestClient(app.test_client()) test_client.auth_header = {"Authorization": f"Bearer {access_token}"} response = test_client.post("/native/v1/bookings", json={ "stockId": stock.id, "quantity": 1 }) assert response.status_code == 400 assert response.json["code"] == "INSUFFICIENT_CREDIT"
def when_account_is_known(self, app): # given user = users_factories.BeneficiaryGrant18Factory(email="*****@*****.**") data = { "new_email": "*****@*****.**", "password": users_factories.DEFAULT_PASSWORD } # when client = TestClient(app.test_client()).with_session_auth(user.email) response = client.put("/beneficiaries/change_email_request", json=data) # then assert response.status_code == 204 information_data = { "FromEmail": "*****@*****.**", "MJ-TemplateID": 2066067, "MJ-TemplateLanguage": True, "To": user.email, "Vars": { "beneficiary_name": user.firstName, "env": "-development", }, } confirmation_data_token = ( "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJjdXJyZW50X2VtYWlsIjo" "idGVzdEBtYWlsLmNvbSIsIm5ld19lbWFpbCI6Im5ld0BlbWFpbC5jb20iLCJ" "leHAiOjE2MDI4Mzg4MDB9.Q2-583JqPSfDjuMD6ZMhMnb07Rr47iBZFRwlFC" "ymSf0") confirmation_link = ( f"{settings.WEBAPP_URL}/changement-email?token={confirmation_data_token}&expiration_timestamp=1602838800" ) confirmation_data = { "FromEmail": "*****@*****.**", "MJ-TemplateID": 2066065, "MJ-TemplateLanguage": True, "To": "*****@*****.**", "Vars": { "beneficiary_name": "Jeanne", "confirmation_link": confirmation_link, "env": "-development", }, } assert [m.sent_data for m in mails_testing.outbox ] == [information_data, confirmation_data]
def test_full_reimburses_book_product_when_bookings_are_below_20000_euros( self): # Given cutoff = datetime.datetime.now() before_cutoff = cutoff - datetime.timedelta(days=1) beneficiary = users_factories.BeneficiaryGrant18Factory( email="*****@*****.**") offerer1 = offers_factories.OffererFactory(siren="123456789") offers_factories.BankInformationFactory( bic="BDFEFR2LCCB", iban="FR7630006000011234567890189", offerer=offerer1) venue1 = offers_factories.VenueFactory(managingOfferer=offerer1, siret="12345678912345") venue2 = offers_factories.VenueFactory(managingOfferer=offerer1, siret="98765432154321") offer1 = offers_factories.ThingOfferFactory(venue=venue1) offer2 = offers_factories.ThingOfferFactory(venue=venue2) paying_stock1 = offers_factories.ThingStockFactory(offer=offer1, price=10000) paying_stock2 = offers_factories.ThingStockFactory(offer=offer2, price=19990) offers_factories.ThingStockFactory(offer=offer1, price=0) beneficiary.deposit.amount = 50000 repository.save(beneficiary.deposit) bookings_factories.UsedBookingFactory(user=beneficiary, stock=paying_stock1, dateUsed=before_cutoff, quantity=1) bookings_factories.UsedBookingFactory(user=beneficiary, stock=paying_stock2, dateUsed=before_cutoff, quantity=1) # When generate_new_payments(cutoff, batch_date=datetime.datetime.now()) # Then pending = get_pending_payments() assert pending.count() == 2 assert total_amount(pending) == 29990 assert get_not_processable_payments().count() == 0
def test_should_send_email_to_beneficiary_when_they_have_soon_to_be_expired_bookings( self, build_soon_to_be_expired_bookings_recap_email_data_for_beneficiary ): # given now = datetime.utcnow() user = users_factories.BeneficiaryGrant18Factory( email="*****@*****.**") created_23_days_ago = now - timedelta(days=23) dvd = ProductFactory( subcategoryId=subcategories.SUPPORT_PHYSIQUE_FILM.id) soon_to_be_expired_dvd_booking = booking_factories.IndividualBookingFactory( stock__offer__product=dvd, stock__offer__name="Fondation", stock__offer__venue__name="Première Fondation", dateCreated=created_23_days_ago, user=user, ) cd = ProductFactory( subcategoryId=subcategories.SUPPORT_PHYSIQUE_MUSIQUE.id) soon_to_be_expired_cd_booking = booking_factories.IndividualBookingFactory( stock__offer__product=cd, stock__offer__name="Fondation et Empire", stock__offer__venue__name="Seconde Fondation", dateCreated=created_23_days_ago, user=user, ) # when send_soon_to_be_expired_individual_bookings_recap_email_to_beneficiary( user, [soon_to_be_expired_cd_booking, soon_to_be_expired_dvd_booking]) # then build_soon_to_be_expired_bookings_recap_email_data_for_beneficiary.assert_called_once_with( beneficiary=user, bookings=[ soon_to_be_expired_cd_booking, soon_to_be_expired_dvd_booking ], days_before_cancel=7, days_from_booking=23, ) assert len(mails_testing.outbox) == 1 # test number of emails sent assert mails_testing.outbox[0].sent_data["MJ-TemplateID"] == 12345
def test_cancel_confirmed_booking(self, app): user = users_factories.BeneficiaryGrant18Factory(email=self.identifier) booking = booking_factories.IndividualBookingFactory( individualBooking__user=user, cancellation_limit_date=datetime.now() - timedelta(days=1)) access_token = create_access_token(identity=self.identifier) test_client = TestClient(app.test_client()) test_client.auth_header = {"Authorization": f"Bearer {access_token}"} response = test_client.post(f"/native/v1/bookings/{booking.id}/cancel") assert response.status_code == 400 assert response.json == { "code": "CONFIRMED_BOOKING", "message": "La date limite d'annulation est dépassée.", }
def test_returns_false_when_no_beneficiary_import_exist_for_this_id( self, app): # given now = datetime.utcnow() beneficiary = users_factories.BeneficiaryGrant18Factory( dateCreated=now) users_factories.BeneficiaryImportStatusFactory( beneficiaryImport__beneficiary=beneficiary, beneficiaryImport__applicationId=123, status=ImportStatus.CREATED, ) # when result = is_already_imported(456) # then assert result is False
def create_digital_booking(quantity=1, price=10, user=None, product_subcategory_id=None): user = user or users_factories.BeneficiaryGrant18Factory() product_kwargs = {} if product_subcategory_id: product_kwargs = {"subcategoryId": product_subcategory_id} product = offers_factories.DigitalProductFactory(**product_kwargs) stock = offers_factories.StockFactory( price=price, offer=offers_factories.ThingOfferFactory(product=product), ) return bookings_factories.UsedBookingFactory(user=user, stock=stock, quantity=quantity, dateUsed=datetime.now())
def test_already_booked(self, app): user = users_factories.BeneficiaryGrant18Factory(email=self.identifier) booking = booking_factories.IndividualBookingFactory( individualBooking__user=user) access_token = create_access_token(identity=self.identifier) test_client = TestClient(app.test_client()) test_client.auth_header = {"Authorization": f"Bearer {access_token}"} response = test_client.post("/native/v1/bookings", json={ "stockId": booking.stock.id, "quantity": 1 }) assert response.status_code == 400 assert response.json["code"] == "ALREADY_BOOKED"
def when_account_is_not_active(self, app): # Given user = users_factories.BeneficiaryGrant18Factory(isActive=True) data = { "new_email": user.email, "password": users_factories.DEFAULT_PASSWORD } client = TestClient(app.test_client()).with_session_auth(user.email) user.isActive = False db.session.commit() # When response = client.put("/beneficiaries/change_email_request", json=data) # Then assert response.status_code == 401 assert response.json["password"] == ["Mot de passe incorrect"]
def when_called_calls_send_email( self, mocked_retrieve_data_for_beneficiary_booking_confirmation_email): # Given user = users_factories.BeneficiaryGrant18Factory() booking = booking_factories.IndividualBookingFactory( individualBooking__user=user) # When send_individual_booking_confirmation_email_to_beneficiary( booking.individualBooking) # Then mocked_retrieve_data_for_beneficiary_booking_confirmation_email.assert_called_once_with( booking.individualBooking) assert len(mails_testing.outbox) == 1 # test number of emails sent assert mails_testing.outbox[0].sent_data["MJ-TemplateID"] == 2942751
def test_should_log_error_when_trying_to_delete_product_with_associated_bookings( self, get_lines_from_thing_file, get_files_to_process_from_titelive_ftp, app ): # Given files_list = list() files_list.append("Quotidien30.tit") get_files_to_process_from_titelive_ftp.return_value = files_list DATA_LINE_PARTS = BASE_DATA_LINE_PARTS[:] DATA_LINE_PARTS[2] = "jeux de société" DATA_LINE_PARTS[4] = "1234" DATA_LINE_PARTS[13] = "O" DATA_LINE_PARTS[27] = "Littérature scolaire" DATA_LINE_PARTS[40] = "" data_line = "~".join(DATA_LINE_PARTS) get_lines_from_thing_file.return_value = iter([data_line]) beneficiary = users_factories.BeneficiaryGrant18Factory() offerer = create_offerer(siren="775671464") venue = create_venue(offerer, name="Librairie Titelive", siret="77567146400110") titelive_provider = activate_provider("TiteLiveThings") repository.save(venue) product = create_product_with_thing_subcategory( id_at_providers="9782895026310", thing_name="Toto à la playa", date_modified_at_last_provider=datetime(2001, 1, 1), last_provider_id=titelive_provider.id, ) offer = create_offer_with_thing_product(venue, product=product) stock = create_stock(offer=offer, price=0) booking = create_booking(user=beneficiary, stock=stock) repository.save(product, offer, stock, booking) titelive_things = TiteLiveThings() # When titelive_things.updateObjects() # Then assert Product.query.count() == 1 provider_log_error = LocalProviderEvent.query.filter_by(type=LocalProviderEventType.SyncError).one() assert provider_log_error.payload == "Error deleting product with ISBN: 9782895026310"
def test_returns_a_thing_stock(self, app): # Given beneficiary = users_factories.BeneficiaryGrant18Factory() stock = offers_factories.ThingStockFactory() offer = stock.offer offer.subcategoryId = subcategories.LIVRE_PAPIER.id repository.save(offer) # When client = TestClient( app.test_client()).with_session_auth(email=beneficiary.email) response = client.get(f"/offers/{humanize(offer.id)}") # Then assert response.status_code == 200 data = response.json assert data["stocks"][0]["cancellationLimitDate"] is None assert data["subcategoryId"] == "LIVRE_PAPIER"