uc_taxes.test in Ubercart 7.3
Tax tests.
File
uc_taxes/tests/uc_taxes.testView source
<?php
/**
* @file
* Tax tests.
*/
/**
* Tests the tax functionality.
*/
class UbercartTaxesTestCase extends UbercartTestHelper {
public static function getInfo() {
return array(
'name' => 'Taxes',
'description' => 'Ensures that taxes are calculated, stored and displayed correctly.',
'group' => 'Ubercart',
);
}
/**
* Overrides DrupalWebTestCase::setUp().
*/
protected function setUp($modules = array(), $permissions = array()) {
$modules = array(
'uc_product_kit',
'uc_attribute',
'uc_cart',
'uc_payment',
'uc_payment_pack',
'uc_taxes',
);
$permissions = array(
'bypass node access',
'administer content types',
'administer rules',
'configure taxes',
);
parent::setUp($modules, $permissions);
}
public function testInclusiveTaxes() {
$this
->drupalLogin($this->adminUser);
// Create a 20% inclusive tax rate.
$rate = (object) array(
'name' => $this
->randomName(8),
'rate' => 0.2,
'taxed_product_types' => array(
'product',
),
'taxed_line_items' => array(),
'weight' => 0,
'shippable' => 0,
'display_include' => 1,
'inclusion_text' => $this
->randomName(6),
);
uc_taxes_rate_save($rate);
// Ensure Rules picks up the new condition.
entity_flush_caches();
// Create a $10 product.
$product = $this
->createProduct(array(
'sell_price' => 10,
));
// Create an attribute.
$attribute = (object) array(
'name' => $this
->randomName(8),
'label' => $this
->randomName(8),
'description' => $this
->randomName(8),
'required' => TRUE,
'display' => 1,
'ordering' => 0,
);
uc_attribute_save($attribute);
// Create an option with a price adjustment of $5.
$option = (object) array(
'aid' => $attribute->aid,
'name' => $this
->randomName(8),
'cost' => 0,
'price' => 5,
'weight' => 0,
'ordering' => 0,
);
uc_attribute_option_save($option);
// Attach the attribute to the product.
$attribute = uc_attribute_load($attribute->aid);
uc_attribute_subject_save($attribute, 'product', $product->nid, TRUE);
// Create a product kit containing the product.
$kit = $this
->drupalCreateNode(array(
'type' => 'product_kit',
'products' => array(
$product->nid,
),
'ordering' => 0,
'mutable' => UC_PRODUCT_KIT_UNMUTABLE_WITH_LIST,
'default_qty' => 1,
));
// Set the kit total to $9 to automatically apply a discount.
$kit = node_load($kit->nid);
$kit->kit_total = 9;
node_save($kit);
$kit = node_load($kit->nid);
$this
->assertEqual($kit->products[$product->nid]->discount, -1, 'Product kit component has correct discount applied.');
// Ensure the price is displayed tax-inclusively on the add-to-cart form.
$this
->drupalGet('node/' . $kit->nid);
$this
->assertText('$10.80' . $rate->inclusion_text, 'Tax inclusive price on node-view form is accurate.');
// $10.80 = $9.00 + 20%
$this
->assertRaw($option->name . ', +$6.00</option>', 'Tax inclusive option price on node view form is accurate.');
// $6.00 = $5.00 + 20%
// Add the product kit to the cart, selecting the option.
$attribute_key = 'products[' . $product->nid . '][attributes][' . $attribute->aid . ']';
$this
->drupalPost('node/' . $kit->nid, array(
$attribute_key => $option->oid,
), t('Add to cart'));
// Check that the subtotal is $16.80 ($10 base + $5 option - $1 discount, with 20% tax)
$this
->drupalGet('cart');
$this
->assertText('Subtotal: $16.80', 'Order subtotal is correct on cart page.');
// Make sure that the subtotal is also correct on the checkout page.
$this
->drupalPost('cart', array(), 'Checkout');
$this
->assertText('Subtotal: $16.80', 'Order subtotal is correct on checkout page.');
// Manually proceed to checkout review.
$zone_id = db_query_range('SELECT zone_id FROM {uc_zones} WHERE zone_country_id = :country ORDER BY rand()', 0, 1, array(
'country' => variable_get('uc_store_country', 840),
))
->fetchField();
$edit = array(
'panes[delivery][delivery_first_name]' => $this
->randomName(10),
'panes[delivery][delivery_last_name]' => $this
->randomName(10),
'panes[delivery][delivery_street1]' => $this
->randomName(10),
'panes[delivery][delivery_city]' => $this
->randomName(10),
'panes[delivery][delivery_zone]' => $zone_id,
'panes[delivery][delivery_postal_code]' => mt_rand(10000, 99999),
'panes[billing][billing_first_name]' => $this
->randomName(10),
'panes[billing][billing_last_name]' => $this
->randomName(10),
'panes[billing][billing_street1]' => $this
->randomName(10),
'panes[billing][billing_city]' => $this
->randomName(10),
'panes[billing][billing_zone]' => $zone_id,
'panes[billing][billing_postal_code]' => mt_rand(10000, 99999),
);
$this
->drupalPost('cart/checkout', $edit, t('Review order'));
$this
->assertRaw(t('Your order is almost complete.'));
// Make sure the price is still listed tax-inclusively.
// !TODO This could be handled more specifically with a regex.
$this
->assertText('$16.80' . $rate->inclusion_text, 'Tax inclusive price appears in cart pane on checkout review page');
// Ensure the tax-inclusive price is listed on the order admin page.
$order_id = db_query("SELECT order_id FROM {uc_orders} WHERE delivery_first_name = :name", array(
':name' => $edit['panes[delivery][delivery_first_name]'],
))
->fetchField();
$this
->assertTrue($order_id, 'Order was created successfully');
$this
->drupalGet('admin/store/orders/' . $order_id);
$this
->assertText('$16.80' . $rate->inclusion_text, 'Tax inclusive price appears on the order view page.');
// And on the invoice.
$this
->drupalGet('admin/store/orders/' . $order_id . '/invoice');
$this
->assertText('$16.80' . $rate->inclusion_text, 'Tax inclusive price appears on the invoice.');
// And on the printable invoice.
$this
->drupalGet('admin/store/orders/' . $order_id . '/invoice');
$this
->assertText('$16.80' . $rate->inclusion_text, 'Tax inclusive price appears on the printable invoice.');
}
protected function loadTaxLine($order_id) {
$order = uc_order_load($order_id, TRUE);
foreach ($order->line_items as $line) {
if ($line['type'] == 'tax') {
return $line;
}
}
return FALSE;
}
protected function assertTaxLineCorrect($line, $rate, $when) {
$this
->assertTrue($line, t('The tax line item was saved to the order ' . $when));
$this
->assertTrue(number_format($rate * $this->product->sell_price, 2) == number_format($line['amount'], 2), t('Stored tax line item has the correct amount ' . $when));
$this
->assertFieldByName('line_items[' . $line['line_item_id'] . '][li_id]', $line['line_item_id'], t('Found the tax line item ID ' . $when));
$this
->assertText($line['title'], t('Found the tax title ' . $when));
$this
->assertText(uc_currency_format($line['amount']), t('Tax display has the correct amount ' . $when));
}
public function testStoredTaxDisplay() {
$this
->drupalLogin($this->adminUser);
// Enable a payment method for the payment preview checkout pane.
$edit = array(
'uc_payment_method_check_checkout' => 1,
);
$this
->drupalPost('admin/store/settings/payment', $edit, t('Save configuration'));
// Create a 20% inclusive tax rate.
$rate = (object) array(
'name' => $this
->randomName(8),
'rate' => 0.2,
'taxed_product_types' => array(
'product',
),
'taxed_line_items' => array(),
'weight' => 0,
'shippable' => 0,
'display_include' => 1,
'inclusion_text' => '',
);
uc_taxes_rate_save($rate);
$this
->drupalGet('admin/store/settings/taxes');
$this
->assertText($rate->name, t('Tax was saved successfully.'));
$this
->drupalGet("admin/store/settings/taxes/manage/uc_taxes_{$rate->id}");
$this
->assertText(t('Conditions'), t('Rules configuration linked to tax.'));
$this
->drupalPost('node/' . $this->product->nid, array(), t('Add to cart'));
// Manually step through checkout. $this->checkout() doesn't know about taxes.
$this
->drupalPost('cart', array(), 'Checkout');
$this
->assertText(t('Enter your billing address and information here.'), t('Viewed cart page: Billing pane has been displayed.'));
$this
->assertRaw($rate->name, t('Tax line item displayed.'));
$this
->assertRaw(uc_currency_format($rate->rate * $this->product->sell_price), t('Correct tax amount displayed.'));
// Build the panes.
$zone_id = db_query_range('SELECT zone_id FROM {uc_zones} WHERE zone_country_id = :country ORDER BY rand()', 0, 1, array(
'country' => variable_get('uc_store_country', 840),
))
->fetchField();
$edit = array(
'panes[delivery][delivery_first_name]' => $this
->randomName(10),
'panes[delivery][delivery_last_name]' => $this
->randomName(10),
'panes[delivery][delivery_street1]' => $this
->randomName(10),
'panes[delivery][delivery_city]' => $this
->randomName(10),
'panes[delivery][delivery_zone]' => $zone_id,
'panes[delivery][delivery_postal_code]' => mt_rand(10000, 99999),
'panes[billing][billing_first_name]' => $this
->randomName(10),
'panes[billing][billing_last_name]' => $this
->randomName(10),
'panes[billing][billing_street1]' => $this
->randomName(10),
'panes[billing][billing_city]' => $this
->randomName(10),
'panes[billing][billing_zone]' => $zone_id,
'panes[billing][billing_postal_code]' => mt_rand(10000, 99999),
);
// Submit the checkout page.
$this
->drupalPost('cart/checkout', $edit, t('Review order'));
$this
->assertRaw(t('Your order is almost complete.'));
$this
->assertRaw($rate->name, t('Tax line item displayed.'));
$this
->assertRaw(uc_currency_format($rate->rate * $this->product->sell_price), t('Correct tax amount displayed.'));
// Complete the review page.
$this
->drupalPost(NULL, array(), t('Submit order'));
$order_id = db_query("SELECT order_id FROM {uc_orders} WHERE delivery_first_name = :name", array(
':name' => $edit['panes[delivery][delivery_first_name]'],
))
->fetchField();
if ($order_id) {
$this
->pass(t('Order %order_id has been created', array(
'%order_id' => $order_id,
)));
$this
->drupalGet('admin/store/orders/' . $order_id . '/edit');
$this
->assertTaxLineCorrect($this
->loadTaxLine($order_id), $rate->rate, 'on initial order load');
$this
->drupalPost('admin/store/orders/' . $order_id . '/edit', array(), t('Submit changes'));
$this
->assertText(t('Order changes saved.'));
$this
->assertTaxLineCorrect($this
->loadTaxLine($order_id), $rate->rate, 'after saving order');
// Change tax rate and ensure order doesn't change.
$oldrate = $rate->rate;
$rate->rate = 0.1;
$rate = uc_taxes_rate_save($rate);
// Save order because tax changes are only updated on save.
$this
->drupalPost('admin/store/orders/' . $order_id . '/edit', array(), t('Submit changes'));
$this
->assertText(t('Order changes saved.'));
$this
->assertTaxLineCorrect($this
->loadTaxLine($order_id), $oldrate, 'after rate change');
// Change taxable products and ensure order doesn't change.
$class = $this
->createProductClass();
$rate->taxed_product_types = array(
$class->name,
);
uc_taxes_rate_save($rate);
entity_flush_caches();
$this
->drupalPost('admin/store/orders/' . $order_id . '/edit', array(), t('Submit changes'));
$this
->assertText(t('Order changes saved.'));
$this
->assertTaxLineCorrect($this
->loadTaxLine($order_id), $oldrate, 'after applicable product change');
// Change order Status back to in_checkout and ensure tax-rate changes now update the order.
uc_order_update_status($order_id, 'in_checkout');
$this
->drupalPost('admin/store/orders/' . $order_id . '/edit', array(), t('Submit changes'));
$this
->assertText(t('Order changes saved.'));
$this
->assertFalse($this
->loadTaxLine($order_id), t('The tax line was removed from the order when order status changed back to in_checkout.'));
// Restore taxable product and ensure new tax is added.
$rate->taxed_product_types = array(
'product',
);
uc_taxes_rate_save($rate);
$this
->drupalPost('admin/store/orders/' . $order_id . '/edit', array(), t('Submit changes'));
$this
->assertText(t('Order changes saved.'));
$this
->assertTaxLineCorrect($this
->loadTaxLine($order_id), $rate->rate, 'when order status changed back to in_checkout');
}
else {
$this
->fail(t('No order was created.'));
}
}
public function testTaxProductClassUpdate() {
$this
->drupalLogin($this->adminUser);
// Create a new product class.
$type = strtolower($this
->randomName(12));
$edit = array(
'pcid' => $type,
'name' => $type,
'description' => $this
->randomName(32),
);
$this
->drupalPost('admin/store/products/classes', $edit, t('Save'));
node_types_rebuild();
// Create a tax rate.
$tax = $this
->randomName(8);
$rate = (object) array(
'id' => 0,
// TODO: should not have to set this
'name' => $tax,
'rate' => rand(1, 20) / 10,
'taxed_product_types' => array(
$type,
),
'taxed_line_items' => array(),
'weight' => 0,
'shippable' => 0,
);
uc_taxes_rate_save($rate);
// Check that the tax rate shows up at checkout.
$product = $this
->createProduct(array(
'type' => $type,
));
$this
->drupalPost('node/' . $product->nid, array(), t('Add to cart'));
$this
->drupalGet('cart/checkout');
$this
->assertText($tax, 'Tax line item displayed.');
// Change the machine name of the product class.
$new_type = strtolower($this
->randomName(12));
$edit = array(
'name' => $new_type,
'type' => $new_type,
);
$this
->drupalPost('admin/structure/types/manage/' . $type, $edit, t('Save content type'));
// Check that the tax rate still shows up at checkout.
$this
->drupalPost('cart', array(), t('Remove'));
$this
->drupalPost('node/' . $product->nid, array(), t('Add to cart'));
$this
->drupalGet('cart/checkout');
$this
->assertText($tax, 'Tax line item displayed after changing product class node type.');
}
}
Classes
Name | Description |
---|---|
UbercartTaxesTestCase | Tests the tax functionality. |