/** * * * @since 1.1.0 * * @group one * @group group * @group destination * * @covers \ingot\testing\tests\click\destination\hooks::track_by_id() */ public function testPageTracking() { $post = get_post(wp_insert_post(['post_title' => 'Hi Chris'])); $args = ['name' => rand(), 'type' => 'click', 'sub_type' => 'destination', 'meta' => ['destination' => 'page', 'link' => 'https://bats.com', 'page' => 11, 'is_tagline' => true]]; $group_id = \ingot\testing\crud\group::create($args, true); $group = \ingot\testing\crud\group::read($group_id); $content_1 = 'hats'; $args = ['type' => 'click', 'group_ID' => $group_id, 'content' => $content_1]; $variant_1 = \ingot\testing\crud\variant::create($args, true); $content_2 = 'bats'; $args = ['type' => 'click', 'group_ID' => $group_id, 'content' => $content_2]; $variant_2 = \ingot\testing\crud\variant::create($args, true); $group['variants'] = [$variant_1, $variant_2]; $update = \ingot\testing\crud\group::update($group, $group_id); $this->assertEquals($group_id, $update); $group = \ingot\testing\crud\group::read($group_id); $this->assertTrue(is_array($group)); $this->assertFalse(empty($group['variants'])); new \ingot\testing\bandit\content($group_id); $group = \ingot\testing\crud\group::read($group_id); $this->assertFalse(empty($group['levers'])); $groups = \ingot\testing\tests\click\destination\init::set_tracking(); new \ingot\testing\tests\click\destination\hooks($groups); $variant_id = \ingot\testing\tests\click\destination\init::get_test($group_id); $tracking = new \ingot\testing\tests\click\destination\hooks([$group_id]); $tracking->track_by_id(11); $totals = \ingot\testing\utility\group::get_total($group, true); $this->assertEquals(1, $totals['total']); $this->assertEquals(1, $totals['conversions']); }
/** * Find all price tests by product ID * * @since 1.1.0 * * @param int $id Product ID * * @return array */ public static function find_by_product($id) { $group_table_name = group::get_table_name(); $variant_table_name = variant::get_table_name(); global $wpdb; $sql = sprintf('select A.* from %s A inner join %s B on A.id = B.group_ID where B.content = %d', $group_table_name, $variant_table_name, $id); return self::query($wpdb, $sql); }
/** * Get price variation or variation as a float for a variant * * @since 1.1.0 * * @param int|array $variant Variation or variations ID * * @return float|void */ public static function get_price_variation($variant) { if (is_numeric($variant)) { $variant = variant::read($variant); } if (variant::valid($variant) && 'price' == $variant['type']) { if (is_numeric($variant['meta']['price'])) { return $variant['meta']['price']; } return $variant['meta']['price'][0]; } return 1; }
/** * Test creating of object * * @since 1.1.0 * * @group price_object * @group price * @group edd_price */ public function testWithMinimal() { $data = ingot_test_data_price::edd_tests(10); $bandit = new \ingot\testing\bandit\price($data['group_ID']); $variant_id = $bandit->choose(); $obj = new \ingot\testing\object\price\test(['ID' => $variant_id, 'expires' => time() * 167234]); $product_ID = \ingot\testing\utility\price::get_product_ID($data['group']); $variant = \ingot\testing\crud\variant::read($variant_id); $this->assertEquals($variant_id, $obj->ID); $this->assertEquals($variant, $obj->variant); $this->assertEquals(get_post($product_ID), $obj->product); $this->assertEquals('edd_get_download_price', $obj->price_callback); }
/** * Get a variant's HTML * * @since 0.4.0 * * @param \WP_REST_Request $request Full data about the request. * @return \WP_Error|\WP_REST_Request */ public function get_item($request) { return $this->not_yet_response(); $context = $request->get_param('context'); $url = $request->get_url_params(); $id = helpers::v('ID', $url, 0); if (0 == absint($id) || !is_array(\ingot\testing\crud\variant::read($id))) { return new \WP_Error('ingot-invalid-test'); } elseif ('context' != 'view') { return new \WP_Error('ingot-test-context-invalid'); } else { if ('view' == $context) { $test = \ingot\testing\crud\variantP::read($id); $html = ingot_click_test($test); return ingot_rest_response($html); } } }
/** * Get HTML for our test. Use this function to output the test. * * Note that because this function has the same name as the test sub_type we registered, it can be called by the Ingot shortcode. * * @return string */ function my_custom_banner() { //check if is bot $is_bot = ingot_is_bot(); $variant = []; //if cookie isset get variant without registering as a new test instance if (!$is_bot && isset($_COOKIE['my_ingot_custom_test_variant']) && 0 < absint($_COOKIE['my_ingot_custom_test_variant'])) { $variant_id = absint($_COOKIE['my_ingot_custom_test_variant']); $variant = \ingot\testing\crud\variant::read($variant_id); } elseif (!$is_bot && isset($my_custom_test_variant_id) && 0 < absint($my_custom_test_variant_id)) { //if is same session as cookie was set, we use the global variable to get the ID $variant_id = absint($my_custom_test_variant_id); $variant = \ingot\testing\crud\variant::read($variant_id); } else { //this should never be reached unless this is a bot, the cookie should have been set at template_redirect //We still need to show something since we want crawlers to index the site properly and false postives on bot checks to look right. $id = my_ingot_custom_test_group(); if (is_numeric($id)) { $group = \ingot\testing\crud\group::read($id); if (is_array($group) && isset($group['variants']) && !empty($group['variants'])) { $variant = array_rand($group['variants']); //set up test and select a variant $test = new \ingot\testing\bandit\content($id); $variant_id = $test->choose(); //a test instance is now registered $variant = \ingot\testing\crud\variant::read($variant_id); } } } //get chosen image URL and return it in an image tag if (isset($variant['content'])) { $content = $variant['content']; } else { //something is very wrong, let's show a picture of a cat in a flower pot $content = 'http://hellogiggles.com/wp-content/uploads/2014/07/22/you-popular-cute-cat-the-very-creative_113506.jpg'; } return sprintf('<img src="%s" />', esc_url($content)); }
/** * Create groups with variants, optionally added to them. * * @param bool $add_variants Optional. If true, the default, variants are added to groups via groups object. If false, they are created, IDs are returned but they will nto be associated with a group properly. * @param int $total_groups Optional. Default is 5. * @param int $variants_per_group Optional. Default is 3. * @param array $args Optional * * @return array */ public static function make_groups($add_variants = true, $total_groups = 5, $variants_per_group = 3, $args = array()) { $defaults = ['group_args' => ['name' => rand(), 'type' => 'click', 'sub_type' => 'button', 'meta' => ['link' => 'https://bats.com']], 'variant_args' => ['type' => 'click', 'group_ID' => 1, 'content' => rand()]]; $keys = array_keys($defaults); foreach ($keys as $i => $key) { if (!empty($args[$key])) { $args[$key] = wp_parse_args($args[$key], $defaults[$key]); } else { $args[$key] = $defaults[$key]; } } $groups = ['ids' => [], 'variants' => []]; $group_args = $args['group_args']; $variant_args = $args['variant_args']; for ($g = 0; $g <= $total_groups; $g++) { $variants = []; $group_args['name'] = (string) $g . rand(); $group_id = \ingot\testing\crud\group::create($group_args, true); $groups['ids'][] = $group_id; $variant_args['group_ID'] = $group_id; for ($v = 0; $v <= $variants_per_group; $v++) { $variant_id = \ingot\testing\crud\variant::create($variant_args, true); $variants[] = $variant_id; } $groups['variants'][$group_id] = $variants; if ($add_variants) { if (is_user_logged_in()) { $obj = new \ingot\testing\object\group($group_id); $obj->update_group(['variants' => $variants]); } else { $_group = \ingot\testing\crud\group::read($group_id); $_group['variants'] = $variants; $saved = \ingot\testing\crud\group::update($_group, $group_id, true); } } } return $groups; }
/** * Test that EDD sale of non-variable product is properly priced/recorded * * @since 1.1.0 * * @group pricez * @group edd_price * * @covers \ingot\testing\tests\price\plugins\edd */ public function testPriceTrackingNonVariableProduct() { $price_is = 10; $product = ingot_test_data_price::edd_create_simple_download($price_is); $group_id = \ingot\testing\crud\group::create(['type' => 'price', 'sub_type' => 'edd', 'meta' => ['product_ID' => $product->ID], 'wp_ID' => $product->ID], true); $variant_one = \ingot\testing\crud\variant::create(['group_ID' => $group_id, 'type' => 'price', 'meta' => ['price' => [0.5]], 'content' => $product->ID], true); $variant_two = \ingot\testing\crud\variant::create(['group_ID' => $group_id, 'type' => 'price', 'meta' => ['price' => [0.5]], 'content' => $product->ID], true); $group = \ingot\testing\crud\group::read($group_id); $group['variants'] = [$variant_one, $variant_two]; \ingot\testing\crud\group::update($group, $group_id, true); $cookie_class = new \ingot\testing\cookies\price([]); $price_cookie = $cookie_class->get_cookie(); $this->assertArrayHasKey('edd', $price_cookie); $this->assertFalse(empty($price_cookie['edd'])); $this->assertInternalType('array', $price_cookie['edd']); $product_id = \ingot\testing\utility\price::get_product_ID($group); $this->assertEquals($product_id, $product->ID); $this->assertArrayHasKey($product_id, $price_cookie['edd']); new \ingot\testing\tests\price\plugins\edd($price_cookie['edd']); $test = \ingot\testing\utility\price::get_price_test_from_cookie('edd', $product->ID, $price_cookie); $this->assertInternalType('object', $test); $price_should_be = $test->get_price(); //NOTE: USING edd_get_download_price here is to ensure we don't have recursion $this->assertEquals(edd_get_download_price($product->ID), $price_should_be); $group_obj = new \ingot\testing\object\group($group_id); $lever = $group_obj->get_lever($test->ID); $this->assertInternalType('object', $lever); $before_wins = $lever->getNumerator(); $payment_id = ingot_test_data_price::edd_create_simple_payment($product); edd_complete_purchase($payment_id, 'publish', 'pending'); $group_obj = new \ingot\testing\object\group($group_id); $lever = $group_obj->get_lever($test->ID); $this->assertInternalType('object', $lever); $after_wins = $lever->getNumerator(); $this->assertEquals($before_wins + 1, $after_wins); }
/** * Save variants and return IDs * * @since 0.4.0 * * @param array $group Group config -- variants key should be an array of variant configs to save * * @return array||WP_Error */ protected function save_variants($group) { $variants_ids = []; $variants = helpers::v('variants', $group, []); $product_id = null; if ('price' == $group['type']) { $product_id = helpers::v('product_ID', $group['meta'], null); if (!is_numeric($product_id)) { return new \WP_Error('ingot-no-product-id', __('No product ID was set.', 'ingot')); } } if (isset($group['ID'])) { $group_id = $group['ID']; } elseif (isset($group['id'])) { $group_id = $group['id']; } else { return new \WP_Error('ingot-generalized-failure'); } if (!empty($variants)) { foreach ($variants as $variant) { if (is_numeric($variant)) { continue; } $variant['group_ID'] = $group_id; $variant['type'] = $group['type']; if ('price' == $group['type']) { $variant['content'] = $product_id; } if ((!isset($variant['content']) || empty($variant['content'])) && 'button_color' == $group['sub_type']) { $variant['content'] = ' '; } if (!isset($variant['ID']) || 0 == abs($variant['ID'])) { unset($variant['ID']); $_variant_id = variant::create($variant); } else { $_variant_id = variant::update($variant, $variant['ID']); } if (is_wp_error($_variant_id)) { return $_variant_id; } $variants_ids[] = $_variant_id; } } return $variants_ids; }
/** * Get names of group and variants * * @since 0.4.0 * * @return array */ public function names() { $data = ['variants' => [], 'group' => $this->group['name']]; if (!empty($this->group['variants'])) { $variants = variant::get_items($this->get_ID()); if (!empty($variants)) { $data['variants'] = wp_list_pluck($variants, 'content'); } } return $data; }
/** * Create the variants and save in group * * @param int $group_id The group ID * * @return int|WP_Error Should return group ID. May return WP_Error if there was an error creating variants or saving them in group. */ protected function add_variants($group_id) { $variant_args = ['type' => 'click', 'group_ID' => $group_id]; /** * This array will be the HTML we output for each variant. * * As an example I'm using URLs of cute cate photos * * @TODO -- You should use something meaningful here. */ $variant_contents = ['https://placekitten.com/900/300', 'https://placekitten.com/900/200', 'https://placekitten.com/800/400']; $variant_ids = []; //create the variants foreach ($variant_contents as $content) { $variant_args['content'] = $content; $variant_id = \ingot\testing\crud\variant::create($variant_args); if (is_numeric($variant_id)) { $variant_ids[] = $variant_id; } else { return $variant_id; } } //save variant IDs in group $group = \ingot\testing\crud\group::read($group_id); $group['variants'] = $variant_ids; $saved = \ingot\testing\crud\group::update($group, $group_id); //this should be the group ID, could be an error. return $saved; }
/** * Check if all tables exists * * @since 1.1.0 * @since 0.3.0 in class ingot_boostrap * * @access protected * * @return bool */ public static function check_if_tables_exist() { if (!self::table_exists(\ingot\testing\crud\tracking::get_table_name()) || !self::table_exists(\ingot\testing\crud\group::get_table_name()) || !self::table_exists(\ingot\testing\crud\session::get_table_name()) || !self::table_exists(\ingot\testing\crud\variant::get_table_name())) { return false; } return true; }
/** * Test that we can delete all variants * * @since 0.4.0 * * @group crud * @group variant_crud * * @covers \ingot\testing\crud\variant::delete() */ public function testDeleteAll() { for ($i = 0; $i <= 7; $i++) { $params = ['type' => 'click', 'group_ID' => $i + rand(), 'content' => $i]; $created[$i] = \ingot\testing\crud\variant::create($params); } \ingot\testing\crud\variant::delete('all'); $items = \ingot\testing\crud\variant::get_items(array()); $this->assertEquals(count($items), 0); }
/** * Test that we can query by plugin and exclude those without variants * * @since 1.1.0 * * @group xs * @group price_query * @group price * * @covers \ingot\testing\crud\price_query::find_by_plugin() */ public function testQueryByPluginNoVariant() { $args = ['type' => 'price', 'sub_type' => 'edd', 'meta' => ['product_ID' => 5], 'wp_ID' => 5]; $variant_args = ['type' => 'price', 'meta' => ['price' => []], 'content' => 5]; for ($i = 0; $i <= 5; $i++) { $group_id = \ingot\testing\crud\group::create($args); $args['wp_ID'] = $args['wp_ID'] + 1; if (3 == $i) { $expected_id = $group_id; $variant_args['group_ID'] = $group_id; $variant_args['meta']['price'] = rand_float(); $variant_id = \ingot\testing\crud\variant::create($variant_args, true); $this->assertTrue(is_numeric($variant_id)); $group = \ingot\testing\crud\group::read($group_id); $group['variants'] = [$variant_id]; \ingot\testing\crud\group::update($group, $group_id, true); } } $groups = \ingot\testing\crud\price_query::find_by_plugin('edd', true); $this->assertInternalType('array', $groups); $this->assertFalse(empty($groups)); $ids = wp_list_pluck($groups, 'ID'); $this->assertTrue(in_array($expected_id, $ids)); $this->assertSame(1, count($groups)); }
/** * Setup tracking hooks * * @since 1.1.0 * * @return array Groups being tracked */ public static function set_tracking() { $groups = self::get_destination_tests(); if (!empty($groups)) { self::clear_invalid($groups); } if (!empty($groups)) { foreach ($groups as $group_id) { $group = group::read($group_id); if (group::valid($group)) { if (destination::is_tagline($group)) { if (!self::$tagline) { $variant_id = self::get_test($group_id); $variant = variant::read($variant_id); if (variant::valid($variant)) { self::$tagline = $variant['content']; } } if (is_string(self::$tagline)) { add_filter('bloginfo', function ($output, $show) { if ('description' == $show) { return self::$tagline; } return $output; }, 24, 2); } } } } if (!empty($groups)) { new \ingot\testing\tests\click\destination\hooks($groups); } return $groups; } }
/** * Set variant property * * @since 1.1.0 * * @access private */ private function set_variant() { if (!isset($this->variant)) { $this->variant = variant::read($this->ID); } }
/** * Register a conversion * * @since 0.4.0 * * @param int $variant_ID ID of variant to register conversion for * @param int $session_ID Optional. Session ID. If a valid session ID is passed, that session will be marked as having converted with this vartiant ID. */ function ingot_register_conversion($variant_ID, $session_ID = 0) { $variant = \ingot\testing\crud\variant::read($variant_ID); if (is_array($variant)) { $bandit = new \ingot\testing\bandit\content($variant['group_ID']); $bandit->record_victory($variant_ID); if (0 < absint($session_ID) && is_array($session = \ingot\testing\crud\session::read($session_ID))) { $session['click_ID'] = $variant_ID; $session['used'] = true; if (0 !== ($userID = get_current_user_id())) { $session['click_url'] = $userID; } \ingot\testing\crud\session::update($session, $session['ID'], true); } } }
/** * Register a conversion * * @since 0.4.0 * * @param int|array $variant Variant config or Variant ID to register conversion for * @param int $session_ID Optional. Session ID. If a valid session ID is passed, that session will be marked as having converted with this vartiant ID. */ function ingot_register_conversion($variant, $session_ID = 0) { if (is_numeric($variant)) { $variant = \ingot\testing\crud\variant::read($variant); } if (\ingot\testing\crud\variant::valid($variant)) { $bandit = new \ingot\testing\bandit\content($variant['group_ID']); $bandit->record_victory($variant['ID']); if (0 < absint($session_ID) && is_array($session = \ingot\testing\crud\session::read($session_ID))) { } else { $session = \ingot\testing\ingot::instance()->get_current_session()['session']; } if (\ingot\testing\crud\session::valid($session)) { $session['click_ID'] = $variant['ID']; $session['used'] = true; if (0 !== ($userID = get_current_user_id())) { $session['click_url'] = $userID; } \ingot\testing\crud\session::update($session, $session['ID'], true); } } }
/** * Get names of group and variants * * @since 0.4.0 * * @return array */ public function names() { $data = ['variants' => [], 'group' => $this->group['name']]; if (!empty($this->group['variants'])) { //this loop is dumb -- https://github.com/Ingothq/ingot/issues/101 foreach ($this->group['variants'] as $i => $variant_id) { if (is_array($variant_id) && isset($variant_id['content'])) { $name = $variant_id['content']; $variant_id = $variant_id['ID']; } else { $variant = variant::read($variant_id); if (is_array($variant)) { $name = $variant['content']; } } if (is_numeric($variant_id)) { $data['variants'][$variant_id] = $name; } } } return $data; }
/** * Choose a variant and set in the variant property * * @since 0.4.0 */ protected function choose() { $variant_id = $this->bandit->choose(); $variant = variant::read($variant_id); if (is_array($variant)) { $this->variant = $variant; } else { //@todo } }
/** * Set variant property * * @param int|array|\MaBandit\lever|null $variant Variant ID, config, or lever. If null, one will be chosen */ protected function set_variant($variant) { if (is_numeric($variant) && true === variant::valid($_variant = variant::read($variant))) { $this->variant = $_variant; } elseif (is_array($variant) && variant::valid($variant)) { $this->variant = $variant; } elseif (is_a($variant, 'MaBandit\\lever')) { /** @var \MaBandit\Lever $variant */ $this->variant = variant::read($variant->getValue()); } else { $this->set_bandit(); $this->choose(); } }
public function setUp() { parent::setUp(); \ingot\testing\crud\group::delete('all'); \ingot\testing\crud\variant::delete('all'); }
/** * Get a group by variant ID * * @since 0.4.0 * * @param int $variant_id * * @return array|bool Group config if found or false if not found */ public static function get_by_variant_id($variant_id) { if (is_array($variant = variant::read($variant_id))) { $group_id = helpers::v('group_ID', $variant, 0); if (is_array($group = self::read($group_id))) { return $group; } } return false; }
/** * Test item exists method * * @since 1.1.0 * * @group variant * @group variant_crud * @group crud * * @covers \ingot\testing\crud\group::variant() */ public function testExists() { $params = ['type' => 'click', 'group_ID' => rand(), 'content' => rand()]; $id = \ingot\testing\crud\variant::create($params); $this->assertTrue(is_numeric($id)); $this->assertTrue(\ingot\testing\crud\variant::exists($id)); $this->assertFalse(\ingot\testing\crud\variant::exists(99999)); \ingot\testing\crud\variant::delete($id); $this->assertFalse(\ingot\testing\crud\variant::exists($id)); }