Projet

Général

Profil

Paste
Télécharger (23,8 ko) Statistiques
| Branche: | Révision:

root / drupal7 / sites / all / modules / feeds / tests / feeds_fetcher_http.test @ ec2b0e7b

1
<?php
2

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

    
8
/**
9
 * HTTP fetcher test class.
10
 */
11
class FeedsFileHTTPTestCase extends FeedsWebTestCase {
12
  public static function getInfo() {
13
    return array(
14
      'name' => 'Fetcher: HTTP',
15
      'description' => 'Tests for file http fetcher plugin.',
16
      'group' => 'Feeds',
17
    );
18
  }
19

    
20
  /**
21
   * {@inheritdoc}
22
   */
23
  public function setUp() {
24
    parent::setUp();
25

    
26
    // Include FeedsProcessor.inc so processor related constants are available.
27
    module_load_include('inc', 'feeds', 'plugins/FeedsProcessor');
28

    
29
    // Do not use curl as that will result into HTTP requests returning a 404.
30
    variable_set('feeds_never_use_curl', TRUE);
31
  }
32

    
33
  /**
34
   * Setup importer to import items from testing/feeds/nodes.csv.
35
   */
36
  public function setUpImporter() {
37
    // Set up an importer.
38
    $this->createImporterConfiguration('Node import', 'node');
39
    $this->setSettings('node', NULL, array(
40
      'content_type' => '',
41
      'import_period' => 0,
42
    ));
43
    $this->setPlugin('node', 'FeedsHTTPFetcher');
44
    $this->setPlugin('node', 'FeedsCSVParser');
45
    $this->setSettings('node', 'FeedsNodeProcessor', array(
46
      'update_existing' => FEEDS_UPDATE_EXISTING,
47
    ));
48
    $this->addMappings('node', array(
49
      0 => array(
50
        'source' => 'title',
51
        'target' => 'title',
52
        'unique' => TRUE,
53
      ),
54
      1 => array(
55
        'source' => 'body',
56
        'target' => 'body',
57
      ),
58
    ));
59
  }
60

    
61
  /**
62
   * Configures the evironment so that multiple cron runs are needed to complete
63
   * an import.
64
   *
65
   * @param string $source_url
66
   *   The URL of the file to import.
67
   */
68
  protected function setUpMultipleCronRuns($source_url) {
69
    // Process 5 items per batch.
70
    variable_set('feeds_process_limit', 5);
71

    
72
    // Set variable to enforce that only five items get imported per cron run.
73
    // @see feeds_tests_cron_queue_alter()
74
    // @see feeds_tests_feeds_after_save()
75
    variable_set('feeds_tests_feeds_source_import_queue_time', 5);
76
    variable_set('feeds_tests_feeds_after_save_sleep', 1);
77

    
78
    // Set up importer.
79
    $this->setUpImporter();
80
    // Only import during cron runs, not immediately.
81
    $this->setSettings('node', NULL, array(
82
      'import_on_create' => FALSE,
83
    ));
84

    
85
    // Set source file to import.
86
    $edit = array(
87
      'feeds[FeedsHTTPFetcher][source]' => $source_url,
88
    );
89
    $this->drupalPost('import/node', $edit, t('Schedule import'));
90

    
91
    // Ensure that no nodes have been created yet.
92
    $this->assertNodeCount(0, 'No nodes have been created yet (actual: @count).');
93
  }
94

    
95
  /**
96
   * Returns the file in the Feeds in_progress directory.
97
   *
98
   * @return object
99
   *   The found file.
100
   *
101
   * @throws Exception
102
   *   In case no file was found, so the test can abort without issuing a fatal
103
   *   error.
104
   */
105
  protected function getInProgressFile() {
106
    // Assert that a file exists in the in_progress dir.
107
    $files = file_scan_directory('private://feeds/in_progress', '/.*/');
108
    debug($files);
109
    $this->assertEqual(1, count($files), 'The feeds "in progress" dir contains one file.');
110
    if (!count($files)) {
111
      // Abort test.
112
      throw new Exception('File not found.');
113
    }
114
    return reset($files);
115
  }
116

    
117
  /**
118
   * Test the Feed URL form.
119
   */
120
  public function testFormValidation() {
121
    // Set up an importer.
122
    $id = drupal_strtolower($this->randomName());
123
    $this->createImporterConfiguration($this->randomString(), $id);
124

    
125
    // Check that by default, we add http:// to the front of the URL.
126
    $edit = array(
127
      'feeds[FeedsHTTPFetcher][source]' => 'example.com',
128
    );
129
    $this->drupalPost('import/' . $id, $edit, t('Import'));
130
    $this->assertText(t('There are no new nodes.'));
131
    $this->assertFieldByName('feeds[FeedsHTTPFetcher][source]', 'http://example.com');
132

    
133
    $this->setSettings($id, 'FeedsHTTPFetcher', array('auto_scheme' => 'feed'));
134
    $this->drupalPost('import/' . $id, $edit, t('Import'));
135
    $this->assertText(t('There are no new nodes.'));
136
    $this->assertFieldByName('feeds[FeedsHTTPFetcher][source]', 'feed://example.com');
137

    
138
    $this->setSettings($id, 'FeedsHTTPFetcher', array('auto_scheme' => ''));
139
    $this->drupalPost('import/' . $id, $edit, t('Import'));
140
    $this->assertText(t('The URL example.com is invalid.'));
141
    $this->assertFieldByName('feeds[FeedsHTTPFetcher][source]', 'example.com');
142
  }
143

    
144
  /**
145
   * Tests if the result of a http request can be cached on the file system.
146
   *
147
   * When a first request is made, the data is retrieved from the given source
148
   * url and cached on the file system.
149
   * On the second request, send to the same source url, the HTTP header
150
   * "If-Modified-Since" is set. This should result into a 304 HTTP status from
151
   * the source, as the contents did not change in between. In such case, the
152
   * data should be retrieved from the cache.
153
   */
154
  public function testHttpRequestUsingFileCache() {
155
    // Include http request functions.
156
    feeds_include_library('http_request.inc', 'http_request');
157

    
158
    // First request.
159
    $url = url('testing/feeds/nodes.csv', array('absolute' => TRUE));
160
    $result = feeds_http_request($url);
161

    
162
    // Assert that the first request was successful and was not retrieved from
163
    // cache.
164
    $this->assertEqual(200, $result->code, 'Request status code is 200.');
165
    $this->assertTrue(empty($result->from_cache), 'Request was not retrieved from cache.');
166
    // Assert that a file was created.
167
    $file_url = 'private://feeds/cache/' . hash('sha256', $url);
168
    $this->assertTrue(file_exists($file_url), format_string('The file @file_url exists.', array(
169
      '@file_url' => $file_url,
170
    )));
171

    
172
    // Reset feeds_http_request() static cache.
173
    drupal_static_reset('feeds_http_request');
174

    
175
    // Write some garbage to the cached file to ensure that the cache is
176
    // retrieved from that file.
177
    $garbage = static::randomString(100);
178
    file_put_contents($file_url, $garbage);
179

    
180
    // Second request.
181
    $result2 = feeds_http_request($url);
182

    
183
    // Assert that the second request was successful and was retrieved from
184
    // cache.
185
    $this->assertEqual(200, $result2->code, 'Request status code is 200.');
186
    $this->assertTrue(!empty($result2->from_cache), 'Request was retrieved from cache.');
187
    $this->assertEqual($garbage, $result2->data, 'The cache came from the file cache.');
188

    
189
    // Assert that the file is removed when caches are cleared.
190
    drupal_flush_all_caches();
191
    $this->assertFalse(file_exists($file_url), format_string('The file @file_url no longer exists.', array(
192
      '@file_url' => $file_url,
193
    )));
194
  }
195

    
196
  /**
197
   * Tests if the source is refetched when the cached file is manually removed.
198
   *
199
   * A call to feeds_http_request() should always get us data.
200
   */
201
  public function testRefetchWhenCachedFileIsRemoved() {
202
    // Include http request functions.
203
    feeds_include_library('http_request.inc', 'http_request');
204

    
205
    // First request.
206
    $url = url('testing/feeds/nodes.csv', array('absolute' => TRUE));
207
    $result1 = feeds_http_request($url);
208

    
209
    // Assert that the first request was successful and was not retrieved from
210
    // cache.
211
    $this->assertEqual(200, $result1->code, 'Request status code is 200.');
212
    $this->assertTrue(empty($result1->from_cache), 'Request was not retrieved from cache.');
213

    
214
    // Reset feeds_http_request() static cache.
215
    drupal_static_reset('feeds_http_request');
216

    
217
    // Write some garbage to the cached file to ensure that the cache is
218
    // retrieved from that file.
219
    $file_url = 'private://feeds/cache/' . hash('sha256', $url);
220
    $garbage = static::randomString(100);
221
    file_put_contents($file_url, $garbage);
222

    
223
    // Second request.
224
    $result2 = feeds_http_request($url);
225

    
226
    // Assert that the second request was successful and was retrieved from
227
    // cache.
228
    $this->assertEqual(200, $result2->code, 'Request status code is 200.');
229
    $this->assertTrue(!empty($result2->from_cache), 'Request was retrieved from cache.');
230
    $this->assertEqual($garbage, $result2->data, 'The cache came from the file cache.');
231

    
232
    // Now remove the cached file.
233
    drupal_unlink($file_url);
234
    $this->assertFalse(file_exists($file_url), format_string('The file @file_url no longer exists.', array(
235
      '@file_url' => $file_url,
236
    )));
237

    
238
    // Third request.
239
    $result3 = feeds_http_request($url);
240

    
241
    // Assert that the data is refetched, even though the source hasn't changed.
242
    $this->assertEqual(200, $result3->code, 'Request status code is 200.');
243
    $this->assertTrue(empty($result3->from_cache), 'Request was not retrieved from cache.');
244
    $this->assertEqual($result1->data, $result3->data, 'Data is available on the response.');
245
  }
246

    
247
  /**
248
   * Tests that the source isn't fetched twice during the same request.
249
   */
250
  public function testNoRefetchOnSameRequest() {
251
    // Include http request functions.
252
    feeds_include_library('http_request.inc', 'http_request');
253

    
254
    // First request.
255
    $url = url('testing/feeds/nodes.csv', array('absolute' => TRUE));
256
    $result1 = feeds_http_request($url);
257

    
258
    // Set flag that the source has changed.
259
    variable_set('feeds_tests_nodes_changed', TRUE);
260

    
261
    // Second request.
262
    $result2 = feeds_http_request($url);
263

    
264
    // Assert that the result is exactly the same.
265
    $this->assertEqual($result1->data, $result2->data, 'The data was retrieved from cache.');
266

    
267
    // Assert that the data *is* refetched (and different) after a cache clear.
268
    drupal_flush_all_caches();
269
    drupal_static_reset();
270
    $result3 = feeds_http_request($url);
271
    $this->assertNotEqual($result1->data, $result3->data, 'The data is refetched.');
272
  }
273

    
274
  /**
275
   * Tests if the data is not cached when the option for caching is disabled.
276
   */
277
  public function testHTTPCacheDisabled() {
278
    $this->setUpImporter();
279

    
280
    // Disable caching HTTP request result.
281
    $this->setSettings('node', 'FeedsHTTPFetcher', array(
282
      'cache_http_result' => FALSE,
283
    ));
284

    
285
    $source_url = url('testing/feeds/nodes.csv', array('absolute' => TRUE));
286
    $edit = array(
287
      'feeds[FeedsHTTPFetcher][source]' => $source_url,
288
    );
289
    $this->drupalPost('import/node', $edit, t('Import'));
290
    $this->assertText('Created 9 nodes');
291

    
292
    // Assert that no cache entries were created.
293
    $number_of_cache_entries = db_query('SELECT COUNT(cid) FROM {cache_feeds_http}')->fetchField();
294
    $this->assertEqual(0, $number_of_cache_entries, format_string('No cache entries were created in the cache_feeds_http table (actual: @actual).', array(
295
      '@actual' => $number_of_cache_entries,
296
    )));
297

    
298
    // Assert that no cache file was created.
299
    $file_url = 'private://feeds/cache/' . hash('sha256', $source_url);
300
    $this->assertFalse(file_exists($file_url), format_string('The file @file_url does not exist.', array(
301
      '@file_url' => $file_url,
302
    )));
303
  }
304

    
305
  /**
306
   * Tests if the data is cached on the file system even when a different cache
307
   * class is used.
308
   *
309
   * This can happen when using Memcache or Redis for all cache bins.
310
   */
311
  public function testHTTPCacheOverride() {
312
    // Revert back to the default cache class.
313
    variable_set('cache_class_cache_feeds_http', 'DrupalDatabaseCache');
314

    
315
    // Import. We cannot test with a simple feeds_http_request() call here,
316
    // because there is no way to override a cache class on a single request.
317
    // @see _cache_get_object().
318
    $this->setUpImporter();
319
    $source_url = url('testing/feeds/nodes.csv', array('absolute' => TRUE));
320
    $edit = array(
321
      'feeds[FeedsHTTPFetcher][source]' => $source_url,
322
    );
323
    $this->drupalPost('import/node', $edit, t('Import'));
324
    $this->assertText('Created 9 nodes');
325

    
326
    // Assert that the raw data is not saved in the database.
327
    $count = db_select('cache_feeds_http')
328
      ->condition('data', '%Title,Body,published,GUID%', 'LIKE')
329
      ->countQuery()
330
      ->execute()
331
      ->fetchField();
332
    $this->assertEqual(0, $count, 'Raw source was not saved in the database.');
333

    
334
    // Assert that a file was created.
335
    $file_url = 'private://feeds/cache/' . hash('sha256', $source_url);
336
    $this->assertTrue(file_exists($file_url), format_string('The file @file_url exists.', array(
337
      '@file_url' => $file_url,
338
    )));
339
  }
340

    
341
  /**
342
   * Tests if cached files are cleaned up even when a different cache class is
343
   * used.
344
   */
345
  public function testCachedFilesCleanupOnHTTPCacheOverride() {
346
    // Revert back to the default cache class.
347
    variable_set('cache_class_cache_feeds_http', 'DrupalDatabaseCache');
348

    
349
    // Create a real cached file by performing an import.
350
    $this->setUpImporter();
351
    $source_url = url('testing/feeds/nodes.csv', array('absolute' => TRUE));
352
    $edit = array(
353
      'feeds[FeedsHTTPFetcher][source]' => $source_url,
354
    );
355
    $this->drupalPost('import/node', $edit, t('Import'));
356
    $this->assertText('Created 9 nodes');
357
    $file_url_with_cache_record = 'private://feeds/cache/' . hash('sha256', $source_url);
358

    
359
    // Write a dummy cached file.
360
    $dir = 'private://feeds/cache';
361
    $file_url_no_cache_record = $dir . '/abc123';
362
    file_prepare_directory($dir, FILE_CREATE_DIRECTORY);
363
    file_put_contents($file_url_no_cache_record, static::randomString());
364

    
365
    // Trigger cleanup of orphaned cached files.
366
    variable_del('feeds_sync_cache_feeds_http_last_check');
367
    $this->cronRun();
368

    
369
    // Assert that the dummy cached file has been cleaned up and the other file
370
    // still exists.
371
    $this->assertFalse(file_exists($file_url_no_cache_record), format_string('The file @file_url no longer exists.', array(
372
      '@file_url' => $file_url_no_cache_record,
373
    )));
374
    $this->assertTrue(file_exists($file_url_with_cache_record), format_string('The file @file_url still exists.', array(
375
      '@file_url' => $file_url_with_cache_record,
376
    )));
377
  }
378

    
379
  /**
380
   * Tests if the cron task for cleaning up cached files are run one at a time.
381
   */
382
  public function testCachedFilesCleanupQueue() {
383
    $queue = DrupalQueue::get('feeds_sync_cache_feeds_http');
384

    
385
    // First, make sure that a queue task is only ran every six hours.
386
    variable_set('feeds_sync_cache_feeds_http_last_check', REQUEST_TIME);
387

    
388
    // Run cron without executing the queue tasks.
389
    feeds_cron();
390

    
391
    // Assert that no task was created for cleaning up the files.
392
    $this->assertEqual(0, $queue->numberOfItems(), 'No task was created for the feeds_sync_cache_feeds_http queue.');
393

    
394
    // Unset last check and run cron.
395
    variable_del('feeds_sync_cache_feeds_http_last_check');
396
    feeds_cron();
397

    
398
    // Assert that one task was created for cleaning up the files and that the
399
    // variable for the last check was updated.
400
    $this->assertEqual(1, $queue->numberOfItems(), 'One task was created for the feeds_sync_cache_feeds_http queue.');
401
    $this->assertEqual(REQUEST_TIME, variable_get('feeds_sync_cache_feeds_http_last_check'));
402

    
403
    // Unset last check and run cron again.
404
    variable_del('feeds_sync_cache_feeds_http_last_check');
405
    feeds_cron();
406

    
407
    // Assert that there still is one task.
408
    $this->assertEqual(1, $queue->numberOfItems(), 'One task exists for the feeds_sync_cache_feeds_http queue.');
409
    $this->assertEqual(REQUEST_TIME, variable_get('feeds_sync_cache_feeds_http_last_check'));
410
  }
411

    
412
  /**
413
   * Tests if a source is not refetched on a second import when the source did
414
   * not change.
415
   */
416
  public function testSourceCaching() {
417
    $this->setUpImporter();
418

    
419
    $source_url = url('testing/feeds/nodes.csv', array('absolute' => TRUE));
420
    $edit = array(
421
      'feeds[FeedsHTTPFetcher][source]' => $source_url,
422
    );
423
    $this->drupalPost('import/node', $edit, t('Import'));
424

    
425
    $this->assertText('Created 9 nodes');
426

    
427
    // Ensure that the fetched content was cached in a file.
428
    $file_url = 'private://feeds/cache/' . hash('sha256', $source_url);
429
    $this->assertTrue(file_exists($file_url), format_string('The file @file_url exists.', array(
430
      '@file_url' => $file_url,
431
    )));
432

    
433
    // Overwrite cached file, change one item.
434
    $csv = file_get_contents($file_url);
435
    $lines = explode("\n", $csv);
436
    $lines[3] = '"Nam liber tempor","CHANGED IN CACHED FILE",1151766000,1';
437
    $csv = implode("\n", $lines);
438
    $this->verbose('<pre>' . $csv . '</pre>');
439
    file_put_contents($file_url, $csv);
440

    
441
    // Re-import file. Ensure that the data from the cache was used.
442
    $this->drupalPost('import/node', $edit, t('Import'));
443
    $this->assertText('Updated 1 node');
444

    
445
    // Assert that node 3 had changed.
446
    $node = node_load(3);
447
    $this->assertEqual('Nam liber tempor', $node->title);
448
    $this->assertEqual('CHANGED IN CACHED FILE', $node->body[LANGUAGE_NONE][0]['value']);
449
  }
450

    
451
  /**
452
   * Tests if the source is refetched on a second import when the source
453
   * changed.
454
   */
455
  public function testChangedSource() {
456
    $this->setUpImporter();
457

    
458
    $source_url = url('testing/feeds/nodes.csv', array('absolute' => TRUE));
459
    $edit = array(
460
      'feeds[FeedsHTTPFetcher][source]' => $source_url,
461
    );
462
    $this->drupalPost('import/node', $edit, t('Import'));
463

    
464
    $this->assertText('Created 9 nodes');
465

    
466
    // Ensure that the fetched content was cached in a file.
467
    $file_url = 'private://feeds/cache/' . hash('sha256', $source_url);
468
    $this->assertTrue(file_exists($file_url), format_string('The file @file_url exists.', array(
469
      '@file_url' => $file_url,
470
    )));
471

    
472
    // Overwrite cached file, change one item.
473
    $csv = file_get_contents($file_url);
474
    $lines = explode("\n", $csv);
475
    $lines[3] = '"Nam liber tempor","CHANGED IN CACHED FILE",1151766000,1';
476
    $csv = implode("\n", $lines);
477
    $this->verbose('<pre>' . $csv . '</pre>');
478
    file_put_contents($file_url, $csv);
479

    
480
    // Set flag that the source has changed.
481
    variable_set('feeds_tests_nodes_changed', TRUE);
482

    
483
    // Re-import file. Ensure that the content was refetched.
484
    $this->drupalPost('import/node', $edit, t('Import'));
485
    $this->assertText('Updated 2 nodes');
486

    
487
    // Assert that node 1 and 4 changed.
488
    $node = node_load(1);
489
    $this->assertEqual('Ut wisi enim ad minim veniam', $node->title);
490
    $this->assertEqual('CHANGED IN SOURCE', $node->body[LANGUAGE_NONE][0]['value']);
491
    $node = node_load(4);
492
    $this->assertEqual('Typi non habent', $node->title);
493
    $this->assertEqual('CHANGED IN SOURCE', $node->body[LANGUAGE_NONE][0]['value']);
494

    
495
    // Assert that node 3 had NOT changed.
496
    $node = node_load(3);
497
    $this->assertEqual('Nam liber tempor', $node->title);
498
    $this->assertNotEqual('CHANGED IN CACHED FILE', $node->body[LANGUAGE_NONE][0]['value']);
499
  }
500

    
501
  /**
502
   * Tests that a non-writable cache directory does not result into fatal
503
   * errors.
504
   */
505
  public function testNonWritableCacheDirectory() {
506
    // Set the cache directory to a non-writable directory.
507
    variable_set('feeds_http_file_cache_dir', 'file://non-writeable-dir/feeds');
508

    
509
    $this->setUpImporter();
510

    
511
    $source_url = url('testing/feeds/nodes.csv', array('absolute' => TRUE));
512
    $edit = array(
513
      'feeds[FeedsHTTPFetcher][source]' => $source_url,
514
    );
515
    $this->drupalPost('import/node', $edit, t('Import'));
516

    
517
    // Assert that a message is being displayed and that we are back on the
518
    // import form.
519
    $this->assertText("The feeds cache directory (file://non-writeable-dir/feeds) either cannot be created or is not writable. You can change the cache directory by setting the 'feeds_http_file_cache_dir' variable.");
520
    $this->assertFieldByName('feeds[FeedsHTTPFetcher][source]', $source_url);
521
  }
522

    
523
  /**
524
   * Tests importing source that needs multiple cron runs.
525
   *
526
   * Make sure that:
527
   * - The content is not saved in the feeds_source table.
528
   * - That the source is not refetched while the import has not completed yet.
529
   */
530
  public function testImportSourceWithMultipleCronRuns() {
531
    $source_url = url('testing/feeds/nodes.csv', array('absolute' => TRUE));
532
    $this->setUpMultipleCronRuns($source_url);
533

    
534
    // Run cron. Five nodes should be imported.
535
    $this->cronRun();
536

    
537
    // Assert that only one file was created in the in_progress dir.
538
    $this->getInProgressFile();
539

    
540
    // Assert that five nodes have been created now.
541
    $this->assertNodeCount(5);
542

    
543
    // Assert that the content is *not* saved in the feeds_source table.
544
    $source = db_select('feeds_source')
545
      ->fields('feeds_source', array())
546
      ->condition('id', 'node')
547
      ->execute()
548
      ->fetch();
549
    $this->assertTrue(strpos($source->fetcher_result, 'Title,Body,published,GUID') === FALSE, 'The content has not been saved in the feeds_source table.');
550

    
551
    // Now change the source to test if the source is not refetched while the
552
    // import hasn't been finished yet. The following is different:
553
    // - Items 1 and 4 changed.
554
    // - Items 2 and 7 were removed.
555
    variable_set('feeds_tests_nodes_changed', TRUE);
556

    
557
    // Run cron again. Another four nodes should be imported.
558
    $this->cronRun();
559
    $this->assertNodeCount(9);
560

    
561
    // Check if the imported nodes match that from the original source.
562
    $node = node_load(1);
563
    $this->assertEqual('Ut wisi enim ad minim veniam', $node->title);
564
    $this->assertTrue(strpos($node->body[LANGUAGE_NONE][0]['value'], 'CHANGE') === FALSE);
565
    $node = node_load(4);
566
    $this->assertEqual('Typi non habent', $node->title);
567
    $this->assertTrue(strpos($node->body[LANGUAGE_NONE][0]['value'], 'CHANGE') === FALSE);
568
    $node = node_load(7);
569
    $this->assertEqual('Claritas est etiam', $node->title);
570
    $node = node_load(9);
571
    $this->assertEqual('Eodem modo typi', $node->title);
572
  }
573

    
574
  /**
575
   * Tests that an import is aborted when the temporary file in the in_progress
576
   * dir is removed.
577
   */
578
  public function testAbortImportWhenTemporaryFileIsDeleted() {
579
    $source_url = $GLOBALS['base_url'] . '/' . drupal_get_path('module', 'feeds') . '/tests/feeds/many_nodes_ordered.csv';
580
    $this->setUpMultipleCronRuns($source_url);
581

    
582
    // Run the first cron.
583
    $this->cronRun();
584

    
585
    // Assert that five nodes have been created.
586
    $this->assertNodeCount(5);
587

    
588
    // Remove file.
589
    $file = $this->getInProgressFile();
590
    drupal_unlink($file->uri);
591

    
592
    // Run cron again and assert that no more nodes are imported.
593
    $this->cronRun();
594
    $this->assertNodeCount(5);
595
  }
596

    
597
  /**
598
   * Tests that FeedsHTTPFetcherResult::getRaw() always returns the same result
599
   * for the same instance, even when caches are cleared in between.
600
   *
601
   * Parsers can call this method multiple times on separate requests. When an
602
   * import did not complete in one run, the source should never be refetched
603
   * when calling getRaw().
604
   *
605
   * When an import is restarted, a new FeedsHTTPFetcherResult is created and in
606
   * that case the source *should* be refetched.
607
   */
608
  public function testFeedsHTTPFetcherResultGetRaw() {
609
    // Set source file to fetch.
610
    $source_url = url('testing/feeds/nodes.csv', array('absolute' => TRUE));
611

    
612
    // Retrieve the raw content.
613
    $fetcher_result1 = new FeedsHTTPFetcherResult($source_url);
614
    $raw1 = $fetcher_result1->getRaw();
615

    
616
    // Simulate the case where the import is picked up later. In between caches
617
    // were cleared, the source was changed by the source provider and the
618
    // fetcher result was serialized and saved in the database.
619
    $fetcher_result_serialized = serialize($fetcher_result1);
620
    // Assert that the raw content was not serialized.
621
    $this->assertTrue(strpos($fetcher_result_serialized, $raw1) === FALSE, 'The raw data was not saved in the serialized fetcher result.');
622
    variable_set('feeds_tests_nodes_changed', TRUE);
623
    drupal_static_reset();
624
    drupal_flush_all_caches();
625

    
626
    // And retrieve the raw content again.
627
    $fetcher_result2 = unserialize($fetcher_result_serialized);
628
    $raw2 = $fetcher_result2->getRaw();
629

    
630
    // Assert that the content didn't change.
631
    $this->assertEqual($raw1, $raw2, 'The fetcher result returned the same raw data.');
632

    
633
    // Simulate the case where the import has restarted and ensure that the
634
    // contents *do* change in that case.
635
    $fetcher_result3 = new FeedsHTTPFetcherResult($source_url);
636
    $raw3 = $fetcher_result3->getRaw();
637
    // Assert that the content changed.
638
    $this->assertNotEqual($raw1, $raw3, 'A new fetcher result returned the other raw data.');
639
  }
640

    
641
}