You are here

class ALProfilesAPITest in Acquia Lift Connector 7.2

Same name and namespace in other branches
  1. 7 acquia_lift_profiles/tests/acquia_lift_profiles_unit.test \ALProfilesAPITest

@file Unit tests for Acquia Lift Profiles module.

Hierarchy

Expanded class hierarchy of ALProfilesAPITest

File

acquia_lift_profiles/tests/acquia_lift_profiles_unit.test, line 8
Unit tests for Acquia Lift Profiles module.

View source
class ALProfilesAPITest extends DrupalUnitTestCase {
  public static function getInfo() {
    return array(
      'name' => t('Acquia Lift Profiles Unit Tests'),
      'description' => t('Unit tests for ALProfilesAPI methods.'),
      'group' => t('Personalize'),
    );
  }
  protected function setUp() {
    require_once dirname(__FILE__) . '/../includes/acquia_lift_profiles.classes.inc';
    require_once dirname(__FILE__) . '/acquia_lift_profiles.test_classes.inc';
    parent::setUp();
  }
  protected function tearDown() {
    parent::tearDown();
    $this->logger = NULL;
    DummyAcquiaLiftHttpClient::clearLoggedRequests();
  }

  /**
   * @var AcquiaLiftTestLogger
   */
  protected $logger = NULL;

  /**
   * @var DummyALProfilesHttpClient
   */
  protected $httpClient = NULL;

  /**
   * The string to use as account name.
   *
   * @var string
   */
  protected $accountName = 'MYALPROFILESACCOUNT';

  /**
   * The string to use as customer site.
   *
   * @var string
   */
  protected $customerSite = '';

  /**
   * The string to use as the username.
   *
   * @var string
   */
  protected $accessKey = 'abc123456';

  /**
   * The string to use as the password.
   *
   * @var string
   */
  protected $secretKey = 'xyz987654';

  /**
   * The string to use as the API URL.
   *
   * @var string
   */
  protected $apiUrl = 'http://api.acquia_lift_profiles.example.com';

  /**
   * Tests getting ALProfilesAPI instance with invalid and valid credentials.
   */
  function testGetInstance() {

    // Make sure calls to variable_get() for the account name and api url return
    // an empty string.
    global $conf;
    $original_conf = $conf;
    $conf['acquia_lift_profiles_account_name'] = '';
    $conf['acquia_lift_profiles_api_url'] = '';
    $conf['acquia_lift_profiles_access_key'] = '';
    $conf['acquia_lift_profiles_secret_key'] = '';
    try {
      $acquia_lift_profiles_api = ALProfilesAPI::getInstance('', 'ohai');
      $this
        ->fail('Should never reach here.');
    } catch (Exception $e) {
      $this
        ->assertTrue($e instanceof ALProfilesCredsException);
      $this
        ->assertEqual('Missing acquia_lift_profiles account information.', $e
        ->getMessage());
      try {
        $acquia_lift_profiles_api = ALProfilesAPI::getInstance($this->accountName, $this->customerSite, 'some\\invalid\\url', $this->accessKey, $this->secretKey);
        $this
          ->fail('Should never reach here.');
      } catch (Exception $e) {
        $this
          ->assertTrue($e instanceof ALProfilesCredsException);
        $this
          ->assertEqual('API URL is not a valid URL.', $e
          ->getMessage());
        try {

          // Here we pass valid creds.
          $acquia_lift_profiles_api = ALProfilesAPI::getInstance($this->accountName, $this->customerSite, $this->apiUrl, $this->accessKey, $this->secretKey);
          $acquia_lift_profiles_api
            ->setLogger(new AcquiaLiftTestLogger());
          $this
            ->assertEqual($this->apiUrl, $acquia_lift_profiles_api
            ->getApiUrl());
        } catch (Exception $e) {
          $this
            ->fail('Exception thrown when none expected.');
        }
      }
    }
    ALProfilesAPI::reset();

    // Put back our original conf settings.
    $conf = $original_conf;
  }
  function testGetSegments() {
    $acquia_lift_profiles_api = $this
      ->getALProfilesAPI();
    $acquia_lift_profiles_api
      ->getSegments();

    // Define the requests we expect to have been made to our dummy http
    // client for this operation.
    $canonicalRequest = "GET\naccept:application/json\n/dashboard/rest/{$acquia_lift_profiles_api->getAccountName()}/segments";
    $hmac = base64_encode(hash_hmac('sha1', $canonicalRequest, $this->secretKey, TRUE));
    $auth_header = 'HMAC ' . $this->accessKey . ':' . $hmac;
    $requests = array(
      array(
        'type' => 'get',
        'uri' => "{$acquia_lift_profiles_api->getApiUrl()}/dashboard/rest/{$acquia_lift_profiles_api->getAccountName()}/segments",
        'headers' => array(
          'Authorization' => $auth_header,
          'Accept' => 'application/json',
        ),
        'options' => array(),
        'body' => NULL,
      ),
    );

    // Confirm the expected requests were made.
    $this
      ->assertAPIRequests($requests);
    $logs = array();
    $this
      ->assertLogs($logs);

    // Now try with a broken http client (simulating a bad response).
    $acquia_lift_profiles_api = $this
      ->getALProfilesAPI(TRUE);
    try {
      $acquia_lift_profiles_api
        ->getSegments();
      $this
        ->fail('Exception should have been thrown');
    } catch (Exception $e) {
    }

    // Confirm the expected requests were made.
    $this
      ->assertAPIRequests($requests);
    $logs = array(
      array(
        'level' => 'error',
        'message' => 'Could not get segments from Acquia Lift Profiles "500 Internal Server Error"',
      ),
    );
    $this
      ->assertLogs($logs);

    // Now try with a non-empty customer site
    ALProfilesAPI::reset();
    $this->customerSite = 'TESTSITE';
    $acquia_lift_profiles_api = $this
      ->getALProfilesAPI();
    $acquia_lift_profiles_api
      ->getSegments();

    // Define the requests we expect to have been made to our dummy http
    // client for this operation.
    $canonicalRequest = "GET\naccept:application/json\n/dashboard/rest/{$acquia_lift_profiles_api->getAccountName()}/segments?customerSite={$this->customerSite}";
    $hmac = base64_encode(hash_hmac('sha1', $canonicalRequest, $this->secretKey, TRUE));
    $auth_header = 'HMAC ' . $this->accessKey . ':' . $hmac;
    $requests = array(
      array(
        'type' => 'get',
        'uri' => "{$acquia_lift_profiles_api->getApiUrl()}/dashboard/rest/{$acquia_lift_profiles_api->getAccountName()}/segments?customerSite={$this->customerSite}",
        'headers' => array(
          'Authorization' => $auth_header,
          'Accept' => 'application/json',
        ),
        'options' => array(),
        'body' => NULL,
      ),
    );

    // Confirm the expected requests were made.
    $this
      ->assertAPIRequests($requests);
    $logs = array();
    $this
      ->assertLogs($logs);
    ALProfilesAPI::reset();
    $this->customerSite = '';
  }

