Skip to content

fix(promocode): clarify Apply-to-all scope (Audience: All only)#928

Open
caseylocker wants to merge 2 commits into
masterfrom
feature/promo-code-apply-to-all-audience-restriction
Open

fix(promocode): clarify Apply-to-all scope (Audience: All only)#928
caseylocker wants to merge 2 commits into
masterfrom
feature/promo-code-apply-to-all-audience-restriction

Conversation

@caseylocker
Copy link
Copy Markdown

@caseylocker caseylocker commented May 11, 2026

ref: https://app.clickup.com/t/86b9vrpxp

Summary

The backend tightens canBeAppliedTo() so the implicit "apply to all" branch only covers Audience = All ticket types (see companion summit-api PR). This change updates the admin copy so the checkbox label and a new helper-text row name the restriction explicitly. WithInvitation, WithoutInvitation, and WithPromoCode ticket types must be opted in via the picker after saving.

No JS logic change — the apply_to_all_tix flag is and remains UI-only (deleted before send at src/actions/promocode-actions.js:160 and re-derived from ticket_types_rules.length === 0 at src/reducers/promocodes/promocode-reducer.js:179).

What changed

  • src/i18n/en.jsonapply_to_all_tix rewritten to "Apply to all ticket types (Audience: All)"; new apply_to_all_tix_helper key.
  • src/components/forms/promocode-form/forms/discount-base-pc-form.js — added <small className="form-text text-muted"> helper row beneath the checkbox.
  • src/components/forms/speakers-promo-code-spec-form.js — same i18n key is rendered under the AUTO_GENERATED_SPEAKERS_DISCOUNT_CODE branch; added the matching helper row there.
  • src/components/forms/promocode-form/__tests__/promocode-form.integration.test.js — new test cases (6 discount-code classes × label/helper assertions + helper-renders-when-unchecked).
  • doc/promo-code-apply-to-all-audience-restriction.md — dedicated spec.

AC5 wording note

The ClickUp acceptance criterion #5 says "submitting apply_to_all_ticket_types = true resolves to Audience = All only, regardless of frontend." No such payload field is sent — apply_to_all_tix is a UI-only flag and is stripped before the API call. The actual enforcement is on the backend at the entity level (canBeAppliedTo). See the companion summit-api PR. A hostile client cannot bypass — there's no field to forge.

Test plan

  • yarn test --watchAll=false src/components/forms/promocode-form/__tests__/promocode-form.integration.test.js — 38/38 pass
  • yarn test --watchAll=false --testPathPatterns="promocode|promo-code|methods" — 97/97 pass
  • Manual: against the dev stack (api.dev.fnopen.com, YOCO summit), opened the SUMMIT_DISCOUNT_CODE editor for promo 100OFF (1773). Label rendered as "Apply to all ticket types (Audience: All)"; helper-text row visible directly below the checkbox. A fresh navigation rendered the box checked (derived from empty ticket_types_rules) with Amount/Rate visible and no picker — confirming the UI-only flag round-trips. Unchecked → DiscountTicketTable picker appeared with all summit ticket types exposed (added a throwaway Audience=WithPromoCode type on YOCO and confirmed it appeared in the picker dropdown after a hard refresh).
  • Manual: against the dev stack, opened the speakers list page → bulk-select speaker → Send Email modal → set Promo Code Strategy to AUTO_GENERATED_SPEAKERS_DISCOUNT_CODE. Same label + helper rendered inside the modal's SpeakerPromoCodeSpecForm. Closes the coverage gap that no Jest test covers this form.

Notes

  • 7 pre-existing test failures in the repo are unrelated (actions.test.js, dropbox-sync-actions.test.js, edit-sponsor-page.test.js) — same failures present on origin/master baseline.

Summary by CodeRabbit

  • Updates
    • Improved clarity for the "Apply to all Ticket Types" promo code option with updated label text and new helper text explaining which ticket types are covered

Review Change Stack

Backend tightens canBeAppliedTo() so the implicit "apply to all" branch only
covers Audience = All ticket types (see companion API SDS). This change
updates the admin copy so the checkbox label and a new helper-text row name
the restriction explicitly. WithInvitation, WithoutInvitation, and
WithPromoCode ticket types must be opted in via the picker after saving.

No JS logic change — the apply_to_all_tix flag is and remains UI-only.

Refs: ClickUp 86b9vrpxp; companion summit-api branch
feat/promo-code-apply-to-all-audience-restriction
The `edit_promocode.apply_to_all_tix` i18n key is also rendered by
speakers-promo-code-spec-form.js under the AUTO_GENERATED_SPEAKERS_DISCOUNT_CODE
branch (a discount-code path). The label update from the prior commit lands
there too, so the same helper row belongs beneath that checkbox to keep the
admin clarity consistent across both forms.

Spec line citations updated to reflect the actual en.json position.

Refs: ClickUp 86b9vrpxp; Codex review of a694ada.
@caseylocker caseylocker self-assigned this May 11, 2026
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 11, 2026

