uc_quote.test 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232
  1. <?php
  2. /**
  3. * @file
  4. * Ubercart Shipping Quote Tests.
  5. */
  6. /**
  7. * SimpleTests for Ubercart Shipping Quotes.
  8. */
  9. class UbercartQuoteTestCase extends UbercartTestHelper {
  10. public static function getInfo() {
  11. return array(
  12. 'name' => 'Shipping Quotes',
  13. 'description' => 'Test shipping quotes.',
  14. 'group' => 'Ubercart',
  15. );
  16. }
  17. /**
  18. * Overrides DrupalWebTestCase::setUp().
  19. */
  20. function setUp() {
  21. $modules = array('rules_admin', 'uc_payment', 'uc_payment_pack', 'uc_quote', 'uc_flatrate');
  22. $permissions = array('administer rules', 'bypass rules access');
  23. parent::setUp($modules, $permissions);
  24. module_load_include('inc', 'uc_flatrate', 'uc_flatrate.admin');
  25. $this->drupalLogin($this->adminUser);
  26. }
  27. /**
  28. * Creates a flat rate shipping quote with optional conditions.
  29. *
  30. * @param $edit
  31. * Data to use to create shipping quote, same format as the values
  32. * submitted from the add flatrate method form.
  33. * @param $condition
  34. * If specified, a RulesAnd component defining the conditions to apply
  35. * for this method.
  36. */
  37. function createQuote($edit = array(), $condition = FALSE) {
  38. $edit += array(
  39. 'title' => $this->randomName(8),
  40. 'label' => $this->randomName(8),
  41. 'base_rate' => mt_rand(1, 10),
  42. 'product_rate' => mt_rand(1, 10),
  43. );
  44. $form_state = array('values' => $edit);
  45. drupal_form_submit('uc_flatrate_admin_method_edit_form', $form_state);
  46. $method = db_query("SELECT * FROM {uc_flatrate_methods} WHERE mid = :mid", array(':mid' => $form_state['values']['mid']))->fetchObject();
  47. if ($condition) {
  48. $name = 'get_quote_from_flatrate_' . $method->mid;
  49. $condition['LABEL'] = $edit['label'] . ' conditions';
  50. $oldconfig = rules_config_load($name);
  51. $newconfig = rules_import(array($name => $condition));
  52. $newconfig->id = $oldconfig->id;
  53. unset($newconfig->is_new);
  54. $newconfig->status = ENTITY_CUSTOM;
  55. $newconfig->save();
  56. entity_flush_caches();
  57. }
  58. $this->assertTrue($method->base_rate == $edit['base_rate'], 'Flatrate quote was created successfully');
  59. return $method;
  60. }
  61. /**
  62. * Simulates selection of a delivery country on the checkout page.
  63. *
  64. * @param $country
  65. * The text version of the country name to select, e.g. "Canada" or
  66. * "United States".
  67. */
  68. protected function selectCountry($country = "Canada") {
  69. $dom = new DOMDocument();
  70. $dom->loadHTML($this->content);
  71. $parent = $dom->getElementById('edit-panes-delivery-delivery-country');
  72. $options = $parent->getElementsByTagName('option');
  73. for ($i = 0; $i < $options->length; $i++) {
  74. if ($options->item($i)->textContent == $country) {
  75. $options->item($i)->setAttribute('selected', 'selected');
  76. }
  77. else {
  78. $options->item($i)->removeAttribute('selected');
  79. }
  80. }
  81. $this->drupalSetContent($dom->saveHTML());
  82. return $this->drupalPostAjax(NULL, array(), 'panes[delivery][delivery_country]');
  83. }
  84. /**
  85. * Simulates selection of a quote on the checkout page.
  86. *
  87. * @param $n
  88. * The index of the quote to select.
  89. */
  90. protected function selectQuote($n) {
  91. // Get the list of available quotes.
  92. $xpath = '//*[@name="panes[quotes][quotes][quote_option]"]';
  93. $elements = $this->xpath($xpath);
  94. $vals = array();
  95. foreach ($elements as $element) {
  96. $vals[(string) $element['id']] = (string) $element['value'];
  97. }
  98. // Set the checked attribute of the chosen quote.
  99. $dom = new DOMDocument();
  100. $dom->loadHTML($this->content);
  101. $i = 0;
  102. $selected = '';
  103. foreach ($vals as $id => $value) {
  104. if ($i == $n) {
  105. $dom->getElementById($id)->setAttribute('checked', 'checked');
  106. $selected = $value;
  107. }
  108. else {
  109. $dom->getElementById($id)->removeAttribute('checked');
  110. }
  111. $i++;
  112. }
  113. $this->drupalSetContent($dom->saveHTML());
  114. // Post the selection via Ajax.
  115. $option = array('panes[quotes][quotes][quote_option]' => $selected);
  116. return $this->drupalPostAjax(NULL, array(), $option);
  117. }
  118. /**
  119. * Verifies shipping pane is hidden when there are no shippable items.
  120. */
  121. public function testNoQuote() {
  122. $product = $this->createProduct(array('shippable' => FALSE));
  123. $quote = $this->createQuote();
  124. $this->drupalPost('node/' . $product->nid, array(), t('Add to cart'));
  125. $this->drupalPost('cart', array('items[0][qty]' => 1), t('Checkout'));
  126. $this->assertNoText('Calculate shipping cost', 'Shipping pane is not present with no shippable item.');
  127. }
  128. /**
  129. * Tests basic flatrate shipping quote functionality.
  130. */
  131. public function testQuote() {
  132. // Create product and quotes.
  133. $product = $this->createProduct();
  134. $quote1 = $this->createQuote();
  135. $quote2 = $this->createQuote(array(), array(
  136. 'LABEL' => 'quote_conditions',
  137. 'PLUGIN' => 'and',
  138. 'REQUIRES' => array('rules'),
  139. 'USES VARIABLES' => array(
  140. 'order' => array(
  141. 'type' => 'uc_order',
  142. 'label' => 'Order'
  143. ),
  144. ),
  145. 'AND' => array( array(
  146. 'data_is' => array(
  147. 'data' => array('order:delivery-address:country'),
  148. 'value' => '840',
  149. ),
  150. )),
  151. ));
  152. // Define strings to test for.
  153. $qty = mt_rand(2, 100);
  154. foreach (array($quote1, $quote2) as $quote) {
  155. $quote->amount = uc_currency_format($quote->base_rate + $quote->product_rate * $qty);
  156. $quote->option_text = $quote->label . ': ' . $quote->amount;
  157. $quote->total = uc_currency_format($product->sell_price * $qty + $quote->base_rate + $quote->product_rate * $qty);
  158. }
  159. // Add product to cart, update qty, and go to checkout page.
  160. $this->drupalPost('node/' . $product->nid, array(), t('Add to cart'));
  161. $this->drupalPost('cart', array('items[0][qty]' => $qty), t('Checkout'));
  162. $this->assertText($quote1->option_text, 'The default quote option is available');
  163. $this->assertText($quote2->option_text, 'The second quote option is available');
  164. $this->assertText($quote1->total, 'Order total includes the default quote.');
  165. // Select a different quote and ensure the total updates correctly. Currently, we have to do this
  166. // by examining the ajax return value directly (rather than the page contents) because drupalPostAjax() can
  167. // only handle replacements via the 'wrapper' property, and the ajax callback may use a command with a selector.
  168. $edit = array('panes[quotes][quotes][quote_option]' => 'flatrate_2---0');
  169. $result = $this->ucPostAjax(NULL, $edit, $edit);
  170. $this->assertText($quote2->total, 'The order total includes the selected quote.');
  171. // Switch to a different country and ensure the ajax updates the page correctly.
  172. $edit['panes[delivery][delivery_country]'] = 124;
  173. $result = $this->ucPostAjax(NULL, $edit, 'panes[delivery][delivery_country]');
  174. $this->assertText($quote1->option_text, 'The default quote is still available after changing the country.');
  175. $this->assertNoText($quote2->option_text, 'The second quote is no longer available after changing the country.');
  176. $this->assertText($quote1->total, 'The total includes the default quote.');
  177. // Proceed to review page and ensure the correct quote is present.
  178. $edit['panes[quotes][quotes][quote_option]'] = 'flatrate_1---0';
  179. $edit = $this->populateCheckoutForm($edit);
  180. $this->drupalPost(NULL, $edit, t('Review order'));
  181. $this->assertRaw(t('Your order is almost complete.'));
  182. $this->assertText($quote1->total, 'The total is correct on the order review page.');
  183. // Submit the review.
  184. $this->drupalPost(NULL, array(), t('Submit order'));
  185. $order_id = db_query("SELECT order_id FROM {uc_orders} WHERE delivery_first_name = :name", array(':name' => $edit['panes[delivery][delivery_first_name]']))->fetchField();
  186. if ($order_id) {
  187. $order = uc_order_load($order_id);
  188. foreach ($order->line_items as $line) {
  189. if ($line['type'] == 'shipping') {
  190. break;
  191. }
  192. }
  193. // Verify line item is correct.
  194. $this->assertEqual($line['type'], 'shipping', t('The shipping line item was saved to the order.'));
  195. $this->assertEqual($quote1->amount, uc_currency_format($line['amount']), t('Stored shipping line item has the correct amount.'));
  196. // Verify order total is correct on order-view form.
  197. $this->drupalGet('admin/store/orders/' . $order_id);
  198. $this->assertText($quote1->total, 'The total is correct on the order admin view page.');
  199. // Verify shipping line item is correct on order edit form.
  200. $this->drupalGet('admin/store/orders/' . $order_id . '/edit');
  201. $this->assertFieldByName('line_items[' . $line['line_item_id'] . '][title]', $quote1->label, t('Found the correct shipping line item title.'));
  202. $this->assertFieldByName('line_items[' . $line['line_item_id'] . '][amount]', substr($quote1->amount, 1), t('Found the correct shipping line item title.'));
  203. // Verify that the "get quotes" button works as expected.
  204. $result = $this->ucPostAjax('admin/store/orders/' . $order_id . '/edit', array(), array('op' => t('Get shipping quotes')));
  205. $this->assertText($quote1->option_text, 'The default quote is available on the order-edit page.');
  206. $this->assertNoText($quote2->option_text, 'The second quote is not available on the order-edit page.');
  207. }
  208. else {
  209. $this->fail('No order was created.');
  210. }
  211. }
  212. }