You are here

ip2country.test in IP-based Determination of a Visitor's Country 7

Tests suite for the ip2country module.

@author Tim Rohaly. <http://drupal.org/user/202830>

File

tests/ip2country.test
View source
<?php

/**
 * @file
 * Tests suite for the ip2country module.
 *
 * @author Tim Rohaly.    <http://drupal.org/user/202830>
 */

// Utility functions for loading IP/Country DB from external sources.
module_load_include('inc', 'ip2country');

/**
 * Tests operations of the IP to Country module.
 *
 * @todo Need 1 class for unit tests, 1 class for functional tests,
 * and 1 function for DB tests because filling takes so long.
 */
class ip2countryTestCase extends DrupalWebTestCase {

  /**
   * Admin user.
   */
  protected $adminUser;

  /**
   * Authenticated but unprivileged user.
   */
  protected $unprivUser;

  /**
   * Implements DrupalWebTestCase::getInfo().
   */
  public static function getInfo() {
    return array(
      'name' => 'IP/Country lookup',
      'description' => 'Test operations of IP to Country module.',
      'group' => 'IP to Country',
    );
  }

  /**
   * Overrides DrupalWebTestCase::setUp().
   */
  protected function setUp() {

    //
    // Don't install ip2country! parent::setUp() creates a clean
    // environment, so we can influence the install before we call setUp().
    // We don't want the DB populated, so we'll manually install ip2country.
    //
    parent::setUp();

    //
    // Set a run-time long enough so the script won't break.
    //
    $this->timeLimit = 3 * 60;

    // 3 minutes!
    drupal_set_time_limit($this->timeLimit);

    // Turn off automatic DB download when module is installed.
    variable_set('ip2country_populate_database_on_install', FALSE);

    // Explicitly enable the module so that it will have access
    // to the variable we set above.
    $status = module_enable(array(
      'ip2country',
    ), FALSE);
    $this
      ->resetAll();

    // The secret ingredient.
    $this
      ->assertTrue($status, t('Module %module enabled.', array(
      '%module' => 'ip2country',
    )));
    $this
      ->assertTrue(ip2country_get_count() == 0, t('Database is empty.'));

    // Create our test users.
    $this->adminUser = $this
      ->drupalCreateUser(array(
      'administer site configuration',
      'access administration pages',
      'access site reports',
      'administer ip2country',
    ));
    $this->unprivUser = $this
      ->drupalCreateUser();
  }

  /**
   * Tests IP lookup for addresses in / not in the database.
   */
  public function testIpLookup() {
    ip2country_update_database('arin');
    $this
      ->assertTrue(($count = ip2country_get_count()) != 0, t('Database has been updated with @rows rows.', array(
      '@rows' => $count,
    )));

    // Real working IPs.
    $ip_array = array(
      '125.29.33.201',
      '212.58.224.138',
      '184.51.240.110',
      '210.87.9.66',
      '93.184.216.119',
    );
    foreach ($ip_array as $ip_address) {

      // Test dotted quad string form of address.
      $country = ip2country_get_country($ip_address);
      $this
        ->assertTrue($country, t('@ip found, resolved to @country.', array(
        '@ip' => $ip_address,
        '@country' => $country,
      )));

      // Test 32-bit unsigned long form of address.
      $usl_country = ip2country_get_country(ip2long($ip_address));
      $this
        ->assertTrue($usl_country == $country, t('Unsigned long lookup found same country code.'));
      $this
        ->pass(t('Valid IP found in database.'));
    }

    // Invalid and reserved IPs.
    $ip_array = array(
      '127.0.0.1',
      '358.1.1.0',
    );
    foreach ($ip_array as $ip_address) {
      $country = ip2country_get_country($ip_address);
      $this
        ->assertFalse($country, t('@ip not found in database.', array(
        '@ip' => $ip_address,
      )));
      $this
        ->pass(t('Invalid IP not found in database.'));
    }
    ip2country_empty_database();
    $this
      ->assertTrue(ip2country_get_count() == 0, t('Database is Empty.'));
  }

  /**
   * Tests injecting IP data via hook_ip2country_alter().
   */
  public function testAlterHook() {
    $this
      ->pass(t('testAlterHook passed.'));
  }

  /**
   * Tests Default country.
   */
  public function testDefaultCountry() {
    $this
      ->pass(t('testDefaultCountry passed.'));
  }