📝 Walkthrough

Walkthrough

This PR adds specification-driven updates to the promo code form's "Apply to all Ticket Types" checkbox, including clarified copy, helper text explaining audience coverage behavior, and integration test assertions across the discount form, speakers discount form, and i18n keys.

Changes

Promo Code Apply-to-All UI Clarity Update

Layer / File(s) Summary
Specification and translation keys
doc/promo-code-apply-to-all-audience-restriction.md, src/i18n/en.json
Comprehensive spec document defines the goal, scope, approach, and concrete tasks. Updates the edit_promocode.apply_to_all_tix label and introduces edit_promocode.apply_to_all_tix_helper with guidance text explaining that only Audience = All ticket types are covered.
UI component helper text implementation
src/components/forms/promocode-form/forms/discount-base-pc-form.js, src/components/forms/speakers-promo-code-spec-form.js
Adds muted helper text beneath the "apply to all" checkbox in both the discount form and speakers discount form, wired to the new translation key. Reorders and adds necessary imports.
Integration test coverage for helper text
src/components/forms/promocode-form/__tests__/promocode-form.integration.test.js
New test assertions verify that both the checkbox label and helper-text row render correctly across multiple discount code variants, plus a regression case confirming helper visibility when the checkbox is unchecked.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~12 minutes

Suggested reviewers

  • smarcet
  • santipalenque

Poem

🐰 A checkbox speaks with clearer voice today,
Helper text joins the form's display,
"Audience All" gets its gentle say,
Tests confirm both label and helper stay,
Clarity blooms in every way! ✨

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'fix(promocode): clarify Apply-to-all scope (Audience: All only)' directly and specifically describes the main change: clarifying the UI copy and scope of the 'apply to all' checkbox to reflect that only Audience=All ticket types are covered, which is the primary intent across all file changes.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feature/promo-code-apply-to-all-audience-restriction

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@caseylocker caseylocker marked this pull request as ready for review May 12, 2026 15:48
@caseylocker caseylocker requested a review from smarcet May 12, 2026 15:49
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (2)
src/components/forms/speakers-promo-code-spec-form.js (1)

17-20: 💤 Low value

Style consistency improvement.

Adding semicolons to import statements improves code style consistency across the file.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/components/forms/speakers-promo-code-spec-form.js` around lines 17 - 20,
The import statements for Dropdown, Input, PromocodeInput, and TagInput are
missing semicolons; update each import line (the ones importing
"openstack-uicore-foundation/lib/components/inputs/dropdown",
"openstack-uicore-foundation/lib/components/inputs/text-input",
"openstack-uicore-foundation/lib/components/inputs/promocode-input", and
"openstack-uicore-foundation/lib/components/inputs/tag-input") to end with a
semicolon to match the file's style and maintain consistency.
src/components/forms/promocode-form/forms/discount-base-pc-form.js (1)

3-4: 💤 Low value

Minor: Import order adjustment.

The reordering of imports (Input before BasePCForm) appears to be alphabetical sorting. This is a minor style improvement bundled with the feature change.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/components/forms/promocode-form/forms/discount-base-pc-form.js` around
lines 3 - 4, The import order was changed so Input is imported before
BasePCForm; revert to the original logical ordering by placing BasePCForm before
Input to match project style (i.e., import BasePCForm from "./base-pc-form" then
import Input from
"openstack-uicore-foundation/lib/components/inputs/text-input"); update the
import sequence around the symbols BasePCForm and Input so only order changes
are made.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@src/components/forms/promocode-form/forms/discount-base-pc-form.js`:
- Around line 3-4: The import order was changed so Input is imported before
BasePCForm; revert to the original logical ordering by placing BasePCForm before
Input to match project style (i.e., import BasePCForm from "./base-pc-form" then
import Input from
"openstack-uicore-foundation/lib/components/inputs/text-input"); update the
import sequence around the symbols BasePCForm and Input so only order changes
are made.

In `@src/components/forms/speakers-promo-code-spec-form.js`:
- Around line 17-20: The import statements for Dropdown, Input, PromocodeInput,
and TagInput are missing semicolons; update each import line (the ones importing
"openstack-uicore-foundation/lib/components/inputs/dropdown",
"openstack-uicore-foundation/lib/components/inputs/text-input",
"openstack-uicore-foundation/lib/components/inputs/promocode-input", and
"openstack-uicore-foundation/lib/components/inputs/tag-input") to end with a
semicolon to match the file's style and maintain consistency.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: c0c365b5-6b5f-41be-800e-ae2f409a4317

📥 Commits

Reviewing files that changed from the base of the PR and between 4aada82 and cab35a3.

📒 Files selected for processing (5)
  • doc/promo-code-apply-to-all-audience-restriction.md
  • src/components/forms/promocode-form/__tests__/promocode-form.integration.test.js
  • src/components/forms/promocode-form/forms/discount-base-pc-form.js
  • src/components/forms/speakers-promo-code-spec-form.js
  • src/i18n/en.json

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant