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 @ 9d13637e

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'] = '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
}