Projet

Général

Profil

Paste
Télécharger (34,3 ko) Statistiques
| Branche: | Révision:

root / drupal7 / sites / all / modules / commerce / tests / commerce_base.test @ 651307cd

1
<?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_ui')) {
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'] = $currency_code;
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
   *
586
   *  @return
587
   *  	The customer profile created or FALSE if the profile wasn't created.
588
   */
589
  public function createDummyCustomerProfile($type = 'billing', $uid = 0) {
590
    // Initialize the profile.
591
    $profile = commerce_customer_profile_new($type, $uid);
592
    // Initialize the address.
593
    $defaults = array();
594
    $defaults['name_line'] = $this->randomName();
595
    $field = field_info_field('commerce_customer_address');
596
    $instance = field_info_instance('commerce_customer_profile', 'commerce_customer_address', $type);
597
    $values = array_merge($defaults, addressfield_default_values($field, $instance), $this->generateAddressInformation());
598
    $values['data'] = serialize($values['data']);
599
    $profile->commerce_customer_address[LANGUAGE_NONE][] = $values;
600
    // Save the dummy profile.
601
    commerce_customer_profile_save($profile);
602

    
603
    return $profile;
604
  }
605

    
606
  /**
607
   * Enable extra currencies in the store.
608
   *
609
   * @param $currencies
610
   *  Array of currency codes to be enabled
611
   */
612
  public function enableCurrencies($currencies) {
613
    $currencies = array_merge(drupal_map_assoc($currencies), variable_get('commerce_enabled_currencies', array('USD' => 'USD')));
614
    variable_set('commerce_enabled_currencies', $currencies);
615
  }
616

    
617
  // =============== Helper functions ===============
618

    
619
  /**
620
   * Checks if a group of modules is enabled.
621
   *
622
   * @param $module_name
623
   *  Array of module names to check (without the .module extension)
624
   * @return
625
   *  TRUE if all of the modules are enabled.
626
   */
627
  protected function modulesUp($module_names) {
628
    if (is_string($module_names)) {
629
      $module_names = array($module_names);
630
    }
631
    foreach ($module_names as $module_name) {
632
      if (!module_exists($module_name)) {
633
        return FALSE;
634
      }
635
    }
636
    return TRUE;
637
  }
638

    
639
  /**
640
   * Generate random valid information for Address information.
641
   */
642
  protected function generateAddressInformation() {
643
    $address_info['name_line'] = $this->randomName();
644
    $address_info['thoroughfare'] = $this->randomName();
645
    $address_info['locality'] = $this->randomName();
646
    $address_info['postal_code'] = rand(00000, 99999);
647
    $address_info['administrative_area'] = 'KY';
648

    
649
    return $address_info;
650
  }
651

    
652
  /**
653
   * Generate a random valid email
654
   *
655
   * @param string $type
656
   *  Domain type
657
   *
658
   * @return string
659
   *  Valid email
660
   */
661
  protected function generateEmail($type = 'com'){
662
    return $this->randomName() . '@' . $this->randomName() . '.' . $type;
663
  }
664

    
665
  /**
666
   * Assertions for Drupal Commerce.
667
   */
668

    
669
  /**
670
   * Asserts that a product has been added to the cart.
671
   *
672
   * @param $order
673
   *  A full loaded commerce_order object.
674
   * @param $product
675
   *  A full loaded commerce_product object.
676
   * @param $user
677
   * 	User that owns the cart.
678
   *
679
   * @return TRUE if the product is in the cart, FALSE otherwise.
680
   */
681
  public function assertProductAddedToCart($order, $product, $user = NULL) {
682
    // The order should be in cart status.
683
    $this->assertTrue(commerce_cart_order_is_cart($order), t('The order checked is in cart status'));
684

    
685
    $product_is_in_cart = FALSE;
686
    // Loop through the line items looking for products.
687
    foreach (entity_metadata_wrapper('commerce_order', $order)->commerce_line_items as $delta => $line_item_wrapper) {
688
      // If this line item matches the product checked...
689
      if ($line_item_wrapper->getBundle() == 'product' &&
690
          $line_item_wrapper->commerce_product->product_id->value() == $product->product_id) {
691
            $product_is_in_cart = TRUE;
692
      }
693
    }
694

    
695
    $this->assertTrue($product_is_in_cart, t('Product !product_title is present in the cart', array('!product_title' => $product->title)));
696

    
697
    // Access to the cart page to check if the product is there.
698
    if (empty($user)) {
699
      $user = $this->createStoreCustomer();
700
    }
701
    $this->drupalLogin($user);
702
    $this->drupalGet($this->getCommerceUrl('cart'));
703
    $this->assertText($product->title, t('Product !product_title is present in the cart view', array('!product_title' => $product->title)));
704
  }
