Projet

Général

Profil

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

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

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
  public static function getInfo() {
26
    return array(
27
      'name' => 'Mapper: Multilingual fields',
28
      'description' => 'Tests Feeds multilingual support.',
29
      'group' => 'Feeds',
30
      'dependencies' => array('date', 'entity_translation', 'i18n_taxonomy', 'link'),
31
    );
32
  }
33

    
34
  public function setUp() {
35
    $modules = array(
36
      'locale',
37
      'entity_translation',
38
      'date',
39
      'link',
40
      'list',
41
      'number',
42
    );
43

    
44
    $permissions = array(
45
      'administer entity translation',
46
      'translate any entity',
47
      'administer languages',
48
    );
49

    
50
    parent::setUp($modules, $permissions);
51

    
52
    // Include FeedsProcessor.inc so processor related constants are available.
53
    module_load_include('inc', 'feeds', 'plugins/FeedsProcessor');
54

    
55
    // Add French language.
56
    $this->addLanguage('fr', 'French');
57

    
58
    // Add Categories vocabulary.
59
    $edit = array(
60
      'name' => 'Categories',
61
      'machine_name' => 'categories',
62
    );
63
    $this->drupalPost('admin/structure/taxonomy/add', $edit, 'Save');
64

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

    
105
    // Create term reference field.
106
    $field = array(
107
      'field_name' => 'field_category',
108
      'type' => 'taxonomy_term_reference',
109
      'cardinality' => FIELD_CARDINALITY_UNLIMITED,
110
      'settings' => array(
111
        'allowed_values' => array(
112
          array(
113
            'vocabulary' => 'categories',
114
            'parent' => 0,
115
          ),
116
        ),
117
      ),
118
    );
119
    field_create_field($field);
120

    
121
    // Add term reference field to article bundle.
122
    $this->instance = array(
123
      'field_name' => 'field_category',
124
      'bundle' => $this->contentType,
125
      'entity_type' => 'node',
126
      'widget' => array(
127
        'type' => 'taxonomy_autocomplete',
128
      ),
129
      'display' => array(
130
        'default' => array(
131
          'type' => 'taxonomy_term_reference_link',
132
        ),
133
      ),
134
    );
135
    field_create_instance($this->instance);
136

    
137
    // Make content type and fields multilingual.
138
    $field_names = array(
139
      'body',
140
      'field_category',
141
    );
142
    foreach ($this->fields as $field_name => $field_type) {
143
      $field_names[] = 'field_' . $field_name;
144
    }
145
    $this->setupMultilingual($this->contentType, $field_names);
146

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

    
150
    // Create an importer configuration with basic mapping.
151
    $this->createImporterConfiguration('Test multilingual fields import from CSV', 'node');
152
    $this->setPlugin('node', 'FeedsCSVParser');
153
    $this->setPlugin('node', 'FeedsFileFetcher');
154
    $this->setSettings('node', 'FeedsNodeProcessor', array(
155
      'bundle' => $this->contentType,
156
      'language' => 'en',
157
    ));
158

    
159
    // Add language neutral mappings.
160
    $this->addMappings('node', array(
161
      0 => array(
162
        'source' => 'guid',
163
        'target' => 'guid',
164
        'unique' => 1,
165
      ),
166
      1 => array(
167
        'source' => 'title',
168
        'target' => 'title',
169
      ),
170
    ));
171
  }
172

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

    
187
    // Add French mappers.
188
    $mappings = $this->getMappingsInLanguage('fr', $index);
189
    // Append "_fr" to each source name.
190
    foreach ($mappings as &$mapping) {
191
      $mapping['source'] .= '_fr';
192
    }
193
    $this->addMappings('node', $mappings);
194

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

    
199
    // Load node.
200
    $node = node_load(1, NULL, TRUE);
201

    
202
    // Inspect availability of English values.
203
    $english = $this->getEnglishValues($node) + array(
204
      'field_category' => array(
205
        'expected' => 1,
206
        'actual' => $node->field_category['en'][0]['tid'],
207
      ),
208
    );
209
    foreach ($english as $field_name => $value) {
210
      $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'])));
211
    }
212

    
213
    // Inspect availability of French values.
