Пример #1
0
    class AddContactToEligibleSoonListTest:
        def setup_method(self):
            self.notification_service = MailjetNotificationService()

        @patch("pcapi.settings.MAILJET_NOT_YET_ELIGIBLE_LIST_ID", MOCK_MAILJET_LIST_ID)
        @patch("pcapi.infrastructure.services.notification.mailjet_notification_service.add_contact_to_list")
        def test_call_add_contact_to_list(self, add_contact_to_list_mock):
            # Given
            beneficiary_contact = BeneficiaryContact("*****@*****.**", "2003-03-05", "98")
            mock_response = Mock()
            mock_response.status_code = 201
            add_contact_to_list_mock.return_value = mock_response

            # When
            self.notification_service.add_contact_to_eligible_soon_list(beneficiary_contact)

            # Then
            add_contact_to_list_mock.assert_called_once_with(beneficiary_contact.email, MOCK_MAILJET_LIST_ID)

        @patch("pcapi.settings.MAILJET_NOT_YET_ELIGIBLE_LIST_ID", MOCK_MAILJET_LIST_ID)
        @patch("pcapi.infrastructure.services.notification.mailjet_notification_service.add_contact_to_list")
        def test_raises_error_on_list_addition_when_status_code_not_201_or_400(self, add_contact_to_list_mock):
            # Given
            beneficiary_contact = BeneficiaryContact("*****@*****.**", "2003-03-05", "98")
            mock_response = Mock()
            mock_response.status_code = 500
            mock_response.reason = "Error adding to list"

            add_contact_to_list_mock.return_value = mock_response
            # When
            with pytest.raises(AddNewBeneficiaryContactException) as error:
                self.notification_service.add_contact_to_eligible_soon_list(beneficiary_contact)

            # Then
            assert error.value.errors["mailjet"] == ["Error adding to list"]
Пример #2
0
def cancel_booking_by_beneficiary(user: User, booking: Booking) -> None:
    if not user.isBeneficiary:
        raise RuntimeError(
            "Unexpected call to cancel_booking_by_beneficiary with non-beneficiary user %s"
            % user)
    validation.check_beneficiary_can_cancel_booking(user, booking)

    booking.isCancelled = True
    booking.cancellationReason = BookingCancellationReasons.BENEFICIARY
    repository.save(booking)

    notifier = MailjetNotificationService()
    notifier.send_booking_cancellation_emails_to_user_and_offerer(
        booking=booking,
        reason=booking.cancellationReason,
        # FIXME: we should not have to pass this argument.
        # Notification-related code should be reorganized.
        send_email=send_raw_email,
    )

    # FIXME: why do we do that when the booking is cancelled by the
    # *beneficiary*, but not when it's cancelled by the *offerer* (see
    # cancel_booking_by_offerer)?
    if feature_queries.is_active(FeatureToggle.SYNCHRONIZE_ALGOLIA):
        redis.add_offer_id(client=app.redis_client,
                           offer_id=booking.stock.offerId)
Пример #3
0
 def setup_method(self):
     self.notification_service = MailjetNotificationService()
     self.notification_service.create_mailing_contact = MagicMock()
     self.notification_service.add_contact_to_eligible_soon_list = MagicMock(
     )
     self.add_contact_in_eligibility_list = AddContactInEligibilityList(
         notification_service=self.notification_service)
Пример #4
0
    class CreateMailingContactTest:
        def setup_method(self):
            self.notification_service = MailjetNotificationService()

        @patch("pcapi.infrastructure.services.notification.mailjet_notification_service.create_contact")
        @patch("pcapi.infrastructure.services.notification.mailjet_notification_service.add_contact_informations")
        def test_call_create_contact_from_mailing_and_add_informations(
            self, add_contact_info_mock, create_contact_mock, app
        ):
            # Given
            beneficiary_contact = BeneficiaryContact("*****@*****.**", "2003-03-05", "98")
            birth_date_timestamp = 1046822400
            mock_response_create = Mock()
            mock_response_informations = Mock()
            mock_response_create.status_code = 201
            mock_response_informations.status_code = 200

            create_contact_mock.return_value = mock_response_create
            add_contact_info_mock.return_value = mock_response_informations

            # When
            self.notification_service.create_mailing_contact(beneficiary_contact)

            # Then
            create_contact_mock.assert_called_once_with(beneficiary_contact.email)
            add_contact_info_mock.assert_called_once_with(
                beneficiary_contact.email, birth_date_timestamp, beneficiary_contact.department_code
            )

        @patch("pcapi.infrastructure.services.notification.mailjet_notification_service.create_contact")
        def test_raises_error_on_creation_when_status_code_not_201_or_400(self, create_contact_mock):
            # Given
            beneficiary_contact = BeneficiaryContact("*****@*****.**", "2003-03-05", "98")
            mock_response = Mock()
            mock_response.status_code = 500
            mock_response.reason = "Error creating contact"

            create_contact_mock.return_value = mock_response

            # When
            with pytest.raises(AddNewBeneficiaryContactException) as error:
                self.notification_service.create_mailing_contact(beneficiary_contact)

            # Then
            assert error.value.errors["mailjet"] == ["Error creating contact"]
