fix(promo-codes): restrict implicit "apply to all" to Audience=All only#541
fix(promo-codes): restrict implicit "apply to all" to Audience=All only#541caseylocker wants to merge 2 commits into
Conversation
When SummitRegistrationPromoCode::allowed_ticket_types is empty, canBeAppliedTo() previously returned true for any ticket type — including WithPromoCode-audience tickets that are deliberately hidden from the public. This change tightens the implicit-sweep branch to require Audience = All; non-All audiences must be opted in via explicit allowed_ticket_types membership. Adds 11 unit tests (4 audience values × empty/explicit) and a smoke test confirming DomainAuthorizedSummitRegistrationDiscountCode's override still applies to its explicitly-allowed WithPromoCode tickets. Refs: ClickUp 86b9vrpxp; parent feature SDS doc/promo-codes-for-early-registration-access.md
…case testNonEmptyAllowedTicketTypesNotContainingTicketReturnsFalse previously only ran for Audience=All. Convert it to a DataProvider so a regression that accidentally returns true on the absent-from-list path for WithInvitation / WithoutInvitation / WithPromoCode also gets caught. Also tighten the stale "returns true when allowed_ticket_types is empty" comment in DomainAuthorizedSummitRegistrationDiscountCode::addTicketTypeRule to reflect the post-fix conditional, and refresh the SDS line-number cites to match the current method body. Refs: ClickUp 86b9vrpxp; Codex review of 8defe88.
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (4)
📝 WalkthroughWalkthroughThis PR enforces audience-aware applicability for promo codes when ChangesPromo Code Audience Restriction
🎯 3 (Moderate) | ⏱️ ~25 minutes
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
📘 OpenAPI / Swagger preview ➡️ https://OpenStackweb.github.io/summit-api/openapi/pr-541/ This page is automatically updated on each push to this PR. |
There was a problem hiding this comment.
Pull request overview
This PR tightens promo-code applicability so the implicit “apply to all ticket types” behavior (empty allowed_ticket_types) only applies to ticket types whose audience is All, preventing unintended applicability to restricted audiences like WithPromoCode.
Changes:
- Updated
SummitRegistrationPromoCode::canBeAppliedTo()so an emptyallowed_ticket_typescollection returnstrueonly forAudience_All. - Added a dedicated unit-test matrix covering all audiences across empty/non-empty allowed-ticket-type scenarios, plus subclass delegation smoke tests.
- Added an SDS documenting the rationale, scope, and acceptance criteria; updated a related in-code comment to reflect the new audience-conditional empty-collection behavior.
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated no comments.
| File | Description |
|---|---|
app/Models/Foundation/Summit/Registration/PromoCodes/SummitRegistrationPromoCode.php |
Restricts empty allowed_ticket_types (“apply to all”) to Audience_All ticket types only. |
tests/Unit/Services/PromoCodeCanBeAppliedToAudienceTest.php |
Adds unit coverage guarding the new audience restriction and verifying subclass delegation behavior. |
doc/promo-code-apply-to-all-audience-restriction.md |
Documents the design decision, scope, and test plan for the audience restriction. |
app/Models/Foundation/Summit/Registration/PromoCodes/DomainAuthorizedSummitRegistrationDiscountCode.php |
Updates a comment to align with the now audience-conditional empty-collection behavior. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
ref: https://app.clickup.com/t/86b9vrpxp
Summary
Tightens
SummitRegistrationPromoCode::canBeAppliedTo()so the implicit "apply to all" branch (emptyallowed_ticket_types) only matches ticket types withAudience = All. Other audiences (WithInvitation,WithoutInvitation,WithPromoCode) must be opted in via explicitallowed_ticket_typesmembership.doc/promo-codes-for-early-registration-access.md(merged via PR feat(promo-codes): domain-authorized promo codes for early registration access #525)doc/promo-code-apply-to-all-audience-restriction.mdfeat/→feature/to satisfycheck-branch-nameCI)What changed
app/Models/Foundation/Summit/Registration/PromoCodes/SummitRegistrationPromoCode.php:483-495— empty-collection branch returns$ticketType->getAudience() === SummitTicketType::Audience_All. Subclass overrides (SummitRegistrationDiscountCode::canBeAppliedTo,DomainAuthorizedSummitRegistrationDiscountCode::canBeAppliedTo) delegate to the patched base — no override changes needed.tests/Unit/Services/PromoCodeCanBeAppliedToAudienceTest.php— new unit tests, dataProvider over all 4 audiences × {empty, present, absent} + a smoke test for the domain-authorized override.doc/promo-code-apply-to-all-audience-restriction.md— dedicated SDS.app/Models/Foundation/Summit/Registration/PromoCodes/DomainAuthorizedSummitRegistrationDiscountCode.php:73— tightened a stale comment now that the empty branch is audience-conditional.Caller audit
canBeAppliedTo()is the single gate for every production path:RegularPromoCodeTicketTypesStrategy::applyPromo2TicketType()line 82SummitOrderService.php:812and:1093(order/checkout pipeline)RegularTicketTypePromoCodeValidationStrategy.php:91No code path independently treats empty
allowed_ticket_typesas "applies to all audiences" for promo codes. The out-of-scope siblingSummitAttendee.php:1367is a different domain (invitations).Behavior change (intentional)
Existing discount codes with empty
allowed_ticket_typesthat today implicitly coverWithInvitation/WithoutInvitationtickets will stop covering them after deploy. This is called out in the ticket: "Existing discount codes with 'Apply to all' checked continue to work correctly for Audience = All ticket types — no regression."AC5 wording note
The ClickUp acceptance criterion #5 says "submitting
apply_to_all_ticket_types = trueresolves to Audience = All only, regardless of frontend." No such payload field exists in this API — it's a conceptual name. The actual enforcement iscanBeAppliedTo(), the single gate every consumer flows through. A hostile client cannot bypass it because there's noapply_to_all_*field to honor or ignore.Test plan
./vendor/bin/phpunit tests/Unit/Services/PromoCodeCanBeAppliedToAudienceTest.php— passtests/Unit/Services/passes (53 tests, 77 assertions, no deprecations)Run Unit Tests On Pushworkflow rantests/oauth2/(OAuth2Testsshard) on the PR head — green. The previously-flaggedOAuth2SummitTicketTypesApiTest::testGetAllowedTicketTypesApplyingRegularDiscountCodeToAllOfThem(:218) still passes:default_ticket_typeisAudience=Allpertests/InsertSummitTestData.php:355, so it remains discount-eligible after the empty branch is gated, and'+id'ordering keeps it atdata[0]for the assertion.SUMMIT_DISCOUNT_CODEwith empty rules, verify it does NOT apply to aWithPromoCodeticket type; add the WithPromoCode type toallowed_ticket_types, verify it then applies. Deferred: dev/staging do not yet carry this change. Reviewer please run after first deploy.Summary by CodeRabbit
Bug Fixes
Tests
Documentation