modules = func_get_args(); call_user_func_array(array('parent', 'setup'), $this->modules); $permissions = array( 'access comments', 'access content', 'post comments', 'post comments without approval', ); $this->users['regular_1'] = $this->drupalCreateUser($permissions); $this->users['regular_2'] = $this->drupalCreateUser($permissions); $this->users['regular_3'] = $this->drupalCreateUser($permissions); $permissions[] = 'create page content'; $this->users['create_1'] = $this->drupalCreateUser($permissions); $this->users['create_2'] = $this->drupalCreateUser($permissions); $permissions[] = 'access statistics pro reports'; $this->users['stats'] = $this->drupalCreateUser($permissions); $permissions[] = 'administer site configuration'; $permissions[] = 'administer statistics pro settings'; $this->users['stats_admin'] = $this->drupalCreateUser($permissions); } function getAddedDate($timestamp, $diff = 0, $diff_unit = 'd') { switch ($diff_unit) { case 's': $delta = $diff; break; case 'm': $delta = 60 * $diff; break; case 'h': $delta = 3600 * $diff; break; case 'w': $delta = 7 * 24 * 3600 * $diff; break; case 'y': $delta = 365 * 24 * 3600 * $diff; break; default: $delta = 24 * 3600 * $diff; } $timestamp += $delta; return $timestamp; } function setChangedTimestamp($node, $new_changed_time) { db_query( 'UPDATE {node} SET changed = %d WHERE nid = %d', $new_changed_time, $node->nid ); db_query( 'UPDATE {node_revisions} SET timestamp = %d WHERE vid = %d', $new_changed_time, $node->vid ); } function createNode($settings) { $node = $this->drupalCreateNode($settings); if (isset($settings['changed']) && ($settings['changed'] != $node->changed)) { $this->setChangedTimestamp($node, $settings['changed']); } $this->verbose('Node created: ' . var_export($node, TRUE)); $this->node_titles[] = $node->title; return $node; } function createInitialData() { $this->node_titles = array(); $now = time(); $this->drupalLogin($this->users['create_1']); $title = t('Node !this/!total - now', array('!this' => 1, '!total' => 1)); $settings = array('title' => $title); $this->createNode($settings); $title = t('Node !this/!total - yesterday', array('!this' => 1, '!total' => 1)); $settings['title'] = $title; $settings['created'] = $this->getAddedDate($now, -1, 'd'); $settings['changed'] = $settings['created']; $this->createNode($settings); $title = t('Node !this/!total - last week', array('!this' => 1, '!total' => 2)); $settings['title'] = $title; $settings['created'] = $this->getAddedDate($now, -1, 'w'); $settings['changed'] = $settings['created']; $this->createNode($settings); $title = t('Node !this/!total - last week', array('!this' => 2, '!total' => 2)); $settings['title'] = $title; $settings['created'] = $this->getAddedDate($now, -5, 'd'); $settings['changed'] = $settings['created']; $this->createNode($settings); $title = t('Node !this/!total - last month', array('!this' => 1, '!total' => 1)); $settings['title'] = $title; $settings['created'] = $this->getAddedDate($now, -15, 'd'); $settings['changed'] = $settings['created']; $this->createNode($settings); $title = t('Node !this/!total - last year', array('!this' => 1, '!total' => 3)); $settings['title'] = $title; $settings['created'] = $this->getAddedDate($now, -45, 'd'); $settings['changed'] = $settings['created']; $this->createNode($settings); $title = t('Node !this/!total - last year', array('!this' => 2, '!total' => 3)); $settings['title'] = $title; $settings['created'] = $this->getAddedDate($now, -315, 'd'); $settings['changed'] = $settings['created']; $this->createNode($settings); $title = t('Node !this/!total - last year', array('!this' => 3, '!total' => 3)); $settings['title'] = $title; $settings['created'] = $this->getAddedDate($now, -183, 'd'); $settings['changed'] = $settings['created']; $this->createNode($settings); } function callCron() { $this->drupalLogin($this->users['stats_admin']); $this->drupalGet('/admin/reports/status/run-cron'); $this->drupalLogout(); } function getTypeName($type) { if (!$this->type_names) { $this->type_names = array( 'pi' => t('page impressions'), 'upi' => t('authenticated users page impressions'), 'error' => t('errors'), 'uerror' => t('authenticated users errors'), 'warning' => t('warnings'), 'uwarning' => t('authenticated users warnings'), 'users' => t('total number of users'), 'terms' => t('total number of terms'), 'nodes' => t('total number of nodes'), 'node_types' => t('total number of node types'), 'comments' => t('total number of comments'), 'aliases' => t('total number of aliases'), 'sessions' => t('total number of sessions'), 'modules' => t('total number of modules'), 'emergency' => t('emergencies'), 'uemergency' => t('authenticated users emergencies'), 'alert' => t('alerts'), 'ualert' => t('authenticated users alerts'), 'critical' => t('critical conditions'), 'ucritical' => t('authenticated users critical conditions'), ); } $defined = isset($this->type_names[$type]); if ($defined) { return $this->type_names[$type]; } else { $this->assertTrue( $defined, t("Type '%type' not identified.", array('%type' => $type)), t('Get type name from type.') ); return ''; } } function completeTestStatsHasTexts($texts, $raws, $period = FALSE, $group = '', $url = FALSE, $use_post = TRUE) { if (!$url) { $url = 'admin/reports/statspro'; } if ($period === FALSE) { $edits = array(); $period_name = 'Period not changed'; } elseif (is_numeric($period)) { $edits = array( 'statspro_period' => 'custom_days', 'statspro_custom_number_days' => (int) $period, ); $period_name = 'custom_days ' . (int) $period; } else { $edits = array( 'statspro_period' => $period, ); $period_name = (int) $period; } if ($use_post) { $submit = t('Save configuration'); $page = $this->drupalPost($url, $edits, $submit); } else { $page = $this->drupalGet($url); } // $this->verbose(var_export($page, TRUE)); foreach ($texts as $text) { $this->assertText( $text, t("Text '@text' found for period '@period'.", array('@text' => $text, '@period' => $period_name)), $group ); } foreach ($raws as $raw) { $this->assertRaw( $raw, t("Raw text '@text' found in HTML for period '@period'.", array('@text' => $raw, '@period' => $period_name)), $group ); } } function completeTestAggregatedData($type, $correct, $group) { $result = $this->statspro->get_aggregate_stat($type); $this->verbose(t("statspro->get_aggregate_stat('@type') result: '@result'", array( '@result' => var_export($result, TRUE), '@type' => $type, ) )); $message = t( "The number of @name - statspro->get_aggregate_stat(@type) - should be '@correct'. It is '@wrong'.", array( '@correct' => var_export($correct, TRUE), '@wrong' => var_export($result['amount'], TRUE), '@name' => $this->getTypeName($type), '@type' => $type, ) ); $this->assertEqual($result['amount'], $correct, $message, $group); } function get_dump($value, $level = 0) { if ($level == -1) { $trans[' '] = '∴'; $trans["\t"] = '⇒'; $trans["\n"] = '¶;'; $trans["\r"] = '⇐'; $trans["\0"] = '⊕'; return strtr(htmlspecialchars($value), $trans); } $output = ''; if ($level == 0) { $output .= '
'; } $type = gettype($value); $output .= $type; if ($type == 'string') { $output .= '(' . mb_strlen($value) . ')'; $value = dump($value, -1); } elseif ($type == 'boolean') { $value = ($value ? 'true' : 'false'); } elseif ($type == 'object') { $props = get_class_vars(get_class($value)); $output .= '(' . count($props) . ') ' . get_class($value) . ''; foreach ($props as $key => $val) { $output .= "\n" . str_repeat("\t", $level + 1) . $key . ' => '; $output .= dump($value->$key, $level + 1); } $value = ''; } elseif ($type == 'array') { $output .= '(' . count($value) . ')'; foreach ($value as $key => $val) { $output .= "\n" . str_repeat("\t", $level + 1) . dump($key, -1) . ' => '; $output .= dump($val, $level + 1); } $value = ''; } $output .= " $value"; if ($level == 0) { $output .= ''; } return $output; } } /** * Class responsible for testing the module. */ class StatisticsProTestCase extends StatisticsProBaseTestCase { /** * Implementation of getInfo(). */ function getinfo() { return array( 'name' => t('Main tests'), 'description' => t('Test Statistics Pro module functionality.'), 'group' => 'Statistics Pro', ); } /** * Implementation of setUp(). */ function setup() { // Enable any modules required for the test parent::setup('views', 'statistics', 'statspro', 'devel'); } function testMainTests() { $this->createInitialData(); /** * Turning on the access logs. */ $this->drupalLogin($this->users['stats_admin']); $edit = array( 'statistics_enable_access_log' => 1, 'statistics_flush_accesslog_timer' => 9676800, ); $this->drupalPost( 'admin/reports/settings', $edit, t('Save configuration') ); $this->drupalLogout(); // Anonymous user navigation. $this->drupalGetNodeByTitle(t('Node !this/!total - now', array('!this' => 1, '!total' => 1))); $this->drupalGetNodeByTitle(t('Node !this/!total - last week', array('!this' => 2, '!total' => 2))); $this->drupalGetNodeByTitle(t('Node !this/!total - last year', array('!this' => 2, '!total' => 3))); // Asking for inexistent pages. $this->drupalGet('node/111'); $this->drupalGet('node/1099'); // Authenticated user nagivation. $this->drupalLogin($this->users['regular_3']); $this->drupalGetNodeByTitle(t('Node !this/!total - last week', array('!this' => 2, '!total' => 2))); $this->drupalGetNodeByTitle(t('Node !this/!total - last month', array('!this' => 1, '!total' => 1))); $this->drupalGetNodeByTitle(t('Node !this/!total - last week', array('!this' => 1, '!total' => 2))); $this->drupalGetNodeByTitle(t('Node !this/!total - now', array('!this' => 1, '!total' => 1))); // Asking for inexistent pages. $this->drupalGet('node/700'); $this->drupalGet('node/199'); $this->drupalLogin($this->users['regular_1']); $this->drupalGetNodeByTitle(t('Node !this/!total - last week', array('!this' => 1, '!total' => 2))); $this->drupalGetNodeByTitle(t('Node !this/!total - now', array('!this' => 1, '!total' => 1))); $this->drupalGetNodeByTitle(t('Node !this/!total - last year', array('!this' => 1, '!total' => 3))); $this->callCron(); $group = t('General Statistics Pro tests'); $periods = statspro_get_period_items(); // $this->drupalLogin($this->users['stats_admin']); // // $edit = array( // 'plugin' => 'google', // 'type' => 'line2D', // 'width' => 400, // 'height' => 200, // 'color[background]' => '#ffffff', // 'color[text]' => '#000000', // 'color[0]' => '#ff0000', // 'color[1]' => '#00cc00', // 'color[2]' => '#0066b3', // 'color[3]' => '#ff8000', // 'color[4]' => '#ffcc00', // 'color[5]' => '#330099', // 'color[6]' => '#990099', // 'color[7]' => '#ccff00', // ); // $this->drupalPost('admin/settings/charts', $edit, t('Save settings')); $this->drupalLogin($this->users['stats']); /** * Common stats. * * Period: default (today). */ $period = 'today'; $texts = array( 'User registrations8', 'User online7', 'New nodes1', 'Changed nodes0', 'Comments0', 'Page impressions21', 'Page impressions for authenticated users10', 'Errors0', 'Errors for authenticated users0', 'Warnings4', 'Warnings for authenticated users2', 'Emergencies0', 'Emergencies for authenticated users0', 'Alerts0', 'Alerts for authenticated users0', 'Critical conditions0', 'Critical conditions for authenticated users0', ); $raws = array( // t( // ' t('PIs, errors and warnings - @period', array('@period' => $periods[$period]))) // ), ); $this->completeTestStatsHasTexts($texts, $raws, FALSE, $group, FALSE, FALSE); /** * Common stats. * * Period: yesterday. */ $period = 'yesterday'; $texts = array( 'User registrations0', 'User online0', 'New nodes1', 'Changed nodes0', 'Comments0', 'No access and log files available for specified period.', ); $raws = array( // t( // ' t('General view - @period', array('@period' => 'custom period of '))) // ), // t( // ' t('General view - @period', array('@period' => 'custom period of '))) // ), // t( // ' t('General view - @period', array('@period' => 'custom period of '))) // ), // t( // ' t('General view - @period', array('@period' => 'custom period of '))) // ), // t( // ' t('General view - @period', array('@period' => 'custom period of '))) // ), // t( // ' t('General view - @period', array('@period' => 'custom period of '))) // ), // t( // ' t('General view - @period', array('@period' => 'custom period of '))) // ), // t( // ' t('General view - @period', array('@period' => 'custom period of '))) // ), // t( // 'completeTestStatsHasTexts( $texts, $raws, FALSE, $group, 'admin/reports/statspro/comment', FALSE ); /** * Log stats. */ $texts = array( 'Overview for warnings.', 'Overview for warnings, registered users only.', 'Date', 'Trend', 'Amount', ); $result = db_query( 'SELECT day FROM {statspro} WHERE error > 0 OR uerror > 0 OR warning > 0 OR uwarning > 0'); while ($row = db_fetch_array($result)) { $texts[] = $row['day']; } $raws = array(); $this->completeTestStatsHasTexts( $texts, $raws, FALSE, $group, 'admin/reports/statspro/log', FALSE ); /** * Nodes stats. */ $texts = array( 'Overview for new created nodes.', 'Overview for changed nodes.', 'Date', 'Trend', 'Amount', 'New nodes', 'Changed nodes', ); $raws = array(); $this->completeTestStatsHasTexts( $texts, $raws, FALSE, $group, 'admin/reports/statspro/node', FALSE ); /** * PI stats. */ $texts = array( 'Page impressions for guests and registered users.', 'Page impressions registered users.', 'Date', 'Trend', 'Amount', 'Page impressions', 'Page impressions, users', ); $raws = array(); $this->completeTestStatsHasTexts( $texts, $raws, FALSE, $group, 'admin/reports/statspro/pi', FALSE ); /** * Users stats. */ $texts = array( 'Overview for new user registrations.', 'Overview for online user activity.', 'Date', 'Trend', 'Amount', 'User registrations', 'User online', ); $raws = array(); $this->completeTestStatsHasTexts( $texts, $raws, FALSE, $group, 'admin/reports/statspro/user', FALSE ); /** * Generating some traffic to be reported by path aggregator. */ $this->drupalLogout(); $this->drupalGet('node/1'); $this->drupalGet('node/4'); $this->drupalGet('node/5'); $this->drupalGet('node/6'); $this->drupalGet('node/7'); $this->drupalGet('node/8'); $this->drupalLogin($this->users['regular_2']); $this->drupalGet('node/1'); $this->drupalGet('node/2'); $this->drupalGet('node/3'); $this->drupalGet('node/4'); $this->drupalGet('node/5'); $this->drupalLogin($this->users['regular_3']); $this->drupalGet('node/4'); $this->drupalGet('node/5'); $this->drupalGet('node/6'); $this->drupalGet('node/7'); $this->drupalGet('node/8'); /** * Path aggregated aggregator creation tests. */ $this->drupalLogin($this->users['stats_admin']); $aggregators = array(); $texts = array('No path aggregators defined.'); $raws = array(); $group = 'Path aggregated'; $this->completeTestStatsHasTexts( $texts, $raws, FALSE, $group, 'admin/settings/statspro/path_aggregator/list', FALSE ); $aggregator_name = 'Aggregator 1'; $aggregators[] = $aggregator_name; $edit = array( 'name' => $aggregator_name, 'paths' => "node/1\nnode/3", ); $this->drupalPost( 'admin/settings/statspro/path_aggregator/add', $edit, t('Add') ); $this->assertText( $aggregator_name, t('New path aggregator %name created.', array('%name' => $aggregator_name)), $group ); $aggregator_name = 'Aggregator 2'; $aggregators[] = $aggregator_name; $edit = array( 'name' => $aggregator_name, 'paths' => "node/2\nnode/4", ); $this->drupalPost( 'admin/settings/statspro/path_aggregator/add', $edit, t('Add') ); $this->assertText( $aggregator_name, t('New path aggregator %name created.', array('%name' => $aggregator_name)), $group ); $aggregator_name = 'Aggregator even'; $aggregators[] = $aggregator_name; $edit = array( 'name' => $aggregator_name, 'paths' => "node/2\nnode/4\nnode/6\nnode/8", ); $this->drupalPost( 'admin/settings/statspro/path_aggregator/add', $edit, t('Add') ); $this->assertText( $aggregator_name, t('New path aggregator %name created.', array('%name' => $aggregator_name)), $group ); $aggregator_name = 'Aggregator odd'; $aggregators[] = $aggregator_name; $edit = array( 'name' => $aggregator_name, 'paths' => "node/1\nnode/3\nnode/5\nnode/7", ); $this->drupalPost( 'admin/settings/statspro/path_aggregator/add', $edit, t('Add') ); $this->assertText( $aggregator_name, t('New path aggregator %name created.', array('%name' => $aggregator_name)), $group ); $texts = $aggregators; $raws = array(); $this->completeTestStatsHasTexts( $texts, $raws, FALSE, $group, 'admin/settings/statspro/path_aggregator/list', FALSE ); /** * Path aggregated report tests. */ $this->drupalLogin($this->users['stats']); $texts = array( 'Aggregator 1321', 'Aggregator 2431', 'Aggregator even421', 'Aggregator odd531', ); $raws = array(); $this->completeTestStatsHasTexts( $texts, $raws, FALSE, $group, 'admin/reports/statspro/path_aggregated', FALSE ); $this->drupalLogin($this->users['stats_admin']); $edit = array(); $this->drupalPost( 'admin/settings/statspro/path_aggregator/delete/3', $edit, 'Delete' ); $texts = array( 'Aggregator 1', 'Aggregator 2', 'Aggregator odd', ); foreach ($texts as $text) { $this->assertText( $text, t('Text %text found on page.', array('%text' => $text)), $group ); } $text = 'Aggregator even'; $this->assertNoText( $text, t('Text %text not found on page.', array('%text' => $text)), $group ); } } /** * Class resposible for testing the statspro class. */ class StatsproTestCase extends StatisticsProBaseTestCase { protected $statspro; /** * Implementation of getInfo(). */ function getinfo() { return array( 'name' => t('statspro class tests'), 'description' => t('Test the statspro class.'), 'group' => 'Statistics Pro', ); } /** * Implementation of setUp(). */ function setup() { // Enable any modules required for the test parent::setup('views', 'statistics', 'statspro'); require_once drupal_get_path('module', 'statspro') . '/statspro.inc'; $this->statspro = new StatsPro(); } function testInitialState() { $this->createInitialData(); $this->callCron(); $group = t('General statspro class tests'); /** * Absolute amounts: pi, upi, error, uerror, warning and uwarning. */ $this->completeTestAggregatedData('pi', 0, $group); $this->completeTestAggregatedData('upi', 0, $group); $this->completeTestAggregatedData('error', 0, $group); $this->completeTestAggregatedData('uerror', 0, $group); $this->completeTestAggregatedData('warning', 0, $group); $this->completeTestAggregatedData('uwarning', 0, $group); $this->completeTestAggregatedData('emergency', 0, $group); $this->completeTestAggregatedData('uemergency', 0, $group); $this->completeTestAggregatedData('alert', 0, $group); $this->completeTestAggregatedData('ualert', 0, $group); $this->completeTestAggregatedData('critical', 0, $group); $this->completeTestAggregatedData('ucritical', 0, $group); /** * Non-absolute amounts: users, terms, nodes, node_types, comments, * aliases, sessions and modules. */ /** * Drupal already creates the "zero" user which is tne non-authenticated * user and saves the slot for the admin user so we have to add 2 to the * number of users we created up until now in the test. */ $correct = 2 + count($this->users); $this->completeTestAggregatedData('users', $correct, $group); $this->completeTestAggregatedData('terms', 0, $group); $correct = count($this->node_titles); $this->completeTestAggregatedData('nodes', $correct, $group); // Drupal already has 2 node types defined: page and story. $correct = 2; $this->completeTestAggregatedData('node_types', $correct, $group); $this->completeTestAggregatedData('comments', 0, $group); $this->completeTestAggregatedData('aliases', 0, $group); $this->completeTestAggregatedData('sessions', 1, $group); // The basic Drupal installation already has 11 modules enabled. $correct = 11 + count($this->modules); $this->completeTestAggregatedData('modules', $correct, $group); } function testPosNavegationState() { $this->createInitialData(); /** * Turning on the access logs. */ $this->drupalLogin($this->users['stats_admin']); $edit = array( 'statistics_enable_access_log' => 1, 'statistics_flush_accesslog_timer' => 9676800, ); $this->drupalPost( 'admin/reports/settings', $edit, t('Save configuration') ); $this->drupalLogout(); // Anonymous user navigation. $this->drupalGetNodeByTitle(t('Node !this/!total - now', array('!this' => 1, '!total' => 1))); $this->drupalGetNodeByTitle(t('Node !this/!total - last week', array('!this' => 2, '!total' => 2))); $this->drupalGetNodeByTitle(t('Node !this/!total - last year', array('!this' => 2, '!total' => 3))); // Asking for inexistent pages. $this->drupalGet('node/111'); $this->drupalGet('node/1099'); // Authenticated user nagivation. $this->drupalLogin($this->users['regular_3']); $this->drupalGetNodeByTitle(t('Node !this/!total - last week', array('!this' => 2, '!total' => 2))); $this->drupalGetNodeByTitle(t('Node !this/!total - last month', array('!this' => 1, '!total' => 1))); $this->drupalGetNodeByTitle(t('Node !this/!total - last week', array('!this' => 1, '!total' => 2))); $this->drupalGetNodeByTitle(t('Node !this/!total - now', array('!this' => 1, '!total' => 1))); // Asking for inexistent pages. $this->drupalGet('node/700'); $this->drupalGet('node/199'); $this->drupalLogin($this->users['regular_1']); $this->drupalGetNodeByTitle(t('Node !this/!total - last week', array('!this' => 1, '!total' => 2))); $this->drupalGetNodeByTitle(t('Node !this/!total - now', array('!this' => 1, '!total' => 1))); $this->drupalGetNodeByTitle(t('Node !this/!total - last year', array('!this' => 1, '!total' => 3))); $this->callCron(); $group = t('General statspro class tests'); /** * Absolute amounts: pi, upi, error, uerror, warning and uwarning. * /** * Besides the 10 get nodes above, Drupal produces 11 extra page impressions. */ $correct = 10 + 11; $this->completeTestAggregatedData('pi', $correct, $group); $this->completeTestAggregatedData('upi', 10, $group); $this->completeTestAggregatedData('error', 0, $group); $this->completeTestAggregatedData('uerror', 0, $group); $this->completeTestAggregatedData('warning', 4, $group); $this->completeTestAggregatedData('uwarning', 2, $group); $this->completeTestAggregatedData('emergency', 0, $group); $this->completeTestAggregatedData('uemergency', 0, $group); $this->completeTestAggregatedData('alert', 0, $group); $this->completeTestAggregatedData('ualert', 0, $group); $this->completeTestAggregatedData('critical', 0, $group); $this->completeTestAggregatedData('ucritical', 0, $group); /** * Non-absolute amounts: users, terms, nodes, node_types, comments, * aliases, sessions and modules. */ /** * Drupal already creates the "zero" user which is tne non-authenticated * user and saves the slot for the admin user so we have to add 2 to the * number of users we created up until now in the test. */ $correct = 2 + count($this->users); $this->completeTestAggregatedData('users', $correct, $group); $this->completeTestAggregatedData('terms', 0, $group); $correct = count($this->node_titles); $this->completeTestAggregatedData('nodes', $correct, $group); // Drupal already has 2 node types defined: page and story. $correct = 2; $this->completeTestAggregatedData('node_types', $correct, $group); $this->completeTestAggregatedData('comments', 0, $group); $this->completeTestAggregatedData('aliases', 0, $group); $this->completeTestAggregatedData('sessions', 1, $group); // The basic Drupal installation already has 11 modules enabled. $correct = 11 + count($this->modules); $this->completeTestAggregatedData('modules', $correct, $group); } }