uc_quote.test 9.4 KB

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