TangibleInc / template-system

A template system for WordPress with content type loops and conditions
https://docs.loopsandlogic.com/reference/template-system/
8 stars 3 forks source link

Framework: Ajax module - Remove exit after wp_send_json_success/error #112

Closed nicolas-jaussaud closed 6 months ago

nicolas-jaussaud commented 6 months ago

Hi!

This pull request remove the exit after wp_send_json_success() and wp_send_json_error() in the ajax module

I would like to remove it so that it can be bypassed more easily in tests. Here is the function I'm using to test ajax actions currently (from here):

function test_ajax_action( string $name, array $args = [] ) : array {

  $_POST['nonce'] = \tangible\ajax\create_nonce(); 
  $_POST['data'] = $args;

  add_filter( 'wp_doing_ajax', '__return_true', 10 );
  add_filter( 'wp_die_ajax_handler', $filter = function() { return function() {}; }, 10 );

  ob_start();
  do_action( 'wp_ajax_tangible_ajax_' . $name );
  $response = ob_get_clean();

  remove_filter( 'wp_doing_ajax', '__return_true', 10 );
  remove_filter( 'wp_die_ajax_handler', $filter, 10 );

  unset( $_POST['nonce'] ); 
  unset( $_POST['data'] ); 

  return json_decode( $response, true );
}

I initially wanted to replace it with wp_die(), but it seems to be already called at the end of wp_send_json() when doing ajax

If it's not possible to remove the exits or if that would make more sense, I can also update the pull request and use exit only when DOING_TANGIBLE_TEST is not defined, or add our own filter so that it can still be bypassed

eliot-akira commented 6 months ago

Thanks for the pull request!

I see what you mean about wp_send_json(). When doing AJAX it calls wp_die instead of die. And wp_die has two filters (here), wp_die_ajax_handler and wp_die_json_handler, which let our tests override die with an empty function.

OK, I understand, these exit statements are unnecessary. Any existing AJAX actions should be fine, logically they always return after calling ajax\success() or ajax\error().

So I'll merge this.


On a related topic, I recently started exploring wp-now using Playground (PHP-WASM/SQLite on Node) for integration tests (rough draft here) instead of wp-env using Docker. It's much faster to boot up a temporary WordPress site for testing, and lets me write tests that interact with the site using TypeScript and REST API. Very convenient.

eliot-akira commented 6 months ago

For reference, I'm using a tool called git-subrepo to push/pull changes to the Framework module in its own repository.

(Originally it was a Git extension using Bash which I wrapped as a standalone NPM package @tangible/git-subrepo. I may rewrite it in JavaScript so it can run cross-platform without Bash.)

To push new changes to the Framework, I ran:

$ npm run subrepo push framework

Subrepo 'framework' pushed to 'git@github.com:TangibleInc/framework.git' (main).

What I like with this workflow is that its commit history is updated also.

So far this tool is working well for managing nested Git repositories, the way I imagine the project organization, the framework and modules. Ideally any module can be turned into a sub-project with a Git repo to develop/test/publish on its own.

nicolas-jaussaud commented 6 months ago

Thank you for merging!

On a related topic, I recently started exploring wp-now using Playground (PHP-WASM/SQLite on Node) for integration tests (rough draft here) instead of wp-env using Docker. It's much faster to boot up a temporary WordPress site for testing, and lets me write tests that interact with the site using TypeScript and REST API. Very convenient.

I'm very excited to try that!

It looks like I could use a very similar logic to test ajax actions more realistically. I think I'm going to keep the tests as they are for now, as the ajax actions I'm testing are themselves doing requests to a third party api (like here for example), and I'm not sure how I could deal with that

I have been very curious about wordpress playground since you created play.tangible.one, and reading the recent thread you started about wordpress studio made me really want to learn more about it!

I was thinking that maybe I could try to use it for the fields documentation at some point, as it could be transitioned from being inside the fields-example plugin to just markdown files with iframes for the examples (with the code and a live preview)

It would be very cool to be able to edit the code directly from the documentation page and immediately see the results, and it would be close to what you did for play.tangible.one so I could use your work as an example

eliot-akira commented 6 months ago

Playground has documentation for developers with helpful info on how it works, and how to embed custom WordPress sites. I wrote the page, Host your own Playground, when I was figuring out how to do it. I've been making a few pull requests to contribute/participate, because I find it fascinating, an advanced use case of WebAssembly and overall a great example of how to run an open-source community project.

From when I created play.tangible.one as a first draft, Playground has evolved significantly. At the time the site's code was written, it was necessary to fork the Playground and customize its Docker pipeline to generate a binary .data file for a custom site with bundled plugin.

Now there's a better way, it can start a custom site from a zip file URL. So I've been meaning to refresh the site, and continue developing fun features like shareable snippets. I wrote a library called Base64 Compressor for this purpose, to export a template post and compress it as URL-safe base64 string.


In the Loops & Logic docs, a React static site using Docusaurus, I started a Playground component for runnable code examples.

Not quite ready yet, but you can see some interesting use of "blueprints" to install the Template System from GitHub, and create a little plugin that overrides the theme to render template posts. It's weird being able to run PHP and automate WordPress with JavaScript in the browser.


With wp-now, I'm finding it refreshing and easy to automate WordPress on the server side with Node and TypeScript. I'm thinking of adding a minimal testing library to the Framework for common setup and utility functions.

wp-now-testra-example

I started to write tests for a REST API in the Framework using wp-now and fetch. The API module will be similar to the AJAX module but using standard fetch instead of jQuery.ajax. It will have a registry of actions and the same interface, like api\success() and api\error(). In the screenshot I'm using a new run command added to the Roller - similar to a tool called tsx, it compiles the given TypeScript file and runs it. It's a nice workflow.

I'll try to create an "overview" issue for some of these topics, so we can discuss them further - especially about modules in the Framework which are meant to be useful for all our plugins. Please feel free to add if you have any thoughts or questions.