cdn.test in CDN 7.2
Test CDN.
File
tests/cdn.testView source
<?php
/**
* @file
* Test CDN.
*/
class CDNUnitTestCase extends DrupalUnitTestCase {
function setUp() {
parent::setUp();
// Alter $_SERVER to include some relatively rarely set HTTP headers.
$alt_server = array(
'HTTP_ACCEPT_ENCODING',
'HTTPS' => 'off',
'HTTP_X_FORWARDED_PROTO' => 'http',
'HTTP_USER_AGENT' => $this
->randomName(),
);
$alt_server = array_merge($alt_server, $_SERVER);
$_SERVER = $alt_server;
$this
->setRequestProtocol('http');
// Enable the private:// stream wrapper.
$this
->variableSet('file_private_path', conf_path() . '/files/private');
// Pretend the CDN module is enabled; this ensures invocations of its own
// hook implementations will work as expected.
$cdn_module_file = drupal_get_path('module', 'cdn') . '/cdn.module';
$module_list['system']['filename'] = 'modules/system/system.module';
$module_list['cdn']['filename'] = $cdn_module_file;
module_list(TRUE, FALSE, FALSE, $module_list);
$implementations =& drupal_static('module_implements');
$implementations = array();
$this
->loadFile('cdn.constants.inc');
$this
->loadFile('cdn.module');
// Override $conf to be able to use variable_set() and variable_get() in
// DrupalUnitTestCase. At the same time, make sure we can restore the
// original values.
global $conf;
$this->originalConfig = $conf;
$this
->variableSetDefaults();
}
function tearDown() {
// Restore the original values that are used by variable_get().
global $conf;
$conf = $this->originalConfig;
parent::tearDown();
}
function loadFile($file) {
$cdn_path = DRUPAL_ROOT . '/' . drupal_get_path('module', 'cdn');
require_once "{$cdn_path}/{$file}";
}
/**
* Mock function for variable_set().
*/
function variableSet($name, $value) {
global $conf;
$conf[$name] = $value;
}
/**
* Set the default variable values for the CDN module.
*/
function variableSetDefaults() {
global $conf;
$this->defaultConfig = array(
CDN_STATUS_VARIABLE => CDN_ENABLED,
CDN_MODE_VARIABLE => FALSE,
CDN_HTTPS_SUPPORT_VARIABLE => FALSE,
CDN_BASIC_MAPPING_VARIABLE => '',
CDN_BASIC_MAPPING_HTTPS_VARIABLE => '',
CDN_BASIC_FARFUTURE_VARIABLE => FALSE,
CDN_SEO_REDIRECT_VARIABLE => TRUE,
);
$conf = array_merge($conf, $this->defaultConfig);
}
/**
* Set the protocol of the current "request".
*
* @param $protocol
* 'http' or 'https'.
*/
function setRequestProtocol($protocol) {
if ($protocol == 'http') {
$_SERVER['HTTPS'] = 'off';
$_SERVER['HTTP_X_FORWARDED_PROTO'] = 'http';
}
elseif ($protocol == 'https') {
$_SERVER['HTTPS'] = 'on';
$_SERVER['HTTP_X_FORWARDED_PROTO'] = 'https';
}
}
/**
* Set the User-Agent of the current "request".
*
* @param $ua
* A User-Agent, which can be almost any string.
*/
function setUserAgent($ua) {
$_SERVER['HTTP_USER_AGENT'] = $ua;
}
/**
* Configure HTTPS-related settings.
*
* @param $supported
* Boolean that indicates whether HTTPS is supported by the current CDN
* or not.
* @param $mapping
* The CDN mapping to use when the CDN supports HTTPS and the current
* request is happening over HTTPS.
*/
function configureHTTPS($supported, $mapping = '') {
$this
->variableSet(CDN_HTTPS_SUPPORT_VARIABLE, $supported);
$this
->variableSet(CDN_BASIC_MAPPING_HTTPS_VARIABLE, $mapping);
}
/**
* Given a file URI, get the expanded file path.
*
* @param $uri
* @see file_stream_wrapper_get_instance_by_uri()
* @return
* A Drupal root-relative path.
*/
function getExpandedFilePath($uri) {
$wrapper = file_stream_wrapper_get_instance_by_uri($uri);
return str_replace($GLOBALS['base_url'] . '/', '', $wrapper
->getExternalUrl());
}
/**
* Given a file URI, get its path, create the file and ensure it exists.
*
* @param $uri
* @see getExpandedFilePath()
*/
function touchFile($uri) {
$path = $this
->getExpandedFilePath($uri);
$this
->assertTrue(touch(rawurldecode($path)), 'Test file created.');
return $path;
}
}
class CDNWebTestCase extends DrupalWebTestCase {
function setUp() {
parent::setUp('cdn');
}
function loadFile($file) {
$cdn_path = DRUPAL_ROOT . '/' . drupal_get_path('module', 'cdn');
require_once "{$cdn_path}/{$file}";
}
}
class CDNGeneralTestCase extends CDNUnitTestCase {
public static function getInfo() {
return array(
'name' => 'General',
'description' => 'Verify general functionality.',
'group' => 'CDN',
);
}
function testHTTPSDetection() {
// HTTPS + HTTP_X_FORWARDED_PROTO permutations.
$_SERVER['HTTPS'] = 'off';
$_SERVER['HTTP_X_FORWARDED_PROTO'] = 'http';
$this
->assertEqual(FALSE, cdn_request_is_https(), 'HTTP request detected.');
$_SERVER['HTTPS'] = 'off';
$_SERVER['HTTP_X_FORWARDED_PROTO'] = 'https';
$this
->assertEqual(TRUE, cdn_request_is_https(), 'HTTPS request detected.');
$_SERVER['HTTPS'] = 'on';
$_SERVER['HTTP_X_FORWARDED_PROTO'] = 'https';
$this
->assertEqual(TRUE, cdn_request_is_https(), 'HTTPS request detected.');
$_SERVER['HTTPS'] = 'on';
$_SERVER['HTTP_X_FORWARDED_PROTO'] = 'http';
$this
->assertEqual(TRUE, cdn_request_is_https(), 'HTTPS request detected.');
// HTTPS + HTTP_X_FORWARDED_PROTOCOL permutations.
unset($_SERVER['HTTP_X_FORWARDED_PROTO']);
$_SERVER['HTTPS'] = 'off';
$_SERVER['HTTP_X_FORWARDED_PROTOCOL'] = 'http';
$this
->assertEqual(FALSE, cdn_request_is_https(), 'HTTP request detected.');
$_SERVER['HTTPS'] = 'off';
$_SERVER['HTTP_X_FORWARDED_PROTOCOL'] = 'https';
$this
->assertEqual(TRUE, cdn_request_is_https(), 'HTTPS request detected.');
$_SERVER['HTTPS'] = 'on';
$_SERVER['HTTP_X_FORWARDED_PROTOCOL'] = 'https';
$this
->assertEqual(TRUE, cdn_request_is_https(), 'HTTPS request detected.');
$_SERVER['HTTPS'] = 'on';
$_SERVER['HTTP_X_FORWARDED_PROTOCOL'] = 'http';
$this
->assertEqual(TRUE, cdn_request_is_https(), 'HTTPS request detected.');
}
}
class CDNOriginPullTestCase extends CDNUnitTestCase {
public static function getInfo() {
return array(
'name' => 'Origin Pull mode',
'description' => 'Verify Origin Pull mode-related functionality.',
'group' => 'CDN',
);
}
function setUp() {
parent::setUp();
$this
->loadFile('cdn.basic.inc');
$this
->loadFile('cdn.basic.farfuture.inc');
$this
->variableSet(CDN_MODE_VARIABLE, CDN_MODE_BASIC);
}
/**
* Assert a CDN mapping (and optionally set a mapping).
*
* @param $mapping
* The mapping to set; if FALSE, no new mapping will be set.
* @param $parsed_reference
* The reference the parsed mapping will be compared to.
* @param $domains_reference
* The reference the domains (as returned by cdn_get_domains()) will be
* compared to.
*/
function assertMapping($mapping, $parsed_reference, $domains_reference) {
if ($mapping !== FALSE) {
$this
->variableSet(CDN_BASIC_MAPPING_VARIABLE, $mapping);
}
$this
->assertEqual($parsed_reference, _cdn_basic_parse_raw_mapping(cdn_basic_get_mapping()), 'CDN mapping parsed correctly.');
$domains = cdn_get_domains();
sort($domains);
$this
->assertEqual($domains_reference, $domains, 'CDN domains parsed correctly.');
}
function testMapping() {
$this
->setRequestProtocol('http');
$this
->assertEqual('', cdn_basic_get_mapping(), 'The default CDN mapping is empty.');
// Ensure the parsing of the raw mapping works correctly.
$this
->assertMapping('', array(), array());
$this
->assertMapping('http://cdn-a.com', array(
'*' => array(
'http://cdn-a.com',
),
), array(
'cdn-a.com',
));
$this
->assertMapping('http://cdn-a.com/', array(
'*' => array(
'http://cdn-a.com',
),
), array(
'cdn-a.com',
));
$this
->assertMapping('//cdn-a.com', array(
'*' => array(
'//cdn-a.com',
),
), array(
'cdn-a.com',
));
$this
->assertMapping('//cdn-a.com/', array(
'*' => array(
'//cdn-a.com',
),
), array(
'cdn-a.com',
));
$parsed_mapping = array(
'css' => array(
'http://cdn-a.com',
),
'jpg' => array(
'http://cdn-a.com',
),
'jpeg' => array(
'http://cdn-a.com',
),
'png' => array(
'http://cdn-a.com',
),
'zip' => array(
'http://cdn-b.com',
),
'*' => array(
'http://cdn-c.com',
),
);
$domains = array(
'cdn-a.com',
'cdn-b.com',
'cdn-c.com',
);
$this
->assertMapping("http://cdn-a.com|.css .jpg .jpeg .png\nhttp://cdn-b.com|.zip\nhttp://cdn-c.com", $parsed_mapping, $domains);
$parsed_mapping = array(
'css' => array(
'http://cdn-a.com',
'http://cdn-d.com',
),
'jpg' => array(
'http://cdn-a.com',
'http://cdn-d.com',
),
'jpeg' => array(
'http://cdn-a.com',
'http://cdn-d.com',
),
'png' => array(
'http://cdn-a.com',
'http://cdn-d.com',
'http://cdn-b.com',
),
'*' => array(
'http://cdn-c.com',
),
);
$domains = array(
'cdn-a.com',
'cdn-b.com',
'cdn-c.com',
'cdn-d.com',
);
$this
->assertMapping("http://cdn-a.com http://cdn-d.com|.css .jpg .jpeg .png\nhttp://cdn-b.com|.png\nhttp://cdn-c.com", $parsed_mapping, $domains);
// When a HTTPS request is performed and the CDN is not marked to support
// HTTPS, then it should fall back to the default CDN mapping.
$this
->setRequestProtocol('https');
$this
->assertMapping(FALSE, $parsed_mapping, $domains);
// When a HTTPS request is performed and the CDN *is* marked to support
// HTTPS, then it should still fall back to the default CDN mapping. (When
// file URLs are actually altered, it will then replace `http://` with
// `https://` -- this will be tested in a different test.)
$this
->configureHTTPS(TRUE);
$this
->assertMapping(FALSE, $parsed_mapping, $domains);
// When a HTTPS request is performed *and* the CDN is marked to support
// HTTPS *and* there's a HTTPS-specific CDN mapping, that mapping should
// be used instead!
$this
->configureHTTPS(TRUE, "https://cdn-a.com|.css .jpg .jpeg .png\nhttps://cdn-b.com|.zip\nhttps://cdn-c.com");
$this
->assertMapping(FALSE, array(
'css' => array(
'https://cdn-a.com',
),
'jpg' => array(
'https://cdn-a.com',
),
'jpeg' => array(
'https://cdn-a.com',
),
'png' => array(
'https://cdn-a.com',
),
'zip' => array(
'https://cdn-b.com',
),
'*' => array(
'https://cdn-c.com',
),
), array(
'cdn-a.com',
'cdn-b.com',
'cdn-c.com',
));
// Ensure the default CDN mapping is used whenever a HTTP request occurs
// and the CDN is marked to suppport HTTPS and there's a HTTPS-specific
// CDN mapping.
$this
->configureHTTPS(FALSE);
$this
->assertMapping(FALSE, $parsed_mapping, $domains);
}
function testFileUrlAlterHook() {
// Provide a very basic CDN mapping.
$this
->variableSet(CDN_BASIC_MAPPING_VARIABLE, 'http://cdn-a.com');
$filename = 'újjáépítésérol — 100% in B&W.jpg';
$uri = "public://{$filename}";
$this
->touchFile($uri);
cdn_file_url_alter($uri);
$expected = 'http://cdn-a.com' . base_path() . variable_get('file_public_path', conf_path() . '/files') . '/' . drupal_encode_path($filename);
$this
->assertIdentical($uri, $expected, 'cdn_file_url_alter() works correctly.');
// Test that private:// file URLs are not altered.
$uri = "private://{$filename}";
$expected = $uri;
cdn_file_url_alter($uri);
$this
->assertIdentical($uri, $expected, 'cdn_file_url_alter() excludes private:// files.');
}
}
class CDNOriginPullFarFutureTestCase extends CDNUnitTestCase {
public static function getInfo() {
return array(
'name' => 'Origin Pull mode — Far Future expiration',
'description' => 'Verify Origin Pull mode\'s Far Future expiration functionality.',
'group' => 'CDN',
);
}
function setUp() {
parent::setUp();
$this
->loadFile('cdn.basic.inc');
$this
->loadFile('cdn.basic.farfuture.inc');
$this
->variableSet(CDN_MODE_VARIABLE, CDN_MODE_BASIC);
$this
->variableSet(CDN_BASIC_FARFUTURE_VARIABLE, TRUE);
}
/**
* Assert a UFI mapping (and optionally set a mapping).
*
* @param $mapping
* The mapping to set; if FALSE, no new mapping will be set.
* @param $parsed_reference
* The reference the parsed mapping will be compared to.
* @param $message
*/
function assertUFIMapping($mapping, $parsed_reference, $message = NULL) {
if (is_null($message)) {
$message = 'UFI mapping parsed correctly.';
}
if ($mapping !== FALSE) {
$this
->variableSet(CDN_BASIC_FARFUTURE_UNIQUE_IDENTIFIER_MAPPING_VARIABLE, $mapping);
}
$parsed = _cdn_basic_farfuture_parse_raw_mapping(variable_get(CDN_BASIC_FARFUTURE_UNIQUE_IDENTIFIER_MAPPING_VARIABLE, CDN_BASIC_FARFUTURE_UNIQUE_IDENTIFIER_MAPPING_DEFAULT));
$this
->assertEqual($parsed_reference, $parsed, $message);
}
/**
* Assert a UFI method. Must be run after a UFI mapping is asserted (and
* set) by assertUFIMapping().
*
* @param $path
* The path to get a UFI for.
* @param $ufi_method_reference
* The reference the resulting UFI method will be compared to.
*/
function assertUFIMethod($path, $ufi_method_reference) {
$ufi_mapping = _cdn_basic_farfuture_parse_raw_mapping(variable_get(CDN_BASIC_FARFUTURE_UNIQUE_IDENTIFIER_MAPPING_VARIABLE, CDN_BASIC_FARFUTURE_UNIQUE_IDENTIFIER_MAPPING_DEFAULT));
$this
->assertEqual($ufi_method_reference, cdn_basic_farfuture_get_ufi_method($path, $ufi_mapping), 'Correct UFI method applied.');
}
function testUFIMapping() {
$default = CDN_BASIC_FARFUTURE_UNIQUE_IDENTIFIER_MAPPING_DEFAULT;
$parsed_mapping = _cdn_basic_farfuture_parse_raw_mapping($default);
$this
->assertUFIMapping(FALSE, $parsed_mapping, 'The default UFI mapping is set to sensible defaults.');
// Growing complexity for a single-directory UFI.
$this
->assertUFIMapping("sites/*|mtime", array(
'sites/*' => array(
'*' => array(
'ufi method' => 'mtime',
'specificity' => 20,
),
),
), 'Simple single-directory UFI mapping (step 1).');
$this
->assertUFIMethod('sites/foo', 'mtime');
$this
->assertUFIMapping("sites/*|mtime\nsites/*|.woff .ttf|md5_hash", array(
'sites/*' => array(
'*' => array(
'ufi method' => 'mtime',
'specificity' => 20,
),
'woff' => array(
'ufi method' => 'md5_hash',
'specificity' => 21,
),
'ttf' => array(
'ufi method' => 'md5_hash',
'specificity' => 21,
),
),
), 'Simple single-directory UFI mapping (step 2).');
$this
->assertUFIMethod('sites/foo', 'mtime');
$this
->assertUFIMethod('sites/foobambamb.woff', 'md5_hash');
$this
->assertUFIMethod('sites/foo/bar/baz.ttf', 'md5_hash');
$this
->assertUFIMapping("sites/*|mtime\nsites/*|.woff .ttf|md5_hash\nsites/*|.mov .mp4|perpetual", array(
'sites/*' => array(
'*' => array(
'ufi method' => 'mtime',
'specificity' => 20,
),
'woff' => array(
'ufi method' => 'md5_hash',
'specificity' => 21,
),
'ttf' => array(
'ufi method' => 'md5_hash',
'specificity' => 21,
),
'mov' => array(
'ufi method' => 'perpetual',
'specificity' => 21,
),
'mp4' => array(
'ufi method' => 'perpetual',
'specificity' => 21,
),
),
), 'Simple single-directory UFI mapping (step 2).');
$this
->assertUFIMethod('sites/foo', 'mtime');
$this
->assertUFIMethod('sites/foobambamb.woff', 'md5_hash');
$this
->assertUFIMethod('sites/foo/bar/baz.ttf', 'md5_hash');
$this
->assertUFIMethod('sites/movies/foo.mov', 'perpetual');
$this
->assertUFIMethod('sites/movies/bar.mp4', 'perpetual');
}
function testFileUrlAlterHook() {
// We don't want to test the UFI functionality here.
$this
->variableSet(CDN_BASIC_FARFUTURE_UNIQUE_IDENTIFIER_MAPPING_VARIABLE, '*|perpetual');
// Provide a very basic CDN mapping.
$this
->variableSet(CDN_BASIC_MAPPING_VARIABLE, 'http://cdn-a.com');
$filename = 'újjáépítésérol — 100% in B&W.jpg';
$uri = "public://{$filename}";
$this
->touchFile($uri);
cdn_file_url_alter($uri);
$path_info = pathinfo($filename);
$expected = implode('/', array(
'http://cdn-a.com' . base_path() . 'cdn/farfuture',
drupal_hmac_base64('perpetual:forever' . $path_info['filename'], drupal_get_private_key() . drupal_get_hash_salt()),
'perpetual:forever',
variable_get('file_public_path', conf_path() . '/files'),
drupal_encode_path($filename),
));
$this
->assertIdentical($uri, $expected, 'cdn_file_url_alter() works correctly.');
}
}
class CDNImageTestCase extends CDNUnitTestCase {
public static function getInfo() {
return array(
'name' => 'Image and Download Link HTML altering',
'description' => 'Verify that image and anchor link URLs inside HTML are rewritten correctly.',
'group' => 'CDN',
);
}
function setUp() {
parent::setUp();
$this
->loadFile('cdn.fallback.inc');
}
function testImage() {
$cdn = 'http://cdn-a.com';
$this
->variableSet(CDN_BASIC_MAPPING_VARIABLE, $cdn);
$this
->variableSet(CDN_MODE_VARIABLE, CDN_MODE_BASIC);
// Image altering type 1: "just image", i.e. "<img />".
$template = function ($url) {
return '<img alt="Foo!" src="' . $url . '" title="Bar!"/>';
};
// Simplest case possible.
$img_url = base_path() . 'foo/bar/image.png';
$html = $template($img_url);
cdn_html_alter_image_urls($html);
$this
->assertIdentical($template($cdn . $img_url), $html, 'Image HTML correctly altered.');
// Query strings should not be stripped
$img_url = base_path() . 'foo/bar/image.png?foobar';
$html = $template($img_url);
cdn_html_alter_image_urls($html);
$this
->assertIdentical($template($cdn . $img_url), $html, 'Image HTML correctly altered (query string not stripped).');
// In particular: not the query string used to generate image styles.
$img_url = base_path() . 'foo/bar/image.png?itok=1234abcd';
$html = $template($img_url);
cdn_html_alter_image_urls($html);
$this
->assertIdentical($template($cdn . $img_url), $html, 'Image HTML correctly altered (image style query string not stripped).');
// Edge case: a script generating an image is not (yet) supported.
$img_url = base_path() . 'foo/bar/showimage?formula=12345.png';
$html = $template($img_url);
cdn_html_alter_image_urls($html);
$this
->assertIdentical($template($cdn . $img_url), $html, 'Image HTML correctly altered (query string not stripped).');
// Image altering type 2: "linked image", i.e. "<a><img /></a>"..
$template = function ($a_url, $img_url) {
return '<a rel="gallery" href="' . $a_url . '" class="gallery-image"><img alt="Foo!" src="' . $img_url . '" title="Bar!" /></a>';
};
// Simplest case possible: a linked image linking to the same image.
$img_base_url = base_path() . 'foo/bar/image';
$a_url = $img_url = $img_base_url . '.png';
$html = $template($a_url, $img_url);
cdn_html_alter_image_urls($html);
$this
->assertIdentical($template($cdn . $a_url, $cdn . $img_url), $html, 'Linked image HTML correctly altered.');
// Slightly more complex: a linked image linking to a derivative image.
$img_url = $img_base_url . '-thumbnail.png?itok=5678wxyz';
$html = $template($a_url, $img_url);
cdn_html_alter_image_urls($html);
$this
->assertIdentical($template($cdn . $a_url, $cdn . $img_url), $html, 'Linked image HTML correctly altered.');
// Slightly more complex: a linked derivative image linking to another
// derivative image.
$a_url = $img_base_url . '-large.png?itok=9012klmn';
$img_url = $img_base_url . '-thumbnail.png?itok=5678wxyz';
$html = $template($a_url, $img_url);
cdn_html_alter_image_urls($html);
$this
->assertIdentical($template($cdn . $a_url, $cdn . $img_url), $html, 'Linked image HTML correctly altered.');
// Ensure that images linking to content (i.e. not a bigger version of the
// image) don't get their anchors modified
$a_url = base_path() . 'node';
$html = $template($a_url, $img_url);
$html = cdn_post_render_html_alter($html);
$this
->assertIdentical($template($a_url, $cdn . $img_url), $html, 'Linked image HTML correctly altered (anchor unmodified).');
// Same, but now for a link with a query string.
$a_url = base_path() . 'node?foobar';
$html = $template($a_url, $img_url);
$html = cdn_post_render_html_alter($html);
$this
->assertIdentical($template($a_url, $cdn . $img_url), $html, 'Linked image HTML correctly altered (anchor unmodified, even with query strings).');
}
function testOtherContentLink() {
$cdn = 'http://cdn-a.com';
$this
->variableSet(CDN_BASIC_MAPPING_VARIABLE, "{$cdn}|.png .pdf");
$this
->variableSet(CDN_MODE_VARIABLE, CDN_MODE_BASIC);
// Image altering type 1: "just image", i.e. "<img />".
$template = function ($url) {
return '<a href="' . $url . '">Download this!</a>';
};
// Simplest case possible.
$a_url = base_path() . 'foo/bar/image.png';
$html = $template($a_url);
$html = cdn_post_render_html_alter($html);
$this
->assertIdentical($template($cdn . $a_url), $html, 'Other content link correctly altered.');
// Query strings should not be stripped.
$a_url = base_path() . 'foo/bar/image.pdf?foobar';
$html = $template($a_url);
$html = cdn_post_render_html_alter($html);
$this
->assertIdentical($template($cdn . $a_url), $html, 'Other content link correctly altered (query string not stripped).');
// Edge case: a script generating an image is not (yet) supported.
$a_url = base_path() . 'foo/bar/image.gif';
$html = $template($a_url);
$html = cdn_post_render_html_alter($html);
$this
->assertIdentical($template($a_url), $html, 'Other content link correctly NOT altered (extension does not map).');
// Edge case: a script generating an image is not (yet) supported.
$a_url = base_path() . 'foo/bar/showimage?formula=12345.png';
$html = $template($a_url);
$html = cdn_post_render_html_alter($html);
$this
->assertIdentical($template($a_url), $html, 'Other content link correctly NOT altered (extension not pulled from query string).');
}
function testOtherContentLinkWrappingImage() {
$cdn = 'http://cdn-a.com';
$this
->variableSet(CDN_BASIC_MAPPING_VARIABLE, "{$cdn}|.png .jpeg");
$this
->variableSet(CDN_MODE_VARIABLE, CDN_MODE_BASIC);
// Image altering type 2: "linked image", i.e. "<a><img /></a>"..
$template = function ($a_url, $img_url) {
return '<a href="' . $a_url . '"><img src="' . $img_url . '" /></a>';
};
// Test that images linking to a URL with an extension that matches a
// mapped extension, even if the extension is different than the image,
// are modified.
$a_url = base_path() . 'node.jpeg';
$img_url = base_path() . 'foo/bar/image.png';
$html = $template($a_url, $img_url);
$html = cdn_post_render_html_alter($html);
$this
->assertIdentical($template($cdn . $a_url, $cdn . $img_url), $html, 'Other content link wrapping image correctly altered.');
$a_url = base_path() . 'node.gif';
$html = $template($a_url, $img_url);
$html = cdn_post_render_html_alter($html);
$this
->assertIdentical($template($a_url, $cdn . $img_url), $html, 'Other content link wrapping correctly NOT altered (extension does not map).');
}
}
class CDNCssUrlTestCase extends CDNWebTestCase {
public static function getInfo() {
return array(
'name' => 'CSS URLs',
'description' => 'Verify URLs in CSS files are rewritten properly.',
'group' => 'CDN',
);
}
function setUp() {
parent::setUp();
$this
->loadFile('cdn.basic.css.inc');
variable_set(CDN_MODE_VARIABLE, CDN_MODE_BASIC);
variable_set(CDN_BASIC_FARFUTURE_VARIABLE, TRUE);
}
// Makes sure the URL components are preserved.
function testCssUrl() {
global $base_url;
$css_info = array(
array(
'type' => 'file',
'data' => drupal_get_path('module', 'cdn') . '/tests/css/orig/url.css',
),
);
try {
// Make sure the URL in the supplied CSS file matches what we expect.
// trim() is needed to avoid issues with differences in newlines.
$this
->assertEqual(trim(file_get_contents(_cdn_build_css_cache($css_info))), '.home{background:url(' . $base_url . '/' . drupal_get_path('module', 'cdn') . '/tests/css/orig/geo-md-webfont.eot?#iefix);}');
} catch (Exception $exc) {
$this
->fail($exc);
}
}
}
class CDNSEOTestCase extends CDNUnitTestCase {
public static function getInfo() {
return array(
'name' => 'SEO',
'description' => 'Verify SEO duplicate content prevention.',
'group' => 'CDN',
);
}
function testSEO() {
// Test with and without SEO duplicate content prevention. Each case is tested
// with three sorts of paths:
// - page path (without any extension and with all of the three default
// "allowed" extensions, meaning that they c)
// - file path
// - generated file path
// SEO duplicate content prevention disabled.
$this
->variableSet(CDN_SEO_REDIRECT_VARIABLE, FALSE);
$this
->setUserAgent('Amazon CloudFront');
$this
->assertIdentical(_cdn_seo_should_redirect('node/1'), FALSE, 'Disabled SEO duplicate content prevention is respected for page paths.');
$this
->assertIdentical(_cdn_seo_should_redirect('node/1.htm.'), FALSE, 'Disabled SEO duplicate content prevention is respected for page paths.');
$this
->assertIdentical(_cdn_seo_should_redirect('node/1.htm'), FALSE, 'Disabled SEO duplicate content prevention is respected for page paths.');
$this
->assertIdentical(_cdn_seo_should_redirect('node/1.php'), FALSE, 'Disabled SEO duplicate content prevention is respected for page paths.');
$this
->assertIdentical(_cdn_seo_should_redirect('misc/jquery.js'), FALSE, 'Disabled SEO duplicate content prevention is respected for file paths.');
$this
->assertIdentical(_cdn_seo_should_redirect('sites/default/files/styles/thumbnail/foobar.png'), FALSE, 'Disabled SEO duplicate content prevention is respected for generated file paths.');
$this
->setUserAgent($this
->randomName());
$this
->assertIdentical(_cdn_seo_should_redirect('node/1'), FALSE, 'Disabled SEO duplicate content prevention is respected for page paths.');
$this
->assertIdentical(_cdn_seo_should_redirect('node/1.html'), FALSE, 'Disabled SEO duplicate content prevention is respected for page paths.');
$this
->assertIdentical(_cdn_seo_should_redirect('node/1.htm'), FALSE, 'Disabled SEO duplicate content prevention is respected for page paths.');
$this
->assertIdentical(_cdn_seo_should_redirect('node/1.php'), FALSE, 'Disabled SEO duplicate content prevention is respected for page paths.');
$this
->assertIdentical(_cdn_seo_should_redirect('misc/jquery.js'), FALSE, 'Disabled SEO duplicate content prevention is respected for file paths.');
$this
->assertIdentical(_cdn_seo_should_redirect('sites/default/files/styles/thumbnail/foobar.png'), FALSE, 'Disabled SEO duplicate content prevention is respected for generated file paths.');
// SEO page request duplicate content prevention enabled.
$this
->variableSet(CDN_SEO_REDIRECT_VARIABLE, TRUE);
$this
->setUserAgent('The Amazon CloudFront User Agent!');
// Note that this is a superstring of the provided CDN user agent "Amazon CloudFront"!
$this
->assertIdentical(_cdn_seo_should_redirect('node/1'), url('node/1', array(
'absolute' => TRUE,
)), 'Enabled SEO duplicate content prevention works correctly when a CDN UA requests a page path: the response is a redirect.');
$this
->assertIdentical(_cdn_seo_should_redirect('node/1.html'), url('node/1.html', array(
'absolute' => TRUE,
)), 'Enabled SEO duplicate content prevention works correctly when a CDN UA requests a page path: the response is a redirect.');
$this
->assertIdentical(_cdn_seo_should_redirect('node/1.htm'), url('node/1.htm', array(
'absolute' => TRUE,
)), 'Enabled SEO duplicate content prevention works correctly when a CDN UA requests a page path: the response is a redirect.');
$this
->assertIdentical(_cdn_seo_should_redirect('node/1.php'), url('node/1.php', array(
'absolute' => TRUE,
)), 'Enabled SEO duplicate content prevention works correctly when a CDN UA requests a page path: the response is a redirect.');
$this
->assertIdentical(_cdn_seo_should_redirect('misc/jquery.js'), FALSE, 'Enabled SEO duplicate content prevention works correctly when a CDN UA requests a file path: the response is not a redirect.');
$this
->assertIdentical(_cdn_seo_should_redirect('sites/default/files/styles/thumbnail/foobar.png'), FALSE, 'Enabled SEO duplicate content prevention works correctly when a CDN UA requests a generated file path: the response is not a redirect.');
$this
->setUserAgent($this
->randomName());
$this
->assertIdentical(_cdn_seo_should_redirect('node/1'), FALSE, 'Enabled SEO duplicate content prevention works correctly when a non-CDN UA requests a page path: the response is a redirect.');
$this
->assertIdentical(_cdn_seo_should_redirect('node/1.htm'), FALSE, 'Enabled SEO duplicate content prevention works correctly when a non-CDN UA requests a page path: the response is a redirect.');
$this
->assertIdentical(_cdn_seo_should_redirect('node/1.html'), FALSE, 'Enabled SEO duplicate content prevention works correctly when a non-CDN UA requests a page path: the response is a redirect.');
$this
->assertIdentical(_cdn_seo_should_redirect('node/1.php'), FALSE, 'Enabled SEO duplicate content prevention works correctly when a non-CDN UA requests a page path: the response is a redirect.');
$this
->assertIdentical(_cdn_seo_should_redirect('misc/jquery.js'), FALSE, 'Enabled SEO duplicate content prevention works correctly when a non-CDN UA requests a file path: the response is not a redirect.');
$this
->assertIdentical(_cdn_seo_should_redirect('sites/default/files/styles/thumbnail/foobar.png'), FALSE, 'Enabled SEO duplicate content prevention works correctly when a non-CDN UA requests a generated file path: the response is not a redirect.');
}
}