Skip to content
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

Force Standard mode when fetching scannable URLs in Wizard #6683

Merged
merged 32 commits into from
Nov 5, 2021

Conversation

delawski
Copy link
Collaborator

@delawski delawski commented Nov 3, 2021

Summary

Fixes #6650
Fixes #6692

This PR fixes an issue described in #6650 (comment):

[ ... ] When legacy Reader mode is initially selected (as it currently is by default), the Site Scan in the onboarding wizard is only scanning the URLs that are available in legacy Reader mode (singular posts, pages, and attachments). In reality, since we're forcing Standard mode in the onboarding wizard's Site Scan, we should be obtaining the scannable URLs for Standard mode as well. Then once the user saves the settings in the onboarding wizard, the scannable URLs should be re-fetched without any option overrides to obtain the URLs to show for the site preview on the Done screen.

A new argument is introduced to the /amp/v1/scannable-url endpoint: force_standard_mode. When it is set to true, the Standard template mode will be used for generating a list of scannable URLs.

This update allows us to fetch a correct set of URLs needed in the Site Scan step of the Onboarding Wizard.

Whenever AMP settings are saved, a new set of scannable URLs is fetched. This way we can guarantee that only relevant pages are listed in last step of the Wizard (the Review panel).


Update

This PR has been updated with a fix to #6692. The amp-first query parameter has been dropped in favour of amp_validate[force_standard_mode]=1. Moreover, the Site Scan in the Wizard will cache the validation results. This way, if a user selects the Standard mode in the Wizard, they will not see the "Stale results" notice on the Settings screen anymore.

Also, when landing on the AMP Settings screen after completing the Onboarding Wizard, a scan-if-stale query parameter is added to the URL. If the scan results are stale, a site scan will be initiated automatically and the query parameter will be removed from the URL.

Checklist

  • My code is tested and passes existing tests.
  • My code follows the Engineering Guidelines (updates are often made to the guidelines, check it out periodically).

@github-actions
Copy link
Contributor

github-actions bot commented Nov 3, 2021

Plugin builds for ee32eb7 are ready 🛎️!

Comment on lines -235 to -245
useEffect( () => {
if ( status ) {
return;
}

if ( ! validateNonce ) {
throw new Error( 'Invalid site scan configuration' );
}

dispatch( { type: ACTION_SCANNABLE_URLS_REQUEST } );
}, [ status, validateNonce ] );
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since the scannable URLs are now fetched in a different way, there was no reason to keep the useEffect. The validateNonce check can be done directly in the context provider body.

Comment on lines 125 to 137
// Allow query parameter to force a response to be served with Standard mode (AMP-first). This is used as
// part of Site Scanning in order to determine if the primary theme is suitable for serving AMP.
if ( ! amp_is_canonical() && $request->get_param( 'force_standard_mode' ) ) {
add_filter(
'option_' . AMP_Options_Manager::OPTION_NAME,
function ( $options ) {
$options[ Option::THEME_SUPPORT ] = AMP_Theme_Support::STANDARD_MODE_SLUG;

return $options;
}
);
}

Copy link
Collaborator Author

@delawski delawski Nov 3, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is very much inspired by a similar filter introduced in #6615.

I was trying to write a unit test for that but I couldn't get the option filter to actually override the template mode (even though it works as expected on the live site). After adding the following test to the ScannableURLsRestControllerTest.php, I was still getting just 2 scannable URLs (the assertGreaterThan assertion failed):

b/tests/php/src/Validation/ScannableURLsRestControllerTest.php
--- a/tests/php/src/Validation/ScannableURLsRestControllerTest.php	(revision 2540a67282420840f4c6cf109dc960b3db589970)
+++ b/tests/php/src/Validation/ScannableURLsRestControllerTest.php	(date 1635969779679)
@@ -142,6 +142,14 @@
 				$this->assertNull( $scannable_url_entry['stale'] );
 			}
 		}
