def test_apply_with_rate(self): rule = factories.CustomReimbursementRuleFactory(rate=0.8) single = bookings_factories.BookingFactory(quantity=1) double = bookings_factories.BookingFactory(quantity=2) assert rule.apply(single) == 8 assert rule.apply(double) == 16
def test_apply_with_amount(self): rule = factories.CustomReimbursementRuleFactory(amount=10) single = bookings_factories.BookingFactory(quantity=1) double = bookings_factories.BookingFactory(quantity=2) assert rule.apply(single) == 10 assert rule.apply(double) == 20
def test_cannot_change_existing_end_date(self): today = datetime.today() timespan = (today - timedelta(days=10), today) rule = payments_factories.CustomReimbursementRuleFactory( timespan=timespan) with pytest.raises(exceptions.WrongDateForReimbursementRule): api.edit_reimbursement_rule(rule, end_date=today + timedelta(days=5))
def test_is_relevant(self): offer1 = offers_factories.OfferFactory() booking1 = bookings_factories.BookingFactory(stock__offer=offer1) rule = factories.CustomReimbursementRuleFactory(offer=offer1) assert rule.is_relevant(booking1) booking2 = bookings_factories.BookingFactory() assert not rule.is_relevant(booking2)
def test_update_from_csv_file_detects_existing_rules_and_mismatches(): rule1 = payments_factories.CustomReimbursementRuleFactory(amount=8) rule2 = payments_factories.CustomReimbursementRuleFactory(amount=8) # fmt: off csv = "\n".join(( "this,is,a,header", f"""name of offerer,{humanize(rule1.offerId)},"12,34€",8€""", f"""name of offerer,{humanize(rule2.offerId)},"12,34€",7€""", )) # fmt: on results = update_from_csv_file(io.StringIO(csv)) assert not results["created"] assert results["errors"] == [ f"line 3: Existing rule on offer {humanize(rule2.offerId)} ({rule2.offerId}) reimburses 8.00, file says 7" ]
def test_validation(self): # Validation is thoroughly verified in `test_validation.py`. # This is just an integration test. timespan = (datetime.today() - timedelta(days=10), None) rule = payments_factories.CustomReimbursementRuleFactory( timespan=timespan) end = pytz.utc.localize(datetime.today()) with pytest.raises(exceptions.WrongDateForReimbursementRule): api.edit_reimbursement_rule(rule, end_date=end)
def test_edit_rule(self): timespan = (pytz.utc.localize(datetime(2021, 1, 1)), None) rule = payments_factories.CustomReimbursementRuleFactory( timespan=timespan) end = pytz.utc.localize(datetime(2030, 10, 3, 0, 0)) api.edit_reimbursement_rule(rule, end_date=end) db.session.refresh(rule) assert rule.timespan.lower == datetime(2021, 1, 1, 0, 0) # unchanged assert rule.timespan.upper == datetime(2030, 10, 3, 0, 0)
def test_check_stock_has_no_custom_reimbursement_rule(): stock = offers_factories.StockFactory() validation.check_stock_has_no_custom_reimbursement_rule( stock) # should not raise payments_factories.CustomReimbursementRuleFactory(offer=stock.offer) with pytest.raises(ApiErrors) as error: validation.check_stock_has_no_custom_reimbursement_rule(stock) assert error.value.errors["price"] == [ "Vous ne pouvez pas modifier le prix de cette offre" ]
def test_with_custom_reimbursement_rule(self): booking = bookings_factories.IndividualBookingFactory() rule = payments_factories.CustomReimbursementRuleFactory( offer=booking.stock.offer, amount=2) reimbursement = BookingReimbursement(booking, rule, Decimal(2)) batch_date = datetime.utcnow() payment = create_payment_for_booking(reimbursement, batch_date) assert payment.amount == 2 assert payment.customReimbursementRuleId == rule.id assert payment.reimbursementRate is None assert payment.reimbursementRule is None
def test_select_custom_reimbursement_rule_if_applicable(self): offer1 = offers_factories.DigitalOfferFactory() booking1 = bookings_factories.UsedBookingFactory(stock__offer=offer1) offer2 = offers_factories.DigitalOfferFactory() booking2 = bookings_factories.UsedBookingFactory(stock__offer=offer2) rule1 = payments_factories.CustomReimbursementRuleFactory(offer=offer1, amount=5) payments_factories.CustomReimbursementRuleFactory( offer=offer2, timespan=[booking2.dateCreated + timedelta(days=2), None]) educational = bookings_factories.UsedEducationalBookingFactory() bookings = [booking1, booking2, educational] reimbursements = reimbursement.find_all_booking_reimbursements( bookings, reimbursement.CustomRuleFinder()) assert reimbursements[0].booking == booking1 assert reimbursements[0].rule == rule1 assert reimbursements[0].reimbursed_amount == 5 assert_no_reimbursement_for_digital(reimbursements[1], booking2) assert_total_reimbursement( reimbursements[2], reimbursement.EducationalOffersReimbursement, educational)
def test_is_active(self): start = datetime.datetime(2021, 1, 12, 0, 0) rule = factories.CustomReimbursementRuleFactory(timespan=(start, None)) # Test without upper bound assert rule.is_active(DummyBooking(start)) assert rule.is_active( DummyBooking(start + datetime.timedelta(seconds=2))) assert not rule.is_active( DummyBooking(start - datetime.timedelta(seconds=2))) # Test with upper bound end = datetime.datetime(2021, 5, 12, 0, 0) rule = factories.CustomReimbursementRuleFactory(timespan=(start, end)) assert rule.is_active( DummyBooking(start + datetime.timedelta(seconds=2))) assert not rule.is_active( DummyBooking(start - datetime.timedelta(seconds=2))) assert rule.is_active(DummyBooking(end - datetime.timedelta(seconds=2))) assert not rule.is_active(DummyBooking(end)) assert not rule.is_active( DummyBooking(end + datetime.timedelta(seconds=2)))
def test_edit_rule(mocked_validate_csrf_token, client, app): admin = users_factories.AdminFactory() timespan = (datetime.datetime.today() - datetime.timedelta(days=10), None) rule = payments_factories.CustomReimbursementRuleFactory(timespan=timespan) client = client.with_session_auth(admin.email) data = {"end_date": "2030-10-01"} response = client.post( f"/pc/back-office/customreimbursementrule/edit/?id={rule.id}", form=data) assert response.status_code == 302 rule = payments_models.CustomReimbursementRule.query.one() assert rule.timespan.lower == timespan[0] # unchanged assert rule.timespan.upper == datetime.datetime(2030, 9, 30, 22, 0) # UTC
def test_offerer_without_category_rule(self): yesterday = datetime.now() - timedelta(days=1) far_in_the_past = datetime.now() - timedelta(days=800) booking1 = bookings_factories.UsedBookingFactory() offerer = booking1.offerer booking2 = bookings_factories.UsedBookingFactory( offerer=offerer, dateUsed=far_in_the_past) booking3 = bookings_factories.UsedBookingFactory() rule = payments_factories.CustomReimbursementRuleFactory( offerer=offerer, timespan=(yesterday, None)) finder = reimbursement.CustomRuleFinder() assert finder.get_rule(booking1) == rule assert finder.get_rule(booking2) is None # outside `rule.timespan` assert finder.get_rule(booking3) is None # no rule for this offerer
def test_use_custom_reimbursement_rule_with_rate(self): booking = bookings_factories.UsedBookingFactory(amount=10, quantity=2) offerer = booking.offerer rule = payments_factories.CustomReimbursementRuleFactory( offerer=booking.offerer, rate=0.8) offers_factories.BankInformationFactory(offerer=offerer, iban="iban1", bic="bic1") cutoff = batch_date = datetime.datetime.now() generate_new_payments(cutoff, batch_date) payment = Payment.query.one() assert payment.amount == 16 # 2 (quantity) * 0.8 (rate) * 10 (amount) assert payment.customReimbursementRule == rule assert payment.reimbursementRate == Decimal("0.8")
def test_use_custom_reimbursement_rule_with_amount(self): offer = offers_factories.DigitalOfferFactory() offers_factories.BankInformationFactory(venue=offer.venue, iban="iban1", bic="bic1") bookings_factories.UsedBookingFactory(amount=10, quantity=2, stock__offer=offer) rule = payments_factories.CustomReimbursementRuleFactory(offer=offer, amount=7) cutoff = batch_date = datetime.datetime.now() generate_new_payments(cutoff, batch_date) payment = Payment.query.one() assert payment.amount == 14 # 2 (booking.quantity) * 7 (Rule.amount) assert payment.customReimbursementRule == rule assert payment.reimbursementRate is None
def test_offerer_with_category_rule(self): yesterday = datetime.now() - timedelta(days=1) far_in_the_past = datetime.now() - timedelta(days=800) booking1 = bookings_factories.UsedBookingFactory( stock__offer__subcategoryId=subcategories.FESTIVAL_CINE.id) offerer = booking1.offerer booking2 = bookings_factories.UsedBookingFactory( stock__offer__subcategoryId=subcategories.LIVRE_PAPIER.id, stock__offer__venue__managingOfferer=offerer) booking3 = bookings_factories.UsedBookingFactory( offerer=offerer, stock__offer__subcategoryId=subcategories.FESTIVAL_CINE.id, dateUsed=far_in_the_past) booking4 = bookings_factories.UsedBookingFactory() rule = payments_factories.CustomReimbursementRuleFactory( offerer=offerer, subcategories=[subcategories.FESTIVAL_CINE.id], timespan=(yesterday, None)) finder = reimbursement.CustomRuleFinder() assert finder.get_rule(booking1) == rule assert finder.get_rule(booking2) is None # wrong category assert finder.get_rule(booking3) is None # outside `rule.timespan` assert finder.get_rule(booking4) is None # no rule for this offerer