705

    
706
  /**
707
   *	Asserts that a product has been created.
708
   *
709
   * @param $product
710
   *  A full loaded commerce_product object.
711
   * @param $user
712
   * 	User that access the admin pages. Optional, if not informed, the check
713
   * 	is done with the store admin.
714
   */
715
  public function assertProductCreated($product, $user = NULL) {
716
    // Check if the product is not empty and reload it from database.
717
    $this->assertFalse(empty($product), t('Product object is not empty'));
718
    $product = commerce_product_load($product->product_id);
719
    $this->assertFalse(empty($product), t('Product object is correctly loaded from database'));
720

    
721
    // Access to the admin page for the product and check if the product is there.
722
    if (empty($user)) {
723
      $user = $this->createStoreAdmin();
724
    }
725
    $this->drupalLogin($user);
726
    $this->drupalGet('admin/commerce/products/' . $product->product_id);
727
    $this->assertFieldById('edit-sku', $product->sku, t('When editing the product in the administration interface, the SKU is informed correctly'));
728
    $this->assertFieldById('edit-title', $product->title, t('When editing the product in the administration interface, the Title is informed correctly'));
729
  }
730

    
731
}
732

    
733
/**
734
 * Test class to test the CommerceBaseTestCase functions. All testTestFoo
735
 * functions have "testTest" in the name to indicate that they are verifying
736
 * that a test is working. Somewhat "meta" to do this, but it eases test
737
 * development.
738
 */