214
    $french = $this->getFrenchValues($node) + array(
215
      'field_category' => array(
216
        'expected' => 2,
217
        'actual' => $node->field_category['fr'][0]['tid'],
218
      ),
219
    );
220
    foreach ($french as $field_name => $value) {
221
      $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'])));
222
    }
223
  }
224

    
225
  /**
226
   * Tests if values of fields in other languages are kept when not importing
227
   * in that language.
228
   */
229
  public function testChangedLanguageImport() {
230
    // Add Dutch language.
231
    $this->addLanguage('nl', 'Dutch');
232

    
233
    // Import an item first in the Dutch language.
234
    $this->setSettings('node', 'FeedsNodeProcessor', array(
235
      'language' => 'nl',
236
    ));
237
    $mappings = $this->getMappingsInLanguage('nl', 2);
238
    $this->addMappings('node', $mappings);
239
    $this->importFile('node', $this->absolutePath() . '/tests/feeds/multilingual_nl.csv');
240
    $this->assertText(t('Created 1 node'));
241

    
242
    // Assert that Dutch values were created.
243
    $node = node_load(1, NULL, TRUE);
244
    $dutch = $this->getDutchValues($node) + array(
245
      'field_category' => array(
246
        'expected' => 1,
247
        'actual' => $node->field_category['nl'][0]['tid'],
248
      ),
249
    );
250
    foreach ($dutch as $field_name => $value) {
251
      $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'])));
252
    }
253

    
254
    // Set import to update existing nodes.
255
    $this->setSettings('node', 'FeedsNodeProcessor', array(
256
      'update_existing' => FEEDS_UPDATE_EXISTING,
257
    ));
258

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

    
271
    // Assert that French values were created.
272
    $node = node_load(1, NULL, TRUE);
273
    $french = $this->getFrenchValues($node) + array(
274
      'field_category' => array(
275
        'expected' => 2,
276
        'actual' => $node->field_category['fr'][0]['tid'],
277
      ),
278
    );
279
    foreach ($french as $field_name => $value) {
280
      $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'])));
281
    }
282

    
283
    // Assert that Dutch values still exist.
284
    $dutch = $this->getDutchValues($node) + array(
285
      'field_category' => array(
286
        'expected' => 1,
287
        'actual' => $node->field_category['nl'][0]['tid'],
288
      ),
289
    );
290
    foreach ($dutch as $field_name => $value) {
291
      $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'])));
292
    }
293
  }
294

    
295
  /**
296
   * Tests if values of fields in other languages are kept when not importing
297
   * in that language for nodes that were not created by Feeds.
298
   */