  /**
   * Test ALProfilesAPI->saveEvent()
   */
  public function testSaveEvent() {
    $acquia_lift_profiles_api = $this
      ->getALProfilesAPI();
    $event_name = 'test_event';
    $event_label = 'My Test Event';
    $acquia_lift_profiles_api
      ->saveEvent($event_name, $event_label);

    // Define the requests we expect to have been made to our dummy http
    // client for this operation.
    $canonicalRequest = "PUT\naccept:application/json\n/dashboard/rest/{$acquia_lift_profiles_api->getAccountName()}/events/{$event_name}?label={$event_label}&type=OTHER";
    $hmac = base64_encode(hash_hmac('sha1', $canonicalRequest, $this->secretKey, TRUE));
    $auth_header = 'HMAC ' . $this->accessKey . ':' . $hmac;
    $encoded_label = rawurlencode($event_label);
    $requests = array(
      array(
        'type' => 'put',
        'uri' => "{$acquia_lift_profiles_api->getApiUrl()}/dashboard/rest/{$acquia_lift_profiles_api->getAccountName()}/events/{$event_name}?label={$encoded_label}&type=OTHER",
        'headers' => array(
          'Authorization' => $auth_header,
          'Accept' => 'application/json',
        ),
        'options' => array(),
        'body' => NULL,
      ),
    );

    // Confirm the expected requests were made.
    $this
      ->assertAPIRequests($requests);
    $logs = array(
      array(
        'level' => PersonalizeLogLevel::INFO,
        'message' => "The event {$event_name} has been saved to Acquia Lift Profiles",
      ),
    );
    $this
      ->assertLogs($logs);

    // Now try with a broken client.
    $acquia_lift_profiles_api = $this
      ->getALProfilesAPI(TRUE);
    try {
      $acquia_lift_profiles_api
        ->saveEvent($event_name, $event_label);
    } catch (Exception $e) {
      $this
        ->assertTrue($e instanceof ALProfilesException);
    }

    // Confirm the expected requests were made.
    $this
      ->assertAPIRequests($requests);
    $logs = array(
      array(
        'level' => PersonalizeLogLevel::ERROR,
        'message' => "Could not save event {$event_name} to Acquia Lift Profiles",
      ),
    );
    $this
      ->assertLogs($logs);

    // Now try with a non-empty customer site
    ALProfilesAPI::reset();
    $this->customerSite = 'TESTSITE';
    $acquia_lift_profiles_api = $this
      ->getALProfilesAPI();
    $acquia_lift_profiles_api
      ->saveEvent($event_name, $event_label);

    // Our request should now include a customerSite param in the querystring
    $canonicalRequest = "PUT\naccept:application/json\n/dashboard/rest/{$acquia_lift_profiles_api->getAccountName()}/events/{$event_name}?customerSite={$this->customerSite}&label={$event_label}&type=OTHER";
    $hmac = base64_encode(hash_hmac('sha1', $canonicalRequest, $this->secretKey, TRUE));
    $auth_header = 'HMAC ' . $this->accessKey . ':' . $hmac;
    $encoded_label = rawurlencode($event_label);
    $requests = array(
      array(
        'type' => 'put',
        'uri' => "{$acquia_lift_profiles_api->getApiUrl()}/dashboard/rest/{$acquia_lift_profiles_api->getAccountName()}/events/{$event_name}?customerSite={$this->customerSite}&label={$encoded_label}&type=OTHER",
        'headers' => array(
          'Authorization' => $auth_header,
          'Accept' => 'application/json',
        ),
        'options' => array(),
        'body' => NULL,
      ),
    );

    // Confirm the expected requests were made.
    $this
      ->assertAPIRequests($requests);
    $logs = array(
      array(
        'level' => PersonalizeLogLevel::INFO,
        'message' => "The event {$event_name} has been saved to Acquia Lift Profiles",
      ),
    );
    $this
      ->assertLogs($logs);
    $this->customerSite = '';
    ALProfilesAPI::reset();
  }

