'#description'=>t('If you selected "Multiple top-level domains" above, enter all related top-level domains. Add one domain per line. By default, the data in your reports only includes the path and name of the page, and not the domain name. For more information see section <em>Show separate domain names</em> in <a href="@url">Tracking Multiple Domains</a>.',array('@url'=>url('http://support.google.com/analytics/bin/answer.py',array('query'=>array('answer'=>'1034342'))))),
'#description'=>t('If you selected "Multiple top-level domains" above, enter all related top-level domains. Add one domain per line. By default, the data in your reports only includes the path and name of the page, and not the domain name. For more information see section <em>Show separate domain names</em> in <a href="@url">Tracking Multiple Domains</a>.',array('@url'=>'https://support.google.com/analytics/answer/1034342')),
'#description'=>t('User ID enables the analysis of groups of sessions, across devices, using a unique, persistent, and non-personally identifiable ID string representing a user. <a href="@url">Learn more about the benfits of using User ID</a>.',array('@url'=>'https://support.google.com/analytics/answer/3123663')),
);
// Link specific configurations.
// Link specific configurations.
$form['tracking']['linktracking']=array(
$form['tracking']['linktracking']=array(
...
@@ -200,6 +214,27 @@ function googleanalytics_admin_settings_form($form_state) {
...
@@ -200,6 +214,27 @@ function googleanalytics_admin_settings_form($form_state) {
'#description'=>t('A file extension list separated by the | character that will be tracked as download when clicked. Regular expressions are supported. For example: !extensions',array('!extensions'=>GOOGLEANALYTICS_TRACKFILES_EXTENSIONS)),
'#description'=>t('A file extension list separated by the | character that will be tracked as download when clicked. Regular expressions are supported. For example: !extensions',array('!extensions'=>GOOGLEANALYTICS_TRACKFILES_EXTENSIONS)),
'#description'=>t('Enhanced Link Attribution improves the accuracy of your In-Page Analytics report by automatically differentiating between multiple links to the same URL on a single page by using link element IDs. <a href="@url">Enable enhanced link attribution</a> in the Admin UI of your Google Analytics account.',array('@url'=>'https://support.google.com/analytics/answer/2558867')),
'#description'=>t('By default, the URL reported to Google Analytics will not include the "fragment identifier" (i.e. the portion of the URL beginning with a hash sign), and hash changes by themselves will not cause new pageviews to be reported. Checking this box will cause hash changes to be reported as pageviews (in modern browsers) and all pageview URLs to include the fragment where applicable.'),
);
);
// Message specific configurations.
// Message specific configurations.
...
@@ -233,7 +268,7 @@ function googleanalytics_admin_settings_form($form_state) {
...
@@ -233,7 +268,7 @@ function googleanalytics_admin_settings_form($form_state) {
'#description'=>t('If checked, internal search keywords are tracked. You must configure your Google account to use the internal query parameter <strong>search</strong>. For more information see <a href="@url">Setting Up Site Search for a Profile</a>.',array('@url'=>url('http://support.google.com/analytics/bin/answer.py',array('query'=>array('answer'=>'1012264'))))).$site_search_dependencies,
'#description'=>t('If checked, internal search keywords are tracked. You must configure your Google account to use the internal query parameter <strong>search</strong>. For more information see <a href="@url">Setting Up Site Search for a Profile</a>.',array('@url'=>'https://support.google.com/analytics/answer/1012264')).$site_search_dependencies,
'#description'=>t('If checked, the alternative Google <a href="@doubleclick">DoubleClick data tracking</a> is used to enable AdWords remarketing features. If you choose this option you will need to <a href="@privacy">update your privacy policy</a>.',array('@doubleclick'=>url('http://support.google.com/analytics/bin/answer.py',array('query'=>array('answer'=>'2444872'))),'@privacy'=>url('http://support.google.com/analytics/bin/answer.py',array('query'=>array('answer'=>'2636405'))))),
'#description'=>t('The display features plugin can be used to enable Display Advertising Features in Google Analytics, such as Remarketing, Demographics and Interest Reporting, and more. <a href="@displayfeatures">Learn more about Display Advertising Features in Google Analytics</a>. If you choose this option you will need to <a href="@privacy">update your privacy policy</a>.',array('@displayfeatures'=>'https://support.google.com/analytics/answer/3450482','@privacy'=>'https://support.google.com/analytics/answer/2700409')),
@@ -259,7 +294,7 @@ function googleanalytics_admin_settings_form($form_state) {
...
@@ -259,7 +294,7 @@ function googleanalytics_admin_settings_form($form_state) {
'#type'=>'checkbox',
'#type'=>'checkbox',
'#title'=>t('Anonymize visitors IP address'),
'#title'=>t('Anonymize visitors IP address'),
'#description'=>t('Tell Google Analytics to anonymize the information sent by the tracker objects by removing the last octet of the IP address prior to its storage. Note that this will slightly reduce the accuracy of geographic reporting. In some countries it is not allowed to collect personally identifying information for privacy reasons and this setting may help you to comply with the local laws.'),
'#description'=>t('Tell Google Analytics to anonymize the information sent by the tracker objects by removing the last octet of the IP address prior to its storage. Note that this will slightly reduce the accuracy of geographic reporting. In some countries it is not allowed to collect personally identifying information for privacy reasons and this setting may help you to comply with the local laws.'),
'#description'=>t('You can add Google Analytics <a href="@custom_var_documentation">Custom Variables</a> here. These will be added to every page that Google Analytics tracking code appears on. Google Analytics will only accept custom variables if the <em>name</em> and <em>value</em> combined are less than 128 bytes after URL encoding. Keep the names as short as possible and expect long values to get trimmed. You may use tokens in custom variable names and values. Global and user tokens are always available; on node pages, node tokens are also available.',array('@custom_var_documentation'=>'https://developers.google.com/analytics/devguides/collection/gajs/gaTrackingCustomVariables')),
'#description'=>t('You can set values for Google Analytics <a href="@custom_var_documentation">Custom Dimensions</a> here. You must have already configured your custom dimensions in the <a href="@setup_documentation">Google Analytics Management Interface</a>. You may use tokens. Global and user tokens are always available; on node pages, node tokens are also available.',array('@custom_var_documentation'=>'https://developers.google.com/analytics/devguides/collection/analyticsjs/custom-dims-mets','@setup_documentation'=>'https://support.google.com/analytics/answer/2709829')),
'#description'=>t('You can supplement Google Analytics\' basic IP address tracking of visitors by segmenting users based on custom dimensions. Section 7 of the <a href="@ga_tos">Google Analytics terms of service</a> requires that You will not (and will not allow any third party to) use the Service to track, collect or upload any data that personally identifies an individual (such as a name, userid, email address or billing information), or other data which can be reasonably linked to such information by Google. You will have and abide by an appropriate Privacy Policy and will comply with all applicable laws and regulations relating to the collection of information from Visitors. You must post a Privacy Policy and that Privacy Policy must provide notice of Your use of cookies that are used to collect traffic data, and You must not circumvent any privacy features (e.g., an opt-out) that are part of the Service.',array('@ga_tos'=>'http://www.google.com/analytics/terms/gb.html')),
'#description'=>t('You can add Google Analytics <a href="@custom_var_documentation">Custom Metrics</a> here. You must have already configured your custom metrics in the <a href="@setup_documentation">Google Analytics Management Interface</a>. You may use tokens. Global and user tokens are always available; on node pages, node tokens are also available.',array('@custom_var_documentation'=>'https://developers.google.com/analytics/devguides/collection/analyticsjs/custom-dims-mets','@setup_documentation'=>'https://support.google.com/analytics/answer/2709829')),
'#description'=>t('You can supplement Google Analytics\' basic IP address tracking of visitors by segmenting users based on custom variables. Section 7 of the <a href="@ga_tos">Google Analytics terms of service</a> requires that You will not (and will not allow any third party to) use the Service to track, collect or upload any data that personally identifies an individual (such as a name, email address or billing information), or other data which can be reasonably linked to such information by Google. You will have and abide by an appropriate Privacy Policy and will comply with all applicable laws and regulations relating to the collection of information from Visitors. You must post a Privacy Policy and that Privacy Policy must provide notice of Your use of cookies that are used to collect traffic data, and You must not circumvent any privacy features (e.g., an opt-out) that are part of the Service.',array('@ga_tos'=>'http://www.google.com/analytics/terms/gb.html')),
'#description'=>t('You can supplement Google Analytics\' basic IP address tracking of visitors by segmenting users based on custom metrics. Section 7 of the <a href="@ga_tos">Google Analytics terms of service</a> requires that You will not (and will not allow any third party to) use the Service to track, collect or upload any data that personally identifies an individual (such as a name, userid, email address or billing information), or other data which can be reasonably linked to such information by Google. You will have and abide by an appropriate Privacy Policy and will comply with all applicable laws and regulations relating to the collection of information from Visitors. You must post a Privacy Policy and that Privacy Policy must provide notice of Your use of cookies that are used to collect traffic data, and You must not circumvent any privacy features (e.g., an opt-out) that are part of the Service.',array('@ga_tos'=>'http://www.google.com/analytics/terms/gb.html')),
@@ -372,33 +431,36 @@ function googleanalytics_admin_settings_form($form_state) {
...
@@ -372,33 +431,36 @@ function googleanalytics_admin_settings_form($form_state) {
'#title'=>t('Custom JavaScript code'),
'#title'=>t('Custom JavaScript code'),
'#collapsible'=>TRUE,
'#collapsible'=>TRUE,
'#collapsed'=>TRUE,
'#collapsed'=>TRUE,
'#description'=>t('You can add custom Google Analytics <a href="@snippets">code snippets</a> here. These will be added every time tracking is in effect. Before you add your custom code, you should read the <a href="@ga_concepts_overview">Google Analytics Tracking Code - Functional Overview</a> and the <a href="@ga_js_api">Google Analytics Tracking API</a> documentation. <strong>Do not include the <script> tags</strong>, and always end your code with a semicolon (;).',array('@snippets'=>'http://drupal.org/node/248699','@ga_concepts_overview'=>'https://developers.google.com/analytics/resources/concepts/gaConceptsTrackingOverview','@ga_js_api'=>'https://developers.google.com/analytics/devguides/collection/gajs/methods/')),
'#description'=>t('You can add custom Google Analytics <a href="@snippets">code snippets</a> here. These will be added every time tracking is in effect. Before you add your custom code, you should read the <a href="@ga_concepts_overview">Google Analytics Tracking Code - Functional Overview</a> and the <a href="@ga_js_api">Google Analytics Tracking API</a> documentation. <strong>Do not include the <script> tags</strong>, and always end your code with a semicolon (;).',array('@snippets'=>'http://drupal.org/node/248699','@ga_concepts_overview'=>'https://developers.google.com/analytics/resources/concepts/gaConceptsTrackingOverview','@ga_js_api'=>'https://developers.google.com/analytics/devguides/collection/analyticsjs/method-reference')),
'#description'=>t('Enter one value per line, in the format name|value. Settings in this textarea will be added to <code>ga("create", "UA-XXXX-Y", {"name":"value"});</code>. For more information, read <a href="@url">create only fields</a> documentation in the Analytics.js field reference.',array('@url'=>'https://developers.google.com/analytics/devguides/collection/analyticsjs/field-reference#create')),
'#description'=>t("Code in this textarea will be added <strong>after</strong> _gaq.push(['_trackPageview']). This is useful if you'd like to track a site in two accounts."),
'#description'=>t('Code in this textarea will be added <strong>after</strong> <code>ga("send", "pageview");</code>. This is useful if you\'d like to track a site in two accounts.'),
'#description'=>t('Google recommends adding the external JavaScript files to the header for performance reasons. If <em>Multiple top-level domains</em> has been selected, this setting will be forced to header.'),
'#description'=>t('If checked, the Google Universal Analytics debugging script will be loaded. You should not enable your production site to use this version of the JavaScript. The analytics_debug.js script is larger than the analytics.js tracking code and it is not typically cached. Using it in your production site will slow down your site for all of your users. Again, this is only for your own testing purposes. Debug messages are printed to the <code>window.console</code> object.'),
form_set_error("googleanalytics_custom_var][slots][".$custom_var['slot']."][name",t('The custom variable @slot-number requires a <em>Name</em> if a <em>Value</em> has been provided.',array('@slot-number'=>$custom_var['slot'])));
form_set_error("googleanalytics_custom_var][slots][".$custom_var['slot']."][value",t('The custom variable @slot-number requires a <em>Value</em> if a <em>Name</em> has been provided.',array('@slot-number'=>$custom_var['slot'])));
form_set_error('googleanalytics_cross_domains',t('A list of top-level domains is required if <em>Multiple top-level domains</em> has been selected.'));
form_set_error('googleanalytics_cross_domains',t('A list of top-level domains is required if <em>Multiple top-level domains</em> has been selected.'));
}
}
// Disallow empty list of download file extensions.
form_set_error('googleanalytics_codesnippet_before',t('Do not add the tracker code provided by Google into the javascript code snippets! This module already builds the tracker code based on your Google Analytics account number and settings.'));
form_set_error('googleanalytics_codesnippet_before',t('Do not add the tracker code provided by Google into the javascript code snippets! This module already builds the tracker code based on your Google Analytics account number and settings.'));
form_set_error('googleanalytics_codesnippet_after',t('Do not add the tracker code provided by Google into the javascript code snippets! This module already builds the tracker code based on your Google Analytics account number and settings.'));
form_set_error('googleanalytics_codesnippet_after',t('Do not add the tracker code provided by Google into the javascript code snippets! This module already builds the tracker code based on your Google Analytics account number and settings.'));
returnt('Field name %name is an unknown field name. Please see <a href="@url">create only fields</a> documentation for supported field names.',array('%name'=>$name,'@url'=>'https://developers.google.com/analytics/devguides/collection/analyticsjs/field-reference#create'));
}
}
/**
* Checks whether a field value is valid.
*
* @param string $value
* The option value entered by the user.
*
* @return string
* The error message if the specified value is invalid, NULL otherwise.
console.info("Download url '%s' has been found. Tracked download as extension '%s'.",Drupal.googleanalytics.getPageUrl(this.href),Drupal.googleanalytics.getDownloadExtension(this.href).toUpperCase());
'description'=>$t('Google Analytics module has not been configured yet. Please configure its settings from the <a href="@url">Google Analytics settings page</a>.',array('@url'=>url('admin/config/system/googleanalytics'))),
'description'=>$t('Google Analytics module has not been configured yet. Please configure its settings from the <a href="@url">Google Analytics settings page</a>.',array('@url'=>url('admin/config/system/googleanalytics'))),
'severity'=>REQUIREMENT_WARNING,
'severity'=>REQUIREMENT_WARNING,
...
@@ -82,6 +75,15 @@ function googleanalytics_requirements($phase) {
...
@@ -82,6 +75,15 @@ function googleanalytics_requirements($phase) {
'description'=>$t('Google Analytics module has debugging enabled. Please disable debugging setting in production sites from the <a href="@url">Google Analytics settings page</a>.',array('@url'=>url('admin/config/system/googleanalytics'))),
'severity'=>REQUIREMENT_WARNING,
'value'=>$t('Debugging enabled'),
);
}
return$requirements;
return$requirements;
}
}
...
@@ -427,10 +429,55 @@ function googleanalytics_update_7006() {
...
@@ -427,10 +429,55 @@ function googleanalytics_update_7006() {
drupal_set_message(Database::getConnection()->prefixTables("A backup of your previous Google Analytics code snippet has been saved in database table '{variable}' as 'googleanalytics_codesnippet_before_backup_7200'. You need to manually upgrade the custom 'before' code snippet."),'warning');
$messages[]=t('Manual upgrade of custom "before" code snippet is required.');
drupal_set_message(Database::getConnection()->prefixTables("A backup of your previous Google Analytics code snippet has been saved in database table '{variable}' as 'googleanalytics_codesnippet_before_backup_7200'. You need to manually upgrade the custom 'before' code snippet."),'warning');
$messages[]=t('Manual upgrade of custom "after" code snippet is required.');
}
returnempty($messages)?t('No custom code snipped found. Nothing to do.'):implode(' ',$messages);
}
/**
* Delete obsolete custom variables. Custom variables are now custom dimensions and metrics.
*/
functiongoogleanalytics_update_7201(){
variable_del('googleanalytics_custom_var');
returnt('Deleted obsolete custom variables. Custom variables are now custom dimensions and metrics and you need to manually configure them!');
@@ -20,6 +20,8 @@ class GoogleAnalyticsBasicTest extends DrupalWebTestCase {
...
@@ -20,6 +20,8 @@ class GoogleAnalyticsBasicTest extends DrupalWebTestCase {
$permissions=array(
$permissions=array(
'access administration pages',
'access administration pages',
'administer google analytics',
'administer google analytics',
'administer modules',
'administer site configuration',
);
);
// User to set up google_analytics.
// User to set up google_analytics.
...
@@ -28,6 +30,16 @@ class GoogleAnalyticsBasicTest extends DrupalWebTestCase {
...
@@ -28,6 +30,16 @@ class GoogleAnalyticsBasicTest extends DrupalWebTestCase {
}
}
functiontestGoogleAnalyticsConfiguration(){
functiontestGoogleAnalyticsConfiguration(){
// Check if Configure link is available on 'Extend' page.
// Requires 'administer modules' permission.
$this->drupalGet('admin/modules');
$this->assertRaw('admin/config/system/googleanalytics','[testGoogleAnalyticsConfiguration]: Configure link from Extend page to Google Analytics Settings page exists.');
// Check if Configure link is available on 'Status Reports' page. NOTE: Link is only shown without UA code configured.
// Requires 'administer site configuration' permission.
$this->drupalGet('admin/reports/status');
$this->assertRaw('admin/config/system/googleanalytics','[testGoogleAnalyticsConfiguration]: Configure link from Status Reports page to Google Analytics Settings page exists.');
@@ -39,6 +51,11 @@ class GoogleAnalyticsBasicTest extends DrupalWebTestCase {
...
@@ -39,6 +51,11 @@ class GoogleAnalyticsBasicTest extends DrupalWebTestCase {
}
}
functiontestGoogleAnalyticsPageVisibility(){
functiontestGoogleAnalyticsPageVisibility(){
// Verify that no tracking code is embedded into the webpage; if there is
// only the module installed, but UA code not configured. See #2246991.
$this->drupalGet('');
$this->assertNoRaw('//www.google-analytics.com/analytics.js','[testGoogleAnalyticsPageVisibility]: Tracking code is not displayed without UA code configured.');
$ua_code='UA-123456-1';
$ua_code='UA-123456-1';
variable_set('googleanalytics_account',$ua_code);
variable_set('googleanalytics_account',$ua_code);
...
@@ -58,7 +75,7 @@ class GoogleAnalyticsBasicTest extends DrupalWebTestCase {
...
@@ -58,7 +75,7 @@ class GoogleAnalyticsBasicTest extends DrupalWebTestCase {
$this->assertNoRaw($ua_code,'[testGoogleAnalyticsPageVisibility]: Tracking code is not displayed on admin page.');
$this->assertNoRaw($ua_code,'[testGoogleAnalyticsPageVisibility]: Tracking code is not displayed on admin page.');
// Checking for tracking code URI here, as $ua_code is displayed in the form.
// Checking for tracking code URI here, as $ua_code is displayed in the form.
$this->assertRaw('google-analytics.com/ga.js','[testGoogleAnalyticsPageVisibility]: Tracking code is displayed on admin subpage.');
$this->assertRaw('//www.google-analytics.com/analytics.js','[testGoogleAnalyticsPageVisibility]: Tracking code is displayed on admin subpage.');
$this->drupalGet('');
$this->drupalGet('');
$this->assertNoRaw($ua_code,'[testGoogleAnalyticsPageVisibility]: Tracking code is NOT displayed on front page.');
$this->assertNoRaw($ua_code,'[testGoogleAnalyticsPageVisibility]: Tracking code is NOT displayed on front page.');
...
@@ -89,22 +106,22 @@ class GoogleAnalyticsBasicTest extends DrupalWebTestCase {
...
@@ -89,22 +106,22 @@ class GoogleAnalyticsBasicTest extends DrupalWebTestCase {
$this->assertRaw('/404.html','[testGoogleAnalyticsPageVisibility]: 404 Not Found tracking code shown on non-existent page.');
$this->assertRaw('/404.html','[testGoogleAnalyticsPageVisibility]: 404 Not Found tracking code shown on non-existent page.');
// DNT Tests:
// DNT Tests:
// Enable caching of pages for anonymous users.
// Enable system internal page cache for anonymous users.
variable_set('cache',1);
variable_set('cache',1);
// Test whether DNT headers will fail to disable embedding of tracking code.
// Test whether DNT headers will fail to disable embedding of tracking code.
$this->drupalGet('',array(),array('DNT: 1'));
$this->drupalGet('',array(),array('DNT: 1'));
$this->assertRaw('_gaq.push(["_trackPageview"]);','[testGoogleAnalyticsDNTVisibility]: DNT header send from client, but page caching is enabled and tracker cannot removed.');
$this->assertRaw('ga("send", "pageview");','[testGoogleAnalyticsDNTVisibility]: DNT header send from client, but page caching is enabled and tracker cannot removed.');
// DNT works only with caching of pages for anonymous users disabled.
// DNT works only with system internal page cache for anonymous users disabled.
variable_set('cache',0);
variable_set('cache',0);
$this->drupalGet('');
$this->drupalGet('');
$this->assertRaw('_gaq.push(["_trackPageview"]);','[testGoogleAnalyticsDNTVisibility]: Tracking is enabled without DNT header.');
$this->assertRaw('ga("send", "pageview");','[testGoogleAnalyticsDNTVisibility]: Tracking is enabled without DNT header.');
// Test whether DNT header is able to remove the tracking code.
// Test whether DNT header is able to remove the tracking code.
$this->drupalGet('',array(),array('DNT: 1'));
$this->drupalGet('',array(),array('DNT: 1'));
$this->assertNoRaw('_gaq.push(["_trackPageview"]);','[testGoogleAnalyticsDNTVisibility]: DNT header received from client. Tracking has been disabled by browser.');
$this->assertNoRaw('ga("send", "pageview");','[testGoogleAnalyticsDNTVisibility]: DNT header received from client. Tracking has been disabled by browser.');
// Disable DNT feature and see if tracker is still embedded.
// Disable DNT feature and see if tracker is still embedded.
$this->assertRaw('_gaq.push(["_trackPageview"]);','[testGoogleAnalyticsDNTVisibility]: DNT feature is disabled, DNT header from browser has been ignored.');
$this->assertRaw('ga("send", "pageview");','[testGoogleAnalyticsDNTVisibility]: DNT feature is disabled, DNT header from browser has been ignored.');
}
}
functiontestGoogleAnalyticsTrackingCode(){
functiontestGoogleAnalyticsTrackingCode(){
...
@@ -118,40 +135,75 @@ class GoogleAnalyticsBasicTest extends DrupalWebTestCase {
...
@@ -118,40 +135,75 @@ class GoogleAnalyticsBasicTest extends DrupalWebTestCase {
$this->assertRaw('_gaq.push(["_gat._anonymizeIp"]);','[testGoogleAnalyticsTrackingCode]: Anonymize visitors IP address found on frontpage.');
$this->assertRaw('ga("set", "anonymizeIp", true);','[testGoogleAnalyticsTrackingCode]: Anonymize visitors IP address found on frontpage.');
// Test if track Enhanced Link Attribution is enabled.
variable_set('googleanalytics_tracklinkid',1);
$this->drupalGet('');
$this->assertRaw('ga("require", "linkid", "linkid.js");','[testGoogleAnalyticsTrackingCode]: Tracking code for Enhanced Link Attribution is enabled.');
// Test if track Enhanced Link Attribution is disabled.
variable_set('googleanalytics_tracklinkid',0);
$this->drupalGet('');
$this->assertNoRaw('ga("require", "linkid", "linkid.js");','[testGoogleAnalyticsTrackingCode]: Tracking code for Enhanced Link Attribution is not enabled.');
// Test if tracking of User ID is enabled.
variable_set('googleanalytics_trackuserid',1);
$this->drupalGet('');
$this->assertRaw(', {"userId":"','[testGoogleAnalyticsTrackingCode]: Tracking code for User ID is enabled.');
// Test if tracking of User ID is disabled.
variable_set('googleanalytics_trackuserid',0);
$this->drupalGet('');
$this->assertNoRaw(', {"userId":"','[testGoogleAnalyticsTrackingCode]: Tracking code for User ID is disabled.');
$this->assertNoRaw('ga("set", "page", location.pathname + location.search + location.hash);','[testGoogleAnalyticsTrackingCode]: Tracking code for url fragments is not enabled.');
$this->assertRaw('_gaq.push(["_setDomainName",','[testGoogleAnalyticsTrackingCode]: One domain with multiple subdomains is active on real host.');
$this->assertRaw('{"cookieDomain":"'.$cookie_domain.'"}','[testGoogleAnalyticsTrackingCode]: One domain with multiple subdomains is active on real host.');
}
}
else{
else{
// Special cases, Localhost and IP addresses don't show '_setDomainName'.
// Special cases, Localhost and IP addresses don't show '_setDomainName'.
$this->assertNoRaw('_gaq.push(["_setDomainName",','[testGoogleAnalyticsTrackingCode]: One domain with multiple subdomains may be active on localhost (test result is not reliable).');
$this->assertNoRaw('{"cookieDomain":"'.$cookie_domain.'"}','[testGoogleAnalyticsTrackingCode]: One domain with multiple subdomains may be active on localhost (test result is not reliable).');
$this->assertRaw('_gaq.push(["_setDomainName", "none"]);','[testGoogleAnalyticsTrackingCode]: _setDomainName: "none" found. Cross domain tracking is active.');
$this->assertRaw('ga("create", "'.$ua_code.'", {"allowLinker":true','[testGoogleAnalyticsTrackingCode]: "allowLinker" has been found. Cross domain tracking is active.');
$this->assertRaw('_gaq.push(["_setAllowLinker", true]);','[testGoogleAnalyticsTrackingCode]: _setAllowLinker: true found. Cross domain tracking is active.');
$this->assertRaw('ga("require", "linker");','[testGoogleAnalyticsTrackingCode]: Require linker has been found. Cross domain tracking is active.');
$this->assertRaw('ga("linker:autoLink", ["www.example.com","www.example.net"]);','[testGoogleAnalyticsTrackingCode]: "linker:autoLink" has been found. Cross domain tracking is active.');
$this->assertRaw('"trackCrossDomains":["www.example.com","www.example.net"]','[testGoogleAnalyticsTrackingCode]: Cross domain tracking with www.example.com and www.example.net is active.');
$this->assertRaw('"trackCrossDomains":["www.example.com","www.example.net"]','[testGoogleAnalyticsTrackingCode]: Cross domain tracking with www.example.com and www.example.net is active.');
variable_set('googleanalytics_domain_mode',0);
// Test whether debugging script has been enabled.
variable_set('googleanalytics_debug',1);
$this->drupalGet('');
$this->assertRaw('//www.google-analytics.com/analytics_debug.js','[testGoogleAnalyticsTrackingCode]: Google debugging script has been enabled.');
// Check if text and link is shown on 'Status Reports' page.
// Requires 'administer site configuration' permission.
$this->drupalGet('admin/reports/status');
$this->assertRaw(t('Google Analytics module has debugging enabled. Please disable debugging setting in production sites from the <a href="@url">Google Analytics settings page</a>.',array('@url'=>url('admin/config/system/googleanalytics'))),'[testGoogleAnalyticsConfiguration]: Debugging enabled is shown on Status Reports page.');
// Test whether the BEFORE and AFTER code is added to the tracker.
// Test whether debugging script has been disabled.
$this->assertRaw('_setDetectFlash(false);','[testGoogleAnalyticsTrackingCode]: Before codesnippet has been found with "Flash" detection disabled.');
$this->assertRaw('ga("create", "'.$ua_code.'", {"cookieDomain":"foo.example.com","cookieName":"myNewName","cookieExpires":20000,"allowAnchor":true,"sampleRate":4.3});','[testGoogleAnalyticsTrackingCode]: Create only fields have been found.');
$this->assertRaw('t2._setAccount','[testGoogleAnalyticsTrackingCode]: After codesnippet with "t2" tracker has been found.');
$this->assertRaw('ga("set", "forceSSL", true);','[testGoogleAnalyticsTrackingCode]: Before codesnippet will force http pages to also send all beacons using https.');
$this->assertRaw('ga("create", "UA-123456-3", {name: "newTracker"});','[testGoogleAnalyticsTrackingCode]: After codesnippet with "newTracker" tracker has been found.');
$this->assertRaw('ga("set", '.drupal_json_encode('dimension1').', '.drupal_json_encode("Value: $site_slogan").');','[testGoogleAnalyticsCustomDimensionsAndMetrics]: Tokens have been replaced in dimension value.');
$this->assertRaw('ga("set", '.drupal_json_encode('dimension2').', '.drupal_json_encode($googleanalytics_custom_dimension['indexes']['2']['value']).');','[testGoogleAnalyticsCustomDimensionsAndMetrics]: Random value is shown.');
$this->assertNoRaw('ga("set", '.drupal_json_encode('dimension3').', '.drupal_json_encode('').');','[testGoogleAnalyticsCustomDimensionsAndMetrics]: Empty value is not shown.');
$this->assertRaw("_gaq.push(['_setCustomVar', 1, \"Name: $site_slogan\", \"Value: $site_slogan\", 3]",'[testGoogleAnalyticsCustomVariables]: Tokens have been replaced in custom variable.');
$this->assertRaw('ga("set", '.drupal_json_encode('metric1').', ','[testGoogleAnalyticsCustomDimensionsAndMetrics]: Tokens have been replaced in metric value.');
$this->assertNoRaw("_gaq.push(['_setCustomVar', 2,",'[testGoogleAnalyticsCustomVariables]: Value with empty name is not shown.');
$this->assertRaw('ga("set", '.drupal_json_encode('metric2').', '.drupal_json_encode($googleanalytics_custom_metric['indexes']['2']['value']).');','[testGoogleAnalyticsCustomDimensionsAndMetrics]: Random value is shown.');
$this->assertNoRaw("_gaq.push(['_setCustomVar', 3,",'[testGoogleAnalyticsCustomVariables]: Name with empty value is not shown.');
$this->assertNoRaw('ga("set", '.drupal_json_encode('metric3').', '.drupal_json_encode('').');','[testGoogleAnalyticsCustomDimensionsAndMetrics]: Empty value is not shown.');
$this->assertNoRaw("_gaq.push(['_setCustomVar', 4,",'[testGoogleAnalyticsCustomVariables]: Empty name and value is not shown.');
$this->assertNoRaw("_gaq.push(['_setCustomVar', 5,",'[testGoogleAnalyticsCustomVariables]: Empty name and value is not shown.');
}
}
}
}
...
@@ -334,8 +449,8 @@ class GoogleAnalyticsStatusMessagesTest extends DrupalWebTestCase {
...
@@ -334,8 +449,8 @@ class GoogleAnalyticsStatusMessagesTest extends DrupalWebTestCase {
$this->assertRaw('_gaq.push(["_trackEvent", "Messages", "Error message", "Username field is required."]);','[testGoogleAnalyticsStatusMessages]: _trackEvent "Username field is required." is shown.');
$this->assertRaw('ga("send", "event", "Messages", "Error message", "Username field is required.");','[testGoogleAnalyticsStatusMessages]: Event message "Username field is required." is shown.');
$this->assertRaw('_gaq.push(["_trackEvent", "Messages", "Error message", "Password field is required."]);','[testGoogleAnalyticsStatusMessages]: _trackEvent "Password field is required." is shown.');
$this->assertRaw('ga("send", "event", "Messages", "Error message", "Password field is required.");','[testGoogleAnalyticsStatusMessages]: Event message "Password field is required." is shown.');
//drupal_set_message('Example error <em>message</em> with html tags and <a href="http://example.com/">link</a>.', 'error');
//drupal_set_message('Example error <em>message</em> with html tags and <a href="http://example.com/">link</a>.', 'error');
//$this->drupalGet('');
//$this->drupalGet('');
//$this->assertNoRaw('_gaq.push(["_trackEvent", "Messages", "Status message", "Example status message."]);', '[testGoogleAnalyticsStatusMessages]: Example status message is not enabled for tracking.');
//$this->assertNoRaw('ga("send", "event", "Messages", "Status message", "Example status message.");', '[testGoogleAnalyticsStatusMessages]: Example status message is not enabled for tracking.');
//$this->assertNoRaw('_gaq.push(["_trackEvent", "Messages", "Warning message", "Example warning message."]);', '[testGoogleAnalyticsStatusMessages]: Example warning message is not enabled for tracking.');
//$this->assertNoRaw('ga("send", "event", "Messages", "Warning message", "Example warning message.");', '[testGoogleAnalyticsStatusMessages]: Example warning message is not enabled for tracking.');
//$this->assertRaw('_gaq.push(["_trackEvent", "Messages", "Error message", "Example error message."]);', '[testGoogleAnalyticsStatusMessages]: Example error message is shown.');
//$this->assertRaw('ga("send", "event", "Messages", "Error message", "Example error message.");', '[testGoogleAnalyticsStatusMessages]: Example error message is shown.');
//$this->assertRaw('_gaq.push(["_trackEvent", "Messages", "Error message", "Example error message with html tags and link."]);', '[testGoogleAnalyticsStatusMessages]: HTML has been stripped successful from Example error message with html tags and link.');
//$this->assertRaw('ga("send", "event", "Messages", "Error message", "Example error message with html tags and link.");', '[testGoogleAnalyticsStatusMessages]: HTML has been stripped successful from Example error message with html tags and link.');
}
}
}
}
...
@@ -438,5 +553,135 @@ class GoogleAnalyticsRolesTest extends DrupalWebTestCase {
...
@@ -438,5 +553,135 @@ class GoogleAnalyticsRolesTest extends DrupalWebTestCase {
$this->drupalGet('');
$this->drupalGet('');
$this->assertRaw($ua_code,'[testGoogleAnalyticsRoleVisibility]: Tracking code is displayed on frontpage for included anonymous users.');
$this->assertRaw($ua_code,'[testGoogleAnalyticsRoleVisibility]: Tracking code is displayed on frontpage for included anonymous users.');
$this->assertRaw(t('Pages on which this PHP code returns <code>TRUE</code> (experts only)'),'[testGoogleAnalyticsPhpFilter]: Permission to administer PHP for tracking visibility.');
$this->assertRaw(check_plain('<?php return TRUE; ?>'),'[testGoogleAnalyticsPhpFilter]: PHP code snippted is displayed.');
// Login the delegated user and check if fields are visible.
$this->assertNoRaw(t('Pages on which this PHP code returns <code>TRUE</code> (experts only)'),'[testGoogleAnalyticsPhpFilter]: No permission to administer PHP for tracking visibility.');
$this->assertNoRaw(check_plain('<?php return TRUE; ?>'),'[testGoogleAnalyticsPhpFilter]: No permission to view PHP code snippted.');
// Set a different value and verify that this is still the same after the post.
Drupal.googleanalytics.test.assertFalse(Drupal.googleanalytics.isDownload(base_url+Drupal.settings.basePath+'node/8'),"Verify that '/node/8' url is not detected as file download.");
Drupal.googleanalytics.test.assertTrue(Drupal.googleanalytics.isDownload(base_url+Drupal.settings.basePath+'files/foo1.zip'),"Verify that '/files/foo1.zip' url is detected as a file download.");
Drupal.googleanalytics.test.assertTrue(Drupal.googleanalytics.isDownload(base_url+Drupal.settings.basePath+'files/foo1.zip#foo'),"Verify that '/files/foo1.zip#foo' url is detected as a file download.");
Drupal.googleanalytics.test.assertTrue(Drupal.googleanalytics.isDownload(base_url+Drupal.settings.basePath+'files/foo1.zip?foo=bar'),"Verify that '/files/foo1.zip?foo=bar' url is detected as a file download.");
Drupal.googleanalytics.test.assertTrue(Drupal.googleanalytics.isDownload(base_url+Drupal.settings.basePath+'files/foo1.zip?foo=bar#foo'),"Verify that '/files/foo1.zip?foo=bar#foo' url is detected as a file download.");
Drupal.googleanalytics.test.assertFalse(Drupal.googleanalytics.isDownload(base_url+Drupal.settings.basePath+'files/foo2.ddd'),"Verify that '/files/foo2.ddd' url is not detected as file download.");
console.groupEnd();
console.group("Test 'isInternal':");
Drupal.googleanalytics.test.assertTrue(Drupal.googleanalytics.isInternal(base_url+Drupal.settings.basePath+'node/1'),"Link '"+base_url+Drupal.settings.basePath+"node/2' has been detected as internal link.");
Drupal.googleanalytics.test.assertTrue(Drupal.googleanalytics.isInternal(base_url+Drupal.settings.basePath+'node/1#foo'),"Link '"+base_url+Drupal.settings.basePath+"node/1#foo' has been detected as internal link.");
Drupal.googleanalytics.test.assertTrue(Drupal.googleanalytics.isInternal(base_url+Drupal.settings.basePath+'node/1?foo=bar'),"Link '"+base_url+Drupal.settings.basePath+"node/1?foo=bar' has been detected as internal link.");
Drupal.googleanalytics.test.assertTrue(Drupal.googleanalytics.isInternal(base_url+Drupal.settings.basePath+'node/1?foo=bar#foo'),"Link '"+base_url+Drupal.settings.basePath+"node/1?foo=bar#foo' has been detected as internal link.");
Drupal.googleanalytics.test.assertTrue(Drupal.googleanalytics.isInternal(base_url+Drupal.settings.basePath+'go/foo'),"Link '"+base_url+Drupal.settings.basePath+"go/foo' has been detected as internal link.");
Drupal.googleanalytics.test.assertFalse(Drupal.googleanalytics.isInternal('http://example.com/node/3'),"Link 'http://example.com/node/3' has been detected as external link.");
console.groupEnd();
console.group("Test 'isInternalSpecial':");
Drupal.googleanalytics.test.assertTrue(Drupal.googleanalytics.isInternalSpecial(base_url+Drupal.settings.basePath+'go/foo'),"Link '"+base_url+Drupal.settings.basePath+"go/foo' has been detected as special internal link.");
Drupal.googleanalytics.test.assertFalse(Drupal.googleanalytics.isInternalSpecial(base_url+Drupal.settings.basePath+'node/1'),"Link '"+base_url+Drupal.settings.basePath+"node/1' has been detected as special internal link.");
console.groupEnd();
console.group("Test 'getPageUrl':");
Drupal.googleanalytics.test.assertSame(base_path+'node/1',Drupal.googleanalytics.getPageUrl(base_url+Drupal.settings.basePath+'node/1'),"Absolute internal URL '"+Drupal.settings.basePath+"node/1' has been extracted from full qualified url '"+base_url+base_path+"node/1'.");
Drupal.googleanalytics.test.assertSame(base_path+'node/1',Drupal.googleanalytics.getPageUrl(Drupal.settings.basePath+'node/1'),"Absolute internal URL '"+Drupal.settings.basePath+"node/1' has been extracted from absolute url '"+base_path+"node/1'.");
Drupal.googleanalytics.test.assertSame('http://example.com/node/2',Drupal.googleanalytics.getPageUrl('http://example.com/node/2'),"Full qualified external url 'http://example.com/node/2' has been extracted.");
Drupal.googleanalytics.test.assertSame('//example.com/node/2',Drupal.googleanalytics.getPageUrl('//example.com/node/2'),"Full qualified external url '//example.com/node/2' has been extracted.");
console.groupEnd();
console.group("Test 'getDownloadExtension':");
Drupal.googleanalytics.test.assertSame('zip',Drupal.googleanalytics.getDownloadExtension(base_url+Drupal.settings.basePath+'/files/foo1.zip'),"Download extension 'zip' has been found in '"+base_url+Drupal.settings.basePath+"files/foo1.zip'.");
Drupal.googleanalytics.test.assertSame('zip',Drupal.googleanalytics.getDownloadExtension(base_url+Drupal.settings.basePath+'/files/foo1.zip#foo'),"Download extension 'zip' has been found in '"+base_url+Drupal.settings.basePath+"files/foo1.zip#foo'.");
Drupal.googleanalytics.test.assertSame('zip',Drupal.googleanalytics.getDownloadExtension(base_url+Drupal.settings.basePath+'/files/foo1.zip?foo=bar'),"Download extension 'zip' has been found in '"+base_url+Drupal.settings.basePath+"files/foo1.zip?foo=bar'.");
Drupal.googleanalytics.test.assertSame('zip',Drupal.googleanalytics.getDownloadExtension(base_url+Drupal.settings.basePath+'/files/foo1.zip?foo=bar#foo'),"Download extension 'zip' has been found in '"+base_url+Drupal.settings.basePath+"files/foo1.zip?foo=bar'.");
Drupal.googleanalytics.test.assertSame('',Drupal.googleanalytics.getDownloadExtension(base_url+Drupal.settings.basePath+'/files/foo2.dddd'),"No download extension found in '"+base_url+Drupal.settings.basePath+"files/foo2.dddd'.");
console.groupEnd();
// List of top-level domains: example.com, example.net
console.group("Test 'isCrossDomain' (requires cross domain configuration with 'example.com' and 'example.net'):");
Drupal.googleanalytics.test.assertTrue(Drupal.googleanalytics.isCrossDomain('example.com',Drupal.settings.googleanalytics.trackCrossDomains),"URL 'example.com' has been found in cross domain list.");
Drupal.googleanalytics.test.assertTrue(Drupal.googleanalytics.isCrossDomain('example.net',Drupal.settings.googleanalytics.trackCrossDomains),"URL 'example.com' has been found in cross domain list.");
Drupal.googleanalytics.test.assertFalse(Drupal.googleanalytics.isCrossDomain('www.example.com',Drupal.settings.googleanalytics.trackCrossDomains),"URL 'www.example.com' not found in cross domain list.");
Drupal.googleanalytics.test.assertFalse(Drupal.googleanalytics.isCrossDomain('www.example.net',Drupal.settings.googleanalytics.trackCrossDomains),"URL 'www.example.com' not found in cross domain list.");
}
else{
console.warn('Cross domain tracking is not enabled. Tests skipped.');