  /**
   * Tests module permissions / access to configuration page.
   */
  public function testUserAccess() {

    //
    // Test as anonymous user.
    //
    $this
      ->drupalGet('admin/config');
    $this
      ->assertResponse(403);
    $this
      ->assertText(t('Access denied'));
    $this
      ->assertText(t('You are not authorized to access this page.'));
    $this
      ->drupalGet('admin/config/people/ip2country');
    $this
      ->assertResponse(403);

    // Try to trigger DB update as anonymous.
    $this
      ->drupalGet('admin/config/people/ip2country/update/arin');
    $this
      ->assertResponse(403);

    //
    // Test as authenticated but unprivileged user.
    //
    $this
      ->drupalLogin($this->unprivUser);
    $this
      ->drupalGet('admin/config');
    $this
      ->assertResponse(403);
    $this
      ->drupalGet('admin/config/people/ip2country');
    $this
      ->assertResponse(403);
    $this
      ->drupalLogout();

    //
    // As admin user.
    //
    $this
      ->drupalLogin($this->adminUser);
    $this
      ->drupalGet('admin/config');
    $this
      ->assertResponse(200);
    $this
      ->assertText(t('User location'));
    $this
      ->assertText(t('Settings for determining user location from IP address.'));
    $this
      ->drupalGet('admin/config/people/ip2country');
    $this
      ->assertResponse(200);
    $this
      ->assertText(t('User location'));
    $this
      ->assertText(t('Configuration settings for the ip2country module.'));
    $this
      ->assertText(t('Database is empty.'));
    $this
      ->assertFieldByName('ip2country_watchdog', 1, t('Database updates are being logged to watchdog.'));
    $this
      ->assertFieldByName('ip2country_rir', 'arin', t('Database updates from arin.'));

    // Update database via UI - choose a random RIR.
    // (Actually short-circuiting the UI here because of the Ajax call).
    $rir = array_rand(array(
      'afrinic' => 'AFRINIC',
      'arin' => 'ARIN',
      'apnic' => 'APNIC',
      'lacnic' => 'LACNIC',
      'ripe' => 'RIPE',
    ));
    $this
      ->drupalGet('admin/config/people/ip2country/update/' . $rir);
    $this
      ->assertText(t('The IP to Country database has been updated from @rir.', array(
      '@rir' => strtoupper($rir),
    )));

    // Check watchdog.
    $this
      ->drupalGet('admin/reports/dblog');
    $this
      ->assertText(t('Recent log messages'));
    $this
      ->assertText('ip2country');
    $this
      ->assertLink(t('Manual database update from @rir server.', array(
      '@rir' => strtoupper($rir),
    )));

    // Drill down.
    $this
      ->clickLink(t('Manual database update from @rir server.', array(
      '@rir' => strtoupper($rir),
    )));
    $this
      ->assertText(t('Details'));
    $this
      ->assertText('ip2country');
    $this
      ->assertText(t('Manual database update from @rir server.', array(
      '@rir' => strtoupper($rir),
    )));
    $this
      ->drupalLogout();
  }

  /**
   * Tests $user object for proper value.
   */
  public function testUserObject() {
    $this
      ->pass(t('testUserObject passed.'));
  }

  /**
   * Tests UI.
   */
  public function testUi() {
    $this
      ->pass(t('testUi passed.'));
  }

  /**
   * Tests IP Spoofing.
   *
   * @todo Should cover anonymous vs authenticated users and
   * check for info $messages.
   */
  public function testIpSpoofing() {
    $this
      ->pass(t('testIpSpoofing passed.'));
  }

  /**
   * Tests Country Spoofing.
   *
   * @todo Should cover anonymous vs authenticated users and
   * check for info $messages.
   */
  public function testCountrySpoofing() {
    $this
      ->pass(t('testCountrySpoofing passed.'));
  }

  /**
   * Tests manual lookup.
   */
  public function testIpManualLookup() {

    //$this->clickLink(t('Lookup'));
    $this
      ->pass(t('testIpManualLookup passed.'));
  }

  /**
   * Tests DB download.
   */
  public function testDbDownload() {
    ip2country_empty_database();
    $this
      ->assertTrue(ip2country_get_count() == 0, t('Database is Empty.'));

    // Choose a random RIR.
    $rir = array_rand(array(
      //    'afrinic' => 'AFRINIC', // Don't use AFRINIC because it's incomplete.
      'arin' => 'ARIN',
      'apnic' => 'APNIC',
      'lacnic' => 'LACNIC',
      'ripe' => 'RIPE',
    ));
    ip2country_update_database($rir);
    $this
      ->assertTrue(($count = ip2country_get_count()) != 0, t('Database has been updated from %rir with @rows rows.', array(
      '%rir' => strtoupper($rir),
      '@rows' => $count,
    )));
    ip2country_empty_database();
    $this
      ->assertTrue(ip2country_get_count() == 0, t('Database is Empty.'));
  }

  /**
   * Tests manual DB update.
   */
  public function testDbManualUpdate() {

    //$this->clickLink(t('Update'));
    $rows = db_select('ip2country')
      ->countQuery()
      ->execute()
      ->fetchField();

    //$this->assertText(

    //  t('The IP to Country database has been updated from @rir. @rows rows affected.', array('@rir' => $rir, '@rows' => $rows)),
    //  t('Database was updated manually.')

    //);
    $this
      ->pass(t('testDbManualUpdate passed.'));
  }

  /**
   * Tests cron DB update.
   */
  public function testDbCronUpdate() {
    $this
      ->pass(t('testDbCronUpdate passed.'));
  }

  /**
   * Tests logging of DB updates.
   */
  public function testDbUpdateLogging() {

    // Turn off logging.
    // Turn on logging.
    $edit = array(
      'ip2country_watchdog' => array(
        'test' => TRUE,
      ),
    );

    //$this->drupalPost(

    //  'admin/store/settings/countries/edit',
    //  $edit,
    //  t('Import')

    //);

    //$this->assertText(

    //  t('Database updated from @rir server.', array('@rir' => $rir)),
    //  t('Watchdog reported database update.')

    //);
    $this
      ->pass(t('testDbUpdateLogging passed.'));
  }

  /**
   * Overrides DrupalWebTestCase::tearDown().
   */
  protected function tearDown() {

    // Perform any clean-up tasks.
    variable_del('ip2country_populate_database_on_install');

    // Finally...
    parent::tearDown();
  }

}

Classes

Namesort descending Description
ip2countryTestCase Tests operations of the IP to Country module.