diff --git a/acquia_search/acquia_search.info b/acquia_search/acquia_search.info
index b5622f7..8d013e0 100644
--- a/acquia_search/acquia_search.info
+++ b/acquia_search/acquia_search.info
@@ -9,5 +9,4 @@ dependencies[] = apachesolr_search
 dependencies[] = search
 
 files[] = Acquia_Search_Service.php
-
-
+files[] = tests/acquia_search.test
diff --git a/acquia_search/tests/acquia_search.test b/acquia_search/tests/acquia_search.test
index e254f24..a31c805 100644
--- a/acquia_search/tests/acquia_search.test
+++ b/acquia_search/tests/acquia_search.test
@@ -1,66 +1,216 @@
 <?php
+/**
+ * @file
+ * Tests for the Acquia Search module.
+ */
 
-// For local testing, don't try to use SSL.
-if (!defined('ACQUIA_DEVELOPMENT_NOSSL')) {
-  define('ACQUIA_DEVELOPMENT_NOSSL', 1);
-}
+/**
+ * Unit tests of the functionality of the Acquia Search module.
+ */
+class AcquiaSearchUnitTestCase extends DrupalUnitTestCase {
+  protected $id;
+  protected $key;
+  protected $salt;
+  protected $derivedKey;
 
-class AcquiaSearchTest extends DrupalTestCase {
-  function get_info() {
+  public static function getInfo() {
     return array(
-      'name' => t('Acquia Search'),
-      'desc' => t('Acquia Search unit and functional tests.'),
-      'group' => t('Acquia'),
+      'name' => 'Acquia Search unit tests',
+      'description' => 'Tests the low level Acquia Search functions.',
+      'group' => 'Acquia',
     );
   }
-  function setUp() {
-  	parent::setUp('acquia_agent', 'search', 'apachesolr', 'apachesolr_search', 'acquia_search');
+
+  /**
+   * Overrides DrupalTestCase::setUp().
+   */
+  public function setUp() {
+    parent::setUp();
+    require_once dirname(dirname(__FILE__)) . '/acquia_search.module';
+
+    // Generate and store a random set of credentials.
+    // Make them as close to the production values as possible
+    // Something like AAAA-1234
+    $this->id = $this->randomName(10);
+    // Most of the keys and salts have a 32char lenght
+    $this->key = $this->randomName(32);
+    $this->salt = $this->randomName(32);
+    // Create a derived key from these values
+    $this->derivedKey = _acquia_search_create_derived_key($this->salt, $this->id, $this->key);
+  }
+  /**
+   * Tests derived key generation.
+   */
+  public function testDerivedKey() {
+    // Mimic the hashing code in the API function.
+    $derivation_string =  $this->id . 'solr' . $this->salt;
+    // str_pad extends the string with the same string in this case
+    // until it has filled 80 chars.
+    $derived_key = hash_hmac('sha1', str_pad($derivation_string, 80, $derivation_string), $this->key);
+
+    // $this->derivedKey is generated from the API function.
+    // @see setUp()
+    $this->assertEqual($this->derivedKey, $derived_key, t('Derived key API function generates the expected hash.'), 'Acquia Search');
   }
 
-  function testHMAC() {
-    $this->DrupalVariableSet('acquia_identifier', 'valid_identifier');
-    $this->DrupalVariableSet('acquia_key', 'valid_key');
-    $this->DrupalVariableSet('acquia_search_derived_key_salt', 'valid_salt');
-    $this->DrupalVariableSet('acquia_subscription_data', array('active' => TRUE));
+  /**
+   * Tests HMAC generation.
+   */
+  public function testHMACCookie() {
 
-    $key = $this->randomName();
+    // Generate the expected hash.
     $time = REQUEST_TIME;
-    $nonce = md5($this->randomName());
+    $nonce = $this->randomName(32);
     $string = $time . $nonce . $this->randomName();
-    $hash1 = hash_hmac('sha1', $string, $key); 
-    $hash2 = _acquia_search_hmac($key, $string);
-    // The results of these two hmac function must be equal if
-    // ours is correct.  We don't use the PHP built-in since for
-    // the module since it may be missing depending on compile
-    // options.
-    $this->assertEqual($hash1, $hash2, 'Same result using hash_hmac() and _acquia_search_hmac().');
-    $derived_key = _acquia_search_derived_key();
-    // The response is cehcked using the derived key, so construct another hmac.
-    $hash3 = hash_hmac('sha1', $nonce . $string, $derived_key);
-    $this->assertTrue(acquia_search_valid_response($hash3, $nonce, $string), 'Response HMAC would be accepted as valid.');
+    $hmac = hash_hmac('sha1', $time . $nonce . $string, $this->derivedKey);
+
+    // @todo Make the API function more testable.
+    $authenticator = acquia_search_authenticator($string, $nonce, $this->derivedKey);
+    preg_match('/acquia_solr_hmac=([a-zA-Z0-9]{40});/', $authenticator, $matches);
+    $this->assertEqual($hmac, $matches[1], t('HMAC API function generates the expected hmac hash.'), 'Acquia Search');
+    preg_match('/acquia_solr_time=([0-9]{10});/', $authenticator, $matches);
+    $this->assertNotNull($matches, t('HMAC API function generates a timestamp.'), 'Acquia Search');
+    preg_match('/acquia_solr_nonce=([a-zA-Z0-9]{32});/', $authenticator, $matches);
+    $this->assertEqual($nonce, $matches[1], t('HMAC API function generates the expected nonce.'), 'Acquia Search');
   }
-  
-  function testDefaultBlocksEnable() {
-    
-    require_once drupal_get_path('module','acquia_search') . '/acquia_search.install';
-    $themes_regions = array (
-      'garland' => 'left',
-      'acquia_marina' => 'sidebar_first',
-      'madeuptheme' => null
+}
+
+/**
+ * Tests the functionality of the Acquia Search module.
+ */
+class AcquiaSearchWebTestCase extends DrupalWebTestCase {
+
+  protected $id;
+  protected $key;
+  protected $salt;
+  protected $derivedKey;
+  protected $url;
+
+  public static function getInfo() {
+    return array(
+      'name' => 'Acquia Search UI tests',
+      'description' => 'Tests the Acquia Search user interface and functionality.',
+      'group' => 'Acquia',
     );
-    foreach ($themes_regions as $theme => $expected_region) {
-      
-      if ($theme == 'madeuptheme') {
-        $block_regions = array('something', 'or', 'theother');
-      } else {
-        $block_regions = array_keys(system_region_list($theme));
-      }
-      $region = _acquia_search_find_block_region($block_regions);
-      $this->assertEqual($region, $expected_region);
-    }
-    
-    $facets = _acquia_search_get_default_facets();
-    $this->assertNotEqual($facets,array());
   }
-}
 
+/**
+   * Overrides DrupalTestCase::setUp().
+   */
+  public function setUp() {
+    parent::setUp('acquia_agent', 'acquia_connector_test', 'search', 'apachesolr', 'apachesolr_search', 'acquia_search');
+
+    // Generate and store a random set of credentials.
+    $this->id = $this->randomName(10);
+    $this->key = $this->randomName(32);
+    $this->salt = $this->randomName(32);
+    $this->derivedKey = _acquia_search_create_derived_key($this->salt, $this->id, $this->key);
+    $subscription = array(
+      'timestamp' => REQUEST_TIME - 60,
+      'active' => '1',
+    );
+
+    variable_set('acquia_identifier', $this->id);
+    variable_set('acquia_key', $this->key);
+    variable_set('acquia_subscription_data', $subscription);
+
+    $environment = acquia_search_get_environment();
+    $this->url = $environment['url'];
+  }
+
+  /**
+   * Creates an admin user.
+   */
+  public function createAdminUser() {
+    $permissions = array(
+      'access content',
+      'search content',
+      'administer nodes',
+      'administer search',
+    );
+    return $this->drupalCreateUser($permissions);
+  }
+
+  /**
+   * Method to clear static caches that could interrupt with the
+   * simpletest procedures for Acquia Search.
+   */
+  public function clearStaticCache() {
+    // Reset the static to test for bug where default environment was only set
+    // on the current page load. We want to ensure the setting persists.
+    // @see http://drupal.org/node/1784804
+    drupal_static_reset('apachesolr_load_all_environments');
+    drupal_static_reset('apachesolr_default_environment');
+  }
+
+  /**
+   * Enables the environment of Acquia Search.
+   */
+  public function enableEnvironment() {
+    // API function that creates the environemnt if it doesn't exist yet.
+    acquia_search_enable_acquia_solr_environment();
+  }
+
+  /**
+   * Tests Acquia Search environment creation.
+   *
+   * Tests executed:
+   * - Acquia Search environment is saved and loaded.
+   * - Acquia Search environment is set as the default environment when created.
+   * - The service class is set to AcquiaSearchService.
+   * - The environment's URL is built as expected.
+   */
+  public function testEnvironment() {
+    // Enable the Acquia Search environment
+    $this->enableEnvironment();
+    // Clear the static caches
+    $this->clearStaticCache();
+    // Load the newly enabled environment
+    $environment = apachesolr_environment_load(ACQUIA_SEARCH_ENVIRONMENT_ID);
+    // Load the default environment variable
+    $default_environment = apachesolr_default_environment();
+
+    // Test all the things!
+    // Check if the environment is a valid variable
+    $this->assertTrue($environment, t('Acquia Search environment saved.'), 'Acquia Search');
+    // Check if the default environment is Acquia Search
+    $this->assertEqual(ACQUIA_SEARCH_ENVIRONMENT_ID, $default_environment, t('Acquia Search is set to the default environment.'), 'Acquia Search');
+    // Check if the service class is actually the Acquia Search Service Class
+    $class = isset($environment['service_class']) ? $environment['service_class'] : '';
+    $this->assertEqual('AcquiaSearchService', $class, t('Acquia Search is using the AcquiaSearchService service class.'), 'Acquia Search');
+    // Check if the url is the same as the one we wanted to save.
+    $this->assertEqual($this->url, $environment['url'], t('Acquia Search is connected to the expected URL.'), 'Acquia Search');
+  }
+
+  /**
+   * Tests that the Acquia Search environment shows up in the interface and that
+   * administrators cannot delete it.
+   *
+   * Tests executed:
+   * - Acquia Search environment is present in the UI.
+   * - Acquia Search is reflected as the default environment in the UI.
+   * - Admin user receives 403 when attempting to delete the environment.
+   */
+  public function testEnvironmentUI() {
+    // Enable the Acquia Search environment
+    $this->enableEnvironment();
+    // Clear the static caches
+    $this->clearStaticCache();
+
+    $admin_user = $this->createAdminUser();
+    $this->drupalLogin($admin_user);
+
+    $settings_path = 'admin/config/search/apachesolr/settings';
+    $this->drupalGet($settings_path);
+    $this->assertText('Acquia Search', t('The Acquia Search environment is displayed in the UI.'), 'Acquia Search');
+
+    $path = 'admin/config/search/apachesolr/settings/' . ACQUIA_SEARCH_ENVIRONMENT_ID . '/edit';
+    $options = array('query' => array('destination' => $settings_path));
+    $link = l('Acquia Search', $path, $options);
+    $raw = t('!environment <em>(Default)</em>', array('!environment' => $link));
+    $this->assertRaw($raw, t('The Acquia Search environment is reflected as the default in the UI.'), 'Acquia Search');
+
+    $this->drupalGet('admin/config/search/apachesolr/settings/' . ACQUIA_SEARCH_ENVIRONMENT_ID . '/delete');
+    $this->assertResponse(403, t('The Acquia Search environment cannot be deleted via the UI.'));
+  }
+}