  /**
   * Test ALProfilesAPI->deleteEvent()
   */
  public function testDeleteEvent() {
    $acquia_lift_profiles_api = $this
      ->getALProfilesAPI();
    $event_name = 'test_event';
    $acquia_lift_profiles_api
      ->deleteEvent($event_name);

    // Define the requests we expect to have been made to our dummy http
    // client for this operation.
    $canonicalRequest = "DELETE\n/dashboard/rest/{$acquia_lift_profiles_api->getAccountName()}/events/{$event_name}";
    $hmac = base64_encode(hash_hmac('sha1', $canonicalRequest, $this->secretKey, TRUE));
    $auth_header = 'HMAC ' . $this->accessKey . ':' . $hmac;
    $requests = array(
      array(
        'type' => 'delete',
        'uri' => "{$acquia_lift_profiles_api->getApiUrl()}/dashboard/rest/{$acquia_lift_profiles_api->getAccountName()}/events/{$event_name}",
        'headers' => array(
          'Authorization' => $auth_header,
        ),
        'options' => array(),
        'body' => NULL,
      ),
    );

    // Confirm the expected requests were made.
    $this
      ->assertAPIRequests($requests);
    $logs = array(
      array(
        'level' => PersonalizeLogLevel::INFO,
        'message' => "The event {$event_name} was deleted from Acquia Lift Profiles",
      ),
    );
    $this
      ->assertLogs($logs);

    // Now try with a broken client.
    $acquia_lift_profiles_api = $this
      ->getALProfilesAPI(TRUE);
    try {
      $acquia_lift_profiles_api
        ->deleteEvent($event_name);
    } catch (Exception $e) {
      $this
        ->assertTrue($e instanceof ALProfilesException);
    }

    // Confirm the expected requests were made.
    $this
      ->assertAPIRequests($requests);
    $logs = array(
      array(
        'level' => PersonalizeLogLevel::ERROR,
        'message' => "Could not delete event {$event_name} from Acquia Lift Profiles",
      ),
    );
    $this
      ->assertLogs($logs);

    // Now try with a non-empty customer site
    ALProfilesAPI::reset();
    $this->customerSite = 'TESTSITE';
    $acquia_lift_profiles_api = $this
      ->getALProfilesAPI();
    $event_name = 'test_event';
    $acquia_lift_profiles_api
      ->deleteEvent($event_name);

    // Our request should now include a customerSite param in the querystring
    $canonicalRequest = "DELETE\n/dashboard/rest/{$acquia_lift_profiles_api->getAccountName()}/events/{$event_name}?customerSite=TESTSITE";
    $hmac = base64_encode(hash_hmac('sha1', $canonicalRequest, $this->secretKey, TRUE));
    $auth_header = 'HMAC ' . $this->accessKey . ':' . $hmac;
    $requests = array(
      array(
        'type' => 'delete',
        'uri' => "{$acquia_lift_profiles_api->getApiUrl()}/dashboard/rest/{$acquia_lift_profiles_api->getAccountName()}/events/{$event_name}?customerSite=TESTSITE",
        'headers' => array(
          'Authorization' => $auth_header,
        ),
        'options' => array(),
        'body' => NULL,
      ),
    );

    // Confirm the expected requests were made.
    $this
      ->assertAPIRequests($requests);
    $logs = array(
      array(
        'level' => PersonalizeLogLevel::INFO,
        'message' => "The event {$event_name} was deleted from Acquia Lift Profiles",
      ),
    );
    $this
      ->assertLogs($logs);
    ALProfilesAPI::reset();
  }

