Projet

Général

Profil

Paste
Télécharger (51,4 ko) Statistiques
| Branche: | Révision:

root / drupal7 / sites / all / modules / field_collection / field_collection.test @ 31a5a6d6

1 31a5a6d6 Assos Assos
<?php
2
3
/**
4
 * @file
5
 * field_collections tests.
6
 */
7
8
/**
9
 * Test basics.
10
 */
11
class FieldCollectionBasicTestCase extends DrupalWebTestCase {
12
13
  public static function getInfo() {
14
    return array(
15
      'name' => 'Field collection',
16
      'description' => 'Tests creating and using field collections.',
17
      'group' => 'Field types',
18
    );
19
  }
20
21
  function setUp() {
22
    parent::setUp('field_collection', 'entity_crud_hook_test');
23
24
    // Create a field_collection field to use for the tests.
25
    $this->field_name = 'field_test_collection';
26
    $this->field = array('field_name' => $this->field_name, 'type' => 'field_collection', 'cardinality' => 4);
27
    $this->field = field_create_field($this->field);
28
    $this->field_id = $this->field['id'];
29
30
    $this->instance = array(
31
      'field_name' => $this->field_name,
32
      'entity_type' => 'node',
33
      'bundle' => 'article',
34
      'label' => $this->randomName() . '_label',
35
      'description' => $this->randomName() . '_description',
36
      'weight' => mt_rand(0, 127),
37
      'settings' => array(),
38
      'widget' => array(
39
        'type' => 'hidden',
40
        'label' => 'Test',
41
        'settings' => array(),
42
      ),
43
    );
44
    $this->instance = field_create_instance($this->instance);
45
  }
46
47
  /**
48
   * Pass if the message $text was set by one of the CRUD hooks in
49
   * entity_crud_hook_test.module, i.e., if the $text is an element of
50
   * $_SESSION['entity_crud_hook_test'].
51
   *
52
   * @see EntityCrudHookTestCase::assertHookMessage()
53
   * @see FieldCollectionBasicTestCase::assertNoHookMessage()
54
   * @see FieldCollectionBasicTestCase::clearHookMessages()
55
   *
56
   * @param $text
57
   *   Plain text to look for.
58
   * @param $message
59
   *   Message to display.
60
   * @param $group
61
   *   The group this message belongs to, defaults to 'Other'.
62
   * @return
63
   *   TRUE on pass, FALSE on fail.
64
   */
65
  protected function assertHookMessage($text, $message = NULL, $group = 'Other') {
66
    if (!isset($message)) {
67
      $message = $text;
68
    }
69
    return $this->assertTrue(array_search($text, $_SESSION['entity_crud_hook_test']) !== FALSE, $message, $group);
70
  }
71
72
  /**
73
   * Fail if the message $text was set by one of the CRUD hooks in
74
   * entity_crud_hook_test.module, i.e., if the $text is an element of
75
   * $_SESSION['entity_crud_hook_test'].
76
   *
77
   * @see FieldCollectionBasicTestCase::assertHookMessage()
78
   * @see FieldCollectionBasicTestCase::clearHookMessages()
79
   *
80
   * @param $text
81
   *   Plain text to look for.
82
   * @param $message
83
   *   Message to display.
84
   * @param $group
85
   *   The group this message belongs to, defaults to 'Other'.
86
   * @return
87
   *   TRUE on pass, FALSE on fail.
88
   */
89
  protected function assertNoHookMessage($text, $message = NULL, $group = 'Other') {
90
    if (!isset($message)) {
91
      $message = $text;
92
    }
93
    return $this->assertFalse(array_search($text, $_SESSION['entity_crud_hook_test']) !== FALSE, $message, $group);
94
  }
95
96
  /**
97
   * Clear hook messages recorded by entity_crud_hook_test.
98
   *
99
   * @see FieldCollectionBasicTestCase::assertHookMessage()
100
   * @see FieldCollectionBasicTestCase::assertNoHookMessage()
101
   */
102
  protected function clearHookMessages() {
103
    $_SESSION['entity_crud_hook_test'] = array();
104
  }
105
106
  /**
107
   * Helper for creating a new node with a field collection item.
108
   */
109
  protected function createNodeWithFieldCollection() {
110
    $node = $this->drupalCreateNode(array('type' => 'article'));
111
    // Manually create a field_collection.
112
    $entity = entity_create('field_collection_item', array('field_name' => $this->field_name));
113
    $entity->setHostEntity('node', $node);
114
    $entity->save();
115
116
    return array($node, $entity);
117
  }
118
119
  /**
120
   * Tests CRUD.
121
   */
122
  function testCRUD() {
123
    list ($node, $entity) = $this->createNodeWithFieldCollection();
124
    $node = node_load($node->nid, NULL, TRUE);
125
    $this->assertEqual($entity->item_id, $node->{$this->field_name}[LANGUAGE_NONE][0]['value'], 'A field_collection has been successfully created and referenced.');
126
    $this->assertEqual($entity->revision_id, $node->{$this->field_name}[LANGUAGE_NONE][0]['revision_id'], 'A field_collection has been successfully created and referenced.');
127
128
    // Test adding an additional field_collection during node edit.
129
    $entity2 = entity_create('field_collection_item', array('field_name' => $this->field_name));
130
    $node->{$this->field_name}[LANGUAGE_NONE][] = array('entity' => $entity2);
131
    node_save($node);
132
133
    $node = node_load($node->nid, NULL, TRUE);
134
    $this->assertTrue(!empty($entity2->item_id) && !empty($entity2->revision_id), 'Field_collection has been saved.');
135
    $this->assertEqual($entity->item_id, $node->{$this->field_name}[LANGUAGE_NONE][0]['value'], 'Existing reference has been kept during update.');
136
    $this->assertEqual($entity->revision_id, $node->{$this->field_name}[LANGUAGE_NONE][0]['revision_id'], 'Existing reference has been kept during update (revision).');
137
    $this->assertEqual($entity2->item_id, $node->{$this->field_name}[LANGUAGE_NONE][1]['value'], 'New field_collection has been properly referenced');
138
    $this->assertEqual($entity2->revision_id, $node->{$this->field_name}[LANGUAGE_NONE][1]['revision_id'], 'New field_collection has been properly referenced (revision)');
139
140
    // Make sure deleting the field_collection removes the reference.
141
    $this->clearHookMessages();
142
    $entity2->delete();
143
    $this->assertHookMessage('entity_crud_hook_test_entity_presave called for type node');
144
    $node = node_load($node->nid, NULL, TRUE);
145
    $this->assertTrue(!isset($node->{$this->field_name}[LANGUAGE_NONE][1]), 'Reference correctly deleted.');
146
147
    // Make sure field_collections are removed during deletion of the host.
148
    $this->clearHookMessages();
149
    node_delete($node->nid);
150
    $this->assertNoHookMessage('entity_crud_hook_test_entity_presave called for type node');
151
    $this->assertTrue(entity_load('field_collection_item', FALSE) === array(), 'Field collections are deleted when the host is deleted.');
152
153
    // Try deleting nodes with collections without any values.
154
    $node = $this->drupalCreateNode(array('type' => 'article'));
155
    node_delete($node->nid);
156
    $this->assertTrue(node_load($node->nid, NULL, TRUE) == FALSE, 'Node without collection values deleted.');
157
158
    // Test creating a field collection entity with a not-yet saved host entity.
159
    $node = entity_create('node', array('type' => 'article'));
160
    $entity = entity_create('field_collection_item', array('field_name' => $this->field_name));
161
    $entity->setHostEntity('node', $node);
162
    $entity->save();
163
    // Now the node should have been saved with the collection and the link
164
    // should have been established.
165
    $this->assertTrue(!empty($node->nid), 'Node has been saved with the collection.');
166
    $this->assertTrue(count($node->{$this->field_name}[LANGUAGE_NONE]) == 1 && !empty($node->{$this->field_name}[LANGUAGE_NONE][0]['value']) && !empty($node->{$this->field_name}[LANGUAGE_NONE][0]['revision_id']), 'Link has been established.');
167
168
    // Again, test creating a field collection with a not-yet saved host entity,
169
    // but this time save both entities via the host.
170
    $node = entity_create('node', array('type' => 'article'));
171
    $entity = entity_create('field_collection_item', array('field_name' => $this->field_name));
172
    $entity->setHostEntity('node', $node);
173
    node_save($node);
174
    $this->assertTrue(!empty($entity->item_id) && !empty($entity->revision_id), 'Collection has been saved with the host.');
175
    $this->assertTrue(count($node->{$this->field_name}[LANGUAGE_NONE]) == 1 && !empty($node->{$this->field_name}[LANGUAGE_NONE][0]['value']) && !empty($node->{$this->field_name}[LANGUAGE_NONE][0]['revision_id']), 'Link has been established.');
176
177
    // Test Revisions.
178
    list ($node, $item) = $this->createNodeWithFieldCollection();
179
    $entity2 = entity_create('field_collection_item', array('field_name' => $this->field_name));
180
    $node->{$this->field_name}[LANGUAGE_NONE][] = array('entity' => $entity2);
181
    node_save($node);
182
    $this->assertEqual($entity2->archived, FALSE, 'New field collection item with new content revision is not archived.');
183
184
    // Test saving a new revision of a node.
185
    $node->revision = TRUE;
186
    node_save($node);
187
    $item_updated = field_collection_item_load($node->{$this->field_name}[LANGUAGE_NONE][0]['value']);
188
    $this->assertNotEqual($item->revision_id, $item_updated->revision_id, 'Creating a new host entity revision creates a new field collection revision.');
189
190
    // Test saving a new revision with a new field collection item.
191
    $node->revision = TRUE;
192
193
    // Test saving the node without creating a new revision.
194
    $item = $item_updated;
195
    $node->revision = FALSE;
196
    node_save($node);
197
    $item_updated = field_collection_item_load($node->{$this->field_name}[LANGUAGE_NONE][0]['value']);
198
    $this->assertEqual($item->revision_id, $item_updated->revision_id, 'Updating a new host entity  without creating a new revision does not create a new field collection revision.');
199
200
    // Create a new revision of the node, such we have a non default node and
201
    // field collection revision. Then test using it.
202
    $vid = $node->vid;
203
    $item_revision_id = $item_updated->revision_id;
204
    $node->revision = TRUE;
205
    node_save($node);
206
207
    $item_updated = field_collection_item_load($node->{$this->field_name}[LANGUAGE_NONE][0]['value']);
208
    $this->assertNotEqual($item_revision_id, $item_updated->revision_id, 'Creating a new host entity revision creates a new field collection revision.');
209
    $this->assertTrue($item_updated->isDefaultRevision(), 'Field collection of default host entity revision is default too.');
210
    $this->assertEqual($item_updated->hostEntityId(), $node->nid, 'Can access host entity ID of default field collection revision.');
211
    $this->assertEqual($item_updated->hostEntity()->vid, $node->vid, 'Loaded default host entity revision.');
212
213
    $item = entity_revision_load('field_collection_item', $item_revision_id);
214
    $this->assertFalse($item->isDefaultRevision(), 'Field collection of non-default host entity is non-default too.');
215
    $this->assertEqual($item->hostEntityId(), $node->nid, 'Can access host entity ID of non-default field collection revision.');
216
    $this->assertEqual($item->hostEntity()->vid, $vid, 'Loaded non-default host entity revision.');
217
218
    // Delete the non-default revision and make sure the field collection item
219
    // revision has been deleted too.
220
    entity_revision_delete('node', $vid);
221
    $this->assertFalse(entity_revision_load('node', $vid), 'Host entity revision deleted.');
222
    $this->assertFalse(entity_revision_load('field_collection_item', $item_revision_id), 'Field collection item revision deleted.');
223
224
    // Test having archived field collections, i.e. collections referenced only
225
    // in non-default revisions.
226
    list ($node, $item) = $this->createNodeWithFieldCollection();
227
    // Create two revisions.
228
    $node_vid = $node->vid;
229
    $node->revision = TRUE;
230
    node_save($node);
231
232
    $node_vid2 = $node->vid;
233
    $node->revision = TRUE;
234
    node_save($node);
235
236
    // Now delete the field collection item for the default revision.
237
    $item = field_collection_item_load($node->{$this->field_name}[LANGUAGE_NONE][0]['value']);
238
    $item_revision_id = $item->revision_id;
239
    $item->deleteRevision();
240
    $node = node_load($node->nid);
241
    $this->assertTrue(!isset($node->{$this->field_name}[LANGUAGE_NONE][0]), 'Field collection item revision removed from host.');
242
    $this->assertFalse(field_collection_item_revision_load($item->revision_id), 'Field collection item default revision deleted.');
243
244
    $item = field_collection_item_load($item->item_id);
245
    $this->assertNotEqual($item->revision_id, $item_revision_id, 'Field collection default revision has been updated.');
246
    $this->assertTrue($item->archived, 'Field collection item has been archived.');
247
    $this->assertFalse($item->isInUse(), 'Field collection item specified as not in use.');
248
    $this->assertTrue($item->isDefaultRevision(), 'Field collection of non-default host entity is default (but archived).');
249
    $this->assertEqual($item->hostEntityId(), $node->nid, 'Can access host entity ID of non-default field collection revision.');
250
    $this->assertEqual($item->hostEntity()->nid, $node->nid, 'Loaded non-default host entity revision.');
251
252
    // Test deleting a revision of an archived field collection.
253
    $node_revision2 = node_load($node->nid, $node_vid2);
254
    $item = field_collection_item_revision_load($node_revision2->{$this->field_name}[LANGUAGE_NONE][0]['revision_id']);
255
    $item->deleteRevision();
256
    // There should be one revision left, so the item should still exist.
257
    $item = field_collection_item_load($item->item_id);
258
    $this->assertTrue($item->archived, 'Field collection item is still archived.');
259
    $this->assertFalse($item->isInUse(), 'Field collection item specified as not in use.');
260
261
    // Test that deleting the first node revision deletes the whole field
262
    // collection item as it contains its last revision.
263
    node_revision_delete($node_vid);
264
    $this->assertFalse(field_collection_item_load($item->item_id), 'Archived field collection deleted when last revision deleted.');
265
266
    // Test that removing a field-collection item also deletes it.
267
    list ($node, $item) = $this->createNodeWithFieldCollection();
268
269
    $node->{$this->field_name}[LANGUAGE_NONE] = array();
270
    $node->revision = FALSE;
271
    node_save($node);
272
    $this->assertFalse(field_collection_item_load($item->item_id), 'Removed field collection item has been deleted.');
273
274
    // Test removing a field-collection item while creating a new host revision.
275
    list ($node, $item) = $this->createNodeWithFieldCollection();
276
    $node->{$this->field_name}[LANGUAGE_NONE] = array();
277
    $node->revision = TRUE;
278
    node_save($node);
279
    // Item should not be deleted but archived now.
280
    $item = field_collection_item_load($item->item_id);
281
    $this->assertTrue($item, 'Removed field collection item still exists.');
282
    $this->assertTrue($item->archived, 'Removed field collection item is archived.');
283
284
    // Test removing an old node revision. Make sure that the field collection
285
    // is not removed
286
    list ($node, $item) = $this->createNodeWithFieldCollection();
287
    $node_vid = $node->vid;
288
    $node->revision = TRUE;
289
    node_save($node);
290
    $node_vid2 = $node->vid;
291
    $item_vid2 = $node->{$this->field_name}[LANGUAGE_NONE][0]['revision_id'];
292
    node_revision_delete($node_vid);
293
    $item2 = field_collection_item_revision_load($item_vid2);
294
    $item_id2 = isset($item2->item_id) ? $item2->item_id : -1;
295
    $this->assertEqual($item_id2, $item->item_id, 'Removing an old node revision does not delete newer field collection revisions');
296
297
  }
298
299
  /**
300
   * Make sure the basic UI and access checks are working.
301
   */
302
  function testBasicUI() {
303
    // Add a field to the collection.
304
    $field = array(
305
      'field_name' => 'field_text',
306
      'type' => 'text',
307
      'cardinality' => 1,
308
      'translatable' => FALSE,
309
    );
310
    field_create_field($field);
311
    $instance = array(
312
      'entity_type' => 'field_collection_item',
313
      'field_name' => 'field_text',
314
      'bundle' => $this->field_name,
315
      'label' => 'Test text field',
316
      'widget' => array(
317
        'type' => 'text_textfield',
318
      ),
319
    );
320
    field_create_instance($instance);
321
322
    $user = $this->drupalCreateUser();
323
    $node = $this->drupalCreateNode(array('type' => 'article'));
324
325
    $this->drupalLogin($user);
326
    // Make sure access is denied.
327
    $path = 'field-collection/field-test-collection/add/node/' . $node->nid;
328
    $this->drupalGet($path);
329
    $this->assertText(t('Access denied'), 'Access has been denied.');
330
331
    $user_privileged = $this->drupalCreateUser(array('access content', 'edit any article content'));
332
    $this->drupalLogin($user_privileged);
333
    $this->drupalGet("node/$node->nid");
334
    $this->assertLinkByHref($path, 0, 'Add link is shown.');
335
    $this->drupalGet($path);
336
    $this->assertText(t('Test text field'), 'Add form is shown.');
337
338
    $edit['field_text[und][0][value]'] = $this->randomName();
339
    $this->drupalPost($path, $edit, t('Save'));
340
    $this->assertText(t('The changes have been saved.'), 'Field collection saved.');
341
342
    $this->assertText($edit['field_text[und][0][value]'], "Added field value is shown.");
343
344
    $edit['field_text[und][0][value]'] = $this->randomName();
345
    $this->drupalPost('field-collection/field-test-collection/1/edit', $edit, t('Save'));
346
    $this->assertText(t('The changes have been saved.'), 'Field collection saved.');
347
    $this->assertText($edit['field_text[und][0][value]'], "Field collection has been edited.");
348
349
    $this->drupalGet('field-collection/field-test-collection/1');
350
    $this->assertText($edit['field_text[und][0][value]'], "Field collection can be viewed.");
351
352
    // Add further 3 items, so we have reached 4 == maxium cardinality.
353
    $this->drupalPost($path, $edit, t('Save'));
354
    $this->drupalPost($path, $edit, t('Save'));
355
    $this->drupalPost($path, $edit, t('Save'));
356
    // Make sure adding doesn't work any more as we have restricted cardinality
357
    // to 1.
358
    $this->drupalGet($path);
359
    $this->assertText(t('Too many items.'), 'Maxium cardinality has been reached.');
360
361
    $this->drupalPost('field-collection/field-test-collection/1/delete', array(), t('Delete'));
362
    $this->drupalGet($path);
363
    // Add form is shown again.
364
    $this->assertText(t('Test text field'), 'Field collection item has been deleted.');
365
366
    // Test the viewing a revision. There should be no links to change it.
367
    $vid = $node->vid;
368
    $node = node_load($node->nid, NULL, TRUE);
369
    $node->revision = TRUE;
370
    node_save($node);
371
372
    $this->drupalGet("node/$node->nid/revisions/$vid/view");
373
    $this->assertResponse(403, 'Access to view revision denied');
374
    // Login in as admin and try again.
375
    $user = $this->drupalCreateUser(array('administer nodes', 'bypass node access'));
376
    $this->drupalLogin($user);
377
    $this->drupalGet("node/$node->nid/revisions/$vid/view");
378
    $this->assertNoResponse(403, 'Access to view revision granted');
379
380
    $this->assertNoLinkByHref($path, 'No links on revision view.');
381
    $this->assertNoLinkByHref('field-collection/field-test-collection/2/edit', 'No links on revision view.');
382
    $this->assertNoLinkByHref('field-collection/field-test-collection/2/delete', 'No links on revision view.');
383
384
    $this->drupalGet("node/$node->nid/revisions");
385
  }
386
387
  /**
388
   * Make sure that field_collection-entities are copied when host-entities do.
389
   */
390
  public function testCopyingEntities() {
391
    list($node, $entity) = $this->createNodeWithFieldCollection();
392
393
    // Create a copy of that node.
394
    $node->nid = NULL;
395
    $node->vid = NULL;
396
    $node->is_new = TRUE;
397
398
    node_save($node);
399
    $item = $node->{$this->field_name}[LANGUAGE_NONE][0];
400
    $this->assertNotEqual($entity->item_id, $item['value']);
401
402
    // Do a php clone to the $node object and save it.
403
    $node2 = clone $node;
404
    $node2->nid = NULL;
405
    $node2->is_new = TRUE;
406
    $node2->vid = NULL;
407
    node_save($node2);
408
409
    $item2 = $node2->{$this->field_name}[LANGUAGE_NONE][0];
410
    $this->assertNotEqual($item2['value'], $item['value']);
411
412
    // Create another copy this time (needlessly) forcing a new revision.
413
    $node->nid = NULL;
414
    $node->vid = NULL;
415
    $node->is_new = TRUE;
416
    $node->revision = TRUE;
417
    node_save($node);
418
    $item3 = $node->{$this->field_name}[LANGUAGE_NONE][0];
419
    $this->assertNotEqual($item['value'], $item3['value']);
420
  }
421
422
}
423
424
425
/**
426
 * Test using field collection with Rules.
427
 */
