Added Entity and Entity Reference Revisions which got dropped somewhere along the...
[yaffs-website] / web / core / modules / node / tests / src / Functional / NodeTypeTest.php
1 <?php
2
3 namespace Drupal\Tests\node\Functional;
4
5 use Drupal\field\Entity\FieldConfig;
6 use Drupal\node\Entity\NodeType;
7 use Drupal\Core\Url;
8 use Drupal\Tests\system\Functional\Menu\AssertBreadcrumbTrait;
9 use Drupal\Tests\system\Functional\Cache\AssertPageCacheContextsAndTagsTrait;
10
11 /**
12  * Ensures that node type functions work correctly.
13  *
14  * @group node
15  */
16 class NodeTypeTest extends NodeTestBase {
17
18   use AssertBreadcrumbTrait;
19   use AssertPageCacheContextsAndTagsTrait;
20
21   /**
22    * Modules to enable.
23    *
24    * @var array
25    */
26   public static $modules = ['field_ui', 'block'];
27
28   /**
29    * Ensures that node type functions (node_type_get_*) work correctly.
30    *
31    * Load available node types and validate the returned data.
32    */
33   public function testNodeTypeGetFunctions() {
34     $node_types = NodeType::loadMultiple();
35     $node_names = node_type_get_names();
36
37     $this->assertTrue(isset($node_types['article']), 'Node type article is available.');
38     $this->assertTrue(isset($node_types['page']), 'Node type basic page is available.');
39
40     $this->assertEqual($node_types['article']->label(), $node_names['article'], 'Correct node type base has been returned.');
41
42     $article = NodeType::load('article');
43     $this->assertEqual($node_types['article'], $article, 'Correct node type has been returned.');
44     $this->assertEqual($node_types['article']->label(), $article->label(), 'Correct node type name has been returned.');
45   }
46
47   /**
48    * Tests creating a content type programmatically and via a form.
49    */
50   public function testNodeTypeCreation() {
51     // Create a content type programmatically.
52     $type = $this->drupalCreateContentType();
53
54     $type_exists = (bool) NodeType::load($type->id());
55     $this->assertTrue($type_exists, 'The new content type has been created in the database.');
56
57     // Log in a test user.
58     $web_user = $this->drupalCreateUser(['create ' . $type->label() . ' content']);
59     $this->drupalLogin($web_user);
60
61     $this->drupalGet('node/add/' . $type->id());
62     $this->assertResponse(200, 'The new content type can be accessed at node/add.');
63
64     // Create a content type via the user interface.
65     $web_user = $this->drupalCreateUser(['bypass node access', 'administer content types']);
66     $this->drupalLogin($web_user);
67
68     $this->drupalGet('node/add');
69     $this->assertCacheTag('config:node_type_list');
70     $this->assertCacheContext('user.permissions');
71     $elements = $this->cssSelect('dl.node-type-list dt');
72     $this->assertEqual(3, count($elements));
73
74     $edit = [
75       'name' => 'foo',
76       'title_label' => 'title for foo',
77       'type' => 'foo',
78     ];
79     $this->drupalPostForm('admin/structure/types/add', $edit, t('Save and manage fields'));
80     $type_exists = (bool) NodeType::load('foo');
81     $this->assertTrue($type_exists, 'The new content type has been created in the database.');
82
83     $this->drupalGet('node/add');
84     $elements = $this->cssSelect('dl.node-type-list dt');
85     $this->assertEqual(4, count($elements));
86   }
87
88   /**
89    * Tests editing a node type using the UI.
90    */
91   public function testNodeTypeEditing() {
92     $assert = $this->assertSession();
93     $this->drupalPlaceBlock('system_breadcrumb_block');
94     $web_user = $this->drupalCreateUser(['bypass node access', 'administer content types', 'administer node fields']);
95     $this->drupalLogin($web_user);
96
97     $field = FieldConfig::loadByName('node', 'page', 'body');
98     $this->assertEqual($field->getLabel(), 'Body', 'Body field was found.');
99
100     // Verify that title and body fields are displayed.
101     $this->drupalGet('node/add/page');
102     $assert->pageTextContains('Title');
103     $assert->pageTextContains('Body');
104
105     // Rename the title field.
106     $edit = [
107       'title_label' => 'Foo',
108     ];
109     $this->drupalPostForm('admin/structure/types/manage/page', $edit, t('Save content type'));
110
111     $this->drupalGet('node/add/page');
112     $assert->pageTextContains('Foo');
113     $assert->pageTextNotContains('Title');
114
115     // Change the name and the description.
116     $edit = [
117       'name' => 'Bar',
118       'description' => 'Lorem ipsum.',
119     ];
120     $this->drupalPostForm('admin/structure/types/manage/page', $edit, t('Save content type'));
121
122     $this->drupalGet('node/add');
123     $assert->pageTextContains('Bar');
124     $assert->pageTextContains('Lorem ipsum');
125     $this->clickLink('Bar');
126     $assert->pageTextContains('Foo');
127     $assert->pageTextContains('Body');
128
129     // Change the name through the API
130     /** @var \Drupal\node\NodeTypeInterface $node_type */
131     $node_type = NodeType::load('page');
132     $node_type->set('name', 'NewBar');
133     $node_type->save();
134
135     /** @var \Drupal\Core\Entity\EntityTypeBundleInfoInterface $bundle_info */
136     $bundle_info = \Drupal::service('entity_type.bundle.info');
137     $node_bundles = $bundle_info->getBundleInfo('node');
138     $this->assertEqual($node_bundles['page']['label'], 'NewBar', 'Node type bundle cache is updated');
139
140     // Remove the body field.
141     $this->drupalPostForm('admin/structure/types/manage/page/fields/node.page.body/delete', [], t('Delete'));
142     // Resave the settings for this type.
143     $this->drupalPostForm('admin/structure/types/manage/page', [], t('Save content type'));
144     $front_page_path = Url::fromRoute('<front>')->toString();
145     $this->assertBreadcrumb('admin/structure/types/manage/page/fields', [
146       $front_page_path => 'Home',
147       'admin/structure/types' => 'Content types',
148       'admin/structure/types/manage/page' => 'NewBar',
149     ]);
150     // Check that the body field doesn't exist.
151     $this->drupalGet('node/add/page');
152     $assert->pageTextNotContains('Body');
153   }
154
155   /**
156    * Tests deleting a content type that still has content.
157    */
158   public function testNodeTypeDeletion() {
159     $this->drupalPlaceBlock('page_title_block');
160     // Create a content type programmatically.
161     $type = $this->drupalCreateContentType();
162
163     // Log in a test user.
164     $web_user = $this->drupalCreateUser([
165       'bypass node access',
166       'administer content types',
167     ]);
168     $this->drupalLogin($web_user);
169
170     // Add a new node of this type.
171     $node = $this->drupalCreateNode(['type' => $type->id()]);
172     // Attempt to delete the content type, which should not be allowed.
173     $this->drupalGet('admin/structure/types/manage/' . $type->label() . '/delete');
174     $this->assertRaw(
175       t('%type is used by 1 piece of content on your site. You can not remove this content type until you have removed all of the %type content.', ['%type' => $type->label()]),
176       'The content type will not be deleted until all nodes of that type are removed.'
177     );
178     $this->assertNoText(t('This action cannot be undone.'), 'The node type deletion confirmation form is not available.');
179
180     // Delete the node.
181     $node->delete();
182     // Attempt to delete the content type, which should now be allowed.
183     $this->drupalGet('admin/structure/types/manage/' . $type->label() . '/delete');
184     $this->assertRaw(
185       t('Are you sure you want to delete the content type %type?', ['%type' => $type->label()]),
186       'The content type is available for deletion.'
187     );
188     $this->assertText(t('This action cannot be undone.'), 'The node type deletion confirmation form is available.');
189
190     // Test that a locked node type could not be deleted.
191     $this->container->get('module_installer')->install(['node_test_config']);
192     // Lock the default node type.
193     $locked = \Drupal::state()->get('node.type.locked');
194     $locked['default'] = 'default';
195     \Drupal::state()->set('node.type.locked', $locked);
196     // Call to flush all caches after installing the forum module in the same
197     // way installing a module through the UI does.
198     $this->resetAll();
199     $this->drupalGet('admin/structure/types/manage/default');
200     $this->assertNoLink(t('Delete'));
201     $this->drupalGet('admin/structure/types/manage/default/delete');
202     $this->assertResponse(403);
203     $this->container->get('module_installer')->uninstall(['node_test_config']);
204     $this->container = \Drupal::getContainer();
205     unset($locked['default']);
206     \Drupal::state()->set('node.type.locked', $locked);
207     $this->drupalGet('admin/structure/types/manage/default');
208     $this->clickLink(t('Delete'));
209     $this->assertResponse(200);
210     $this->drupalPostForm(NULL, [], t('Delete'));
211     $this->assertFalse((bool) NodeType::load('default'), 'Node type with machine default deleted.');
212   }
213
214   /**
215    * Tests Field UI integration for content types.
216    */
217   public function testNodeTypeFieldUiPermissions() {
218     // Create an admin user who can only manage node fields.
219     $admin_user_1 = $this->drupalCreateUser(['administer content types', 'administer node fields']);
220     $this->drupalLogin($admin_user_1);
221
222     // Test that the user only sees the actions available to him.
223     $this->drupalGet('admin/structure/types');
224     $this->assertLinkByHref('admin/structure/types/manage/article/fields');
225     $this->assertNoLinkByHref('admin/structure/types/manage/article/display');
226
227     // Create another admin user who can manage node fields display.
228     $admin_user_2 = $this->drupalCreateUser(['administer content types', 'administer node display']);
229     $this->drupalLogin($admin_user_2);
230
231     // Test that the user only sees the actions available to him.
232     $this->drupalGet('admin/structure/types');
233     $this->assertNoLinkByHref('admin/structure/types/manage/article/fields');
234     $this->assertLinkByHref('admin/structure/types/manage/article/display');
235   }
236
237   /**
238    * Tests for when there are no content types defined.
239    */
240   public function testNodeTypeNoContentType() {
241     /** @var \Drupal\Core\Entity\EntityTypeBundleInfoInterface $bundle_info */
242     $bundle_info = \Drupal::service('entity_type.bundle.info');
243     $this->assertEqual(2, count($bundle_info->getBundleInfo('node')), 'The bundle information service has 2 bundles for the Node entity type.');
244     $web_user = $this->drupalCreateUser(['administer content types']);
245     $this->drupalLogin($web_user);
246
247     // Delete 'article' bundle.
248     $this->drupalPostForm('admin/structure/types/manage/article/delete', [], t('Delete'));
249     // Delete 'page' bundle.
250     $this->drupalPostForm('admin/structure/types/manage/page/delete', [], t('Delete'));
251
252     // Navigate to content type administration screen
253     $this->drupalGet('admin/structure/types');
254     $this->assertRaw(t('No content types available. <a href=":link">Add content type</a>.', [
255         ':link' => Url::fromRoute('node.type_add')->toString(),
256       ]), 'Empty text when there are no content types in the system is correct.');
257
258     $bundle_info->clearCachedBundles();
259     $this->assertEqual(0, count($bundle_info->getBundleInfo('node')), 'The bundle information service has 0 bundles for the Node entity type.');
260   }
261
262 }