-
Notifications
You must be signed in to change notification settings - Fork 3
Plugins endpoint #90
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
Plugins endpoint #90
Conversation
My understanding is all endpoints' |
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.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
author
seems 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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
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 something like 4317929?
Active, | ||
#[serde(rename = "inactive")] | ||
Inactive, | ||
} |
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.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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?
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.
} | ||
} | ||
|
||
pub fn retrieve_plugin_request(&self, context: WPContext, plugin: &str) -> WPNetworkRequest { |
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.
You mentioned introducing PluginSlug
& WpOrgPluginSlug
types. Will the plugin: &str
be replaced by one of those types?
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.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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)
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.
Approving to unblock.
Active, | ||
#[serde(rename = "inactive")] | ||
Inactive, | ||
} |
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.
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
/plugins
endpoint variants - except for filtering. It closely follows the/users
implementation, so there isn't too much that's completely new.backup-wp-content-plugins
,restore-wp-content-plugins
&delete-wp-plugins-backup
Make tasks. For most of our integration tests, restoring the DB to a previous state will be enough. However, with/plugins
the filesystem is also involved, so we need new helpers just for/plugins
integration tests.test_helpers::run_and_restore_wp_content_plugins
function. This is similar towp_db::run_and_restore
function, providing a convenient way to handle the restoration ofwp-contents/plugins
folder from a backup using theMake
task.create
,delete
&update
plugin tests are a little fragile at the moment. They require the test site to havehello-dolly
andclassic-editor
plugins 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
/plugins
endpoint will be infoo/bar
format, for examplehello-dolly/hello
&classic-editor/classic-editor
foo
format:hello-dolly
&classic-editor
These discrepancies could become a headache for the consumers, so I think we might want to introduce
PluginSlug
&WpOrgPluginSlug
types 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-editor
as opposed to something like/plugins?slug=classic-editor%2Fclassic-editor
where the/
character is encoded. To handle this, theplugins_url_with_slug
helper function will first split the given slug using/
as the separator, and then use it to extend the url.Incorrect(?) documentation
author
seems to return aString
as opposed to aJSONObject
.Both
update
&delete
endpoints' documentation claims that thecontext
argument 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 thecontext
parameter, both as a query pair as well as part of the JSON body of thePOST
request 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: View
in the JSON body and got an error back sayingcontext
is not one ofedit
,embed
&view
values.To avoid confusion, I've decided not to include the
context
parameter for these endpoints.Note that one small discrepancy with
plugins
implementation, compared to/users
is that I've decided to include specific parsers forcreate
&update
endpoints - as opposed to using the parser forretrieve
response. I'd like to go back and change/users
as 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-plugins
cargo test --test '*' -- --nocapture --test-threads 1
What Next
WPApiHelper