+
+		// Test `force_standard_mode` query parameter.
+		$request_with_forced_standard_mode  = new WP_REST_Request( 'GET', '/amp/v1/scannable-urls', [ 'force_standard_mode' => true ] );
+		$response_with_forced_standard_mode = rest_get_server()->dispatch( $request_with_forced_standard_mode );
+
+		$this->assertFalse( $response_with_forced_standard_mode->is_error() );
+		$scannable_urls_in_standard_mode = $response_with_forced_standard_mode->get_data();
+		$this->assertGreaterThan( 2, count( $scannable_urls_in_standard_mode ), 'Expected more than two URLs since in Standard mode.' );
 	}
 
 	/**

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's probably because the options are cached in a member variable:

private function get_options() {
if ( null === $this->options ) {
$this->options = array_merge(
AMP_Options_Manager::get_options(),
$this->option_overrides
);
}
return $this->options;
}

I determined this was indeed the case, but there was also a secondary cause: when an option is not set in the DB, the option_{$option_name} filter does not apply. Instead, the default_option_{$option_name} applies. In the context of the unit tests, the option is not set here, so that is also why it was failing.

As opposed to a filter, I was originally thinking that ScannableURLProvider could have a set_options method that would allow you to override the options used for scanning. However, I see that this will not fully work because amp_is_post_supported() does not consider the options stored in ScannableURLProvider but rather the options stored in the DB.

So it seems filters are the way to go, and to remove any caching in ScannableURLProvider.

Oh, and a third reason this doesn't work is the [ 'force_standard_mode' => true ] was being passed in as the $attributes and not as params. I believe it should have been done as follows:

// Test `force_standard_mode` query parameter.
$request_with_forced_standard_mode = new WP_REST_Request( 'GET', '/amp/v1/scannable-urls' );
$request_with_forced_standard_mode->set_param( 'force_standard_mode', 'true' );

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've addressed these concerns in bf243ab and 4c8d969.

@delawski
Copy link
Collaborator Author

delawski commented Nov 3, 2021

Note that the failing E2E tests should be fixed in #6675. Once it's approved and merged, develop can be merged back to this branch and the CI error should be gone.

…cannable-urls-force-standard-mode

* 'develop' of github.com:ampproject/amp-wp: (23 commits)
  Use exact match for gutenberg slugs
  Bump axios from 0.21.1 to 0.24.0
  Bump @babel/core from 7.15.8 to 7.16.0
  Update `package-lock.json`
  Further harmonize themes and plugins API filtering
  Reuse obtained plugins array and count
  Increase JS unit test coverage
  Clean up Validated URLs index before some E2E tests
  Use XPath in E2E test to ensure iframe src has been updated
  Fix pagination of AMP-compatible theme list page
  Fix pagination of AMP-compatible plugins list page
  Bump eslint-plugin-jsdoc from 36.1.1 to 37.0.3
  Bump svgo from 2.7.0 to 2.8.0
  Bump lint-staged from 11.2.3 to 11.2.6
  Bump postcss from 8.3.9 to 8.3.11
  Treat shortcode error like plugin and omit Gutenberg
  Bump @babel/plugin-proposal-class-properties from 7.14.5 to 7.16.0
  Update Gutenberg package dependencies
  Bump eslint-plugin-import from 2.24.2 to 2.25.2
  Move setup code to `beforeAll` lifecycle hook
  ...
@westonruter westonruter added this to the v2.2 milestone Nov 4, 2021
@westonruter
Copy link
Member

westonruter commented Nov 4, 2021

Alas, no:

image

@westonruter
Copy link
Member

westonruter commented Nov 4, 2021

@delawski What about the change to replace amp-first with amp_validate[force_standard_mode]=1 and then to cache the site scan results when in the Onboarding Wizard so that by chance if they selected Standard mode the results would not be stale? We should still automatically initiate a scan after leaving the onboarding wizard in case Standard mode was not selected. I don't think we have an issue for this yet, but all of this could be tackled together there.

Update: See #6692.

@delawski
Copy link
Collaborator Author

delawski commented Nov 5, 2021

Er, but then it may have been removed by the time that hasQueryArg checks for it above.

Yes, we need to read it on the client side so that the site scan can be initiated.

@westonruter
Copy link
Member

I found an issue with the Done screen:

image

  1. Set template mode to Transitional.
  2. Initiated site scan from Settings Screen
  3. Opened wizard
  4. Passed through Site Scan (which scanned 8 URLs as expected)
  5. Switched template mode to Reader
  6. Selected LEGACY thene.
  7. Problem: I see URLs on the Done screen which are not available in Reader mode, like the Category and Date archives.

The problem is that after the options are saved, the force_standard_mode parameter is still being passed to the scannable-urls endpoint:

/wp-json/amp/v1/scannable-urls?_fields%5B0%5D=url&_fields%5B1%5D=amp_url&_fields%5B2%5D=type&_fields%5B3%5D=label&force_standard_mode=1&_locale=user

This parameter should only be present when opening the Wizard. Once the options have been saved and the user is at the Done screen, the parameter should be omitted.

@westonruter
Copy link
Member

Yes, we need to read it on the client side so that the site scan can be initiated.

It's still initially available client-side. WordPress core uses the same replaceState method to scrub removable query vars. See wp_admin_canonical_url().

But that would run earlier than our code, so it would break things.

@delawski
Copy link
Collaborator Author

delawski commented Nov 5, 2021

The problem is that after the options are saved, the force_standard_mode parameter is still being passed to the scannable-urls endpoint:

/wp-json/amp/v1/scannable-urls?_fields%5B0%5D=url&_fields%5B1%5D=amp_url&_fields%5B2%5D=type&_fields%5B3%5D=label&force_standard_mode=1&_locale=user

This parameter should only be present when opening the Wizard. Once the options have been saved and the user is at the Done screen, the parameter should be omitted.

This has been addressed in e464460

@westonruter
Copy link
Member

Witn ee32eb7 the run time of PHPUnit tests is reduced by 5 seconds.

@westonruter westonruter merged commit d903d69 into develop Nov 5, 2021
@westonruter westonruter deleted the feature/scannable-urls-force-standard-mode branch November 5, 2021 22:47
@milindmore22
Copy link
Collaborator

QA Passed
Wizard Site Scanner is forcing Standard Mode with force_standard_mode parameter as observed in the request.
https://amp-local.test/?amp_validate%5Bcache%5D=true&amp_validate%5Bcache_bust%5D=0.7579931808456741&amp_validate%5Bforce_standard_mode%5D=true&amp_validate%5Bnonce%5D=09a867751491632767b4438b9019d1ae&amp_validate%5Bomit_stylesheets%5D=true

@westonruter westonruter added the Changelogged Whether the issue/PR has been added to release notes. label Dec 15, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Changelogged Whether the issue/PR has been added to release notes. Site Scanning
Projects
None yet
4 participants