Пример #5
0
def book_offer(
    beneficiary: User,
    stock: Stock,
    quantity: int,
) -> Booking:
    """Return a booking or raise an exception if it's not possible."""
    validation.check_can_book_free_offer(beneficiary, stock)
    validation.check_offer_already_booked(beneficiary, stock.offer)
    validation.check_quantity(stock.offer, quantity)
    validation.check_stock_is_bookable(stock)
    total_amount = quantity * stock.price
    validation.check_expenses_limits(beneficiary, total_amount, stock.offer)

    # FIXME (dbaty, 2020-10-20): if we directly set relations (for
    # example with `booking.user = beneficiary`) instead of foreign keys,
    # the session tries to add the object when `get_user_expenses()`
    # is called because autoflush is enabled. As such, the PostgreSQL
    # exceptions (tooManyBookings and insufficientFunds) may raise at
    # this point and will bubble up. If we want them to be caught, we
    # have to set foreign keys, so that the session is NOT autoflushed
    # in `get_user_expenses` and is only committed in `repository.save()`
    # where exceptions are caught. Since we are using flask-sqlalchemy,
    # I don't think that we should use autoflush, nor should we use
    # the `pcapi.repository.repository` module.
    booking = Booking(
        userId=beneficiary.id,
        stockId=stock.id,
        amount=stock.price,
        quantity=quantity,
        token=generate_booking_token(),
    )

    booking.dateCreated = datetime.datetime.utcnow()
    booking.confirmationDate = compute_confirmation_date(
        stock.beginningDatetime, booking.dateCreated)

    repository.save(booking)

    notifier = MailjetNotificationService()
    notifier.send_booking_recap(booking)
    notifier.send_booking_confirmation_to_beneficiary(booking)

    if feature_queries.is_active(FeatureToggle.SYNCHRONIZE_ALGOLIA):
        redis.add_offer_id(client=app.redis_client, offer_id=stock.offerId)

    return booking
Пример #6
0
 def setup_method(self):
     self.notification_service = MailjetNotificationService()
Пример #7
0
from pcapi.infrastructure.repository.venue.venue_label.venue_label_sql_repository import VenueLabelSQLRepository
from pcapi.infrastructure.repository.venue.venue_with_basic_information.venue_with_basic_information_sql_repository import (
    VenueWithBasicInformationSQLRepository, )
from pcapi.infrastructure.repository.venue.venue_with_offerer_name.venue_with_offerer_name_sql_repository import (
    VenueWithOffererNameSQLRepository, )
from pcapi.infrastructure.services.notification.mailjet_notification_service import MailjetNotificationService
from pcapi.use_cases.add_contact_in_eligiblity_list import AddContactInEligibilityList
from pcapi.use_cases.get_bookings_for_beneficiary import GetBookingsForBeneficiary
from pcapi.use_cases.get_venue_labels import GetVenueLabels
from pcapi.use_cases.get_venues_by_pro_user import GetVenuesByProUser
from pcapi.use_cases.list_favorites_of_beneficiary import ListFavoritesOfBeneficiary
from pcapi.use_cases.list_offerers_for_pro_user import ListOfferersForProUser

beneficiary_bookings_repository = BeneficiaryBookingsSQLRepository()
favorite_repository = FavoriteSQLRepository()
notification_service = MailjetNotificationService()
venue_label_repository = VenueLabelSQLRepository()
venue_identifier_repository = VenueWithBasicInformationSQLRepository()
venue_with_offerer_informations_repository = VenueWithOffererNameSQLRepository(
)
paginated_offerers_repository = PaginatedOfferersSQLRepository()

api_libraires_stocks = StockProviderLibrairesRepository()
api_fnac_stocks = StockProviderFnacRepository()
api_titelive_stocks = StockProviderTiteLiveRepository()
api_praxiel_stocks = StockProviderPraxielRepository()

# Usecases
get_venue_labels = GetVenueLabels(
    venue_label_repository=venue_label_repository)