Projet

Général

Profil

Paste
Télécharger (35,9 ko) Statistiques
| Branche: | Révision:

root / drupal7 / sites / all / modules / feeds / tests / feeds_mapper_multilingual_fields.test @ ed9a13f1

1
<?php
2

    
3
/**
4
 * @file
5
 * Contains FeedsMapperMultilingualFieldsTestCase.
6
 */
7

    
8
/**
9
 * Tests field mapping with multiple languages.
10
 */
11
class FeedsMapperMultilingualFieldsTestCase extends FeedsMapperTestCase {
12

    
13
  /**
14
   * Name of created content type.
15
   *
16
   * @var string
17
   */
18
  private $contentType;
19

    
20
  /**
21
   * @var array
22
   */
23
  protected $fields = array();
24

    
25
  /**
26
   * {@inheritdoc}
27
   */
28
  public static function getInfo() {
29
    return array(
30
      'name' => 'Mapper: Multilingual fields',
31
      'description' => 'Tests Feeds multilingual support.',
32
      'group' => 'Feeds',
33
      'dependencies' => array('date', 'entity_translation', 'i18n_taxonomy', 'link'),
34
    );
35
  }
36

    
37
  /**
38
   * {@inheritdoc}
39
   */
40
  public function setUp() {
41
    $modules = array(
42
      'locale',
43
      'entity_translation',
44
      'date',
45
      'link',
46
      'list',
47
      'number',
48
    );
49

    
50
    $permissions = array(
51
      'administer entity translation',
52
      'translate any entity',
53
      'administer languages',
54
    );
55

    
56
    parent::setUp($modules, $permissions);
57

    
58
    // Include FeedsProcessor.inc so processor related constants are available.
59
    module_load_include('inc', 'feeds', 'plugins/FeedsProcessor');
60

    
61
    // Add French language.
62
    $this->addLanguage('fr', 'French');
63

    
64
    // Add Categories vocabulary.
65
    $edit = array(
66
      'name' => 'Categories',
67
      'machine_name' => 'categories',
68
    );
69
    $this->drupalPost('admin/structure/taxonomy/add', $edit, 'Save');
70

    
71
    // Create content type.
72
    $this->fields = array(
73
      'date' => array(
74
        'type' => 'date',
75
        'settings' => array(
76
          'field[settings][granularity][hour]' => FALSE,
77
          'field[settings][granularity][minute]' => FALSE,
78
          'field[settings][tz_handling]' => 'none',
79
        ),
80
      ),
81
      'datestamp' => array(
82
        'type' => 'datestamp',
83
        'settings' => array(
84
          'field[settings][granularity][second]' => TRUE,
85
          'field[settings][tz_handling]' => 'utc',
86
        ),
87
      ),
88
      'datetime' => array(
89
        'type' => 'datetime',
90
        'settings' => array(
91
          'field[settings][granularity][second]' => TRUE,
92
          'field[settings][tz_handling]' => 'utc',
93
        ),
94
      ),
95
      'image' => array(
96
        'type' => 'image',
97
        'instance_settings' => array(
98
          'instance[settings][alt_field]' => 1,
99
          'instance[settings][title_field]' => 1,
100
        ),
101
      ),
102
      'link' => 'link_field',
103
      'list_boolean' => 'list_boolean',
104
      'number_integer' => 'number_integer',
105
      'number_decimal' => 'number_decimal',
106
      'number_float' => 'number_float',
107
      'text' => 'text',
108
    );
109
    $this->contentType = $this->createContentType(array(), $this->fields);
110

    
111
    // Create term reference field.
112
    $field = array(
113
      'field_name' => 'field_category',
114
      'type' => 'taxonomy_term_reference',
115
      'cardinality' => FIELD_CARDINALITY_UNLIMITED,
116
      'settings' => array(
117
        'allowed_values' => array(
118
          array(
119
            'vocabulary' => 'categories',
120
            'parent' => 0,
121
          ),
122
        ),
123
      ),
124
    );
125
    field_create_field($field);
126

    
127
    // Add term reference field to article bundle.
128
    $this->instance = array(
129
      'field_name' => 'field_category',
130
      'bundle' => $this->contentType,
131
      'entity_type' => 'node',
132
      'widget' => array(
133
        'type' => 'taxonomy_autocomplete',
134
      ),
135
      'display' => array(
136
        'default' => array(
137
          'type' => 'taxonomy_term_reference_link',
138
        ),
139
      ),
140
    );
141
    field_create_instance($this->instance);
142

    
143
    // Make content type and fields multilingual.
144
    $field_names = array(
145
      'body',
146
      'field_category',
147
    );
148
    foreach ($this->fields as $field_name => $field_type) {
149
      $field_names[] = 'field_' . $field_name;
150
    }
151
    $this->setupMultilingual($this->contentType, $field_names);
152

    
153
    // Copy directory of source files, CSV file expects them in public://images.
154
    $this->copyDir($this->absolutePath() . '/tests/feeds/assets', 'public://images');
155

    
156
    // Create an importer configuration with basic mapping.
157
    $this->createImporterConfiguration('Test multilingual fields import from CSV', 'node');
158
    $this->setPlugin('node', 'FeedsCSVParser');
159
    $this->setPlugin('node', 'FeedsFileFetcher');
160
    $this->setSettings('node', 'FeedsNodeProcessor', array(
161
      'bundle' => $this->contentType,
162
      'language' => 'en',
163
    ));
164

    
165
    // Add language neutral mappings.
166
    $this->addMappings('node', array(
167
      0 => array(
168
        'source' => 'guid',
169
        'target' => 'guid',
170
        'unique' => 1,
171
      ),
172
      1 => array(
173
        'source' => 'title',
174
        'target' => 'title',
175
      ),
176
    ));
177
  }
178

    
179
  /**
180
   * Tests multilingual mappings to translatable fields (entity translation).
181
   */
182
  public function testMultilingualFieldMappings() {
183
    // Add English mappers.
184
    $index = 2;
185
    $mappings = $this->getMappingsInLanguage('en', $index);
186
    // Append "_en" to each source name.
187
    foreach ($mappings as &$mapping) {
188
      $mapping['source'] .= '_en';
189
    }
190
    $this->addMappings('node', $mappings);
191
    $index += count($mappings);
192

    
193
    // Add French mappers.
194
    $mappings = $this->getMappingsInLanguage('fr', $index);
195
    // Append "_fr" to each source name.
196
    foreach ($mappings as &$mapping) {
197
      $mapping['source'] .= '_fr';
198
    }
199
    $this->addMappings('node', $mappings);
200

    
201
    // Import file that has items with both English and French field values.
202
    $this->importFile('node', $this->absolutePath() . '/tests/feeds/multilingual_en_fr.csv');
203
    $this->assertText(t('Created 1 node'));
204

    
205
    // Load node.
206
    $node = node_load(1, NULL, TRUE);
207

    
208
    // Inspect availability of English values.
209
    $english = $this->getEnglishValues($node) + array(
210
      'field_category' => array(
211
        'expected' => 1,
212
        'actual' => $node->field_category['en'][0]['tid'],
213
      ),
214
    );
215
    foreach ($english as $field_name => $value) {
216
      $this->assertEqual($value['expected'], $value['actual'], format_string('The English field %field has the expected value (actual: @actual).', array('%field' => $field_name, '@actual' => $value['actual'])));
217
    }
218

    
219
    // Inspect availability of French values.
220
    $french = $this->getFrenchValues($node) + array(
221
      'field_category' => array(
222
        'expected' => 2,
223
        'actual' => $node->field_category['fr'][0]['tid'],
224
      ),
225
    );
226
    foreach ($french as $field_name => $value) {
227
      $this->assertEqual($value['expected'], $value['actual'], format_string('The French field %field has the expected value (actual: @actual).', array('%field' => $field_name, '@actual' => $value['actual'])));
228
    }
229
  }
230

    
231
  /**
232
   * Tests if values of fields in other languages are kept when not importing
233
   * in that language.
234
   */
235
  public function testChangedLanguageImport() {
236
    // Add Dutch language.
237
    $this->addLanguage('nl', 'Dutch');
238

    
239
    // Import an item first in the Dutch language.
240
    $this->setSettings('node', 'FeedsNodeProcessor', array(
241
      'language' => 'nl',
242
    ));
243
    $mappings = $this->getMappingsInLanguage('nl', 2);
244
    $this->addMappings('node', $mappings);
245
    $this->importFile('node', $this->absolutePath() . '/tests/feeds/multilingual_nl.csv');
246
    $this->assertText(t('Created 1 node'));
247

    
248
    // Assert that Dutch values were created.
249
    $node = node_load(1, NULL, TRUE);
250
    $dutch = $this->getDutchValues($node) + array(
251
      'field_category' => array(
252
        'expected' => 1,
253
        'actual' => $node->field_category['nl'][0]['tid'],
254
      ),
255
    );
256
    foreach ($dutch as $field_name => $value) {
257
      $this->assertEqual($value['expected'], $value['actual'], format_string('The Dutch field %field has the expected value (actual: @actual).', array('%field' => $field_name, '@actual' => $value['actual'])));
258
    }
259

    
260
    // Set import to update existing nodes.
261
    $this->setSettings('node', 'FeedsNodeProcessor', array(
262
      'update_existing' => FEEDS_UPDATE_EXISTING,
263
    ));
264

    
265
    // Change mappers language to French.
266
    $path = 'admin/structure/feeds/node/mapping';
267
    foreach ($mappings as $i => $mapping) {
268
      $this->drupalPostAJAX($path, array(), 'mapping_settings_edit_' . $i);
269
      $edit = array("config[$i][settings][field_language]" => 'fr');
270
      $this->drupalPostAJAX(NULL, $edit, 'mapping_settings_update_' . $i);
271
      $this->drupalPost(NULL, array(), t('Save'));
272
    }
273
    // Import French item.
274
    $this->importFile('node', $this->absolutePath() . '/tests/feeds/multilingual_fr.csv');
275
    $this->assertText(t('Updated 1 node'));
276

    
277
    // Assert that French values were created.
278
    $node = node_load(1, NULL, TRUE);
279
    $french = $this->getFrenchValues($node) + array(
280
      'field_category' => array(
281
        'expected' => 2,
282
        'actual' => $node->field_category['fr'][0]['tid'],
283
      ),
284
    );
285
    foreach ($french as $field_name => $value) {
286
      $this->assertEqual($value['expected'], $value['actual'], format_string('The French field %field has the expected value (actual: @actual).', array('%field' => $field_name, '@actual' => $value['actual'])));
287
    }
288

    
289
    // Assert that Dutch values still exist.
290
    $dutch = $this->getDutchValues($node) + array(
291
      'field_category' => array(
292
        'expected' => 1,
293
        'actual' => $node->field_category['nl'][0]['tid'],
294
      ),
295
    );
296
    foreach ($dutch as $field_name => $value) {
297
      $this->assertEqual($value['expected'], $value['actual'], format_string('The Dutch field %field has the expected value (actual: @actual).', array('%field' => $field_name, '@actual' => $value['actual'])));
298
    }
299
  }
300

    
301
  /**
302
   * Tests if values of fields in other languages are kept when not importing
303
   * in that language for nodes that were not created by Feeds.
304
   */
305
  public function testChangedLanguageImportForExistingNode() {
306
    // Add Dutch language.
307
    $this->addLanguage('nl', 'Dutch');
308

    
309
    // Date settings.
310
    foreach (array('datestamp', 'datetime') as $field) {
311
      $field = 'field_' . $field;
312
      $edit = array(
313
        'field[settings][granularity][second]' => 1,
314
      );
315
      $this->drupalPost('admin/structure/types/manage/' . $this->contentType . '/fields/' . $field . '/field-settings', $edit, 'Save field settings');
316
    }
317

    
318
    // Hack to get date fields to not round to every 15 seconds.
319
    foreach (array('date', 'datestamp', 'datetime') as $field) {
320
      $field = 'field_' . $field;
321
      $edit = array(
322
        'widget_type' => 'date_select',
323
      );
324
      $this->drupalPost('admin/structure/types/manage/' . $this->contentType . '/fields/' . $field . '/widget-type', $edit, 'Continue');
325
      $edit = array(
326
        'instance[widget][settings][increment]' => 1,
327
        'field[settings][enddate_get]' => 1,
328
      );
329
      $this->drupalPost('admin/structure/types/manage/' . $this->contentType . '/fields/' . $field, $edit, 'Save settings');
330
      $edit = array(
331
        'widget_type' => 'date_text',
332
      );
333
      $this->drupalPost('admin/structure/types/manage/' . $this->contentType . '/fields/' . $field . '/widget-type', $edit, 'Continue');
334
    }
335

    
336
    // Create a node with Dutch values (except for the title, which is used as
337
    // unique target).
338
    $edit = array(
339
      'title' => 'Teste Feeds Multilingue 1',
340
      'language' => 'nl',
341
    );
342
    $this->drupalPost('node/add/' . $this->contentType, $edit, t('Save'));
343
    // Add values for Dutch fields.
344
    $edit = array(
345
      'body[nl][0][value]' => 'Dit is de berichttekst',
346
      'field_date[nl][0][value][date]' => '07/29/1985',
347
      'field_datestamp[nl][0][value][date]' => '07/29/1985 - 04:48:12',
348
      'field_datetime[nl][0][value][date]' => '07/29/1985 - 04:48:12',
349
      'field_link[nl][0][url]' => 'http://google.nl',
350
      'field_list_boolean[nl]' => '1',
351
      'field_number_decimal[nl][0][value]' => '30.3',
352
      'field_number_float[nl][0][value]' => '30.2795',
353
      'field_number_integer[nl][0][value]' => '30',
354
      'field_text[nl][0][value]' => 'Wortelen',
355
      'files[field_image_nl_0]' => drupal_realpath('public://images/attersee.jpeg'),
356
      'field_category[nl]' => 'Nieuws',
357
    );
358
    $this->drupalPost('node/1/edit/nl', $edit, t('Save'));
359
    // Add alt/title to the image.
360
    $edit = array(
361
      'field_image[nl][0][alt]' => 'Bij het zien',
362
      'field_image[nl][0][title]' => 'Bij het zien van de groene vloeistof',
363
    );
364
    $this->drupalPost('node/1/edit/nl', $edit, t('Save'));
365
    $this->drupalGet('node/1/edit/nl');
366

    
367
    // Assert that the Dutch values were put in as expected.
368
    $node = node_load(1, NULL, TRUE);
369
    $dutch = $this->getDutchValues($node) + array(
370
      'field_category' => array(
371
        'expected' => 1,
372
        'actual' => $node->field_category['nl'][0]['tid'],
373
      ),
374
    );
375
    foreach ($dutch as $field_name => $value) {
376
      $this->assertEqual($value['expected'], $value['actual'], format_string('The Dutch field %field has the expected value (actual: @actual).', array('%field' => $field_name, '@actual' => $value['actual'])));
377
    }
378

    
379
    // Change unique target from guid (0) to title (1).
380
    $path = 'admin/structure/feeds/node/mapping';
381
    $this->drupalPostAJAX($path, array(), 'mapping_settings_edit_0');
382
    $edit = array("config[0][settings][unique]" => FALSE);
383
    $this->drupalPostAJAX(NULL, $edit, 'mapping_settings_update_0');
384
    $this->drupalPost(NULL, array(), t('Save'));
385
    $this->drupalPostAJAX($path, array(), 'mapping_settings_edit_1');
386
    $edit = array("config[1][settings][unique]" => 1);
387
    $this->drupalPostAJAX(NULL, $edit, 'mapping_settings_update_1');
388
    $this->drupalPost(NULL, array(), t('Save'));
389

    
390
    // Update this item with Feeds.
391
    $this->setSettings('node', 'FeedsNodeProcessor', array(
392
      'update_existing' => FEEDS_UPDATE_EXISTING,
393
    ));
394
    $this->addMappings('node', $this->getMappingsInLanguage('fr'));
395
    $this->importFile('node', $this->absolutePath() . '/tests/feeds/multilingual_fr.csv');
396
    $this->assertText(t('Updated 1 node'));
397

    
398
    // Assert that French values were created.
399
    $node = node_load(1, NULL, TRUE);
400
    $french = $this->getFrenchValues($node) + array(
401
      'field_category' => array(
402
        'expected' => 2,
403
        'actual' => $node->field_category['fr'][0]['tid'],
404
      ),
405
    );
406
    foreach ($french as $field_name => $value) {
407
      $this->assertEqual($value['expected'], $value['actual'], format_string('The French field %field has the expected value (actual: @actual).', array('%field' => $field_name, '@actual' => $value['actual'])));
408
    }
409

    
410
    // Assert that Dutch values still exist.
411
    $dutch = $this->getDutchValues($node) + array(
412
      'field_category' => array(
413
        'expected' => 1,
414
        'actual' => $node->field_category['nl'][0]['tid'],
415
      ),
416
    );
417
    foreach ($dutch as $field_name => $value) {
418
      $this->assertEqual($value['expected'], $value['actual'], format_string('The Dutch field %field has the expected value (actual: @actual).', array('%field' => $field_name, '@actual' => $value['actual'])));
419
    }
420
  }
421

    
422
  /**
423
   * Tests if fields still are imported in their language when the
424
   * entity_translation module gets disabled.
425
   *
426
   * The entity_translation module is mainly an UI module for configuring field
427
   * language and disabling that module should not have effect on importing
428
   * values in a specific language for fields.
429
   */
430
  public function testWithDisabledEntityTranslationModule() {
431
    module_disable(array('entity_translation'));
432
    // Make sure that entity info is reset.
433
    drupal_flush_all_caches();
434
    drupal_static_reset();
435

    
436
    // Configure importer to import in French language.
437
    $this->setSettings('node', 'FeedsNodeProcessor', array(
438
      'language' => 'fr',
439
    ));
440
    $this->addMappings('node', $this->getMappingsInLanguage('fr'));
441

    
442
    // Import content.
443
    $this->importFile('node', $this->absolutePath() . '/tests/feeds/multilingual_fr.csv');
444
    $this->assertText(t('Created 1 node'));
445

    
446
    // Assert that the fields were all created in French.
447
    $node = node_load(1, NULL, TRUE);
448
    $french = $this->getFrenchValues($node) + array(
449
      'field_category' => array(
450
        'expected' => 1,
451
        'actual' => $node->field_category['fr'][0]['tid'],
452
      ),
453
    );
454
    foreach ($french as $field_name => $value) {
455
      $this->assertEqual($value['expected'], $value['actual'], format_string('The field %field has the expected value (actual: @actual).', array('%field' => $field_name, '@actual' => $value['actual'])));
456
    }
457
  }
458

    
459
  /**
460
   * Tests if fields are still imported in their language when the
461
   * entity_translation module gets uninstalled.
462
   *
463
   * @see testWithDisabledEntityTranslationModule()
464
   */
465
  public function testWithUninstalledEntityTranslationModule() {
466
    module_disable(array('entity_translation'));
467
    drupal_uninstall_modules(array('entity_translation'));
468
    // Make sure that entity info is reset.
469
    drupal_flush_all_caches();
470
    drupal_static_reset();
471

    
472
    // Configure importer to import in French language.
473
    $this->setSettings('node', 'FeedsNodeProcessor', array(
474
      'language' => 'fr',
475
    ));
476
    $this->addMappings('node', $this->getMappingsInLanguage('fr'));
477

    
478
    // Import content.
479
    $this->importFile('node', $this->absolutePath() . '/tests/feeds/multilingual_fr.csv');
480
    $this->assertText(t('Created 1 node'));
481

    
482
    // Assert that the fields were all created in French.
483
    $node = node_load(1, NULL, TRUE);
484
    $french = $this->getFrenchValues($node) + array(
485
      'field_category' => array(
486
        'expected' => 1,
487
        'actual' => $node->field_category['fr'][0]['tid'],
488
      ),
489
    );
490
    foreach ($french as $field_name => $value) {
491
      $this->assertEqual($value['expected'], $value['actual'], format_string('The field %field has the expected value (actual: @actual).', array('%field' => $field_name, '@actual' => $value['actual'])));
492
    }
493
  }
494

    
495
  /**
496
   * Tests if fields are imported in LANGUAGE_NONE if the field's language gets
497
   * disabled after configuring.
498
   */
499
  public function testDisabledLanguage() {
500
    // Configure importer to import in French language.
501
    $this->setSettings('node', 'FeedsNodeProcessor', array(
502
      'language' => 'fr',
503
    ));
504
    $this->addMappings('node', $this->getMappingsInLanguage('fr'));
505

    
506
    // Now disable the French language.
507
    $path = 'admin/config/regional/language';
508
    $edit = array(
509
      'enabled[fr]' => FALSE,
510
    );
511
    $this->drupalPost($path, $edit, t('Save configuration'));
512
    // Reset static cache to update the available languages.
513
    drupal_static_reset();
514

    
515
    // Ensure no error messages are shown on the mappings page.
516
    $this->drupalGet('admin/structure/feeds/node/mapping');
517

    
518
    // Import content.
519
    $this->importFile('node', $this->absolutePath() . '/tests/feeds/multilingual_fr.csv');
520
    $this->assertText(t('Created 1 node'));
521

    
522
    // Assert that the fields were all created in LANGUAGE_NONE.
523
    $node = node_load(1, NULL, TRUE);
524
    $french = $this->getFrenchValues($node, LANGUAGE_NONE) + array(
525
      'field_category' => array(
526
        'expected' => 1,
527
        'actual' => $node->field_category[LANGUAGE_NONE][0]['tid'],
528
      ),
529
    );
530
    foreach ($french as $field_name => $value) {
531
      $this->assertEqual($value['expected'], $value['actual'], format_string('The field %field has the expected value (actual: @actual).', array('%field' => $field_name, '@actual' => $value['actual'])));
532
    }
533
  }
534

    
535
  /**
536
   * Tests if fields are imported in LANGUAGE_NONE if the field's language gets
537
   * removed after configuring.
538
   */
539
  public function testRemovedLanguage() {
540
    // Configure importer to import in French language.
541
    $this->setSettings('node', 'FeedsNodeProcessor', array(
542
      'language' => 'fr',
543
    ));
544
    $this->addMappings('node', $this->getMappingsInLanguage('fr'));
545

    
546
    // Now remove the French language.
547
    $path = 'admin/config/regional/language/delete/fr';
548
    $this->drupalPost($path, array(), t('Delete'));
549
    // Reset static cache to update the available languages.
550
    drupal_static_reset();
551

    
552
    // Import content.
553
    $this->importFile('node', $this->absolutePath() . '/tests/feeds/multilingual_fr.csv');
554
    $this->assertText(t('Created 1 node'));
555

    
556
    // Assert that the fields were all created in LANGUAGE_NONE.
557
    $node = node_load(1, NULL, TRUE);
558
    $french = $this->getFrenchValues($node, LANGUAGE_NONE) + array(
559
      'field_category' => array(
560
        'expected' => 1,
561
        'actual' => $node->field_category[LANGUAGE_NONE][0]['tid'],
562
      ),
563
    );
564
    foreach ($french as $field_name => $value) {
565
      $this->assertEqual($value['expected'], $value['actual'], format_string('The field %field has the expected value (actual: @actual).', array('%field' => $field_name, '@actual' => $value['actual'])));
566
    }
567
  }
568

    
569
  /**
570
   * Tests if autocreated terms are in the language that was set on the target configuration
571
   * in case the taxonomy is multilingual.
572
   */
573
  public function testAutocreatedTermLanguage() {
574
    module_enable(array('i18n_taxonomy'));
575
    // Make sure that entity info is reset.
576
    drupal_flush_all_caches();
577
    drupal_static_reset();
578

    
579
    // Enable multilingual taxonomy.
580
    $edit = array('i18n_mode' => 4);
581
    $this->drupalPost('admin/structure/taxonomy/categories/edit', $edit, 'Save');
582

    
583
    // Configure importer to import in French language.
584
    $this->setSettings('node', 'FeedsNodeProcessor', array(
585
      'language' => 'fr',
586
    ));
587
    $this->addMappings('node', array(
588
      2 => array(
589
        'source' => 'term',
590
        'target' => 'field_category',
591
        'autocreate' => TRUE,
592
        'field_language' => 'fr',
593
      ),
594
    ));
595

    
596
    // Import French item.
597
    $this->importFile('node', $this->absolutePath() . '/tests/feeds/multilingual_fr.csv');
598
    $this->assertText(t('Created 1 node'));
599

    
600
    // Assert that the created term is in the French language.
601
    $term = taxonomy_term_load(1);
602
    $this->assertEqual('fr', entity_language('taxonomy_term', $term));
603
  }
604

    
605
  /**
606
   * Tests if values are cleared out when an empty value or no value is
607
   * provided.
608
   */
609
  public function testClearOutValues() {
610
    // Set to update existing nodes.
611
    $this->setSettings('node', 'FeedsNodeProcessor', array(
612
      'update_existing' => FEEDS_UPDATE_EXISTING,
613
    ));
614

    
615
    // Add English mappers.
616
    $index = 2;
617
    $mappings = $this->getMappingsInLanguage('en', $index);
618
    // Append "_en" to each source name.
619
    foreach ($mappings as &$mapping) {
620
      $mapping['source'] .= '_en';
621
    }
622
    $this->addMappings('node', $mappings);
623
    $index += count($mappings);
624

    
625
    // Add French mappers.
626
    $mappings = $this->getMappingsInLanguage('fr', $index);
627
    // Append "_fr" to each source name.
628
    foreach ($mappings as &$mapping) {
629
      $mapping['source'] .= '_fr';
630
    }
631
    $this->addMappings('node', $mappings);
632

    
633
    // Import file that has items with both English and French field values.
634
    $this->importFile('node', $this->absolutePath() . '/tests/feeds/multilingual_en_fr.csv');
635
    $this->assertText(t('Created 1 node'));
636

    
637
    // Now import a file where the French remained, but the English values were
638
    // removed.
639
    $this->importFile('node', $this->absolutePath() . '/tests/feeds/multilingual_en_fr_empty.csv');
640
    $this->assertText(t('Updated 1 node'));
641

    
642
    // Load node.
643
    $node = node_load(1, NULL, TRUE);
644

    
645
    // Check that the English values are gone, but the French values are still
646
    // there.
647
    $fields = array(
648
      'body',
649
      'field_date',
650
      'field_datestamp',
651
      'field_datetime',
652
      'field_image',
653
      'field_link',
654
      'field_list_boolean',
655
      'field_number_decimal',
656
      'field_number_float',
657
      'field_number_integer',
658
      'field_category',
659
      'field_text',
660
    );
661
    foreach ($fields as $field_name) {
662
      $this->assertTrue(empty($node->{$field_name}['en']), format_string('The field %field is empty.', array('%field' => $field_name)));
663
    }
664

    
665
    // Inspect availability of French values.
666
    $french = $this->getFrenchValues($node) + array(
667
      'field_category' => array(
668
        'expected' => 2,
669
        'actual' => $node->field_category['fr'][0]['tid'],
670
      ),
671
    );
672
    // Since the image was placed on the node again, its file name is now
673
    // "la fayette_0.jpeg."
674
    $french['field_image']['expected'] = 'la fayette_0.jpeg';
675
    foreach ($french as $field_name => $value) {
676
      $this->assertEqual($value['expected'], $value['actual'], format_string('The French field %field has the expected value (actual: @actual).', array('%field' => $field_name, '@actual' => $value['actual'])));
677
    }
678
  }
679

    
680
  /**
681
   * Tests if values are cleared out when an empty value is provided for a
682
   * language that got disabled.
683
   */
684
  public function testClearOutValuesWithDisabledLanguage() {
685
    // Set to update existing nodes.
686
    $this->setSettings('node', 'FeedsNodeProcessor', array(
687
      'update_existing' => FEEDS_UPDATE_EXISTING,
688
    ));
689

    
690
    // Configure importer to import in French language.
691
    $this->setSettings('node', 'FeedsNodeProcessor', array(
692
      'language' => 'fr',
693
    ));
694
    $this->addMappings('node', $this->getMappingsInLanguage('fr'));
695

    
696
    // Now disable the French language.
697
    $path = 'admin/config/regional/language';
698
    $edit = array(
699
      'enabled[fr]' => FALSE,
700
    );
701
    $this->drupalPost($path, $edit, t('Save configuration'));
702

    
703
    // Ensure no error messages are shown on the mappings page.
704
    $this->drupalGet('admin/structure/feeds/node/mapping');
705

    
706
    // Import content. Since the French language was disabled, the content
707
    // should be imported as LANGUAGE_NONE.
708
    // @see ::testDisabledLanguage()
709
    $this->importFile('node', $this->absolutePath() . '/tests/feeds/multilingual_fr.csv');
710
    $this->assertText(t('Created 1 node'));
711

    
712
    // Now import a file with empty values.
713
    $this->importFile('node', $this->absolutePath() . '/tests/feeds/multilingual_empty.csv');
714
    $this->assertText(t('Updated 1 node'));
715

    
716
    // Load node.
717
    $node = node_load(1, NULL, TRUE);
718

    
719
    // Check that the values in LANGUAGE_NONE are gone.
720
    $fields = array(
721
      'body',
722
      'field_date',
723
      'field_datestamp',
724
      'field_datetime',
725
      'field_image',
726
      'field_link',
727
      'field_list_boolean',
728
      'field_number_decimal',
729
      'field_number_float',
730
      'field_number_integer',
731
      'field_category',
732
      'field_text',
733
    );
734
    foreach ($fields as $field_name) {
735
      $this->assertTrue(empty($node->{$field_name}[LANGUAGE_NONE]), format_string('The field %field is empty.', array('%field' => $field_name)));
736
    }
737
  }
738

    
739
  /**
740
   * Adds a language to test with.
741
   *
742
   * @param string $langcode
743
   *   The language's langcode.
744
   * @param string $label
745
   *   The language human readable name.
746
   */
747
  protected function addLanguage($langcode, $label) {
748
    $edit = array(
749
      'langcode' => $langcode,
750
    );
751
    $this->drupalPost('admin/config/regional/language/add', $edit, t('Add language'));
752
    $this->assertText(format_string('The language @language has been created and can now be used.', array('@language' => $label)));
753
  }
754

    
755
  /**
756
   * Sets given content type and fields to be translatable.
757
   *
758
   * @param string $typename
759
   *   The machine name of the node type.
760
   * @param array $field_names
761
   *   The fields to enable multilingual support for.
762
   */
763
  protected function setupMultilingual($typename, array $field_names) {
764
    // Enable entity field translation for content type.
765
    $edit = array(
766
      'language_content_type' => 4,
767
      'entity_translation_hide_translation_links' => 1,
768
      'entity_translation_node_metadata' => 0,
769
    );
770
    $this->drupalPost('admin/structure/types/manage/' . $typename, $edit, t('Save content type'));
771

    
772
    // Enable field translation on fields.
773
    $edit = array(
774
      'field[translatable]' => 1,
775
    );
776
    foreach ($field_names as $field_name) {
777
      $this->drupalPost("admin/structure/types/manage/{$typename}/fields/{$field_name}", $edit, t('Save settings'));
778
    }
779

    
780
    // Reset static cache so that all languages are available when
781
    // field_available_languages() is called during node_load().
782
    drupal_static_reset();
783
  }
784

    
785
  /**
786
   * Adds mappings for each field in specified language.
787
   *
788
   * @param string $langcode
789
   *   The code of the desired language.
790
   * @param int $start
791
   *   The index number to start the array with. This must be
792
   *   specified in order to add mappings to the right index when
793
   *   calling FeedsWebTestCase::addMappings().
794
   */
795
  protected function getMappingsInLanguage($langcode, $start = 2) {
796
    $mappings = array(
797
      $start => array(
798
        'source' => 'body',
799
        'target' => 'body',
800
      ),
801
      array(
802
        'source' => 'date',
803
        'target' => 'field_date:start',
804
      ),
805
      array(
806
        'source' => 'datestamp',
807
        'target' => 'field_datestamp:start',
808
      ),
809
      array(
810
        'source' => 'datetime',
811
        'target' => 'field_datetime:start',
812
      ),
813
      array(
814
        'source' => 'image',
815
        'target' => 'field_image:uri',
816
      ),
817
      array(
818
        'source' => 'image_alt',
819
        'target' => 'field_image:alt',
820
      ),
821
      array(
822
        'source' => 'image_title',
823
        'target' => 'field_image:title',
824
      ),
825
      array(
826
        'source' => 'link',
827
        'target' => 'field_link:url',
828
      ),
829
      array(
830
        'source' => 'list_boolean',
831
        'target' => 'field_list_boolean',
832
      ),
833
      array(
834
        'source' => 'number_decimal',
835
        'target' => 'field_number_decimal',
836
      ),
837
      array(
838
        'source' => 'number_float',
839
        'target' => 'field_number_float',
840
      ),
841
      array(
842
        'source' => 'number_integer',
843
        'target' => 'field_number_integer',
844
      ),
845
      array(
846
        'source' => 'term',
847
        'target' => 'field_category',
848
        'autocreate' => TRUE,
849
      ),
850
      array(
851
        'source' => 'text',
852
        'target' => 'field_text',
853
      ),
854
    );
855
    foreach ($mappings as &$mapping) {
856
      $mapping['field_language'] = $langcode;
857
    }
858
    return $mappings;
859
  }
860

    
861
  /**
862
   * Returns expected and actual values of given node for the Dutch language.
863
   *
864
   * @param object $node
865
   *   The multilingual node.
866
   * @param string $langcode
867
   *   The used language code.
868
   *
869
   * @return array
870
   *   The expected and actual Dutch values.
871
   */
872
  protected function getDutchValues($node, $langcode = 'nl') {
873
    return array(
874
      'body' => array(
875
        'expected' => 'Dit is de berichttekst',
876
        'actual' => $node->body[$langcode][0]['value'],
877
      ),
878
      'field_date' => array(
879
        'expected' => '1985-07-29T00:00:00',
880
        'actual' => $node->field_date[$langcode][0]['value'],
881
      ),
882
      'field_datestamp' => array(
883
        'expected' => '491460492',
884
        'actual' => $node->field_datestamp[$langcode][0]['value'],
885
      ),
886
      'field_datetime' => array(
887
        'expected' => '1985-07-29 04:48:12',
888
        'actual' => $node->field_datetime[$langcode][0]['value'],
889
      ),
890
      'field_image' => array(
891
        'expected' => 'attersee.jpeg',
892
        'actual' => $node->field_image[$langcode][0]['filename'],
893
      ),
894
      'field_image:alt' => array(
895
        'expected' => 'Bij het zien',
896
        'actual' => $node->field_image[$langcode][0]['alt'],
897
      ),
898
      'field_image:title' => array(
899
        'expected' => 'Bij het zien van de groene vloeistof',
900
        'actual' => $node->field_image[$langcode][0]['title'],
901
      ),
902
      'field_link' => array(
903
        'expected' => 'http://google.nl',
904
        'actual' => $node->field_link[$langcode][0]['url'],
905
      ),
906
      'field_list_boolean' => array(
907
        'expected' => '1',
908
        'actual' => $node->field_list_boolean[$langcode][0]['value'],
909
      ),
910
      'field_number_decimal' => array(
911
        'expected' => 30.3,
912
        'actual' => $node->field_number_decimal[$langcode][0]['value'],
913
      ),
914
      'field_number_float' => array(
915
        'expected' => 30.2795,
916
        'actual' => $node->field_number_float[$langcode][0]['value'],
917
      ),
918
      'field_number_integer' => array(
919
        'expected' => 30,
920
        'actual' => $node->field_number_integer[$langcode][0]['value'],
921
      ),
922
      'field_text' => array(
923
        'expected' => 'Wortelen',
924
        'actual' => $node->field_text[$langcode][0]['value'],
925
      ),
926
    );
927
  }
928

    
929
  /**
930
   * Returns expected and actual values of given node for the English language.
931
   *
932
   * @param object $node
933
   *   The multilingual node.
934
   * @param string $langcode
935
   *   The used language code.
936
   *
937
   * @return array
938
   *   The expected and actual English values.
939
   */
940
  protected function getEnglishValues($node, $langcode = 'en') {
941
    return array(
942
      'body' => array(
943
        'expected' => 'This is the body',
944
        'actual' => $node->body[$langcode][0]['value'],
945
      ),
946
      'field_date' => array(
947
        'expected' => '2015-10-21T00:00:00',
948
        'actual' => $node->field_date[$langcode][0]['value'],
949
      ),
950
      'field_datestamp' => array(
951
        'expected' => '1445470140',
952
        'actual' => $node->field_datestamp[$langcode][0]['value'],
953
      ),
954
      'field_datetime' => array(
955
        'expected' => '2015-10-21 23:29:00',
956
        'actual' => $node->field_datetime[$langcode][0]['value'],
957
      ),
958
      'field_image' => array(
959
        'expected' => 'foosball.jpeg',
960
        'actual' => $node->field_image[$langcode][0]['filename'],
961
      ),
962
      'field_image:alt' => array(
963
        'expected' => 'Foosball',
964
        'actual' => $node->field_image[$langcode][0]['alt'],
965
      ),
966
      'field_image:title' => array(
967
        'expected' => 'Foosball played by two guys',
968
        'actual' => $node->field_image[$langcode][0]['title'],
969
      ),
970
      'field_link' => array(
971
        'expected' => 'http://google.ca',
972
        'actual' => $node->field_link[$langcode][0]['url'],
973
      ),
974
      'field_list_boolean' => array(
975
        'expected' => '0',
976
        'actual' => $node->field_list_boolean[$langcode][0]['value'],
977
      ),
978
      'field_number_decimal' => array(
979
        'expected' => 4.2,
980
        'actual' => $node->field_number_decimal[$langcode][0]['value'],
981
      ),
982
      'field_number_float' => array(
983
        'expected' => 3.1416,
984
        'actual' => $node->field_number_float[$langcode][0]['value'],
985
      ),
986
      'field_number_integer' => array(
987
        'expected' => 1000,
988
        'actual' => $node->field_number_integer[$langcode][0]['value'],
989
      ),
990
      'field_text' => array(
991
        'expected' => 'Carrots',
992
        'actual' => $node->field_text[$langcode][0]['value'],
993
      ),
994
    );
995
  }
996

    
997
  /**
998
   * Returns expected and actual values of given node for the French language.
999
   *
1000
   * @param object $node
1001
   *   The multilingual node.
1002
   * @param string $langcode
1003
   *   The used language code.
1004
   *
1005
   * @return array
1006
   *   The expected and actual French values.
1007
   */
1008
  protected function getFrenchValues($node, $langcode = 'fr') {
1009
    return array(
1010
      'body' => array(
1011
        'expected' => 'Ceci est la corps',
1012
        'actual' => $node->body[$langcode][0]['value'],
1013
      ),
1014
      'field_date' => array(
1015
        'expected' => '1955-11-05T00:00:00',
1016
        'actual' => $node->field_date[$langcode][0]['value'],
1017
      ),
1018
      'field_datestamp' => array(
1019
        'expected' => '-446731187',
1020
        'actual' => $node->field_datestamp[$langcode][0]['value'],
1021
      ),
1022
      'field_datetime' => array(
1023
        'expected' => '1955-11-05 12:00:13',
1024
        'actual' => $node->field_datetime[$langcode][0]['value'],
1025
      ),
1026
      'field_image' => array(
1027
        'expected' => 'la fayette.jpeg',
1028
        'actual' => $node->field_image[$langcode][0]['filename'],
1029
      ),
1030
      'field_image:alt' => array(
1031
        'expected' => 'La Fayette',
1032
        'actual' => $node->field_image[$langcode][0]['alt'],
1033
      ),
1034
      'field_image:title' => array(
1035
        'expected' => 'la Fayette dans les bois',
1036
        'actual' => $node->field_image[$langcode][0]['title'],
1037
      ),
1038
      'field_link' => array(
1039
        'expected' => 'http://google.fr',
1040
        'actual' => $node->field_link[$langcode][0]['url'],
1041
      ),
1042
      'field_list_boolean' => array(
1043
        'expected' => '1',
1044
        'actual' => $node->field_list_boolean[$langcode][0]['value'],
1045
      ),
1046
      'field_number_decimal' => array(
1047
        'expected' => 1.2,
1048
        'actual' => $node->field_number_decimal[$langcode][0]['value'],
1049
      ),
1050
      'field_number_float' => array(
1051
        'expected' => 5.6295,
1052
        'actual' => $node->field_number_float[$langcode][0]['value'],
1053
      ),
1054
      'field_number_integer' => array(
1055
        'expected' => 2000,
1056
        'actual' => $node->field_number_integer[$langcode][0]['value'],
1057
      ),
1058
      'field_text' => array(
1059
        'expected' => 'Carottes',
1060
        'actual' => $node->field_text[$langcode][0]['value'],
1061
      ),
1062
    );
1063
  }
1064

    
1065
}