Completed
Pull Request — master (#157)
by
unknown
01:57
created

DriverEntityWithBundleTest::testEntityWithBundle()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 19
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 19
c 0
b 0
f 0
rs 9.4285
cc 1
eloc 12
nc 1
nop 0
1
<?php
2
3
namespace Drupal\Tests\Driver\Kernel\Drupal8\Entity;
4
5
use Drupal\Driver\Plugin\DriverFieldPluginManager;
6
use Drupal\Driver\Plugin\DriverEntityPluginManager;
7
use Drupal\Driver\Wrapper\Field\DriverFieldDrupal8;
8
use Drupal\Driver\Wrapper\Entity\DriverEntityDrupal8;
9
use Drupal\entity_test\Entity\EntityTestBundle;
10
11
/**
12
 * Tests the entity plugin base class.
13
 *
14
 * @group driver
15
 */
16
class DriverEntityWithBundleTest extends DriverEntityKernelTestBase {
17
18
  /**
19
   * Machine name of the entity type being tested.
20
   *
21
   * @var string
22
   */
23
  protected $entityType = 'entity_test_with_bundle';
24
25
  /**
26
   * A field plugin manager object.
27
   *
28
   * @var \Drupal\Driver\Plugin\DriverPluginManagerInterface
29
   */
30
  protected $fieldPluginManager;
31
32
  /**
33
   * A field plugin manager object.
34
   *
35
   * @var \Drupal\Driver\Plugin\DriverPluginManagerInterface
36
   */
37
  protected $entityPluginManager;
38
39
  /**
40
   * {@inheritdoc}
41
   */
42
  protected function setUp() {
43
    parent::setUp();
44
    $namespaces = \Drupal::service('container.namespaces');
45
    $cache_backend = \Drupal::service('cache.discovery');
46
    $module_handler = \Drupal::service('module_handler');
47
    $this->fieldPluginManager = new DriverFieldPluginManager($namespaces, $cache_backend, $module_handler, 8);
48
    $this->entityPluginManager = new DriverEntityPluginManager($namespaces, $cache_backend, $module_handler, 8);
49
    $this->installEntitySchema('entity_test_with_bundle');
50
    EntityTestBundle::create([
51
      'id' => 'test_bundle',
52
      'label' => 'Test label',
53
      'description' => 'Test description',
54
    ])->save();
55
  }
56
57
  /**
58
   * Test basic driver entity methods on an entity with bundles.
59
   */
60
  public function testLoadDeleteReload() {
61
    $value = $this->randomString();
62
    $fieldName = 'name';
63
    $processedName = 'now' . $value . 'processed';
64
    $field = new DriverFieldDrupal8(
65
        [['value' => $value]],
66
        $fieldName,
67
        $this->entityType
68
    );
69
    $entity = new DriverEntityDrupal8(
70
        $this->entityType
71
    );
72
    $entity->setBundle('test_bundle');
73
    $entity->setFields([$fieldName => $field]);
74
    $entity->save();
75
    $entityId = $entity->id();
76
77
    // Test load method.
78
    $alternateEntity = new DriverEntityDrupal8(
79
        $this->entityType
80
    );
81
    $alternateEntity->load($entityId);
82
    $this->assertFalse($alternateEntity->isNew());
83
    $this->assertEquals('test_bundle', $alternateEntity->bundle());
84
    $this->assertEquals($processedName, $alternateEntity->get($fieldName)->value);
0 ignored issues
show
Documentation Bug introduced by
The method get does not exist on object<Drupal\Driver\Wra...ty\DriverEntityDrupal8>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
85
86
    // Test reload method.
87
    $newValue = $this->randomString();
88
    $newProcessedName = 'now' . $newValue . 'processed';
89
    $entity->set($fieldName, [['value' => $newValue]]);
90
    $entity->save();
91
    $entities = $this->storage->loadByProperties([$fieldName => $newProcessedName]);
92
    $this->assertEquals(1, count($entities));
93
    // Alternate entity has stale value until reloaded.
94
    $this->assertNotEquals($newProcessedName, $alternateEntity->get($fieldName)->value);
0 ignored issues
show
Documentation Bug introduced by
The method get does not exist on object<Drupal\Driver\Wra...ty\DriverEntityDrupal8>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
95
    $alternateEntity->reload();
96
    $this->assertEquals($newProcessedName, $alternateEntity->get($fieldName)->value);
0 ignored issues
show
Documentation Bug introduced by
The method get does not exist on object<Drupal\Driver\Wra...ty\DriverEntityDrupal8>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
97
98
    // Test delete method.
99
    $alternateEntity->delete();
100
    $entities = $this->storage->loadByProperties([$fieldName => $newProcessedName]);
101
    $this->assertEquals(0, count($entities));
102
  }
103
104
  /**
105
   * Test setting a field on an entity with bundle.
106
   */
107
  public function testEntityWithBundle() {
108
    $value = $this->randomString();
109
    $fieldName = 'name';
110
111
    // Also tests passing the bundle in the create method and the constructor.
112
    $entity = DriverEntityDrupal8::create(
113
        [$fieldName => [['value' => $value]]],
114
        $this->entityType,
115
        'test_bundle'
116
    )->save();
117
118
    // Test bundle set properly.
119
    $this->assertEquals($entity->bundle(), 'test_bundle');
120
121
    // The test driverfield plugin has been matched,  which mutates the text.
122
    $processedName = 'now' . $value . 'processed';
123
    $entities = $this->storage->loadByProperties(['name' => $processedName]);
124
    $this->assertEquals(1, count($entities));
125
  }
126
127
  /**
128
   * Test setting a nonexistent bundle.
129
   */
130 View Code Duplication
  public function testSetNonexistentBundle() {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
131
    $entity = new DriverEntityDrupal8(
132
        $this->entityType
133
    );
134
    $this->setExpectedException(\Exception::class, "'nonexistent_bundle' could not be identified as a bundle of the '" . $this->entityType);
135
    $entity->setBundle('nonexistent_bundle');
136
  }
137
138
  /**
139
   * Test setting a non existent bundle as a field.
140
   */
141 View Code Duplication
  public function testSetNonExistentBundleByField() {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
142
    $entity = new DriverEntityDrupal8(
143
        $this->entityType
144
    );
145
146
    $this->setExpectedException(\Exception::class, "No entity of type 'entity_test_bundle' has id or label matching");
147
    $entity->set('type', ['nonexistent bundle']);
148
  }
149
150
  /**
151
   * Test modifying an already set the bundle.
152
   */
153
  public function testModifyBundle() {
154
    EntityTestBundle::create([
155
      'id' => 'other_bundle',
156
      'label' => 'Other label',
157
      'description' => 'Other description',
158
    ])->save();
159
    $entity = new DriverEntityDrupal8(
160
        $this->entityType
161
    );
162
163
    // Test exception when explicitly setting already set bundle bundle.
164
    $entity->setBundle('test_bundle');
165
    $entity->getFinalPlugin();
166
    $this->setExpectedException(\Exception::class, "Cannot change entity bundle after final plugin discovery");
167
    $entity->setBundle('other_bundle');
168
  }
169
170
  /**
171
   * Test can identify bundle by label.
172
   */
173
  public function testEntityWithBundleByLabel() {
174
    $entity = new DriverEntityDrupal8(
175
        $this->entityType
176
    );
177
    // test_bundle has the label "Test label".
178
    $entity->setBundle('test label');
179
    $this->assertEquals($entity->bundle(), 'test_bundle');
180
  }
181
182
  /**
183
   * Test extracting a bundle from among other fields, for various formats.
184
   */
185
  public function testCanExtractBundleFromFields() {
186
    $variants = [
187
        [['target_id' => 'Test label']],
188
        ['target_id' => 'Test label'],
189
        [['Test label']],
190
        ['Test label'],
191
    ];
192
193
    foreach ($variants as $variant) {
194
      // Test passing bundle as raw field.
195
      $this->assertCanExtractBundleFromFields($variant);
196
197
      // Test passing bundle as driverfield object.
198
      $field = new DriverFieldDrupal8(
199
        $variant,
200
        'type',
201
        $this->entityType,
202
        'test_bundle'
203
      );
204
      $this->assertCanExtractBundleFromFields($field);
205
    }
206
  }
207
208
  /**
209
   * Test extracting a bundle in a particular format from among other fields.
210
   *
211
   * @param array|object $variant
212
   *   A representation of a field identifying an entity's bundle.
213
   */
214
  public function assertCanExtractBundleFromFields($variant) {
215
    $value = $this->randomString();
216
    $fields = [
217
      'name' => [['value' => $value]],
218
      'type' => $variant,
219
    ];
220
221
    $entity = DriverEntityDrupal8::create(
222
        $fields,
223
        $this->entityType
224
    )->save();
225
226
    // Test bundle set properly.
227
    $this->assertEquals($entity->bundle(), 'test_bundle');
228
229
    // The test driverfield plugin has been matched,  which mutates the text.
230
    $processedName = 'now' . $value . 'processed';
231
    $entities = $this->storage->loadByProperties(['name' => $processedName]);
232
233
    $bundleString = str_replace(PHP_EOL, '', print_r($variant, TRUE));
234
    $message = "Entity not created correctly when bundle input has value " . $bundleString;
235
    $this->assertEquals(1, count($entities), $message);
236
  }
237
238
}
239