Projet

Général

Profil

Paste
Télécharger (10,6 ko) Statistiques
| Branche: | Révision:

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

1
<?php
2

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

    
8
/**
9
 * Tests the CSV parser using the UI.
10
 */
11
class FeedsCSVParserTestCase extends FeedsWebTestCase {
12

    
13
  /**
14
   * {@inheritdoc}
15
   */
16
  public static function getInfo() {
17
    return array(
18
      'name' => 'CSV parser functional tests',
19
      'description' => 'Tests the CSV parser using the UI.',
20
      'group' => 'Feeds',
21
    );
22
  }
23

    
24
  /**
25
   * Tests parsing a CSV when the mbstring extension is not available.
26
   */
27
  public function testMbstringExtensionDisabled() {
28
    // Set "feeds_use_mbstring" to FALSE to emulate that the mbstring extension
29
    // is not loaded.
30
    variable_set('feeds_use_mbstring', FALSE);
31

    
32
    // Remove items after parsing because in < PHP 5.4 processing items with
33
    // encoding issues leads to test failures because check_plain() can only
34
    // handle UTF-8 encoded strings.
35
    // @see feeds_tests_feeds_after_parse()
36
    variable_set('feeds_tests_feeds_after_parse_empty_items', TRUE);
37

    
38
    // Create node type.
39
    $node_type = $this->drupalCreateContentType();
40

    
41
    // Create and configure importer.
42
    $this->createImporterConfiguration('Content CSV', 'csv');
43
    $this->setPlugin('csv', 'FeedsFileFetcher');
44
    $this->setPlugin('csv', 'FeedsCSVParser');
45
    $this->setSettings('csv', 'FeedsNodeProcessor', array('bundle' => $node_type->type));
46
    $this->addMappings('csv', array(
47
      0 => array(
48
        'source' => 'id',
49
        'target' => 'guid',
50
      ),
51
      1 => array(
52
        'source' => 'text',
53
        'target' => 'title',
54
      ),
55
    ));
56

    
57
    // Ensure that on the CSV parser settings page a message is shown about that
58
    // the mbstring extension is not available.
59
    $this->drupalGet('admin/structure/feeds/csv/settings/FeedsCSVParser');
60
    $this->assertNoField('encoding');
61
    $this->assertText('PHP mbstring extension must be available for character encoding conversion.');
62

    
63
    // Try to import a CSV file that is not UTF-8 encoded. No encoding warning
64
    // should be shown, but import should fail.
65
    $this->importFile('csv', $this->absolutePath() . '/tests/feeds/encoding_SJIS.csv');
66
    $this->assertNoText('Source file is not in UTF-8 encoding.');
67
  }
68

    
69
  /**
70
   * Tests an encoding failure during parsing a CSV.
71
   */
72
  public function testEncodingFailure() {
73
    // Create node type.
74
    $node_type = $this->drupalCreateContentType();
75

    
76
    // Create and configure importer.
77
    $this->createImporterConfiguration('Content CSV', 'csv');
78
    $this->setPlugin('csv', 'FeedsFileFetcher');
79
    $this->setPlugin('csv', 'FeedsCSVParser');
80
    $this->setSettings('csv', 'FeedsNodeProcessor', array('bundle' => $node_type->type));
81
    $this->addMappings('csv', array(
82
      0 => array(
83
        'source' => 'id',
84
        'target' => 'guid',
85
      ),
86
      1 => array(
87
        'source' => 'text',
88
        'target' => 'title',
89
      ),
90
    ));
91

    
92
    // Ensure that on the CSV parser settings page a setting for encoding is
93
    // shown.
94
    $this->drupalGet('admin/structure/feeds/csv/settings/FeedsCSVParser');
95
    $this->assertField('encoding');
96
    $this->assertNoText('PHP mbstring extension must be available for character encoding conversion.');
97

    
98
    // Try to import a CSV file that is not UTF-8 encoded. Import should be
99
    // halted and an encoding warning should be shown.
100
    $this->importFile('csv', $this->absolutePath() . '/tests/feeds/encoding_SJIS.csv');
101
    $this->assertNoText('Failed importing 4 nodes.');
102
    $this->assertText('Source file is not in UTF-8 encoding.');
103
  }
104

    
105
  /**
106
   * Tests if a CSV template is generated properly using various settings.
107
   *
108
   * @see ::getTemplateDataProvider()
109
   */
110
  public function testGetTemplate() {
111
    // Create node type.
112
    $node_type = $this->drupalCreateContentType();
113

    
114
    foreach ($this->getTemplateDataProvider() as $key => $testdata) {
115
      // Prepend 'csv' to importer machine name as '0' is not a valid machine
116
      // name.
117
      $key = 'csv' . $key;
118

    
119
      // Create and configure importer.
120
      $this->createImporterConfiguration('Content CSV', $key);
121
      $this->setPlugin($key, 'FeedsCSVParser');
122
      $this->setSettings($key, 'FeedsCSVParser', array(
123
        'delimiter' => $testdata['delimiter'],
124
      ));
125
      $this->setSettings($key, 'FeedsNodeProcessor', array('bundle' => $node_type->type));
126
      $this->addMappings($key, $testdata['mapping']);
127

    
128
      // Get CSV template and assert result.
129
      $this->drupalGet('import/' . $key . '/template');
130
      $this->assertRaw($testdata['expected']);
131

    
132
      // Check texts that are displayed on the import page. These texts in the
133
      // content should have gone through to check_plain() so we do that here as
134
      // well.
135
      $this->drupalGet('import/' . $key);
136
      $this->assertText('Import CSV files with one or more of these columns: ' . check_plain($testdata['texts']['columns']) . '.');
137
      if (isset($testdata['texts']['unique'])) {
138
        $this->assertText(check_plain($testdata['texts']['unique']));
139
      }
140
      else {
141
        $this->assertText(t('No columns are unique. The import will only create new items, no items will be updated.'));
142
      }
143
    }
144
  }
145

    
146
  /**
147
   * Data provider for ::testGetTemplate().
148
   */
149
  protected function getTemplateDataProvider() {
150
    return array(
151
      // Delimiter ',' test. Source keys containing a ',' should be wrapped in
152
      // quotes.
153
      array(
154
        'delimiter' => ',',
155
        'mapping' => array(
156
          array(
157
            'source' => 'title+;|',
158
            'target' => 'title',
159
          ),
160
          array(
161
            'source' => 'alpha, beta + gamma',
162
            'target' => 'body',
163
          ),
164
          array(
165
            'source' => 'guid',
166
            'target' => 'guid',
167
          ),
168
        ),
169
        'expected' => 'title+;|,"alpha, beta + gamma",guid',
170
        'texts' => array(
171
          'columns' => 'title+;|, "alpha, beta + gamma", guid',
172
        ),
173
      ),
174

    
175
      // Delimiter ';' test. Source keys containing a ';' should be wrapped in
176
      // quotes.
177
      array(
178
        'delimiter' => ';',
179
        'mapping' => array(
180
          array(
181
            'source' => 'title;)',
182
            'target' => 'title',
183
          ),
184
          array(
185
            'source' => 'alpha, beta + gamma',
186
            'target' => 'body',
187
          ),
188
          array(
189
            'source' => 'guid',
190
            'target' => 'guid',
191
          ),
192
        ),
193
        'expected' => '"title;)";alpha, beta + gamma;guid',
194
        'texts' => array(
195
          'columns' => 'title;), "alpha, beta + gamma", guid',
196
        ),
197
      ),
198

    
199
      // Delimiter 'TAB' test.
200
      array(
201
        'delimiter' => 'TAB',
202
        'mapping' => array(
203
          array(
204
            'source' => 'title,;|',
205
            'target' => 'title',
206
          ),
207
          array(
208
            'source' => 'alpha, beta + gamma',
209
            'target' => 'body',
210
          ),
211
          array(
212
            'source' => 'guid',
213
            'target' => 'guid',
214
          ),
215
        ),
216
        'expected' => 'title,;|	alpha, beta + gamma	guid',
217
        'texts' => array(
218
          'columns' => '"title,;|", "alpha, beta + gamma", guid',
219
        ),
220
      ),
221

    
222
      // Delimiter '|' test. Source keys containing a '|' should be wrapped in
223
      // quotes.
224
      array(
225
        'delimiter' => '|',
226
        'mapping' => array(
227
          array(
228
            'source' => 'title+;,',
229
            'target' => 'title',
230
          ),
231
          array(
232
            'source' => 'alpha|beta|gamma',
233
            'target' => 'body',
234
          ),
235
          array(
236
            'source' => 'guid',
237
            'target' => 'guid',
238
          ),
239
        ),
240
        'expected' => 'title+;,|"alpha|beta|gamma"|guid',
241
        'texts' => array(
242
          'columns' => '"title+;,", alpha|beta|gamma, guid',
243
        ),
244
      ),
245

    
246
      // Delimiter '+' test. Source keys containing a '+' should be wrapped in
247
      // quotes.
248
      array(
249
        'delimiter' => '+',
250
        'mapping' => array(
251
          array(
252
            'source' => 'title,;|',
253
            'target' => 'title',
254
          ),
255
          array(
256
            'source' => 'alpha, beta + gamma',
257
            'target' => 'body',
258
          ),
259
          array(
260
            'source' => 'guid',
261
            'target' => 'guid',
262
          ),
263
        ),
264
        'expected' => 'title,;|+"alpha, beta + gamma"+guid',
265
        'texts' => array(
266
          'columns' => '"title,;|", "alpha, beta + gamma", guid',
267
        ),
268
      ),
269

    
270
      // Ensure that when a source key is used multiple times in mapping, the
271
      // key is only printed once in the CSV template.
272
      array(
273
        'delimiter' => ',',
274
        'mapping' => array(
275
          array(
276
            'source' => 'text',
277
            'target' => 'title',
278
            'unique' => TRUE,
279
          ),
280
          array(
281
            'source' => 'guid',
282
            'target' => 'guid',
283
            'unique' => TRUE,
284
          ),
285
          array(
286
            'source' => 'date',
287
            'target' => 'created',
288
          ),
289
          array(
290
            'source' => 'date',
291
            'target' => 'changed',
292
          ),
293
          array(
294
            'source' => 'text',
295
            'target' => 'body',
296
          ),
297
        ),
298
        'expected' => 'text,guid,date',
299
        'texts' => array(
300
          'columns' => 'text, guid, date',
301
          'unique' => 'Columns text, guid are mandatory and values in these columns are considered unique',
302
        ),
303
      ),
304

    
305
      // Special characters. Things like '&' shouldn't be converted to '&amp;'
306
      // for example.
307
      array(
308
        'delimiter' => ',',
309
        'mapping' => array(
310
          array(
311
            'source' => '&',
312
            'target' => 'title',
313
            'unique' => TRUE,
314
          ),
315
          array(
316
            'source' => 'alpha&beta',
317
            'target' => 'body',
318
          ),
319
          array(
320
            'source' => '<created>',
321
            'target' => 'created',
322
          ),
323
          array(
324
            'source' => '\'guid\'',
325
            'target' => 'guid',
326
          ),
327
        ),
328
        'expected' => '&,alpha&beta,<created>,\'guid\'',
329
        'texts' => array(
330
          'columns' => '&, alpha&beta, <created>, \'guid\'',
331
          'unique' => 'Column & is mandatory and considered unique',
332
        ),
333
      ),
334

    
335
      // Blank sources (source which name only contains spaces) should not end
336
      // up in the template, but a zero should.
337
      array(
338
        'delimiter' => ',',
339
        'mapping' => array(
340
          array(
341
            'source' => '0',
342
            'target' => 'body',
343
          ),
344
          array(
345
            'source' => ' ',
346
            'target' => 'guid',
347
            'unique' => TRUE,
348
          ),
349
        ),
350
        'expected' => '0',
351
        'texts' => array(
352
          'columns' => '0',
353
        ),
354
      ),
355
    );
356
  }
357

    
358
}