Exemple #1
0
def test_cancel_bookings_when_offerer_has_one_or_more():
    # Given
    fraudulent_emails_providers = ["example.com"]
    admin_user = AdminFactory(email="*****@*****.**")
    beneficiary1 = BeneficiaryGrant18Factory(email="*****@*****.**")
    beneficiary2 = BeneficiaryGrant18Factory(email="*****@*****.**")
    fraudulent_user = ProFactory(email="*****@*****.**", )
    offerer_with_bookings = OffererFactory()
    UserOffererFactory(user=fraudulent_user, offerer=offerer_with_bookings)
    offer1 = OfferFactory(venue__managingOfferer=offerer_with_bookings)
    offer2 = OfferFactory(venue__managingOfferer=offerer_with_bookings)
    stock1 = StockFactory(offer=offer1)
    stock2 = StockFactory(offer=offer2)
    booking1 = BookingFactory(user=beneficiary1, stock=stock1)
    booking2 = BookingFactory(user=beneficiary2, stock=stock2)

    # When
    suspend_fraudulent_pro_by_email_providers(fraudulent_emails_providers,
                                              admin_user,
                                              dry_run=False)

    # Then
    assert Offerer.query.count() == 1
    assert Venue.query.count() == 2
    assert Offer.query.count() == 2
    assert Stock.query.count() == 2
    assert Booking.query.count() == 2
    assert booking1.isCancelled
    assert booking1.status is BookingStatus.CANCELLED
    assert booking1.cancellationReason is BookingCancellationReasons.FRAUD
    assert booking2.isCancelled
    assert booking2.status is BookingStatus.CANCELLED
    assert booking2.cancellationReason is BookingCancellationReasons.FRAUD
    def test_update_venue_other_offer_id_at_provider(
            self, mocked_validate_csrf_token, app):
        AdminFactory(email="*****@*****.**")
        venue = VenueFactory(siret="22222222222222")
        id_at_providers = "id_at_provider_ne_contenant_pas_le_siret"
        stock = StockFactory(offer__venue=venue,
                             idAtProviders=id_at_providers,
                             offer__idAtProviders=id_at_providers)

        data = dict(
            name=venue.name,
            siret="88888888888888",
            city=venue.city,
            postalCode=venue.postalCode,
            address=venue.address,
            publicName=venue.publicName,
            latitude=venue.latitude,
            longitude=venue.longitude,
            isPermanent=venue.isPermanent,
        )

        client = TestClient(
            app.test_client()).with_session_auth("*****@*****.**")
        response = client.post(f"/pc/back-office/venue/edit/?id={venue.id}",
                               form=data)

        assert response.status_code == 302

        venue_edited = Venue.query.get(venue.id)
        stock = Stock.query.get(stock.id)
        offer = Offer.query.get(stock.offer.id)

        assert venue_edited.siret == "88888888888888"
        assert stock.idAtProviders == "id_at_provider_ne_contenant_pas_le_siret"
        assert offer.idAtProviders == "id_at_provider_ne_contenant_pas_le_siret"
