1
|
<?php
|
2
|
|
3
|
/**
|
4
|
* @file
|
5
|
* Contains FeedsMapperTaxonomyTestCase.
|
6
|
*/
|
7
|
|
8
|
/**
|
9
|
* Test case for taxonomy mapper mappers/taxonomy.inc.
|
10
|
*/
|
11
|
class FeedsMapperTaxonomyTestCase extends FeedsMapperTestCase {
|
12
|
|
13
|
public static function getInfo() {
|
14
|
return array(
|
15
|
'name' => 'Mapper: Taxonomy',
|
16
|
'description' => 'Test Feeds Mapper support for Taxonomy.',
|
17
|
'group' => 'Feeds',
|
18
|
);
|
19
|
}
|
20
|
|
21
|
public function setUp() {
|
22
|
parent::setUp();
|
23
|
|
24
|
// Add Tags vocabulary
|
25
|
$edit = array(
|
26
|
'name' => 'Tags',
|
27
|
'machine_name' => 'tags',
|
28
|
);
|
29
|
$this->drupalPost('admin/structure/taxonomy/add', $edit, 'Save');
|
30
|
|
31
|
$edit = array(
|
32
|
'name' => 'term1',
|
33
|
);
|
34
|
$this->drupalPost('admin/structure/taxonomy/tags/add', $edit, t('Save'));
|
35
|
$this->assertText('Created new term term1.');
|
36
|
|
37
|
// Create term reference field.
|
38
|
$field = array(
|
39
|
'field_name' => 'field_tags',
|
40
|
'type' => 'taxonomy_term_reference',
|
41
|
'cardinality' => FIELD_CARDINALITY_UNLIMITED,
|
42
|
'settings' => array(
|
43
|
'allowed_values' => array(
|
44
|
array(
|
45
|
'vocabulary' => 'tags',
|
46
|
'parent' => 0,
|
47
|
),
|
48
|
),
|
49
|
),
|
50
|
);
|
51
|
field_create_field($field);
|
52
|
|
53
|
// Add term reference field to feed item bundle.
|
54
|
$this->instance = array(
|
55
|
'field_name' => 'field_tags',
|
56
|
'bundle' => 'article',
|
57
|
'entity_type' => 'node',
|
58
|
'widget' => array(
|
59
|
'type' => 'options_select',
|
60
|
),
|
61
|
'display' => array(
|
62
|
'default' => array(
|
63
|
'type' => 'taxonomy_term_reference_link',
|
64
|
),
|
65
|
),
|
66
|
);
|
67
|
field_create_instance($this->instance);
|
68
|
|
69
|
// Add term reference field to feed node bundle.
|
70
|
$this->instance = array(
|
71
|
'field_name' => 'field_tags',
|
72
|
'bundle' => 'page',
|
73
|
'entity_type' => 'node',
|
74
|
'widget' => array(
|
75
|
'type' => 'options_select',
|
76
|
),
|
77
|
'display' => array(
|
78
|
'default' => array(
|
79
|
'type' => 'taxonomy_term_reference_link',
|
80
|
),
|
81
|
),
|
82
|
);
|
83
|
field_create_instance($this->instance);
|
84
|
|
85
|
// Create an importer configuration with basic mapping.
|
86
|
$this->createImporterConfiguration('Syndication', 'syndication');
|
87
|
$this->addMappings('syndication',
|
88
|
array(
|
89
|
0 => array(
|
90
|
'source' => 'title',
|
91
|
'target' => 'title',
|
92
|
),
|
93
|
1 => array(
|
94
|
'source' => 'description',
|
95
|
'target' => 'body',
|
96
|
),
|
97
|
2 => array(
|
98
|
'source' => 'timestamp',
|
99
|
'target' => 'created',
|
100
|
),
|
101
|
3 => array(
|
102
|
'source' => 'url',
|
103
|
'target' => 'url',
|
104
|
'unique' => TRUE,
|
105
|
),
|
106
|
4 => array(
|
107
|
'source' => 'guid',
|
108
|
'target' => 'guid',
|
109
|
'unique' => TRUE,
|
110
|
),
|
111
|
)
|
112
|
);
|
113
|
}
|
114
|
|
115
|
/**
|
116
|
* Tests inheriting taxonomy from the feed node.
|
117
|
*/
|
118
|
public function testInheritTaxonomy() {
|
119
|
// Adjust importer settings
|
120
|
$this->setSettings('syndication', NULL, array('import_period' => FEEDS_SCHEDULE_NEVER));
|
121
|
$this->setSettings('syndication', NULL, array('import_on_create' => FALSE));
|
122
|
$this->assertText('Do not import on submission');
|
123
|
|
124
|
// Map feed node's taxonomy to feed item node's taxonomy.
|
125
|
$mappings = array(
|
126
|
5 => array(
|
127
|
'source' => 'parent:taxonomy:tags',
|
128
|
'target' => 'field_tags',
|
129
|
),
|
130
|
);
|
131
|
$this->addMappings('syndication', $mappings);
|
132
|
|
133
|
// Create feed node and add term term1.
|
134
|
$langcode = LANGUAGE_NONE;
|
135
|
$nid = $this->createFeedNode('syndication', NULL, 'Syndication');
|
136
|
$term = taxonomy_get_term_by_name('term1');
|
137
|
$term = reset($term);
|
138
|
$edit = array(
|
139
|
'field_tags' . '[' . $langcode . '][]' => $term->tid,
|
140
|
);
|
141
|
$this->drupalPost("node/$nid/edit", $edit, t('Save'));
|
142
|
$this->assertTaxonomyTerm($term->name);
|
143
|
|
144
|
// Import nodes.
|
145
|
$this->drupalPost("node/$nid/import", array(), 'Import');
|
146
|
$this->assertText('Created 10 nodes.');
|
147
|
|
148
|
$count = db_query("SELECT COUNT(*) FROM {taxonomy_index}")->fetchField();
|
149
|
|
150
|
// There should be one term for each node imported plus the term on the feed node.
|
151
|
$this->assertEqual(11, $count, 'Found correct number of tags for all feed nodes and feed items.');
|
152
|
}
|
153
|
|
154
|
/**
|
155
|
* Tests searching taxonomy terms by name.
|
156
|
*/
|
157
|
public function testSearchByName() {
|
158
|
$terms = array(
|
159
|
'Drupal',
|
160
|
'localization',
|
161
|
'localization client',
|
162
|
'localization server',
|
163
|
'open atrium',
|
164
|
'translation',
|
165
|
'translation server',
|
166
|
'Drupal planet',
|
167
|
);
|
168
|
|
169
|
$this->setSettings('syndication', 'FeedsNodeProcessor', array(
|
170
|
'skip_hash_check' => TRUE,
|
171
|
'update_existing' => 2,
|
172
|
));
|
173
|
$mappings = array(
|
174
|
5 => array(
|
175
|
'source' => 'tags',
|
176
|
'target' => 'field_tags',
|
177
|
'term_search' => 0,
|
178
|
),
|
179
|
);
|
180
|
$this->addMappings('syndication', $mappings);
|
181
|
$nid = $this->createFeedNode('syndication', NULL, 'Syndication');
|
182
|
$this->assertText('Created 10 nodes.');
|
183
|
// Check that terms we not auto-created.
|
184
|
$this->drupalGet('node/2');
|
185
|
foreach ($terms as $term) {
|
186
|
$this->assertNoTaxonomyTerm($term);
|
187
|
}
|
188
|
$this->drupalGet('node/3');
|
189
|
$this->assertNoTaxonomyTerm('Washington DC');
|
190
|
|
191
|
// Change the mapping configuration.
|
192
|
$this->removeMappings('syndication', $mappings);
|
193
|
// Turn on autocreate.
|
194
|
$mappings[5]['autocreate'] = TRUE;
|
195
|
$this->addMappings('syndication', $mappings);
|
196
|
$this->drupalPost('node/' . $nid . '/import', array(), t('Import'));
|
197
|
$this->assertText('Updated 10 nodes.');
|
198
|
|
199
|
$this->drupalGet('node/2');
|
200
|
foreach ($terms as $term) {
|
201
|
$this->assertTaxonomyTerm($term);
|
202
|
}
|
203
|
$this->drupalGet('node/3');
|
204
|
$this->assertTaxonomyTerm('Washington DC');
|
205
|
|
206
|
$names = db_query('SELECT name FROM {taxonomy_term_data}')->fetchCol();
|
207
|
$this->assertEqual(count($names), 31, 'Found correct number of terms in the database.');
|
208
|
|
209
|
// Run import again. This verifys that the terms we found by name.
|
210
|
$this->drupalPost('node/' . $nid . '/import', array(), t('Import'));
|
211
|
$this->assertText('Updated 10 nodes.');
|
212
|
$names = db_query('SELECT name FROM {taxonomy_term_data}')->fetchCol();
|
213
|
$this->assertEqual(count($names), 31, 'Found correct number of terms in the database.');
|
214
|
}
|
215
|
|
216
|
/**
|
217
|
* Tests mapping to taxonomy terms by tid.
|
218
|
*/
|
219
|
public function testSearchByID() {
|
220
|
// Create 10 terms. The first one was created in setup.
|
221
|
$terms = array(1);
|
222
|
foreach (range(2, 10) as $i) {
|
223
|
$term = (object) array(
|
224
|
'name' => 'term' . $i,
|
225
|
'vid' => 1,
|
226
|
);
|
227
|
taxonomy_term_save($term);
|
228
|
$terms[] = $term->tid;
|
229
|
}
|
230
|
|
231
|
FeedsPlugin::loadMappers();
|
232
|
|
233
|
$entity = new stdClass();
|
234
|
$target = 'field_tags';
|
235
|
$mapping = array(
|
236
|
'term_search' => FEEDS_TAXONOMY_SEARCH_TERM_ID,
|
237
|
'language' => LANGUAGE_NONE,
|
238
|
);
|
239
|
|
240
|
$source = FeedsSource::instance('tmp', 0);
|
241
|
|
242
|
taxonomy_feeds_set_target($source, $entity, $target, $terms, $mapping);
|
243
|
$this->assertEqual(count($entity->field_tags[LANGUAGE_NONE]), 10);
|
244
|
|
245
|
// Test a second mapping with a bogus term id.
|
246
|
taxonomy_feeds_set_target($source, $entity, $target, array(1234), $mapping);
|
247
|
$this->assertEqual(count($entity->field_tags[LANGUAGE_NONE]), 10);
|
248
|
}
|
249
|
|
250
|
/**
|
251
|
* Tests mapping to a taxonomy term's guid.
|
252
|
*/
|
253
|
public function testSearchByGUID() {
|
254
|
// Create 10 terms. The first one was created in setup.
|
255
|
$tids = array(1);
|
256
|
foreach (range(2, 10) as $i) {
|
257
|
$term = (object) array(
|
258
|
'name' => 'term' . $i,
|
259
|
'vid' => 1,
|
260
|
);
|
261
|
taxonomy_term_save($term);
|
262
|
$tids[] = $term->tid;
|
263
|
}
|
264
|
|
265
|
// Create a bunch of bogus imported terms.
|
266
|
$guids = array();
|
267
|
foreach ($tids as $tid) {
|
268
|
$guid = 100 * $tid;
|
269
|
$guids[] = $guid;
|
270
|
$record = array(
|
271
|
'entity_type' => 'taxonomy_term',
|
272
|
'entity_id' => $tid,
|
273
|
'id' => 'does_not_exist',
|
274
|
'feed_nid' => 0,
|
275
|
'imported' => REQUEST_TIME,
|
276
|
'url' => '',
|
277
|
'guid' => $guid,
|
278
|
);
|
279
|
drupal_write_record('feeds_item', $record);
|
280
|
}
|
281
|
|
282
|
FeedsPlugin::loadMappers();
|
283
|
|
284
|
$entity = new stdClass();
|
285
|
$target = 'field_tags';
|
286
|
$mapping = array(
|
287
|
'term_search' => FEEDS_TAXONOMY_SEARCH_TERM_GUID,
|
288
|
'language' => LANGUAGE_NONE,
|
289
|
);
|
290
|
|
291
|
$source = FeedsSource::instance('tmp', 0);
|
292
|
|
293
|
taxonomy_feeds_set_target($source, $entity, $target, $guids, $mapping);
|
294
|
$this->assertEqual(count($entity->field_tags[LANGUAGE_NONE]), 10);
|
295
|
foreach ($entity->field_tags[LANGUAGE_NONE] as $delta => $values) {
|
296
|
$this->assertEqual($tids[$delta], $values['tid'], 'Correct term id foud.');
|
297
|
}
|
298
|
|
299
|
// Test a second mapping with a bogus term id.
|
300
|
taxonomy_feeds_set_target($source, $entity, $target, array(1234), $mapping);
|
301
|
$this->assertEqual(count($entity->field_tags[LANGUAGE_NONE]), 10);
|
302
|
foreach ($entity->field_tags[LANGUAGE_NONE] as $delta => $values) {
|
303
|
$this->assertEqual($tids[$delta], $values['tid'], 'Correct term id foud.');
|
304
|
}
|
305
|
}
|
306
|
|
307
|
/**
|
308
|
* Tests importing empty values
|
309
|
*/
|
310
|
public function testBlankSourceValues() {
|
311
|
// Create a CSV importer configuration.
|
312
|
$this->createImporterConfiguration('Node import from CSV', 'node');
|
313
|
$this->setPlugin('node', 'FeedsFileFetcher');
|
314
|
$this->setPlugin('node', 'FeedsCSVParser');
|
315
|
$this->setSettings('node', 'FeedsNodeProcessor', array('bundle' => 'article'));
|
316
|
$this->setSettings('node', NULL, array('content_type' => ''));
|
317
|
$this->addMappings('node', array(
|
318
|
0 => array(
|
319
|
'source' => 'title',
|
320
|
'target' => 'title',
|
321
|
),
|
322
|
1 => array(
|
323
|
'source' => 'tags',
|
324
|
'target' => 'field_tags',
|
325
|
'term_search' => 0,
|
326
|
'autocreate' => 1,
|
327
|
),
|
328
|
2 => array(
|
329
|
'source' => 'guid',
|
330
|
'target' => 'guid',
|
331
|
'unique' => TRUE,
|
332
|
),
|
333
|
));
|
334
|
|
335
|
// Verify that there are 5 nodes total.
|
336
|
$this->importFile('node', $this->absolutePath() . '/tests/feeds/taxonomy_empty_terms.csv');
|
337
|
$this->assertText('Created 5 nodes');
|
338
|
|
339
|
// Make sure only two terms were added
|
340
|
$names = db_query('SELECT name FROM {taxonomy_term_data}')->fetchCol();
|
341
|
$this->assertEqual(count($names), 2, 'Found correct number of terms in the database.');
|
342
|
|
343
|
// Make sure the correct terms were created
|
344
|
$terms = array(
|
345
|
'term1',
|
346
|
'0',
|
347
|
);
|
348
|
foreach ($terms as $term_name) {
|
349
|
$this->assertTrue(in_array($term_name, $names), 'Correct term created');
|
350
|
}
|
351
|
}
|
352
|
|
353
|
/**
|
354
|
* Tests that there are no errors when trying to map to an invalid vocabulary.
|
355
|
*/
|
356
|
public function testMissingVocabulary() {
|
357
|
$this->addMappings('syndication', array(
|
358
|
5 => array(
|
359
|
'source' => 'tags',
|
360
|
'target' => 'field_tags',
|
361
|
'term_search' => 0,
|
362
|
'autocreate' => TRUE,
|
363
|
),
|
364
|
));
|
365
|
|
366
|
// Create an invalid configuration.
|
367
|
db_delete('taxonomy_vocabulary')->execute();
|
368
|
|
369
|
$this->createFeedNode('syndication', NULL, 'Syndication');
|
370
|
$this->assertText('Created 10 nodes.');
|
371
|
}
|
372
|
|
373
|
/**
|
374
|
* Tests if values are cleared out when an empty value or no value
|
375
|
* is provided.
|
376
|
*/
|
377
|
public function testClearOutValues() {
|
378
|
// Create a CSV importer configuration.
|
379
|
$this->createImporterConfiguration('Node import from CSV', 'node');
|
380
|
$this->setSettings('node', NULL, array(
|
381
|
'content_type' => '',
|
382
|
));
|
383
|
$this->setPlugin('node', 'FeedsFileFetcher');
|
384
|
$this->setPlugin('node', 'FeedsCSVParser');
|
385
|
$this->setSettings('node', 'FeedsNodeProcessor', array(
|
386
|
'bundle' => 'article',
|
387
|
'update_existing' => 1,
|
388
|
));
|
389
|
$this->addMappings('node', array(
|
390
|
0 => array(
|
391
|
'source' => 'title',
|
392
|
'target' => 'title',
|
393
|
),
|
394
|
1 => array(
|
395
|
'source' => 'alpha',
|
396
|
'target' => 'field_tags',
|
397
|
'term_search' => 0,
|
398
|
'autocreate' => 1,
|
399
|
),
|
400
|
2 => array(
|
401
|
'source' => 'guid',
|
402
|
'target' => 'guid',
|
403
|
'unique' => TRUE,
|
404
|
),
|
405
|
));
|
406
|
|
407
|
$this->importFile('node', $this->absolutePath() . '/tests/feeds/content.csv');
|
408
|
$this->assertText('Created 2 nodes');
|
409
|
|
410
|
// Check the imported nodes.
|
411
|
$terms1 = taxonomy_get_term_by_name('Lorem');
|
412
|
$term1 = reset($terms1);
|
413
|
$terms2 = taxonomy_get_term_by_name('Ut wisi');
|
414
|
$term2 = reset($terms2);
|
415
|
$taxonomy_values = array(
|
416
|
1 => $term1->tid,
|
417
|
2 => $term2->tid,
|
418
|
);
|
419
|
for ($i = 1; $i <= 2; $i++) {
|
420
|
$this->drupalGet("node/$i/edit");
|
421
|
$this->assertFieldByName('field_tags[und][]', $taxonomy_values[$i]);
|
422
|
}
|
423
|
|
424
|
// Import CSV file with empty values.
|
425
|
$this->importFile('node', $this->absolutePath() . '/tests/feeds/content_empty.csv');
|
426
|
$this->assertText('Updated 2 nodes');
|
427
|
|
428
|
// Check if the taxonomy reference field was cleared out for node 1.
|
429
|
$this->drupalGet('node/1/edit');
|
430
|
$this->assertFieldByName('field_tags[und][]', '_none');
|
431
|
$this->drupalGet('node/1');
|
432
|
$this->assertNoText('field_tags');
|
433
|
|
434
|
// Check if zero's didn't cleared out the taxonomy reference field for
|
435
|
// node 2.
|
436
|
$terms0 = taxonomy_get_term_by_name('0');
|
437
|
$term0 = reset($terms0);
|
438
|
$this->drupalGet('node/2/edit');
|
439
|
$this->assertFieldByName('field_tags[und][]', $term0->tid);
|
440
|
$this->drupalGet('node/2');
|
441
|
$this->assertText('field_tags');
|
442
|
|
443
|
// Re-import the first file again and check if the values returned.
|
444
|
$this->importFile('node', $this->absolutePath() . '/tests/feeds/content.csv');
|
445
|
$this->assertText('Updated 2 nodes');
|
446
|
for ($i = 1; $i <= 2; $i++) {
|
447
|
$this->drupalGet("node/$i/edit");
|
448
|
$this->assertFieldByName('field_tags[und][]', $taxonomy_values[$i]);
|
449
|
}
|
450
|
|
451
|
// Import CSV file with non-existent values.
|
452
|
$this->importFile('node', $this->absolutePath() . '/tests/feeds/content_non_existent.csv');
|
453
|
$this->assertText('Updated 2 nodes');
|
454
|
|
455
|
// Check if the taxonomy reference field was cleared out for node 1.
|
456
|
$this->drupalGet('node/1/edit');
|
457
|
$this->assertFieldByName('field_tags[und][]', '_none');
|
458
|
$this->drupalGet('node/1');
|
459
|
$this->assertNoText('field_tags');
|
460
|
}
|
461
|
|
462
|
/**
|
463
|
* Finds node style taxonomy term markup in DOM.
|
464
|
*/
|
465
|
public function assertTaxonomyTerm($term) {
|
466
|
$term = check_plain($term);
|
467
|
$this->assertPattern('/<a href="\/.*taxonomy\/term\/[0-9]+">' . $term . '<\/a>/', 'Found ' . $term);
|
468
|
}
|
469
|
|
470
|
/**
|
471
|
* Asserts that the term does not exist on a node page.
|
472
|
*/
|
473
|
public function assertNoTaxonomyTerm($term) {
|
474
|
$term = check_plain($term);
|
475
|
$this->assertNoPattern('/<a href="\/.*taxonomy\/term\/[0-9]+">' . $term . '<\/a>/', 'Did not find ' . $term);
|
476
|
}
|
477
|
|
478
|
}
|