739
class CommerceBaseTesterTestCase extends CommerceBaseTestCase {
740
  protected $site_admin;
741

    
742
  /**
743
   * getInfo() returns properties that are displayed in the test selection form.
744
   */
745
  public static function getInfo() {
746
    return array(
747
      'name' => t('Commerce base'),
748
      'description' => t('Test the functionality of the base test class. Essentially, these are meta-tests.'),
749
      'group' => t('Drupal Commerce'),
750
    );
751
  }
752

    
753
  /**
754
   * setUp() performs any pre-requisite tasks that need to happen.
755
   */
756
  public function setUp() {
757
    $modules = parent::setUpHelper('all');
758
    parent::setUp($modules);
759

    
760
    $this->site_admin = $this->createSiteAdmin();
761
    cache_clear_all(); // Just in case
762
  }
763

    
764
  /**
765
   * Ensure that all of the Commerce modules (and their dependencies) are
766
   * enabled in the test environment.
767
   */
768
  public function testModulesEnabled() {
769
    $this->drupalLogin($this->site_admin);
770
    $this->drupalGet('admin/modules');
771

    
772
    $module_ids = array(
773
      'edit-modules-commerce-commerce-cart-enable',
774
      'edit-modules-commerce-commerce-checkout-enable',
775
      'edit-modules-commerce-commerce-enable',
776
      'edit-modules-commerce-commerce-customer-enable',
777
      'edit-modules-commerce-commerce-line-item-enable',
778
      'edit-modules-commerce-commerce-order-enable',
779
      'edit-modules-commerce-commerce-payment-enable',
780
      'edit-modules-commerce-commerce-price-enable',
781
      'edit-modules-commerce-commerce-product-enable',
782
      'edit-modules-commerce-commerce-product-reference-enable',
783
      'edit-modules-commerce-commerce-product-pricing-enable',
784
      'edit-modules-commerce-commerce-tax-enable',
785

    
786
      'edit-modules-commerce-commerce-payment-example-enable',
787

    
788
      'edit-modules-commerce-commerce-ui-enable',
789
      'edit-modules-commerce-commerce-customer-ui-enable',
790
      'edit-modules-commerce-commerce-line-item-ui-enable',
791
      'edit-modules-commerce-commerce-order-ui-enable',
792
      'edit-modules-commerce-commerce-payment-ui-enable',
793
      'edit-modules-commerce-commerce-product-pricing-ui-enable',
794
      'edit-modules-commerce-commerce-product-ui-enable',
795
      'edit-modules-commerce-commerce-tax-ui-enable',
796

    
797
      'edit-modules-fields-addressfield-enable',
798
      'edit-modules-other-entity-enable',
799

    
800
      'edit-modules-rules-rules-enable',
801

    
802
      'edit-modules-chaos-tool-suite-ctools-enable',
803

    
804
      'edit-modules-views-views-enable',
805
    );
806
    foreach ($module_ids as $module_id) {
807
      $this->assertFieldChecked($module_id);
808
    }
809
  }
810

    
811
  /**
812
   * Test that Store Admin role actually gets set up.
813
   */
814
  public function testTestStoreAdmin() {
815
    $store_admin = $this->createStoreAdmin();
816
    $this->drupalLogin($this->site_admin);
817
    $this->drupalGet('admin/people/permissions');
818
    // This will break if it isn't the second role created
819
    $this->assertFieldChecked('edit-5-configure-store');
820
  }
821

    
822
  /**
823
   * Make a test product type.
824
   */
825
  public function testTestCreateDummyProductType() {
826
    $product_type = $this->createDummyProductType();
827
    $store_admin = $this->createStoreAdmin();
828
    $this->drupalLogin($store_admin);
829
    $this->drupalGet('admin/commerce/products/types');
830
    $this->assertText($product_type['name'], t('Dummy product type name found on admin/commerce/products/types'));
831
  }
832

    
833
  /**
834
   * Make a test product.
835
   */
836
  public function testTestCreateDummyProduct() {
837
    // Create the product.
838
    $product = $this->createDummyProduct();
839

    
840
    // Login with the store admin.
841
    $store_admin = $this->createStoreAdmin();
842
    $this->drupalLogin($store_admin);
843

    
844
    // Assert that the product is in the product listing.
845
    $this->drupalGet('admin/commerce/products');
846
    $this->assertText($product->title, t('Dummy product found on admin page at admin/commerce/products'));
847
    $this->drupalGet('admin/commerce/products/list');
848
    $this->assertText($product->title, t('Dummy product found on admin page at admin/commerce/products/list'));
849
  }
850

    
851
  /**
852
   * Test the creation of a product_display content type and add a product
853
   * reference field to the content type.
854
   */
855
  public function testTestCreateDummyProductDisplayAndRefField() {
856
    $this->createDummyProductDisplayContentType();
857

    
858
    $this->drupalLogin($this->site_admin);
859
    $this->drupalGet('node/add/product-display');
860
    $this->assertText('product_display', t('product_display content type successfully created and accessible.'));
861
    //$this->assertOptionSelected('edit-field-product-und', '_none', 'Dummy Product Display reference field shows up on node add page');
862
    $this->assertFieldById('edit-field-product-und', '', t('Product reference field found on Dummy Product Display.'));
863

    
864
    // Try to add the same field a second time and see if any errors pop up.
865
    //  If uncommented, this will product an error. Basically, this should be
866
    //  turned into an assertion that checks for the presence of the field.
867
    //$this->attachProductReferenceField('product_display', 'field_product');
868
  }
869

    
870
  /**
871
   * Test the createDummyProductNode function.
872
   */
873
  public function testTestCreateDummyProductNode() {
874
    // Create a dummy product display content type
875
    $this->createDummyProductDisplayContentType();
876

    
877
    // Create dummy product display nodes (and their corresponding product
878
    //  entities)
879
    $sku = 'PROD-01';
880
    $product_name = 'Product One';
881
    $product = $this->createDummyProduct($sku, $product_name);
882
    $product_node = $this->createDummyProductNode(array($product->product_id), $product_name);
883

    
884
    $this->drupalLogin($this->site_admin);
885
    $this->drupalGet("node/{$product_node->nid}");
886
    $this->assertText($product_name, t('Product !product_name created successfully', array('!product_name' => $product_name)));
887
  }
888

    
889
  /**
890
   * Test the createDummyProductNodeBatch function.
891
   */
892
  public function testTestCreateDummyProductNodeBatch() {
893
    $product_nodes = $this->createDummyProductNodeBatch(3);
894
    $this->drupalLogin($this->site_admin);
895
    $product_node = $product_nodes[1];
896
    $this->drupalGet("node/{$product_node->nid}");
897
    $this->assertText($product_node->title, t('Product !product_title node page exists', array('product_title' => $product_node->title)));
898
  }
899

    
900
  /**
901
   * Test the createDummyOrder function.
902
   */
903
  public function testTestCreateDummyOrder() {
904
    $normal_user = $this->drupalCreateUser(array('access checkout'));
905
    $this->drupalLogin($normal_user);
906

    
907
    $sku = 'PROD-01';
908
    $product_name = 'Product One';
909
    $product = $this->createDummyProduct($sku, $product_name);
910
    $order = $this->createDummyOrder($normal_user->uid, array($product->product_id => 1));
911

    
912
    // Check if the order is in cart status.
913
    $this->assertTrue(commerce_cart_order_is_cart($order), t('Order is in a shopping cart status'));
914
    $this->drupalGet('checkout');
915

    
916
    $this->assertTitle(t('Checkout'). ' | Drupal', t('Checkout accessible for the order'));
917
    $this->assertText($product_name, t('Product is added to the order'));
918
  }
919

    
920
  /**
921
   * Test the currency value rounding.
922
   */
923
  public function testCurrencyRounding() {
924

    
925
    // array( rounding_step => array( 'value' => 'expected result'));
926
    $rounding_numbers = array(
927
      '0.05' => array(
928
        '1' => '1',
929
        '5' => '5',
930
        '777' => '777',
931
        '1.22' => '1.20',
932
        '12.2249' => '12.20',
933
        '1200.225' => '1200.25',
934
        '0.2749' => '0.25',
935
        '490.275' => '490.30',
936
      ),
937
      '0.02' => array(
938
        '1' => '1',
939
        '777' => '777',
940
        '1.205' => '1.20',
941
        '12.20999' => '12.20',
942
        '1200.21' => '1200.22',
943
        '0.26999' => '0.26',
944
        '490.2712' => '490.28',
945
      ),
946
      '0.5' => array(
947
        '1' => '1',
948
        '5' => '5',
949
        '1.22' => '1',
950
        '12.2499' => '12',
951
        '1200.25' => '1200.5',
952
        '0.749' => '0.5',
953
        '490.75' => '491.0',
954
      ),
955
      '0.2' => array(
956
        '1' => '1',
957
        '777' => '777',
958
        '1.05' => '1',
959
        '12.0999' => '12',
960
        '1200.1' => '1200.2',
961
        '0.6999' => '0.6',
962
        '490.712' => '490.8',
963
      ),
964
    );
965

    
966
    foreach ($rounding_numbers as $rounding_step => $numbers) {
967
      foreach ($numbers as $input => $output) {
968
        $currency = array('decimals' => 2, 'rounding_step' => $rounding_step);
969

    
970
        $result = commerce_currency_round($input, $currency);
971
        $this->assertEqual($result, $output, t('Rounding !input to !output with the rounding step: !rounding_step', array('!input' => $input, '!output' => $output, '!rounding_step' => $rounding_step)));
972
      }
973
    }
974
  }
975

    
976
  /**
977
   * Test enabling extra currencies.
978
   */
979
  public function testEnableCurrencies() {
980
    // Enable Euros.
981
    $this->enableCurrencies(array('EUR'));
982
    // Check if Euros is enabled.
983
    $this->assertTrue(in_array('EUR', variable_get('commerce_enabled_currencies', array('USD' => 'USD'))), t('Euros are enabled'));
984
  }
985

    
986
  /**
987
   * Test creating a new tax type.
988
   */
989
  public function testTestCreateDummyTaxType() {
990
    // Create a dummy tax type.
991
    $tax_type = $this->createDummyTaxType();
992

    
993
    // Create and login with a store admin user.
994
    $store_admin = $this->createStoreAdmin();
995
    $this->drupalLogin($store_admin);
996

    
997
    // Access to the tax type listing page and assert that the dummy tax type
998
    // is present.
999
    $this->drupalGet('admin/commerce/config/taxes/types');
1000
    $this->assertText($tax_type['display_title'], t('Dummy tax type found on admin page at admin/commerce/config/taxes/types'));
1001
  }
1002

    
1003
  /**
1004
   * Test creating a new tax rate.
1005
   */
1006
  public function testTestCreateDummyTaxRate() {
1007
    // Create a dummy tax type.
1008
    $tax_type = $this->createDummyTaxType();
1009

    
1010
    // Create a dummy tax rate.
1011
    $tax_rate = $this->createDummyTaxRate();
1012

    
1013
    // Create and login with a store admin user.
1014
    $store_admin = $this->createStoreAdmin();
1015
    $this->drupalLogin($store_admin);
1016

    
1017
    // Access to the tax type listing page and assert that the dummy tax type
1018
    // is present.
1019
    $this->drupalGet('admin/commerce/config/taxes/rates');
1020
    $this->assertText($tax_rate['display_title'], t('Dummy tax rate found on admin page at admin/commerce/config/taxes/rates'));
1021
  }
1022
}