xpath('//div[@id=:id and contains(@class, :class)]', array( ':id' => $id, ':class' => $class, )); $this->assertTrue(!empty($elements[0]), $message); } /** * Asserts that a class is not set for the given element id. * * @param $id * Id of the HTML element to check. * @param $class * The class name to check for. * @param $message * Message to display. * @return * TRUE on pass, FALSE on fail. */ function assertNoSkinrClass($id, $class, $message = '') { $elements = $this->xpath('//div[@id=:id]', array(':id' => $id)); $class_attr = (string) $elements[0]['class']; $this->assertTrue(strpos($class_attr, $class) === FALSE, $message); } /** * Pass if the message $text was set by one of the CRUD hooks in * skinr_test.module, i.e., if the $text is an element of * $_SESSION['skinr_test']. * * @param $text * Plain text to look for. * @param $message * Message to display. * @param $group * The group this message belongs to, defaults to 'Other'. * @return * TRUE on pass, FALSE on fail. */ protected function assertHookMessage($text, $message = NULL, $group = 'Other') { if (!isset($message)) { $message = $text; } return $this->assertTrue(array_search($text, $_SESSION['skinr_test']) !== FALSE, $message, $group); } } /** * Tests basic module installation. */ class SkinrInstallationTestCase extends DrupalWebTestCase { protected $profile = 'testing'; public static function getInfo() { return array( 'name' => 'Installation', 'description' => 'Tests basic module installation.', 'group' => 'Skinr', ); } function setUp() { parent::setUp(); } /** * Tests installation and uninstallation of Skinr modules. */ function testInstallation() { $this->admin_user = $this->drupalCreateUser(array( 'access administration pages', 'administer modules', 'administer permissions', )); $this->drupalLogin($this->admin_user); // Install the modules. $edit = array( 'modules[Skinr][skinr][enable]' => TRUE, 'modules[Skinr][skinr_ui][enable]' => TRUE, ); $this->drupalPost('admin/modules', $edit, t('Save configuration')); // Grant permissions. $edit = array( DRUPAL_AUTHENTICATED_RID . '[administer skinr]' => TRUE, DRUPAL_AUTHENTICATED_RID . '[edit skin settings]' => TRUE, DRUPAL_AUTHENTICATED_RID . '[edit advanced skin settings]' => TRUE, ); $this->drupalPost('admin/people/permissions', $edit, t('Save permissions')); // Verify that we are able to access Skinr's administration pages. $this->drupalGet('admin/structure/skinr'); $this->assertResponse(200); // Uninstall the modules. $edit = array( 'modules[Skinr][skinr_ui][enable]' => FALSE, ); $this->drupalPost('admin/modules', $edit, t('Save configuration')); $edit = array( 'modules[Skinr][skinr][enable]' => FALSE, ); $this->drupalPost(NULL, $edit, t('Save configuration')); // Uninstall Skinr UI first. $edit = array( 'uninstall[skinr_ui]' => TRUE, ); $this->drupalPost('admin/modules/uninstall', $edit, t('Uninstall')); $this->drupalPost(NULL, array(), t('Uninstall')); // Now uninstall Skinr. $edit = array( 'uninstall[skinr]' => TRUE, ); $this->drupalPost('admin/modules/uninstall', $edit, t('Uninstall')); $this->drupalPost(NULL, array(), t('Uninstall')); // Verify that no system variables are left. $count = db_query("SELECT 1 FROM {variable} WHERE name LIKE 'skinr_*'")->fetchField(); $this->assertEqual($count, 0, t('No variables found.')); } } /** * Tests API functionality. * * @link http://drupal.org/node/953336#comment-3738456 Make sure this patch is applied to drupal core @endlink */ class SkinrApiTestCase extends SkinrWebTestCase { protected $profile = 'testing'; public static function getInfo() { return array( 'name' => 'API', 'description' => 'Tests Skinr API functionality.', 'group' => 'Skinr', ); } public function setUp() { parent::setUp(array('skinr', 'skinr_test', 'skinr_test_incompatible')); // Enable skinr_test_subtheme, but NOT the basetheme. theme_enable(array('skinr_test_subtheme')); } /** * Tests skinr_implements(). */ public function testSkinrImplementsAPI() { // Verify that skinr_implements() only returns extensions that are // compatible with this version of Skinr. $extensions = skinr_implements_api(); $this->verbose(highlight_string(' array(), // System and node are required core modules, so always expected. 'system' => array ( 'version' => VERSION, 'path' => drupal_get_path('module', 'skinr') . '/modules', 'include file' => drupal_get_path('module', 'skinr') . '/modules/system.skinr.inc', ), 'node' => array( 'version' => VERSION, 'path' => drupal_get_path('module', 'skinr') . '/modules', 'include file' => drupal_get_path('module', 'skinr') . '/modules/node.skinr.inc', ), // skinr_test has been installed. 'skinr_test' => array( 'directory' => 'skins', ), 'skinr_test_basetheme' => array( 'type' => 'theme', 'api' => 2, 'directory' => 'skins', 'base themes' => array(), 'sub themes' => drupal_map_assoc(array('skinr_test_subtheme')), 'include file' => drupal_get_path('theme', 'skinr_test_basetheme') . '/skinr_test_basetheme.skinr.inc', ), 'skinr_test_subtheme' => array( 'type' => 'theme', 'api' => 2, 'directory' => 'skins', 'base themes' => drupal_map_assoc(array('skinr_test_basetheme')), 'sub themes' => array(), 'include file' => drupal_get_path('theme', 'skinr_test_subtheme') . '/skinr_test_subtheme.skinr.inc', ), ); // When running tests on Skinr code packaged by drupal.org, all 'version' // properties will have the version of the Skinr module. When running on a // repository checkout, the version is NULL (undefined). $skinr_module_info = system_get_info('module', 'skinr'); $skinr_module_version = (!empty($skinr_module_info['version']) ? $skinr_module_info['version'] : NULL); foreach ($all_expected as $name => $expected) { // Populate defaults. $expected += array( 'type' => 'module', 'name' => $name, 'version' => $skinr_module_version, ); $expected += array( 'path' => drupal_get_path($expected['type'], $name), 'directory' => NULL, ); $this->assertEqual($extensions[$name], $expected, t('%extension implementation found:
@data
', array( '%extension' => $name, '@data' => var_export($extensions[$name], TRUE), ))); unset($extensions[$name]); } // Ensure that skinr_test_incompatible is not contained. $this->assertTrue(!isset($extensions['skinr_test_incompatible']), 'Incompatible extension not found.'); // After asserting all expected, the list of extensions should be empty. $this->assertTrue(empty($extensions), 'No unexpected extensions found.'); } /** * Test module_implements(). */ function testSkinrImplements() { // Test clearing cache. cache_clear_all('skinr_implements', 'cache_bootstrap'); $this->assertFalse(cache_get('skinr_implements', 'cache_bootstrap'), t('The skinr implements cache is empty.')); $this->drupalGet(''); $this->assertTrue(cache_get('skinr_implements', 'cache_bootstrap'), t('The skinr implements cache is populated after requesting a page.')); // Test clearing cache with an authenticated user. $this->user = $this->drupalCreateUser(array()); $this->drupalLogin($this->user); cache_clear_all('skinr_implements', 'cache_bootstrap'); $this->drupalGet(''); $this->assertTrue(cache_get('skinr_implements', 'cache_bootstrap'), t('The skinr implements cache is populated after requesting a page.')); // Make sure $module.skinr.inc files (both in the module root, which are // auto-loaded by drupal, and in custom paths and themes, which are // loaded by skinr_implements()) are loaded when the hook is called. Also // ensure only module that implement the current Skinr API are loaded. $modules = skinr_implements('skinr_skin_info'); // Ensure the hook is found in includes. $this->assertTrue(in_array('skinr_test', $modules), 'Hook found in $module.skinr.inc file auto-loaded by module_hook().'); $this->assertTrue(in_array('skinr_test_subtheme', $modules), 'Hook found in $module.skinr.inc file in custom path.'); // Ensure that skinr_test_incompatible is not included. $this->assertTrue(!in_array('skinr_test_incompatible', $modules), 'Hook in incompatible module not found.'); } /** * Tests skinr_implements() caching and auto-loading. */ function testSkinrImplementsCache() { module_enable(array('block')); $this->resetAll(); // Enable main system block for content region and the user menu block for // the first sidebar. $default_theme = variable_get('theme_default', 'bartik'); db_merge('block') ->key(array( 'theme' => $default_theme, 'module' => 'system', 'delta' => 'main', )) ->fields(array( 'status' => 1, 'region' => 'content', 'pages' => '', )) ->execute(); db_merge('block') ->key(array( 'theme' => $default_theme, 'module' => 'system', 'delta' => 'powered-by', )) ->fields(array( 'status' => 1, 'region' => 'sidebar_first', 'pages' => '', )) ->execute(); // Enable a skin defined in an include file, which applies to a module // element that is equally registered in an include file (built-in Block // module integration). $skin = (object) array( 'theme' => $default_theme, 'module' => 'block', 'element' => 'system__powered-by', 'skin' => 'skinr_test_font', 'options' => array('font_1'), 'status' => 1, ); skinr_skin_save($skin); // Verify the skin is contained in the output. $this->drupalGet(''); $this->assertSkinrClass('block-system-powered-by', 'font-1', 'Skin found.'); // Once again, so we hit the cache. $this->drupalGet(''); $this->assertSkinrClass('block-system-powered-by', 'font-1', 'Skin found.'); // Visit skin edit page after to test for groups, after hitting cache. $this->drupalGet('skinr-test/hook-dynamic-loading'); $this->assertText('success!', t('$module.skinr.inc file auto-loaded.')); } /** * Test that module_invoke_all() can load a hook defined in hook_hook_info(). */ function testSkinrInvokeAll() { // Ensure functions from $module.skinr.inc in both module root and in // custom paths are triggered. $config_info = skinr_invoke_all('skinr_config_info'); $this->verbose(highlight_string('assertTrue(in_array('system', $config_info), 'Function triggered in $module.skinr.inc file auto-loaded by module_hook().'); $this->assertTrue(in_array('node', $config_info), 'Function triggered in $module.skinr.inc file in custom path.'); // Ensure that skinr_test_incompatible is not included. $this->assertTrue(!in_array('skinr_test_incompatible', $config_info), 'Function in incompatible module not triggered.'); } /** * Tests hook_skinr_skin_info(). */ public function testSkinrSkinInfo() { // Verify that skinr_get_skin_info() finds and returns all registered skins // in $module.skinr.inc files as well as Skinr plugin files, but does not // return skins that are incompatible with the current Skinr API version. $skin_info = skinr_get_skin_info(); $path = drupal_get_path('module', 'skinr_test'); // skinr_test_font is registered via hook_skinr_skin_info() in // skinr_test.skinr.inc. $this->assertTrue(isset($skin_info['skinr_test_font']), 'Skin registered in $module.skinr.inc found.'); $this->assertEqual($skin_info['skinr_test_font']['source']['path'], $path, t('Skin path points to module directory: @path', array( '@path' => $skin_info['skinr_test_font']['source']['path'], ))); unset($skin_info['skinr_test_font']); // skinr_test_example is registered via hook_skinr_skin_PLUGIN_info() in // skins/example.inc. $this->assertTrue(isset($skin_info['skinr_test_example']), 'Skin registered in plugin file found.'); $this->assertEqual($skin_info['skinr_test_example']['source']['path'], $path . '/skins/example', t('Skin path points to plugin directory: @path', array( '@path' => $skin_info['skinr_test_example']['source']['path'], ))); unset($skin_info['skinr_test_example']); // skinr_test_basetheme is registered via hook_skinr_skin_info() in // skinr_test_basetheme.skinr.inc. $this->assertTrue(isset($skin_info['skinr_test_basetheme']), 'Skin registered in $basetheme.skinr.inc found.'); $this->assertEqual($skin_info['skinr_test_basetheme']['source']['path'], $path . '/themes/skinr_test_basetheme', t('Skin path points to basetheme directory: @path', array( '@path' => $skin_info['skinr_test_basetheme']['source']['path'], ))); $default_theme = variable_get('theme_default', 'bartik'); $this->assertEqual($skin_info['skinr_test_basetheme']['status'][$default_theme], 0, 'Basetheme skin is disabled for default theme.'); $this->assertEqual($skin_info['skinr_test_basetheme']['status']['skinr_test_basetheme'], 1, 'Basetheme skin is enabled for Skinr test basetheme.'); unset($skin_info['skinr_test_basetheme']); // skinr_test_subtheme is registered via hook_skinr_skin_info() in // skinr_test_subtheme.skinr.inc. $this->assertTrue(isset($skin_info['skinr_test_subtheme']), 'Skin registered in $subtheme.skinr.inc found.'); $this->assertEqual($skin_info['skinr_test_subtheme']['source']['path'], $path . '/themes/skinr_test_subtheme', t('Skin path points to subtheme directory: @path', array( '@path' => $skin_info['skinr_test_subtheme']['source']['path'], ))); unset($skin_info['skinr_test_subtheme']); // Ensure that skinr_test_incompatible is not contained. $this->assertTrue(!isset($skin_info['skinr_test_incompatible']), 'Incompatible skin not found.'); // After asserting all expected, the list of skins should be empty. $this->assertTrue(empty($skin_info), t('No unexpected skins found:
@data
', array( '@data' => var_export($skin_info, TRUE), ))); } /** * Tests hook_skinr_group_info(). */ public function testSkinrGroupInfo() { $group_info = skinr_get_group_info(); // Verify that default skin groups are found. $all_expected = array( 'general' => array( 'title' => t('General'), 'weight' => -10, ), 'box' => array( 'title' => t('Box styles'), ), 'typography' => array( 'title' => t('Typography'), ), 'layout' => array( 'title' => t('Layout'), ), ); foreach ($all_expected as $name => $expected) { // We don't want to be pixel-perfect here. if (isset($group_info[$name]['description'])) { $expected['description'] = $group_info[$name]['description']; } $expected += array( 'description' => '', 'weight' => 0, ); $this->assertEqual($group_info[$name], $expected, t('Group %group found:
@data
', array( '%group' => $name, '@data' => var_export($group_info[$name], TRUE), ))); unset($group_info[$name]); } // After asserting all expected, the list of extensions should be empty. $this->assertTrue(empty($group_info), 'No unexpected groups found.'); } /** * Tests hook_skinr_config_info(). */ public function testSkinrConfigInfo() { // Verify that skinr_get_config_info() finds all existing and compatible // hook_skinr_config_info() implementations. $config = skinr_get_config_info(); // Skinr's own implementation in skinr.skinr.inc should always be found. $this->assertTrue(in_array('system', $config), 'hook_skinr_config_info() in $module.skinr.inc found.'); foreach ($config as $key => $type) { if ($type == 'system') { unset($config[$key]); } } // Skinr's implementation on behalf of Node module in modules/node.skinr.inc // should be found. $this->assertTrue(in_array('node', $config), 'hook_skinr_config_info() in a custom path found.'); foreach ($config as $key => $type) { if ($type == 'node') { unset($config[$key]); } } // Ensure that skinr_test_incompatible is not included. $this->verbose(highlight_string('assertTrue(!isset($config['skinr_test_incompatible']), 'Incompatible hook_skinr_config_info() not found.'); // After asserting all expected, the list of skins should be empty. $this->assertTrue(empty($config), 'No unexpected skins found.'); } /** * Test hook invocations for CRUD operations on skin configurations. */ public function testSkinrSkinHooks() { $skin = (object) array( 'theme' => 'skinr_test_subtheme', 'module' => 'block', 'element' => 'system__user-menu', 'skin' => 'skinr_test_subtheme', 'options' => array('option1', 'option2'), 'status' => 1, ); $_SESSION['skinr_test'] = array(); skinr_skin_save($skin); $this->assertHookMessage('skinr_test_skinr_skin_presave called'); $this->assertHookMessage('skinr_test_skinr_skin_insert called'); $_SESSION['skinr_test'] = array(); $skin = skinr_skin_load($skin->sid); $this->assertHookMessage('skinr_test_skinr_skin_load called'); $_SESSION['skinr_test'] = array(); $skin = skinr_skin_load_unchanged($skin->sid); $this->assertHookMessage('skinr_test_skinr_skin_load called'); $_SESSION['skinr_test'] = array(); $skin->options = array('option3'); skinr_skin_save($skin); $this->assertHookMessage('skinr_test_skinr_skin_presave called'); $this->assertHookMessage('skinr_test_skinr_skin_update called'); $_SESSION['skinr_test'] = array(); skinr_skin_delete($skin->sid); $this->assertHookMessage('skinr_test_skinr_skin_delete called'); } /** * Test skinr_skin_save() against invalid entries. */ public function testSkinrSkinLoadSave() { // Only save valid skins. $skin = (object) array( 'theme' => '', 'module' => 'block', 'element' => 'system__user-menu', 'skin' => 'skinr_test_subtheme', 'options' => array('option1', 'option2'), 'status' => 1, ); $this->assertFalse(skinr_skin_save($skin), 'Skin configuration object was not saved when $skin->theme was empty.'); $skin->theme = 'skinr_test_subtheme'; $skin->module = ''; $this->assertFalse(skinr_skin_save($skin), 'Skin configuration object was not saved when $skin->module was empty.'); $skin->module = 'block'; $skin->element = ''; $this->assertFalse(skinr_skin_save($skin), 'Skin configuration object was not saved when $skin->element was empty.'); $skin->element = 'system-user-menu'; $skin->skin = ''; $this->assertFalse(skinr_skin_save($skin), 'Skin configuration object was not saved when $skin->skin was empty.'); $skin->skin = 'skinr_test_subtheme'; $skin->options = ''; $this->assertFalse(skinr_skin_save($skin), 'Skin configuration object was not saved when $skin->options was not an array.'); $skin->options = array(); $this->assertFalse(skinr_skin_save($skin), 'Skin configuration object was not saved when $skin->options was an empty array.'); $skin->options = array('option1' => 0, 'option2' => 0); $this->assertFalse(skinr_skin_save($skin), 'Skin configuration object was not saved when $skin->options was a complex empty array.'); $skin->options = array('option1', 'option2'); $this->assertTrue(skinr_skin_save($skin), 'Skin configuration object was saved.'); $this->assertTrue(isset($skin->sid), 'The sid was added to the skin configuration object.'); // Test loading a skin configuration. $loaded_skin = skinr_skin_load($skin->sid); $this->assertTrue(is_array($loaded_skin->options), 'Options for the skin configuration object were unserialized.'); $this->assertTrue($loaded_skin->theme == $skin->theme && $loaded_skin->module == $skin->module && $loaded_skin->element == $skin->element && $loaded_skin->status == $skin->status && $loaded_skin->options[0] == $skin->options[0] && $loaded_skin->options[1] == $skin->options[1], 'Skin configuration object was loaded properly.'); // Save a second skin. $second_skin = (object) array( 'theme' => 'skinr_test_subtheme', 'module' => 'block', 'element' => 'system__main', 'skin' => 'skinr_test_subtheme', 'options' => array('option3'), 'status' => 1, ); skinr_skin_save($second_skin); // Test loading multiple skin configurations. $skins = skinr_skin_load_multiple(array($skin->sid, $second_skin->sid)); $this->assertTrue(count($skins) == 2 && isset($skins[$skin->sid]->sid) && isset($skins[$second_skin->sid]->sid), 'Successfully loaded multiple skins.'); // Test loading all skin configurations. drupal_static_reset('skinr_skin_load_multiple'); $skins = skinr_skin_load_multiple(FALSE); $this->assertTrue(count($skins) == 2 && isset($skins[$skin->sid]->sid) && isset($skins[$second_skin->sid]->sid), 'Successfully loaded all skins.'); } } /** * Tests API functionality. * * @link http://drupal.org/node/953336#comment-3738456 Make sure this patch is applied to drupal core @endlink */ class SkinrDisplayTestCase extends SkinrWebTestCase { protected $profile = 'testing'; public static function getInfo() { return array( 'name' => 'Display', 'description' => 'Tests if applied skins appear on the front-end.', 'group' => 'Skinr', ); } public function setUp() { parent::setUp(array('block', 'skinr', 'skinr_test')); $this->admin_user = $this->drupalCreateUser(array( 'administer blocks', )); $this->drupalLogin($this->admin_user); // Enable main system block for content region and the user menu block for // the first sidebar. // @see http://drupal.org/node/913086 $default_theme = variable_get('theme_default', 'bartik'); db_merge('block') ->key(array( 'theme' => $default_theme, 'module' => 'system', 'delta' => 'main', )) ->fields(array( 'status' => 1, 'region' => 'content', 'pages' => '', )) ->execute(); db_merge('block') ->key(array( 'theme' => $default_theme, 'module' => 'system', 'delta' => 'user-menu', )) ->fields(array( 'status' => 1, 'region' => 'sidebar_first', 'pages' => '', )) ->execute(); // Enable Garland. theme_enable(array('garland')); } public function testSkinrDisplayed() { // Save a skin configuration object. $skin = (object) array( 'theme' => 'bartik', 'module' => 'block', 'element' => 'system__user-menu', 'skin' => 'skinr_test_font', 'options' => array('font_1'), 'status' => 1, ); $this->assertTrue(skinr_skin_save($skin), 'Skin configuration object was saved.'); $this->verbose(print_r($skin, TRUE)); // Go to the front page. $this->drupalGet(''); $this->assertSkinrClass('block-system-user-menu', 'font-1', 'CSS class of configured skin option found.'); $content = $this->drupalGetContent(); $css = drupal_get_path('module', 'skinr_test') . '/skinr_test.css'; $this->assertRaw($css, t('Stylesheet was included on page.')); $js = drupal_get_path('module', 'skinr_test') . '/skinr_test.js'; $this->assertRaw($js, t('Javascript was included on page.')); $js = drupal_get_path('module', 'skinr_test') . '/skinr_test_advanced.css'; $this->assertRaw($js, t('Javascript with advanced settings was included on page.')); $js = drupal_get_path('module', 'skinr_test') . '/skinr_test_data.css'; $this->assertRaw($js, t('Javascript with filename set in settings array was included on page.')); } }