Skip to content

Commit

Permalink
Merge branch 'develop' into enhance/#7278-connect-ga4-cta-tile.
Browse files Browse the repository at this point in the history
  • Loading branch information
hussain-t committed Sep 26, 2023
2 parents f0e3a5d + 3ecad74 commit 0e34d51
Show file tree
Hide file tree
Showing 2 changed files with 285 additions and 3 deletions.
83 changes: 80 additions & 3 deletions includes/Modules/Analytics_4.php
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@
use Google\Site_Kit_Dependencies\Google\Service\GoogleAnalyticsAdmin as Google_Service_GoogleAnalyticsAdmin;
use Google\Site_Kit\Modules\Analytics_4\GoogleAnalyticsAdmin\EnhancedMeasurementSettingsModel;
use Google\Site_Kit_Dependencies\Google\Service\GoogleAnalyticsAdmin\GoogleAnalyticsAdminV1betaAccount;
use Google\Site_Kit_Dependencies\Google\Service\GoogleAnalyticsAdmin\GoogleAnalyticsAdminV1betaCustomDimension;
use Google\Site_Kit_Dependencies\Google\Service\GoogleAnalyticsAdmin\GoogleAnalyticsAdminV1betaDataStream;
use Google\Site_Kit_Dependencies\Google\Service\GoogleAnalyticsAdmin\GoogleAnalyticsAdminV1betaDataStreamWebStreamData;
use Google\Site_Kit_Dependencies\Google\Service\GoogleAnalyticsAdmin\GoogleAnalyticsAdminV1betaListDataStreamsResponse;
Expand Down Expand Up @@ -347,6 +348,14 @@ protected function get_datapoint_definitions() {
);
}

if ( Feature_Flags::enabled( 'newsKeyMetrics' ) ) {
$datapoints['POST:create-custom-dimension'] = array(
'service' => 'analyticsdata',
'scopes' => array( Analytics::EDIT_SCOPE ),
'request_scopes_message' => __( 'You’ll need to grant Site Kit permission to create a new Analytics 4 custom dimension on your behalf.', 'google-site-kit' ),
);
}

return $datapoints;
}

Expand Down Expand Up @@ -756,6 +765,77 @@ protected function create_data_request( Data_Request $data ) {
'updateMask' => 'streamEnabled', // Only allow updating the streamEnabled field for now.
)
);
case 'POST:create-custom-dimension':
if ( ! isset( $data['propertyID'] ) ) {
return new WP_Error(
'missing_required_param',
/* translators: %s: Missing parameter name */
sprintf( __( 'Request parameter is empty: %s.', 'google-site-kit' ), 'propertyID' ),
array( 'status' => 400 )
);
}

if ( ! isset( $data['customDimension'] ) ) {
return new WP_Error(
'missing_required_param',
/* translators: %s: Missing parameter name */
sprintf( __( 'Request parameter is empty: %s.', 'google-site-kit' ), 'customDimension' ),
array( 'status' => 400 )
);
}

$custom_dimension_data = $data['customDimension'];

$fields = array(
'parameterName',
'displayName',
'description',
'scope',
'disallowAdsPersonalization',
);

$invalid_keys = array_diff( array_keys( $custom_dimension_data ), $fields );

if ( ! empty( $invalid_keys ) ) {
return new WP_Error(
'invalid_property_name',
/* translators: %s: Invalid property names */
sprintf( __( 'Invalid properties in customDimension: %s.', 'google-site-kit' ), implode( ', ', $invalid_keys ) ),
array( 'status' => 400 )
);
}

// Define the valid `DimensionScope` enum values.
$valid_scopes = array( 'EVENT', 'USER', 'ITEM' );

// If the scope field is not set, default to `EVENT`.
// Otherwise, validate against the enum values.
if ( ! isset( $custom_dimension_data['scope'] ) ) {
$custom_dimension_data['scope'] = 'EVENT';
} elseif ( ! in_array( $custom_dimension_data['scope'], $valid_scopes, true ) ) {
return new WP_Error(
'invalid_scope',
/* translators: %s: Invalid scope */
sprintf( __( 'Invalid scope: %s.', 'google-site-kit' ), $custom_dimension_data['scope'] ),
array( 'status' => 400 )
);
}

$custom_dimension = new GoogleAnalyticsAdminV1betaCustomDimension();
$custom_dimension->setParameterName( $custom_dimension_data['parameterName'] );
$custom_dimension->setDisplayName( $custom_dimension_data['displayName'] );
$custom_dimension->setDescription( $custom_dimension_data['description'] );
$custom_dimension->setScope( $custom_dimension_data['scope'] );
$custom_dimension->setDisallowAdsPersonalization( $custom_dimension_data['disallowAdsPersonalization'] );

$analyticsadmin = $this->get_service( 'analyticsadmin' );

