Skip to content

Commit

Permalink
(PC-33734)[API] feat: turn on ENABLE_COLLECTIVE_NEW_STATUSES FF by de…
Browse files Browse the repository at this point in the history
…fault
  • Loading branch information
jcicurel-pass committed Dec 27, 2024
1 parent 7276aa6 commit 8672c50
Show file tree
Hide file tree
Showing 11 changed files with 112 additions and 118 deletions.
1 change: 0 additions & 1 deletion api/src/pcapi/models/feature.py
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,6 @@ def nameKey(self) -> str:
FeatureToggle.ENABLE_BANK_ACCOUNT_SYNC,
FeatureToggle.ENABLE_BEAMER,
FeatureToggle.ENABLE_CODIR_OFFERERS_REPORT, # only for production
FeatureToggle.ENABLE_COLLECTIVE_NEW_STATUSES,
FeatureToggle.ENABLE_CRON_TO_UPDATE_OFFERER_STATS, # only for production
FeatureToggle.ENABLE_CULTURAL_SURVEY,
FeatureToggle.ENABLE_DMS_LINK_ON_MAINTENANCE_PAGE_FOR_AGE_18,
Expand Down
2 changes: 2 additions & 0 deletions api/src/pcapi/routes/pro/collective_stocks.py
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,8 @@ def edit_collective_stock(
return collective_stock_serialize.CollectiveStockResponseModel.from_orm(collective_stock)
except educational_exceptions.CollectiveOfferIsPublicApi:
raise ApiErrors({"global": ["Les stocks créés par l'api publique ne sont pas editables."]}, 403)
except educational_exceptions.CollectiveOfferForbiddenAction:
raise ApiErrors({"global": ["Cette action n'est pas autorisée sur l'offre collective liée à ce stock."]}, 403)
except offers_exceptions.BookingLimitDatetimeTooLate:
raise ApiErrors(
{"educationalStock": ["La date limite de confirmation ne peut être fixée après la date de l évènement"]},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,7 @@ def test_should_replace_bookingLimitDatetime_with_old_event_datetime_if_provided
# stock = CollectiveStock.query.filter_by(id=stock_to_be_updated.id).one()
# mocked_async_index_offer_ids.assert_called_once_with([stock.collectiveOfferId])

@override_features(ENABLE_COLLECTIVE_NEW_STATUSES=False)
def test_should_not_allow_stock_edition_when_booking_status_is_REIMBURSED_or_USED(self) -> None:
# Given
educational_factories.EducationalYearFactory(
Expand Down Expand Up @@ -285,6 +286,7 @@ def should_update_bookings_cancellation_limit_date_if_beginningDatetime_earlier(
booking_updated = CollectiveBooking.query.filter_by(id=booking.id).one()
assert booking_updated.cancellationLimitDate == datetime.datetime.utcnow()

@override_features(ENABLE_COLLECTIVE_NEW_STATUSES=False)
@time_machine.travel("2020-11-17 15:00:00")
def test_should_allow_stock_edition_and_not_modify_cancellation_limit_date_when_booking_cancelled(self) -> None:
# Given
Expand Down Expand Up @@ -474,6 +476,7 @@ def test_can_lower_price_and_edit_price_details_ended(self):

@pytest.mark.usefixtures("db_session")
class ReturnErrorTest:
@override_features(ENABLE_COLLECTIVE_NEW_STATUSES=False)
def test_edit_stock_of_non_approved_offer_fails(self) -> None:
# Given
offer = educational_factories.CollectiveOfferFactory(validation=OfferValidationStatus.PENDING)
Expand Down Expand Up @@ -547,6 +550,7 @@ def test_should_not_allow_stock_edition_when_bookingLimitDatetime_not_provided_a
stock = CollectiveStock.query.filter_by(id=stock_to_be_updated.id).one()
assert stock.beginningDatetime == datetime.datetime(2021, 12, 10)

@override_features(ENABLE_COLLECTIVE_NEW_STATUSES=False)
@time_machine.travel("2020-11-17 15:00:00")
def test_should_allow_stock_edition_and_not_modify_cancellation_limit_date_when_booking_cancelled(self) -> None:
# Given
Expand Down Expand Up @@ -586,6 +590,7 @@ def test_should_allow_stock_edition_and_not_modify_cancellation_limit_date_when_
stock = CollectiveStock.query.filter_by(id=stock_to_be_updated.id).one()
assert stock.beginningDatetime == new_event_date.replace(tzinfo=None)

@override_features(ENABLE_COLLECTIVE_NEW_STATUSES=False)
def test_edit_offer_of_cancelled_booking(self) -> None:
# Given
offer = educational_factories.CollectiveOfferFactory()
Expand Down Expand Up @@ -627,6 +632,8 @@ def test_edit_offer_of_cancelled_booking(self) -> None:
assert stock.price == 1500
assert stock.numberOfTickets == 35

@override_features(ENABLE_COLLECTIVE_NEW_STATUSES=False)
# TODO: impossible test case ? Booking limit is now + 3, start and end are now - 5 and offer is pre-booked
@time_machine.travel("2020-01-05 10:00:00")
def test_edit_offer_of_other_status_booking(self) -> None:
# Given
Expand Down Expand Up @@ -672,6 +679,7 @@ def test_edit_offer_of_other_status_booking(self) -> None:
# Then
assert error.value.errors == {"global": ["Les évènements passés ne sont pas modifiables"]}

@override_features(ENABLE_COLLECTIVE_NEW_STATUSES=False)
def test_edit_price_or_ticket_number_if_status_confirmed(self):
initial_event_date = datetime.datetime.utcnow() + datetime.timedelta(days=10)
initial_booking_limit_date = datetime.datetime.utcnow() + datetime.timedelta(days=5)
Expand Down
10 changes: 10 additions & 0 deletions api/tests/core/educational/test_models.py
Original file line number Diff line number Diff line change
Expand Up @@ -90,12 +90,20 @@ def test_bookable(self) -> None:
collective_stock = factories.CollectiveStockFactory()
assert collective_stock.isBookable

@override_features(ENABLE_COLLECTIVE_NEW_STATUSES=False)
def test_bookable_if_booking_is_cancelled(self) -> None:
collective_stock = factories.CollectiveStockFactory()
factories.CollectiveBookingFactory(collectiveStock=collective_stock, status=CollectiveBookingStatus.CANCELLED)

assert collective_stock.isBookable

@override_features(ENABLE_COLLECTIVE_NEW_STATUSES=True)
def test_bookable_if_booking_is_cancelled_with_new_statuses(self) -> None:
collective_stock = factories.CollectiveStockFactory()
factories.CollectiveBookingFactory(collectiveStock=collective_stock, status=CollectiveBookingStatus.CANCELLED)

assert not collective_stock.isBookable


class CollectiveOfferIsSoldOutTest:
def test_is_sold_out_property_false(self) -> None:
Expand Down Expand Up @@ -695,11 +703,13 @@ def test_get_displayed_status_for_offer_with_cancelled_booking(self):


class CollectiveOfferTemplateDisplayedStatusTest:
@override_features(ENABLE_COLLECTIVE_NEW_STATUSES=False)
@pytest.mark.parametrize("status", set(COLLECTIVE_OFFER_TEMPLATE_STATUSES) - {CollectiveOfferDisplayedStatus.ENDED})
def test_get_offer_displayed_status(self, status):
offer = factories.create_collective_offer_template_by_status(status)
assert offer.displayedStatus == status

@override_features(ENABLE_COLLECTIVE_NEW_STATUSES=False)
def test_get_offer_displayed_status_ended(self):
# when ENABLE_COLLECTIVE_NEW_STATUSES FF is off, and ended offer is INACTIVE
offer = factories.create_collective_offer_template_by_status(CollectiveOfferDisplayedStatus.ENDED)
Expand Down
3 changes: 3 additions & 0 deletions api/tests/core/offers/test_repository.py
Original file line number Diff line number Diff line change
Expand Up @@ -1320,6 +1320,7 @@ def admin_user_fixture():

@pytest.mark.usefixtures("db_session")
class GetCollectiveOffersTemplateByFiltersTest:
@override_features(ENABLE_COLLECTIVE_NEW_STATUSES=False)
def test_status_filter_active(self, admin_user):
template = educational_factories.CollectiveOfferTemplateFactory()
educational_factories.CollectiveOfferTemplateFactory(validation=offer_mixin.OfferValidationStatus.REJECTED)
Expand Down Expand Up @@ -1347,6 +1348,7 @@ def test_filter_each_status_with_new_statuses(self, admin_user, offer_status):
)
assert result.count() == 0

@override_features(ENABLE_COLLECTIVE_NEW_STATUSES=False)
@pytest.mark.parametrize(
"offer_status",
set(educational_models.COLLECTIVE_OFFER_TEMPLATE_STATUSES)
Expand All @@ -1366,6 +1368,7 @@ def test_filter_each_status(self, admin_user, offer_status):
)
assert result.count() == 0

@override_features(ENABLE_COLLECTIVE_NEW_STATUSES=False)
def test_filter_ended(self, admin_user):
template = educational_factories.create_collective_offer_template_by_status(
educational_models.CollectiveOfferDisplayedStatus.ENDED
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,7 @@ def test_cancel_unallowed_action(self, client, status):


class Returns400Test:

@override_features(ENABLE_COLLECTIVE_NEW_STATUSES=False)
@pytest.mark.parametrize(
"status",
[
Expand Down
111 changes: 44 additions & 67 deletions api/tests/routes/pro/patch_collective_offer_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,10 +53,10 @@ def auth_client_fixture(client, user_offerer):
class Returns200Test:
endpoint = "Private API.edit_collective_offer"

@override_features(ENABLE_COLLECTIVE_NEW_STATUSES=True)
@time_machine.travel("2019-01-01 12:00:00")
@override_settings(ADAGE_API_URL="https://adage_base_url")
def test_patch_collective_offer(self, client):
# Given
offer = educational_factories.CollectiveOfferFactory(
mentalDisabilityCompliant=False,
contactEmail="[email protected]",
Expand All @@ -68,16 +68,14 @@ def test_patch_collective_offer(self, client):
interventionArea=["01", "07", "08"],
)
booking = educational_factories.CollectiveBookingFactory(
collectiveStock__collectiveOffer=offer, collectiveStock__beginningDatetime=datetime(2020, 1, 1)
)
offerers_factories.UserOffererFactory(
user__email="[email protected]",
offerer=offer.venue.managingOfferer,
collectiveStock__collectiveOffer=offer,
collectiveStock__beginningDatetime=datetime(2020, 1, 1),
status=CollectiveBookingStatus.PENDING,
)
offerers_factories.UserOffererFactory(user__email="[email protected]", offerer=offer.venue.managingOfferer)
domain = educational_factories.EducationalDomainFactory(name="Architecture")
national_program = educational_factories.NationalProgramFactory()

# When
data = {
"name": "New name",
"mentalDisabilityCompliant": True,
Expand All @@ -92,14 +90,12 @@ def test_patch_collective_offer(self, client):
"formats": [subcategories.EacFormat.CONCERT.value],
}

# WHEN
client = client.with_session_auth("[email protected]")
with patch(
"pcapi.routes.pro.collective_offers.offerers_api.can_offerer_create_educational_offer",
):
response = client.patch(f"/collective/offers/{offer.id}", json=data)

# Then
assert response.status_code == 200
assert response.json["name"] == "New name"
assert response.json["mentalDisabilityCompliant"]
Expand Down Expand Up @@ -150,32 +146,17 @@ def test_patch_collective_offer(self, client):
assert adage_request["sent_data"] == expected_payload
assert adage_request["url"] == "https://adage_base_url/v1/prereservation-edit"

@override_features(ENABLE_COLLECTIVE_NEW_STATUSES=True)
@override_settings(ADAGE_API_URL="https://adage_base_url")
def test_patch_collective_offer_do_not_notify_educational_redactor_when_no_active_booking(
self,
client,
):
# Given
def test_patch_collective_offer_do_not_notify_educational_redactor_when_no_booking(self, client):
offer = educational_factories.CollectiveOfferFactory()
educational_factories.CollectiveBookingFactory(
collectiveStock__collectiveOffer=offer, status=CollectiveBookingStatus.CANCELLED
)
offerers_factories.UserOffererFactory(
user__email="[email protected]",
offerer=offer.venue.managingOfferer,
)
data = {
"name": "New name",
}
offerers_factories.UserOffererFactory(user__email="[email protected]", offerer=offer.venue.managingOfferer)
data = {"name": "New name"}

# WHEN
client = client.with_session_auth("[email protected]")
with patch(
"pcapi.routes.pro.collective_offers.offerers_api.can_offerer_create_educational_offer",
):
with patch("pcapi.routes.pro.collective_offers.offerers_api.can_offerer_create_educational_offer"):
response = client.patch(f"/collective/offers/{offer.id}", json=data)

# Then
assert response.status_code == 200
assert len(educational_testing.adage_requests) == 0

Expand Down Expand Up @@ -227,6 +208,7 @@ def test_patch_collective_offer_update_student_level_college_6(self, client):
assert len(offer.students) == 1
assert offer.students[0].value == "Collège - 6e"

@override_features(ENABLE_COLLECTIVE_NEW_STATUSES=False)
@pytest.mark.parametrize(
"factory",
[
Expand All @@ -235,7 +217,6 @@ def test_patch_collective_offer_update_student_level_college_6(self, client):
],
)
def test_update_venue_both_offer_and_booking(self, auth_client, venue, other_related_venue, factory):

offer = educational_factories.CollectiveOfferFactory(venue=other_related_venue)
stock = educational_factories.CollectiveStockFactory(collectiveOffer=offer)

Expand All @@ -257,6 +238,26 @@ def test_update_venue_both_offer_and_booking(self, auth_client, venue, other_rel
assert booking.venueId == venue.id
assert cancelled_booking.venueId == venue.id

@override_features(ENABLE_COLLECTIVE_NEW_STATUSES=True)
def test_update_venue_both_offer_and_booking_with_new_statuses(self, auth_client, venue, other_related_venue):
offer = educational_factories.CollectiveOfferFactory(venue=other_related_venue)
stock = educational_factories.CollectiveStockFactory(collectiveOffer=offer)

booking = educational_factories.PendingCollectiveBookingFactory(
venue=other_related_venue, collectiveStock=stock
)

patch_path = "pcapi.routes.pro.collective_offers.offerers_api.can_offerer_create_educational_offer"
with patch(patch_path):
response = auth_client.patch(url_for(self.endpoint, offer_id=offer.id), json={"venueId": venue.id})
assert response.status_code == 200

db.session.refresh(offer)
db.session.refresh(booking)

assert offer.venueId == venue.id
assert booking.venueId == venue.id

@override_features(ENABLE_COLLECTIVE_NEW_STATUSES=True)
@pytest.mark.parametrize("status", educational_testing.STATUSES_ALLOWING_EDIT_DETAILS)
def test_patch_collective_offer_allowed_action(self, client, status):
Expand Down Expand Up @@ -293,21 +294,14 @@ def test_patch_collective_offer_allowed_action(self, client, status):


class Returns400Test:
@override_features(ENABLE_COLLECTIVE_NEW_STATUSES=False)
def test_patch_non_approved_offer_fails(self, app, client):
offer = educational_factories.CollectiveOfferFactory(validation=OfferValidationStatus.PENDING)
offerers_factories.UserOffererFactory(
user__email="[email protected]",
offerer=offer.venue.managingOfferer,
)
offerers_factories.UserOffererFactory(user__email="[email protected]", offerer=offer.venue.managingOfferer)

data = {
"visualDisabilityCompliant": True,
}
# WHEN
data = {"visualDisabilityCompliant": True}
client = client.with_session_auth("[email protected]")
with patch(
"pcapi.routes.pro.collective_offers.offerers_api.can_offerer_create_educational_offer",
):
with patch("pcapi.routes.pro.collective_offers.offerers_api.can_offerer_create_educational_offer"):
response = client.patch(f"/collective/offers/{offer.id}", json=data)

assert response.status_code == 400
Expand Down Expand Up @@ -563,51 +557,33 @@ def when_user_is_not_attached_to_offerer(self, app, client):
]
assert CollectiveOffer.query.get(offer.id).name == "Old name"

@override_features(ENABLE_COLLECTIVE_NEW_STATUSES=False)
def test_cannot_update_offer_with_used_booking(self, client):
# Given
offer = educational_factories.CollectiveOfferFactory()
educational_factories.UsedCollectiveBookingFactory(
collectiveStock__collectiveOffer=offer,
)
offerers_factories.UserOffererFactory(
user__email="[email protected]",
offerer=offer.venue.managingOfferer,
)
data = {
"name": "New name",
}
offerers_factories.UserOffererFactory(user__email="[email protected]", offerer=offer.venue.managingOfferer)
data = {"name": "New name"}

# WHEN
client = client.with_session_auth("[email protected]")
with patch(
"pcapi.routes.pro.collective_offers.offerers_api.can_offerer_create_educational_offer",
):
with patch("pcapi.routes.pro.collective_offers.offerers_api.can_offerer_create_educational_offer"):
response = client.patch(f"/collective/offers/{offer.id}", json=data)

# Then
assert response.status_code == 403
assert response.json == {"offer": "the used or refund offer can't be edited."}

@override_features(ENABLE_COLLECTIVE_NEW_STATUSES=False)
def test_cannot_update_offer_created_by_public_api(self, client):
# Given
provider = providers_factories.ProviderFactory()
offer = educational_factories.CollectiveOfferFactory(provider=provider)
offerers_factories.UserOffererFactory(
user__email="[email protected]",
offerer=offer.venue.managingOfferer,
)
data = {
"name": "New name",
}
offerers_factories.UserOffererFactory(user__email="[email protected]", offerer=offer.venue.managingOfferer)
data = {"name": "New name"}

# WHEN
client = client.with_session_auth("[email protected]")
with patch(
"pcapi.routes.pro.collective_offers.offerers_api.can_offerer_create_educational_offer",
):
with patch("pcapi.routes.pro.collective_offers.offerers_api.can_offerer_create_educational_offer"):
response = client.patch(f"/collective/offers/{offer.id}", json=data)

# Then
assert response.status_code == 403
assert response.json == {"global": ["Collective offer created by public API is only editable via API."]}

Expand All @@ -634,6 +610,7 @@ def test_patch_collective_offer_replacing_venue_with_different_offerer(self, cli
assert response.status_code == 403
assert response.json == {"venueId": "New venue needs to have the same offerer"}

@override_features(ENABLE_COLLECTIVE_NEW_STATUSES=False)
def test_update_collective_offer_venue_of_reimbursed_offer_fails(self, client, other_related_venue):
offer = educational_factories.ReimbursedCollectiveOfferFactory()
offerers_factories.UserOffererFactory(user__email="[email protected]", offerer=offer.venue.managingOfferer)
Expand Down
Loading

0 comments on commit 8672c50

Please sign in to comment.