Conversation
My understanding is all endpoints' |
crazytonyli
left a comment
There was a problem hiding this comment.
It'd be good to address the potential issue of parsing a unknown PluginStatus.
| plugin_slug, | ||
| parsed_response | ||
| ); | ||
| } |
There was a problem hiding this comment.
authorseems to return a String as opposed to a JSONObject.
What do you think about adding tests for the author property, so that we can be sure that it's indeed a documentation error (rather than a breaking change in the API)?
There was a problem hiding this comment.
The current tests should already cover this as it retrieving plugins would fail with ParsingError if we got a json object instead of the expected String type.
Happy to add more tests if you have anything specific in mind.
Any chance you were thinking that author field was part of a {foo}Params} type, rather than a return type like the SparsePlugin? 😅 That's not the case, but if it was, I agree it would have been good to add a test that utilized that parameter.
There was a problem hiding this comment.
I was thinking adding an explicit check which asserts author is a certain string, not even not nil.
| self.api_base_url | ||
| // The '/' character has to be preserved and not get encoded | ||
| .by_extending(["plugins"].into_iter().chain(plugin.split('/'))) | ||
| } |
There was a problem hiding this comment.
There was an issue in iOS app where the app crashed due to unexpected characters in plugin slug. See wordpress-mobile/WordPressKit-iOS#767.
I couldn't reproduce the crash, because I can't find a real-world plugin that has a non-ascii slug. However, I think it's still worthy adding some unit tests to ensure a correct URL is constructed for strange plugin slugs (i.e. has % or non-ascii charaectrs). What do you think?
There was a problem hiding this comment.
I've added a few more tests for this in b189438. It'd be really good if we can find a real world case for it though.
| Active, | ||
| #[serde(rename = "inactive")] | ||
| Inactive, | ||
| } |
There was a problem hiding this comment.
If a new plugin status is added in a newer WordPress version, will that cause parser errors in this library, because status in contextual models (i.e. PluginWithViewContext) is non-optinal? What do you think adding a "unknown" case here?
There was a problem hiding this comment.
@jkmassel could correct me if I am wrong, but I think one of the promises with WordPress.org REST API is that it'll remain backward compatible. So, I don't think we should make things harder for ourselves by taking breaking changes into account.
I don't like the idea of adding an Unknown variant for this - as that'll become a precedent and we'll have to start adding it everywhere else. I'd rather our library break in such an edge case - which I don't think will ever happen for PluginStatus to be honest.
There was a problem hiding this comment.
one of the promises with WordPress.org REST API is that it'll remain backward compatible.
I believe adding another value (for example, "status": "activating") to an existing property is still "backward compatible". But our library won't be able to parse that response, which introduces issues to the consumer apps.
I'd rather our library break in such an edge case - which I don't think will ever happen for PluginStatus to be honest.
I just checked the source code. I don't know how to reproduce such a case, but I believe the code says status can also be network-active. https://github.com/WordPress/WordPress/blob/6.5.3/wp-includes/rest-api/endpoints/class-wp-rest-plugins-controller.php#L898
There was a problem hiding this comment.
That's for multisites, and although we don't plan to directly support them, I see your point.
I still don't like the idea of building separate fallbacks for every enum we add. So, I was thinking maybe we should generalize the Recognized / Unrecognized approach that we used for errors - hopefully in a little bit better way, so we can use it everywhere?
There was a problem hiding this comment.
Do you mind creating an issue to track this issue of parsing the status property, if it's not going to be addressed in this PR?
| } | ||
| } | ||
|
|
||
| pub fn retrieve_plugin_request(&self, context: WPContext, plugin: &str) -> WPNetworkRequest { |
There was a problem hiding this comment.
You mentioned introducing PluginSlug & WpOrgPluginSlug types. Will the plugin: &str be replaced by one of those types?
There was a problem hiding this comment.
Yeap, this is one of the cases where it's not clear which type of slug it should take. (It's the PluginSlug in this example, just as a reference)
|
Thanks for the review @crazytonyli. I added some more unit tests as you suggested and replied to your other comments. Ready for another look! 🙇♂️ |
| pub fn update_plugin_request( | ||
| &self, | ||
| plugin: &str, | ||
| params: PluginUpdateParams, |
There was a problem hiding this comment.
This should be:
| params: PluginUpdateParams, | |
| params: &PluginUpdateParams, |
It's addressed in a later PR, but I won't include it here to avoid the extra merge conflict. (as I have multiple PRs building on one another)
crazytonyli
left a comment
There was a problem hiding this comment.
Approving to unblock.
| Active, | ||
| #[serde(rename = "inactive")] | ||
| Inactive, | ||
| } |
There was a problem hiding this comment.
Do you mind creating an issue to track this issue of parsing the status property, if it's not going to be addressed in this PR?
|
Thanks @crazytonyli! 🙇♂️ |
Implements the
/pluginsendpoint variants - except for filtering. It closely follows the/usersimplementation, so there isn't too much that's completely new.backup-wp-content-plugins,restore-wp-content-plugins&delete-wp-plugins-backupMake tasks. For most of our integration tests, restoring the DB to a previous state will be enough. However, with/pluginsthe filesystem is also involved, so we need new helpers just for/pluginsintegration tests.test_helpers::run_and_restore_wp_content_pluginsfunction. This is similar towp_db::run_and_restorefunction, providing a convenient way to handle the restoration ofwp-contents/pluginsfolder from a backup using theMaketask.create,delete&updateplugin tests are a little fragile at the moment. They require the test site to havehello-dollyandclassic-editorplugins to be installed. (one being active, the other inactive) I am considering adding specific Make tasks to ensure a specific state before running these tests, but I'd like to split that into its own PR - if I do implement it.There has been several annoying issues in this implementation:
Plugin Slugs
/pluginsendpoint will be infoo/barformat, for examplehello-dolly/hello&classic-editor/classic-editorfooformat:hello-dolly&classic-editorThese discrepancies could become a headache for the consumers, so I think we might want to introduce
PluginSlug&WpOrgPluginSlugtypes to clearly differentiate them in our API. I'd like to do this in its own PR.Furthermore, most of the endpoints expect the plugin slug to be part of the url and not the query pairs. So, for example with
classic-editor, the proper retrieve request url would be/plugins/classic-editor/classic-editoras opposed to something like/plugins?slug=classic-editor%2Fclassic-editorwhere the/character is encoded. To handle this, theplugins_url_with_slughelper function will first split the given slug using/as the separator, and then use it to extend the url.Incorrect(?) documentation
authorseems to return aStringas opposed to aJSONObject.Both
update&deleteendpoints' documentation claims that thecontextargument will determine which fields will be in the response, however it seems it always returns the fields foredit. (which contains all the fields) I've tried this by sending thecontextparameter, both as a query pair as well as part of the JSON body of thePOSTrequest and in both cases, I got all the fields back. I might have made a mistake in my testing, but I have some confidence that this is correct, because while testing I accidentally sentcontext: Viewin the JSON body and got an error back sayingcontextis not one ofedit,embed&viewvalues.To avoid confusion, I've decided not to include the
contextparameter for these endpoints.Note that one small discrepancy with
pluginsimplementation, compared to/usersis that I've decided to include specific parsers forcreate&updateendpoints - as opposed to using the parser forretrieveresponse. I'd like to go back and change/usersas well to follow this pattern to make it easier to find the correct parser for each response. This will add a few "unnecessary" functions, but I think it's worth it.To Test
make test-server && make dump-mysql && make backup-wp-content-pluginscargo test --test '*' -- --nocapture --test-threads 1What Next
WPApiHelper