return $analyticsadmin
->properties_customDimensions // phpcs:ignore WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase
->create(
self::normalize_property_id( $data['propertyID'] ),
$custom_dimension
);
case 'GET:webdatastreams':
if ( ! isset( $data['propertyID'] ) ) {
return new WP_Error(
Expand All @@ -766,7 +846,6 @@ protected function create_data_request( Data_Request $data ) {
);
}

/* @var Google_Service_GoogleAnalyticsAdmin $analyticsadmin phpcs:ignore Squiz.PHP.CommentedOutCode.Found */
$analyticsadmin = $this->get_service( 'analyticsadmin' );

return $analyticsadmin
Expand All @@ -793,7 +872,6 @@ protected function create_data_request( Data_Request $data ) {
);
}

/* @var Google_Service_GoogleAnalyticsAdmin $analyticsadmin phpcs:ignore Squiz.PHP.CommentedOutCode.Found */
$analyticsadmin = $this->get_service( 'analyticsadmin' );
$batch_request = $analyticsadmin->createBatch();

Expand Down Expand Up @@ -1259,7 +1337,6 @@ public static function normalize_property_id( $property_id ) {
* @return boolean|WP_Error
*/
public function check_service_entity_access() {
/* @var Google_Service_GoogleAnalyticsAdmin $analyticsadmin phpcs:ignore Squiz.PHP.CommentedOutCode.Found */
$analyticsadmin = $this->get_service( 'analyticsadmin' );
$settings = $this->settings->get();

Expand Down
205 changes: 205 additions & 0 deletions tests/phpunit/integration/Modules/Analytics_4Test.php
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
use Google\Site_Kit\Tests\UserAuthenticationTrait;
use Google\Site_Kit_Dependencies\Google\Service\Exception;
use Google\Site_Kit_Dependencies\Google\Service\GoogleAnalyticsAdmin\GoogleAnalyticsAdminV1betaConversionEvent;
use Google\Site_Kit_Dependencies\Google\Service\GoogleAnalyticsAdmin\GoogleAnalyticsAdminV1betaCustomDimension;
use Google\Site_Kit_Dependencies\Google\Service\GoogleAnalyticsAdmin\GoogleAnalyticsAdminV1betaDataStream;
use Google\Site_Kit_Dependencies\Google\Service\GoogleAnalyticsAdmin\GoogleAnalyticsAdminV1betaDataStreamWebStreamData;
use Google\Site_Kit_Dependencies\Google\Service\GoogleAnalyticsAdmin\GoogleAnalyticsAdminV1betaListConversionEventsResponse;
Expand Down Expand Up @@ -727,6 +728,31 @@ public function test_get_datapoints() {
);
}

public function test_get_datapoints__news_key_metrics() {
$this->enable_feature( 'newsKeyMetrics' );
$this->assertEqualSets(
array(
'account-summaries',
'accounts',
'container-lookup',
'container-destinations',
'google-tag-settings',
'conversion-events',
'create-property',
'create-webdatastream',
'properties',
'property',
'report',
'webdatastreams',
'webdatastreams-batch',
'create-account-ticket',
'enhanced-measurement-settings',
'create-custom-dimension',
),
$this->analytics->get_datapoints()
);
}

/**
* @dataProvider data_google_tag_ids
*
Expand Down Expand Up @@ -1927,6 +1953,171 @@ public function test_set_enhanced_measurement_settings() {
$this->assertEquals( "/v1alpha/properties/$property_id/dataStreams/$web_data_stream_id/enhancedMeasurementSettings", $request_url['path'] );
}

public function test_create_custom_dimension__required_params() {
$this->enable_feature( 'newsKeyMetrics' );
$property_id = '123456789';

FakeHttp::fake_google_http_handler(
$this->analytics->get_client(),
$this->create_fake_http_handler( $property_id )
);
$this->analytics->register();

// Call set_data without EDIT_SCOPE.
$data = $this->analytics->set_data(
'create-custom-dimension',
array(
'propertyID' => $property_id,
'customDimension' => array(
'description' => 'Test Custom Dimension Description',
'disallowAdsPersonalization' => false,
'displayName' => 'Test Custom Dimension',
'parameterName' => 'googlesitekit_post_author',
'scope' => 'EVENT',
),
)
);

// Verify that the EDIT_SCOPE is required.
$this->assertWPErrorWithMessage( 'You’ll need to grant Site Kit permission to create a new Analytics 4 custom dimension on your behalf.', $data );
$this->assertEquals( 'missing_required_scopes', $data->get_error_code() );
$this->assertEquals(
array(
'scopes' => array(
'https://www.googleapis.com/auth/analytics.edit',
),
'status' => 403,
),
$data->get_error_data( 'missing_required_scopes' )
);

// Grant EDIT_SCOPE so request doesn't fail.
$this->authentication->get_oauth_client()->set_granted_scopes(
array_merge(
$this->authentication->get_oauth_client()->get_required_scopes(),
(array) Analytics::EDIT_SCOPE
)
);

// Call set_data with no parameters.
$data = $this->analytics->set_data(
'create-custom-dimension',
array()
);

// Verify that the propertyID is required.
$this->assertWPErrorWithMessage( 'Request parameter is empty: propertyID.', $data );
$this->assertEquals( 'missing_required_param', $data->get_error_code() );
$this->assertEquals( array( 'status' => 400 ), $data->get_error_data( 'missing_required_param' ) );

// Call set_data with only the propertyID parameter.
$data = $this->analytics->set_data(
'create-custom-dimension',
array(
'propertyID' => $property_id,
)
);

// Verify that the customDimension object is required.
$this->assertWPErrorWithMessage( 'Request parameter is empty: customDimension.', $data );
$this->assertEquals( 'missing_required_param', $data->get_error_code() );
$this->assertEquals( array( 'status' => 400 ), $data->get_error_data( 'missing_required_param' ) );

// Call set_data with invalid customDimension fields.
$data = $this->analytics->set_data(
'create-custom-dimension',
array(
'propertyID' => $property_id,
'customDimension' => array(
'invalidField' => 'invalidValue',
),
)
);

// Verify that the keys are valid for the customDimension object.
$this->assertWPErrorWithMessage( 'Invalid properties in customDimension: invalidField.', $data );
$this->assertEquals( 'invalid_property_name', $data->get_error_code() );
$this->assertEquals( array( 'status' => 400 ), $data->get_error_data( 'invalid_property_name' ) );

// Call set_data with invalid scope.
$data = $this->analytics->set_data(
'create-custom-dimension',
array(
'propertyID' => $property_id,
'customDimension' => array(
'description' => 'Test Custom Dimension Description',
'disallowAdsPersonalization' => false,
'displayName' => 'Test Custom Dimension',
'parameterName' => 'googlesitekit_post_author',
'scope' => 'invalidValue',
),
)
);

// Verify that scope has a valid value.
$this->assertWPErrorWithMessage( 'Invalid scope: invalidValue.', $data );
$this->assertEquals( 'invalid_scope', $data->get_error_code() );
$this->assertEquals( array( 'status' => 400 ), $data->get_error_data( 'invalid_scope' ) );
}

public function test_create_custom_dimension() {
$this->enable_feature( 'newsKeyMetrics' );
$property_id = '123456789';

FakeHttp::fake_google_http_handler(
$this->analytics->get_client(),
$this->create_fake_http_handler( $property_id )
);
$this->analytics->register();

$this->authentication->get_oauth_client()->set_granted_scopes(
array_merge(
$this->authentication->get_oauth_client()->get_required_scopes(),
(array) Analytics::EDIT_SCOPE
)
);

$custom_dimension = array(
'description' => 'Test Custom Dimension Description',
'disallowAdsPersonalization' => false,
'displayName' => 'Test Custom Dimension',
'parameterName' => 'googlesitekit_post_author',
'scope' => 'EVENT',
);

$response = $this->analytics->set_data(
'create-custom-dimension',
array(
'propertyID' => $property_id,
'customDimension' => $custom_dimension,
)
);

$this->assertNotWPError( $response );

$response_array = (array) $response;

// Assert that the keys exist.
$keys = array_keys( $custom_dimension );

foreach ( $keys as $key ) {
$this->assertArrayHasKey( $key, $response_array );
}

// Validate the response against the expected mock value.
foreach ( $custom_dimension as $key => $value ) {
$this->assertEquals( $value, $response_array[ $key ] );
}

// Verify the request URL and params were correctly generated.
$this->assertCount( 1, $this->request_handler_calls );

$request_url = $this->request_handler_calls[0]['url'];

$this->assertEquals( 'analyticsadmin.googleapis.com', $request_url['host'] );
$this->assertEquals( "/v1beta/properties/$property_id/customDimensions", $request_url['path'] );
}

/**
* Returns a date string for the given number of days ago.
*
Expand Down Expand Up @@ -2031,6 +2222,20 @@ protected function create_fake_http_handler( $property_id ) {
json_encode( $conversion_events )
);

case "/v1beta/properties/$property_id/customDimensions":
$custom_dimension = new GoogleAnalyticsAdminV1betaCustomDimension();
$custom_dimension->setParameterName( 'googlesitekit_post_author' );
$custom_dimension->setDisplayName( 'Test Custom Dimension' );
$custom_dimension->setDescription( 'Test Custom Dimension Description' );
$custom_dimension->setScope( 'EVENT' );
$custom_dimension->setDisallowAdsPersonalization( false );

return new Response(
200,
array(),
json_encode( $custom_dimension )
);

default:
return new Response( 200 );
}
Expand Down

0 comments on commit 0e34d51

Please sign in to comment.