299
  public function testChangedLanguageImportForExistingNode() {
300
    // Add Dutch language.
301
    $this->addLanguage('nl', 'Dutch');
302

    
303
    // Date settings.
304
    foreach (array('datestamp', 'datetime') as $field) {
305
      $field = 'field_' . $field;
306
      $edit = array(
307
        'field[settings][granularity][second]' => 1,
308
      );
309
      $this->drupalPost('admin/structure/types/manage/' . $this->contentType . '/fields/' . $field . '/field-settings', $edit, 'Save field settings');
310
    }
311

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

    
330
    // Create a node with Dutch values.
331
    $edit = array(
332
      'title' => 'Teste Feeds Multilingue 1',
333
      'body[und][0][value]' => 'Dit is de berichttekst',
334
      'field_date[und][0][value][date]' => '07/29/1985',
335
      'field_datestamp[und][0][value][date]' => '07/29/1985 - 04:48:12',
336
      'field_datetime[und][0][value][date]' => '07/29/1985 - 04:48:12',
337
      'field_link[und][0][url]' => 'http://google.nl',
338
      'field_list_boolean[und]' => '1',
339
      'field_number_decimal[und][0][value]' => '30.3',
340
      'field_number_float[und][0][value]' => '30.2795',
341
      'field_number_integer[und][0][value]' => '30',
342
      'field_text[und][0][value]' => 'Wortelen',
343
      'files[field_image_und_0]' => drupal_realpath('public://images/attersee.jpeg'),
344
      'field_category[und]' => 'Nieuws',
345
      'language' => 'nl',
346
    );
347
    $this->drupalPost('node/add/' . $this->contentType, $edit, t('Save'));
348
    // Add alt/title to the image.
349
    $edit = array(
350
      'field_image[nl][0][alt]' => 'Bij het zien',
351
      'field_image[nl][0][title]' => 'Bij het zien van de groene vloeistof',
352
    );
353
    $this->drupalPost('node/1/edit/nl', $edit, t('Save'));
354
    $this->drupalGet('node/1/edit/nl');
355

    
356
    // Assert that the Dutch values were put in as expected.
357
    $node = node_load(1, NULL, TRUE);
358
    $dutch = $this->getDutchValues($node) + array(
359
      'field_category' => array(
360
        'expected' => 1,
361
        'actual' => $node->field_category['nl'][0]['tid'],
362
      ),
363
    );
364
    foreach ($dutch as $field_name => $value) {
365
      $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'])));
366
    }
367

    
368
    // Change unique target from guid (0) to title (1).
369
    $path = 'admin/structure/feeds/node/mapping';
370
    $this->drupalPostAJAX($path, array(), 'mapping_settings_edit_0');
371
    $edit = array("config[0][settings][unique]" => FALSE);
372
    $this->drupalPostAJAX(NULL, $edit, 'mapping_settings_update_0');
373
    $this->drupalPost(NULL, array(), t('Save'));
374
    $this->drupalPostAJAX($path, array(), 'mapping_settings_edit_1');
375
    $edit = array("config[1][settings][unique]" => 1);
376
    $this->drupalPostAJAX(NULL, $edit, 'mapping_settings_update_1');
377
    $this->drupalPost(NULL, array(), t('Save'));
378

    
379
    // Update this item with Feeds.
380
    $this->setSettings('node', 'FeedsNodeProcessor', array(
381
      'update_existing' => FEEDS_UPDATE_EXISTING,
382
    ));
383
    $this->addMappings('node', $this->getMappingsInLanguage('fr'));
384
    $this->importFile('node', $this->absolutePath() . '/tests/feeds/multilingual_fr.csv');
385
    $this->assertText(t('Updated 1 node'));
386

    
387
    // Assert that French values were created.
388
    $node = node_load(1, NULL, TRUE);
389
    $french = $this->getFrenchValues($node) + array(
390
      'field_category' => array(
391
        'expected' => 2,
392
        'actual' => $node->field_category['fr'][0]['tid'],
393
      ),
394
    );
395
    foreach ($french as $field_name => $value) {
396
      $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'])));
397
    }
398

    
399
    // Assert that Dutch values still exist.
400
    $dutch = $this->getDutchValues($node) + array(
401
      'field_category' => array(
402
        'expected' => 1,
403
        'actual' => $node->field_category['nl'][0]['tid'],
404
      ),
405
    );
406
    foreach ($dutch as $field_name => $value) {
407
      $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'])));
408
    }
409
  }
410

    
411
  /**
412
   * Tests if fields still are imported in their language when the
413
   * entity_translation module gets disabled.
414
   *
415
   * The entity_translation module is mainly an UI module for configuring field
416
   * language and disabling that module should not have effect on importing
417
   * values in a specific language for fields.
418
   */
419
  public function testWithDisabledEntityTranslationModule() {
420
    module_disable(array('entity_translation'));
421
    // Make sure that entity info is reset.
422
    drupal_flush_all_caches();
423
    drupal_static_reset();
424

    
425
    // Configure importer to import in French language.
426
    $this->setSettings('node', 'FeedsNodeProcessor', array(
427
      'language' => 'fr',
428
    ));
429
    $this->addMappings('node', $this->getMappingsInLanguage('fr'));
430

    
431
    // Import content.
432
    $this->importFile('node', $this->absolutePath() . '/tests/feeds/multilingual_fr.csv');
433
    $this->assertText(t('Created 1 node'));
434

    
435
    // Assert that the fields were all created in French.
436
    $node = node_load(1, NULL, TRUE);
437
    $french = $this->getFrenchValues($node) + array(
438
      'field_category' => array(
439
        'expected' => 1,
440
        'actual' => $node->field_category['fr'][0]['tid'],
441
      ),
442
    );
443
    foreach ($french as $field_name => $value) {
444
      $this->assertEqual($value['expected'], $value['actual'], format_string('The field %field has the expected value (actual: @actual).', array('%field' => $field_name, '@actual' => $value['actual'])));
445
    }
446
  }