  /**
   * Tests the method that canonicalizes a request into a string for signing.
   */
  function testCanonicalizeRequest() {
    $method = 'GET';
    $path = '/some/path';
    $parameters = array(
      'param' => 'stuff',
      'another' => 'moar-stuff',
      'last-param' => 'yet-moar-stuff',
    );
    $headers = array(
      'User-Agent' => 'Drupal',
      'Accept' => 'text/plain',
      'Host' => 'example.com',
    );
    $acquia_lift_profiles_api = $this
      ->getALProfilesAPI();
    $expected = "GET\naccept:text/plain\nhost:example.com\nuser-agent:Drupal\n/some/path?another=moar-stuff&last-param=yet-moar-stuff&param=stuff";
    $str = $acquia_lift_profiles_api
      ->canonicalizeRequest($method, $path, $parameters, $headers, FALSE);
    $this
      ->assertEqual($str, $expected);
    $method = 'PUT';
    $parameters['new-param'] = 'ohai';

    // Add a header that's not in the whitelist, it should not get added to the
    // canonical request.
    $headers['Content-Type'] = 'application/x-www-form-urlencoded';
    $expected = "PUT\naccept:text/plain\nhost:example.com\nuser-agent:Drupal\n/some/path?another=moar-stuff&last-param=yet-moar-stuff&new-param=ohai&param=stuff";
    $str = $acquia_lift_profiles_api
      ->canonicalizeRequest($method, $path, $parameters, $headers, FALSE);
    $this
      ->assertEqual($str, $expected);
  }

  /**
   * Returns a ALProfilesAPI instance that can be used to test methods.
   *
   * @param bool $broken
   *   Whether the HTTP client used by the API class should be broken, simulating
   *   500 responses from Acquia Lift Profiles.
   * @return ALProfilesAPI
   *   A ALProfilesAPI instance.
   */
  protected function getALProfilesAPI($broken = FALSE) {

    // Make sure calls to variable_get() for the customer site return an empty string.
    global $conf;
    $original_conf = $conf;
    $conf['acquia_lift_profiles_site_name'] = '';
    $acquia_lift_profiles_api = ALProfilesAPI::getInstance($this->accountName, $this->customerSite, $this->apiUrl, $this->accessKey, $this->secretKey);
    $conf = $original_conf;

    // Create a dummy http client for the Acquia Lift Profiles API to use. All
    // requests to it will be logged and retrievable for checking later.
    $this->httpClient = new DummyALProfilesHttpClient($broken);
    $acquia_lift_profiles_api
      ->setHttpClient($this->httpClient);
    if ($this->logger === NULL) {

      // Create a dummy logger instance which will maintain a log in memory
      // that we can retrieve for checking later.
      $this->logger = new AcquiaLiftTestLogger(FALSE);
    }
    $acquia_lift_profiles_api
      ->setLogger($this->logger);
    return $acquia_lift_profiles_api;
  }

  /**
   * Asserts that the expected requests were made to the http client.
   *
   * @param $expected_requests
   */
  protected function assertAPIRequests($expected_requests) {
    $logged_requests = DummyAcquiaLiftHttpClient::getLoggedRequests();
    $this
      ->assertEqual($expected_requests, $logged_requests);
    DummyAcquiaLiftHttpClient::clearLoggedRequests();
  }

  /**
   * Asserts that the expected messages were logged to the logger.
   *
   * @param $expected_logs
   */
  protected function assertLogs($expected_logs) {
    $logs = $this->logger
      ->getLogs();
    $this
      ->assertEqual($expected_logs, $logs);
    $this->logger
      ->clearLogs();
  }

}

Members