428
class FieldCollectionRulesIntegrationTestCase extends DrupalWebTestCase {
429
430
  public static function getInfo() {
431
    return array(
432
      'name' => 'Field collection Rules integration',
433
      'description' => 'Tests using field collections with rules.',
434
      'group' => 'Field types',
435
      'dependencies' => array('rules'),
436
    );
437
  }
438
439
  function setUp() {
440
    parent::setUp(array('field_collection', 'rules'));
441
    variable_set('rules_debug_log', 1);
442
  }
443
444
  protected function createFields($cardinality = 4) {
445
    // Create a field_collection field to use for the tests.
446
    $this->field_name = 'field_test_collection';
447
    $this->field = array('field_name' => $this->field_name, 'type' => 'field_collection', 'cardinality' => $cardinality);
448
    $this->field = field_create_field($this->field);
449
    $this->field_id = $this->field['id'];
450
451
    $this->instance = array(
452
      'field_name' => $this->field_name,
453
      'entity_type' => 'node',
454
      'bundle' => 'article',
455
      'label' => $this->randomName() . '_label',
456
      'description' => $this->randomName() . '_description',
457
      'weight' => mt_rand(0, 127),
458
      'settings' => array(),
459
      'widget' => array(
460
        'type' => 'hidden',
461
        'label' => 'Test',
462
        'settings' => array(),
463
      ),
464
    );
465
    $this->instance = field_create_instance($this->instance);
466
    // Add a field to the collection.
467
    $field = array(
468
      'field_name' => 'field_text',
469
      'type' => 'text',
470
      'cardinality' => 1,
471
      'translatable' => FALSE,
472
    );
473
    field_create_field($field);
474
    $instance = array(
475
      'entity_type' => 'field_collection_item',
476
      'field_name' => 'field_text',
477
      'bundle' => $this->field_name,
478
      'label' => 'Test text field',
479
      'widget' => array(
480
        'type' => 'text_textfield',
481
      ),
482
    );
483
    field_create_instance($instance);
484
  }
485
486
  /**
487
   * Test creation field collection items.
488
   */
489
  function testCreation() {
490
    $this->createFields();
491
492
    $node = $this->drupalCreateNode(array('type' => 'article'));
493
    // Create a field collection.
494
    $action_set = rules_action_set(array('node' => array('type' => 'node', 'bundle' => 'article')));
495
    $action_set->action('entity_create', array(
496
      'type' => 'field_collection_item',
497
      'param_field_name' => $this->field_name,
498
      'param_host_entity:select' => 'node',
499
    ));
500
    $action_set->action('data_set', array('data:select' => 'entity-created:field-text', 'value' => 'foo'));
501
    $action_set->execute($node);
502
503
    $node = node_load($node->nid, NULL, TRUE);
504
    $this->assertTrue(!empty($node->{$this->field_name}[LANGUAGE_NONE][0]['value']), 'A field_collection has been successfully created.');
505
    $this->assertTrue(!empty($node->{$this->field_name}[LANGUAGE_NONE][0]['revision_id']), 'A field_collection has been successfully created (revision).');
506
507
    // Now try making use of the field collection in rules.
508
    $action_set = rules_action_set(array('node' => array('type' => 'node', 'bundle' => 'article')));
509
    $action_set->action('drupal_message', array('message:select' => 'node:field-test-collection:0:field-text'));
510
    $action_set->execute($node);
511
512
    $msg = drupal_get_messages();
513
    $this->assertEqual(array_pop($msg['status']), 'foo', 'Field collection can be used.');
514
    RulesLog::logger()->checkLog();
515
  }
516
517
  /**
518
   * Test using field collection items via the host while they are being created.
519
   */
520
  function testUsageDuringCreation() {
521
    // Test using a single-cardinality field collection.
522
    $this->createFields(1);
523
524
    $node = $this->drupalCreateNode(array('type' => 'article'));
525
    $entity = entity_create('field_collection_item', array('field_name' => $this->field_name));
526
    $entity->setHostEntity('node', $node);
527
    // Now the field collection is linked to the host, but not yet saved.
528
529
    // Test using the wrapper on it.
530
    $wrapper = entity_metadata_wrapper('node', $node);
531
    $wrapper->get($this->field_name)->field_text->set('foo');
532
    $this->assertEqual($entity->field_text[LANGUAGE_NONE][0]['value'], 'foo', 'Field collection item used during creation via the wrapper.');
533
534
    // Now test it via Rules, which should save our changes.
535
    $set = rules_action_set(array('node' => array('type' => 'node', 'bundle' => 'article')));
536
    $set->action('data_set', array('data:select' => 'node:' . $this->field_name . ':field-text', 'value' => 'bar'));
537
    $set->execute($node);
538
    $this->assertEqual($entity->field_text[LANGUAGE_NONE][0]['value'], 'bar', 'Field collection item used during creation via Rules.');
539
    $this->assertTrue(!empty($entity->item_id) && !empty($entity->revision_id), 'Field collection item has been saved by Rules and the host entity.');
540
    RulesLog::logger()->checkLog();
541
  }
542
}
543
544
/**
545
 * Test using field collection with content that gets translated.
546
 */