447

    
448
  /**
449
   * Tests if fields are still imported in their language when the
450
   * entity_translation module gets uninstalled.
451
   *
452
   * @see testWithDisabledEntityTranslationModule()
453
   */
454
  public function testWithUninstalledEntityTranslationModule() {
455
    module_disable(array('entity_translation'));
456
    drupal_uninstall_modules(array('entity_translation'));
457
    // Make sure that entity info is reset.
458
    drupal_flush_all_caches();
459
    drupal_static_reset();
460

    
461
    // Configure importer to import in French language.
462
    $this->setSettings('node', 'FeedsNodeProcessor', array(
463
      'language' => 'fr',
464
    ));
465
    $this->addMappings('node', $this->getMappingsInLanguage('fr'));
466

    
467
    // Import content.
468
    $this->importFile('node', $this->absolutePath() . '/tests/feeds/multilingual_fr.csv');
469
    $this->assertText(t('Created 1 node'));
470

    
471
    // Assert that the fields were all created in French.
472
    $node = node_load(1, NULL, TRUE);
473
    $french = $this->getFrenchValues($node) + array(
474
      'field_category' => array(
475
        'expected' => 1,
476
        'actual' => $node->field_category['fr'][0]['tid'],
477
      ),
478
    );
479
    foreach ($french as $field_name => $value) {
480
      $this->assertEqual($value['expected'], $value['actual'], format_string('The field %field has the expected value (actual: @actual).', array('%field' => $field_name, '@actual' => $value['actual'])));
481
    }
482
  }
483

    
484
  /**
485
   * Tests if fields are imported in LANGUAGE_NONE if the field's language gets
486
   * disabled after configuring.
487
   */
488
  public function testDisabledLanguage() {
489
    // Configure importer to import in French language.
490
    $this->setSettings('node', 'FeedsNodeProcessor', array(
491
      'language' => 'fr',
492
    ));
493
    $this->addMappings('node', $this->getMappingsInLanguage('fr'));
494

    
495
    // Now disable the French language.
496
    $path = 'admin/config/regional/language';
497
    $edit = array(
498
      'enabled[fr]' => FALSE,
499
    );
500
    $this->drupalPost($path, $edit, t('Save configuration'));
501
    // Reset static cache to update the available languages.
502
    drupal_static_reset();
503

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

    
507
    // Import content.
508
    $this->importFile('node', $this->absolutePath() . '/tests/feeds/multilingual_fr.csv');
509
    $this->assertText(t('Created 1 node'));
510

    
511
    // Assert that the fields were all created in LANGUAGE_NONE.
512
    $node = node_load(1, NULL, TRUE);
513
    $french = $this->getFrenchValues($node, LANGUAGE_NONE) + array(
514
      'field_category' => array(
515
        'expected' => 1,
516
        'actual' => $node->field_category[LANGUAGE_NONE][0]['tid'],
517
      ),
518
    );
519
    foreach ($french as $field_name => $value) {
520
      $this->assertEqual($value['expected'], $value['actual'], format_string('The field %field has the expected value (actual: @actual).', array('%field' => $field_name, '@actual' => $value['actual'])));
521
    }
522
  }
523

    
524
  /**
525
   * Tests if fields are imported in LANGUAGE_NONE if the field's language gets
526
   * removed after configuring.
527
   */
528
  public function testRemovedLanguage() {
529
    // Configure importer to import in French language.
530
    $this->setSettings('node', 'FeedsNodeProcessor', array(
531
      'language' => 'fr',
532
    ));
533
    $this->addMappings('node', $this->getMappingsInLanguage('fr'));
534

    
535
    // Now remove the French language.
536
    $path = 'admin/config/regional/language/delete/fr';
537
    $this->drupalPost($path, array(), t('Delete'));
538
    // Reset static cache to update the available languages.
539
    drupal_static_reset();
540

    
541
    // Import content.
542
    $this->importFile('node', $this->absolutePath() . '/tests/feeds/multilingual_fr.csv');
543
    $this->assertText(t('Created 1 node'));
544

    
545
    // Assert that the fields were all created in LANGUAGE_NONE.
546
    $node = node_load(1, NULL, TRUE);
547
    $french = $this->getFrenchValues($node, LANGUAGE_NONE) + array(
548
      'field_category' => array(
549
        'expected' => 1,
550
        'actual' => $node->field_category[LANGUAGE_NONE][0]['tid'],
551
      ),
552
    );
553
    foreach ($french as $field_name => $value) {
554
      $this->assertEqual($value['expected'], $value['actual'], format_string('The field %field has the expected value (actual: @actual).', array('%field' => $field_name, '@actual' => $value['actual'])));
555
    }
556
  }