Exemple #3
0
def test_reset_stock_quantity():
    offer = OfferFactory(idAtProviders="1")
    venue = offer.venue
    stock1_no_bookings = StockFactory(offer=offer, quantity=10)
    stock2_only_cancelled_bookings = StockFactory(offer=offer, quantity=10)
    CancelledBookingFactory(stock=stock2_only_cancelled_bookings)
    stock3_mix_of_bookings = StockFactory(offer=offer, quantity=10)
    BookingFactory(stock=stock3_mix_of_bookings)
    CancelledBookingFactory(stock=stock3_mix_of_bookings)
    manually_added_offer = OfferFactory(venue=venue)
    stock4_manually_added = StockFactory(offer=manually_added_offer, quantity=10)
    stock5_other_venue = StockFactory(quantity=10)

    api.reset_stock_quantity(venue)

    assert stock1_no_bookings.quantity == 0
    assert stock2_only_cancelled_bookings.quantity == 0
    assert stock3_mix_of_bookings.quantity == 1
    assert stock4_manually_added.quantity == 10
    assert stock5_other_venue.quantity == 10
    def test_insufficient_credit(self, app):
        users_factories.UserFactory(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/book_offer", json={"stockId": stock.id, "quantity": 1})

        assert response.status_code == 400
        assert response.json["code"] == "INSUFFICIENT_CREDIT"
Exemple #5
0
    def test_edit_venue_provider(self, mock_siret_can_be_synchronized,
                                 mock_synchronize_venue_provider,
                                 validate_csrf_token, client, app):
        # Given
        AdminFactory(email="*****@*****.**")
        venue = VenueFactory()
        old_provider = ProviderFactory(name="old provider",
                                       enabledForPro=True,
                                       localClass=None,
                                       apiUrl="https://example.com")
        new_provider = ProviderFactory(name="new provider",
                                       enabledForPro=True,
                                       localClass=None,
                                       apiUrl="https://example2.com")
        venue_provider = VenueProviderFactory(provider=old_provider,
                                              venue=venue)

        existing_stock = StockFactory(quantity=10,
                                      offer__venue=venue,
                                      offer__idAtProviders="1")
        BookingFactory(stock=existing_stock)

        mock_siret_can_be_synchronized.return_value = True

        data = dict(
            provider=new_provider.id,
            venue=venue.id,
            venueIdAtOfferProvider="hsf4uiagèy12386dq",
        )

        client.with_session_auth("*****@*****.**")
        response = client.post(
            f"/pc/back-office/venue_providers/edit/?id={venue_provider.id}",
            form=data)

        assert response.status_code == 302

        # Then
        venue_provider = VenueProvider.query.one()

        # Check that venue_provider model have been updated
        assert venue_provider.venue == venue
        assert venue_provider.provider == new_provider
        assert venue_provider.venueIdAtOfferProvider == "hsf4uiagèy12386dq"

        # Check that the quantity of existing stocks have been updated and quantity reset to booked_quantity.
        assert existing_stock.quantity == 1
        assert existing_stock.offer.lastProviderId == new_provider.id

        mock_synchronize_venue_provider.assert_called_once_with(venue_provider)
    def test_book_offer(self, app):
        stock = StockFactory()
        user = users_factories.UserFactory(email=self.identifier)

        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/book_offer", json={"stockId": stock.id, "quantity": 1})

        assert response.status_code == 204

        booking = Booking.query.filter(Booking.stockId == stock.id).first()
        assert booking.userId == user.id
Exemple #7
0
    def should_update_id_at_providers_for_offers_and_stocks_with_current_siret(self, mock_repository, app):
        # Given
        current_siret = "32363560700019"
        venue = VenueFactory(siret=current_siret, id=12)
        offer = OfferFactory(venue=venue, idAtProviders="9782742785988@85234081900014")
        stock = StockFactory(offer=offer, idAtProviders="9782742785988@85234081900014")

        # When
        update_offer_and_stock_id_at_providers(venue_id=12)

        # Then
        assert offer.idAtProviders == "9782742785988@32363560700019"
        assert stock.idAtProviders == "9782742785988@32363560700019"
        assert mock_repository.save.call_count == 2
        assert mock_repository.save.call_args_list == [call(offer), call(stock)]
Exemple #8
0
    def should_call_synchronize_on_expected_venue_provider(self, mock_do_sync_venue_provider, app):
        # Given
        venue = VenueFactory()
        offer = OfferFactory(venue=venue)
        stock = StockFactory(offer=offer)
        titelive = activate_provider(provider_classname="TiteLiveStocks")
        venue_provider = create_venue_provider(venue=venue, provider=titelive)

        repository.save(venue_provider, stock)

        # When
        fully_sync_library(venue_id=venue.id)

        # Then
        mock_do_sync_venue_provider.assert_called_once_with(venue_provider)
    def test_update_offer_and_stock_id_at_providers(self):
        # Given
        current_siret = "88888888888888"
        venue = VenueFactory(siret=current_siret)
        offer = OfferFactory(venue=venue,
                             idAtProviders="1111111111111@22222222222222")
        other_venue_offer = OfferFactory(
            venue=venue, idAtProviders="3333333333333@12222222222222")
        stock = StockFactory(offer=offer,
                             idAtProviders="1111111111111@22222222222222")

        # When
        update_offer_and_stock_id_at_providers(venue, "22222222222222")

        # Then
        assert offer.idAtProviders == "1111111111111@88888888888888"
        assert stock.idAtProviders == "1111111111111@88888888888888"
        assert other_venue_offer.idAtProviders == "3333333333333@12222222222222"
Exemple #10
0
def test_change_venue_provider():
    api_url = "https://example.com/provider/api"
    provider = offerers_factories.APIProviderFactory()
    venue_provider = offerers_factories.VenueProviderFactory(provider=provider)
    venue = venue_provider.venue
    stock = StockFactory(quantity=10, offer__venue=venue, offer__idAtProviders="1")
    BookingFactory(stock=stock)
    new_provider = offerers_factories.APIProviderFactory(apiUrl=api_url)

    api.change_venue_provider(venue_provider, new_provider.id)

    # Check venue_provider has change provider and sync date reset
    assert len(venue.venueProviders) == 1
    assert venue.venueProviders[0].providerId == new_provider.id
    assert venue.venueProviders[0].lastSyncDate == None
    # Check that the quantity of existing stocks has been reset.
    assert stock.quantity == 1
    assert stock.offer.lastProviderId == new_provider.id
Exemple #11
0
    def should_update_quantity_to_booking_amount_for_each_synchronized_stock_on_venue(
        self, mock_do_sync_venue_provider, app
    ):
        # Given
        titelive = activate_provider(provider_classname="TiteLiveStocks")
        venue = VenueFactory()
        offer = OfferFactory(venue=venue, idAtProviders="titelive")
        stock = StockFactory(offer=offer, quantity=2, lastProviderId=titelive.id, idAtProviders="titelive")
        booking = BookingFactory(stock=stock)
        venue_provider = create_venue_provider(venue=venue, provider=titelive)

        repository.save(venue_provider, booking)

        # When
        fully_sync_library(venue_id=venue.id)

        # Then
        assert stock.quantity == 1
Exemple #12
0
    def test_post_bookings(self, app):
        stock = StockFactory()
        user = users_factories.BeneficiaryGrant18Factory(email=self.identifier)

        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 == 200

        booking = (Booking.query.filter(Booking.stockId == stock.id).options(
            joinedload(Booking.individualBooking)).first())
        assert booking.individualBooking.userId == user.id
        assert response.json["bookingId"] == booking.id
Exemple #13
0
    def test_get_bookings(self, app):
        OFFER_URL = "https://demo.pass/some/path?token={token}&email={email}&offerId={offerId}"
        user = users_factories.BeneficiaryGrant18Factory(email=self.identifier)

        permanent_booking = booking_factories.UsedIndividualBookingFactory(
            individualBooking__user=user,
            stock__offer__subcategoryId=subcategories.
            TELECHARGEMENT_LIVRE_AUDIO.id,
            dateUsed=datetime(2021, 2, 3),
        )

        event_booking = booking_factories.IndividualBookingFactory(
            individualBooking__user=user,
            stock=EventStockFactory(beginningDatetime=datetime(2021, 3, 14)))

        digital_stock = StockWithActivationCodesFactory()
        first_activation_code = digital_stock.activationCodes[0]
        second_activation_code = digital_stock.activationCodes[1]
        digital_booking = booking_factories.UsedIndividualBookingFactory(
            individualBooking__user=user,
            stock=digital_stock,
            activationCode=first_activation_code,
        )
        ended_digital_booking = booking_factories.UsedIndividualBookingFactory(
            individualBooking__user=user,
            displayAsEnded=True,
            stock=digital_stock,
            activationCode=second_activation_code,
        )
        expire_tomorrow = booking_factories.IndividualBookingFactory(
            individualBooking__user=user,
            dateCreated=datetime.now() - timedelta(days=29))
        used_but_in_future = booking_factories.UsedIndividualBookingFactory(
            individualBooking__user=user,
            dateUsed=datetime(2021, 3, 11),
            stock=StockFactory(beginningDatetime=datetime(2021, 3, 15)),
        )

        cancelled_permanent_booking = booking_factories.CancelledIndividualBookingFactory(
            individualBooking__user=user,
            stock__offer__subcategoryId=subcategories.
            TELECHARGEMENT_LIVRE_AUDIO.id,
            cancellation_date=datetime(2021, 3, 10),
        )
        cancelled = booking_factories.CancelledIndividualBookingFactory(
            individualBooking__user=user,
            cancellation_date=datetime(2021, 3, 8))
        used1 = booking_factories.UsedIndividualBookingFactory(
            individualBooking__user=user, dateUsed=datetime(2021, 3, 1))
        used2 = booking_factories.UsedIndividualBookingFactory(
            individualBooking__user=user,
            displayAsEnded=True,
            dateUsed=datetime(2021, 3, 2),
            stock__offer__url=OFFER_URL,
            cancellation_limit_date=datetime(2021, 3, 2),
        )

        mediation = MediationFactory(id=111,
                                     offer=used2.stock.offer,
                                     thumbCount=1,
                                     credit="street credit")

        access_token = create_access_token(identity=self.identifier)
        test_client = TestClient(app.test_client())
        test_client.auth_header = {"Authorization": f"Bearer {access_token}"}

        # 1: get the user
        # 1: get the bookings
        # 1: get AUTO_ACTIVATE_DIGITAL_BOOKINGS feature
        # 1: rollback
        with assert_num_queries(4):
            response = test_client.get("/native/v1/bookings")

        assert response.status_code == 200
        assert [b["id"] for b in response.json["ongoing_bookings"]] == [
            expire_tomorrow.id,
            event_booking.id,
            used_but_in_future.id,
            digital_booking.id,
            permanent_booking.id,
        ]

        assert response.json["ongoing_bookings"][3]["activationCode"]

        assert [b["id"] for b in response.json["ended_bookings"]] == [
            ended_digital_booking.id,
            cancelled_permanent_booking.id,
            cancelled.id,
            used2.id,
            used1.id,
        ]

        assert response.json["ended_bookings"][3] == {
            "activationCode": None,
            "cancellationDate": None,
            "cancellationReason": None,
            "confirmationDate": "2021-03-02T00:00:00Z",
            "completedUrl":
            f"https://demo.pass/some/path?token={used2.token}&[email protected]&offerId={humanize(used2.stock.offer.id)}",
            "dateUsed": "2021-03-02T00:00:00Z",
            "expirationDate": None,
            "quantity": 1,
            "qrCodeData": None,
            "id": used2.id,
            "stock": {
                "beginningDatetime": None,
                "id": used2.stock.id,
                "offer": {
                    "category": {
                        "categoryType": "Thing",
                        "label": "Support physique (DVD, Blu-ray...)",
                        "name": "FILM",
                    },
                    "subcategoryId": subcategories.SUPPORT_PHYSIQUE_FILM.id,
                    "extraData": None,
                    "id": used2.stock.offer.id,
                    "image": {
                        "credit": "street credit",
                        "url": mediation.thumbUrl
                    },
                    "isDigital": True,
                    "isPermanent": False,
                    "name": used2.stock.offer.name,
                    "url":
                    f"https://demo.pass/some/path?token={used2.token}&[email protected]&offerId={humanize(used2.stock.offer.id)}",
                    "venue": {
                        "city": "Paris",
                        "coordinates": {
                            "latitude": 48.87004,
                            "longitude": 2.3785
                        },
                        "id": used2.venue.id,
                        "name": used2.venue.name,
                        "publicName": used2.venue.publicName,
                    },
                    "withdrawalDetails": None,
                },
            },
            "token": used2.token,
            "totalAmount": 1000,
        }

        for booking in response.json["ongoing_bookings"]:
            assert booking["qrCodeData"] is not None