commerce_product.test in Commerce Core 7
Unit tests for the commerce product module.
File
modules/product/tests/commerce_product.testView source
<?php
/**
* @file
* Unit tests for the commerce product module.
*/
/**
* Test the product and product type CRUD.
*/
class CommerceProductCRUDTestCase extends CommerceBaseTestCase {
public static function getInfo() {
return array(
'name' => 'Product CRUD',
'description' => 'Test the product CRUD functions.',
'group' => 'Drupal Commerce',
);
}
function setUp() {
$modules = parent::setUpHelper('all');
$modules[] = 'commerce_product_crud_test';
parent::setUp($modules);
$this->site_admin = $this
->createSiteAdmin();
cache_clear_all();
// Just in case
}
/**
* Ensure the default product types are created.
*/
function testCommerceProductDefaultProducts() {
$default_types = array(
'product' => 'Product',
);
// Load the default product types.
$types_created = commerce_product_types();
// Ensure each type exists.
foreach ($default_types as $type => $name) {
$this
->assertTrue(!empty($types_created[$type]), 'Product type ' . check_plain($type) . ' has been created.');
}
}
/**
* Test the product type CRUD functions.
*/
function testCommerceProductTypeCrud() {
// Ensure commerce_product_ui_product_type_new() returns a valid empty product type.
$new_product_type = commerce_product_ui_product_type_new();
$this
->assertNotNull($new_product_type['type'], 'commerce_product_ui_product_type_new() instantiated the type property.');
$this
->assertNotNull($new_product_type['name'], 'commerce_product_ui_product_type_new() instantiated the help property.');
$this
->assertNotNull($new_product_type['description'], 'commerce_product_ui_product_type_new() instantiated the help property.');
$this
->assertNotNull($new_product_type['help'], 'commerce_product_ui_product_type_new() instantiated the help property');
// Supply customer values for the product type properties.
$type = $this
->randomName(20);
$name = $this
->randomName(40);
$description = $this
->randomString(128);
$help = $this
->randomString(128);
// Add the values to the new content type.
$new_product_type['type'] = $type;
$new_product_type['name'] = $name;
$new_product_type['description'] = $description;
$new_product_type['help'] = $help;
$new_product_type['is_new'] = TRUE;
// Ensure content_product_ui_product_type_save() returns the proper value when inserting.
$return = commerce_product_ui_product_type_save($new_product_type);
$this
->assertEqual($return, SAVED_NEW, 'commerce_product_ui_product_type_save() returned SAVED_NEW when saving a new product type.');
// Load the newly saved content type.
$saved_product_type = commerce_product_type_load($type);
// Ensure the values that were saved match the values that we created.
$this
->assertTrue($saved_product_type, 'commerce_product_type_load() loaded the new product type.');
$this
->assertEqual($type, $saved_product_type['type'], 'The new product type type was properly saved and loaded.');
$this
->assertEqual($name, $saved_product_type['name'], 'The new product type name was properly saved and loaded.');
$this
->assertEqual($description, $saved_product_type['description'], 'The new product type description text was properly saved and loaded.');
$this
->assertEqual($help, $saved_product_type['help'], 'The new product type help text was properly saved and loaded.');
// Alter the title, to ensure the update function works.
$altered_name = $this
->randomName(40);
$saved_product_type['name'] = $altered_name;
// Ensure commerce_product_ui_product_type_save() returns the proper value when updating.
$return = commerce_product_ui_product_type_save($saved_product_type);
$this
->assertEqual($return, SAVED_UPDATED, 'commerce_product_ui_product_type_save() returned SAVED_UPDATED when saving an updated product type.');
// Reset the cached product types, and verify commerce_product_types load the saved type.
commerce_product_types_reset();
$types = commerce_product_types();
$this
->assertNotNull($types[$type], 'commerce_product_types_reset() successfully reset the product types.');
$this
->assertEqual($saved_product_type['name'], $altered_name, 'commerce_product_ui_product_type_save() successfully updated the product type name.');
// Ensure commerce_product_ui_product_type_delete() deletes a content type.
commerce_product_ui_product_type_delete($type);
$deleted_type = commerce_product_type_load($type);
$this
->assertFalse($deleted_type, 'commerce_product_ui_product_type_delete() successfully removed a product type.');
}
/**
* Test the product CRUD functions.
*/
function testCommerceProductCrud() {
global $commerce_product_crud_tests;
// Ensure commerce_product_new() returns a new product.
$new_product = commerce_product_new('product');
$fields = array(
'sku',
'type',
'title',
'uid',
);
foreach ($fields as $field) {
$this
->assertNotNull($new_product->{$field}, 'commerce_product_new() instantiated the ' . check_plain($field) . ' property.');
}
$new_product->sku = $sku = $this
->randomName(10);
$new_product->type = $type = 'product';
$new_product->title = $title = $this
->randomName(10);
$new_product->uid = 1;
// Ensure commerce_product_save() returns SAVED_NEW when saving a new product
$return = commerce_product_save($new_product);
$this
->assertIdentical($return, SAVED_NEW, 'commerce_product_save() successfully saved the new product.');
// Ensure commerce_product_load() loaded the saved product.
$loaded_product = commerce_product_load($new_product->product_id);
foreach ($fields as $field) {
$this
->assertEqual($loaded_product->{$field}, $new_product->{$field}, 'The ' . check_plain($field) . ' value loaded by commerce_product_load() matches the value saved by commerce_product_save()');
}
$this
->assertTrue($loaded_product->created > 0, 'commerce_product_save() added a created date to the product');
$this
->assertTrue($loaded_product->changed > 0, 'commerce_product_save() added a changed date to the product');
// Ensure commerce_product_save() returns SAVED_UPDATED when saving an existing product.
$loaded_product->uid = 0;
$return = commerce_product_save($loaded_product);
$this
->assertIdentical($return, SAVED_UPDATED, 'commerce_product_save() successfully updated the product.');
// Ensure hooks invoked during the save operation can load identical objects
// be checking a global variable set in commerce_product_crud_test_commerce_product_update()
// if the uid is in fact being loaded as 0 in the update hook.
$this
->assertTrue($commerce_product_crud_tests['hook_update_identical_uid'], t('Invoked hooks during save operation can successfully load identical object.'));
// Ensure commerce_product_load_by_sku() can load a product by SKU.
$loaded_product_by_sku = commerce_product_load_by_sku($sku);
$this
->assertEqual($loaded_product_by_sku->product_id, $new_product->product_id, 'The ID of the product loaded via commerce_product_load_by_sku() matches the saved product ID.');
// Ensure commerce_product_load_multiple() can load multiple multiple products.
$saved_product_ids = array();
// First create and save multiple new products.
for ($i = 0; $i < 3; $i++) {
$product = commerce_product_new('product');
$product->type = 'product';
$product->sku = $this
->randomName(10);
$product->title = $this
->randomName(10);
$product->uid = 1;
commerce_product_save($product);
// Save the ID and title of the newly created product.
$saved_products[$product->product_id] = $product->title;
}
$loaded_products = commerce_product_load_multiple(array_keys($saved_products));
$this
->assertEqual(count($saved_products), count($loaded_products), 'commerce_product_load_multiple() loaded the proper number of the products.');
foreach ($loaded_products as $loaded_product) {
$this
->assertEqual($loaded_product->title, $saved_products[$loaded_product->product_id], 'commerce_product_load_multiple() successfully loaded a product.');
}
// Ensure commerce_product_delete() can remove a product.
$return = commerce_product_delete($new_product->product_id);
$this
->assertTrue($return, 'commerce_product_delete() returned TRUE when deleting a product.');
$deleted_product_load = commerce_product_load_multiple(array(
$new_product->product_id,
), array(), TRUE);
$this
->assertFalse($deleted_product_load, 'commerce_product_load_multiple() could not load the deleted product.');
// Ensure commerce_product_delete_multiple() can delete multiple products.
$return = commerce_product_delete_multiple(array_keys($saved_products));
$this
->assertTrue($return, 'commerce_product_delete_multiple() returned TRUE when deleting a product.');
$deleted_products_load = commerce_product_load_multiple(array_keys($saved_products), array(), TRUE);
$this
->assertFalse($deleted_product_load, 'commerce_product_load_multiple() could not load the deleted products.');
}
/**
* Test product Token replacement.
*/
function testCommerceProductTokens() {
$product = commerce_product_new('product');
$creator = $this
->drupalCreateUser();
$product->sku = $this
->randomName(10);
$product->title = $this
->randomName(10);
$product->uid = $creator->uid;
commerce_product_save($product);
$this
->assertEqual(token_replace('[commerce-product:product-id]', array(
'commerce-product' => $product,
)), $product->product_id, '[commerce-product:product-id] was replaced with the product ID.');
$this
->assertEqual(token_replace('[commerce-product:sku]', array(
'commerce-product' => $product,
)), $product->sku, '[commerce-product:sku] was replaced with the SKU.');
$this
->assertEqual(token_replace('[commerce-product:type]', array(
'commerce-product' => $product,
)), $product->type, '[commerce-product:type] was replaced with the product type.');
$this
->assertEqual(token_replace('[commerce-product:type-name]', array(
'commerce-product' => $product,
)), commerce_product_type_get_name($product->type), '[commerce-product:type-name] was replaced with the product type.');
$this
->assertEqual(token_replace('[commerce-product:title]', array(
'commerce-product' => $product,
)), $product->title, '[commerce-product:title] was replaced with the title.');
$this
->assertNotIdentical(strpos(token_replace('[commerce-product:edit-url]', array(
'commerce-product' => $product,
)), url('admin/commerce/products/' . $product->product_id . '/edit')), FALSE, '[commerce-product:edit-url] was replaced with the edit URL.');
$this
->assertEqual(token_replace('[commerce-product:creator:uid]', array(
'commerce-product' => $product,
)), $product->uid, '[commerce-product:creator:uid] was replaced with the uid of the creator.');
$this
->assertEqual(token_replace('[commerce-product:creator:name]', array(
'commerce-product' => $product,
)), check_plain(format_username($creator)), '[commerce-product:creator:name] was replaced with the name of the author.');
$this
->assertEqual(token_replace('[commerce-product:created]', array(
'commerce-product' => $product,
)), format_date($product->created, 'medium'), '[commerce-product:created] was replaced with the created date.');
$this
->assertEqual(token_replace('[commerce-product:changed]', array(
'commerce-product' => $product,
)), format_date($product->changed, 'medium'), '[commerce-product:changed] was replaced with the changed date.');
}
/**
* Test product revision management.
*/
function testCommerceProductRevisions() {
$new_product = commerce_product_new('product');
$new_product->sku = $this
->randomName(10);
$new_product->type = 'product';
$new_product->title = $this
->randomName(10);
$new_product->uid = 1;
commerce_product_save($new_product);
// Ensure commerce_product_save() returns an entity with the revision_id set.
$this
->assertNotNull($new_product->revision_id, 'Revision id was created after first save.');
// Ensure that on update with the revision set to TRUE a new revision is
// created.
$old_revision_id = $new_product->revision_id;
$new_product->revision = TRUE;
$new_product->title = $this
->randomName(10);
commerce_product_save($new_product);
$this
->assertNotEqual($old_revision_id, $new_product->revision_id, 'New revision was created');
// Ensure that on update with the revision set to FALSE a new revision is
// not created.
$old_revision_id = $new_product->revision_id;
$new_product->revision = FALSE;
$new_product->title = $this
->randomName(10);
commerce_product_save($new_product);
$this
->assertEqual($old_revision_id, $new_product->revision_id, 'No new revision was created');
}
}
/**
* Test the Rules and Entity integration.
*
* TODO: replace this with a simpler event test that doesn't depend on the odd
* product loading / saving interplay. I don't even think the unchanged
* condition will ever work as is in here.
*
class CommerceProductRulesTestCase extends DrupalWebTestCase {
public static function getInfo() {
return array(
'name' => 'Product rules integration',
'description' => 'Tests the product rules integration.',
'group' => 'Drupal Commerce',
);
}
function setUp() {
parent::setUp('commerce_product', 'rules');
}
/**
* Calculates the output of t() given an array of placeholders to replace.
*
static function t($text, $strings) {
$placeholders = array();
foreach ($strings as $string) {
$placeholders['%' . $string] = drupal_placeholder($string);
}
return strtr($text, $placeholders);
}
/**
* Tests rules CRUD actions for products.
*
function testRulesCRUD() {
// Test creation.
$action = rules_action('entity_create', array(
'type' => 'commerce_product',
'param_type' => 'product',
'param_sku' => 'foo',
'param_title' => 'bar',
'param_creator' => $GLOBALS['user'],
));
// Test running access() and execute.
$action->access();
$action->execute();
$text = RulesLog::logger()->render();
$pos = strpos($text, self::t('Added the provided variable %entity_created of type %commerce_product', array('entity_created', 'commerce_product')));
$pos = ($pos !== FALSE) ? strpos($text, self::t('Saved %entity_created of type %commerce_product.', array('entity_created', 'commerce_product')), $pos) : FALSE;
$this->assertTrue($pos !== FALSE, 'Product has been created and saved.');
$product = commerce_product_new('product');
commerce_product_save($product);
$rule = rule();
$rule->action('entity_fetch', array('type' => 'commerce_product', 'id' => $product->product_id, 'entity_fetched:var' => 'product'));
$rule->action('entity_save', array('data:select' => 'product', 'immediate' => TRUE));
$rule->action('entity_delete', array('data:select' => 'product'));
// Test running access and integrtiy check + execute.
$rule->access();
$rule->integrityCheck()->execute();
$text = RulesLog::logger()->render();
$pos = strpos($text, RulesTestCase::t('Evaluating the action %entity_fetch.', array('entity_fetch')));
$pos = ($pos !== FALSE) ? strpos($text, self::t('Added the provided variable %product of type %commerce_product', array('product', 'commerce_product')), $pos) : FALSE;
$pos = ($pos !== FALSE) ? strpos($text, self::t('Saved %product of type %commerce_product.', array('product', 'commerce_product')), $pos) : FALSE;
$pos = ($pos !== FALSE) ? strpos($text, self::t('Evaluating the action %entity_delete.', array('entity_delete')), $pos) : FALSE;
$this->assertTrue($pos !== FALSE, 'Product has been fetched, saved and deleted.');
$this->assertFalse(commerce_product_load($product->product_id), 'Product has been deleted.');
}
/**
* Tests making use of product metadata.
*
function testProductPropertyInfo() {
// Populate $values with all values that are setable. They will be set
// with an metadata wrapper, so we also test setting that way.
$values = array();
$wrapper = entity_metadata_wrapper('commerce_product');
foreach ($wrapper as $name => $child) {
$info = $wrapper->$name->info();
if (!empty($info['setter callback'])) {
$info += array('type' => 'text');
$values[$name] = $this->createValue($info['type'], $info);
}
}
$values['type'] = 'product';
$product = entity_create('commerce_product', $values);
$this->assertTrue($product, "Created a product and set all setable values.");
$wrapper = entity_metadata_wrapper('commerce_product', $product);
foreach ($wrapper as $key => $child) {
$this->assertValue($wrapper, $key);
}
}
/**
* Assert the value for the given property is returned.
*
protected function assertValue($wrapper, $key) {
$this->assertTrue($wrapper->$key->value() !== NULL, check_plain($key) . ' property returned.');
$info = $wrapper->$key->info();
if (!empty($info['raw getter callback'])) {
// Also test getting the raw value
$this->assertTrue($wrapper->$key->raw() !== NULL, check_plain($key) . ' raw value returned.');
}
}
/**
* Creates a value for the given data type.
*
protected function createValue($type, $info) {
if (!isset($this->node)) {
// Create some entities to use the first time this runs.
$this->node = $this->drupalCreateNode(array('type' => 'article'));
$this->user = $this->drupalCreateUser();
}
if (isset($info['options list'])) {
$options = array_keys($info['options list']());
return entity_property_list_extract_type($type) ? array(reset($options)) : reset($options);
}
switch ($type) {
case 'decimal':
case 'integer':
case 'duration':
return 1;
case 'date':
return REQUEST_TIME;
case 'boolean':
return TRUE;
case 'text':
return drupal_strtolower($this->randomName(8));
case 'text_formatted':
return array('value' => $this->randomName(16));
default:
return $this->$type;
}
}
/**
* Tests making use of the product 'presave' event and loading the unchanged
* product.
*
public function testProductEvent() {
$rule = rules_reaction_rule();
$rule->event('commerce_product_presave')
->condition('data_is', array('data:select' => 'product:type', 'value' => 'product'))
->condition(rules_condition('data_is', array('data:select' => 'product:sku', 'value:select' => 'product_unchanged:sku'))->negate())
->action('entity_delete', array('data:select' => 'product'));
// Try running access and integrity checks.
$rule->access();
$rule->integrityCheck();
// Save it.
$rule->save('commerce_product_test1', 'commerce_product');
// Force immediate cache clearing so we can test the rule *now*.
rules_clear_cache(TRUE);
// Create initial product.
$product = commerce_product_new('product');
$product->sku = 'foo';
commerce_product_save($product);
$this->assertTrue(commerce_product_load($product->product_id), 'Reaction rule not fired.');
// Now update, so that the rule fires.
$product->sku = 'bar';
unset($product->is_new);
commerce_product_save($product);
$this->assertFalse(commerce_product_load($product->product_id), 'Reaction rule fired.');
RulesLog::logger()->checkLog();
}
}
*/
Classes
Name | Description |
---|---|
CommerceProductCRUDTestCase | Test the product and product type CRUD. |