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

Update support request flow. #6627

Merged
merged 27 commits into from
Oct 18, 2021
Merged

Conversation

dhaval-parekh
Copy link
Collaborator

@dhaval-parekh dhaval-parekh commented Sep 29, 2021

Summary

Amends #6147

Related: #5939

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 Sep 29, 2021

Plugin builds for 4fe6689 are ready 🛎️!

@dhaval-parekh dhaval-parekh changed the title Support request flow. Add test cases for support request CLI. Sep 29, 2021
@pierlon pierlon force-pushed the feature/5939-support-request-flow branch from 44b3b42 to 363d8dc Compare September 30, 2021 05:47
@@ -0,0 +1,27 @@
Feature: AMP Support Request
Copy link
Contributor

Choose a reason for hiding this comment

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

It would be great to also test data for a validated URL is in the output as well.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

To test validated URLs we need to mock those. (Like done previouslly ) But it's not the case here.

@pierlon
Copy link
Contributor

pierlon commented Sep 30, 2021

(Sorry pushed to the wrong branch in #6627 (comment)).

There's a few more issues in #6147 to fix (which is why #5939 was re-opened), so this PR shouldn't close the issue just yet.

@maitreyie-chavan maitreyie-chavan added this to the v2.2 milestone Oct 1, 2021
@maitreyie-chavan maitreyie-chavan linked an issue Oct 3, 2021 that may be closed by this pull request
@dhaval-parekh dhaval-parekh self-assigned this Oct 5, 2021
@dhaval-parekh
Copy link
Collaborator Author

This PR also addresses feedbacks from PR #6147.

@dhaval-parekh dhaval-parekh requested a review from pierlon October 7, 2021 09:39
@pierlon pierlon mentioned this pull request Oct 7, 2021
2 tasks
@@ -170,8 +173,8 @@ public function enqueue_assets( $hook_suffix ) {
];
}

$this->support_data->set_args( $args );
$data = $this->support_data->get_data();
$support_data = $this->injector->make( SupportData::class, [ 'args' => $args ] );
Copy link
Contributor

Choose a reason for hiding this comment

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

After taking a closer look, I think instantiating SupportData via the injector makes things overly complicated. Directly creating a SupportData object should be simple enough here, and therefore there would be no need for Injector.

Suggested change
$support_data = $this->injector->make( SupportData::class, [ 'args' => $args ] );
$support_data = new SupportData( $args );

Copy link
Member

Choose a reason for hiding this comment

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

Another alternative:

Suggested change
$support_data = $this->injector->make( SupportData::class, [ 'args' => $args ] );
$support_data = $this->injector->make( SupportData::class, compact( 'args' ) );

Comment on lines +176 to +177
$support_data = $this->injector->make( SupportData::class, [ 'args' => $args ] );
$data = $support_data->get_data();
Copy link
Contributor

Choose a reason for hiding this comment

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

Alternatively, to get the data in one line:

Suggested change
$support_data = $this->injector->make( SupportData::class, [ 'args' => $args ] );
$data = $support_data->get_data();
$data = ( new SupportData( $args ) )->get_data();

