feat(multivariate): reserve "control" as a variant key#7725
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub. 3 Skipped Deployments
|
Docker builds report
|
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #7725 +/- ##
=======================================
Coverage 98.54% 98.54%
=======================================
Files 1452 1452
Lines 55757 55770 +13
=======================================
+ Hits 54947 54960 +13
Misses 810 810 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
Playwright Test Results (oss - depot-ubuntu-latest-16)Details
Playwright Test Results (oss - depot-ubuntu-latest-arm-16)Details
Playwright Test Results (private-cloud - depot-ubuntu-latest-arm-16)Details
Playwright Test Results (private-cloud - depot-ubuntu-latest-16)Details
Playwright Test Results (oss - depot-ubuntu-latest-16)Details
Playwright Test Results (oss - depot-ubuntu-latest-arm-16)Details
Playwright Test Results (private-cloud - depot-ubuntu-latest-16)Details
Playwright Test Results (private-cloud - depot-ubuntu-latest-arm-16)Details
|
Visual Regression19 screenshots compared. See report for details. |
"control" is the variant reported by the SDK when an identity falls through to the base value, so it must not also be usable as an explicit multivariate option key. Reject it at the mv-options endpoint via a `validate_key` field-level validator (whitespace/format is already handled upstream by the field's slug validator), with the message defined as a reusable constant.
8554f73 to
01a34c6
Compare
docs/if required so people know about the feature. (deferred — see feat(multivariate): report variant key on identities flag responses #7723.)Changes
"control"is the variant the SDK reports when an identity falls through to the base value (see #7723), so it must not also be usable as an explicit multivariate option key — otherwise a real variant and the control group would be indistinguishable in experimentation data.This rejects
"control"at the multivariate-options endpoint:MultivariateFeatureOptionSerializer.validate_keyraises a400when the key equalsCONTROL_VARIANT_KEY.RESERVED_VARIANT_KEY_MESSAGEinfeatures/constants.py(matching the codebase's*_MESSAGEconvention).keyfield'svalidate_slugvalidator already rejects any whitespace/non-slug input beforevalidate_keyruns, so only a clean"control"can reach the check. The check is exact-match (case-sensitive) —"Control"is a distinct slug and doesn't collide with the lowercase fall-through value.Scoped to the writable path only:
keyis read-only on the nested serializer (feature-creation path), so the dedicated mv-options endpoint is the only place a key can be set.How did you test this code?
tests/integration/features/multivariate/): creating an mv option withkey="control"returns400with the reserved-key message; non-reserved keys (e.g."variant-a") still succeed. Existing key tests that incidentally used"control"were updated to a non-reserved key.Local verification:
tests/unit/features/multivariate/+tests/integration/features/multivariate/: 60 passed.ruff checkandmypy(strict): clean.