diff --git a/dfp.info b/dfp.info
index 1334cea..9f92d5b 100755
--- a/dfp.info
+++ b/dfp.info
@@ -16,6 +16,12 @@ dependencies[] = taxonomy
files[] = plugins/export_ui/dfp_tag_ui.class.inc
files[] = plugins/export_ui/dfp_ctools_export_ui.inc
-files[] = tests/dfp.test
+files[] = tests/dfp_ad_categories.test
+files[] = tests/dfp_ads.test
+files[] = tests/dfp_base.test
+files[] = tests/dfp_display_tag.test
+files[] = tests/dfp_globals.test
+files[] = tests/dfp_tokens.test
+files[] = tests/dfp_unit.test
testing_api = 2.x
diff --git a/tests/dfp.test b/tests/dfp.test
deleted file mode 100644
index c8d344c..0000000
--- a/tests/dfp.test
+++ /dev/null
@@ -1,565 +0,0 @@
-admin_user = $this->drupalCreateUser(array('administer DFP', 'administer taxonomy', 'access administration pages', 'administer blocks', 'bypass node access', 'administer nodes', 'edit terms in 1'));
- $this->drupalLogin($this->admin_user);
-
- // Add the some global settings needed for dfp ads to work.
- variable_set('dfp_network_id', '12345');
- variable_set('dfp_default_slug', $this->randomName(8));
- }
-
- /**
- * Create a simple $edit array to be used on the DFP tag form to create a new
- * DFP tag object.
- */
- function dfpBasicTagEditValues() {
- $machinename = drupal_strtolower($this->randomName(8));
- $basic_tag = array(
- 'machinename' => $machinename,
- 'slot' => $machinename,
- 'size' => implode(',', $this->dfpGenerateSize(2)),
- 'adunit' => $this->randomName(8),
- 'block' => 1,
- 'settings[slug]' => $this->randomName(32),
- 'settings[adsense_ad_types]' => '',
- 'settings[adsense_channel_ids]' => '',
- 'settings[adsense_colors][background]' => '',
- 'settings[adsense_colors][border]' => '',
- 'settings[adsense_colors][link]' => '',
- 'settings[adsense_colors][text]' => '',
- 'settings[adsense_colors][url]' => '',
- 'targeting[0][target]' => $this->randomName(8),
- 'targeting[0][value]' => $this->randomName(8),
- 'breakpoints[0][browser_size]' => $this->dfpGenerateSize(),
- 'breakpoints[0][ad_sizes]' => implode(',', $this->dfpGenerateSize(2)),
- );
-
- return $basic_tag;
- }
-
- /**
- * Generate a random size (or array or sizes) to use when testing tags
- * formatted as ###x###.
- */
- function dfpGenerateSize($count = 1) {
- $sizes = array('300x250', '300x600', '728x90', '728x10', '160x600', '120x80', '300x100', '50x50', '160x300');
- shuffle($sizes);
-
- return $count == 1 ? array_pop($sizes) : array_slice($sizes, 0, min($count, count($sizes)));
- }
-
- /**
- * Creates a basic dfp ad tag.
- */
- function createTag($edit = array()) {
- // Create a new tag.
- $edit += $this->dfpBasicTagEditValues();
- $this->drupalPost('admin/structure/dfp_ads/add', $edit, t('Save'));
-
- // Load the tag object.
- $tag = dfp_tag_load($edit['machinename']);
- $this->assertTrue(is_object($tag) && $tag->machinename = $edit['machinename'], 'The new tag was saved correctly.');
-
- // Display the new tag.
- $edit = array();
- $delta = 'dfp_' . (drupal_strlen($tag->machinename) >= 32 ? md5($tag->machinename) : $tag->machinename);
- $edit['blocks[' . $delta . '][region]'] = 'sidebar_first';
- $this->drupalPost('admin/structure/block', $edit, t('Save blocks'));
-
- return $tag;
- }
-
- /**
- * Edit a given tag specified by $machinename with the given values.
- */
- function editTag($machinename, &$edit) {
- // Make sure there is no machinename set when we are editing.
- if (isset($edit['machinename'])) {
- unset($edit['machinename']);
- }
- $this->drupalPost('admin/structure/dfp_ads/list/' . $machinename . '/edit', $edit, t('Save'));
- $tag = dfp_tag_load($machinename);
- return $tag;
- }
-
- /**
- * Create a taxonomy term.
- */
- function createTerm($vocabulary) {
- $term = new stdClass();
- $term->name = $this->randomName();
- $term->description = $this->randomName();
- // Use the first available text format.
- $term->format = db_query_range('SELECT format FROM {filter_format}', 0, 1)->fetchField();
- $term->vid = $vocabulary->vid;
- taxonomy_term_save($term);
- return $term;
- }
-
- /**
- * Assert that a property is properly being set.
- */
- function assertPropertySet($property, $key, $val) {
- $pattern = '|' . '.set' . $property . '\("' . $key . '",{1}\s(.)*' . addslashes($val) . '|';
- $this->assertPattern($pattern, 'A ' . $property . ' property was set for ' . $key . ' = ' . $val);
- }
-
- /**
- * Assert that a property is not being set.
- */
- function assertPropertyNotSet($property, $key, $val) {
- $pattern = '|' . '.set' . $property . '\("' . $key . '",{1}\s(.)*' . addslashes($val) . '|';
- $this->assertNoPattern($pattern, 'A ' . $property . ' property was not set for ' . $key . ' = ' . $val);
- }
-
-}
-
-class dfpDisplayTagTest extends dfpBaseTest {
- /**
- * Implements getInfo().
- */
- public static function getInfo() {
- return array(
- 'name' => t('Displaying DFP Tags'),
- 'description' => t('Tests for displaying DFP tags.'),
- 'group' => t('DFP'),
- );
- }
-
- function testDisplayTag() {
- // Create a simple tag as a block.
- $tag = $this->createTag();
- $this->assertRaw('googletag.defineSlot("' . variable_get('dfp_network_id', '') . '/' . $tag->adunit . '", ' . dfp_format_size($tag->size) . ', "' . $tag->placeholder_id . '")', 'The ad slot has been correctly defined in javascript.');
-
- // Create a tag with a machine name longer than 32 characters.
- $edit = array('machinename' => drupal_strtolower($this->randomName(64)));
- $tag = $this->createTag($edit);
- $this->assertRaw('googletag.defineSlot("' . variable_get('dfp_network_id', '') . '/' . $tag->adunit . '", ' . dfp_format_size($tag->size) . ', "' . $tag->placeholder_id . '")', 'The ad slot with a very long machine name has been correctly defined in javascript.');
-
- // Ensure the DPF click url is safe.
- variable_set('dfp_click_url', 'javascript://example.com?foo&bar');
- $this->drupalGet('/');
- $this->assertNoRaw('javascript://example.com');
- $pattern = '|.setClickUrl\("http(.*):\/\/(.*)javascript%3A\/\/example.com%3Ffoo%26bar"\)|';
- $this->assertPattern($pattern, 'Click URL is filtered for bad protocols and absolute.');
-
- variable_set('dfp_click_url', 'http://example.com?foo&bar');
- $this->drupalGet('/');
- $this->assertRaw('.setClickUrl("http://example.com?foo&bar")', 'Valid external Click URL is not mangled.');
- }
-
- function testDisplayTagWithMapping() {
- $edit = $this->dfpBasicTagEditValues();
-
- // Create a simple tag with a mapping. Verify javascript on page.
- $tag = $this->createTag($edit);
- $mapping_sizes = explode(',', $edit['breakpoints[0][ad_sizes]']);
- $size_count = count($mapping_sizes);
- // Calculate addSize mappings.
- $mapping_tag = '.addSize(';
- $mapping_tag .= '[' . str_replace('x', ', ', $edit['breakpoints[0][browser_size]']) . '], ';
- $mapping_tag .= ($size_count > 1) ? '[' : '';
- for ($i = 0; $i < $size_count; $i++) {
- $mapping_sizes[$i] = '[' . str_replace('x', ', ', $mapping_sizes[$i]) . ']';
- $mapping_tag .= ($i + 1 !== $size_count) ? $mapping_sizes[$i] . ', ' : $mapping_sizes[$i];
- }
- $mapping_tag .= ($size_count > 1) ? '])' : ')';
- $this->assertRaw('googletag.sizeMapping()', 'The ad slot correctly attaches size mapping.');
- $this->assertRaw('.defineSizeMapping(mapping)', 'The ad slot correctly defines size mapping.');
- $this->assertRaw($mapping_tag, 'The ad slot correctly defines specific size mappings.');
-
- // Create a tag with invalid browser size mappings.
- $edit['breakpoints[0][browser_size]'] = $this->randomName(8);
- $this->editTag($tag->machinename, $edit);
- $this->assertText(t('The browser size can only contain numbers and the character x.'), 'An error was correctly thrown when invalid characters.');
-
- // Create a tag with invalid ad size mappings.
- $edit['breakpoints[0][browser_size]'] = $this->dfpGenerateSize();
- $edit['breakpoints[0][ad_sizes]'] = $this->randomName(8);
- $this->editTag($tag->machinename, $edit);
- $this->assertText(t('The ad size(s) can only contain numbers, the character x and commas.'), 'An error was correctly thrown when invalid characters.');
- }
-
- function testSlug() {
- $edit = $this->dfpBasicTagEditValues();
-
- // Create a tag without a slug, display it and ensure the default slug is
- // displayed.
- variable_set('dfp_default_slug', '
Global slug
');
- $edit['settings[slug]'] = '';
- $tag = $this->createTag($edit);
- $this->assertRaw('' . check_plain(variable_get('dfp_default_slug', '')) . '
', 'The default slug is correctly used when no slug exists for an individual tag.');
-
- // Change the slug to and ensure that no slug is displayed.
- $edit['settings[slug]'] = '';
- $this->editTag($tag->machinename, $edit);
- $this->assertNoRaw('', t('No slug is appearing when "@none" is used.', array('@none' => '
')));
-
- // Specify a slug and check that it shows instead of the default slug.
- $slug = 'Custom slug
';
- $edit['settings[slug]'] = $slug;
- $this->editTag($tag->machinename, $edit);
- $this->assertRaw('' . check_plain($slug) . '
', 'The provided slug is correctly displayed with its tag.');
- }
-
- function testTargeting() {
- $edit = $this->dfpBasicTagEditValues();
-
- // Create a tag with a target with only one value.
- $tag = $this->createTag($edit);
- $this->assertPropertySet('Targeting', $edit['targeting[0][target]'], $edit['targeting[0][value]']);
-
- // Create a tag with a target with multiple values.
- $values = array($this->randomName(8), $this->randomName(8), $this->randomName(8));
- $edit['targeting[0][target]'] = $this->randomName(8);
- $edit['targeting[0][value]'] = implode(', ', $values);
- $this->editTag($tag->machinename, $edit);
- $this->assertPropertySet('Targeting', $edit['targeting[0][target]'], implode('","', $values));
-
- // Create a tag with a target but no value.
- $edit['targeting[0][target]'] = $this->randomName(8);
- $edit['targeting[0][value]'] = '';
- $this->editTag($tag->machinename, $edit);
- $this->assertText(t('The value cannot be empty if a target exists.'), 'An error was correctly thrown when a target has no value.');
-
- // Create a tag with an empty target, but a value.
- $edit['targeting[0][target]'] = '';
- $edit['targeting[0][value]'] = $this->randomName(8);
- $this->editTag($tag->machinename, $edit);
- $this->assertText(t('The target cannot be empty if a value exists.'), 'An error was correctly thrown when a target is blank, but a value has been entered.');
-
- // Create a tag with multiple targets.
- $count = 3;
- for ($i = 0; $i < $count; $i++) {
- $edit['targeting[' . $i . '][target]'] = $this->randomName(8);
- $edit['targeting[' . $i . '][value]'] = $this->randomName(8);
- $this->drupalPost('admin/structure/dfp_ads/list/' . $tag->machinename . '/edit', $edit, t('Add another target'));
- $this->editTag($tag->machinename, $edit);
- }
-
- for ($i = 0; $i < $count; $i++) {
- $this->assertPropertySet('Targeting', $edit['targeting[' . $i . '][target]'], $edit['targeting[' . $i . '][value]']);
- }
- // Make sure that empty values are ignored.
- $this->drupalPost('admin/structure/dfp_ads/list/' . $tag->machinename . '/edit', $edit, t('Add another target'));
- $this->editTag($tag->machinename, $edit);
- $this->assertPropertyNotSet('Targeting', '', '');
-
- // Test that target can be removed.
- $edit['targeting[0][target]'] = '';
- $edit['targeting[0][value]'] = '';
- $this->editTag($tag->machinename, $edit);
- $this->assertPropertyNotSet('Targeting', '', '');
- }
-
- function testBackfill() {
- $edit = $this->dfpBasicTagEditValues();
-
- // Create a tag with backfill settings.
- $colors = array('background', 'border', 'link', 'text', 'url');
- $types = array('text', 'image', 'text_image');
- shuffle($types);
-
- $edit['settings[adsense_ad_types]'] = array_pop($types);
- $edit['settings[adsense_channel_ids]'] = $this->randomName(8);
- foreach ($colors as $color) {
- $edit['settings[adsense_colors][' . $color . ']'] = drupal_strtoupper($this->randomName(8));
- }
- $tag = $this->createTag($edit);
- $this->assertPropertySet('', 'adsense_ad_types', $edit['settings[adsense_ad_types]']);
- $this->assertPropertySet('', 'adsense_channel_ids', $edit['settings[adsense_channel_ids]']);
- foreach ($colors as $color) {
- $this->assertPropertySet('', 'adsense_' . $color . '_color', $edit['settings[adsense_colors][' . $color . ']']);
- }
- }
-
-}
-
-class dfpAdCategoriesTest extends dfpBaseTest {
- /**
- * Implements getInfo().
- */
- public static function getInfo() {
- return array(
- 'name' => t('DFP Ad Categories'),
- 'description' => t('Tests the functionaility of DFP ad categories.'),
- 'group' => t('DFP'),
- );
- }
-
- function testEnableDisableAdCategories() {
- // Check that enabling DFP Ad Categories for the "tags" vocabulary works.
- $edit = array(
- 'dfp_enable_ad_categories' => 1,
- 'dfp_enable_ad_categories_bundles[tags]' => 'tags',
- );
- $this->drupalPost('admin/structure/dfp_ads/settings', $edit, t('Save configuration'));
- $this->drupalGet('admin/structure/taxonomy/tags/add');
- $this->assertFieldByName('field_dfp_ad_categories[und]');
-
- // Check that disabling DFP Ad Categories vocabulary works even when a
- // bundle is selected.
- $edit = array(
- 'dfp_enable_ad_categories' => 0,
- );
- $this->drupalPost('admin/structure/dfp_ads/settings', $edit, t('Save configuration'));
- $this->drupalGet('admin/structure/taxonomy/tags/add');
- $this->assertNoFieldByName('field_dfp_ad_categories[und]');
-
- // Check that disabling DFP Ad Categories on a specific vocabulary works.
- // For this test to be valid, we first need to reenable DFP Ad Categories.
- $edit = array(
- 'dfp_enable_ad_categories' => 1,
- 'dfp_enable_ad_categories_bundles[tags]' => 'tags',
- );
- $this->drupalPost('admin/structure/dfp_ads/settings', $edit, t('Save configuration'));
- $this->drupalGet('admin/structure/taxonomy/tags/add');
- $edit = array(
- 'dfp_enable_ad_categories_bundles[tags]' => 0,
- );
- $this->drupalPost('admin/structure/dfp_ads/settings', $edit, t('Save configuration'));
- $this->drupalGet('admin/structure/taxonomy/tags/add');
- $this->assertNoFieldByName('field_dfp_ad_categories[und]');
- }
-
- // Test that DFP Catetories are displayed properly.
- function testDisplayAdCategories() {
- $dfp_add_categories_vocabulary = taxonomy_vocabulary_machine_name_load('dfp_ad_categories');
- $tags_vocabulary = taxonomy_vocabulary_machine_name_load('tags');
-
- // Turn on DFP ad categories for the "tags" vocabulary.
- $edit = array(
- 'dfp_enable_ad_categories' => 1,
- 'dfp_enable_ad_categories_bundles[tags]' => 'tags',
- );
- $this->drupalPost('admin/structure/dfp_ads/settings', $edit, t('Save configuration'));
-
- // Create a new DFP Ad Category term.
- $dfp_category = $this->createTerm($dfp_add_categories_vocabulary);
- $control_tag = $this->createTerm($tags_vocabulary);
- $test_tag = $this->createTerm($tags_vocabulary);
-
- // Create a new "Article" node with these two tags.
- $edit = array(
- 'title' => $this->randomName(8),
- 'field_tags[und]' => $control_tag->name . ', ' . $test_tag->name,
- );
- $this->drupalPost('node/add/article', $edit, t('Save'));
-
- // Edit one the new tags and tag it with a DFP Ad Category.
- $edit = array(
- 'field_dfp_ad_categories[und]' => $dfp_category->tid,
- );
- $this->drupalPost('taxonomy/term/' . $test_tag->tid . '/edit', $edit, t('Save'));
-
- // Create a DFP ad slot that targets the [dfp_tag:ad_categories] token.
- $edit = $this->dfpBasicTagEditValues();
-
- // Create a tag that uses the slot token in a target.
- $edit['slot'] = $this->randomName(8);
- $edit['targeting[0][target]'] = 'categories';
- $edit['targeting[0][value]'] = '[dfp_tag:ad_categories]';
- $tag = $this->createTag($edit);
-
- // Check that when we are on the node page, that the DFP Ad Category is used
- // and that the control tag is also displayed.
- $this->drupalGet('node/1');
- $this->assertPropertySet('Targeting', 'categories', $control_tag->name);
- $this->assertPropertySet('Targeting', 'categories', $dfp_category->name);
-
- // Check that when we are on the term page for one of DFP Ad Categories that
- // it is correctly included.
- $this->drupalGet('taxonomy/term/' . $dfp_category->tid);
- $this->assertPropertySet('Targeting', 'categories', $dfp_category->name);
-
- // Check that when we are on a term page for a term with a coresponding
- // DFP Ad Categories the DFP Ad Category is included.
- $this->drupalGet('taxonomy/term/' . $test_tag->tid);
- $this->assertPropertySet('Targeting', 'categories', $dfp_category->name);
- }
-}
-
-class dfpTokensTest extends dfpBaseTest {
- /**
- * Implements getInfo().
- */
- public static function getInfo() {
- return array(
- 'name' => t('DFP Tokens'),
- 'description' => t('Tests for custom tokens created by the DFP module.'),
- 'group' => t('DFP'),
- );
- }
-
- function testSlotToken() {
- $edit = $this->dfpBasicTagEditValues();
-
- // Create a tag that uses the slot token in a target.
- $test_slot = $this->randomName(8);
- $edit['slot'] = $test_slot;
- $edit['targeting[0][target]'] = 'slot';
- $edit['targeting[0][value]'] = '[dfp_tag:slot]';
- $tag = $this->createTag($edit);
- $this->assertPropertySet('Targeting', 'slot', $test_slot);
- }
-
- function testNetworkIDToken() {
- $edit = $this->dfpBasicTagEditValues();
-
- // Create a tag that uses the networkid token in a target.
- $test_network_id = $this->randomName(8);
- variable_set('dfp_network_id', $test_network_id);
- $edit['targeting[0][target]'] = 'network id';
- $edit['targeting[0][value]'] = '[dfp_tag:network_id]';
- $tag = $this->createTag($edit);
- $this->assertPropertySet('Targeting', 'network id', $test_network_id);
- }
-
- function testUrlPartsToken() {
- // Create a tag that uses the url parts token in a target.
- $tag = $this->createTag();
- $url = 'admin/structure/dfp_ads';
- $url_parts = explode('/', $url);
-
- $max_parts_to_test = 3;
- for ($i = 1; $i <= $max_parts_to_test; $i++) {
- $edit['targeting[0][target]'] = 'url parts';
- $edit['targeting[0][value]'] = '[dfp_tag:url_parts:' . $i . ']';
- $this->editTag($tag->machinename, $edit);
-
- $this->drupalGet($url);
- $replacement = implode('/', array_slice($url_parts, 0, $i));
- $this->assertPropertySet('Targeting', 'url parts', $replacement);
- }
- }
-
-}
-
-class dfpGlobalsTest extends dfpBaseTest {
- /**
- * Implements getInfo().
- */
- public static function getInfo() {
- return array(
- 'name' => t('Gloabl DFP Tag Settings'),
- 'description' => t('Tests for the settings defined in admin/structure/dfp_ads/settings.'),
- 'group' => t('DFP'),
- );
- }
-
- function testGlobalSettingsOn() {
- $injected_js = $this->randomName(32);
- $target = array(
- 'target' => $this->randomName(8),
- 'value' => $this->randomName(8),
- );
-
- variable_set('dfp_async_rendering', '1');
- variable_set('dfp_single_request', '1');
- variable_set('dfp_collapse_empty_divs', '1');
- variable_set('dfp_injected_js', $injected_js);
- variable_set('dfp_targeting', array($target));
- $this->drupalGet('/');
- $this->assertRaw('googletag.pubads().enableAsyncRendering();', 'Asyncronous rendering is turned on.');
- $this->assertRaw('googletag.pubads().enableSingleRequest();', 'Single request is turned on.');
- $this->assertRaw('googletag.pubads().collapseEmptyDivs();', 'Collapse empty divs is turned on.');
- $this->assertRaw($injected_js, 'Injected javascript correctly appears on the page.');
- $this->assertRaw('googletag.pubads().setTargeting("' . $target['target'] . '", "' . $target['value'] . '");', 'Global targetting values appear correclty in javascript.');
- }
-
- function testGlobalSettingsOff() {
- variable_set('dfp_async_rendering', '0');
- variable_set('dfp_single_request', '0');
- variable_set('dfp_collapse_empty_divs', '0');
- $this->drupalGet('/');
- $this->assertNoRaw('googletag.pubads().enableAsyncRendering();', 'Asyncronous rendering is turned off.');
- $this->assertNoRaw('googletag.pubads().enableSingleRequest();', 'Single request is turned off.');
- $this->assertNoRaw('googletag.pubads().collapseEmptyDivs();', 'Collapse empty divs is turned off.');
- }
-
-}
-
-class dfpAdTestTest extends dfpBaseTest {
- /**
- * Implements getInfo().
- */
- public static function getInfo() {
- return array(
- 'name' => t('Displaying AdTest DFP Tags'),
- 'description' => t('Tests for displaying overridden DFP tags for ad test purposes.'),
- 'group' => t('DFP'),
- );
- }
-
- function testTestPage() {
- $tag = $this->createTag();
-
- $override = $this->randomName(8);
- $this->drupalGet('admin/structure/dfp_ads/test_page', array('query' => array('adunit_override' => $override)));
- $this->assertRaw('googletag.defineSlot("' . variable_get('dfp_network_id', '') . '/' . $override . '"', 'The Ad Unit Name was properly overridden on the Ad Test Page.');
- }
-
- function testQueryString() {
- $tag = $this->createTag();
-
- $override = $this->randomName(8);
- variable_set('dfp_adtest_adunit', $override);
- $this->drupalGet('admin/structure/dfp_ads/test_page', array('query' => array('adtest' => 'true')));
- $this->assertRaw('googletag.defineSlot("' . variable_get('dfp_network_id', '') . '/' . $override . '"', 'The Ad Unit Name was properly overridden using the adtest query string.');
-
- // Check that nefarious overrride values are caught because security.
- $nefarious_override = "";
- $this->drupalGet('admin/structure/dfp_ads/test_page', array('query' => array('adunit_override' => $nefarious_override)));
- $this->assertNoRaw($nefarious_override, 'Only strings without executable code can be used for the adunit_override query string.');
- }
-
-}
-
-class DFPUnitTest extends DrupalUnitTestCase {
- protected $profile = 'testing';
-
- /**
- * Implementation of setUp().
- */
- function setUp() {
- // Enable a couple modules.
- drupal_load('module', 'dfp');
- parent::setUp();
- }
-
- /**
- * Implements getInfo().
- */
- public static function getInfo() {
- return array(
- 'name' => t('DFP Unit Tests'),
- 'description' => t('Checks the integrity of certain DFP functions.'),
- 'group' => t('DFP'),
- );
- }
-
- function testDFPformatSize() {
- $sizes = '300x250';
- $expected_result = '[300, 250]';
-
- $this->assertTrue(dfp_format_size($sizes) == $expected_result, 'The dfp_format_sizes function correctly handles an single size.');
- $sizes = '300x250,728x90';
- $expected_result = '[[300, 250], [728, 90]]';
- $this->assertTrue(dfp_format_size($sizes) == $expected_result, 'The dfp_format_sizes function correctly handles multiple sizes.');
- }
-}
diff --git a/tests/dfp_ad_categories.test b/tests/dfp_ad_categories.test
new file mode 100644
index 0000000..13f3ce5
--- /dev/null
+++ b/tests/dfp_ad_categories.test
@@ -0,0 +1,110 @@
+ t('DFP Ad Categories'),
+ 'description' => t('Tests the functionality of DFP ad categories.'),
+ 'group' => t('DFP'),
+ );
+ }
+
+ function testEnableDisableAdCategories() {
+ // Check that enabling DFP Ad Categories for the "tags" vocabulary works.
+ $edit = array(
+ 'dfp_enable_ad_categories' => 1,
+ 'dfp_enable_ad_categories_bundles[tags]' => 'tags',
+ );
+ $this->drupalPost('admin/structure/dfp_ads/settings', $edit, t('Save configuration'));
+ $this->drupalGet('admin/structure/taxonomy/tags/add');
+ $this->assertFieldByName('field_dfp_ad_categories[und]');
+
+ // Check that disabling DFP Ad Categories vocabulary works even when a
+ // bundle is selected.
+ $edit = array(
+ 'dfp_enable_ad_categories' => 0,
+ );
+ $this->drupalPost('admin/structure/dfp_ads/settings', $edit, t('Save configuration'));
+ $this->drupalGet('admin/structure/taxonomy/tags/add');
+ $this->assertNoFieldByName('field_dfp_ad_categories[und]');
+
+ // Check that disabling DFP Ad Categories on a specific vocabulary works.
+ // For this test to be valid, we first need to re-enable DFP Ad Categories.
+ $edit = array(
+ 'dfp_enable_ad_categories' => 1,
+ 'dfp_enable_ad_categories_bundles[tags]' => 'tags',
+ );
+ $this->drupalPost('admin/structure/dfp_ads/settings', $edit, t('Save configuration'));
+ $this->drupalGet('admin/structure/taxonomy/tags/add');
+ $edit = array(
+ 'dfp_enable_ad_categories_bundles[tags]' => 0,
+ );
+ $this->drupalPost('admin/structure/dfp_ads/settings', $edit, t('Save configuration'));
+ $this->drupalGet('admin/structure/taxonomy/tags/add');
+ $this->assertNoFieldByName('field_dfp_ad_categories[und]');
+ }
+
+ // Test that DFP Categories are displayed properly.
+ function testDisplayAdCategories() {
+ $dfp_add_categories_vocabulary = taxonomy_vocabulary_machine_name_load('dfp_ad_categories');
+ $tags_vocabulary = taxonomy_vocabulary_machine_name_load('tags');
+
+ // Turn on DFP ad categories for the "tags" vocabulary.
+ $edit = array(
+ 'dfp_enable_ad_categories' => 1,
+ 'dfp_enable_ad_categories_bundles[tags]' => 'tags',
+ );
+ $this->drupalPost('admin/structure/dfp_ads/settings', $edit, t('Save configuration'));
+
+ // Create a new DFP Ad Category term.
+ $dfp_category = $this->createTerm($dfp_add_categories_vocabulary);
+ $control_tag = $this->createTerm($tags_vocabulary);
+ $test_tag = $this->createTerm($tags_vocabulary);
+
+ // Create a new "Article" node with these two tags.
+ $edit = array(
+ 'title' => $this->randomName(8),
+ 'field_tags[und]' => $control_tag->name . ', ' . $test_tag->name,
+ );
+ $this->drupalPost('node/add/article', $edit, t('Save'));
+
+ // Edit one the new tags and tag it with a DFP Ad Category.
+ $edit = array(
+ 'field_dfp_ad_categories[und]' => $dfp_category->tid,
+ );
+ $this->drupalPost('taxonomy/term/' . $test_tag->tid . '/edit', $edit, t('Save'));
+
+ // Create a DFP ad slot that targets the [dfp_tag:ad_categories] token.
+ $edit = $this->dfpBasicTagEditValues();
+
+ // Create a tag that uses the slot token in a target.
+ $edit['slot'] = $this->randomName(8);
+ $edit['targeting[0][target]'] = 'categories';
+ $edit['targeting[0][value]'] = '[dfp_tag:ad_categories]';
+ $tag = $this->createTag($edit);
+
+ // Check that when we are on the node page, that the DFP Ad Category is used
+ // and that the control tag is also displayed.
+ $this->drupalGet('node/1');
+ $this->assertPropertySet('Targeting', 'categories', $control_tag->name);
+ $this->assertPropertySet('Targeting', 'categories', $dfp_category->name);
+
+ // Check that when we are on the term page for one of DFP Ad Categories that
+ // it is correctly included.
+ $this->drupalGet('taxonomy/term/' . $dfp_category->tid);
+ $this->assertPropertySet('Targeting', 'categories', $dfp_category->name);
+
+ // Check that when we are on a term page for a term with a corresponding
+ // DFP Ad Categories the DFP Ad Category is included.
+ $this->drupalGet('taxonomy/term/' . $test_tag->tid);
+ $this->assertPropertySet('Targeting', 'categories', $dfp_category->name);
+ }
+}
diff --git a/tests/dfp_ads.test b/tests/dfp_ads.test
new file mode 100644
index 0000000..897b976
--- /dev/null
+++ b/tests/dfp_ads.test
@@ -0,0 +1,42 @@
+ t('Displaying AdTest DFP Tags'),
+ 'description' => t('Tests for displaying overridden DFP tags for ad test purposes.'),
+ 'group' => t('DFP'),
+ );
+ }
+
+ function testTestPage() {
+ $tag = $this->createTag();
+
+ $override = $this->randomName(8);
+ $this->drupalGet('admin/structure/dfp_ads/test_page', array('query' => array('adunit_override' => $override)));
+ $this->assertRaw('googletag.defineSlot("' . variable_get('dfp_network_id', '') . '/' . $override . '"', 'The Ad Unit Name was properly overridden on the Ad Test Page.');
+ }
+
+ function testQueryString() {
+ $tag = $this->createTag();
+
+ $override = $this->randomName(8);
+ variable_set('dfp_adtest_adunit', $override);
+ $this->drupalGet('admin/structure/dfp_ads/test_page', array('query' => array('adtest' => 'true')));
+ $this->assertRaw('googletag.defineSlot("' . variable_get('dfp_network_id', '') . '/' . $override . '"', 'The Ad Unit Name was properly overridden using the adtest query string.');
+
+ // Check that nefarious override values are caught because security.
+ $nefarious_override = "";
+ $this->drupalGet('admin/structure/dfp_ads/test_page', array('query' => array('adunit_override' => $nefarious_override)));
+ $this->assertNoRaw($nefarious_override, 'Only strings without executable code can be used for the adunit_override query string.');
+ }
+
+}
diff --git a/tests/dfp_base.test b/tests/dfp_base.test
new file mode 100644
index 0000000..94ba6e3
--- /dev/null
+++ b/tests/dfp_base.test
@@ -0,0 +1,130 @@
+admin_user = $this->drupalCreateUser(array('administer DFP', 'administer taxonomy', 'access administration pages', 'administer blocks', 'bypass node access', 'administer nodes', 'edit terms in 1'));
+ $this->drupalLogin($this->admin_user);
+
+ // Add the some global settings needed for dfp ads to work.
+ variable_set('dfp_network_id', '12345');
+ variable_set('dfp_default_slug', $this->randomName(8));
+ }
+
+ /**
+ * Create a simple $edit array to be used on the DFP tag form to create a new
+ * DFP tag object.
+ */
+ function dfpBasicTagEditValues() {
+ $machinename = drupal_strtolower($this->randomName(8));
+ $basic_tag = array(
+ 'machinename' => $machinename,
+ 'slot' => $machinename,
+ 'size' => implode(',', $this->dfpGenerateSize(2)),
+ 'adunit' => $this->randomName(8),
+ 'block' => 1,
+ 'settings[slug]' => $this->randomName(32),
+ 'settings[adsense_ad_types]' => '',
+ 'settings[adsense_channel_ids]' => '',
+ 'settings[adsense_colors][background]' => '',
+ 'settings[adsense_colors][border]' => '',
+ 'settings[adsense_colors][link]' => '',
+ 'settings[adsense_colors][text]' => '',
+ 'settings[adsense_colors][url]' => '',
+ 'targeting[0][target]' => $this->randomName(8),
+ 'targeting[0][value]' => $this->randomName(8),
+ 'breakpoints[0][browser_size]' => $this->dfpGenerateSize(),
+ 'breakpoints[0][ad_sizes]' => implode(',', $this->dfpGenerateSize(2)),
+ );
+
+ return $basic_tag;
+ }
+
+ /**
+ * Generate a random size (or array or sizes) to use when testing tags
+ * formatted as ###x###.
+ */
+ function dfpGenerateSize($count = 1) {
+ $sizes = array('300x250', '300x600', '728x90', '728x10', '160x600', '120x80', '300x100', '50x50', '160x300');
+ shuffle($sizes);
+
+ return $count == 1 ? array_pop($sizes) : array_slice($sizes, 0, min($count, count($sizes)));
+ }
+
+ /**
+ * Creates a basic dfp ad tag.
+ */
+ function createTag($edit = array()) {
+ // Create a new tag.
+ $edit += $this->dfpBasicTagEditValues();
+ $this->drupalPost('admin/structure/dfp_ads/add', $edit, t('Save'));
+
+ // Load the tag object.
+ $tag = dfp_tag_load($edit['machinename']);
+ $this->assertTrue(is_object($tag) && $tag->machinename = $edit['machinename'], 'The new tag was saved correctly.');
+
+ // Display the new tag.
+ $edit = array();
+ $delta = 'dfp_' . (drupal_strlen($tag->machinename) >= 32 ? md5($tag->machinename) : $tag->machinename);
+ $edit['blocks[' . $delta . '][region]'] = 'sidebar_first';
+ $this->drupalPost('admin/structure/block', $edit, t('Save blocks'));
+
+ return $tag;
+ }
+
+ /**
+ * Edit a given tag specified by $machinename with the given values.
+ */
+ function editTag($machinename, &$edit) {
+ // Make sure there is no machinename set when we are editing.
+ if (isset($edit['machinename'])) {
+ unset($edit['machinename']);
+ }
+ $this->drupalPost('admin/structure/dfp_ads/list/' . $machinename . '/edit', $edit, t('Save'));
+ $tag = dfp_tag_load($machinename);
+ return $tag;
+ }
+
+ /**
+ * Create a taxonomy term.
+ */
+ function createTerm($vocabulary) {
+ $term = new stdClass();
+ $term->name = $this->randomName();
+ $term->description = $this->randomName();
+ // Use the first available text format.
+ $term->format = db_query_range('SELECT format FROM {filter_format}', 0, 1)->fetchField();
+ $term->vid = $vocabulary->vid;
+ taxonomy_term_save($term);
+ return $term;
+ }
+
+ /**
+ * Assert that a property is properly being set.
+ */
+ function assertPropertySet($property, $key, $val) {
+ $pattern = '|' . '.set' . $property . '\("' . $key . '",{1}\s(.)*' . addslashes($val) . '|';
+ $this->assertPattern($pattern, 'A ' . $property . ' property was set for ' . $key . ' = ' . $val);
+ }
+
+ /**
+ * Assert that a property is not being set.
+ */
+ function assertPropertyNotSet($property, $key, $val) {
+ $pattern = '|' . '.set' . $property . '\("' . $key . '",{1}\s(.)*' . addslashes($val) . '|';
+ $this->assertNoPattern($pattern, 'A ' . $property . ' property was not set for ' . $key . ' = ' . $val);
+ }
+
+}
diff --git a/tests/dfp_display_tag.test b/tests/dfp_display_tag.test
new file mode 100644
index 0000000..bf5397c
--- /dev/null
+++ b/tests/dfp_display_tag.test
@@ -0,0 +1,167 @@
+ t('Displaying DFP Tags'),
+ 'description' => t('Tests for displaying DFP tags.'),
+ 'group' => t('DFP'),
+ );
+ }
+
+ function testDisplayTag() {
+ // Create a simple tag as a block.
+ $tag = $this->createTag();
+ $this->assertRaw('googletag.defineSlot("' . variable_get('dfp_network_id', '') . '/' . $tag->adunit . '", ' . dfp_format_size($tag->size) . ', "' . $tag->placeholder_id . '")', 'The ad slot has been correctly defined in javascript.');
+
+ // Create a tag with a machine name longer than 32 characters.
+ $edit = array('machinename' => drupal_strtolower($this->randomName(64)));
+ $tag = $this->createTag($edit);
+ $this->assertRaw('googletag.defineSlot("' . variable_get('dfp_network_id', '') . '/' . $tag->adunit . '", ' . dfp_format_size($tag->size) . ', "' . $tag->placeholder_id . '")', 'The ad slot with a very long machine name has been correctly defined in javascript.');
+
+ // Ensure the DPF click url is safe.
+ variable_set('dfp_click_url', 'javascript://example.com?foo&bar');
+ $this->drupalGet('/');
+ $this->assertNoRaw('javascript://example.com');
+ $pattern = '|.setClickUrl\("http(.*):\/\/(.*)javascript%3A\/\/example.com%3Ffoo%26bar"\)|';
+ $this->assertPattern($pattern, 'Click URL is filtered for bad protocols and absolute.');
+
+ variable_set('dfp_click_url', 'http://example.com?foo&bar');
+ $this->drupalGet('/');
+ $this->assertRaw('.setClickUrl("http://example.com?foo&bar")', 'Valid external Click URL is not mangled.');
+ }
+
+ function testDisplayTagWithMapping() {
+ $edit = $this->dfpBasicTagEditValues();
+
+ // Create a simple tag with a mapping. Verify javascript on page.
+ $tag = $this->createTag($edit);
+ $mapping_sizes = explode(',', $edit['breakpoints[0][ad_sizes]']);
+ $size_count = count($mapping_sizes);
+ // Calculate addSize mappings.
+ $mapping_tag = '.addSize(';
+ $mapping_tag .= '[' . str_replace('x', ', ', $edit['breakpoints[0][browser_size]']) . '], ';
+ $mapping_tag .= ($size_count > 1) ? '[' : '';
+ for ($i = 0; $i < $size_count; $i++) {
+ $mapping_sizes[$i] = '[' . str_replace('x', ', ', $mapping_sizes[$i]) . ']';
+ $mapping_tag .= ($i + 1 !== $size_count) ? $mapping_sizes[$i] . ', ' : $mapping_sizes[$i];
+ }
+ $mapping_tag .= ($size_count > 1) ? '])' : ')';
+ $this->assertRaw('googletag.sizeMapping()', 'The ad slot correctly attaches size mapping.');
+ $this->assertRaw('.defineSizeMapping(mapping)', 'The ad slot correctly defines size mapping.');
+ $this->assertRaw($mapping_tag, 'The ad slot correctly defines specific size mappings.');
+
+ // Create a tag with invalid browser size mappings.
+ $edit['breakpoints[0][browser_size]'] = $this->randomName(8);
+ $this->editTag($tag->machinename, $edit);
+ $this->assertText(t('The browser size can only contain numbers and the character x.'), 'An error was correctly thrown when invalid characters.');
+
+ // Create a tag with invalid ad size mappings.
+ $edit['breakpoints[0][browser_size]'] = $this->dfpGenerateSize();
+ $edit['breakpoints[0][ad_sizes]'] = $this->randomName(8);
+ $this->editTag($tag->machinename, $edit);
+ $this->assertText(t('The ad size(s) can only contain numbers, the character x and commas.'), 'An error was correctly thrown when invalid characters.');
+ }
+
+ function testSlug() {
+ $edit = $this->dfpBasicTagEditValues();
+
+ // Create a tag without a slug, display it and ensure the default slug is
+ // displayed.
+ variable_set('dfp_default_slug', 'Global slug
');
+ $edit['settings[slug]'] = '';
+ $tag = $this->createTag($edit);
+ $this->assertRaw('' . check_plain(variable_get('dfp_default_slug', '')) . '
', 'The default slug is correctly used when no slug exists for an individual tag.');
+
+ // Change the slug to and ensure that no slug is displayed.
+ $edit['settings[slug]'] = '';
+ $this->editTag($tag->machinename, $edit);
+ $this->assertNoRaw('', t('No slug is appearing when "@none" is used.', array('@none' => '
')));
+
+ // Specify a slug and check that it shows instead of the default slug.
+ $slug = 'Custom slug
';
+ $edit['settings[slug]'] = $slug;
+ $this->editTag($tag->machinename, $edit);
+ $this->assertRaw('' . check_plain($slug) . '
', 'The provided slug is correctly displayed with its tag.');
+ }
+
+ function testTargeting() {
+ $edit = $this->dfpBasicTagEditValues();
+
+ // Create a tag with a target with only one value.
+ $tag = $this->createTag($edit);
+ $this->assertPropertySet('Targeting', $edit['targeting[0][target]'], $edit['targeting[0][value]']);
+
+ // Create a tag with a target with multiple values.
+ $values = array($this->randomName(8), $this->randomName(8), $this->randomName(8));
+ $edit['targeting[0][target]'] = $this->randomName(8);
+ $edit['targeting[0][value]'] = implode(', ', $values);
+ $this->editTag($tag->machinename, $edit);
+ $this->assertPropertySet('Targeting', $edit['targeting[0][target]'], implode('","', $values));
+
+ // Create a tag with a target but no value.
+ $edit['targeting[0][target]'] = $this->randomName(8);
+ $edit['targeting[0][value]'] = '';
+ $this->editTag($tag->machinename, $edit);
+ $this->assertText(t('The value cannot be empty if a target exists.'), 'An error was correctly thrown when a target has no value.');
+
+ // Create a tag with an empty target, but a value.
+ $edit['targeting[0][target]'] = '';
+ $edit['targeting[0][value]'] = $this->randomName(8);
+ $this->editTag($tag->machinename, $edit);
+ $this->assertText(t('The target cannot be empty if a value exists.'), 'An error was correctly thrown when a target is blank, but a value has been entered.');
+
+ // Create a tag with multiple targets.
+ $count = 3;
+ for ($i = 0; $i < $count; $i++) {
+ $edit['targeting[' . $i . '][target]'] = $this->randomName(8);
+ $edit['targeting[' . $i . '][value]'] = $this->randomName(8);
+ $this->drupalPost('admin/structure/dfp_ads/list/' . $tag->machinename . '/edit', $edit, t('Add another target'));
+ $this->editTag($tag->machinename, $edit);
+ }
+
+ for ($i = 0; $i < $count; $i++) {
+ $this->assertPropertySet('Targeting', $edit['targeting[' . $i . '][target]'], $edit['targeting[' . $i . '][value]']);
+ }
+ // Make sure that empty values are ignored.
+ $this->drupalPost('admin/structure/dfp_ads/list/' . $tag->machinename . '/edit', $edit, t('Add another target'));
+ $this->editTag($tag->machinename, $edit);
+ $this->assertPropertyNotSet('Targeting', '', '');
+
+ // Test that target can be removed.
+ $edit['targeting[0][target]'] = '';
+ $edit['targeting[0][value]'] = '';
+ $this->editTag($tag->machinename, $edit);
+ $this->assertPropertyNotSet('Targeting', '', '');
+ }
+
+ function testBackfill() {
+ $edit = $this->dfpBasicTagEditValues();
+
+ // Create a tag with backfill settings.
+ $colors = array('background', 'border', 'link', 'text', 'url');
+ $types = array('text', 'image', 'text_image');
+ shuffle($types);
+
+ $edit['settings[adsense_ad_types]'] = array_pop($types);
+ $edit['settings[adsense_channel_ids]'] = $this->randomName(8);
+ foreach ($colors as $color) {
+ $edit['settings[adsense_colors][' . $color . ']'] = drupal_strtoupper($this->randomName(8));
+ }
+ $tag = $this->createTag($edit);
+ $this->assertPropertySet('', 'adsense_ad_types', $edit['settings[adsense_ad_types]']);
+ $this->assertPropertySet('', 'adsense_channel_ids', $edit['settings[adsense_channel_ids]']);
+ foreach ($colors as $color) {
+ $this->assertPropertySet('', 'adsense_' . $color . '_color', $edit['settings[adsense_colors][' . $color . ']']);
+ }
+ }
+
+}
diff --git a/tests/dfp_globals.test b/tests/dfp_globals.test
new file mode 100644
index 0000000..d020888
--- /dev/null
+++ b/tests/dfp_globals.test
@@ -0,0 +1,50 @@
+ t('Global DFP Tag Settings'),
+ 'description' => t('Tests for the settings defined in admin/structure/dfp_ads/settings.'),
+ 'group' => t('DFP'),
+ );
+ }
+
+ function testGlobalSettingsOn() {
+ $injected_js = $this->randomName(32);
+ $target = array(
+ 'target' => $this->randomName(8),
+ 'value' => $this->randomName(8),
+ );
+
+ variable_set('dfp_async_rendering', '1');
+ variable_set('dfp_single_request', '1');
+ variable_set('dfp_collapse_empty_divs', '1');
+ variable_set('dfp_injected_js', $injected_js);
+ variable_set('dfp_targeting', array($target));
+ $this->drupalGet('/');
+ $this->assertRaw('googletag.pubads().enableAsyncRendering();', 'Asyncronous rendering is turned on.');
+ $this->assertRaw('googletag.pubads().enableSingleRequest();', 'Single request is turned on.');
+ $this->assertRaw('googletag.pubads().collapseEmptyDivs();', 'Collapse empty divs is turned on.');
+ $this->assertRaw($injected_js, 'Injected javascript correctly appears on the page.');
+ $this->assertRaw('googletag.pubads().setTargeting("' . $target['target'] . '", "' . $target['value'] . '");', 'Global targeting values appear correctly in javascript.');
+ }
+
+ function testGlobalSettingsOff() {
+ variable_set('dfp_async_rendering', '0');
+ variable_set('dfp_single_request', '0');
+ variable_set('dfp_collapse_empty_divs', '0');
+ $this->drupalGet('/');
+ $this->assertNoRaw('googletag.pubads().enableAsyncRendering();', 'Asyncronous rendering is turned off.');
+ $this->assertNoRaw('googletag.pubads().enableSingleRequest();', 'Single request is turned off.');
+ $this->assertNoRaw('googletag.pubads().collapseEmptyDivs();', 'Collapse empty divs is turned off.');
+ }
+
+}
diff --git a/tests/dfp_tokens.test b/tests/dfp_tokens.test
new file mode 100644
index 0000000..9afb486
--- /dev/null
+++ b/tests/dfp_tokens.test
@@ -0,0 +1,62 @@
+ t('DFP Tokens'),
+ 'description' => t('Tests for custom tokens created by the DFP module.'),
+ 'group' => t('DFP'),
+ );
+ }
+
+ function testSlotToken() {
+ $edit = $this->dfpBasicTagEditValues();
+
+ // Create a tag that uses the slot token in a target.
+ $test_slot = $this->randomName(8);
+ $edit['slot'] = $test_slot;
+ $edit['targeting[0][target]'] = 'slot';
+ $edit['targeting[0][value]'] = '[dfp_tag:slot]';
+ $tag = $this->createTag($edit);
+ $this->assertPropertySet('Targeting', 'slot', $test_slot);
+ }
+
+ function testNetworkIDToken() {
+ $edit = $this->dfpBasicTagEditValues();
+
+ // Create a tag that uses the networkid token in a target.
+ $test_network_id = $this->randomName(8);
+ variable_set('dfp_network_id', $test_network_id);
+ $edit['targeting[0][target]'] = 'network id';
+ $edit['targeting[0][value]'] = '[dfp_tag:network_id]';
+ $tag = $this->createTag($edit);
+ $this->assertPropertySet('Targeting', 'network id', $test_network_id);
+ }
+
+ function testUrlPartsToken() {
+ // Create a tag that uses the url parts token in a target.
+ $tag = $this->createTag();
+ $url = 'admin/structure/dfp_ads';
+ $url_parts = explode('/', $url);
+
+ $max_parts_to_test = 3;
+ for ($i = 1; $i <= $max_parts_to_test; $i++) {
+ $edit['targeting[0][target]'] = 'url parts';
+ $edit['targeting[0][value]'] = '[dfp_tag:url_parts:' . $i . ']';
+ $this->editTag($tag->machinename, $edit);
+
+ $this->drupalGet($url);
+ $replacement = implode('/', array_slice($url_parts, 0, $i));
+ $this->assertPropertySet('Targeting', 'url parts', $replacement);
+ }
+ }
+
+}
diff --git a/tests/dfp_unit.test b/tests/dfp_unit.test
new file mode 100644
index 0000000..688e8b7
--- /dev/null
+++ b/tests/dfp_unit.test
@@ -0,0 +1,40 @@
+ t('DFP Unit Tests'),
+ 'description' => t('Checks the integrity of certain DFP functions.'),
+ 'group' => t('DFP'),
+ );
+ }
+
+ function testDFPformatSize() {
+ $sizes = '300x250';
+ $expected_result = '[300, 250]';
+
+ $this->assertTrue(dfp_format_size($sizes) == $expected_result, 'The dfp_format_sizes function correctly handles an single size.');
+ $sizes = '300x250,728x90';
+ $expected_result = '[[300, 250], [728, 90]]';
+ $this->assertTrue(dfp_format_size($sizes) == $expected_result, 'The dfp_format_sizes function correctly handles multiple sizes.');
+ }
+}