Skip to content

Commit

Permalink
Merge pull request #2016 from woocommerce/release/2.5.0
Browse files Browse the repository at this point in the history
release 2.5.0
  • Loading branch information
ianlin committed Jul 18, 2023
2 parents 47a2b1c + d42579f commit c641f14
Show file tree
Hide file tree
Showing 11 changed files with 161 additions and 40 deletions.
4 changes: 4 additions & 0 deletions changelog.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
*** WooCommerce Google Listings and Ads Changelog ***

= 2.5.0 - 2023-07-18 =
* Tweak - Add Tip with information with Campaign assets are imported.
* Tweak - Provide more detailed error reasons when unable to complete site verification for the Google Merchant Center account being connected in the onboarding flow.

= 2.4.11 - 2023-07-11 =
* Add - Client name and plugin version to requests.
* Dev - Enable unit testing for PHP 8.1.
Expand Down
4 changes: 2 additions & 2 deletions google-listings-and-ads.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
* Plugin Name: Google Listings and Ads
* Plugin URL: https://wordpress.org/plugins/google-listings-and-ads/
* Description: Native integration with Google that allows merchants to easily display their products across Google’s network.
* Version: 2.4.11
* Version: 2.5.0
* Author: WooCommerce
* Author URI: https://woocommerce.com/
* Text Domain: google-listings-and-ads
Expand All @@ -30,7 +30,7 @@

defined( 'ABSPATH' ) || exit;

define( 'WC_GLA_VERSION', '2.4.11' ); // WRCS: DEFINED_VERSION.
define( 'WC_GLA_VERSION', '2.5.0' ); // WRCS: DEFINED_VERSION.

Check warning on line 33 in google-listings-and-ads.php

View check run for this annotation

Codecov / codecov/patch

google-listings-and-ads.php#L33

Added line #L33 was not covered by tests
define( 'WC_GLA_MIN_PHP_VER', '7.4' );
define( 'WC_GLA_MIN_WC_VER', '6.9' );

Expand Down
10 changes: 10 additions & 0 deletions js/src/components/paid-ads/asset-group/asset-group-section.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
*/
import { __ } from '@wordpress/i18n';
import { createInterpolateElement } from '@wordpress/element';
import { Tip } from '@wordpress/components';

