-
Notifications
You must be signed in to change notification settings - Fork 22
Add the built-in WP REST API validation to CountryCodeTrait
to avoid errors when clearing all audience countries in the onboarding flow
#2003
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
…CountryCodeTrait`
… array is not empty for needed Controllers
…ed_locations` in CampaignControllerTest.php
Codecov Report
Additional details and impacted files@@ Coverage Diff @@
## develop #2003 +/- ##
===========================================
+ Coverage 57.5% 57.9% +0.4%
Complexity 4111 4111
===========================================
Files 456 456
Lines 17655 17658 +3
===========================================
+ Hits 10156 10224 +68
+ Misses 7499 7434 -65
Flags with carried forward coverage won't be shown. Click here to find out more.
|
$valid = rest_validate_request_arg( $countries, $request, $param ); | ||
|
||
if ( true !== $valid ) { | ||
return $valid; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd suggest renaming this as $validation_result
, $validation
or something like that. Since it can return a WP_Error object, hence is not "valid".
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Renamed in bdfb365.
* @param bool $check_supported_country Whether to check the country is supported. | ||
* @param mixed $countries An individual string or an array of strings. | ||
* @param Request $request The request to validate. | ||
* @param string $param The parameter name, used in error messages. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe we can add somewhere a short explanation of your findings of why rest_validate_request_arg
is not being called automatically.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added in 4eeffe8.
@@ -0,0 +1,109 @@ | |||
<?php |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe We can add some tests for:
- Countries with wrong format return Error
- Countries not supported can be added without errors.
@@ -0,0 +1,104 @@ | |||
<?php |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we test if in Same for |
Checking here, seems like it runs That rest_validate_request_arg runs the validation.
Seems like the dispatcher is calling |
Hi @eason9487 , the PR looks good to me. I tested it locally and I cannot see anymore the early error when no countries are selected. I left some checks I did after your findings. And some suggestions in regards test and some variable naming. Since the variable naming and the tests are not blockers, I will approve this in advance.
To say something one simple solution might be to just not call the endpoint if country codes are empty in the JS side and keep all of them as required (minItems 1) in the backend. |
…yCodeTrait::validate_country_codes`. Address: #2003 (comment)
…deTrait::validate_country_codes`. Address: #2003 (comment)
@puntope, thanks for the review.
About
Considering several controllers use
The intention of calling this API even if the countries array is empty on the UI side is to always remember the entered data during the onboarding flow, so that the user can continue with the previously entered data if they interrupt or refresh the onboarding flow. So I would think this solution would conflict with the purpose. |
Sorry, @puntope. A thing I mentioned in #2003 (comment) is incorrect. The POST |
Changes proposed in this Pull Request:
This PR solves a task of 📌 Clarify API error messages in #1993
Closes #1855
Originally, clearing the recipient country did not cause API errors. After #1327, the POST
/mc/target_audience
API was also validated by this check, which causes the auto-saving behavior in the onboarding flow to get errors.CountryCodeTrait
.BudgetRecommendationController
CampaignController
TargetAudienceController
andShippingTimeBatchController
.BudgetRecommendationController
test_create_campaign_empty_targeted_locations
in CampaignControllerTest.php📌 Please take a look at the Additional details for contexts and other solutions.
Screenshots:
Kapture.2023-06-28.at.15.09.40.mp4
Detailed test instructions:
Additional details:
About the validation mechanism of WP REST API
When extending the WP REST API, the mechanism of
validate_callback
andsanitize_callback
is somewhat surprising. In summary, the findings are:sanitize_callback
is not specified buttype
is specified, both built-invalidate_callback
andsanitize_callback
will be applied no matter whether thevalidate_callback
is a custom one.validate_callback
andsanitize_callback
are specified with custom callbacks, the built-in schema validation won't be applied.validate_callback
may be applied two times if not specify both callbacks.validate_callback
is skipped, therequired
specified inargs
will still work. This makes the validation options ofargs
work or not, resulting in more unexpected inconsistencies.args
that when a customvalidate_callback
is specified, still uses the built-in schema validation.This can be a bit confusing to use because the main goal of
sanitize_callback
doesn't seem to be data validation, but whether the built-in schema validation works in the end depends onsanitize_callback
and not justvalidate_callback
.Why the current solution: Add the built-in validation to
CountryCodeTrait
When dealing with this issue, I have thought about other possible solutions, and the reasons for choosing the current one so far are:
minItems
anduniqueItems
for country codes, but these have not really worked in the past. This solution will allow them to work together as well.But I still have some doubts about whether doing so within
CountryCodeTrait
is too subtle and becomes inconsistent at a higher level concept.Other possible solutions
CountryCodeTrait::validate_country_codes
and to all related callers.get_country_code_and_allow_empty_validate_callback
toCountryCodeTrait
.validate_callback
inTargetAudienceController
with an additional process: Whencountries
is found to be empty, skip calling to the validation function returned byget_country_code_validate_callback
.sanitize_callback
from allCountryCodeTrait::validate_country_codes
-related callers so that the built-invalidate_callback
will be applied./mc/target_audience
to create audience countries instead of a PUT like the one defined in the RESTful API.Changelog entry