547
class FieldCollectionContentTranslationTestCase extends DrupalWebTestCase {
548
549
  public static function getInfo() {
550
    return array(
551
      'name' => 'Field collection content translation',
552
      'description' => 'Tests using content under translation.',
553
      'group' => 'Field types',
554
      'dependencies' => array('translation'),
555
    );
556
  }
557
558
  public function setUp() {
559
    parent::setUp(array('field_collection', 'translation'));
560
    // Create a field_collection field to use for the tests.
561
    $this->field_name = 'field_test_collection';
562
    $this->field = array('field_name' => $this->field_name, 'type' => 'field_collection', 'cardinality' => 4);
563
    $this->field = field_create_field($this->field);
564
    $this->field_id = $this->field['id'];
565
566
    $this->instance = array(
567
      'field_name' => $this->field_name,
568
      'entity_type' => 'node',
569
      'bundle' => 'article',
570
      'label' => $this->randomName() . '_label',
571
      'description' => $this->randomName() . '_description',
572
      'weight' => mt_rand(0, 127),
573
      'settings' => array(),
574
      'widget' => array(
575
        'type' => 'field_collection_embed',
576
        'label' => 'Test',
577
        'settings' => array(),
578
      ),
579
    );
580
    $this->instance = field_create_instance($this->instance);
581
582
    // Add a field to the collection.
583
    $field = array(
584
      'field_name' => 'field_text',
585
      'type' => 'text',
586
      'cardinality' => 1,
587
      'translatable' => FALSE,
588
    );
589
    field_create_field($field);
590
    $instance = array(
591
      'entity_type' => 'field_collection_item',
592
      'field_name' => 'field_text',
593
      'bundle' => $this->field_name,
594
      'label' => 'Test text field',
595
      'widget' => array(
596
        'type' => 'text_textfield',
597
      ),
598
    );
599
    field_create_instance($instance);
600
601
    $admin_user = $this->drupalCreateUser(array('administer languages', 'administer content types', 'access administration pages', 'create article content', 'edit any article content', 'translate content'));
602
603
    $this->drupalLogin($admin_user);
604
    // Add German language.
605
    locale_add_language('de');
606
607
    // Set "Article" content type to use multilingual support.
608
    variable_set('language_content_type_article', TRANSLATION_ENABLED);
609
  }
610
611
  /**
612
   * Ensure field collections are cloned to new entities on content translation.
613
   */
614
  public function testContentTranslation() {
615
    // Create "Article" content.
616
    $edit['title'] = $this->randomName();
617
    $edit['body[' . LANGUAGE_NONE . '][0][value]'] = $this->randomName();
618
    $edit['language'] = 'en';
619
    $field_collection_name = 'field_test_collection[' . LANGUAGE_NONE . '][0][field_text][' . LANGUAGE_NONE . '][0][value]';
620
    $edit[$field_collection_name] = $this->randomName();
621
622
    $this->drupalPost('node/add/article', $edit, t('Save'));
623
    $this->assertRaw(t('Article %title has been created.', array('%title' => $edit['title'])), 'Article created.');
624
    $node1 = $this->drupalGetNodeByTitle($edit['title']);
625
626
    $this->drupalGet('node/' . $node1->nid . '/edit');
627
    $this->drupalGet('node/' . $node1->nid . '/translate');
628
    $this->drupalGet('node/add/article', array('query' => array('translation' => $node1->nid, 'target' => 'de')));
629
630
    // Suffix translations with the langcode.
631
    unset($edit['language']);
632
    $edit['title'] .= 'DE';
633
    $edit[$field_collection_name] .= 'DE';
634
    $this->drupalPost('node/add/article', $edit, t('Save'), array('query' => array('translation' => $node1->nid, 'target' => 'de')));
635
    $node2 = $this->drupalGetNodeByTitle($edit['title']);
636
637
    // Ensure that our new node is the translation of the first one.
638
    $this->assertEqual($node1->nid, $node2->tnid, 'Succesfully created translation.');
639
    // And check to see that their field collections are different.
640
    $this->assertNotEqual($node1->field_test_collection, $node2->field_test_collection, 'Field collections between translation source and translation differ.');
641
  }
642
643
}
644
645
/**
646
 * Test using field collection with content that gets translated with Entity Translation.
647
 */
