Projet

Général

Profil

Paste
Télécharger (36,7 ko) Statistiques
| Branche: | Révision:

root / drupal7 / sites / all / modules / commerce / tests / commerce_base.test @ 87dbc3bf

1 85ad3d82 Assos Assos
<?php
2
3
/**
4
 * @file
5
 * Defines abstract base test class for the Commerce module tests.
6
 */
7
8
/**
9
 * Abstract class for Commerce testing. All Commerce tests should extend this
10
 * class.
11
 */
12
abstract class CommerceBaseTestCase extends DrupalWebTestCase {
13
14
  /**
15
   * Helper function to determine which modules should be enabled. Should be
16
   * used in place of standard parent::setUp('moduleA', 'moduleB') call.
17
   *
18
   * @param $set
19
   *  Which set of modules to load. Can be one of:
20
   *    'all': (default) All Commerce modules, including UI and payment modules.
21
   *    'ui': All API and UI modules.
22
   *    'api': Just API modules (includes commerce_ui since checkout depends on it).
23
   *    'dependencies': Common dependencies required by many Commerce API and UI
24
   *      modules.
25
   * @param $other_modules
26
   *  Array of modules to include in addition to the sets loaded by $set
27
   */
28
  protected function setUpHelper($set = 'all', array $other_modules = array()) {
29
30
    $dependencies = array(
31
      // API
32
      'entity',
33
    	'entity_token',
34
      'rules',
35
      'addressfield',
36
      //'rules_admin',
37
      // UI
38
      'ctools',
39
      'views',
40
      //'views_ui',
41
      'field',
42
      'field_ui',
43
      'field_sql_storage',
44
    );
45
    $api = array(
46
      'commerce',
47
      'commerce_product',
48
      'commerce_price',
49
      'commerce_customer',
50
      'commerce_line_item',
51
      'commerce_order',
52
      'commerce_product_reference',
53
      'commerce_payment',
54
      'commerce_tax',
55
      'commerce_product_pricing',
56
    );
57
    $ui = array(
58
      'commerce_ui',
59
      'commerce_checkout',
60
      'commerce_cart',
61
      'commerce_line_item_ui',
62
      'commerce_order_ui',
63
      'commerce_product_ui',
64
      'commerce_customer_ui',
65
      'commerce_payment_ui',
66
      'commerce_product_pricing_ui',
67
      'commerce_tax_ui',
68
      //'rules_admin',
69
    );
70
    $payment = array(
71
      'commerce_payment_example',
72
    );
73
74
    // Final module list
75
    $modules = array();
76
77
    // Cascade down the list and add sets
78
    switch ($set) {
79
      case 'all':
80
        $modules = array_merge($payment, $modules);
81
      case 'ui':
82
        $modules = array_merge($ui, $modules);
83
      case 'api':
84
        $modules = array_merge($api, $modules);
85
      case 'dependencies':
86
        $modules = array_merge($dependencies, $modules);
87
        break;
88
    }
89
90
    // Bring in modules specified by caller
91
    $modules = array_merge($modules, $other_modules);
92
93
    return $modules;
94
  }
95
96
  /**
97
   * Helper function to get different combinations of permission sets.
98
   *
99
   * @param $set
100
   *  Can be a single string (from the following) or can be an array containing
101
   *  multiple values that should be merged:
102
   *    'site admin': Admin permissions for Drupal core modules
103
   *    'store admin': All commerce "administer X" permissions
104
   */
105
  protected function permissionBuilder($sets) {
106
    if (is_string($sets)) {
107
      $sets = array($sets);
108
    }
109
    $site_admin = array(
110
      'administer blocks',
111
      'administer comments',
112
      'access dashboard',
113
      'administer filters',
114
      'administer image styles',
115
      'administer menu',
116
      'administer content types',
117
      'administer nodes',
118
      'bypass node access',
119
      'administer url aliases',
120
      'administer search',
121
      'administer modules',
122
      'administer site configuration',
123
      'administer themes',
124
      'administer software updates',
125
      'administer actions',
126
      'access administration pages',
127
      'access site in maintenance mode',
128
      'access site reports',
129
      'block IP addresses',
130
      'administer taxonomy',
131
      'administer permissions',
132
      'administer users',
133
      'administer rules',
134
    );
135
    $store_admin = array(
136
      'access administration pages',
137
      'administer checkout',
138
      'access checkout',
139
      'configure store',
140
      'administer commerce_customer_profile entities',
141
      'administer customer profile types',
142
      'administer line items',
143
      'administer line item types',
144
      'administer commerce_order entities',
145
      'configure order settings',
146
      'view any commerce_order entity',
147
      'create commerce_order entities',
148
      'edit any commerce_order entity',
149
      'administer commerce_product entities',
150
      'administer product types',
151
      'administer product pricing',
152
      'administer payment methods',
153
      'administer payments',
154
      'administer taxes',
155
      'administer rules',
156
    );
157
    $store_customer = array(
158
      'access content',
159
      'access checkout',
160
      'view own commerce_order entities',
161
    );
162
163
    $final_permissions = array();
164
165
    foreach ($sets as $set) {
166
      switch ($set) {
167
        case 'site admin':
168
          $final_permissions = array_unique(array_merge($final_permissions, $site_admin));
169
          break;
170
        case 'store admin':
171
          $final_permissions = array_unique(array_merge($final_permissions, $store_admin));
172
          break;
173
        case 'store customer':
174
          $final_permissions = array_unique(array_merge($final_permissions, $store_customer));
175
          break;
176
      }
177
    }
178
179
    return $final_permissions;
180
  }
181
182
  /**
183
   * Wrapper to easily create users from arrays returned by permissionBuilder().
184
   *
185
   * @param $set
186
   *  See permissionBuilder() function
187
   * @return
188
   *  A user with the permissions returned from permissionBuilder().
189
   */
190
  protected function createUserWithPermissionHelper($set) {
191
    $permissions = $this->permissionBuilder($set);
192
    $user = $this->drupalCreateUser($permissions);
193
    return $user;
194
  }
195
196
  /**
197
   * Returns a site administrator user. Only has permissions for administering
198
   * modules in Drupal core.
199
   */
200
  protected function createSiteAdmin() {
201
    return $this->createUserWithPermissionHelper('site admin');
202
  }
203
204
  /**
205
   * Returns a store administrator user. Only has permissions for administering
206
   * Commerce modules.
207
   */
208
  protected function createStoreAdmin() {
209
    return $this->createUserWithPermissionHelper('store admin');
210
  }
211
212
  /**
213
   * Returns a store customer. It's a regular user with some Commerce
214
   * permissions as access to checkout.
215
   */
216
  protected function createStoreCustomer() {
217
    return $this->createUserWithPermissionHelper('store customer');
218
  }
219
220
  /**
221
   * Return one of the Commerce configured urls.
222
   */
223
  protected function getCommerceUrl($element = 'cart') {
224
    $links = commerce_line_item_summary_links();
225
    if ($element == 'cart') {
226
      return $links['view_cart']['href'];
227
    }
228
    if ($element == 'checkout') {
229
      return $links['checkout']['href'];
230
    }
231
  }
232
233
  /**
234
   * Creates a dummy product type for use with other tests.
235
   *
236
   * @return
237
   *  A product type.
238
   *  FALSE if the appropiate modules were not available.
239
   */
240
  public function createDummyProductType($type = 'product_type', $name = 'Product Type', $description = '', $help = '', $append_random = TRUE) {
241
    if (module_exists('commerce_product')) {
242
      if ($append_random) {
243
        $type = $type .'_'. $this->randomName(20 - strlen($type) - 1);
244
        $name = $name .' '. $this->randomName(40 - strlen($name) - 1);
245
        $description = $description .' '. $this->randomString(128);
246
        $help = $help .' '. $this->randomString(128);
247
      }
248
249
      $new_product_type = commerce_product_ui_product_type_new();
250
      $new_product_type['type'] = $type;
251
      $new_product_type['name'] = $name;
252
      $new_product_type['description'] = $description;
253
      $new_product_type['help'] = $help;
254
      $new_product_type['is_new'] = TRUE;
255
256
      $save_result = commerce_product_ui_product_type_save($new_product_type);
257
258
      if ($save_result === FALSE) {
259
        return FALSE;
260
      }
261
262
      return $new_product_type;
263
    }
264
    else {
265
      return FALSE;
266
    }
267
  }
268
269
  /**
270
   * Creates a dummy product for use with other tests.
271
   *
272
   * @param $type_given
273
   *  Optional. The product type to base this product on. Defaults to 'product'.
274
   * @return
275
   *  A product type with most of it's basic fields set random values.
276
   *  FALSE if the appropiate modules were not available.
277
   */
278
  public function createDummyProduct($sku = '', $title = '', $amount = -1, $currency_code = 'USD', $uid = 1, $type_given = 'product') {
279
    if (module_exists('commerce_product')) {
280
      $new_product = commerce_product_new($type_given);
281
      $new_product->sku = empty($sku) ? $this->randomName(10) : $sku;
282
      $new_product->title = empty($title) ? $this->randomName(10) : $title;
283
      $new_product->uid = $uid;
284
285
      $new_product->commerce_price[LANGUAGE_NONE][0]['amount'] = ($amount < 0) ? rand(2, 500) : $amount;
286
      $new_product->commerce_price[LANGUAGE_NONE][0]['currency_code'] = 'USD';
287
288
      commerce_product_save($new_product);
289
290
      return $new_product;
291
    }
292
    else {
293
      return FALSE;
294
    }
295
  }
296
297
  /**
298
   * Create a dummy product display content type.
299
   *
300
   * @param $type
301
   *  Machine name of the content type to create. Also used for human readable
302
   *  name to keep things simple.
303
   * @param $attach_product_reference_field
304
   *  If TRUE, automatically add a product reference field to the new content
305
   *  type.
306
   * @param $field_name
307
   *  Only used if $attach_product_reference_field is TRUE. Sets the name for
308
   *  the field instance to attach. Creates the field if it doesn't exist.
309
   * @param $cardinality_reference_field
310
   *  Only used if $attach_product_reference_field is TRUE. Sets the
311
   *  cardinality for the field instance to attach.
312
   * @return
313
   *  An object for the content type.
314
   * @see attachProductReferenceField()
315
   */
316
  public function createDummyProductDisplayContentType($type = 'product_display', $attach_product_reference_field = TRUE, $field_name = 'field_product', $cardinality_reference_field = 1) {
317
    // If the specified node type already exists, return it now.
318
    if ($content_type = node_type_load($type)) {
319
      return $content_type;
320
    }
321
322
    $content_type = array(
323
      'type' => $type,
324
      'name' => $type, // Don't use a human readable name here to keep it simple.
325
      'base' => 'node_content',
326
      'description' => 'Use <em>product displays</em> to display products for sale to your customers.',
327
      'custom' => 1,
328
      'modified' => 1,
329
      'locked' => 0,
330
    );
331
    $content_type = node_type_set_defaults($content_type);
332
    node_type_save($content_type);
333
    node_add_body_field($content_type);
334
    $this->pass("Created content type: $type");
335
336
337
    if ($attach_product_reference_field) {
338
      // Maybe $instance should be returned as well
339
      $instance = $this->attachProductReferenceField($type, $field_name, $cardinality_reference_field);
340
    }
341
342
    return $content_type;
343
  }
344
345
  /**
346
   * Create a dummy order in a given status.
347
   *
348
   * @param $uid
349
   * 	 ID of the user that owns the order.
350
   * @param $products
351
   *  	Array of products that are going to be added to the order: keys are
352
   *    product ids, values are the quantity of products to add.
353
   * @param $status
354
   * 	 Status of the order
355
   *
356
   * @return
357
   *   A commerce order object in the given status.
358
   */
359
  public function createDummyOrder($uid = 1, $products = array(), $status = 'cart', $customer_profile_id = NULL) {
360
    // If there aren't any products to add to the order, create one.
361
    if (empty($products)) {
362
      $product = $this->createDummyProduct('PROD-01', 'Product One', -1, 'USD', $uid);
363
      $products[$product->product_id] = rand(1,10);
364
    }
365
366
    // Create a new shopping cart order by adding the products to it.
367
    foreach($products as $product_id => $quantity) {
368
      if ($product = commerce_product_load($product_id)) {
369
        $line_item = commerce_product_line_item_new($product, $quantity);
370
        $line_item = commerce_cart_product_add($uid, $line_item);
371
      }
372
    }
373
374
    // Load the order for returning it.
375
    $order = commerce_cart_order_load($uid);
376
377
    if (!empty($customer_profile_id)) {
378
      $order->commerce_customer_billing[LANGUAGE_NONE][0]['profile_id'] = $customer_profile_id;
379
    }
380
381
    // If the order should be in a different status, update it.
382
    if ($status <> 'cart') {
383
      $order = commerce_order_status_update($order, $status, TRUE);
384
    }
385
386
    commerce_order_save($order);
387
388
    return $order;
389
  }
390
391
  /**
392
   * Attach a product reference field to a given content type. Creates the field
393
   * if the given name doesn't already exist. Automatically sets the display
394
   * formatters to be the "add to cart form" for the teaser and full modes.
395
   *
396
   * @param $content_type
397
   *  Name of the content type that should have a field instance attached.
398
   * @param $field_name
399
   *  Only used if $attach_product_reference_field is TRUE. Sets the name for
400
   *  the field instance to attach. Creates the field if it doesn't exist.
401
   * @return
402
   *  An object containing the field instance that was created.
403
   * @see createDummyProductDisplayContentType()
404
   */
405
  public function attachProductReferenceField($content_type = 'product_display', $field_name = 'field_product', $cardinality = 1) {
406
    if (module_exists('commerce_product')) {
407
      // Check if the field has already been created.
408
      $field_info = field_info_field($field_name);
409
      if (empty($field_info)) {
410
        // Add a product reference field to the product display node type
411
        $field = array(
412
          'field_name' => $field_name,
413
          'type' => 'commerce_product_reference',
414
          'cardinality' => $cardinality,
415
          'translatable' => FALSE,
416
        );
417
        field_create_field($field);
418
        $this->pass("New field created: $field_name");
419
      } else {
420
        debug("NOTE: attachProductReferenceField attempting to create field <code>$field_name</code> that already exists. This is fine and this message is just for your information.");
421
      }
422
423
      // Check that this instance doesn't already exist
424
      $instance = field_info_instance('node', $field_name, $content_type);
425
      if (empty($insance)) {
426
        // Add an instance of the field to the given content type
427
        $instance = array(
428
          'field_name' => $field_name,
429
          'entity_type' => 'node',
430
          'label' => 'Product',
431
          'bundle' => $content_type,
432
          'description' => 'Choose a product to display for sale.',
433
          'required' => TRUE,
434
435
          'widget' => array(
436
            'type' => 'options_select',
437
          ),
438
439
          'display' => array(
440
            'default' => array(
441
              'label' => 'hidden',
442
              'type' => 'commerce_cart_add_to_cart_form',
443
            ),
444
            'teaser' => array(
445
              'label' => 'hidden',
446
              'type' => 'commerce_cart_add_to_cart_form',
447
            ),
448
          ),
449
        );
450
        field_create_instance($instance);
451
        $this->pass("Create field instance of field <code>$field_name</code> on content type <code>$content_type</code>");
452
      } else {
453
        $this->fail("Test Develoepr: You attempted to create a field that already exists. Field: $field_name -- Content Type: $content_type");
454
      }
455
      return $instance;
456
    } else {
457
      $this->fail('Cannot create product reference field because Product module is not enabled.');
458
    }
459
  }
460
461
  /**
462
   * Creates a product display node with an associated product.
463
   *
464
   * @param $product_ids
465
   *  Array of product IDs to use for the product reference field.
466
   * @param $title
467
   *  Optional title for the product node. Will default to a random name.
468
   * @param $product_display_content_type
469
   *  Machine name for the product display content type to use for creating the
470
   *  node. Defaults to 'product_display'.
471
   * @param $product_ref_field_name
472
   *  Machine name for the product reference field on this product display
473
   *  content type. Defaults to 'field_product'.
474
   * @return
475
   *  The newly saved $node object.
476
   */
477
  public function createDummyProductNode($product_ids, $title = '', $product_display_content_type = 'product_display', $product_ref_field_name = 'field_product') {
478
    if (module_exists('commerce_product')) {
479
      if (empty($title)) {
480
        $title = $this->randomString(10);
481
      }
482
      $node = (object) array('type' => $product_display_content_type);
483
      node_object_prepare($node);
484
      $node->uid = 1;
485
      $node->title = $title;
486
      foreach ($product_ids as $product_id) {
487
        $node->{$product_ref_field_name}[LANGUAGE_NONE][]['product_id'] = $product_id;
488
      }
489
      node_save($node);
490
      return $node;
491
    } else {
492
      $this->fail(t('Cannot use use createProductNode because the product module is not enabled.'));
493
    }
494
  }
495
496
  	/**
497
     * Create a full product node without worrying about the earlier steps in
498
     * the process.
499
     *
500
     * @param $count
501
     *  Number of product nodes to create. Each one will have a new product
502
     *  entity associated with it. SKUs will be like PROD-n. Titles will be
503
     *  like 'Product #n'. Price will be 10*n. Counting begins at 1.
504
     * @return
505
     *  An array of product node objects.
506
     */
507
  public function createDummyProductNodeBatch($count) {
508
    $this->createDummyProductDisplayContentType();
509
    $product_nodes = array();
510
    for ($i=1; $i<$count; $i++) {
511
      $sku = "PROD-$i";
512
      $title = "Product #$i";
513
      $price = $i*10;
514
      $product = $this->createDummyProduct($sku, $title, $price);
515
      $product_node = $this->createDummyProductNode(array($product->product_id), $title);
516
      $product_nodes[$i] = $product_node;
517
    }
518
    return $product_nodes;
519
  }
520
521
	/**
522
 	 * Create a dummy tax type.
523
 	 *
524
 	 * @param $tax_type
525
 	 * 	Array with the specific elements for the tax type, all the elements not
526
 	 * 	specified and required will be generated randomly.
527
 	 * 	@see hook_commerce_tax_type_info
528
 	 *
529
 	 * @return
530
 	 *  The tax type array just created or FALSE if it wasn't created.
531
 	 */
532
  public function createDummyTaxType($tax_type = array()) {
533
    $defaults = array(
534
      'name' => 'example_tax_type',
535
    	'title' => t('Example tax type'),
536
    	'display_title' => t('Example tax type'),
537
      'description' => t('Example tax type for testing purposes'),
538
    );
539
    // Generate a tax type array based on defaults and specific elements.
540
    $tax_type = array_merge(commerce_tax_ui_tax_type_new(), $defaults, $tax_type);
541
    if (commerce_tax_ui_tax_type_save($tax_type)) {
542
      return commerce_tax_type_load($tax_type['name']);
543
    }
544
    else {
545
      return FALSE;
546
    }
547
  }
548
549
	/**
550
 	 * Create a dummy tax rate.
551
 	 *
552
 	 * @param $tax_type
553
 	 * 	Array with the specific elements for the tax rate, all elements not
554
 	 * 	specified and required will be generated randomly.
555
 	 *	@see hook_commerce_tax_rate_info
556
 	 *
557
 	 * @return
558
 	 *  The tax type array just created or FALSE if it wasn't created.
559
 	 */
560
  public function createDummyTaxRate($tax_rate = array()) {
561
    $defaults = array(
562
    	'name' => 'example_tax_rate',
563
    	'title' => t('Example tax rate'),
564
    	'display_title' => t('Example tax rate'),
565
      'rate' => rand(1,100)/1000,
566
      'type' => 'example_tax_type',
567
    );
568
    // Generate a tax type array based on defaults and specific elements.
569
    $tax_rate = array_merge(commerce_tax_ui_tax_rate_new(), $defaults, $tax_rate);
570
    if (commerce_tax_ui_tax_rate_save($tax_rate)) {
571
      return commerce_tax_rate_load($tax_rate['name']);
572
    }
573
    else {
574
      return FALSE;
575
    }
576
  }
577
578
  /**
579
   * Create a customer profile.
580
   *
581
   *  @param $type
582
   *  	Type of the customer profile, default billing.
583
   *  @param $uid
584
   *  	User id that will own the profile, by default anonymous.
585
   *  @param $address_info
586
   *  	Address information, associative array keyed by the field name.
587
   *  	i.e. 'commerce_customer_address'.
588
   *
589
   *  @return
590
   *  	The customer profile created or FALSE if the profile wasn't created.
591
   */
592
  public function createDummyCustomerProfile($type = 'billing', $uid = 0, $address_info = array()) {
593
    variable_set('site_default_country', 'US');
594
    // Initialize the profile.
595
    $profile = commerce_customer_profile_new($type, $uid);
596
597
    // Set the defaults.
598
    $defaults['name_line'] = $this->randomName();
599
    $defaults = array_merge($defaults, addressfield_default_values(), $this->generateAddressInformation());
600
601
    // Get all the fields for the given type, by default billing.
602
    $instances = field_info_instances('commerce_customer_profile', $type);
603
    foreach ($instances as $name => $instance) {
604
      $info_field = field_info_field($name);
605
      if ($info_field['type'] == 'addressfield') {
606
        $values = !empty($address_info[$name]) ? array_merge($defaults, $address_info[$name]) : $defaults;
607
        $values['data'] = serialize($values['data']);
608
        $profile->{$name}[LANGUAGE_NONE][] = $values;
609
      }
610
    }
611
    commerce_customer_profile_save($profile);
612
    return $profile;
613
  }
614
615
  /**
616
   * Enable extra currencies in the store.
617
   *
618
   * @param $currencies
619
   *  Array of currency codes to be enabled
620
   */
621
  public function enableCurrencies($currencies) {
622
    $currencies = array_merge(drupal_map_assoc($currencies), variable_get('commerce_enabled_currencies', array('USD' => 'USD')));
623
    variable_set('commerce_enabled_currencies', $currencies);
624
  }
625
626
  // =============== Helper functions ===============
627
628
  /**
629
   * Checks if a group of modules is enabled.
630
   *
631
   * @param $module_name
632
   *  Array of module names to check (without the .module extension)
633
   * @return
634
   *  TRUE if all of the modules are enabled.
635
   */
636
  protected function modulesUp($module_names) {
637
    if (is_string($module_names)) {
638
      $module_names = array($module_names);
639
    }
640
    foreach ($module_names as $module_name) {
641
      if (!module_exists($module_name)) {
642
        return FALSE;
643
      }
644
    }
645
    return TRUE;
646
  }
647
648
  /**
649
   * Generate random valid information for Address information.
650
   */
651
  protected function generateAddressInformation() {
652
    $address_info['name_line'] = $this->randomName();
653
    $address_info['thoroughfare'] = $this->randomName();
654
    $address_info['locality'] = $this->randomName();
655
    $address_info['postal_code'] = rand(00000, 99999);
656
    $address_info['administrative_area'] = 'KY';
657
658
    return $address_info;
659
  }
660
661
  /**
662
   * Generate a random valid email
663
   *
664
   * @param string $type
665
   *  Domain type
666
   *
667
   * @return string
668
   *  Valid email
669
   */
670
  protected function generateEmail($type = 'com'){
671
    return $this->randomName() . '@' . $this->randomName() . '.' . $type;
672
  }
673
674
  /**
675
   * Assertions for Drupal Commerce.
676
   */
677
678
  /**
679
   * Asserts that a product has been added to the cart.
680
   *
681
   * @param $order
682
   *  A full loaded commerce_order object.
683
   * @param $product
684
   *  A full loaded commerce_product object.
685
   * @param $user
686
   * 	User that owns the cart.
687
   *
688
   * @return TRUE if the product is in the cart, FALSE otherwise.
689
   */
690
  public function assertProductAddedToCart($order, $product, $user = NULL) {
691
    // The order should be in cart status.
692
    $this->assertTrue(commerce_cart_order_is_cart($order), t('The order checked is in cart status'));
693
694
    $product_is_in_cart = FALSE;
695
    // Loop through the line items looking for products.
696
    foreach (entity_metadata_wrapper('commerce_order', $order)->commerce_line_items as $delta => $line_item_wrapper) {
697
      // If this line item matches the product checked...
698
      if ($line_item_wrapper->type->value() == 'product' &&
699
          $line_item_wrapper->commerce_product->product_id->value() == $product->product_id) {
700
            $product_is_in_cart = TRUE;
701
      }
702
    }
703
704
    $this->assertTrue($product_is_in_cart, t('Product !product_title is present in the cart', array('!product_title' => $product->title)));
705
706
    // Access to the cart page to check if the product is there.
707
    if (empty($user)) {
708
      $user = $this->createStoreCustomer();
709
    }
710
    $this->drupalLogin($user);
711
    $this->drupalGet($this->getCommerceUrl('cart'));
712
    $this->assertText($product->title, t('Product !product_title is present in the cart view', array('!product_title' => $product->title)));
713
  }
714
715
  /**
716
   *	Asserts that a product has been created.
717
   *
718
   * @param $product
719
   *  A full loaded commerce_product object.
720
   * @param $user
721
   * 	User that access the admin pages. Optional, if not informed, the check
722
   * 	is done with the store admin.
723
   */
724
  public function assertProductCreated($product, $user = NULL) {
725
    // Check if the product is not empty and reload it from database.
726
    $this->assertFalse(empty($product), t('Product object is not empty'));
727
    $product = commerce_product_load($product->product_id);
728
    $this->assertFalse(empty($product), t('Product object is correctly loaded from database'));
729
730
    // Access to the admin page for the product and check if the product is there.
731
    if (empty($user)) {
732
      $user = $this->createStoreAdmin();
733
    }
734
    $this->drupalLogin($user);
735
    $this->drupalGet('admin/commerce/products/' . $product->product_id);
736
    $this->assertFieldById('edit-sku', $product->sku, t('When editing the product in the administration interface, the SKU is informed correctly'));
737
    $this->assertFieldById('edit-title', $product->title, t('When editing the product in the administration interface, the Title is informed correctly'));
738
  }
739
740
}
741
742
743
/**
744
 * Sandbox for trying new things with tests. Eases development so only one test
745
 * has to run at a time. Move everything to CommerceBaseTesterTestCase after it
746
 * is functioning here.
747
 */
