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 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 280fe687 Assos Assos
      'entity_token',
34 85ad3d82 Assos Assos
      '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 9d13637e Assos Assos
    if (module_exists('commerce_product_ui')) {
242 85ad3d82 Assos Assos
      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 280fe687 Assos Assos
      $new_product->commerce_price[LANGUAGE_NONE][0]['currency_code'] = $currency_code;
287 85ad3d82 Assos Assos
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 280fe687 Assos Assos
  public function createDummyCustomerProfile($type = 'billing', $uid = 0) {
590 85ad3d82 Assos Assos
    // Initialize the profile.
591
    $profile = commerce_customer_profile_new($type, $uid);
592 280fe687 Assos Assos
    // Initialize the address.
593
    $defaults = array();
594 85ad3d82 Assos Assos
    $defaults['name_line'] = $this->randomName();
595 280fe687 Assos Assos
    $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 85ad3d82 Assos Assos
    commerce_customer_profile_save($profile);
602 280fe687 Assos Assos
603 85ad3d82 Assos Assos
    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 280fe687 Assos Assos
      if ($line_item_wrapper->getBundle() == 'product' &&
690 85ad3d82 Assos Assos
          $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
}