648
class FieldCollectionEntityTranslationTestCase extends DrupalWebTestCase {
649
  const TRANS_FIELD_EN = 'Translatable EN';
650
  const TRANS_FIELD_DE = 'Translatable DE';
651
  const TRANS_FIELD_DE_MOD = 'Translatable DE Mod';
652
  const UNTRANS_FIELD_EN = 'Untranslatable EN';
653
  const UNTRANS_FIELD_DE = 'Untranslatable DE';
654
  const UNTRANS_FIELD_DE_MOD = 'Untranslatable DE Mod';
655
  const NUM_VALUES = 4;
656
657
  public static function getInfo() {
658
    return array(
659
      'name' => 'Field collection entity translation',
660
      'description' => 'Tests using content under translation with Entity Translation.',
661
      'group' => 'Field types',
662
      'dependencies' => array('entity_translation'),
663
    );
664
  }
665
666
  /**
667
   * Login the given user only if she has not changed.
668
   */
669
  function login($user) {
670
    if (!isset($this->current_user) || $this->current_user->uid != $user->uid) {
671
      $this->current_user = $user;
672
      $this->drupalLogin($user);
673
    }
674
  }
675
676
  /**
677
   * Returns a user with administration rights.
678
   *
679
   * @param $permissions
680
   *   Additional permissions for administrative user.
681
   */
682
  function getAdminUser(array $permissions = array()) {
683
    if (!isset($this->admin_user)) {
684
      $this->admin_user = $this->drupalCreateUser(array_merge(array(
685
        'bypass node access',
686
        'administer nodes',
687
        'administer languages',
688
        'administer content types',
689
        'administer blocks',
690
        'access administration pages',
691
        'administer site configuration',
692
        'administer entity translation',
693
      ), $permissions));
694
    }
695
    return $this->admin_user;
696
  }
697
698
  /**
699
   * Returns a user with minimal translation rights.
700
   *
701
   * @param $permissions
702
   *   Additional permissions for administrative user.
703
   */
704
  function getTranslatorUser(array $permissions = array()) {
705
    if (!isset($this->translator_user)) {
706
      $this->translator_user = $this->drupalCreateUser(array_merge(array(
707
        'create page content',
708
        'edit own page content',
709
        'delete own page content',
710
        'translate any entity',
711
      ), $permissions));
712
    }
713
    return $this->translator_user;
714
  }
715
716
  /**
717
   * Install a specified language if it has not been already, otherwise make sure that the language is enabled.
718
   *
719
   * @param $langcode
720
   *   The language code to check.
721
   */
722
  function addLanguage($langcode) {
723
    // Check to make sure that language has not already been installed.
724
    $this->drupalGet('admin/config/regional/language');
725
726
    if (strpos($this->drupalGetContent(), 'enabled[' . $langcode . ']') === FALSE) {
727
      // Doesn't have language installed so add it.
728
      $edit = array();
729
      $edit['langcode'] = $langcode;
730
      $this->drupalPost('admin/config/regional/language/add', $edit, t('Add language'));
731
732
      // Make sure we are not using a stale list.
733
      drupal_static_reset('language_list');
734
      $languages = language_list('language');
735
      $this->assertTrue(array_key_exists($langcode, $languages), t('Language was installed successfully.'));
736
737
      if (array_key_exists($langcode, $languages)) {
738
        $this->assertRaw(t('The language %language has been created and can now be used. More information is available on the <a href="@locale-help">help screen</a>.', array('%language' => $languages[$langcode]->name, '@locale-help' => url('admin/help/locale'))), t('Language has been created.'));
739
      }
740
    }
741
    elseif ($this->xpath('//input[@type="checkbox" and @name=:name and @checked="checked"]', array(':name' => 'enabled[' . $langcode . ']'))) {
742
      // It is installed and enabled. No need to do anything.
743
      $this->assertTrue(TRUE, 'Language [' . $langcode . '] already installed and enabled.');
744
    }
745
    else {
746
      // It is installed but not enabled. Enable it.
747
      $this->assertTrue(TRUE, 'Language [' . $langcode . '] already installed.');
748
      $this->drupalPost(NULL, array('enabled[' . $langcode . ']' => TRUE), t('Save configuration'));
749
      $this->assertRaw(t('Configuration saved.'), t('Language successfully enabled.'));
750
    }
751
  }
752
753
  public function setUp() {
754
    parent::setUp(array('field_collection', 'entity_translation'));
755
    $language_none = LANGUAGE_NONE;
756
    // Login with an admin user.
757
    $this->login($this->getAdminUser());
758
    // Add English and German languages.
759
    $this->addLanguage('en');
760
    $this->addLanguage('de');
761
762
    // Set "Article" content type to use multilingual support with translation.
763
    $edit = array();
764
    $edit['language_content_type'] = ENTITY_TRANSLATION_ENABLED;
765
    $this->drupalPost('admin/structure/types/manage/page', $edit, t('Save content type'));
766
    $this->assertRaw(t('The content type %type has been updated.', array('%type' => 'Basic page')), t('Basic page content type has been updated.'));
767
768
    // Create a field collection field to use for the tests.
769
    $this->field_name = 'field_test_collection';
770
    $this->field_base = "{$this->field_name}[$language_none]";
771
    $this->field = array(
772
      'field_name' => $this->field_name,
773
      'type' => 'field_collection',
774
      'cardinality' => -1,
775
      'translatable' => TRUE,
776
    );
777
    $this->field = field_create_field($this->field);
778
    $this->field_id = $this->field['id'];
779
780
    $this->instance = array(
781
      'field_name' => $this->field_name,
782
      'entity_type' => 'node',
783
      'bundle' => 'page',
784
      'label' => $this->randomName() . '_label',
785
      'description' => $this->randomName() . '_description',
786
      'weight' => mt_rand(0, 127),
787
      'settings' => array(),
788
      'widget' => array(
789
        'type' => 'field_collection_embed',
790
        'label' => 'Test',
791
        'settings' => array(),
792
      ),
793
    );
794
    $this->instance = field_create_instance($this->instance);
795
796
    // Enable entity translation of field collections.
797
    $this->drupalGet('admin/config/regional/entity_translation');
798
    $this->drupalPost('admin/config/regional/entity_translation', array('entity_translation_entity_types[field_collection_item]' => TRUE), t('Save configuration'));
799
    $this->assertRaw(t('The configuration options have been saved.'), t('Entity translation of field collections enabled.'));
800
801
    // Add an untraslatable field to the collection.
802
    $this->field_untrans_name = 'field_text_untrans';
803
    $this->field_untrans_base = "[{$this->field_untrans_name}][$language_none][0][value]";
804
    $field = array(
805
      'field_name' => $this->field_untrans_name,
806
      'type' => 'text',
807
      'cardinality' => 1,
808
      'translatable' => FALSE,
809
    );
810
    field_create_field($field);
811
    $instance = array(
812
      'entity_type' => 'field_collection_item',
813
      'field_name' => $this->field_untrans_name,
814
      'bundle' => $this->field_name,
815
      'label' => 'Test untranslatable text field',
816
      'widget' => array(
817
        'type' => 'text_textfield',
818
      ),
819
    );
820
    field_create_instance($instance);
821
822
    // Add a translatable field to the collection.
823
    $this->field_trans_name = 'field_text_trans';
824
    $this->field_trans_base = "[{$this->field_trans_name}][$language_none][0][value]";
825
    $this->field_trans_dest = "[{$this->field_trans_name}][de][0][value]";
826
    $field = array(
827
      'field_name' => $this->field_trans_name,
828
      'type' => 'text',
829
      'cardinality' => 1,
830
      'translatable' => TRUE,
831
    );
832
    field_create_field($field);
833
    $instance = array(
834
      'entity_type' => 'field_collection_item',
835
      'field_name' => $this->field_trans_name,
836
      'bundle' => $this->field_name,
837
      'label' => 'Test translatable text field',
838
      'widget' => array(
839
        'type' => 'text_textfield',
840
      ),
841
    );
842
    field_create_instance($instance);
843
844
    $this->login($this->getTranslatorUser());
845
  }
846
847
  /**
848
   * Creates a basic page with a value in the field collection.
849
   *
850
   *  @param integer $num_values
851
   *    The number of values to include in the field collection.
852
   *  @param string $langcode
853
   *    Language for the node.
854
   */
855
  protected function createPage($num_values, $langcode = 'en') {
856
    // Check if num_values is greater than the field cardinality.
857
    if ($num_values > self::NUM_VALUES) {
858
      $num_values = self::NUM_VALUES;
859
    }
860
861
    $title = $this->randomName();
862
863
    $this->drupalGet('node/add/page');
864
865
    $edit = array();
866
    $edit['title'] = $title;
867
    for ($i = 0; $i < $num_values; $i++) {
868
      if ($i != 0) {
869
        $this->drupalPost(NULL, array(), t('Add another item'));
870
      }
871
      $edit[$this->field_base . '[' . $i . ']' . $this->field_untrans_base] = self::UNTRANS_FIELD_EN . '_' . $i;
872
      $edit[$this->field_base . '[' . $i . ']' . $this->field_trans_base] = self::TRANS_FIELD_EN . '_' . $i;
873
    }
874
875
    $edit['language'] = $langcode;
876
    $this->drupalPost(NULL, $edit, t('Save'));
877
    $this->assertRaw(t('Basic page %title has been created.', array('%title' => $title)), t('Basic page created.'));
878
879
    // Check to make sure the node was created.
880
    $node = $this->drupalGetNodeByTitle($title);
881
    $this->assertTrue($node, t('Node found in database.'));
882
883
    return $node;
884
885
  }
886
887
  /**
888
   * Create a translation using the Entity Translation Form.
889
   *
890
   * @param $node
891
   *   Node of the basic page to create translation for.
892
   * @param $langcode
893
   *   The language code of the translation.
894
   * @param $source_langcode
895
   *   The original language code.
896
   */
897
  protected function createTranslationForm($node, $langcode, $source_langcode = 'en') {
898
    $language_none = LANGUAGE_NONE;
899
    $edit = array();
900
901
    $this->drupalGet('node/' . $node->nid . '/edit/add/' . $source_langcode . '/' .$langcode);
902
903
    // Get the field collection in the original language.
904
    $fc_values = $node->{$this->field_name}[$source_langcode];
905
906
    // Check if all the fields were populated and fill it with the new value.
907
    foreach ($fc_values as $delta => $fc_value) {
908
      // Load the field collection item.
909
      $fc_item_array = entity_load('field_collection_item', array($fc_value['value']));
910
      $fc_item = reset($fc_item_array);
911
      $fc_untrans_key = "{$this->field_name}[$langcode][$delta]{$this->field_untrans_base}";
912
      $fc_trans_key = "{$this->field_name}[$langcode][$delta]{$this->field_trans_dest}";
913
      $this->assertFieldByXPath(
914
          "//input[@name='$fc_untrans_key']",
915
          $fc_item->{$this->field_untrans_name}[LANGUAGE_NONE][0]['value'],
916
          'Original value of untranslatable field correctly populated'
917
              );
918
      $this->assertFieldByXPath(
919
          "//input[@name='$fc_trans_key']",
920
          $fc_item->{$this->field_trans_name}['en'][0]['value'],
921
          'Original value of translatable field correctly populated'
922
              );
923
924
      $edit[$fc_untrans_key] = self::UNTRANS_FIELD_DE . '_' . $delta;
925
      $edit[$fc_trans_key] = self::TRANS_FIELD_DE . '_' . $delta;
926
    }
927
928
    // Save the translation.
929
    $this->drupalPost(NULL, $edit, t('Save'));
930
    $this->drupalGet('node/' . $node->nid . '/translate');
931
    $this->assertLinkByHref('node/' . $node->nid . '/edit/' . $langcode, 0, t('Translation edit link found. Translation created.'));
932
933
    // Reload the node.
934
    $node = node_load($node->nid, NULL, TRUE);
935
936
    // Check the values of the translated field.
937
    $this->checkFieldCollectionContent($node, $langcode);
938
939
    // Check the values of the field in the original language.
940
    $this->checkFieldCollectionContent($node, $source_langcode);
941
942
    return $node;
943
  }
944
945
  /**
946
   * Removes a translation using the entity translation form.
947
   *
948
   * @param mixed $node
949
   *   The node to remove the translation from.
950
   * @param unknown $langcode
951
   *   The language of the translation to remove.
952
   * @param unknown $source_langcode
953
   *   The source language of the node.
954
   */
955
  protected function removeTranslationForm($node, $langcode, $source_langcode) {
956
    // Number of field collection items in the source language.
957
    $num_original_fc_items = count($node->{$this->field_name}[$source_langcode]);
958
959
    // Fetch the translation edit form.
960
    $this->drupalGet('node/' . $node->nid . '/edit/' . $langcode);
961
962
    // Remove the translation.
963
    $this->drupalPost(NULL, array(), t('Delete translation'));
964
    // Confirm deletion.
965
    $this->drupalPost(NULL, array(), t('Delete'));
966
967
    // Reload the node.
968
    $node = node_load($node->nid, NULL, TRUE);
969
970
    // Check that the translation is removed.
971
    $this->drupalGet('node/' . $node->nid . '/translate');
972
    $this->assertLinkByHref('node/' . $node->nid . '/edit/add/' . $source_langcode . '/' . $langcode, 0, 'The add translation link appears');
973
    $this->assert(empty($node->{$this->field_name}[$langcode]));
974
975
    // Check that the field collection in the original language has not changed.
976
    $num_fc_items = count($node->{$this->field_name}[$source_langcode]);
977
    $this->assertEqual($num_original_fc_items, $num_fc_items, 'The number of field collection items in the original language has not changed.');
978
    $this->checkFieldCollectionContent($node, $source_langcode);
979
  }
980
981
  /**
982
   * Creates a translation programmatically using Entity Translation.
983
   *
984
   * @param $node
985
   *   Node of the basic page to create translation for.
986
   * @param $langcode
987
   *   The language code of the translation.
988
   * @param $source_langcode
989
   *   The source language code.
990
   */
991
  protected function createTranslation($node, $langcode) {
992
    $source_langcode = $node->language;
993
994
    // Get the Entity Translation Handler.
995
    $handler = entity_translation_get_handler('node', $node, TRUE);
996
    // Variable to hold the fields values.
997
    $values = array();
998
    // Translation settings.
999
    $translation = array(
1000
      'translate' => 0,
1001
      'status' => 1,
1002
      'language' => $langcode,
1003
      'source' => $source_langcode,
1004
      'uid' => $node->uid,
1005
    );
1006
    // Copy field values.
1007
    foreach (field_info_instances('node', $node->type) as $instance) {
1008
      $field_name = $instance['field_name'];
1009
      $field = field_info_field($field_name);
1010
      $field_value = array();
1011
      // Copy the value of the translated field if it's translatable.
1012
      if ($field['translatable']) {
1013
        if (isset($node->{$field_name}[$node->language])) {
1014
          $field_value = $node->{$field_name}[$source_langcode];
1015
          $values[$field_name][$langcode] = $field_value;
1016
          $node->{$field_name}[$langcode] = $field_value;
1017
        }
1018
      }
1019
    }
1020
1021
    $handler->setTranslation($translation, $values);
1022
    $handler->saveTranslations();
1023
    field_attach_update('node', $node);
1024
1025
    // Reload an return the node.
1026
    $node = node_load($node->nid, null, TRUE);
1027
    return $node;
1028
  }
1029
1030
  /**
1031
   * Removes a translation programmatically using the entity translation api.
1032
   *
1033
   * @param mixed $node
1034
   *   The node to remove the translation from.
1035
   * @param unknown $langcode
1036
   *   The language of the translation to remove.
1037
   */
1038
  protected function removeTranslation($node, $langcode) {
1039
    // Get a translation entity handler.
1040
    $handler = entity_translation_get_handler('node', $node, TRUE);
1041
1042
    // Remove the translation.
1043
    $handler->removeTranslation($langcode);
1044
    node_save($node);
1045
1046
    // Reload and return the node.
1047
    $node = node_load($node->nid, null, TRUE);
1048
1049
    return $node;
1050
  }
1051
1052
  /**
1053
   * Creates a new revision of the node and checks the result.
1054
   *
1055
   * @param $node
1056
   * @param $langcode
1057
   * @param $source_langcode
1058
   * @return
1059
   *   The new revision of the node.
1060
   */
1061
  protected function createRevision($node, $langcode, $source_langcode) {
1062
    $node_original_revision = $node->vid;
1063
    // The original entries of the translated field.
1064
    $original_fc_item_ids = $node->{$this->field_name}[$langcode];
1065
1066
    // Create the revision.
1067
    $node->revision = TRUE;
1068
    node_save($node);
1069
1070
    // The new entries of the translated field.
1071
    $new_fc_item_ids = $node->{$this->field_name}[$langcode];
1072
1073
    // Check that the field collection items are the same and a new revision of
1074
    // each one has been created.
1075
    foreach ($original_fc_item_ids as $delta => $value) {
1076
      $this->assertEqual($value['value'], $new_fc_item_ids[$delta]['value'], t('We have the same field collection item'));
1077
      $this->assertNotEqual($value['revision_id'], $new_fc_item_ids[$delta]['revision_id'], t('We have a new revision of the field collection item'));
1078
    }
1079
1080
    return $node;
1081
  }
1082
1083
  /**
1084
   * Check the content of the field collection for a specified language.
1085
   *
1086
   * @param mixed $node
1087
   *   The node to check.
1088
   * @param string $langcode
1089
   *   The language to check.
1090
   */
1091
  protected function checkFieldCollectionContent($node, $langcode) {
1092
    switch($langcode) {
1093
      case 'en':
1094
        $untrans_field = self::UNTRANS_FIELD_EN;
1095
        $trans_field = self::TRANS_FIELD_EN;
1096
        break;
1097
      case 'de':
1098
        $untrans_field = self::UNTRANS_FIELD_DE;
1099
        $trans_field = self::TRANS_FIELD_DE;
1100
        break;
1101
    }
1102
    // Get the field collection in the specified language.
1103
    $fc_values = $node->{$this->field_name}[$langcode];
1104
1105
    foreach ($fc_values as $delta => $fc_value) {
1106
      // Load the field collection item.
1107
      $fc_item_array = entity_load('field_collection_item', array($fc_value['value']));
1108
      $fc_item = reset($fc_item_array);
1109
      $fc_untrans_key = "{$this->field_name}[$langcode][$delta]{$this->field_untrans_base}";
1110
      $fc_trans_key = "{$this->field_name}[$langcode][$delta]{$this->field_trans_base}";
1111
1112
      $this->assertEqual($untrans_field . '_' . $delta, $fc_item->{$this->field_untrans_name}[LANGUAGE_NONE][0]['value']);
1113
      $this->assertEqual($trans_field . '_' . $delta, $fc_item->{$this->field_trans_name}[$langcode][0]['value']);
1114
    }
1115
  }
1116
1117
  /**
1118
   * Returns the text field values of an specified node, language and delta.
1119
   *
1120
   * @param mixed $node
1121
   * @param string $langcode
1122
   * @param integer $delta
1123
   * @return array
1124
   */
1125
  protected function getFieldValues($node, $langcode, $delta) {
1126
    $return = array();
1127
1128
    if (isset($node->{$this->field_name}[$langcode][$delta]['value'])) {
1129
      $fc_item_id = $node->{$this->field_name}[$langcode][$delta]['value'];
1130
      // Load the field collection.
1131
      $fc_item_array = entity_load('field_collection_item', array($fc_item_id));
1132
      $fc_item = reset($fc_item_array);
1133
1134
      $return = array(
1135
        'field_untrans' => $fc_item->{$this->field_untrans_name}[LANGUAGE_NONE][0]['value'],
1136
        'field_trans' => $fc_item->{$this->field_trans_name}[$langcode][0]['value'],
1137
      );
1138
    }
1139
1140
    return $return;
1141
  }
1142
1143
  /**
1144
   * Ensures the right behaviour in all Entity Translation use cases.
1145
   */
1146
  public function testEntityTranslation() {
1147
    $source_langcode = 'en';
1148
    $translation_langcode = 'de';
1149
1150
    /*
1151
     * Test with a page with only one value in the field collection
1152
     */
1153
    // Create an article in the original language with only one field collection
1154
    // value.
1155
    $node = $this->createPage(1, $source_langcode);
1156
1157
    // Create a traslation of the page through the entity translation form.
1158
    $node = $this->createTranslationForm($node, $translation_langcode, $source_langcode);
1159
1160
    /*
1161
     * Test with a page with multiple values in the field collection.
1162
     */
1163
    $num_values = 4;
1164
    // Create a page in the original language with multiple field collection
1165
    // values.
1166
    $node = $this->createPage($num_values, $source_langcode);
1167
1168
    // Create a traslation of the page through the entity translation form.
1169
    $node = $this->createTranslationForm($node, $translation_langcode, $source_langcode);
1170
1171
    // Assign a new field collection item to an existing node.
1172
    $values = array();
1173
    $values['field_name'] = $this->field_name;
1174
    $fc_entity = entity_create('field_collection_item', $values);
1175
    $fc_entity->setHostEntity('node', $node, $translation_langcode);
1176
1177
    $fc_entity->{$this->field_untrans_name}[LANGUAGE_NONE][0]['value'] = self::UNTRANS_FIELD_DE_MOD;
1178
    $fc_entity->{$this->field_trans_name}['de'][0]['value'] = self::TRANS_FIELD_DE_MOD;
1179
    $fc_entity->save(TRUE);
1180
1181
    node_save($node);
1182
1183
    // Reload the node to check it.
1184
    $node = node_load($node->nid, NULL, TRUE);
1185
    // Check that there is a new element in the translation.
1186
    $this->assertEqual($num_values + 1, count($node->{$this->field_name}[$translation_langcode]), t('We have one item more in translation.'));
1187
    // Check that the new element is correctly saved.
1188
    $fc_item_values = $this->getFieldValues($node, $translation_langcode, $num_values);
1189
    $this->assertEqual($fc_item_values['field_untrans'], self::UNTRANS_FIELD_DE_MOD);
1190
    $this->assertEqual($fc_item_values['field_trans'], self::TRANS_FIELD_DE_MOD);
1191
    // Check that we have the same items in the original language.
1192
    $this->assertEqual($num_values, count($node->{$this->field_name}[$source_langcode]), t('We have same items in the original language.'));
1193
1194
    // Remove a field collection item from the translation.
1195
    $fc_item_id = $node->{$this->field_name}[$translation_langcode][0]['value'];
1196
    unset($node->{$this->field_name}[$translation_langcode][0]);
1197
    node_save($node);
1198
    // Reload the node.
1199
    $node = node_load($node->nid, NULL, TRUE);
1200
    // Check that we have one item less in the translation.
1201
    // We should take into account that we added a field one step before.
1202
    $this->assertEqual($num_values, count($node->{$this->field_name}[$translation_langcode]), t('We have one item less in translation.'));
1203
    // Check that we have the same items in the original language.
1204
    $this->assertEqual($num_values, count($node->{$this->field_name}[$source_langcode]), t('We have same items in the original language.'));
1205
    // Check that the field collection is removed from the database.
1206
    $fc_items = entity_load('field_collection_item', array($fc_item_id));
1207
    $this->assert(empty($fc_items), t('The field collection item has been removed from the database.'));
1208
1209
    // Delete the translation.
1210
    $this->removeTranslationForm($node, $translation_langcode, $source_langcode);
1211
1212
    /*
1213
     * Check the revisioning of an entity with translations.
1214
     */
1215
    $num_values = 4;
1216
    // Create a page in the original language with multiple field collection
1217
    // values.
1218
    $node_rev = $this->createPage($num_values, $source_langcode);
1219
1220
    // Create a traslation of the page.
1221
    $node_rev = $this->createTranslationForm($node_rev, $translation_langcode, $source_langcode);
1222
1223
    $original_revision = $node_rev->vid;
1224
1225
    // Create a new revision of the node.
1226
    $node_rev = $this->createRevision($node_rev, $translation_langcode, $source_langcode);
1227
1228
    /*
1229
     * Test creating programmatically.
1230
     */
1231
    $num_values = 4;
1232
    // Create a page in the original language.
1233
    $node_prog = $this->createPage($num_values, $source_langcode);
1234
1235
    // Create programmatically a translation of the page.
1236
    $node_prog = $this->createTranslation($node_prog, $translation_langcode);
1237
1238
    $orig_fc_items = $node_prog->{$this->field_name}[$source_langcode];
1239
    $trans_fc_items = $node_prog->{$this->field_name}[$translation_langcode];
1240
1241
    $orig_fc_item_ids = array();
1242
    $trans_fc_item_ids = array();
1243
1244
    // Check each item.
1245
    foreach ($orig_fc_items as $delta => $value) {
1246
      $orig_fc_item_ids[] = $value['value'];
1247
      $trans_fc_item_ids[] = $trans_fc_items[$delta]['value'];
1248
1249
      // Check if we have new items for the translation.
1250
      $this->assertNotEqual($value['value'], $trans_fc_items[$delta]['value'], t('New item generated for translation.'));
1251
    }
1252
1253
    // Check that the original item still exists in the database.
1254
    $fc_items = entity_load('field_collection_item', $orig_fc_item_ids);
1255
    $this->assert(!empty($fc_items), t('Field Collections in the source language still exist.'));
1256
    // Check that the translated item exists in the database.
1257
    $fc_items = entity_load('field_collection_item', $trans_fc_item_ids);
1258
    $this->assert(!empty($fc_items), t('Translations for the Field Collection exist.'));
1259
1260
    // Remove the translation and check that the original field collection items
1261
    // are still there.
1262
    $node_prog = $this->removeTranslation($node, $translation_langcode);
1263
1264
    // Check the content in the source language.
1265
    $this->checkFieldCollectionContent($node_prog, $source_langcode);
1266
1267
    // Check that the field translated content has been removed.
1268
    $this->assert(empty($node->{$this->field_name}[$translation_langcode]), t('Translated content removed.'));
1269
  }
1270
1271
}