You are here

function AcquiaLiftWebTestTarget::testImplementTargetingStructure in Acquia Lift Connector 7.2

Same name and namespace in other branches
  1. 7 tests/acquia_lift.test \AcquiaLiftWebTestTarget::testImplementTargetingStructure()

File

tests/acquia_lift.test, line 1924
Integration tests for Acquia Lift module.

Class

AcquiaLiftWebTestTarget

Code

function testImplementTargetingStructure() {
  module_load_include('inc', 'acquia_lift', 'acquia_lift.admin');

  // Take stock of the current time so we can check the lift_retired property
  // against it after retiring tests.
  $now = time();

  // First, set up our agent, option set, audience and desired targeting
  // structure.
  $agent = $this
    ->createTargetingAgent();

  // Set up some test options for nested tests.
  $agent->data['explore_rate'] = 25;
  $agent->data['control_rate'] = 25;
  $agent->data['decision_style'] = 'adaptive';
  $agent->data['cache_decisions'] = 1;
  personalize_agent_save($agent);
  $this
    ->resetAll();
  $parent_option_set = $this
    ->createPersonalizedBlock(0, $agent, 3);
  if (empty($parent_option_set)) {
    $this
      ->fail('Could not create option set');
    return;
  }

  // Keep the option ids in an array.
  $option_ids = array();
  foreach ($parent_option_set->options as $option) {
    $option_ids[] = $option['option_id'];
  }
  $this
    ->resetAll();
  $audience_name = personalize_generate_machine_name($this
    ->randomName(), NULL, '-');
  $this
    ->createTargetAudience($parent_option_set, $audience_name);
  $targeting = array(
    $audience_name => array(
      $option_ids[1],
      $option_ids[2],
    ),
  );
  try {
    acquia_lift_save_targeting_structure($agent, $targeting);
  } catch (AcquiaLiftException $e) {
    $this
      ->fail('Exception thrown when none expected.');
  }

  // Now implement the targeting structure that is currently just stored in
  // the 'lift_targeting' property.
  AcquiaLiftAPI::setTestInstance();
  acquia_lift_implement_targeting($agent);

  // We should have a new nested acquia_lift agent and option set.
  $this
    ->resetAll();
  $agents = personalize_agent_load_by_type(self::$agent_plugin);
  $this
    ->assertEqual(1, count($agents));
  $nested_agent = reset($agents);
  $nested_test_name = $nested_agent->machine_name;

  // Confirm the test options properties were set.
  $this
    ->assertEqual($nested_agent->data['decision_style'], 'adaptive');
  $this
    ->assertEqual($nested_agent->data['control_rate'], 25);
  $this
    ->assertEqual($nested_agent->data['explore_rate'], 25);
  $this
    ->assertEqual($nested_agent->data['cache_decisions'], 1);
  $option_sets = personalize_option_set_load_by_agent($nested_agent->machine_name);
  $this
    ->assertEqual(1, count($option_sets));
  $nested_osid = key($option_sets);
  $nested_option_set = reset($option_sets);
  $this
    ->assertEqual('options', $nested_option_set->plugin);

  // Confirm the correct options have been added.
  $expected_options = array(
    array(
      'option_id' => $option_ids[1],
    ),
    array(
      'option_id' => $option_ids[2],
    ),
  );
  $this
    ->assertEqual($expected_options, $nested_option_set->options);

  // Confirm this osid is on the original option set's targeting rule for that
  // audience.
  $parent_option_set = personalize_option_set_load($parent_option_set->osid, TRUE);
  $this
    ->assertEqual($nested_osid, $parent_option_set->targeting[$audience_name]['osid']);

  // Create a new target audience and change the structure of our campaign.
  $second_audience = personalize_generate_machine_name($this
    ->randomName(), NULL, '-');
  $this
    ->createTargetAudience($parent_option_set, $second_audience, array(
    array(
      'context' => implode(PERSONALIZE_TARGETING_ADMIN_SEPARATOR, array(
        'some_plugin',
        'some_context',
      )),
      'operator' => 'equals',
      'match' => 'kthxbai',
    ),
  ));
  $targeting = array(
    $audience_name => array(
      $option_ids[2],
    ),
    $second_audience => array(
      $option_ids[0],
      $option_ids[1],
    ),
  );

  // Update the test options.
  $agent->data['explore_rate'] = 35;
  $agent->data['cache_decisions'] = 0;
  personalize_agent_save($agent);
  try {
    acquia_lift_save_targeting_structure($agent, $targeting);
  } catch (AcquiaLiftException $e) {
    $this
      ->fail('Exception thrown when none expected.');
  }
  $this
    ->resetAll();

  // When we implement the new structure it should retire the existing nested
  // test and create a new one.
  AcquiaLiftAPI::setTestInstance();
  acquia_lift_implement_targeting($agent);
  $this
    ->resetAll();
  $parent_option_set = personalize_option_set_load($parent_option_set->osid, TRUE);
  $this
    ->assertFalse(isset($parent_option_set->targeting[$audience_name]['osid']));
  $this
    ->assertNotEqual($nested_osid, $parent_option_set->targeting[$second_audience]['osid']);
  $retired = acquia_lift_get_retired_tests($agent->machine_name);
  $this
    ->assertEqual(1, count($retired));

  // Load the original nested agent and confirm it has been retired.
  $retired_test = personalize_agent_load($nested_test_name, TRUE);
  $this
    ->assertTrue($retired_test->data['lift_retired'] >= $now);
  $this
    ->assertEqual($agent->machine_name, $retired_test->data['lift_parent']);
  $this
    ->assertEqual($audience_name, $retired_test->data['lift_audience']);
  $status = personalize_agent_get_status($nested_test_name);
  $this
    ->assertEqual(PERSONALIZE_STATUS_COMPLETED, $status);

  // Check the new agent and option set.
  $nested_os = personalize_option_set_load($parent_option_set->targeting[$second_audience]['osid'], TRUE);
  $nested_agent = personalize_agent_load($nested_os->agent);

  // Confirm the test options properties were set.
  $this
    ->assertEqual($nested_agent->data['decision_style'], 'adaptive');
  $this
    ->assertEqual($nested_agent->data['control_rate'], 25);
  $this
    ->assertEqual($nested_agent->data['explore_rate'], 35);
  $this
    ->assertEqual($nested_agent->data['cache_decisions'], 1);
  $option_sets = personalize_option_set_load_by_agent($nested_agent->machine_name);
  $this
    ->assertEqual(1, count($option_sets));
  $nested_osid = key($option_sets);
  $nested_option_set = reset($option_sets);
  $this
    ->assertEqual('options', $nested_option_set->plugin);

  // Confirm the correct options have been added.
  $expected_options = array(
    array(
      'option_id' => $option_ids[0],
    ),
    array(
      'option_id' => $option_ids[1],
    ),
  );
  $this
    ->assertEqual($expected_options, $nested_option_set->options);

  // Confirm this osid is on the original option set's targeting rule for that
  // audience.
  $parent_option_set = personalize_option_set_load($parent_option_set->osid, TRUE);
  $this
    ->assertEqual($nested_osid, $parent_option_set->targeting[$second_audience]['osid']);

  // This audience should not have an option id property.
  $this
    ->assertFalse(isset($parent_option_set->targeting[$second_audience]['option_id']));

  // Confirm the option_id property is now on the original audience.
  $first_audience = $audience_name . '-2';

  // Machine name will have changed.
  $this
    ->assertEqual($option_ids[2], $parent_option_set->targeting[$first_audience]['option_id']);

  // It should no longer have an osid property.
  $this
    ->assertFalse(isset($parent_option_set->targeting[$first_audience]['osid']));

  // Now let's place our personalized block so we can test how it gets rendered.
  $admin_user = $this
    ->drupalCreateUser(array(
    'access administration pages',
    'manage personalized content',
    'administer blocks',
  ));
  $this
    ->drupalLogin($admin_user);
  $edit = array(
    'blocks[personalize_blocks_' . $parent_option_set->osid . '][region]' => 'content',
  );
  $this
    ->drupalPost('admin/structure/block', $edit, t('Save blocks'));
  $this
    ->drupalLogout();
  $this
    ->drupalGet('');
  $settings = $this
    ->drupalGetSettings();

  // THe parent agent and option set should be in the personalize js settings.
  $this
    ->assertTrue(isset($settings['personalize']['agent_map'][$agent->machine_name]));
  $this
    ->assertTrue(isset($settings['personalize']['option_sets']['osid-' . $parent_option_set->osid]));

  // The nested agent and option set should *not* be in the personlaize js settings.
  $this
    ->assertFalse(isset($settings['personalize']['agent_map'][$nested_agent->machine_name]));
  $this
    ->assertFalse(isset($settings['personalize']['option_sets']['osid-' . $nested_osid]));

  // The nested agent and option set should be in the acquia_lift_target js settings.
  $this
    ->assertTrue(isset($settings['acquia_lift_target']['agent_map'][$nested_agent->machine_name]));
  $this
    ->assertTrue(isset($settings['acquia_lift_target']['option_sets']['osid-' . $nested_osid]));

  // The parent agent and option set should *not* be in the acquia_lift_target js settings.
  $this
    ->assertFalse(isset($settings['acquia_lift_target']['agent_map'][$agent->machine_name]));
  $this
    ->assertEqual(1, count($settings['acquia_lift_target']['option_sets']));

  // Change the targeting structure again to have two nested tests.
  $targeting = array(
    $first_audience => array(
      $option_ids[0],
      $option_ids[1],
    ),
    $second_audience => array(
      $option_ids[0],
      $option_ids[2],
    ),
  );

  // Update another test option too.
  $agent->data['control_rate'] = 50;
  personalize_agent_save($agent);
  try {
    acquia_lift_save_targeting_structure($agent, $targeting);
  } catch (AcquiaLiftException $e) {
    $this
      ->fail('Exception thrown when none expected.');
  }
  $this
    ->resetAll();

  // When we implement the new structure it should retire one test and create
  // two new tests.
  AcquiaLiftAPI::setTestInstance();
  acquia_lift_implement_targeting($agent);
  $this
    ->resetAll();
  $retired = acquia_lift_get_retired_tests($agent->machine_name);
  $this
    ->assertEqual(2, count($retired));

  // Both audiences' names will have changed.
  $first_audience = $first_audience . '-2';
  $second_audience = $second_audience . '-2';

  // We should have two nested agents each with one option set.
  $nested = acquia_lift_get_nested_tests($agent);
  $this
    ->assertEqual(2, count($nested));
  $nested_agents = personalize_agent_load_multiple($nested);

  // Find the osids of the new option sets so we can check they've been assigned
  // to the correct audiences.
  $new_osids = array();
  foreach ($nested_agents as $test) {

    // Verify the test options.
    // Confirm the test options properties were set.
    $this
      ->assertEqual($test->data['decision_style'], 'adaptive');
    $this
      ->assertEqual($test->data['control_rate'], 50);
    $this
      ->assertEqual($test->data['explore_rate'], 35);
    $this
      ->assertEqual($test->data['cache_decisions'], 1);
    $os = personalize_option_set_load_by_agent($test->machine_name);

    // Check the option ids to ascertain which audience the option set *should*
    // be assigned to.
    $o = reset($os);
    $ids = array_map(function ($option) {
      return $option['option_id'];
    }, $o->options);
    if (in_array('option-3', $ids)) {
      $new_osids[$second_audience] = $o->osid;
    }
    else {
      $new_osids[$first_audience] = $o->osid;
    }
  }

  // Confirm that the correct osid is assigned to each of the two target
  // audiences.
  $parent_option_set = personalize_option_set_load($parent_option_set->osid, TRUE);
  $this
    ->assertEqual(3, count($parent_option_set->targeting));
  foreach ($new_osids as $audience => $osid) {
    $this
      ->assertEqual($osid, $parent_option_set->targeting[$audience]['osid']);
    $this
      ->assertFalse(isset($parent_option_set->targeting[$audience]['option_id']));
  }
}