557

    
558
  /**
559
   * Tests if autocreated terms are in the language that was set on the target configuration
560
   * in case the taxonomy is multilingual.
561
   */
562
  public function testAutocreatedTermLanguage() {
563
    module_enable(array('i18n_taxonomy'));
564
    // Make sure that entity info is reset.
565
    drupal_flush_all_caches();
566
    drupal_static_reset();
567

    
568
    // Enable multilingual taxonomy.
569
    $edit = array('i18n_mode' => 4);
570
    $this->drupalPost('admin/structure/taxonomy/categories/edit', $edit, 'Save');
571

    
572
    // Configure importer to import in French language.
573
    $this->setSettings('node', 'FeedsNodeProcessor', array(
574
      'language' => 'fr',
575
    ));
576
    $this->addMappings('node', array(
577
      2 => array(
578
        'source' => 'term',
579
        'target' => 'field_category',
580
        'autocreate' => TRUE,
581
        'field_language' => 'fr',
582
      ),
583
    ));
584

    
585
    // Import French item.
586
    $this->importFile('node', $this->absolutePath() . '/tests/feeds/multilingual_fr.csv');
587
    $this->assertText(t('Created 1 node'));
588

    
589
    // Assert that the created term is in the French language.
590
    $term = taxonomy_term_load(1);
591
    $this->assertEqual('fr', entity_language('taxonomy_term', $term));
592
  }
593

    
594
  /**
595
   * Tests if values are cleared out when an empty value or no value is
596
   * provided.
597
   */
598
  public function testClearOutValues() {
599
    // Set to update existing nodes.
600
    $this->setSettings('node', 'FeedsNodeProcessor', array(
601
      'update_existing' => FEEDS_UPDATE_EXISTING,
602
    ));
603

    
604
    // Add English mappers.
605
    $index = 2;
606
    $mappings = $this->getMappingsInLanguage('en', $index);
607
    // Append "_en" to each source name.
608
    foreach ($mappings as &$mapping) {
609
      $mapping['source'] .= '_en';
610
    }
611
    $this->addMappings('node', $mappings);
612
    $index += count($mappings);
613

    
614
    // Add French mappers.
615
    $mappings = $this->getMappingsInLanguage('fr', $index);
616
    // Append "_fr" to each source name.
617
    foreach ($mappings as &$mapping) {
618
      $mapping['source'] .= '_fr';
619
    }
620
    $this->addMappings('node', $mappings);
621

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

    
626
    // Now import a file where the French remained, but the English values were
627
    // removed.
628
    $this->importFile('node', $this->absolutePath() . '/tests/feeds/multilingual_en_fr_empty.csv');
629
    $this->assertText(t('Updated 1 node'));
630

    
631
    // Load node.
632
    $node = node_load(1, NULL, TRUE);
633

    
634
    // Check that the English values are gone, but the French values are still
635
    // there.
636
    $fields = array(
637
      'body',
638
      'field_date',
639
      'field_datestamp',
640
      'field_datetime',
641
      'field_image',
642
      'field_link',
643
      'field_list_boolean',
644
      'field_number_decimal',
645
      'field_number_float',
646
      'field_number_integer',
647
      'field_category',
648
      'field_text',
649
    );
650
    foreach ($fields as $field_name) {
651
      $this->assertTrue(empty($node->{$field_name}['en']), format_string('The field %field is empty.', array('%field' => $field_name)));
652
    }
653

    
654
    // Inspect availability of French values.
655
    $french = $this->getFrenchValues($node) + array(
656
      'field_category' => array(
657
        'expected' => 2,
658
        'actual' => $node->field_category['fr'][0]['tid'],
659
      ),
660
    );
661
    // Since the image was placed on the node again, its file name is now
662
    // "la fayette_0.jpeg."
663
    $french['field_image']['expected'] = 'la fayette_0.jpeg';
664
    foreach ($french as $field_name => $value) {
665
      $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'])));
666
    }
667
  }
