Re-add syntax highlighting to daily emails and
...ATDC lessons
This commit is contained in:
parent
0d9bb37503
commit
5fbf48d9ac
48 changed files with 186 additions and 165 deletions
|
@ -30,7 +30,7 @@ Before adding tests, you must create a module to place them in.
|
|||
|
||||
Run `mkdir -p web/modules/custom/atdc` to create an empty module directory and create an `atdc.info.yml` file within it with this content:
|
||||
|
||||
```yaml
|
||||
```language-yaml
|
||||
name: ATDC
|
||||
type: module
|
||||
core_version_requirement: ^10
|
||||
|
@ -47,7 +47,7 @@ Run `mkdir -p web/modules/custom/atdc/tests/src/Functional && touch web/modules/
|
|||
|
||||
Then, add this content.
|
||||
|
||||
```php
|
||||
```language-php
|
||||
<?php
|
||||
|
||||
namespace Drupal\Tests\atdc\Functional;
|
||||
|
@ -66,7 +66,7 @@ Note: within a test class, the namespace is `Drupal\Tests\{module_name}` instead
|
|||
|
||||
With the boilerplate class added, create a test method within it:
|
||||
|
||||
```php
|
||||
```language-php
|
||||
public function testBasic(): void {
|
||||
self::assertTrue(FALSE);
|
||||
}
|
||||
|
@ -137,7 +137,7 @@ As you're writing functional tests by extending `BrowserTestBase`, you can make
|
|||
|
||||
Replace the `testBasic` test method with the following:
|
||||
|
||||
```php
|
||||
```language-php
|
||||
public function testFrontPage(): void {
|
||||
$this->drupalGet('/');
|
||||
|
||||
|
|
|
@ -18,7 +18,7 @@ Let's see how that would look as a unit test.
|
|||
|
||||
Create a new test, `PostNodeRepositoryUnitTest` and, for now, just create a new `PostNodeRepository`:
|
||||
|
||||
```php
|
||||
```language-php
|
||||
<?php
|
||||
|
||||
// web/modules/custom/atdc/tests/src/Unit/PostNodeRepositoryUnitTest.php
|
||||
|
@ -43,7 +43,7 @@ But, as this is a unit test, you can't get the Repository from the service conta
|
|||
|
||||
Try to fix this by creating a new `EntityTypeManager` and injecting it into the constructor:
|
||||
|
||||
```php
|
||||
```language-php
|
||||
$repository = new PostNodeRepository(
|
||||
new EntityTypeManager(),
|
||||
);
|
||||
|
@ -61,7 +61,7 @@ Instead of doing this manually, let's start using mocks.
|
|||
|
||||
Add `use Drupal\Core\Entity\EntityTypeManagerInterface;` and create a mock to use instead of the manually created version.
|
||||
|
||||
```php
|
||||
```language-php
|
||||
$repository = new PostNodeRepository(
|
||||
$this->createMock(EntityTypeManagerInterface::class),
|
||||
);
|
||||
|
@ -73,7 +73,7 @@ As the mock implements `EntityTypeManagerInterface`, this will fix the failure,
|
|||
|
||||
Next, try to get the posts from the Repository:
|
||||
|
||||
```php
|
||||
```language-php
|
||||
$repository->findAll();
|
||||
```
|
||||
|
||||
|
@ -87,7 +87,7 @@ For the test to work, this needs to be mocked too and returned from the `getStor
|
|||
|
||||
Create a mock of `EntityStorageInterface`, which will be used as the node storage:
|
||||
|
||||
```php
|
||||
```language-php
|
||||
$nodeStorage = $this->createMock(EntityStorageInterface::class);
|
||||
```
|
||||
|
||||
|
@ -95,7 +95,7 @@ Next, this needs to be returns from the mock `EntityTypeManager`.
|
|||
|
||||
To do this, specify that the `getStorage()` method when called with the value `node`, will return the mocked node storage:
|
||||
|
||||
```php
|
||||
```language-php
|
||||
$entityTypeManager = $this->createMock(EntityTypeManagerInterface::class);
|
||||
$entityTypeManager->method('getStorage')->with('node')->willReturn($nodeStorage);
|
||||
|
||||
|
@ -112,7 +112,7 @@ You'll need to use a mock for each node and set what each method needs to return
|
|||
|
||||
The same as the Kernel test, set a title for each post with different created times.
|
||||
|
||||
```php
|
||||
```language-php
|
||||
$node1 = $this->createMock(NodeInterface::class);
|
||||
$node1->method('bundle')->willReturn('post');
|
||||
$node1->method('getCreatedTime')->willReturn(strtotime('-1 week'));
|
||||
|
@ -131,7 +131,7 @@ $node3->method('label')->willReturn('Post three');
|
|||
|
||||
Then, specify the `loadByProperties` method should return the posts.
|
||||
|
||||
```php
|
||||
```language-php
|
||||
$nodeStorage->method('loadByProperties')->willReturn([
|
||||
$node1,
|
||||
$node2,
|
||||
|
@ -141,7 +141,7 @@ $nodeStorage->method('loadByProperties')->willReturn([
|
|||
|
||||
Finally, add some assertions that the nodes returned are the correct ones and in the correct order:
|
||||
|
||||
```php
|
||||
```language-php
|
||||
$posts = $repository->findAll();
|
||||
|
||||
self::assertContainsOnlyInstancesOf(NodeInterface::class, $posts);
|
||||
|
@ -166,7 +166,7 @@ This is testing the same thing as the kernel test, but it's your preference whic
|
|||
|
||||
Hopefully, if you run your whole testsuite, you should see output like this:
|
||||
|
||||
```plain
|
||||
```language-plain
|
||||
PHPUnit 9.6.15 by Sebastian Bergmann and contributors.
|
||||
|
||||
......... 9 / 9 (100%)
|
||||
|
@ -176,7 +176,7 @@ Time: 00:07.676, Memory: 10.00 MB
|
|||
|
||||
Or, if you use `--testdox`, output like this:
|
||||
|
||||
```plain
|
||||
```language-plain
|
||||
PHPUnit 9.6.15 by Sebastian Bergmann and contributors.
|
||||
|
||||
Blog Page (Drupal\Tests\atdc\Functional\BlogPage)
|
||||
|
|
|
@ -22,7 +22,7 @@ For example, how do we test the administration pages to see if they work for a u
|
|||
|
||||
Let's start with a new test:
|
||||
|
||||
```php
|
||||
```language-php
|
||||
public function testAdminPageLoggedIn(): void {
|
||||
$this->drupalGet('/admin');
|
||||
|
||||
|
@ -47,7 +47,7 @@ This is commonly known as the **Arrange** step of the test.
|
|||
|
||||
To create a user, use `$this->drupalCreateUser()` and `$this->drupalLogin()` to log in as that user.
|
||||
|
||||
```php
|
||||
```language-php
|
||||
$user = $this->drupalCreateUser();
|
||||
|
||||
$this->drupalLogin($user);
|
||||
|
@ -61,7 +61,7 @@ As we're testing against a temporary Drupal installation, we don't have access t
|
|||
|
||||
To do this, when creating the user, include an array of permissions to add to it:
|
||||
|
||||
```php
|
||||
```language-php
|
||||
$user = $this->createUser(permissions: [
|
||||
'access administration pages',
|
||||
'administer site configuration',
|
||||
|
@ -80,7 +80,7 @@ Let's create a page and test we can view it.
|
|||
|
||||
Firstly, let's ensure the page is not found:
|
||||
|
||||
```php
|
||||
```language-php
|
||||
public function testContent(): void {
|
||||
$this->drupalGet('/node/1');
|
||||
$this->assertSession()->statusCodeEquals(Response::HTTP_NOT_FOUND);
|
||||
|
@ -91,7 +91,7 @@ Similar to `$this->createUser()`, there are similar methods to create content ty
|
|||
|
||||
Again, as there are no existing content or content types, we need to create them and add the follow-up assertions:
|
||||
|
||||
```php
|
||||
```language-php
|
||||
public function testContent(): void {
|
||||
// ...
|
||||
|
||||
|
@ -111,7 +111,7 @@ You're probably expecting the test to pass now, but you'll likely get an error l
|
|||
|
||||
To fix this, we need to tell Drupal to enable the `node` module within the test by adding this within the test class:
|
||||
|
||||
```php
|
||||
```language-php
|
||||
protected static $modules = ['node'];
|
||||
```
|
||||
|
||||
|
@ -123,7 +123,7 @@ Here's a tip for today: if you're getting an unexpected status code or another e
|
|||
|
||||
To do that, add this to your test, and it will output the page content:
|
||||
|
||||
```php
|
||||
```language-php
|
||||
var_dump($this->getSession()->getPage()->getContent());
|
||||
```
|
||||
|
||||
|
|
|
@ -20,7 +20,7 @@ Create a new `BlogPageTest` and have it extend `BrowserTestBase`.
|
|||
|
||||
Let's assert that a page should exist at `/blog` by returning a `200` status code, as this should be accessible by anonymous users.
|
||||
|
||||
```php
|
||||
```language-php
|
||||
<?php
|
||||
|
||||
namespace Drupal\Tests\atdc\Functional;
|
||||
|
@ -49,7 +49,7 @@ Whilst you could create the page using the Views module, let's create a custom r
|
|||
|
||||
Create an `atdc.routing.yml` file:
|
||||
|
||||
```yaml
|
||||
```language-yaml
|
||||
# web/modules/custom/atdc/atdc.routing.yml
|
||||
|
||||
atdc.blog:
|
||||
|
@ -65,13 +65,13 @@ With this added, the status code doesn't change and is a `404`.
|
|||
|
||||
Like in the previous lesson, you need to enable the `atdc` module by setting `$modules` in your test:
|
||||
|
||||
```php
|
||||
```language-php
|
||||
protected static $modules = ['atdc'];
|
||||
```
|
||||
|
||||
You'll also need to create an `atdc.info.yml` file so the module can be installed:
|
||||
|
||||
```yaml
|
||||
```language-yaml
|
||||
# web/modules/custom/atdc/atdc.info.yml
|
||||
|
||||
name: ATDC
|
||||
|
@ -81,7 +81,7 @@ core_version_requirement: ^10
|
|||
|
||||
This should change the status code to a `403`, as you also need the `node` module for the `access content` permission:
|
||||
|
||||
```php
|
||||
```language-php
|
||||
protected static $modules = ['node', 'atdc'];
|
||||
```
|
||||
|
||||
|
@ -97,7 +97,7 @@ Let's do that next.
|
|||
|
||||
Create the expected Controller class within a `src/Controller` directory:
|
||||
|
||||
```php
|
||||
```language-php
|
||||
<?php
|
||||
|
||||
// web/modules/custom/atdc/src/Controller/BlogPageController.php
|
||||
|
@ -115,7 +115,7 @@ For this step, the simplest thing you can do to get a passing test is to return
|
|||
|
||||
As long as it's an array, even an empty one, the test should pass:
|
||||
|
||||
```php
|
||||
```language-php
|
||||
public function __invoke(): array {
|
||||
return [];
|
||||
}
|
||||
|
@ -131,7 +131,7 @@ This is also a good time to do a `git commit`.
|
|||
|
||||
Again, let's start with a new test:
|
||||
|
||||
```php
|
||||
```language-php
|
||||
public function testPostsAreVisible(): void {
|
||||
// Arrange.
|
||||
$this->createNode(['type' => 'post', 'title' => 'First post']);
|
||||
|
@ -165,7 +165,7 @@ Start by extending the `ControllerBase` base class within your Controller:
|
|||
|
||||
Now, within the `__invoke` method, add this to return a list of each node title:
|
||||
|
||||
```php
|
||||
```language-php
|
||||
public function __invoke(): array {
|
||||
$nodeStorage = $this->entityTypeManager()->getStorage('node');
|
||||
$nodes = $nodeStorage->loadMultiple();
|
||||
|
|
|
@ -26,7 +26,7 @@ This will contain the `PostNodeRepository` class that will be responsible for lo
|
|||
|
||||
Add this as the initial content:
|
||||
|
||||
```php
|
||||
```language-php
|
||||
<?php
|
||||
|
||||
namespace Drupal\atdc\Repository;
|
||||
|
@ -62,7 +62,7 @@ $nodes = $nodeStorage->loadMultiple();
|
|||
|
||||
Add them to the `findAll()` method, alter the first line that gets the `EntityTypeManager` (we'll refactor this later) and return the loaded nodes:
|
||||
|
||||
```php
|
||||
```language-php
|
||||
public function findAll(): array {
|
||||
$nodeStorage = \Drupal::entityTypeManager()->getStorage('node');
|
||||
$nodes = $nodeStorage->loadMultiple();
|
||||
|
@ -73,7 +73,7 @@ public function findAll(): array {
|
|||
|
||||
Within the `BlogPageController`, create a constructor method and inject the Repository using constructor property promotion:
|
||||
|
||||
```php
|
||||
```language-php
|
||||
public function __construct(
|
||||
private PostNodeRepository $postNodeRepository,
|
||||
) {
|
||||
|
@ -82,7 +82,7 @@ public function __construct(
|
|||
|
||||
Add `use Drupal\atdc\Repository\PostNodeRepository;` if needed, and use it to load the post nodes:
|
||||
|
||||
```php
|
||||
```language-php
|
||||
|
||||
public function __invoke(): array {
|
||||
$nodes = $this->postNodeRepository->findAll();
|
||||
|
@ -105,7 +105,7 @@ Currently, the test is failing, as the response code is a `500` status because t
|
|||
|
||||
It's expected within the constructor, but you must add a `create` method to inject it.
|
||||
|
||||
```php
|
||||
```language-php
|
||||
public static function create(ContainerInterface $container): self {
|
||||
return new self(
|
||||
$container->get(PostNodeRepository::class),
|
||||
|
@ -123,7 +123,7 @@ To do this, create an `atdc.services.yml` file within your module.
|
|||
|
||||
Add `PostNodeRepository` using the fully-qualified class name as the service name:
|
||||
|
||||
```yaml
|
||||
```language-yaml
|
||||
services:
|
||||
Drupal\atdc\Repository\PostNodeRepository:
|
||||
arguments: []
|
||||
|
@ -139,7 +139,7 @@ Before moving on, let's refactor the `PostNodeRepository` and inject the `Entity
|
|||
|
||||
The same as the `BlogPageController`, create a constructor method and inject the `EntityTypeManagerInterface`:
|
||||
|
||||
```php
|
||||
```language-php
|
||||
public function __construct(
|
||||
private EntityTypeManagerInterface $entityTypeManager,
|
||||
) {
|
||||
|
@ -148,7 +148,7 @@ public function __construct(
|
|||
|
||||
Add the `use Drupal\Core\Entity\EntityTypeManagerInterface;` if needed, and specify it as an argument so it's injected into the constructor:
|
||||
|
||||
```yaml
|
||||
```language-yaml
|
||||
services:
|
||||
Drupal\atdc\Repository\PostNodeRepository:
|
||||
arguments:
|
||||
|
|
|
@ -28,7 +28,7 @@ Instead of making HTTP requests and checking the responses, we can test the resu
|
|||
|
||||
Let's create a new test that uses the `PostNodeRepository` to find the nodes and assert we get an expected number returned.
|
||||
|
||||
```php
|
||||
```language-php
|
||||
<?php
|
||||
|
||||
namespace Drupal\Tests\atdc\Kernel;
|
||||
|
@ -73,7 +73,7 @@ It's defined within `atdc.services.yml`, but we need to be explicit about which
|
|||
|
||||
Create a `$modules` array within the test class and add `atdc`:
|
||||
|
||||
```php
|
||||
```language-php
|
||||
protected static $modules = ['atdc'];
|
||||
```
|
||||
|
||||
|
@ -83,7 +83,7 @@ Run the tests again, and you should get a different error:
|
|||
|
||||
As well as `atdc`, you must enable the `node` module. You can do so by adding it to the `$modules` array:
|
||||
|
||||
```php
|
||||
```language-php
|
||||
protected static $modules = ['node', 'atdc'];
|
||||
```
|
||||
|
||||
|
@ -111,7 +111,7 @@ Within the test, you can use `$this->createNode()` to create posts.
|
|||
|
||||
Create the three posts the test is expecting:
|
||||
|
||||
```php
|
||||
```language-php
|
||||
// Arrange.
|
||||
$this->createNode(['type' => 'post']);
|
||||
$this->createNode(['type' => 'post']);
|
||||
|
@ -126,7 +126,7 @@ Next, let's assert they're returned in a specific order.
|
|||
|
||||
Update the posts to have a specific title and created date so we can specify which order we expect them to be returned in and which titles they should have:
|
||||
|
||||
```php
|
||||
```language-php
|
||||
// Arrange.
|
||||
$this->createNode([
|
||||
'created' => (new DrupalDateTime('-1 week'))->getTimestamp(),
|
||||
|
@ -151,7 +151,7 @@ Note we're intentionally setting them to be in an incorrect order, to begin with
|
|||
|
||||
Next, assert that the titles are returned in the correct order.
|
||||
|
||||
```php
|
||||
```language-php
|
||||
self::assertSame(
|
||||
['Post two', 'Post one', 'Post three'],
|
||||
array_map(
|
||||
|
@ -165,7 +165,7 @@ For each node in `$nodes`, get its label (title) and compare them with the title
|
|||
|
||||
As expected, the test fails:
|
||||
|
||||
```plain
|
||||
```language-plain
|
||||
1) Drupal\Tests\atdc\Kernel\PostNodeRepositoryTest::testPostsAreReturnedByCreatedDate
|
||||
Failed asserting that two arrays are identical.
|
||||
--- Expected
|
||||
|
@ -187,7 +187,7 @@ We need to update the code within `PostNodeRepository` to fix the ordering.
|
|||
|
||||
After loading the nodes, we need to sort them.
|
||||
|
||||
```php
|
||||
```language-php
|
||||
public function findAll(): array {
|
||||
$nodeStorage = $this->entityTypeManager->getStorage('node');
|
||||
$nodes = $nodeStorage->loadMultiple();
|
||||
|
@ -206,7 +206,7 @@ This gets us further, but the test is still failing.
|
|||
|
||||
Whilst the order is correct, the array keys don't match what we expect:
|
||||
|
||||
```plain
|
||||
```language-plain
|
||||
1) Drupal\Tests\atdc\Kernel\PostNodeRepositoryTest::testPostsAreReturnedByCreatedDate
|
||||
Failed asserting that two arrays are identical.
|
||||
--- Expected
|
||||
|
@ -233,7 +233,7 @@ And, because the correct titles are still being shown, our original Functional t
|
|||
|
||||
Tip: to see the names of the tests in your output, add the `--testdox` flag to the `phpunit` command:
|
||||
|
||||
```plain
|
||||
```language-plain
|
||||
Blog Page (Drupal\Tests\atdc\Functional\BlogPage)
|
||||
✔ Blog page
|
||||
✔ Posts are visible
|
||||
|
|
|
@ -12,7 +12,7 @@ In yesterday's lesson, you created your first Kernel test and used it to ensure
|
|||
|
||||
This is how we're creating the posts currently:
|
||||
|
||||
```php
|
||||
```language-php
|
||||
$this->createNode([
|
||||
'created' => (new DrupalDateTime('-1 week'))->getTimestamp(),
|
||||
'title' => 'Post one',
|
||||
|
@ -40,7 +40,7 @@ Let's create a Builder class to create the posts.
|
|||
|
||||
This is how I'd like to create a post using a `PostBuilder`:
|
||||
|
||||
```php
|
||||
```language-php
|
||||
PostBuilder::create()
|
||||
->setCreatedDate('-1 week')
|
||||
->setTitle('Post one')
|
||||
|
@ -51,7 +51,7 @@ This makes it easier to do by creating named methods for each value we want to s
|
|||
|
||||
To do this, create a new class at `src/Builder/PostBuilder.php`:
|
||||
|
||||
```php
|
||||
```language-php
|
||||
<?php
|
||||
|
||||
// web/modules/custom/atdc/src/Builder/PostBuilder.php
|
||||
|
@ -73,7 +73,7 @@ As it returns a new version of `self`, you can also chain methods onto it.
|
|||
|
||||
Add the additional methods and properties:
|
||||
|
||||
```php
|
||||
```language-php
|
||||
private ?DrupalDateTime $created = NULL;
|
||||
|
||||
private string $title;
|
||||
|
@ -95,7 +95,7 @@ Again, by returning `$this`, we can keep chaining methods.
|
|||
|
||||
Finally, create the `getPost()` method that creates the node based on the property values, saves it, and returns it.
|
||||
|
||||
```php
|
||||
```language-php
|
||||
public function getPost(): NodeInterface {
|
||||
$post = Node::create([
|
||||
'created' => $this->created?->getTimestamp(),
|
||||
|
@ -111,7 +111,7 @@ public function getPost(): NodeInterface {
|
|||
|
||||
Now, refactor the test to use the `PostBuilder`:
|
||||
|
||||
```php
|
||||
```language-php
|
||||
PostBuilder::create()
|
||||
->setCreatedDate('-1 week')
|
||||
->setTitle('Post one')
|
||||
|
@ -136,7 +136,7 @@ Finally, for today, let's refactor the assertion that verifies the titles are re
|
|||
|
||||
This is the current assertion:
|
||||
|
||||
```php
|
||||
```language-php
|
||||
self::assertSame(
|
||||
['Post two', 'Post one', 'Post three'],
|
||||
array_map(
|
||||
|
@ -152,7 +152,7 @@ We can make this more reusable and readable by extracting this into a new custom
|
|||
|
||||
Create a new static function at the bottom of the class with a name that describes what it's asserting:
|
||||
|
||||
```php
|
||||
```language-php
|
||||
/**
|
||||
* @param array<int, string> $expectedTitles
|
||||
* @param array<int, NodeInterface> $nodes
|
||||
|
@ -179,7 +179,7 @@ The benefits are that this now has a name that describes what we're asserting, a
|
|||
|
||||
Finally, refactor the test to use the new assertion:
|
||||
|
||||
```php
|
||||
```language-php
|
||||
self::assertNodeTitlesAreSame(
|
||||
['Post two', 'Post one', 'Post three'],
|
||||
$nodes,
|
||||
|
|
|
@ -20,7 +20,7 @@ First, let's ensure that only published nodes are returned and displayed on the
|
|||
|
||||
We can do this easily with a functional test, so add a new test method to `BlogPostTest`:
|
||||
|
||||
```php
|
||||
```language-php
|
||||
public function testOnlyPublishedNodesAreShown(): void {
|
||||
PostBuilder::create()
|
||||
->setTitle('Post one')
|
||||
|
@ -54,7 +54,7 @@ In this test, we want to create some published and unpublished posts and assert
|
|||
|
||||
To fix the error, add this function so it exists:
|
||||
|
||||
```php
|
||||
```language-php
|
||||
public function isPublished(): self {
|
||||
return $this;
|
||||
}
|
||||
|
@ -70,7 +70,7 @@ When using `PostBuilder` in the previous lesson, we were always providing a crea
|
|||
|
||||
Update the `getPost()` method to only set the created time if the `created` property has a value.
|
||||
|
||||
```php
|
||||
```language-php
|
||||
public function getPost(): NodeInterface {
|
||||
$post = Node::create([
|
||||
'title' => $this->title,
|
||||
|
@ -93,7 +93,7 @@ Now, we can see a similar error to the one before for `isNotPublished()`.
|
|||
|
||||
Again, create the simplest version of the method so the test can progress:
|
||||
|
||||
```php
|
||||
```language-php
|
||||
public function isNotPublished(): self {
|
||||
return $this;
|
||||
}
|
||||
|
@ -112,13 +112,13 @@ Within `PostBuilder`, we need to use the `isPublished` and `isNotPublished` meth
|
|||
|
||||
First, add an `isPublished` property to the class and set it to be `TRUE` by default:
|
||||
|
||||
```php
|
||||
```language-php
|
||||
private bool $isPublished = TRUE;
|
||||
```
|
||||
|
||||
Next, update the `isPublished()` and `isNotPublished()` methods to set the value appropriately:
|
||||
|
||||
```php
|
||||
```language-php
|
||||
public function isNotPublished(): self {
|
||||
$this->isPublished = FALSE;
|
||||
|
||||
|
@ -136,7 +136,7 @@ Even though `isPublished` is already true by default, doing this makes it explic
|
|||
|
||||
Finally, within `getPost()`, update the code that creates the node to set the `status` property accordingly.
|
||||
|
||||
```php
|
||||
```language-php
|
||||
$post = Node::create([
|
||||
'status' => $this->isPublished,
|
||||
'title' => $this->title,
|
||||
|
@ -152,7 +152,7 @@ We also need to update the `PostNodeRepository` as that is responsible for loadi
|
|||
|
||||
Currently, all we're doing is this:
|
||||
|
||||
```php
|
||||
```language-php
|
||||
$nodes = $nodeStorage->loadMultiple();
|
||||
```
|
||||
|
||||
|
@ -160,7 +160,7 @@ This will load all nodes, regardless of their type or status.
|
|||
|
||||
To fix this, change this to use `loadByProperties()` instead:
|
||||
|
||||
```php
|
||||
```language-php
|
||||
$nodes = $nodeStorage->loadByProperties();
|
||||
```
|
||||
|
||||
|
@ -170,7 +170,7 @@ Note: you can also use `->getQuery()` if you prefer and write the query yourself
|
|||
|
||||
For this case, let's add a property for `status` and its value to be `TRUE`:
|
||||
|
||||
```php
|
||||
```language-php
|
||||
$nodes = $nodeStorage->loadByProperties([
|
||||
'status' => TRUE,
|
||||
]);
|
||||
|
@ -184,7 +184,7 @@ The other issue is all published nodes are returned, even if they aren't posts.
|
|||
|
||||
Before adding this to `PostNodeRepository`, create a new failing test for it:
|
||||
|
||||
```php
|
||||
```language-php
|
||||
public function testOnlyPostNodesAreShown(): void {
|
||||
PostBuilder::create()->setTitle('Post one')->getPost();
|
||||
PostBuilder::create()->setTitle('Post two')->getPost();
|
||||
|
@ -213,7 +213,7 @@ If you run the test, it should fail as expected:
|
|||
|
||||
Now we have a failing test, let's add the extra condition to `PostNodeRepository`:
|
||||
|
||||
```php
|
||||
```language-php
|
||||
$nodes = $nodeStorage->loadByProperties([
|
||||
'status' => TRUE,
|
||||
'type' => 'post',
|
||||
|
|
|
@ -12,7 +12,7 @@ In this lesson, let's add tags to our posts using the `PostBuilder`.
|
|||
|
||||
As we're doing test-driven development, start by creating a new `PostBuilderTest`:
|
||||
|
||||
```php
|
||||
```language-php
|
||||
<?php
|
||||
|
||||
// web/modules/custom/atdc/tests/src/Kernel/Builder/PostBuilderTest.php
|
||||
|
@ -37,7 +37,7 @@ Let's start by testing the existing functionality within `PostBuilder` by verify
|
|||
|
||||
Create these tests, which should pass by default as the code is already written:
|
||||
|
||||
```php
|
||||
```language-php
|
||||
/** @test */
|
||||
public function it_returns_a_published_post(): void {
|
||||
$node = PostBuilder::create()
|
||||
|
@ -73,7 +73,7 @@ Next, create a test for adding tags to a post.
|
|||
|
||||
It should be mostly the same as the others, but instead of an assertion for the published status, try to use `var_dump()` to see the value of `field_tags`:
|
||||
|
||||
```php
|
||||
```language-php
|
||||
/** @test */
|
||||
public function it_returns_a_post_with_tags(): void {
|
||||
$node = PostBuilder::create()
|
||||
|
@ -104,7 +104,7 @@ The convention is to create a test module that will only be required within the
|
|||
|
||||
To do this, create a `web/modules/custom/atdc/modules/atdc_test` directory and an `atdc_test.info.yml` file with this content:
|
||||
|
||||
```yaml
|
||||
```language-yaml
|
||||
name: ATDC Test
|
||||
type: module
|
||||
core_version_requirement: ^10
|
||||
|
@ -123,7 +123,7 @@ Rather than trying to write them by hand, I create the configuration I need, suc
|
|||
|
||||
To do that for this project, as I'm using the PHP built-in web server, I can use Drush to install Drupal using an SQLite database:
|
||||
|
||||
```plain
|
||||
```language-plain
|
||||
./vendor/bin/drush site:install --db-url sqlite://localhost/atdc.sqlite
|
||||
```
|
||||
|
||||
|
@ -143,7 +143,7 @@ These are the files that I created in my module based on the field I created.
|
|||
|
||||
`field.field.node.post.field_tags.yml`:
|
||||
|
||||
```yaml
|
||||
```language-yaml
|
||||
langcode: en
|
||||
status: true
|
||||
dependencies:
|
||||
|
@ -174,7 +174,7 @@ field_type: entity_reference
|
|||
|
||||
`field.storage.node.field_tags.yml`:
|
||||
|
||||
```yaml
|
||||
```language-yaml
|
||||
langcode: en
|
||||
status: true
|
||||
dependencies:
|
||||
|
@ -198,7 +198,7 @@ custom_storage: false
|
|||
|
||||
Then, enable the module within `PostBuilderTest`:
|
||||
|
||||
```php
|
||||
```language-php
|
||||
protected static $modules = [
|
||||
// Core.
|
||||
'node',
|
||||
|
@ -210,7 +210,7 @@ protected static $modules = [
|
|||
|
||||
Finally, install the configuration to create the field. Add this within the test:
|
||||
|
||||
```php
|
||||
```language-php
|
||||
$this->installConfig(modules: [
|
||||
'atdc_test',
|
||||
]);
|
||||
|
@ -218,7 +218,7 @@ $this->installConfig(modules: [
|
|||
|
||||
After adding this and attempting to install the configuration to add the field, you'll get an error:
|
||||
|
||||
```plain
|
||||
```language-plain
|
||||
Exception when installing config for module atdc_test, the message was: Field 'field_tags' on entity type 'node' references a target entity type 'taxonomy_term', which does not exist.
|
||||
```
|
||||
|
||||
|
@ -234,7 +234,7 @@ As well as the field configuration, we also need to create the Post content type
|
|||
|
||||
This can be done by creating a `node.type.post.yml` file:
|
||||
|
||||
```yaml
|
||||
```language-yaml
|
||||
langcode: en
|
||||
status: true
|
||||
dependencies: { }
|
||||
|
@ -255,7 +255,7 @@ Let's update the test and add assertions about the tags being saved and returned
|
|||
|
||||
Get the tags from the post and assert that three tags are returned:
|
||||
|
||||
```php
|
||||
```language-php
|
||||
$tags = $node->get('field_tags')->referencedEntities();
|
||||
self::assertCount(3, $tags);
|
||||
```
|
||||
|
@ -264,7 +264,7 @@ As none have been added, this would fail the test.
|
|||
|
||||
Update the test to use a `setTags()` method that you haven't created yet:
|
||||
|
||||
```php
|
||||
```language-php
|
||||
$node = PostBuilder::create()
|
||||
->setTitle('test')
|
||||
->setTags(['Drupal', 'PHP', 'Testing'])
|
||||
|
@ -277,7 +277,7 @@ You should get an error confirming the method is undefined:
|
|||
|
||||
To fix this, add the `tags` property and `setTags()` method to `PostBuilder`:
|
||||
|
||||
```php
|
||||
```language-php
|
||||
/**
|
||||
* @var string[]
|
||||
*/
|
||||
|
@ -297,7 +297,7 @@ Tags will be an array of strings, and `setTags()` should set the tags to the `ta
|
|||
|
||||
Next, add the logic to `getPost()` to create a taxonomy term for each tag name.
|
||||
|
||||
```php
|
||||
```language-php
|
||||
$tagTerms = [];
|
||||
|
||||
if ($this->tags !== []) {
|
||||
|
@ -322,7 +322,7 @@ If `$this->tags` is not empty, create a new taxonomy term for each one and save
|
|||
|
||||
As well as asserting we have the correct number of tags, let's also assert that the correct tag names are returned and that they are the correct type of term.
|
||||
|
||||
```php
|
||||
```language-php
|
||||
self::assertContainsOnlyInstancesOf(TermInterface::class, $tags);
|
||||
foreach ($tags as $tag) {
|
||||
self::assertSame('tags', $tag->bundle());
|
||||
|
@ -333,7 +333,7 @@ To assert the tags array only includes taxonomy terms, use `self::assertContains
|
|||
|
||||
Next, add some new assertions to the test to check the tag names match the specified tags.
|
||||
|
||||
```php
|
||||
```language-php
|
||||
self::assertSame('Drupal', $tags[0]->label());
|
||||
self::assertSame('PHP', $tags[1]->label());
|
||||
self::assertSame('Testing', $tags[2]->label());
|
||||
|
|
|
@ -22,7 +22,7 @@ I've also seen Unit tests that are very tightly coupled to the implementation, s
|
|||
|
||||
Based on what you've learned so far, let's write a Unit test that we'd expect to pass:
|
||||
|
||||
```php
|
||||
```language-php
|
||||
<?php
|
||||
|
||||
namespace Drupal\Tests\atdc\Unit;
|
||||
|
@ -58,7 +58,7 @@ Update the test to create a mock version of `NodeInterface` instead.
|
|||
|
||||
As the mock an instance of `NodeInterface`, it satisfies the assertion and the test passes.
|
||||
|
||||
```php
|
||||
```language-php
|
||||
/** @test */
|
||||
public function it_wraps_a_post(): void {
|
||||
$node = $this->createMock(NodeInterface::class);
|
||||
|
@ -69,7 +69,7 @@ public function it_wraps_a_post(): void {
|
|||
|
||||
Next, add an assertion to ensure the bundle is correct:
|
||||
|
||||
```php
|
||||
```language-php
|
||||
self::assertSame('post', $node->bundle());
|
||||
```
|
||||
|
||||
|
@ -81,7 +81,7 @@ Because you're using a mock, all methods will return `NULL`.
|
|||
|
||||
To get this to pass, you need to define what `$this->bundle()` will return:
|
||||
|
||||
```php
|
||||
```language-php
|
||||
$node->method('bundle')->willReturn('post');
|
||||
```
|
||||
|
||||
|
@ -97,7 +97,7 @@ Within the test, instantiate a new `Postwrapper` class that takes the node as an
|
|||
|
||||
Then, add an assertion that a `getType()` method should return `post`.
|
||||
|
||||
```php
|
||||
```language-php
|
||||
$wrapper = new PostWrapper($node);
|
||||
|
||||
self::assertSame('post', $wrapper->getType());
|
||||
|
@ -105,7 +105,7 @@ self::assertSame('post', $wrapper->getType());
|
|||
|
||||
Next, create a `PostWrapper` class with the `getType()` method:
|
||||
|
||||
```php
|
||||
```language-php
|
||||
<?php
|
||||
|
||||
namespace Drupal\atdc;
|
||||
|
@ -132,7 +132,7 @@ We've tested that the `PostWrapper` works with post nodes, but let's also ensure
|
|||
|
||||
Create a new test that creates a mock node and returns `page` as the bundle:
|
||||
|
||||
```php
|
||||
```language-php
|
||||
/**
|
||||
* @test
|
||||
* @testdox It can't wrap a page
|
||||
|
@ -153,7 +153,7 @@ Before creating a new `PostWrapper`, assert that an `InvalidArgumentException` s
|
|||
|
||||
To fix it, within the constructor for `PostWrapper`, check the bundle and throw the expected Exception if the bundle is not `post`:
|
||||
|
||||
```php
|
||||
```language-php
|
||||
/**
|
||||
* @throws \InvalidArgumentException
|
||||
*/
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue