1 |
41cc1b08
|
Assos Assos
|
<?php
|
2 |
|
|
|
3 |
|
|
/**
|
4 |
|
|
* @file
|
5 |
|
|
* Contains FeedsFileHTTPTestCase.
|
6 |
|
|
*/
|
7 |
|
|
|
8 |
|
|
/**
|
9 |
|
|
* HTTP fetcher test class.
|
10 |
|
|
*/
|
11 |
|
|
class FeedsFileHTTPTestCase extends FeedsWebTestCase {
|
12 |
ed9a13f1
|
Assos Assos
|
|
13 |
|
|
/**
|
14 |
|
|
* {@inheritdoc}
|
15 |
|
|
*/
|
16 |
41cc1b08
|
Assos Assos
|
public static function getInfo() {
|
17 |
|
|
return array(
|
18 |
|
|
'name' => 'Fetcher: HTTP',
|
19 |
|
|
'description' => 'Tests for file http fetcher plugin.',
|
20 |
|
|
'group' => 'Feeds',
|
21 |
|
|
);
|
22 |
|
|
}
|
23 |
|
|
|
24 |
ec2b0e7b
|
Assos Assos
|
/**
|
25 |
|
|
* {@inheritdoc}
|
26 |
|
|
*/
|
27 |
|
|
public function setUp() {
|
28 |
|
|
parent::setUp();
|
29 |
|
|
|
30 |
|
|
// Include FeedsProcessor.inc so processor related constants are available.
|
31 |
|
|
module_load_include('inc', 'feeds', 'plugins/FeedsProcessor');
|
32 |
|
|
|
33 |
|
|
// Do not use curl as that will result into HTTP requests returning a 404.
|
34 |
|
|
variable_set('feeds_never_use_curl', TRUE);
|
35 |
|
|
}
|
36 |
|
|
|
37 |
|
|
/**
|
38 |
|
|
* Setup importer to import items from testing/feeds/nodes.csv.
|
39 |
|
|
*/
|
40 |
|
|
public function setUpImporter() {
|
41 |
|
|
// Set up an importer.
|
42 |
|
|
$this->createImporterConfiguration('Node import', 'node');
|
43 |
|
|
$this->setSettings('node', NULL, array(
|
44 |
|
|
'content_type' => '',
|
45 |
|
|
'import_period' => 0,
|
46 |
|
|
));
|
47 |
|
|
$this->setPlugin('node', 'FeedsHTTPFetcher');
|
48 |
|
|
$this->setPlugin('node', 'FeedsCSVParser');
|
49 |
|
|
$this->setSettings('node', 'FeedsNodeProcessor', array(
|
50 |
|
|
'update_existing' => FEEDS_UPDATE_EXISTING,
|
51 |
|
|
));
|
52 |
|
|
$this->addMappings('node', array(
|
53 |
|
|
0 => array(
|
54 |
|
|
'source' => 'title',
|
55 |
|
|
'target' => 'title',
|
56 |
|
|
'unique' => TRUE,
|
57 |
|
|
),
|
58 |
|
|
1 => array(
|
59 |
|
|
'source' => 'body',
|
60 |
|
|
'target' => 'body',
|
61 |
|
|
),
|
62 |
|
|
));
|
63 |
|
|
}
|
64 |
|
|
|
65 |
|
|
/**
|
66 |
|
|
* Configures the evironment so that multiple cron runs are needed to complete
|
67 |
|
|
* an import.
|
68 |
|
|
*
|
69 |
|
|
* @param string $source_url
|
70 |
|
|
* The URL of the file to import.
|
71 |
|
|
*/
|
72 |
|
|
protected function setUpMultipleCronRuns($source_url) {
|
73 |
|
|
// Process 5 items per batch.
|
74 |
|
|
variable_set('feeds_process_limit', 5);
|
75 |
|
|
|
76 |
|
|
// Set variable to enforce that only five items get imported per cron run.
|
77 |
|
|
// @see feeds_tests_cron_queue_alter()
|
78 |
|
|
// @see feeds_tests_feeds_after_save()
|
79 |
|
|
variable_set('feeds_tests_feeds_source_import_queue_time', 5);
|
80 |
|
|
variable_set('feeds_tests_feeds_after_save_sleep', 1);
|
81 |
|
|
|
82 |
|
|
// Set up importer.
|
83 |
|
|
$this->setUpImporter();
|
84 |
|
|
// Only import during cron runs, not immediately.
|
85 |
|
|
$this->setSettings('node', NULL, array(
|
86 |
|
|
'import_on_create' => FALSE,
|
87 |
|
|
));
|
88 |
|
|
|
89 |
|
|
// Set source file to import.
|
90 |
|
|
$edit = array(
|
91 |
|
|
'feeds[FeedsHTTPFetcher][source]' => $source_url,
|
92 |
|
|
);
|
93 |
|
|
$this->drupalPost('import/node', $edit, t('Schedule import'));
|
94 |
|
|
|
95 |
|
|
// Ensure that no nodes have been created yet.
|
96 |
|
|
$this->assertNodeCount(0, 'No nodes have been created yet (actual: @count).');
|
97 |
|
|
}
|
98 |
|
|
|
99 |
|
|
/**
|
100 |
|
|
* Returns the file in the Feeds in_progress directory.
|
101 |
|
|
*
|
102 |
|
|
* @return object
|
103 |
|
|
* The found file.
|
104 |
|
|
*
|
105 |
|
|
* @throws Exception
|
106 |
|
|
* In case no file was found, so the test can abort without issuing a fatal
|
107 |
|
|
* error.
|
108 |
|
|
*/
|
109 |
|
|
protected function getInProgressFile() {
|
110 |
|
|
// Assert that a file exists in the in_progress dir.
|
111 |
|
|
$files = file_scan_directory('private://feeds/in_progress', '/.*/');
|
112 |
|
|
debug($files);
|
113 |
|
|
$this->assertEqual(1, count($files), 'The feeds "in progress" dir contains one file.');
|
114 |
|
|
if (!count($files)) {
|
115 |
|
|
// Abort test.
|
116 |
|
|
throw new Exception('File not found.');
|
117 |
|
|
}
|
118 |
|
|
return reset($files);
|
119 |
|
|
}
|
120 |
|
|
|
121 |
41cc1b08
|
Assos Assos
|
/**
|
122 |
|
|
* Test the Feed URL form.
|
123 |
|
|
*/
|
124 |
|
|
public function testFormValidation() {
|
125 |
|
|
// Set up an importer.
|
126 |
|
|
$id = drupal_strtolower($this->randomName());
|
127 |
|
|
$this->createImporterConfiguration($this->randomString(), $id);
|
128 |
|
|
|
129 |
|
|
// Check that by default, we add http:// to the front of the URL.
|
130 |
|
|
$edit = array(
|
131 |
|
|
'feeds[FeedsHTTPFetcher][source]' => 'example.com',
|
132 |
|
|
);
|
133 |
|
|
$this->drupalPost('import/' . $id, $edit, t('Import'));
|
134 |
|
|
$this->assertText(t('There are no new nodes.'));
|
135 |
|
|
$this->assertFieldByName('feeds[FeedsHTTPFetcher][source]', 'http://example.com');
|
136 |
|
|
|
137 |
|
|
$this->setSettings($id, 'FeedsHTTPFetcher', array('auto_scheme' => 'feed'));
|
138 |
|
|
$this->drupalPost('import/' . $id, $edit, t('Import'));
|
139 |
|
|
$this->assertText(t('There are no new nodes.'));
|
140 |
|
|
$this->assertFieldByName('feeds[FeedsHTTPFetcher][source]', 'feed://example.com');
|
141 |
|
|
|
142 |
|
|
$this->setSettings($id, 'FeedsHTTPFetcher', array('auto_scheme' => ''));
|
143 |
|
|
$this->drupalPost('import/' . $id, $edit, t('Import'));
|
144 |
|
|
$this->assertText(t('The URL example.com is invalid.'));
|
145 |
|
|
$this->assertFieldByName('feeds[FeedsHTTPFetcher][source]', 'example.com');
|
146 |
|
|
}
|
147 |
|
|
|
148 |
ec2b0e7b
|
Assos Assos
|
/**
|
149 |
|
|
* Tests if the result of a http request can be cached on the file system.
|
150 |
|
|
*
|
151 |
|
|
* When a first request is made, the data is retrieved from the given source
|
152 |
|
|
* url and cached on the file system.
|
153 |
|
|
* On the second request, send to the same source url, the HTTP header
|
154 |
|
|
* "If-Modified-Since" is set. This should result into a 304 HTTP status from
|
155 |
|
|
* the source, as the contents did not change in between. In such case, the
|
156 |
|
|
* data should be retrieved from the cache.
|
157 |
|
|
*/
|
158 |
|
|
public function testHttpRequestUsingFileCache() {
|
159 |
|
|
// Include http request functions.
|
160 |
|
|
feeds_include_library('http_request.inc', 'http_request');
|
161 |
|
|
|
162 |
|
|
// First request.
|
163 |
|
|
$url = url('testing/feeds/nodes.csv', array('absolute' => TRUE));
|
164 |
|
|
$result = feeds_http_request($url);
|
165 |
|
|
|
166 |
|
|
// Assert that the first request was successful and was not retrieved from
|
167 |
|
|
// cache.
|
168 |
|
|
$this->assertEqual(200, $result->code, 'Request status code is 200.');
|
169 |
|
|
$this->assertTrue(empty($result->from_cache), 'Request was not retrieved from cache.');
|
170 |
|
|
// Assert that a file was created.
|
171 |
|
|
$file_url = 'private://feeds/cache/' . hash('sha256', $url);
|
172 |
|
|
$this->assertTrue(file_exists($file_url), format_string('The file @file_url exists.', array(
|
173 |
|
|
'@file_url' => $file_url,
|
174 |
|
|
)));
|
175 |
|
|
|
176 |
|
|
// Reset feeds_http_request() static cache.
|
177 |
|
|
drupal_static_reset('feeds_http_request');
|
178 |
|
|
|
179 |
|
|
// Write some garbage to the cached file to ensure that the cache is
|
180 |
|
|
// retrieved from that file.
|
181 |
|
|
$garbage = static::randomString(100);
|
182 |
|
|
file_put_contents($file_url, $garbage);
|
183 |
|
|
|
184 |
|
|
// Second request.
|
185 |
|
|
$result2 = feeds_http_request($url);
|
186 |
|
|
|
187 |
|
|
// Assert that the second request was successful and was retrieved from
|
188 |
|
|
// cache.
|
189 |
|
|
$this->assertEqual(200, $result2->code, 'Request status code is 200.');
|
190 |
|
|
$this->assertTrue(!empty($result2->from_cache), 'Request was retrieved from cache.');
|
191 |
|
|
$this->assertEqual($garbage, $result2->data, 'The cache came from the file cache.');
|
192 |
|
|
|
193 |
|
|
// Assert that the file is removed when caches are cleared.
|
194 |
|
|
drupal_flush_all_caches();
|
195 |
|
|
$this->assertFalse(file_exists($file_url), format_string('The file @file_url no longer exists.', array(
|
196 |
|
|
'@file_url' => $file_url,
|
197 |
|
|
)));
|
198 |
|
|
}
|
199 |
|
|
|
200 |
|
|
/**
|
201 |
|
|
* Tests if the source is refetched when the cached file is manually removed.
|
202 |
|
|
*
|
203 |
|
|
* A call to feeds_http_request() should always get us data.
|
204 |
|
|
*/
|
205 |
|
|
public function testRefetchWhenCachedFileIsRemoved() {
|
206 |
|
|
// Include http request functions.
|
207 |
|
|
feeds_include_library('http_request.inc', 'http_request');
|
208 |
|
|
|
209 |
|
|
// First request.
|
210 |
|
|
$url = url('testing/feeds/nodes.csv', array('absolute' => TRUE));
|
211 |
|
|
$result1 = feeds_http_request($url);
|
212 |
|
|
|
213 |
|
|
// Assert that the first request was successful and was not retrieved from
|
214 |
|
|
// cache.
|
215 |
|
|
$this->assertEqual(200, $result1->code, 'Request status code is 200.');
|
216 |
|
|
$this->assertTrue(empty($result1->from_cache), 'Request was not retrieved from cache.');
|
217 |
|
|
|
218 |
|
|
// Reset feeds_http_request() static cache.
|
219 |
|
|
drupal_static_reset('feeds_http_request');
|
220 |
|
|
|
221 |
|
|
// Write some garbage to the cached file to ensure that the cache is
|
222 |
|
|
// retrieved from that file.
|
223 |
|
|
$file_url = 'private://feeds/cache/' . hash('sha256', $url);
|
224 |
|
|
$garbage = static::randomString(100);
|
225 |
|
|
file_put_contents($file_url, $garbage);
|
226 |
|
|
|
227 |
|
|
// Second request.
|
228 |
|
|
$result2 = feeds_http_request($url);
|
229 |
|
|
|
230 |
|
|
// Assert that the second request was successful and was retrieved from
|
231 |
|
|
// cache.
|
232 |
|
|
$this->assertEqual(200, $result2->code, 'Request status code is 200.');
|
233 |
|
|
$this->assertTrue(!empty($result2->from_cache), 'Request was retrieved from cache.');
|
234 |
|
|
$this->assertEqual($garbage, $result2->data, 'The cache came from the file cache.');
|
235 |
|
|
|
236 |
|
|
// Now remove the cached file.
|
237 |
|
|
drupal_unlink($file_url);
|
238 |
|
|
$this->assertFalse(file_exists($file_url), format_string('The file @file_url no longer exists.', array(
|
239 |
|
|
'@file_url' => $file_url,
|
240 |
|
|
)));
|
241 |
|
|
|
242 |
|
|
// Third request.
|
243 |
|
|
$result3 = feeds_http_request($url);
|
244 |
|
|
|
245 |
|
|
// Assert that the data is refetched, even though the source hasn't changed.
|
246 |
|
|
$this->assertEqual(200, $result3->code, 'Request status code is 200.');
|
247 |
|
|
$this->assertTrue(empty($result3->from_cache), 'Request was not retrieved from cache.');
|
248 |
|
|
$this->assertEqual($result1->data, $result3->data, 'Data is available on the response.');
|
249 |
|
|
}
|
250 |
|
|
|
251 |
|
|
/**
|
252 |
|
|
* Tests that the source isn't fetched twice during the same request.
|
253 |
|
|
*/
|
254 |
|
|
public function testNoRefetchOnSameRequest() {
|
255 |
|
|
// Include http request functions.
|
256 |
|
|
feeds_include_library('http_request.inc', 'http_request');
|
257 |
|
|
|
258 |
|
|
// First request.
|
259 |
|
|
$url = url('testing/feeds/nodes.csv', array('absolute' => TRUE));
|
260 |
|
|
$result1 = feeds_http_request($url);
|
261 |
|
|
|
262 |
|
|
// Set flag that the source has changed.
|
263 |
|
|
variable_set('feeds_tests_nodes_changed', TRUE);
|
264 |
|
|
|
265 |
|
|
// Second request.
|
266 |
|
|
$result2 = feeds_http_request($url);
|
267 |
|
|
|
268 |
|
|
// Assert that the result is exactly the same.
|
269 |
|
|
$this->assertEqual($result1->data, $result2->data, 'The data was retrieved from cache.');
|
270 |
|
|
|
271 |
|
|
// Assert that the data *is* refetched (and different) after a cache clear.
|
272 |
|
|
drupal_flush_all_caches();
|
273 |
|
|
drupal_static_reset();
|
274 |
|
|
$result3 = feeds_http_request($url);
|
275 |
|
|
$this->assertNotEqual($result1->data, $result3->data, 'The data is refetched.');
|
276 |
|
|
}
|
277 |
|
|
|
278 |
|
|
/**
|
279 |
|
|
* Tests if the data is not cached when the option for caching is disabled.
|
280 |
|
|
*/
|
281 |
|
|
public function testHTTPCacheDisabled() {
|
282 |
|
|
$this->setUpImporter();
|
283 |
|
|
|
284 |
|
|
// Disable caching HTTP request result.
|
285 |
|
|
$this->setSettings('node', 'FeedsHTTPFetcher', array(
|
286 |
|
|
'cache_http_result' => FALSE,
|
287 |
|
|
));
|
288 |
|
|
|
289 |
|
|
$source_url = url('testing/feeds/nodes.csv', array('absolute' => TRUE));
|
290 |
|
|
$edit = array(
|
291 |
|
|
'feeds[FeedsHTTPFetcher][source]' => $source_url,
|
292 |
|
|
);
|
293 |
|
|
$this->drupalPost('import/node', $edit, t('Import'));
|
294 |
|
|
$this->assertText('Created 9 nodes');
|
295 |
|
|
|
296 |
|
|
// Assert that no cache entries were created.
|
297 |
|
|
$number_of_cache_entries = db_query('SELECT COUNT(cid) FROM {cache_feeds_http}')->fetchField();
|
298 |
|
|
$this->assertEqual(0, $number_of_cache_entries, format_string('No cache entries were created in the cache_feeds_http table (actual: @actual).', array(
|
299 |
|
|
'@actual' => $number_of_cache_entries,
|
300 |
|
|
)));
|
301 |
|
|
|
302 |
|
|
// Assert that no cache file was created.
|
303 |
|
|
$file_url = 'private://feeds/cache/' . hash('sha256', $source_url);
|
304 |
|
|
$this->assertFalse(file_exists($file_url), format_string('The file @file_url does not exist.', array(
|
305 |
|
|
'@file_url' => $file_url,
|
306 |
|
|
)));
|
307 |
|
|
}
|
308 |
|
|
|
309 |
|
|
/**
|
310 |
|
|
* Tests if the data is cached on the file system even when a different cache
|
311 |
|
|
* class is used.
|
312 |
|
|
*
|
313 |
|
|
* This can happen when using Memcache or Redis for all cache bins.
|
314 |
|
|
*/
|
315 |
|
|
public function testHTTPCacheOverride() {
|
316 |
|
|
// Revert back to the default cache class.
|
317 |
|
|
variable_set('cache_class_cache_feeds_http', 'DrupalDatabaseCache');
|
318 |
|
|
|
319 |
|
|
// Import. We cannot test with a simple feeds_http_request() call here,
|
320 |
|
|
// because there is no way to override a cache class on a single request.
|
321 |
|
|
// @see _cache_get_object().
|
322 |
|
|
$this->setUpImporter();
|
323 |
|
|
$source_url = url('testing/feeds/nodes.csv', array('absolute' => TRUE));
|
324 |
|
|
$edit = array(
|
325 |
|
|
'feeds[FeedsHTTPFetcher][source]' => $source_url,
|
326 |
|
|
);
|
327 |
|
|
$this->drupalPost('import/node', $edit, t('Import'));
|
328 |
|
|
$this->assertText('Created 9 nodes');
|
329 |
|
|
|
330 |
|
|
// Assert that the raw data is not saved in the database.
|
331 |
|
|
$count = db_select('cache_feeds_http')
|
332 |
|
|
->condition('data', '%Title,Body,published,GUID%', 'LIKE')
|
333 |
|
|
->countQuery()
|
334 |
|
|
->execute()
|
335 |
|
|
->fetchField();
|
336 |
|
|
$this->assertEqual(0, $count, 'Raw source was not saved in the database.');
|
337 |
|
|
|
338 |
|
|
// Assert that a file was created.
|
339 |
|
|
$file_url = 'private://feeds/cache/' . hash('sha256', $source_url);
|
340 |
|
|
$this->assertTrue(file_exists($file_url), format_string('The file @file_url exists.', array(
|
341 |
|
|
'@file_url' => $file_url,
|
342 |
|
|
)));
|
343 |
|
|
}
|
344 |
|
|
|
345 |
|
|
/**
|
346 |
|
|
* Tests if cached files are cleaned up even when a different cache class is
|
347 |
|
|
* used.
|
348 |
|
|
*/
|
349 |
|
|
public function testCachedFilesCleanupOnHTTPCacheOverride() {
|
350 |
|
|
// Revert back to the default cache class.
|
351 |
|
|
variable_set('cache_class_cache_feeds_http', 'DrupalDatabaseCache');
|
352 |
|
|
|
353 |
|
|
// Create a real cached file by performing an import.
|
354 |
|
|
$this->setUpImporter();
|
355 |
|
|
$source_url = url('testing/feeds/nodes.csv', array('absolute' => TRUE));
|
356 |
|
|
$edit = array(
|
357 |
|
|
'feeds[FeedsHTTPFetcher][source]' => $source_url,
|
358 |
|
|
);
|
359 |
|
|
$this->drupalPost('import/node', $edit, t('Import'));
|
360 |
|
|
$this->assertText('Created 9 nodes');
|
361 |
|
|
$file_url_with_cache_record = 'private://feeds/cache/' . hash('sha256', $source_url);
|
362 |
|
|
|
363 |
|
|
// Write a dummy cached file.
|
364 |
|
|
$dir = 'private://feeds/cache';
|
365 |
|
|
$file_url_no_cache_record = $dir . '/abc123';
|
366 |
|
|
file_prepare_directory($dir, FILE_CREATE_DIRECTORY);
|
367 |
|
|
file_put_contents($file_url_no_cache_record, static::randomString());
|
368 |
|
|
|
369 |
|
|
// Trigger cleanup of orphaned cached files.
|
370 |
|
|
variable_del('feeds_sync_cache_feeds_http_last_check');
|
371 |
|
|
$this->cronRun();
|
372 |
|
|
|
373 |
|
|
// Assert that the dummy cached file has been cleaned up and the other file
|
374 |
|
|
// still exists.
|
375 |
|
|
$this->assertFalse(file_exists($file_url_no_cache_record), format_string('The file @file_url no longer exists.', array(
|
376 |
|
|
'@file_url' => $file_url_no_cache_record,
|
377 |
|
|
)));
|
378 |
|
|
$this->assertTrue(file_exists($file_url_with_cache_record), format_string('The file @file_url still exists.', array(
|
379 |
|
|
'@file_url' => $file_url_with_cache_record,
|
380 |
|
|
)));
|
381 |
|
|
}
|
382 |
|
|
|
383 |
|
|
/**
|
384 |
|
|
* Tests if the cron task for cleaning up cached files are run one at a time.
|
385 |
|
|
*/
|
386 |
|
|
public function testCachedFilesCleanupQueue() {
|
387 |
|
|
$queue = DrupalQueue::get('feeds_sync_cache_feeds_http');
|
388 |
|
|
|
389 |
|
|
// First, make sure that a queue task is only ran every six hours.
|
390 |
|
|
variable_set('feeds_sync_cache_feeds_http_last_check', REQUEST_TIME);
|
391 |
|
|
|
392 |
|
|
// Run cron without executing the queue tasks.
|
393 |
|
|
feeds_cron();
|
394 |
|
|
|
395 |
|
|
// Assert that no task was created for cleaning up the files.
|
396 |
|
|
$this->assertEqual(0, $queue->numberOfItems(), 'No task was created for the feeds_sync_cache_feeds_http queue.');
|
397 |
|
|
|
398 |
|
|
// Unset last check and run cron.
|
399 |
|
|
variable_del('feeds_sync_cache_feeds_http_last_check');
|
400 |
|
|
feeds_cron();
|
401 |
|
|
|
402 |
|
|
// Assert that one task was created for cleaning up the files and that the
|
403 |
|
|
// variable for the last check was updated.
|
404 |
|
|
$this->assertEqual(1, $queue->numberOfItems(), 'One task was created for the feeds_sync_cache_feeds_http queue.');
|
405 |
|
|
$this->assertEqual(REQUEST_TIME, variable_get('feeds_sync_cache_feeds_http_last_check'));
|
406 |
|
|
|
407 |
|
|
// Unset last check and run cron again.
|
408 |
|
|
variable_del('feeds_sync_cache_feeds_http_last_check');
|
409 |
|
|
feeds_cron();
|
410 |
|
|
|
411 |
|
|
// Assert that there still is one task.
|
412 |
|
|
$this->assertEqual(1, $queue->numberOfItems(), 'One task exists for the feeds_sync_cache_feeds_http queue.');
|
413 |
|
|
$this->assertEqual(REQUEST_TIME, variable_get('feeds_sync_cache_feeds_http_last_check'));
|
414 |
|
|
}
|
415 |
|
|
|
416 |
|
|
/**
|
417 |
|
|
* Tests if a source is not refetched on a second import when the source did
|
418 |
|
|
* not change.
|
419 |
|
|
*/
|
420 |
|
|
public function testSourceCaching() {
|
421 |
|
|
$this->setUpImporter();
|
422 |
|
|
|
423 |
|
|
$source_url = url('testing/feeds/nodes.csv', array('absolute' => TRUE));
|
424 |
|
|
$edit = array(
|
425 |
|
|
'feeds[FeedsHTTPFetcher][source]' => $source_url,
|
426 |
|
|
);
|
427 |
|
|
$this->drupalPost('import/node', $edit, t('Import'));
|
428 |
|
|
|
429 |
|
|
$this->assertText('Created 9 nodes');
|
430 |
|
|
|
431 |
|
|
// Ensure that the fetched content was cached in a file.
|
432 |
|
|
$file_url = 'private://feeds/cache/' . hash('sha256', $source_url);
|
433 |
|
|
$this->assertTrue(file_exists($file_url), format_string('The file @file_url exists.', array(
|
434 |
|
|
'@file_url' => $file_url,
|
435 |
|
|
)));
|
436 |
|
|
|
437 |
|
|
// Overwrite cached file, change one item.
|
438 |
|
|
$csv = file_get_contents($file_url);
|
439 |
|
|
$lines = explode("\n", $csv);
|
440 |
|
|
$lines[3] = '"Nam liber tempor","CHANGED IN CACHED FILE",1151766000,1';
|
441 |
|
|
$csv = implode("\n", $lines);
|
442 |
|
|
$this->verbose('<pre>' . $csv . '</pre>');
|
443 |
|
|
file_put_contents($file_url, $csv);
|
444 |
|
|
|
445 |
|
|
// Re-import file. Ensure that the data from the cache was used.
|
446 |
|
|
$this->drupalPost('import/node', $edit, t('Import'));
|
447 |
|
|
$this->assertText('Updated 1 node');
|
448 |
|
|
|
449 |
|
|
// Assert that node 3 had changed.
|
450 |
|
|
$node = node_load(3);
|
451 |
|
|
$this->assertEqual('Nam liber tempor', $node->title);
|
452 |
|
|
$this->assertEqual('CHANGED IN CACHED FILE', $node->body[LANGUAGE_NONE][0]['value']);
|
453 |
|
|
}
|
454 |
|
|
|
455 |
|
|
/**
|
456 |
|
|
* Tests if the source is refetched on a second import when the source
|
457 |
|
|
* changed.
|
458 |
|
|
*/
|
459 |
|
|
public function testChangedSource() {
|
460 |
|
|
$this->setUpImporter();
|
461 |
|
|
|
462 |
|
|
$source_url = url('testing/feeds/nodes.csv', array('absolute' => TRUE));
|
463 |
|
|
$edit = array(
|
464 |
|
|
'feeds[FeedsHTTPFetcher][source]' => $source_url,
|
465 |
|
|
);
|
466 |
|
|
$this->drupalPost('import/node', $edit, t('Import'));
|
467 |
|
|
|
468 |
|
|
$this->assertText('Created 9 nodes');
|
469 |
|
|
|
470 |
|
|
// Ensure that the fetched content was cached in a file.
|
471 |
|
|
$file_url = 'private://feeds/cache/' . hash('sha256', $source_url);
|
472 |
|
|
$this->assertTrue(file_exists($file_url), format_string('The file @file_url exists.', array(
|
473 |
|
|
'@file_url' => $file_url,
|
474 |
|
|
)));
|
475 |
|
|
|
476 |
|
|
// Overwrite cached file, change one item.
|
477 |
|
|
$csv = file_get_contents($file_url);
|
478 |
|
|
$lines = explode("\n", $csv);
|
479 |
|
|
$lines[3] = '"Nam liber tempor","CHANGED IN CACHED FILE",1151766000,1';
|
480 |
|
|
$csv = implode("\n", $lines);
|
481 |
|
|
$this->verbose('<pre>' . $csv . '</pre>');
|
482 |
|
|
file_put_contents($file_url, $csv);
|
483 |
|
|
|
484 |
|
|
// Set flag that the source has changed.
|
485 |
|
|
variable_set('feeds_tests_nodes_changed', TRUE);
|
486 |
|
|
|
487 |
|
|
// Re-import file. Ensure that the content was refetched.
|
488 |
|
|
$this->drupalPost('import/node', $edit, t('Import'));
|
489 |
|
|
$this->assertText('Updated 2 nodes');
|
490 |
|
|
|
491 |
|
|
// Assert that node 1 and 4 changed.
|
492 |
|
|
$node = node_load(1);
|
493 |
|
|
$this->assertEqual('Ut wisi enim ad minim veniam', $node->title);
|
494 |
|
|
$this->assertEqual('CHANGED IN SOURCE', $node->body[LANGUAGE_NONE][0]['value']);
|
495 |
|
|
$node = node_load(4);
|
496 |
|
|
$this->assertEqual('Typi non habent', $node->title);
|
497 |
|
|
$this->assertEqual('CHANGED IN SOURCE', $node->body[LANGUAGE_NONE][0]['value']);
|
498 |
|
|
|
499 |
|
|
// Assert that node 3 had NOT changed.
|
500 |
|
|
$node = node_load(3);
|
501 |
|
|
$this->assertEqual('Nam liber tempor', $node->title);
|
502 |
|
|
$this->assertNotEqual('CHANGED IN CACHED FILE', $node->body[LANGUAGE_NONE][0]['value']);
|
503 |
|
|
}
|
504 |
|
|
|
505 |
|
|
/**
|
506 |
|
|
* Tests that a non-writable cache directory does not result into fatal
|
507 |
|
|
* errors.
|
508 |
|
|
*/
|
509 |
|
|
public function testNonWritableCacheDirectory() {
|
510 |
|
|
// Set the cache directory to a non-writable directory.
|
511 |
|
|
variable_set('feeds_http_file_cache_dir', 'file://non-writeable-dir/feeds');
|
512 |
|
|
|
513 |
|
|
$this->setUpImporter();
|
514 |
|
|
|
515 |
|
|
$source_url = url('testing/feeds/nodes.csv', array('absolute' => TRUE));
|
516 |
|
|
$edit = array(
|
517 |
|
|
'feeds[FeedsHTTPFetcher][source]' => $source_url,
|
518 |
|
|
);
|
519 |
|
|
$this->drupalPost('import/node', $edit, t('Import'));
|
520 |
|
|
|
521 |
|
|
// Assert that a message is being displayed and that we are back on the
|
522 |
|
|
// import form.
|
523 |
|
|
$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.");
|
524 |
|
|
$this->assertFieldByName('feeds[FeedsHTTPFetcher][source]', $source_url);
|
525 |
|
|
}
|
526 |
|
|
|
527 |
|
|
/**
|
528 |
|
|
* Tests importing source that needs multiple cron runs.
|
529 |
|
|
*
|
530 |
|
|
* Make sure that:
|
531 |
|
|
* - The content is not saved in the feeds_source table.
|
532 |
|
|
* - That the source is not refetched while the import has not completed yet.
|
533 |
|
|
*/
|
534 |
|
|
public function testImportSourceWithMultipleCronRuns() {
|
535 |
|
|
$source_url = url('testing/feeds/nodes.csv', array('absolute' => TRUE));
|
536 |
|
|
$this->setUpMultipleCronRuns($source_url);
|
537 |
|
|
|
538 |
|
|
// Run cron. Five nodes should be imported.
|
539 |
|
|
$this->cronRun();
|
540 |
|
|
|
541 |
|
|
// Assert that only one file was created in the in_progress dir.
|
542 |
|
|
$this->getInProgressFile();
|
543 |
|
|
|
544 |
|
|
// Assert that five nodes have been created now.
|
545 |
|
|
$this->assertNodeCount(5);
|
546 |
|
|
|
547 |
|
|
// Assert that the content is *not* saved in the feeds_source table.
|
548 |
|
|
$source = db_select('feeds_source')
|
549 |
|
|
->fields('feeds_source', array())
|
550 |
|
|
->condition('id', 'node')
|
551 |
|
|
->execute()
|
552 |
|
|
->fetch();
|
553 |
|
|
$this->assertTrue(strpos($source->fetcher_result, 'Title,Body,published,GUID') === FALSE, 'The content has not been saved in the feeds_source table.');
|
554 |
|
|
|
555 |
|
|
// Now change the source to test if the source is not refetched while the
|
556 |
|
|
// import hasn't been finished yet. The following is different:
|
557 |
|
|
// - Items 1 and 4 changed.
|
558 |
|
|
// - Items 2 and 7 were removed.
|
559 |
|
|
variable_set('feeds_tests_nodes_changed', TRUE);
|
560 |
|
|
|
561 |
|
|
// Run cron again. Another four nodes should be imported.
|
562 |
|
|
$this->cronRun();
|
563 |
|
|
$this->assertNodeCount(9);
|
564 |
|
|
|
565 |
|
|
// Check if the imported nodes match that from the original source.
|
566 |
|
|
$node = node_load(1);
|
567 |
|
|
$this->assertEqual('Ut wisi enim ad minim veniam', $node->title);
|
568 |
|
|
$this->assertTrue(strpos($node->body[LANGUAGE_NONE][0]['value'], 'CHANGE') === FALSE);
|
569 |
|
|
$node = node_load(4);
|
570 |
|
|
$this->assertEqual('Typi non habent', $node->title);
|
571 |
|
|
$this->assertTrue(strpos($node->body[LANGUAGE_NONE][0]['value'], 'CHANGE') === FALSE);
|
572 |
|
|
$node = node_load(7);
|
573 |
|
|
$this->assertEqual('Claritas est etiam', $node->title);
|
574 |
|
|
$node = node_load(9);
|
575 |
|
|
$this->assertEqual('Eodem modo typi', $node->title);
|
576 |
|
|
}
|
577 |
|
|
|
578 |
|
|
/**
|
579 |
|
|
* Tests that an import is aborted when the temporary file in the in_progress
|
580 |
|
|
* dir is removed.
|
581 |
|
|
*/
|
582 |
|
|
public function testAbortImportWhenTemporaryFileIsDeleted() {
|
583 |
|
|
$source_url = $GLOBALS['base_url'] . '/' . drupal_get_path('module', 'feeds') . '/tests/feeds/many_nodes_ordered.csv';
|
584 |
|
|
$this->setUpMultipleCronRuns($source_url);
|
585 |
|
|
|
586 |
|
|
// Run the first cron.
|
587 |
|
|
$this->cronRun();
|
588 |
|
|
|
589 |
|
|
// Assert that five nodes have been created.
|
590 |
|
|
$this->assertNodeCount(5);
|
591 |
|
|
|
592 |
|
|
// Remove file.
|
593 |
|
|
$file = $this->getInProgressFile();
|
594 |
|
|
drupal_unlink($file->uri);
|
595 |
|
|
|
596 |
|
|
// Run cron again and assert that no more nodes are imported.
|
597 |
|
|
$this->cronRun();
|
598 |
|
|
$this->assertNodeCount(5);
|
599 |
|
|
}
|
600 |
|
|
|
601 |
|
|
/**
|
602 |
|
|
* Tests that FeedsHTTPFetcherResult::getRaw() always returns the same result
|
603 |
|
|
* for the same instance, even when caches are cleared in between.
|
604 |
|
|
*
|
605 |
|
|
* Parsers can call this method multiple times on separate requests. When an
|
606 |
|
|
* import did not complete in one run, the source should never be refetched
|
607 |
|
|
* when calling getRaw().
|
608 |
|
|
*
|
609 |
|
|
* When an import is restarted, a new FeedsHTTPFetcherResult is created and in
|
610 |
|
|
* that case the source *should* be refetched.
|
611 |
|
|
*/
|
612 |
|
|
public function testFeedsHTTPFetcherResultGetRaw() {
|
613 |
|
|
// Set source file to fetch.
|
614 |
|
|
$source_url = url('testing/feeds/nodes.csv', array('absolute' => TRUE));
|
615 |
|
|
|
616 |
|
|
// Retrieve the raw content.
|
617 |
|
|
$fetcher_result1 = new FeedsHTTPFetcherResult($source_url);
|
618 |
|
|
$raw1 = $fetcher_result1->getRaw();
|
619 |
|
|
|
620 |
|
|
// Simulate the case where the import is picked up later. In between caches
|
621 |
|
|
// were cleared, the source was changed by the source provider and the
|
622 |
|
|
// fetcher result was serialized and saved in the database.
|
623 |
|
|
$fetcher_result_serialized = serialize($fetcher_result1);
|
624 |
|
|
// Assert that the raw content was not serialized.
|
625 |
|
|
$this->assertTrue(strpos($fetcher_result_serialized, $raw1) === FALSE, 'The raw data was not saved in the serialized fetcher result.');
|
626 |
|
|
variable_set('feeds_tests_nodes_changed', TRUE);
|
627 |
|
|
drupal_static_reset();
|
628 |
|
|
drupal_flush_all_caches();
|
629 |
|
|
|
630 |
|
|
// And retrieve the raw content again.
|
631 |
|
|
$fetcher_result2 = unserialize($fetcher_result_serialized);
|
632 |
|
|
$raw2 = $fetcher_result2->getRaw();
|
633 |
|
|
|
634 |
|
|
// Assert that the content didn't change.
|
635 |
|
|
$this->assertEqual($raw1, $raw2, 'The fetcher result returned the same raw data.');
|
636 |
|
|
|
637 |
|
|
// Simulate the case where the import has restarted and ensure that the
|
638 |
|
|
// contents *do* change in that case.
|
639 |
|
|
$fetcher_result3 = new FeedsHTTPFetcherResult($source_url);
|
640 |
|
|
$raw3 = $fetcher_result3->getRaw();
|
641 |
|
|
// Assert that the content changed.
|
642 |
|
|
$this->assertNotEqual($raw1, $raw3, 'A new fetcher result returned the other raw data.');
|
643 |
|
|
}
|
644 |
|
|
|
645 |
41cc1b08
|
Assos Assos
|
} |