748
class CommerceSandboxTestCase extends CommerceBaseTestCase {
749
  protected $site_admin;
750
751
  /**
752
   * getInfo() returns properties that are displayed in the test selection form.
753
   */
754
  public static function getInfo() {
755
    return array(
756
      'name' => t('Commerce sandbox'),
757
      'description' => t('Sandbox for trying new things with tests. Eases development so only one test has to run at a time.'),
758
      'group' => t('Drupal Commerce'),
759
    );
760
  }
761
762
  /**
763
   * setUp() performs any pre-requisite tasks that need to happen.
764
   */
765
  public function setUp() {
766
    $modules = parent::setUpHelper('all');
767
    parent::setUp($modules);
768
769
    $this->site_admin = $this->createSiteAdmin();
770
    cache_clear_all(); // Just in case
771
  }
772
773
  /**
774
   * Sandbox for test development
775
   */
776
  public function testTestTest() {
777
778
  }
779
780
  /**
781
   * Test the createDummyCustomerProfile function.
782
   */
783
  public function testTestCreateDummyCustomerProfile() {
784
    $store_admin = $this->createStoreAdmin();
785
    // Create a new customer profile for the store admin.
786
    $profile = $this->createDummyCustomerProfile('billing', $store_admin->uid);
787
788
    // Load profile reseting cache.
789
    $profile = reset(commerce_customer_profile_load_multiple(array($profile->profile_id), array(), TRUE));
790
791
    $this->assertFalse(empty($profile), t('Profile can be loaded from database'));
792
793
    // Login with store admin user and navigate to the profile listing page.
794
    $this->drupalLogin($store_admin);
795
    $this->drupalGet('admin/commerce/customer-profiles');
796
797
    $this->assertText($profile->commerce_customer_address[LANGUAGE_NONE][0]['name_line'], t('\'Name line\' field for the profile created is present in the customer profile listing'));
798
    $type = commerce_customer_profile_type_load($profile->type);
799
    $this->assertText($type['name'], t('The type of the profile is informed in the profile listing page'));
800
  }
801
802
}
803
804
/**
805
 * Test class to test the CommerceBaseTestCase functions. All testTestFoo
806
 * functions have "testTest" in the name to indicate that they are verifying
807
 * that a test is working. Somewhat "meta" to do this, but it eases test
808
 * development.
809
 */