/**
* Internal dependencies
Expand All @@ -24,6 +25,7 @@ import './asset-group-section.scss';
*/
export default function AssetGroupSection() {
const { adapter } = useAdaptiveFormContext();
const showTip = adapter.hasImportedAssets;

return (
<Section
Expand Down Expand Up @@ -70,6 +72,14 @@ export default function AssetGroupSection() {
// reselect button in the card footer.
hideFooter={ ! adapter.isEmptyAssetEntityGroup }
/>
{ showTip && (
<Tip>
{ __(
'We auto-populated assets directly from your Final URL. We encourage you to edit or add more in order to best showcase your business.',
'google-listings-and-ads'
) }
</Tip>
) }
<AssetGroupCard />
</VerticalGapLayout>
</Section>
Expand Down
13 changes: 13 additions & 0 deletions js/src/components/paid-ads/asset-group/asset-group-section.scss
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,17 @@
font-size: $default-font-size;
color: $gray-700;
}

.components-tip {
padding: $grid-unit-15 $grid-unit-20;
background: #f0f6fc;
border: $border-width solid #c5d9ed;
line-height: $gla-line-height-medium;
color: $gray-900;

> svg {
fill: #007cba;
align-self: initial;
}
}
}
68 changes: 68 additions & 0 deletions js/src/components/paid-ads/asset-group/asset-group-section.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
jest.mock( '.~/components/adaptive-form', () => ( {
useAdaptiveFormContext: jest
.fn()
.mockName( 'useAdaptiveFormContext' )
.mockImplementation( () => {
return {
adapter: {
baseAssetGroup: { final_url: 'https://example.com' },
hasImportedAssets: false,
isEmptyAssetEntityGroup: false,
resetAssetGroup: jest.fn(),
},
};
} ),
} ) );

/**
* External dependencies
*/
import '@testing-library/jest-dom';
import { render, screen } from '@testing-library/react';

/**
* Internal dependencies
*/
import AssetGroupSection from '.~/components/paid-ads/asset-group/asset-group-section';
import { useAdaptiveFormContext } from '.~/components/adaptive-form';

jest.mock( '.~/components/paid-ads/asset-group/asset-group-card', () =>
jest.fn( ( props ) => <div { ...props } /> ).mockName( 'AssetGroupCard' )
);

describe( 'AssetGroupSection', () => {
test( 'Component renders', () => {
render( <AssetGroupSection /> );
expect(
screen.getByText( /Add additional assets/i )
).toBeInTheDocument();
} );

test( 'Component not showing Tip if there are no imported assets', () => {
render( <AssetGroupSection /> );
expect(
screen.queryByText(
'We auto-populated assets directly from your Final URL. We encourage you to edit or add more in order to best showcase your business.'
)
).not.toBeInTheDocument();
} );

test( 'Component showing Tip if there are imported assets', () => {
useAdaptiveFormContext.mockImplementation( () => {
return {
adapter: {
baseAssetGroup: { final_url: 'https://example.com' },
hasImportedAssets: true,
isEmptyAssetEntityGroup: false,
resetAssetGroup: jest.fn(),
},
};
} );
render( <AssetGroupSection /> );
expect(
screen.getByText(
'We auto-populated assets directly from your Final URL. We encourage you to edit or add more in order to best showcase your business.'
)
).toBeInTheDocument();
} );
} );
13 changes: 13 additions & 0 deletions js/src/components/paid-ads/campaign-assets-form.js
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ export default function CampaignAssetsForm( {

const [ baseAssetGroup, setBaseAssetGroup ] = useState( initialAssetGroup );
const [ validationRequestCount, setValidationRequestCount ] = useState( 0 );
const [ hasImportedAssets, setHasImportedAssets ] = useState( false );

const extendAdapter = ( formContext ) => {
const assetGroupErrors = validateAssetGroup( formContext.values );
Expand All @@ -90,13 +91,25 @@ export default function CampaignAssetsForm( {
baseAssetGroup,
validationRequestCount,
assetGroupErrors,
/*
In order to show a Tip in the UI when assets are imported we created the hasImportedAssets
property. When the Final URL changes resetAssetGroup is called with the new Asset Group,
We check if any of the assets has been populated and update this property based on that.
*/
hasImportedAssets,
isValidAssetGroup: Object.keys( assetGroupErrors ).length === 0,
resetAssetGroup( assetGroup ) {
const nextAssetGroup = assetGroup || initialAssetGroup;
let hasNonEmptyAssets = false;

Object.keys( emptyAssetGroup ).forEach( ( key ) => {
if ( assetGroup && assetGroup[ key ]?.length ) {
hasNonEmptyAssets = true;
}
formContext.setValue( key, nextAssetGroup[ key ] );
} );

setHasImportedAssets( hasNonEmptyAssets );
setBaseAssetGroup( nextAssetGroup );
setValidationRequestCount( 0 );
},
Expand Down
2 changes: 1 addition & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "google-listings-and-ads",
"title": "Google Listings and Ads",
"version": "2.4.11",
"version": "2.5.0",
"description": "google-listings-and-ads",
"author": "Automattic",
"license": "GPL-3.0-or-later",
Expand Down
9 changes: 5 additions & 4 deletions readme.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ Requires at least: 5.9
Tested up to: 6.2
Requires PHP: 7.4
Requires PHP Architecture: 64 Bits
Stable tag: 2.4.11
Stable tag: 2.5.0
License: GPLv3
License URI: https://www.gnu.org/licenses/gpl-3.0.html

Expand Down Expand Up @@ -111,6 +111,10 @@ Yes, you can run both at the same time, and we recommend it! In the US, advertis

== Changelog ==

= 2.5.0 - 2023-07-18 =
* Tweak - Add Tip with information with Campaign assets are imported.
* Tweak - Provide more detailed error reasons when unable to complete site verification for the Google Merchant Center account being connected in the onboarding flow.

= 2.4.11 - 2023-07-11 =
* Add - Client name and plugin version to requests.
* Dev - Enable unit testing for PHP 8.1.
Expand All @@ -129,7 +133,4 @@ Yes, you can run both at the same time, and we recommend it! In the US, advertis
= 2.4.10 - 2023-06-13 =
* Tweak - WC 7.8 compatibility.

= 2.4.9 - 2023-06-08 =
* Fix - Prefix psr/http-client package.

[See changelog for all versions](https://raw.githubusercontent.com/woocommerce/google-listings-and-ads/trunk/changelog.txt).
30 changes: 22 additions & 8 deletions src/API/Google/SiteVerification.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

namespace Automattic\WooCommerce\GoogleListingsAndAds\API\Google;

use Automattic\WooCommerce\GoogleListingsAndAds\Exception\ExceptionWithResponseData;
use Automattic\WooCommerce\GoogleListingsAndAds\Internal\ContainerAwareTrait;
use Automattic\WooCommerce\GoogleListingsAndAds\Internal\Interfaces\ContainerAwareInterface;
use Automattic\WooCommerce\GoogleListingsAndAds\Options\OptionsAwareInterface;
Expand All @@ -27,6 +28,7 @@
class SiteVerification implements ContainerAwareInterface, OptionsAwareInterface {

use ContainerAwareTrait;
use ExceptionTrait;
use OptionsAwareTrait;
use PluginHelper;

Expand Down Expand Up @@ -94,7 +96,7 @@ public function verify_site( string $site_url ) {
* @param string $identifier The URL of the site to verify (including protocol).
*
* @return string The meta tag to be used for verification.
* @throws Exception When unable to retrieve meta token.
* @throws ExceptionWithResponseData When unable to retrieve meta token.
*/
protected function get_token( string $identifier ): string {
/** @var SiteVerificationService $service */
Expand All @@ -116,9 +118,15 @@ protected function get_token( string $identifier ): string {
$response = $service->webResource->getToken( $post_body );
} catch ( GoogleServiceException $e ) {
do_action( 'woocommerce_gla_sv_client_exception', $e, __METHOD__ );
throw new Exception(
__( 'Unable to retrieve site verification token.', 'google-listings-and-ads' ),
$e->getCode()

$errors = $this->get_exception_errors( $e );

throw new ExceptionWithResponseData(
/* translators: %s Error message */
sprintf( __( 'Unable to retrieve site verification token: %s', 'google-listings-and-ads' ), reset( $errors ) ),
$e->getCode(),
null,
[ 'errors' => $errors ]
);
}

Expand All @@ -131,7 +139,7 @@ protected function get_token( string $identifier ): string {
*
* @param string $identifier The URL of the site to verify (including protocol).
*
* @throws Exception When unable to verify token.
* @throws ExceptionWithResponseData When unable to verify token.
*/
protected function insert( string $identifier ) {
/** @var SiteVerificationService $service */
Expand All @@ -152,9 +160,15 @@ protected function insert( string $identifier ) {
$service->webResource->insert( self::VERIFICATION_METHOD, $post_body );
} catch ( GoogleServiceException $e ) {
do_action( 'woocommerce_gla_sv_client_exception', $e, __METHOD__ );
throw new Exception(
__( 'Unable to insert site verification.', 'google-listings-and-ads' ),
$e->getCode()

$errors = $this->get_exception_errors( $e );

throw new ExceptionWithResponseData(
/* translators: %s Error message */
sprintf( __( 'Unable to insert site verification: %s', 'google-listings-and-ads' ), reset( $errors ) ),
$e->getCode(),
null,
[ 'errors' => $errors ]
);
}
}
Expand Down
46 changes: 22 additions & 24 deletions tests/Unit/API/Google/SiteVerificationTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,10 @@
namespace Automattic\WooCommerce\GoogleListingsAndAds\Tests\Unit\API\Google;

use Automattic\WooCommerce\GoogleListingsAndAds\API\Google\SiteVerification;
use Automattic\WooCommerce\GoogleListingsAndAds\Exception\ExceptionWithResponseData;
use Automattic\WooCommerce\GoogleListingsAndAds\Options\OptionsInterface;
use Automattic\WooCommerce\GoogleListingsAndAds\Tests\Framework\UnitTest;
use Automattic\WooCommerce\GoogleListingsAndAds\Tests\Tools\HelperTrait\MerchantTrait;
use Automattic\WooCommerce\GoogleListingsAndAds\Vendor\League\Container\Container;
use Automattic\WooCommerce\GoogleListingsAndAds\Vendor\Google\Service\Exception as GoogleServiceException;
use Automattic\WooCommerce\GoogleListingsAndAds\Vendor\Google\Service\SiteVerification as SiteVerificationService;
Expand All @@ -23,6 +25,8 @@
*/
class SiteVerificationTest extends UnitTest {

use MerchantTrait;

/** @var MockObject|OptionsInterface $options */
protected $options;

Expand Down Expand Up @@ -71,37 +75,31 @@ public function test_verify_site_invalid_url() {
public function test_verify_site_token_exception() {
$this->verification_service->webResource
->method( 'getToken' )
->willThrowException( new GoogleServiceException( 'error', 400 ) );

try {
$this->verification->verify_site( $this->site_url );
} catch ( Exception $e ) {
$this->assertEquals( 1, did_action( 'woocommerce_gla_site_verify_failure' ) );
$this->assertEquals( 400, $e->getCode() );
$this->assertEquals(
'Unable to retrieve site verification token.',
$e->getMessage()
);
}
->willThrowException( $this->get_google_service_exception( 400, 'No available tokens' ) );

$this->expectException( ExceptionWithResponseData::class );
$this->expectExceptionCode( 400 );
$this->expectExceptionMessage( 'Unable to retrieve site verification token: No available tokens' );

$this->verification->verify_site( $this->site_url );

$this->assertEquals( 1, did_action( 'woocommerce_gla_site_verify_failure' ) );
}

public function test_verify_site_insert_exception() {
$this->mock_service_get_token();

$this->verification_service->webResource
->method( 'insert' )
->willThrowException( new GoogleServiceException( 'error', 400 ) );

try {
$this->verification->verify_site( $this->site_url );
} catch ( Exception $e ) {
$this->assertEquals( 1, did_action( 'woocommerce_gla_site_verify_failure' ) );
$this->assertEquals( 400, $e->getCode() );
$this->assertEquals(
'Unable to insert site verification.',
$e->getMessage()
);
}
->willThrowException( $this->get_google_service_exception( 400, 'No necessary verification token.' ) );

$this->expectException( ExceptionWithResponseData::class );
$this->expectExceptionCode( 400 );
$this->expectExceptionMessage( 'Unable to insert site verification: No necessary verification token.' );

$this->verification->verify_site( $this->site_url );

$this->assertEquals( 1, did_action( 'woocommerce_gla_site_verify_failure' ) );
}

public function test_verify_site() {
Expand Down

0 comments on commit c641f14

Please sign in to comment.