def when_email_has_special_characters_but_is_not_url_encoded(self, app): # Given user = create_user(email="*****@*****.**") user_admin = create_user(email="*****@*****.**") offerer = create_offerer() user_offerer = create_user_offerer(user_admin, offerer, is_admin=True) venue = create_venue(offerer) offer = create_offer_with_event_product(venue, event_name="Event Name") event_occurrence = create_event_occurrence(offer) stock = create_stock_from_event_occurrence(event_occurrence, price=0) booking = create_booking(user=user, stock=stock, venue=venue) repository.save(user_offerer, booking) url = "/bookings/token/{}?email={}".format(booking.token, user.email) # When response = TestClient(app.test_client()).with_auth("*****@*****.**").patch(url) # Then assert response.status_code == 404
def when_expected_parameters_are_not_given(self, app): # Given user = users_factories.BeneficiaryGrant18Factory( email="*****@*****.**") offerer = create_offerer() venue = create_venue(offerer, postal_code="29100", siret="12345678912341") offer = create_offer_with_thing_product(venue, thumb_count=0) mediation = create_mediation(offer, is_active=True) favorite = create_favorite(mediation=mediation, offer=offer, user=user) repository.save(favorite) # When response = TestClient(app.test_client()).with_session_auth( user.email).delete("/favorites/1") # Then assert response.status_code == 404
def test_should_send_mail_to_offerer_and_pass_culture_administration_when_feature_send_mail_to_users_is_enabled( self, feature_send_mail_to_users_enabled ): # Given user = create_user() offerer = create_offerer() venue = create_venue(offerer) offer = create_offer_with_event_product(venue) event_occurrence = create_event_occurrence(offer) stock = create_stock_from_event_occurrence(event_occurrence) booking = create_booking(user=user, stock=stock) bookings = [booking] recipients = "[email protected], [email protected]" # When mailjet_data = retrieve_offerer_bookings_recap_email_data_after_offerer_cancellation(bookings, recipients) # Then assert mailjet_data["To"] == "[email protected], [email protected]"
def should_not_connect_venue_when_synchronization_is_not_allowed( self, app): # Given offerer = create_offerer() venue = create_venue(offerer, siret="12345678912345") provider = offerers_factories.APIProviderFactory(name="FNAC") repository.save(venue) self.find_by_id.return_value = venue stock_repository = MagicMock() stock_repository.can_be_synchronized.return_value = False # when with pytest.raises(VenueSiretNotRegistered): connect_venue_to_provider(venue, provider) # then assert not VenueProvider.query.first()
def when_user_has_rights_and_regular_offer(self, app): # Given user = users_factories.UserFactory(email="*****@*****.**", publicName="John Doe") admin_user = create_user(email="*****@*****.**") offerer = create_offerer() create_user_offerer(admin_user, offerer) venue = create_venue(offerer, name="Venue name", address="Venue address") offer = create_offer_with_event_product(venue=venue, event_name="Event Name", event_type=EventType.CINEMA) four_days_from_now = datetime.utcnow() + timedelta(days=4) event_occurrence = create_event_occurrence(offer, beginning_datetime=four_days_from_now) stock = create_stock_from_event_occurrence(event_occurrence, price=12) unconfirmed_booking = create_booking( user=user, quantity=3, stock=stock, venue=venue, date_created=datetime.utcnow() - timedelta(hours=48) ) repository.save(unconfirmed_booking) url = f"/v2/bookings/token/{unconfirmed_booking.token}" # When response = TestClient(app.test_client()).with_auth("*****@*****.**").get(url) # Then assert response.headers["Content-type"] == "application/json" assert response.status_code == 200 assert response.json == { "bookingId": humanize(unconfirmed_booking.id), "dateOfBirth": "", "datetime": format_into_utc_date(stock.beginningDatetime), "ean13": "", "email": "*****@*****.**", "formula": "PLACE", "isUsed": False, "offerId": offer.id, "offerName": "Event Name", "offerType": "EVENEMENT", "phoneNumber": "", "price": 12.0, "publicOfferId": humanize(offer.id), "quantity": 3, "userName": "******", "venueAddress": "Venue address", "venueDepartementCode": "93", "venueName": "Venue name", }
def test_should_not_get_offer_with_a_date_between_today_and_the_15_04_and_another_after_15_04( self, app): # Given offerer = create_offerer() venue = create_venue(offerer) offer = create_offer_with_event_product(venue) stock1 = create_stock(beginning_datetime=datetime(2020, 4, 16), offer=offer) stock2 = create_stock(beginning_datetime=datetime(2020, 4, 14), offer=offer) repository.save(stock1, stock2) # When offers = build_query_offers_with_max_stock_date_between_today_and_end_of_quarantine( FIRST_DAY_AFTER_QUARANTINE, TODAY).all() # Then assert offers == []
def when_booking_is_not_provided_at_all(self, app): # Given user = create_user(email="*****@*****.**") offerer = create_offerer() venue = create_venue(offerer) offer = create_offer_with_event_product(venue, event_name="Event Name") event_occurrence = create_event_occurrence(offer) stock = create_stock_from_event_occurrence(event_occurrence, price=0) booking = create_booking(user=user, stock=stock, venue=venue) repository.save(booking) url = "/v2/bookings/token/" # When response = TestClient(app.test_client()).get(url) # Then assert response.status_code == 404
def test_should_return_false_when_stock_booking_limit_is_past(self, app): # Given user = create_user() offerer = create_offerer() venue = create_venue(offerer) offer = create_offer_with_thing_product(venue, is_active=True) stock = create_stock_from_offer(offer, price=0, quantity=2, booking_limit_datetime=datetime.now() - timedelta(days=6)) booking = create_booking(user=user, stock=stock, quantity=2) repository.save(booking) # When is_active = _is_offer_active_for_recap(stock) # Then assert not is_active
def test_should_return_event_data_when_booking_is_on_an_event(self): # Given beginning_datetime = datetime(2019, 7, 20, 12, 0, 0, tzinfo=timezone.utc) user = create_user() offerer = create_offerer() venue = create_venue(offerer) offer = create_offer_with_event_product(venue) event_occurrence = create_event_occurrence( offer, beginning_datetime=beginning_datetime) stock = create_stock_from_event_occurrence(event_occurrence, price=20) booking = create_booking(user=user, stock=stock) # When mailjet_data = retrieve_data_to_warn_beneficiary_after_pro_booking_cancellation( booking) # Then assert mailjet_data == { "FromEmail": "*****@*****.**", "MJ-TemplateID": 1116690, "MJ-TemplateLanguage": True, "To": "*****@*****.**", "Vars": { "event_date": "samedi 20 juillet 2019", "event_hour": "14h", "is_event": 1, "is_free_offer": 0, "is_online": 0, "is_thing": 0, "offer_name": booking.stock.offer.name, "offer_price": "20", "offerer_name": booking.stock.offer.venue.managingOfferer.name, "user_first_name": user.firstName, "venue_name": booking.stock.offer.venue.name, }, }
def test_should_not_delete_stock_from_allocine_when_not_sof_deleted(app): # Given offerer = create_offerer() venue = create_venue(offerer) allocine_provider = get_provider_by_local_class("AllocineStocks") offer = create_offer_with_thing_product(venue) stock = create_stock( id_at_providers="TW92aWU6MjczNjU5%38986972800011-1", is_soft_deleted=False, last_provider_id=allocine_provider.id, offer=offer, ) repository.save(stock) # When delete_corrupted_allocine_stocks() # Then assert Stock.query.count() == 1
def test_should_return_mailjet_data_with_no_ongoing_booking( self, mock_is_offer_active, mock_build_pc_pro_offer_link): # Given user = create_user(email="*****@*****.**", public_name="Jean Dupont") offerer = create_offerer() venue = create_venue(offerer, name="Venue name", departement_code="75") offer = create_offer_with_event_product(venue, event_name="My Event") stock = create_stock_from_offer(offer, price=12.52, beginning_datetime=datetime( 2019, 10, 9, 10, 20, 00)) booking = create_booking(user=user, stock=stock, venue=venue, is_cancelled=True, quantity=2) # When mailjet_data = retrieve_offerer_booking_recap_email_data_after_user_cancellation( booking) # Then assert mailjet_data == { "MJ-TemplateID": 780015, "MJ-TemplateLanguage": True, "Vars": { "departement": "75", "nom_offre": "My Event", "lien_offre_pcpro": "http://pc_pro.com/offer_link", "nom_lieu": "Venue name", "prix": "12.52", "is_event": 1, "date": "09-Oct-2019", "heure": "12h20", "quantite": 2, "user_name": "Jean Dupont", "user_email": "*****@*****.**", "is_active": 1, "nombre_resa": 0, "users": [], }, }
def test_should_not_delete_stock_from_other_provider_than_allocine(app): # Given offerer = create_offerer() venue = create_venue(offerer) provider = ProviderFactory(localClass="not allociné") offer = create_offer_with_thing_product(venue) stock = create_stock( id_at_providers="TW92aWU6MjczNjU5%38986972800011-1", is_soft_deleted=True, last_provider_id=provider.id, offer=offer, ) repository.save(stock) # When delete_corrupted_allocine_stocks() # Then assert Stock.query.count() == 1
def test_should_not_delete_stock_from_allocine_with_new_id_format(app): # Given offerer = create_offerer() venue = create_venue(offerer) allocine_provider = get_provider_by_local_class("AllocineStocks") offer = create_offer_with_thing_product(venue) stock = create_stock( id_at_providers="TW92aWU6MjczNTc5%31940406700021#LOCAL/2020-01-18T14:00:00", is_soft_deleted=True, last_provider_id=allocine_provider.id, offer=offer, ) repository.save(stock) # When delete_corrupted_allocine_stocks() # Then assert Stock.query.count() == 1
def test_should_call_run_process_in_one_off_container_function( self, mock_run_process_in_one_off_container, app): # Given mock_run_process_in_one_off_container.return_value = "azertyTE7898RTYUIZERTYUI" titelive_provider = activate_provider("TiteLiveStocks") offerer = create_offerer() venue1 = create_venue(offerer) venue_provider = create_venue_provider(venue1, titelive_provider) repository.save(venue_provider) update_venue_provider_command = ( f"python src/pcapi/scripts/pc.py update_providables" f" --venue-provider-id {venue_provider.id}") # When do_sync_venue_provider(venue_provider) # Then mock_run_process_in_one_off_container.assert_called_once_with( update_venue_provider_command)
def test_should_update_venue_type_whith_type_from_read_file_when_id_match( self, stub_read_venue_type_from_file, app, capsys): # Given offerer = create_offerer() old_venue_type = create_venue_type("old_type", 1) new_venue_type = create_venue_type("new_type", 2) venue = create_venue(offerer, idx=121, venue_type_id=1) repository.save(venue, old_venue_type, new_venue_type) stub_read_venue_type_from_file.return_value = [("121", "new_type")] # When update_venue_type("fake/path") # Then captured = capsys.readouterr() updated_venue = Venue.query.one() assert updated_venue.venueTypeId == 2 assert "1 venues have been updated" in captured.out
def test_allocine_venue_provider_should_inherit_from_venue_provider( self, app): offerer = create_offerer() venue = create_venue(offerer) provider_allocine = activate_provider("AllocineStocks") allocine_venue_provider = create_allocine_venue_provider( venue, provider_allocine, is_duo=True) repository.save(allocine_venue_provider) assert VenueProvider.query.count() == 1 assert AllocineVenueProvider.query.count() == 1 allocine_vp = VenueProvider.query.filter( VenueProvider.providerId == provider_allocine.id).first() assert isinstance(allocine_vp, AllocineVenueProvider) assert allocine_vp.isDuo assert allocine_vp.isFromAllocineProvider
def test_should_not_update_venue_type_whith_type_from_read_file_when_type_label_does_not_match( self, stub_read_venue_type_from_file, app, capsys): # Given offerer = create_offerer() old_venue_type = create_venue_type("old_type", 1) venue = create_venue(offerer, idx=121, venue_type_id=1) repository.save(venue, old_venue_type) stub_read_venue_type_from_file.return_value = [("121", "other_type")] # When update_venue_type("fake/path") # Then captured = capsys.readouterr() updated_venue = Venue.query.one() assert updated_venue.venueTypeId == 1 assert "venue type id not found for label : other_type and venueId : 121" in captured.out assert "0 venues have been updated" in captured.out
def test_should_raise_error_when_price_is_negative(self, app): # Given offerer = create_offerer() venue = create_venue(offerer) allocine_provider = get_provider_by_local_class("AllocineStocks") allocine_provider.isActive = True allocine_venue_provider = create_allocine_venue_provider( venue, allocine_provider) venue_provider_price_rule = create_allocine_venue_provider_price_rule( allocine_venue_provider, price_rule=PriceRule.default, price=-4) # When with pytest.raises(ApiErrors) as error: repository.save(venue_provider_price_rule) # Then assert error.value.errors["global"] == [ "Vous ne pouvez renseigner un prix négatif" ]
def test_should_not_delete_objects_when_objects_are_not_eligible_and_were_not_indexed( self, mock_build_object, mock_add_objects, mock_delete_objects, mock_add_to_indexed_offers, mock_check_offer_exists, mock_delete_indexed_offers, app, ): # Given client = MagicMock() client.pipeline = MagicMock() client.pipeline.return_value = MagicMock() mock_pipeline = client.pipeline() mock_pipeline.execute = MagicMock() mock_pipeline.reset = MagicMock() offerer = create_offerer(is_active=True, validation_token=None) venue = create_venue(offerer=offerer, validation_token=None) offer1 = create_offer_with_thing_product(venue=venue, is_active=True) stock1 = create_stock(booking_limit_datetime=TOMORROW, offer=offer1, quantity=0) offer2 = create_offer_with_thing_product(venue=venue, is_active=True) stock2 = create_stock(booking_limit_datetime=TOMORROW, offer=offer2, quantity=0) repository.save(stock1, stock2) mock_check_offer_exists.side_effect = [False, False] # When process_eligible_offers(client=client, offer_ids=[offer1.id, offer2.id], from_provider_update=False) # Then mock_build_object.assert_not_called() mock_add_objects.assert_not_called() mock_add_to_indexed_offers.assert_not_called() mock_delete_objects.assert_not_called() mock_delete_indexed_offers.assert_not_called() mock_pipeline.execute.assert_not_called() mock_pipeline.reset.assert_not_called()
def test_should_raise_error_when_saving_wrong_format_price(self, app): # Given offerer = create_offerer() venue = create_venue(offerer) allocine_provider = get_provider_by_local_class("AllocineStocks") allocine_venue_provider = create_allocine_venue_provider( venue, allocine_provider) price = "wrong_price_format" venue_provider_price_rule = create_allocine_venue_provider_price_rule( allocine_venue_provider, price_rule=PriceRule.default, price=price) # When with pytest.raises(ApiErrors) as error: repository.save(venue_provider_price_rule) # Then assert error.value.errors == { "global": ["Le prix doit être un nombre décimal"] }
def should_connect_venue_when_synchronization_is_allowed(self, app): # Given offerer = create_offerer() venue = create_venue(offerer) provider = offerers_factories.APIProviderFactory() repository.save(venue) self.find_by_id.return_value = venue stock_repository = MagicMock() stock_repository.can_be_synchronized.return_value = True # When connect_venue_to_provider(venue, provider) # Then fnac_venue_provider = VenueProvider.query.one() assert fnac_venue_provider.venue == venue
def when_user_is_not_attached_to_linked_offerer(self, app): # Given user = create_user() pro_user = create_user(email="*****@*****.**") offerer = create_offerer() venue = create_venue(offerer) stock = create_stock_with_event_offer(offerer, venue, price=0) booking = create_booking(user=user, stock=stock, venue=venue) repository.save(booking, pro_user) # When url = "/v2/bookings/keep/token/{}?email={}".format(booking.token, user.email) response = TestClient(app.test_client()).with_auth("*****@*****.**").patch(url) # Then assert response.status_code == 403 assert response.json["user"] == ["Vous n'avez pas les droits suffisants pour valider cette contremarque."] assert Booking.query.get(booking.id).isUsed is False
def when_user_doesnt_have_rights_and_token_exists(self, app): # Given user = create_user(email="*****@*****.**") querying_user = create_user(email="*****@*****.**") offerer = create_offerer() venue = create_venue(offerer) offer = create_offer_with_event_product(venue, event_name="Event Name") event_occurrence = create_event_occurrence(offer) stock = create_stock_from_event_occurrence(event_occurrence, price=0) booking = create_booking(user=user, stock=stock, venue=venue) repository.save(querying_user, booking) url = f"/v2/bookings/token/{booking.token}" # When response = TestClient(app.test_client()).with_auth("*****@*****.**").get(url) # Then assert response.status_code == 403 assert response.json["user"] == ["Vous n'avez pas les droits suffisants pour valider cette contremarque."]
def when_user_is_logged_in_and_booking_does_not_exist(self, app): # Given user = create_user() pro_user = create_user(email="*****@*****.**") offerer = create_offerer() user_offerer = create_user_offerer(pro_user, offerer) venue = create_venue(offerer) stock = create_stock_with_event_offer(offerer, venue, price=0) booking = create_booking(user=user, stock=stock, venue=venue) repository.save(booking, user_offerer) # When url = "/v2/bookings/keep/token/{}".format("123456") response = TestClient(app.test_client()).with_auth("*****@*****.**").patch(url) # Then assert response.status_code == 404 assert response.json["global"] == ["Cette contremarque n'a pas été trouvée"]
def test_when_state_is_unknown(self, mock_application_details, app): # Given application_id = "8" offerer = create_offerer(siren="793875030") venue = create_venue(offerer, siret="79387503012345") repository.save(venue) unknown_status = "unknown_status" mock_application_details.return_value = venue_demarche_simplifiee_application_detail_response_with_siret( siret="79387503012345", bic="SOGEFRPP", iban="FR7630007000111234567890144", idx=8, state=unknown_status ) # When with pytest.raises(CannotRegisterBankInformation) as error: self.save_venue_bank_informations.execute(application_id) # Then bank_information_count = BankInformation.query.count() assert bank_information_count == 0 assert error.value.args == (f"Unknown Demarches Simplifiées state {unknown_status}",)
def when_user_is_logged_in_and_booking_token_is_null(self, app): # Given user = create_user() pro_user = create_user(email="*****@*****.**") offerer = create_offerer() user_offerer = create_user_offerer(pro_user, offerer) venue = create_venue(offerer) stock = create_stock_with_event_offer(offerer, venue, price=0) booking = create_booking(user=user, stock=stock, venue=venue) repository.save(booking, user_offerer) # When url = "/v2/bookings/keep/token/" response = TestClient(app.test_client()).with_auth("*****@*****.**").patch(url) # Then assert response.status_code == 404
def test_should_return_mailjet_data_when_multiple_bookings_and_offer_is_a_thing( self, format_environment_for_email, build_pc_pro_offer_link, feature_send_mail_to_users_enabled ): # Given user = create_user(public_name="John Doe", first_name="John", last_name="Doe", email="*****@*****.**") offerer = create_offerer() venue = create_venue(offerer, name="La petite librairie", public_name="La grande librairie") thing_product = create_product_with_thing_type(thing_name="Le récit de voyage") offer = create_offer_with_thing_product(venue=venue, product=thing_product) stock = create_stock_from_offer(offer, price=0) booking = create_booking(user=user, stock=stock, token="12346", quantity=6) user2 = create_user(public_name="James Bond", first_name="James", last_name="Bond", email="*****@*****.**") booking2 = create_booking(user=user2, stock=stock, token="12345") recipients = "[email protected], [email protected]" bookings = [booking, booking2] # When mailjet_data = retrieve_offerer_bookings_recap_email_data_after_offerer_cancellation(bookings, recipients) # Then assert mailjet_data == { "FromEmail": "*****@*****.**", "MJ-TemplateID": 1116333, "MJ-TemplateLanguage": True, "To": "*****@*****.**", "Vars": { "offer_name": "Le récit de voyage", "lien_offre_pcpro": "http://pc_pro.com/offer_link", "venue_name": "La grande librairie", "price": "Gratuit", "is_event": 0, "event_date": "", "event_hour": "", "quantity": 7, "reservations_number": 2, "env": "-testing", "users": [ {"countermark": "12346", "email": "*****@*****.**", "firstName": "John", "lastName": "Doe"}, {"countermark": "12345", "email": "*****@*****.**", "firstName": "James", "lastName": "Bond"}, ], }, }
def test_should_return_the_first_stock_price(self, app): # Given offerer = create_offerer() venue = create_venue(offerer=offerer) offer = create_offer_with_thing_product(venue=venue) stock1 = create_stock(offer=offer, price=7) stock2 = create_stock(offer=offer, price=5) stock3 = create_stock(offer=offer, price=10.3) repository.save(stock1, stock2, stock3) # When result = AlgoliaBackend.serialize_offer(offer) # Then assert result["offer"]["prices"] == [ Decimal("5.00"), Decimal("7.00"), Decimal("10.30") ]
def test_deactivate_offer_should_keep_booking_state(self, app): # given user = users_factories.UserFactory() offerer = create_offerer() venue = create_venue(offerer) existing_offer = create_offer_with_event_product(venue, is_active=True) stock = create_stock(offer=existing_offer) booking = create_booking(user=user, stock=stock) offers = [existing_offer] status = False # when updated_offers = update_is_active_status(offers, status) # then assert any(not updated_offer.isActive for updated_offer in updated_offers) assert not booking.isCancelled assert booking.status is not BookingStatus.CANCELLED
def when_both_email_and_offer_id_are_missing(self, app): # Given user = create_user() offerer = create_offerer() venue = create_venue(offerer) stock = create_stock_with_event_offer(offerer, venue, price=0) booking = create_booking(user=user, stock=stock, venue=venue) repository.save(booking) url = "/bookings/token/{}".format(booking.token) # When response = TestClient(app.test_client()).patch(url) # Then assert response.status_code == 400 assert response.json["offer_id"] == ["L'id de l'offre réservée est obligatoire dans l'URL [?offer_id=<id>]"] assert response.json["email"] == [ "L'adresse email qui a servie à la réservation est obligatoire dans l'URL [?email=<email>]" ]