810
class CommerceBaseTesterTestCase extends CommerceBaseTestCase {
811
  protected $site_admin;
812
813
  /**
814
   * getInfo() returns properties that are displayed in the test selection form.
815
   */
816
  public static function getInfo() {
817
    return array(
818
      'name' => t('Commerce base'),
819
      'description' => t('Test the functionality of the base test class. Essentially, these are meta-tests.'),
820
      'group' => t('Drupal Commerce'),
821
    );
822
  }
823
824
  /**
825
   * setUp() performs any pre-requisite tasks that need to happen.
826
   */
827
  public function setUp() {
828
    $modules = parent::setUpHelper('all');
829
    parent::setUp($modules);
830
831
    $this->site_admin = $this->createSiteAdmin();
832
    cache_clear_all(); // Just in case
833
  }
834
835
  /**
836
   * Ensure that all of the Commerce modules (and their dependencies) are
837
   * enabled in the test environment.
838
   */
839
  public function testModulesEnabled() {
840
    $this->drupalLogin($this->site_admin);
841
    $this->drupalGet('admin/modules');
842
843
    $module_ids = array(
844
      'edit-modules-commerce-commerce-cart-enable',
845
      'edit-modules-commerce-commerce-checkout-enable',
846
      'edit-modules-commerce-commerce-enable',
847
      'edit-modules-commerce-commerce-customer-enable',
848
      'edit-modules-commerce-commerce-line-item-enable',
849
      'edit-modules-commerce-commerce-order-enable',
850
      'edit-modules-commerce-commerce-payment-enable',
851
      'edit-modules-commerce-commerce-price-enable',
852
      'edit-modules-commerce-commerce-product-enable',
853
      'edit-modules-commerce-commerce-product-reference-enable',
854
      'edit-modules-commerce-commerce-product-pricing-enable',
855
      'edit-modules-commerce-commerce-tax-enable',
856
857
      'edit-modules-commerce-commerce-payment-example-enable',
858
859
      'edit-modules-commerce-commerce-ui-enable',
860
      'edit-modules-commerce-commerce-customer-ui-enable',
861
      'edit-modules-commerce-commerce-line-item-ui-enable',
862
      'edit-modules-commerce-commerce-order-ui-enable',
863
      'edit-modules-commerce-commerce-payment-ui-enable',
864
      'edit-modules-commerce-commerce-product-pricing-ui-enable',
865
      'edit-modules-commerce-commerce-product-ui-enable',
866
      'edit-modules-commerce-commerce-tax-ui-enable',
867
868
      'edit-modules-fields-addressfield-enable',
869
      'edit-modules-other-entity-enable',
870
871
      'edit-modules-rules-rules-enable',
872
873
      'edit-modules-chaos-tool-suite-ctools-enable',
874
875
      'edit-modules-views-views-enable',
876
    );
877
    foreach ($module_ids as $module_id) {
878
      $this->assertFieldChecked($module_id);
879
    }
880
  }
881
882
  /**
883
   * Test that Store Admin role actually gets set up.
884
   */
885
  public function testTestStoreAdmin() {
886
    $store_admin = $this->createStoreAdmin();
887
    $this->drupalLogin($this->site_admin);
888
    $this->drupalGet('admin/people/permissions');
889
    // This will break if it isn't the second role created
890
    $this->assertFieldChecked('edit-5-configure-store');
891
  }
892
893
  /**
894
   * Make a test product type.
895
   */
896
  public function testTestCreateDummyProductType() {
897
    $product_type = $this->createDummyProductType();
898
    $store_admin = $this->createStoreAdmin();
899
    $this->drupalLogin($store_admin);
900
    $this->drupalGet('admin/commerce/products/types');
901
    $this->assertText($product_type['name'], t('Dummy product type name found on admin/commerce/products/types'));
902
  }
903
904
  /**
905
   * Make a test product.
906
   */
907
  public function testTestCreateDummyProduct() {
908
    // Create the product.
909
    $product = $this->createDummyProduct();
910
911
    // Login with the store admin.
912
    $store_admin = $this->createStoreAdmin();
913
    $this->drupalLogin($store_admin);
914
915
    // Assert that the product is in the product listing.
916
    $this->drupalGet('admin/commerce/products');
917
    $this->assertText($product->title, t('Dummy product found on admin page at admin/commerce/products'));
918
    $this->drupalGet('admin/commerce/products/list');
919
    $this->assertText($product->title, t('Dummy product found on admin page at admin/commerce/products/list'));
920
  }
921
922
  /**
923
   * Test the creation of a product_display content type and add a product
924
   * reference field to the content type.
925
   */
926
  public function testTestCreateDummyProductDisplayAndRefField() {
927
    $this->createDummyProductDisplayContentType();
928
929
    $this->drupalLogin($this->site_admin);
930
    $this->drupalGet('node/add/product-display');
931
    $this->assertText('product_display', t('product_display content type successfully created and accessible.'));
932
    //$this->assertOptionSelected('edit-field-product-und', '_none', 'Dummy Product Display reference field shows up on node add page');
933
    $this->assertFieldById('edit-field-product-und', '', t('Product reference field found on Dummy Product Display.'));
934
935
    // Try to add the same field a second time and see if any errors pop up.
936
    //  If uncommented, this will product an error. Basically, this should be
937
    //  turned into an assertion that checks for the presence of the field.
938
    //$this->attachProductReferenceField('product_display', 'field_product');
939
  }
940
941
  /**
942
   * Test the createDummyProductNode function.
943
   */
944
  public function testTestCreateDummyProductNode() {
945
    // Create a dummy product display content type
946
    $this->createDummyProductDisplayContentType();
947
948
    // Create dummy product display nodes (and their corresponding product
949
    //  entities)
950
    $sku = 'PROD-01';
951
    $product_name = 'Product One';
952
    $product = $this->createDummyProduct($sku, $product_name);
953
    $product_node = $this->createDummyProductNode(array($product->product_id), $product_name);
954
955
    $this->drupalLogin($this->site_admin);
956
    $this->drupalGet("node/{$product_node->nid}");
957
    $this->assertText($product_name, t('Product !product_name created successfully', array('!product_name' => $product_name)));
958
  }
959
960
  /**
961
   * Test the createDummyProductNodeBatch function.
962
   */
963
  public function testTestCreateDummyProductNodeBatch() {
964
    $product_nodes = $this->createDummyProductNodeBatch(3);
965
    $this->drupalLogin($this->site_admin);
966
    $product_node = $product_nodes[1];
967
    $this->drupalGet("node/{$product_node->nid}");
968
    $this->assertText($product_node->title, t('Product !product_title node page exists', array('product_title' => $product_node->title)));
969
  }
970
971
  /**
972
   * Test the createDummyOrder function.
973
   */
974
  public function testTestCreateDummyOrder() {
975
    $normal_user = $this->drupalCreateUser(array('access checkout'));
976
    $this->drupalLogin($normal_user);
977
978
    $sku = 'PROD-01';
979
    $product_name = 'Product One';
980
    $product = $this->createDummyProduct($sku, $product_name);
981
    $order = $this->createDummyOrder($normal_user->uid, array($product->product_id => 1));
982
983
    // Check if the order is in cart status.
984
    $this->assertTrue(commerce_cart_order_is_cart($order), t('Order is in a shopping cart status'));
985
    $this->drupalGet('checkout');
986
987
    $this->assertTitle(t('Checkout'). ' | Drupal', t('Checkout accessible for the order'));
988
    $this->assertText($product_name, t('Product is added to the order'));
989
  }
990
991
  /**
992
   * Test the currency value rounding.
993
   */
994
  public function testCurrencyRounding() {
995
996
    // array( rounding_step => array( 'value' => 'expected result'));
997
    $rounding_numbers = array(
998
      '0.05' => array(
999
        '1' => '1',
1000
        '5' => '5',
1001
        '777' => '777',
1002
        '1.22' => '1.20',
1003
        '12.2249' => '12.20',
1004
        '1200.225' => '1200.25',
1005
        '0.2749' => '0.25',
1006
        '490.275' => '490.30',
1007
      ),
1008
      '0.02' => array(
1009
        '1' => '1',
1010
        '777' => '777',
1011
        '1.205' => '1.20',
1012
        '12.20999' => '12.20',
1013
        '1200.21' => '1200.22',
1014
        '0.26999' => '0.26',
1015
        '490.2712' => '490.28',
1016
      ),
1017
      '0.5' => array(
1018
        '1' => '1',
1019
        '5' => '5',
1020
        '1.22' => '1',
1021
        '12.2499' => '12',
1022
        '1200.25' => '1200.5',
1023
        '0.749' => '0.5',
1024
        '490.75' => '491.0',
1025
      ),
1026
      '0.2' => array(
1027
        '1' => '1',
1028
        '777' => '777',
1029
        '1.05' => '1',
1030
        '12.0999' => '12',
1031
        '1200.1' => '1200.2',
1032
        '0.6999' => '0.6',
1033
        '490.712' => '490.8',
1034
      ),
1035
    );
1036
1037
    foreach ($rounding_numbers as $rounding_step => $numbers) {
1038
      foreach ($numbers as $input => $output) {
1039
        $currency = array('decimals' => 2, 'rounding_step' => $rounding_step);
1040
1041
        $result = commerce_currency_round($input, $currency);
1042
        $this->assertEqual($result, $output, t('Rounding !input to !output with the rounding step: !rounding_step', array('!input' => $input, '!output' => $output, '!rounding_step' => $rounding_step)));
1043
      }
1044
    }
1045
  }
1046
1047
  /**
1048
   * Test enabling extra currencies.
1049
   */
1050
  public function testEnableCurrencies() {
1051
    // Enable Euros.
1052
    $this->enableCurrencies(array('EUR'));
1053
    // Check if Euros is enabled.
1054
    $this->assertTrue(in_array('EUR', variable_get('commerce_enabled_currencies', array('USD' => 'USD'))), t('Euros are enabled'));
1055
  }
1056
1057
  /**
1058
   * Test creating a new tax type.
1059
   */
1060
  public function testTestCreateDummyTaxType() {
1061
    // Create a dummy tax type.
1062
    $tax_type = $this->createDummyTaxType();
1063
1064
    // Create and login with a store admin user.
1065
    $store_admin = $this->createStoreAdmin();
1066
    $this->drupalLogin($store_admin);
1067
1068
    // Access to the tax type listing page and assert that the dummy tax type
1069
    // is present.
1070
    $this->drupalGet('admin/commerce/config/taxes/types');
1071
    $this->assertText($tax_type['display_title'], t('Dummy tax type found on admin page at admin/commerce/config/taxes/types'));
1072
  }
1073
1074
  /**
1075
   * Test creating a new tax rate.
1076
   */
1077
  public function testTestCreateDummyTaxRate() {
1078
    // Create a dummy tax type.
1079
    $tax_type = $this->createDummyTaxType();
1080
1081
    // Create a dummy tax rate.
1082
    $tax_rate = $this->createDummyTaxRate();
1083
1084
    // Create and login with a store admin user.
1085
    $store_admin = $this->createStoreAdmin();
1086
    $this->drupalLogin($store_admin);
1087
1088
    // Access to the tax type listing page and assert that the dummy tax type
1089
    // is present.
1090
    $this->drupalGet('admin/commerce/config/taxes/rates');
1091
    $this->assertText($tax_rate['display_title'], t('Dummy tax rate found on admin page at admin/commerce/config/taxes/rates'));
1092
  }
1093
}