View source
<?php
namespace Drupal\uc_store\Tests;
use Drupal\Component\Utility\SafeMarkup;
use Drupal\simpletest\WebTestBase;
use Drupal\uc_country\Entity\Country;
use Drupal\uc_order\Entity\Order;
use Drupal\uc_order\Entity\OrderProduct;
abstract class UbercartTestBase extends WebTestBase {
public static $modules = [
'block',
'uc_cart',
];
protected $strictConfigSchema = FALSE;
protected $adminUser;
public static $adminPermissions = [
'access administration pages',
'administer store',
'administer countries',
'administer order workflow',
'administer product classes',
'administer product features',
'administer products',
'administer content types',
'create product content',
'delete any product content',
'edit any product content',
'create orders',
'view all orders',
'edit orders',
'delete orders',
'unconditionally delete orders',
];
protected $product;
protected function setUp() {
parent::setUp();
$this
->drupalPlaceBlock('local_actions_block');
$this
->drupalPlaceBlock('local_tasks_block');
$class = get_class($this);
$adminPermissions = [];
while ($class) {
if (property_exists($class, 'adminPermissions')) {
$adminPermissions = array_merge($adminPermissions, $class::$adminPermissions);
}
$class = get_parent_class($class);
}
$countries = \Drupal::service('country_manager')
->getAvailableList();
$country_ids = array_rand($countries, 8);
foreach ($country_ids as $country_id) {
Country::load($country_id)
->enable()
->save();
}
\Drupal::configFactory()
->getEditable('uc_store.settings')
->set('address.country', $country_id)
->save();
$this->adminUser = $this
->drupalCreateUser($adminPermissions);
$this->product = $this
->createProduct([
'uid' => $this->adminUser
->id(),
'promote' => 0,
]);
}
protected function createProduct(array $product = []) {
$weight_units = [
'lb',
'kg',
'oz',
'g',
];
$length_units = [
'in',
'ft',
'cm',
'mm',
];
$product += [
'type' => 'product',
'model' => $this
->randomMachineName(8),
'cost' => mt_rand(1, 9999),
'price' => mt_rand(1, 9999),
'weight' => [
0 => [
'value' => mt_rand(1, 9999),
'units' => array_rand(array_flip($weight_units)),
],
],
'dimensions' => [
0 => [
'length' => mt_rand(1, 9999),
'width' => mt_rand(1, 9999),
'height' => mt_rand(1, 9999),
'units' => array_rand(array_flip($length_units)),
],
],
'pkg_qty' => mt_rand(1, 99),
'default_qty' => 1,
'shippable' => 1,
];
$product['model'] = [
[
'value' => $product['model'],
],
];
$product['price'] = [
[
'value' => $product['price'],
],
];
return $this
->drupalCreateNode($product);
}
protected function createAttribute(array $data = [], $save = TRUE) {
$attribute = $data + [
'name' => $this
->randomMachineName(8),
'label' => $this
->randomMachineName(8),
'description' => $this
->randomMachineName(8),
'required' => mt_rand(0, 1) ? TRUE : FALSE,
'display' => mt_rand(0, 3),
'ordering' => mt_rand(-10, 10),
];
$attribute = (object) $attribute;
if ($save) {
uc_attribute_save($attribute);
}
return $attribute;
}
protected function createAttributeOption(array $data = [], $save = TRUE) {
$max_aid = db_select('uc_attributes', 'a')
->fields('a', [
'aid',
])
->orderBy('aid', 'DESC')
->range(0, 1)
->execute()
->fetchField();
$option = $data + [
'aid' => $max_aid,
'name' => $this
->randomMachineName(8),
'cost' => mt_rand(-500, 500),
'price' => mt_rand(-500, 500),
'weight' => mt_rand(-500, 500),
'ordering' => mt_rand(-10, 10),
];
$option = (object) $option;
if ($save) {
uc_attribute_option_save($option);
}
return $option;
}
protected function addToCart($product, array $options = []) {
$this
->drupalPostForm('node/' . $product
->id(), $options, 'Add to cart');
}
protected function createProductClass(array $data = []) {
$class = strtolower($this
->randomMachineName(12));
$edit = $data + [
'type' => $class,
'name' => $class,
'description' => $this
->randomMachineName(32),
'uc_product[product]' => TRUE,
];
$this
->drupalPostForm('admin/structure/types/add', $edit, t('Save content type'));
return node_type_load($class);
}
protected function populateCheckoutForm(array $edit = []) {
foreach ([
'billing',
'delivery',
] as $pane) {
$prefix = 'panes[' . $pane . ']';
$key = $prefix . '[country]';
$country_id = isset($edit[$key]) ? $edit[$key] : \Drupal::config('uc_store.settings')
->get('address.country');
$country = \Drupal::service('country_manager')
->getCountry($country_id);
$edit += [
$prefix . '[first_name]' => $this
->randomMachineName(10),
$prefix . '[last_name]' => $this
->randomMachineName(10),
$prefix . '[street1]' => $this
->randomMachineName(10),
$prefix . '[city]' => $this
->randomMachineName(10),
$prefix . '[postal_code]' => mt_rand(10000, 99999),
];
if (!empty($country
->getZones())) {
$edit += [
$prefix . '[zone]' => array_rand($country
->getZones()),
];
}
}
if (!isset($edit['panes[customer][primary_email]']) && !$this->loggedInUser) {
$edit['panes[customer][primary_email]'] = $this
->randomMachineName(8) . '@example.com';
}
return $edit;
}
protected function checkout(array $edit = []) {
$this
->drupalPostForm('cart', [], 'Checkout');
$this
->assertText(t('Enter your billing address and information here.'), 'Viewed cart page: Billing pane has been displayed.');
$edit = $this
->populateCheckoutForm($edit);
$this
->drupalPostForm('cart/checkout', $edit, t('Review order'));
$this
->assertRaw(t('Your order is almost complete.'));
$this
->drupalPostForm(NULL, [], t('Submit order'));
$order_ids = \Drupal::entityQuery('uc_order')
->condition('billing_first_name', $edit['panes[billing][first_name]'])
->execute();
$order_id = reset($order_ids);
if ($order_id) {
$this
->pass(SafeMarkup::format('Order %order_id has been created', [
'%order_id' => $order_id,
]));
$order = Order::load($order_id);
}
else {
$this
->fail('No order was created.');
$order = FALSE;
}
return $order;
}
protected function createOrder(array $edit = []) {
if (empty($edit['primary_email'])) {
$edit['primary_email'] = $this
->randomString() . '@example.org';
}
$order = Order::create($edit);
if (!isset($edit['products'])) {
$order->products[] = OrderProduct::create([
'nid' => $this->product->nid->target_id,
'title' => $this->product->title->value,
'model' => $this->product->model,
'qty' => 1,
'cost' => $this->product->cost->value,
'price' => $this->product->price->value,
'weight' => $this->product->weight,
'data' => [],
]);
}
$order
->save();
return Order::load($order
->id());
}
protected function createPaymentMethod($plugin_id, array $values = []) {
$has_user = $this->loggedInUser;
if (!$has_user) {
$this
->drupalLogin($this->adminUser);
}
$values += [
'id' => strtolower($this
->randomMachineName()),
'label' => $this
->randomString(),
];
$this
->drupalPostForm('admin/store/config/payment/add/' . $plugin_id, $values, 'Save');
if (!$has_user) {
$this
->drupalLogout();
}
return $values;
}
protected function assertNoMailString($field_name, $string, $email_depth, $message = '', $group = 'Other') {
$mails = $this
->drupalGetMails();
$string_found = FALSE;
for ($i = count($mails) - 1; $i >= count($mails) - $email_depth && $i >= 0; $i--) {
$mail = $mails[$i];
$normalized_mail = preg_replace('/\\s+/', ' ', $mail[$field_name]);
$normalized_string = preg_replace('/\\s+/', ' ', $string);
$string_found = FALSE !== strpos($normalized_mail, $normalized_string);
if ($string_found) {
break;
}
}
if (!$message) {
$message = SafeMarkup::format('Expected text not found in @field of email message: "@expected".', [
'@field' => $field_name,
'@expected' => $string,
]);
}
return $this
->assertFalse($string_found, $message, $group);
}
protected function ucPostAjax($path, $edit, $triggering_element, $ajax_path = NULL, array $options = [], array $headers = [], $form_html_id = NULL, $ajax_settings = NULL) {
$commands = parent::drupalPostAjaxForm($path, $edit, $triggering_element, $ajax_path, $options, $headers, $form_html_id, $ajax_settings);
$dom = new \DOMDocument();
@$dom
->loadHTML($this
->getRawContent());
foreach ($commands as $command) {
if ($command['command'] == 'insert' && isset($command['selector']) && preg_match('/^\\#-?[_a-zA-Z]+[_a-zA-Z0-9-]*$/', $command['selector'])) {
$xpath = new \DOMXPath($dom);
$wrapperNode = $xpath
->query('//*[@id="' . substr($command['selector'], 1) . '"]')
->item(0);
if ($wrapperNode) {
$newDom = new \DOMDocument();
@$newDom
->loadHTML('<div>' . $command['data'] . '</div>');
$newNode = $dom
->importNode($newDom->documentElement->firstChild->firstChild, TRUE);
$method = isset($command['method']) ? $command['method'] : $ajax_settings['method'];
switch ($method) {
case 'replaceWith':
$wrapperNode->parentNode
->replaceChild($newNode, $wrapperNode);
break;
case 'append':
$wrapperNode
->appendChild($newNode);
break;
case 'prepend':
$wrapperNode
->insertBefore($newNode, $wrapperNode->firstChild);
break;
case 'before':
$wrapperNode->parentNode
->insertBefore($newNode, $wrapperNode);
break;
case 'after':
$wrapperNode->parentNode
->insertBefore($newNode, $wrapperNode->nextSibling);
break;
case 'html':
foreach ($wrapperNode->childNodes as $childNode) {
$wrapperNode
->removeChild($childNode);
}
$wrapperNode
->appendChild($newNode);
break;
}
}
}
}
$content = $dom
->saveHTML();
$this
->setRawContent($content);
$this
->verbose('Page content after ajax submission:<hr />' . $this->content);
return $commands;
}
}