Namesort descending Modifiers Type Description Overrides
ALProfilesAPITest::$accessKey protected property The string to use as the username.
ALProfilesAPITest::$accountName protected property The string to use as account name.
ALProfilesAPITest::$apiUrl protected property The string to use as the API URL.
ALProfilesAPITest::$customerSite protected property The string to use as customer site.
ALProfilesAPITest::$httpClient protected property
ALProfilesAPITest::$logger protected property
ALProfilesAPITest::$secretKey protected property The string to use as the password.
ALProfilesAPITest::assertAPIRequests protected function Asserts that the expected requests were made to the http client.
ALProfilesAPITest::assertLogs protected function Asserts that the expected messages were logged to the logger.
ALProfilesAPITest::getALProfilesAPI protected function Returns a ALProfilesAPI instance that can be used to test methods.
ALProfilesAPITest::getInfo public static function
ALProfilesAPITest::setUp protected function Sets up unit test environment. Overrides DrupalUnitTestCase::setUp
ALProfilesAPITest::tearDown protected function Overrides DrupalUnitTestCase::tearDown
ALProfilesAPITest::testCanonicalizeRequest function Tests the method that canonicalizes a request into a string for signing.
ALProfilesAPITest::testDeleteEvent public function Test ALProfilesAPI->deleteEvent()
ALProfilesAPITest::testGetInstance function Tests getting ALProfilesAPI instance with invalid and valid credentials.
ALProfilesAPITest::testGetSegments function
ALProfilesAPITest::testSaveEvent public function Test ALProfilesAPI->saveEvent()
DrupalTestCase::$assertions protected property Assertions thrown in that test case.
DrupalTestCase::$databasePrefix protected property The database prefix of this test run.
DrupalTestCase::$originalFileDirectory protected property The original file directory, before it was changed for testing purposes.
DrupalTestCase::$results public property Current results of this test case.
DrupalTestCase::$setup protected property Flag to indicate whether the test has been set up.
DrupalTestCase::$setupDatabasePrefix protected property
DrupalTestCase::$setupEnvironment protected property
DrupalTestCase::$skipClasses protected property This class is skipped when looking for the source of an assertion.
DrupalTestCase::$testId protected property The test run ID.
DrupalTestCase::$timeLimit protected property Time limit for the test.
DrupalTestCase::$useSetupInstallationCache public property Whether to cache the installation part of the setUp() method.
DrupalTestCase::$useSetupModulesCache public property Whether to cache the modules installation part of the setUp() method.
DrupalTestCase::$verboseDirectoryUrl protected property URL to the verbose output file directory.
DrupalTestCase::assert protected function Internal helper: stores the assert.
DrupalTestCase::assertEqual protected function Check to see if two values are equal.
DrupalTestCase::assertFalse protected function Check to see if a value is false (an empty string, 0, NULL, or FALSE).
DrupalTestCase::assertIdentical protected function Check to see if two values are identical.
DrupalTestCase::assertNotEqual protected function Check to see if two values are not equal.
DrupalTestCase::assertNotIdentical protected function Check to see if two values are not identical.
DrupalTestCase::assertNotNull protected function Check to see if a value is not NULL.
DrupalTestCase::assertNull protected function Check to see if a value is NULL.
DrupalTestCase::assertTrue protected function Check to see if a value is not false (not an empty string, 0, NULL, or FALSE).
DrupalTestCase::deleteAssert public static function Delete an assertion record by message ID.
DrupalTestCase::error protected function Fire an error assertion. 1
DrupalTestCase::errorHandler public function Handle errors during test runs. 1
DrupalTestCase::exceptionHandler protected function Handle exceptions.
DrupalTestCase::fail protected function Fire an assertion that is always negative.
DrupalTestCase::generatePermutations public static function Converts a list of possible parameters into a stack of permutations.
DrupalTestCase::getAssertionCall protected function Cycles through backtrace until the first non-assertion method is found.
DrupalTestCase::getDatabaseConnection public static function Returns the database connection to the site running Simpletest.
DrupalTestCase::insertAssert public static function Store an assertion from outside the testing context.
DrupalTestCase::pass protected function Fire an assertion that is always positive.
DrupalTestCase::randomName public static function Generates a random string containing letters and numbers.
DrupalTestCase::randomString public static function Generates a random string of ASCII characters of codes 32 to 126.
DrupalTestCase::run public function Run all tests in this class.
DrupalTestCase::verbose protected function Logs a verbose message in a text file.
DrupalUnitTestCase::__construct function Constructor for DrupalUnitTestCase. Overrides DrupalTestCase::__construct