@@ -106,8 +111,8 @@ public function send_diagnostic( /** @noinspection PhpUnusedParameterInspection
'is_synthetic' => $is_synthetic,
];

$this->support_data->set_args( $args );
$data = $this->support_data->get_data();
$support_data = $this->injector->make( SupportData::class, [ 'args' => $args ] );
Copy link
Contributor

Choose a reason for hiding this comment

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

Same suggestion as above, creating the SupportData object should be simple enough.

Suggested change
$support_data = $this->injector->make( SupportData::class, [ 'args' => $args ] );
$support_data = new SupportData( $args );

@@ -476,11 +450,7 @@ public static function normalize_error( $error_data ) {

$error_data['text'] = ( ! empty( $error_data['text'] ) ) ? trim( $error_data['text'] ) : '';

$error_data = wp_json_encode( $error_data );
$error_data = static::remove_domain( $error_data );
Copy link
Contributor

Choose a reason for hiding this comment

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

Any reason for overloading the remove_domain() method and not just iterating over the error data and calling remove_domain() on each value?

Suggested change
$error_data = static::remove_domain( $error_data );
foreach ( $error_data as $key => $value ) {
$error_data[ $key ] = self::remove_domain( $value );
}

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Internally self::remove_domain() will do the same thing if the provided value is an array. I kept that part in self::remove_domain() because $error_data can be multi-dimension array.

Copy link
Contributor

Choose a reason for hiding this comment

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

Ah I see. Not a fan of overloading remove_domain() and returning multiple data types however as that increases code complexity.

@@ -101,10 +103,10 @@ public function callback( WP_REST_Request $request ) {
$request_args = $request->get_param( 'args' );
$request_args = ( ! empty( $request_args ) && is_array( $request_args ) ) ? $request_args : [];

$this->support_data->set_args( $request_args );
$support_response = $this->support_data->send_data();
$support_data = $this->injector->make( SupportData::class, [ 'args' => $request_args ] );
Copy link
Contributor

Choose a reason for hiding this comment

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

Same suggestion as above, creating the SupportData object should be simple enough.

Suggested change
$support_data = $this->injector->make( SupportData::class, [ 'args' => $request_args ] );
$support_data = new SupportData( $args );

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Originally it was $support_data = new SupportData( $args );. I have used an injector after suggestions from the previous PR.

Copy link
Contributor

Choose a reason for hiding this comment

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

Hmm yea, but unless I'm missing something there's no benefit in creating the SupportData via the injector as its not a service or anything. cc @westonruter.

Copy link
Member

Choose a reason for hiding this comment

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

Another example of using the injector to create a class can be found in PairedRouting:

$structure_class = apply_filters( 'amp_custom_paired_url_structure', null );
if ( ! $structure_class || ! is_subclass_of( $structure_class, PairedUrlStructure::class ) ) {
$structure_slug = AMP_Options_Manager::get_option( Option::PAIRED_URL_STRUCTURE );
if ( array_key_exists( $structure_slug, self::PAIRED_URL_STRUCTURES ) ) {
$structure_class = self::PAIRED_URL_STRUCTURES[ $structure_slug ];
} else {
$structure_class = QueryVarUrlStructure::class;
}
}
$this->paired_url_structure = $this->injector->make( $structure_class );

While in practice it makes no difference, in theory the injector is better because this could reference an interface instead of an actual class, and the bindings defined in AmpWpPlugin could automatically route the class to instantiate. This could make it easier to test with a mock, as I understand.

Also, by using make the injector is able to re-use instances which are listed among the shared instances in AmpWpPlugin, which isn't possible otherwise.

So yeah, I understand from dependency injection that classes should generally not be instantiated directly.

cc @schlessera

Copy link
Contributor

Choose a reason for hiding this comment

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

Thanks for the explanation @westonruter. In this scenario we wouldn't be benefiting from using the injector, since the class being instantiated does not require any sort of dependency resolution and so would not make use of the bindings or shared instances provided by AmpWpPlugin. However, I do understand the benefits of using the injector with regards to testing especially, so after giving it more thought I'm OK with the current implementation.

@dhaval-parekh dhaval-parekh requested a review from pierlon October 14, 2021 16:07
@dhaval-parekh dhaval-parekh changed the title Add test cases for support request CLI. Update support request flow. Oct 14, 2021
@@ -89,7 +89,7 @@ export function AMPSupport( props ) {
{
__html: sprintf(
/* translators: %s is the URL to create a new support topic */
__( 'In order to best assist you, please submit the following information to our private database. Once you have done so, copy the the resulting support ID and mention it in a <a href="%s" rel="noreferrer" target="_blank">support forum topic</a>. You do not have to submit data to get support, but our team will be able to help you more effectively if you do so.', 'amp' ),
__( 'In order to best assist you, please click the Send Data button below to send the following site information to our private database. Once you have done so, copy the the resulting Support UUID in the blue box that appears and include the ID in a new <a href="%s" rel="noreferrer" target="_blank">support forum topic</a>. You do not have to submit data to get support, but our team will be able to help you more effectively if you do so.', 'amp' ),
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
__( 'In order to best assist you, please click the Send Data button below to send the following site information to our private database. Once you have done so, copy the the resulting Support UUID in the blue box that appears and include the ID in a new <a href="%s" rel="noreferrer" target="_blank">support forum topic</a>. You do not have to submit data to get support, but our team will be able to help you more effectively if you do so.', 'amp' ),
__( 'In order to best assist you, please tap the Send Data button below to send the following site information to our private database. Once you have done so, copy the the resulting Support UUID in the blue box that appears and include the ID in a new <a href="%s" rel="noreferrer" target="_blank">support forum topic</a>. You do not have to submit data to get support, but our team will be able to help you more effectively if you do so.', 'amp' ),

@@ -101,10 +103,10 @@ public function callback( WP_REST_Request $request ) {
$request_args = $request->get_param( 'args' );
$request_args = ( ! empty( $request_args ) && is_array( $request_args ) ) ? $request_args : [];

$this->support_data->set_args( $request_args );
$support_response = $this->support_data->send_data();
$support_data = $this->injector->make( SupportData::class, [ 'args' => $request_args ] );
Copy link
Member

Choose a reason for hiding this comment

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

Another example of using the injector to create a class can be found in PairedRouting:

$structure_class = apply_filters( 'amp_custom_paired_url_structure', null );
if ( ! $structure_class || ! is_subclass_of( $structure_class, PairedUrlStructure::class ) ) {
$structure_slug = AMP_Options_Manager::get_option( Option::PAIRED_URL_STRUCTURE );
if ( array_key_exists( $structure_slug, self::PAIRED_URL_STRUCTURES ) ) {
$structure_class = self::PAIRED_URL_STRUCTURES[ $structure_slug ];
} else {
$structure_class = QueryVarUrlStructure::class;
}
}
$this->paired_url_structure = $this->injector->make( $structure_class );

While in practice it makes no difference, in theory the injector is better because this could reference an interface instead of an actual class, and the bindings defined in AmpWpPlugin could automatically route the class to instantiate. This could make it easier to test with a mock, as I understand.

Also, by using make the injector is able to re-use instances which are listed among the shared instances in AmpWpPlugin, which isn't possible otherwise.

So yeah, I understand from dependency injection that classes should generally not be instantiated directly.

cc @schlessera

Copy link
Contributor

@pierlon pierlon left a comment

Choose a reason for hiding this comment

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

This looks good, passing onto @westonruter for a final review.

@@ -476,11 +450,7 @@ public static function normalize_error( $error_data ) {

$error_data['text'] = ( ! empty( $error_data['text'] ) ) ? trim( $error_data['text'] ) : '';

$error_data = wp_json_encode( $error_data );
$error_data = static::remove_domain( $error_data );
Copy link
Contributor

Choose a reason for hiding this comment

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

Ah I see. Not a fan of overloading remove_domain() and returning multiple data types however as that increases code complexity.

@codecov
Copy link

codecov bot commented Oct 15, 2021

Codecov Report

Merging #6627 (a0fb445) into develop (4547bfb) will increase coverage by 0.53%.
The diff coverage is 74.41%.

❗ Current head a0fb445 differs from pull request most recent head 855f48e. Consider uploading reports for the commit 855f48e to get more accurate results
Impacted file tree graph

@@              Coverage Diff              @@
##             develop    #6627      +/-   ##
=============================================
+ Coverage      76.63%   77.16%   +0.53%     
- Complexity      6318     6412      +94     
=============================================
  Files            248      250       +2     
  Lines          19812    20077     +265     
=============================================
+ Hits           15182    15493     +311     
+ Misses          4630     4584      -46     
Flag Coverage Δ
javascript 79.06% <ø> (ø)
php 77.08% <74.41%> (+0.56%) ⬆️
unit 77.08% <74.41%> (+0.56%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

Impacted Files Coverage Δ
src/Support/SupportCliCommand.php 40.00% <0.00%> (-35.87%) ⬇️
src/Support/SupportRESTController.php 60.00% <60.00%> (ø)
src/Support/SupportData.php 78.83% <72.72%> (+1.87%) ⬆️
...s/validation/class-amp-validated-url-post-type.php 66.15% <100.00%> (ø)
src/Admin/SupportLink.php 96.36% <100.00%> (ø)
src/Admin/SupportScreen.php 98.41% <100.00%> (ø)
src/RemoteRequest/CachedResponse.php 0.00% <0.00%> (-77.78%) ⬇️
src/RemoteRequest/CachedRemoteGetRequest.php 52.17% <0.00%> (-6.53%) ⬇️
...es/sanitizers/class-amp-allowed-tags-generated.php 57.14% <0.00%> (-3.58%) ⬇️
... and 18 more

Copy link
Member

@westonruter westonruter left a comment

Choose a reason for hiding this comment

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

I've addressed some of my PR feedback with commits.

@@ -42,15 +51,16 @@ public function register() {
// Add support link to Admin Bar.
add_action( 'admin_bar_menu', [ $this, 'admin_bar_menu' ], 105 );

// Add support link to meta box.
add_filter( 'amp_validated_url_status_actions', [ $this, 'amp_validated_url_status_actions' ], 10, 2 );
if ( is_admin() ) {
Copy link
Member

Choose a reason for hiding this comment

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

Not strictly required since outside the admin these actions won't do anything, but it doesn't hurt.

@@ -170,8 +173,8 @@ public function enqueue_assets( $hook_suffix ) {
];
}

$this->support_data->set_args( $args );
$data = $this->support_data->get_data();
$support_data = $this->injector->make( SupportData::class, [ 'args' => $args ] );
Copy link
Member

Choose a reason for hiding this comment

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

Another alternative:

Suggested change
$support_data = $this->injector->make( SupportData::class, [ 'args' => $args ] );
$support_data = $this->injector->make( SupportData::class, compact( 'args' ) );

Comment on lines +90 to +91
* @codeCoverageIgnore
*
Copy link
Member

Choose a reason for hiding this comment

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

Why ignore coverage?

Copy link
Member

Choose a reason for hiding this comment

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

Ah, because now it is covered in the feature test.

Comment on lines +341 to +351
if ( is_resource( $file ) ) {
while ( ! feof( $file ) ) {
$line = fgets( $file );
$lines[] = $line;
$line_count = count( $lines );
if ( $line_count > $no_of_lines ) {
array_shift( $lines );
}
}

fclose( $file );
Copy link
Member

Choose a reason for hiding this comment

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

While this looks like it will do the job, it is still reading through the entire file. It is using less memory now, which is good, but it could be more optimal by only seeking through the file starting from the end. For example: https://stackoverflow.com/a/15017711/93579

Copy link
Member

Choose a reason for hiding this comment

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

This would still be good to do.

@westonruter westonruter enabled auto-merge October 18, 2021 20:46
@westonruter westonruter merged commit 65cdda6 into develop Oct 18, 2021
@westonruter westonruter deleted the feature/5939-support-request-flow branch October 18, 2021 20:56
@westonruter westonruter added the Changelogged Whether the issue/PR has been added to release notes. label Dec 14, 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.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Add support request flow
4 participants