668

    
669
  /**
670
   * Tests if values are cleared out when an empty value is provided for a
671
   * language that got disabled.
672
   */
673
  public function testClearOutValuesWithDisabledLanguage() {
674
    // Set to update existing nodes.
675
    $this->setSettings('node', 'FeedsNodeProcessor', array(
676
      'update_existing' => FEEDS_UPDATE_EXISTING,
677
    ));
678

    
679
    // Configure importer to import in French language.
680
    $this->setSettings('node', 'FeedsNodeProcessor', array(
681
      'language' => 'fr',
682
    ));
683
    $this->addMappings('node', $this->getMappingsInLanguage('fr'));
684

    
685
    // Now disable the French language.
686
    $path = 'admin/config/regional/language';
687
    $edit = array(
688
      'enabled[fr]' => FALSE,
689
    );
690
    $this->drupalPost($path, $edit, t('Save configuration'));
691

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

    
695
    // Import content. Since the French language was disabled, the content
696
    // should be imported as LANGUAGE_NONE.
697
    // @see ::testDisabledLanguage()
698
    $this->importFile('node', $this->absolutePath() . '/tests/feeds/multilingual_fr.csv');
699
    $this->assertText(t('Created 1 node'));
700

    
701
    // Now import a file with empty values.
702
    $this->importFile('node', $this->absolutePath() . '/tests/feeds/multilingual_empty.csv');
703
    $this->assertText(t('Updated 1 node'));
704

    
705
    // Load node.
706
    $node = node_load(1, NULL, TRUE);
707

    
708
    // Check that the values in LANGUAGE_NONE are gone.
709
    $fields = array(
710
      'body',
711
      'field_date',
712
      'field_datestamp',
713
      'field_datetime',
714
      'field_image',
715
      'field_link',
716
      'field_list_boolean',
717
      'field_number_decimal',
718
      'field_number_float',
719
      'field_number_integer',
720
      'field_category',
721
      'field_text',
722
    );
723
    foreach ($fields as $field_name) {
724
      $this->assertTrue(empty($node->{$field_name}[LANGUAGE_NONE]), format_string('The field %field is empty.', array('%field' => $field_name)));
725
    }
726
  }
727

    
728
  /**
729
   * Adds a language to test with.
730
   *
731
   * @param string $langcode
732
   *   The language's langcode.
733
   * @param string $label
734
   *   The language human readable name.
735
   */
736
  protected function addLanguage($langcode, $label) {
737
    $edit = array(
738
      'langcode' => $langcode,
739
    );
740
    $this->drupalPost('admin/config/regional/language/add', $edit, t('Add language'));
741
    $this->assertText(format_string('The language @language has been created and can now be used.', array('@language' => $label)));
742
  }
743

    
744
  /**
745
   * Sets given content type and fields to be translatable.
746
   *
747
   * @param string $typename
748
   *   The machine name of the node type.
749
   * @param array $field_names
750
   *   The fields to enable multilingual support for.
751
   */
752
  protected function setupMultilingual($typename, array $field_names) {
753
    // Enable entity field translation for content type.
754
    $edit = array(
755
      'language_content_type' => 4,
756
      'entity_translation_hide_translation_links' => 1,
757
      'entity_translation_node_metadata' => 0,
758
    );
759
    $this->drupalPost('admin/structure/types/manage/' . $typename, $edit, t('Save content type'));
760

    
761
    // Enable field translation on fields.
762
    $edit = array(
763
      'field[translatable]' => 1,
764
    );
765
    foreach ($field_names as $field_name) {
766
      $this->drupalPost("admin/structure/types/manage/{$typename}/fields/{$field_name}", $edit, t('Save settings'));
767
    }
768

    
769
    // Reset static cache so that all languages are available when
770
    // field_available_languages() is called during node_load().
771
    drupal_static_reset();
772
  }
773

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

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

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

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