From f713d225bf6221372caddfbf85f461def5d3e918 Mon Sep 17 00:00:00 2001 From: Oliver Davies <oliver@oliverdavies.uk> Date: Sat, 21 Oct 2017 20:23:05 +0100 Subject: [PATCH 01/33] Add correct nodes test --- tests/src/Functional/PageListTest.php | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/tests/src/Functional/PageListTest.php b/tests/src/Functional/PageListTest.php index 9c1d9e6..ccce3c8 100644 --- a/tests/src/Functional/PageListTest.php +++ b/tests/src/Functional/PageListTest.php @@ -21,4 +21,19 @@ class PageListTest extends BrowserTestBase { $this->assertSession()->statusCodeEquals(200); } + /** + * Ensure that only the correct nodes are returned. + * + * Ensure that only published pages are returned by the view. Unpublished + * pages or content of different types should not be shown. + */ + public function testOnlyPublishedPagesAreShown() { + // Given that a have a mixture of published and unpublished pages, as well + // as other types of content. + + // When I view the page. + + // Then I should only see the published pages. + } + } From a104767e10314ebce30f19638f5d216773cb5c01 Mon Sep 17 00:00:00 2001 From: Oliver Davies <oliver@oliverdavies.uk> Date: Sat, 21 Oct 2017 20:25:33 +0100 Subject: [PATCH 02/33] Create some test content This includes some content of different types, as well as a mixture of published and unpublished content. This mean that we can test that these nodes are not returned in addition to ensuring that the correct ones are returned. --- tests/src/Functional/PageListTest.php | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/tests/src/Functional/PageListTest.php b/tests/src/Functional/PageListTest.php index ccce3c8..3ea80a5 100644 --- a/tests/src/Functional/PageListTest.php +++ b/tests/src/Functional/PageListTest.php @@ -28,8 +28,16 @@ class PageListTest extends BrowserTestBase { * pages or content of different types should not be shown. */ public function testOnlyPublishedPagesAreShown() { - // Given that a have a mixture of published and unpublished pages, as well - // as other types of content. + $this->drupalCreateContentType(['type' => 'article']); + + // This is a published page, so it should be visible. + $this->drupalCreateNode(['type' => 'page', 'status' => TRUE]); + + // This is an article, so it should not be visible. + $this->drupalCreateNode(['type' => 'article']); + + // This page is not published, so it should not be visible. + $this->drupalCreateNode(['type' => 'page', 'status' => FALSE]); // When I view the page. From 88a0399f39e21d8d584159ddea3634a1a1e0600d Mon Sep 17 00:00:00 2001 From: Oliver Davies <oliver@oliverdavies.uk> Date: Sat, 21 Oct 2017 20:35:37 +0100 Subject: [PATCH 03/33] Get the result of the view --- .gitignore | 1 + tests/src/Functional/PageListTest.php | 12 +++++++++++- 2 files changed, 12 insertions(+), 1 deletion(-) create mode 100644 .gitignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..2659611 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +composer.lock diff --git a/tests/src/Functional/PageListTest.php b/tests/src/Functional/PageListTest.php index 3ea80a5..42030c0 100644 --- a/tests/src/Functional/PageListTest.php +++ b/tests/src/Functional/PageListTest.php @@ -39,7 +39,17 @@ class PageListTest extends BrowserTestBase { // This page is not published, so it should not be visible. $this->drupalCreateNode(['type' => 'page', 'status' => FALSE]); - // When I view the page. + // Rather than testing the rendered HTML, we are going to load the view + // results programmatically and run assertions against the data it returns. + // This makes it easier to test certain scenarios, and ensures that the + // test is future-proofed and won't fail at a later date due to a change in + // the presentation code. + $result = views_get_view_result('pages'); + + // $result contains an array of Drupal\views\ResultRow objects. We can use + // a Collection here to pluck the nid from each node and return them as an + // array. + $nids = collect($result)->pluck('nid')->all(); // Then I should only see the published pages. } From 744556a6811ec8d02f6b8fe5eb4362d9970ad4c1 Mon Sep 17 00:00:00 2001 From: Oliver Davies <oliver@oliverdavies.uk> Date: Sat, 21 Oct 2017 20:52:42 +0100 Subject: [PATCH 04/33] Compare the expected nids with the view result --- tests/src/Functional/PageListTest.php | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/tests/src/Functional/PageListTest.php b/tests/src/Functional/PageListTest.php index 42030c0..93f0e0a 100644 --- a/tests/src/Functional/PageListTest.php +++ b/tests/src/Functional/PageListTest.php @@ -47,11 +47,13 @@ class PageListTest extends BrowserTestBase { $result = views_get_view_result('pages'); // $result contains an array of Drupal\views\ResultRow objects. We can use - // a Collection here to pluck the nid from each node and return them as an - // array. - $nids = collect($result)->pluck('nid')->all(); + // array_column to get the nid from each node and return them as an array. + $nids = array_column($result, 'nid'); - // Then I should only see the published pages. + // Only node 1 matches the criteria of being a published page, so only that + // node ID should be being returned from the view. assertEquals() can be + // used to compare the expected result to what is being returned. + $this->assertEquals([1], $nids); } } From f6d572211ff35e7b60bdafb6a7c6570f5141848c Mon Sep 17 00:00:00 2001 From: Oliver Davies <oliver@oliverdavies.uk> Date: Sat, 21 Oct 2017 20:58:14 +0100 Subject: [PATCH 05/33] Add type condition to the view --- config/install/views.view.pages.yml | 42 +++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/config/install/views.view.pages.yml b/config/install/views.view.pages.yml index bf293cd..d09a6d2 100644 --- a/config/install/views.view.pages.yml +++ b/config/install/views.view.pages.yml @@ -1,6 +1,8 @@ langcode: en status: true dependencies: + config: + - node.type.page module: - node - user @@ -136,6 +138,46 @@ display: expose: operator: '' group: 1 + type: + id: type + table: node_field_data + field: type + relationship: none + group_type: group + admin_label: '' + operator: in + value: + page: page + group: 1 + exposed: false + expose: + operator_id: '' + label: '' + description: '' + use_operator: false + operator: '' + identifier: '' + required: false + remember: false + multiple: false + remember_roles: + authenticated: authenticated + reduce: false + is_grouped: false + group_info: + label: '' + description: '' + identifier: '' + optional: true + widget: select + multiple: false + remember: false + default_group: All + default_group_multiple: { } + group_items: { } + entity_type: node + entity_field: type + plugin_id: bundle sorts: created: id: created From 569d4a80dc0723ab5173c69c128284d9f6987238 Mon Sep 17 00:00:00 2001 From: Oliver Davies <oliver@oliverdavies.uk> Date: Sat, 21 Oct 2017 21:01:55 +0100 Subject: [PATCH 06/33] Add results order test --- tests/src/Functional/PageListTest.php | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/tests/src/Functional/PageListTest.php b/tests/src/Functional/PageListTest.php index 93f0e0a..b998b02 100644 --- a/tests/src/Functional/PageListTest.php +++ b/tests/src/Functional/PageListTest.php @@ -56,4 +56,15 @@ class PageListTest extends BrowserTestBase { $this->assertEquals([1], $nids); } + /** + * Ensure that the results are ordered by title. + */ + public function testResultsAreOrderedAlphabetically() { + // Given I have multiple nodes with different titles. + + // When I view the pages list. + + // Then I should see pages in the correct order. + } + } From fc8eb51bdf8644cdc8191ee3ba3ef0bd4062dae3 Mon Sep 17 00:00:00 2001 From: Oliver Davies <oliver@oliverdavies.uk> Date: Sat, 21 Oct 2017 21:02:58 +0100 Subject: [PATCH 07/33] Create some test content Create several different nodes in an incorrect order so that we can see the test fail when asserting that they should be ordered alphabetically. --- tests/src/Functional/PageListTest.php | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/tests/src/Functional/PageListTest.php b/tests/src/Functional/PageListTest.php index b998b02..2c45f64 100644 --- a/tests/src/Functional/PageListTest.php +++ b/tests/src/Functional/PageListTest.php @@ -60,7 +60,10 @@ class PageListTest extends BrowserTestBase { * Ensure that the results are ordered by title. */ public function testResultsAreOrderedAlphabetically() { - // Given I have multiple nodes with different titles. + $this->drupalCreateNode(['title' => 'Page A']); + $this->drupalCreateNode(['title' => 'Page D']); + $this->drupalCreateNode(['title' => 'Page C']); + $this->drupalCreateNode(['title' => 'Page B']); // When I view the pages list. From 992390b80308cb54a1894ab2a52fce3174c1ea3e Mon Sep 17 00:00:00 2001 From: Oliver Davies <oliver@oliverdavies.uk> Date: Sat, 21 Oct 2017 21:04:37 +0100 Subject: [PATCH 08/33] Retrieve the data from the view --- tests/src/Functional/PageListTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/src/Functional/PageListTest.php b/tests/src/Functional/PageListTest.php index 2c45f64..513c586 100644 --- a/tests/src/Functional/PageListTest.php +++ b/tests/src/Functional/PageListTest.php @@ -65,7 +65,7 @@ class PageListTest extends BrowserTestBase { $this->drupalCreateNode(['title' => 'Page C']); $this->drupalCreateNode(['title' => 'Page B']); - // When I view the pages list. + $nids = array_column(views_get_view_result('pages'), 'nid'); // Then I should see pages in the correct order. } From 461e66bf5341c6b24f52df353e2214fe22b1594c Mon Sep 17 00:00:00 2001 From: Oliver Davies <oliver@oliverdavies.uk> Date: Sat, 21 Oct 2017 21:13:55 +0100 Subject: [PATCH 09/33] Assert expected node order --- tests/src/Functional/PageListTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/src/Functional/PageListTest.php b/tests/src/Functional/PageListTest.php index 513c586..d01adc7 100644 --- a/tests/src/Functional/PageListTest.php +++ b/tests/src/Functional/PageListTest.php @@ -67,7 +67,7 @@ class PageListTest extends BrowserTestBase { $nids = array_column(views_get_view_result('pages'), 'nid'); - // Then I should see pages in the correct order. + $this->assertEquals([1, 4, 3, 2], $nids); } } From 81af444a97953c07fda20aad00d4deede071ad1e Mon Sep 17 00:00:00 2001 From: Oliver Davies <oliver@oliverdavies.uk> Date: Sat, 21 Oct 2017 21:21:00 +0100 Subject: [PATCH 10/33] Update sort criteria Remove the default "Authored on" sort criteria and replace it with a "Content: Title" sort to order the items alphabetically. --- config/install/views.view.pages.yml | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/config/install/views.view.pages.yml b/config/install/views.view.pages.yml index d09a6d2..9834a6b 100644 --- a/config/install/views.view.pages.yml +++ b/config/install/views.view.pages.yml @@ -179,21 +179,20 @@ display: entity_field: type plugin_id: bundle sorts: - created: - id: created + title: + id: title table: node_field_data - field: created - order: DESC - entity_type: node - entity_field: created - plugin_id: date + field: title relationship: none group_type: group admin_label: '' + order: ASC exposed: false expose: label: '' - granularity: second + entity_type: node + entity_field: title + plugin_id: standard header: { } footer: { } empty: { } From 66389b7a21349d379682a83bcfeecac44aa710b6 Mon Sep 17 00:00:00 2001 From: Oliver Davies <oliver@oliverdavies.uk> Date: Sat, 21 Oct 2017 21:50:37 +0100 Subject: [PATCH 11/33] Update README --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 4125f53..8ccdeb9 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # TDD Dublin demo module -A demo module to accompany my [TDD Test Driven Drupal][0] talk at DrupalCamp +A demo module to accompany my [TDD - Test Driven Drupal][0] talk at DrupalCamp Dublin 2017. ## Acceptance Criteria From 5ead634ab2297774c8a9dbe565d54330e7f9aea7 Mon Sep 17 00:00:00 2001 From: Oliver Davies <oliver@oliverdavies.uk> Date: Sat, 21 Oct 2017 21:58:44 +0100 Subject: [PATCH 12/33] Add dependencies section --- README.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/README.md b/README.md index 8ccdeb9..bd43e09 100644 --- a/README.md +++ b/README.md @@ -12,6 +12,16 @@ develop a module to the following acceptance criteria: - I want to see a list of all published pages at `/pages` - Ordered alphabetically by title +## Dependencies + +The module has a dependency on the `tightenco/collect` library which is +required in its `composer.json` file. This will need to be installed via +Composer in order for the tests to run. + +The library is used only to make it simpler to retrieve data from within an +array of view results so that assertions can be made against it. The same tests +could be written in a slightly different way without the dependency if needed. + ## Running the Tests These tests are functional tests based on the `BrowserTestBase` class so need From 5574c5ee9aae715b7f667b14ea04402f2e1247b5 Mon Sep 17 00:00:00 2001 From: Oliver Davies <oliver@oliverdavies.uk> Date: Sat, 21 Oct 2017 22:08:42 +0100 Subject: [PATCH 13/33] Update README --- README.md | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index bd43e09..6edca55 100644 --- a/README.md +++ b/README.md @@ -3,6 +3,12 @@ A demo module to accompany my [TDD - Test Driven Drupal][0] talk at DrupalCamp Dublin 2017. +In order to see my workflow of writing comments first, converting them into +failing tests, and then writing the implementation code to make them pass, you +can see the [list of previous commits][1] and see each step taken, as well as +[the tags][2] that identify the commits when each failing test is added and +then subsequently passes. + ## Acceptance Criteria This module will be used to demonstrate how to take a test-driven approach to @@ -12,16 +18,6 @@ develop a module to the following acceptance criteria: - I want to see a list of all published pages at `/pages` - Ordered alphabetically by title -## Dependencies - -The module has a dependency on the `tightenco/collect` library which is -required in its `composer.json` file. This will need to be installed via -Composer in order for the tests to run. - -The library is used only to make it simpler to retrieve data from within an -array of view results so that assertions can be made against it. The same tests -could be written in a slightly different way without the dependency if needed. - ## Running the Tests These tests are functional tests based on the `BrowserTestBase` class so need @@ -48,3 +44,5 @@ rather than all of the tests within the module. For example: ``` [0]: https://www.oliverdavies.uk/talks/tdd-test-driven-drupal +[1]: https://github.com/opdavies/tdd_dublin/commits/HEAD +[2]: https://github.com/opdavies/tdd_dublin/tags From af09babd7a80bdbbd961af13ce8e60a6d1d7be0f Mon Sep 17 00:00:00 2001 From: Oliver Davies <oliver@oliverdavies.uk> Date: Sat, 21 Oct 2017 22:19:56 +0100 Subject: [PATCH 14/33] Add comments --- tests/src/Functional/PageListTest.php | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/tests/src/Functional/PageListTest.php b/tests/src/Functional/PageListTest.php index d01adc7..7fe1ba4 100644 --- a/tests/src/Functional/PageListTest.php +++ b/tests/src/Functional/PageListTest.php @@ -60,13 +60,26 @@ class PageListTest extends BrowserTestBase { * Ensure that the results are ordered by title. */ public function testResultsAreOrderedAlphabetically() { + // Create a number of nodes with different titles, specifying the title for + // each. These are intentionally not in alphabetical order so that when the + // assertion is written for the results to be in the expected order, it + // will fail, rather than them being in the expected order based on the + // default sort criteria based on the created timestamp. + // + // Also, the titles are added explicitly so that the assertion can be + // written against the expected order based on these titles. If they + // weren't added, each title would be automatically generated so the + // expected order would not be known beforehand. $this->drupalCreateNode(['title' => 'Page A']); $this->drupalCreateNode(['title' => 'Page D']); $this->drupalCreateNode(['title' => 'Page C']); $this->drupalCreateNode(['title' => 'Page B']); + // Get the result data from the view. $nids = array_column(views_get_view_result('pages'), 'nid'); + // Compare the expected order based on the titles defined above to the + // ordered results from the view. $this->assertEquals([1, 4, 3, 2], $nids); } From eb5465c5a6571e9df322f2426a708b8e87eb49a3 Mon Sep 17 00:00:00 2001 From: Oliver Davies <oliver@oliverdavies.uk> Date: Tue, 7 Nov 2017 01:08:47 +0000 Subject: [PATCH 15/33] Update README --- README.md | 10 ++++------ .../{node.type.page.yml => node.type.page.yml_} | 0 tests/src/Kernel/PageListTest.php | 0 3 files changed, 4 insertions(+), 6 deletions(-) rename config/install/{node.type.page.yml => node.type.page.yml_} (100%) create mode 100644 tests/src/Kernel/PageListTest.php diff --git a/README.md b/README.md index 6edca55..4e61bed 100644 --- a/README.md +++ b/README.md @@ -24,23 +24,21 @@ These tests are functional tests based on the `BrowserTestBase` class so need to be executed with PHPUnit (which is required in core's `composer.json` file). The path to your `vendor` directory may be different depending on your setup. -Because of autoloading, you will need to be inside Drupal's `core` subdirectory -when running the tests for them to execute successfully. +Because of autoloading, you will either need to be inside Drupal's `core` subdirectory +, or add `-c core` to the PHPUnit command when running the tests for them to execute successfully. This also assumes that the module is within a `modules/custom` directory and named `tdd_dublin` as per the repository name. ``` -cd core - -../vendor/bin/phpunit ../modules/custom/tdd_dublin +vendor/bin/phpunit -c core modules/custom/tdd_dublin ``` You can use PHPUnit's `--filter` option to specify a single test method to run, rather than all of the tests within the module. For example: ``` -../vendor/bin/phpunit ../modules/custom/tdd_dublin --filter=testOnlyPublishedPagesAreShown +vendor/bin/phpunit -c core modules/custom/tdd_dublin --filter=testOnlyPublishedPagesAreShown ``` [0]: https://www.oliverdavies.uk/talks/tdd-test-driven-drupal diff --git a/config/install/node.type.page.yml b/config/install/node.type.page.yml_ similarity index 100% rename from config/install/node.type.page.yml rename to config/install/node.type.page.yml_ diff --git a/tests/src/Kernel/PageListTest.php b/tests/src/Kernel/PageListTest.php new file mode 100644 index 0000000..e69de29 From ab524316b606081368561bea9295b00081135aeb Mon Sep 17 00:00:00 2001 From: Oliver Davies <oliver@oliverdavies.uk> Date: Tue, 21 Nov 2017 00:51:00 +0000 Subject: [PATCH 16/33] Rename file --- config/install/{node.type.page.yml_ => node.type.page.yml} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename config/install/{node.type.page.yml_ => node.type.page.yml} (100%) diff --git a/config/install/node.type.page.yml_ b/config/install/node.type.page.yml similarity index 100% rename from config/install/node.type.page.yml_ rename to config/install/node.type.page.yml From 81cb121a9951367511d4336746231f37387acc92 Mon Sep 17 00:00:00 2001 From: Oliver Davies <oliver@oliverdavies.uk> Date: Tue, 21 Nov 2017 00:47:45 +0000 Subject: [PATCH 17/33] Change tests to kernel tests Fixes #1 --- tests/src/Functional/PageListTest.php | 86 ------------------- tests/src/Kernel/PageListTest.php | 116 ++++++++++++++++++++++++++ 2 files changed, 116 insertions(+), 86 deletions(-) delete mode 100644 tests/src/Functional/PageListTest.php diff --git a/tests/src/Functional/PageListTest.php b/tests/src/Functional/PageListTest.php deleted file mode 100644 index 7fe1ba4..0000000 --- a/tests/src/Functional/PageListTest.php +++ /dev/null @@ -1,86 +0,0 @@ -<?php - -namespace Drupal\Tests\tdd_dublin\Functional; - -use Drupal\Tests\BrowserTestBase; - -class PageListTest extends BrowserTestBase { - - /** - * {@inheritdoc} - */ - protected static $modules = ['tdd_dublin']; - - /** - * Test that the pages listing page exists and is accessible. - */ - public function testListingPageExists() { - // Go to /pages and check that it is accessible by checking the status - // code. - $this->drupalGet('pages'); - $this->assertSession()->statusCodeEquals(200); - } - - /** - * Ensure that only the correct nodes are returned. - * - * Ensure that only published pages are returned by the view. Unpublished - * pages or content of different types should not be shown. - */ - public function testOnlyPublishedPagesAreShown() { - $this->drupalCreateContentType(['type' => 'article']); - - // This is a published page, so it should be visible. - $this->drupalCreateNode(['type' => 'page', 'status' => TRUE]); - - // This is an article, so it should not be visible. - $this->drupalCreateNode(['type' => 'article']); - - // This page is not published, so it should not be visible. - $this->drupalCreateNode(['type' => 'page', 'status' => FALSE]); - - // Rather than testing the rendered HTML, we are going to load the view - // results programmatically and run assertions against the data it returns. - // This makes it easier to test certain scenarios, and ensures that the - // test is future-proofed and won't fail at a later date due to a change in - // the presentation code. - $result = views_get_view_result('pages'); - - // $result contains an array of Drupal\views\ResultRow objects. We can use - // array_column to get the nid from each node and return them as an array. - $nids = array_column($result, 'nid'); - - // Only node 1 matches the criteria of being a published page, so only that - // node ID should be being returned from the view. assertEquals() can be - // used to compare the expected result to what is being returned. - $this->assertEquals([1], $nids); - } - - /** - * Ensure that the results are ordered by title. - */ - public function testResultsAreOrderedAlphabetically() { - // Create a number of nodes with different titles, specifying the title for - // each. These are intentionally not in alphabetical order so that when the - // assertion is written for the results to be in the expected order, it - // will fail, rather than them being in the expected order based on the - // default sort criteria based on the created timestamp. - // - // Also, the titles are added explicitly so that the assertion can be - // written against the expected order based on these titles. If they - // weren't added, each title would be automatically generated so the - // expected order would not be known beforehand. - $this->drupalCreateNode(['title' => 'Page A']); - $this->drupalCreateNode(['title' => 'Page D']); - $this->drupalCreateNode(['title' => 'Page C']); - $this->drupalCreateNode(['title' => 'Page B']); - - // Get the result data from the view. - $nids = array_column(views_get_view_result('pages'), 'nid'); - - // Compare the expected order based on the titles defined above to the - // ordered results from the view. - $this->assertEquals([1, 4, 3, 2], $nids); - } - -} diff --git a/tests/src/Kernel/PageListTest.php b/tests/src/Kernel/PageListTest.php index e69de29..9b34bd6 100644 --- a/tests/src/Kernel/PageListTest.php +++ b/tests/src/Kernel/PageListTest.php @@ -0,0 +1,116 @@ +<?php + +namespace Drupal\Tests\tdd_dublin\Kernel; + +use Drupal\KernelTests\KernelTestBase; +use Drupal\node\Entity\Node; +use Drupal\node\Entity\NodeType; + +/** + * @group tdd_dublin + */ +class PageListTest extends KernelTestBase { + + /** + * {@inheritdoc} + */ + protected static $modules = [ + 'node', + 'system', + 'tdd_dublin', + 'user', + 'views', + ]; + + /** + * {@inheritdoc} + */ + protected function setUp() { + parent::setUp(); + + $this->installConfig(['tdd_dublin']); + + $this->installEntitySchema('node'); + $this->installEntitySchema('user'); + } + + /** + * Ensure that only the correct nodes are returned. + * + * Ensure that only published pages are returned by the view. Unpublished + * pages or content of different types should not be shown. + */ + public function testOnlyPublishedPagesAreShown() { + NodeType::create(['type' => 'article', 'name' => t('Article')]); + + // This is a published page, so it should be visible. + Node::create($this->getValidParams(['status' => TRUE]))->save(); + + // This is an article, so it should not be visible. + Node::create($this->getValidParams(['type' => 'article']))->save(); + + // This page is not published, so it should not be visible. + Node::create($this->getValidParams(['status' => FALSE]))->save(); + + // Rather than testing the rendered HTML, we are going to load the view + // results programmatically and run assertions against the data it returns. + // This makes it easier to test certain scenarios, and ensures that the + // test is future-proofed and won't fail at a later date due to a change in + // the presentation code. + $result = views_get_view_result('pages'); + + // $result contains an array of Drupal\views\ResultRow objects. We can use + // array_column to get the nid from each node and return them as an array. + $nids = array_column($result, 'nid'); + + // Only node 1 matches the criteria of being a published page, so only that + // node ID should be being returned from the view. assertEquals() can be + // used to compare the expected result to what is being returned. + $this->assertEquals([1], $nids); + } + + /** + * Ensure that the results are ordered by title. + */ + public function testResultsAreOrderedAlphabetically() { + // Create a number of nodes with different titles, specifying the title for + // each. These are intentionally not in alphabetical order so that when the + // assertion is written for the results to be in the expected order, it + // will fail, rather than them being in the expected order based on the + // default sort criteria based on the created timestamp. + // + // Also, the titles are added explicitly so that the assertion can be + // written against the expected order based on these titles. If they + // weren't added, each title would be automatically generated so the + // expected order would not be known beforehand. + Node::create($this->getValidParams(['title' => 'Page A']))->save(); + Node::create($this->getValidParams(['title' => 'Page D']))->save(); + Node::create($this->getValidParams(['title' => 'Page C']))->save(); + Node::create($this->getValidParams(['title' => 'Page B']))->save(); + + // Get the result data from the view. + $nids = array_column(views_get_view_result('pages'), 'nid'); + + // Compare the expected order based on the titles defined above to the + // ordered results from the view. + $this->assertEquals([1, 4, 3, 2], $nids); + } + + /** + * Default parameters for creating test nodes. + * + * @param array $overrides + * An associative array of overridden values. + * + * @return array + * The overridden parameters array, combined with the defaults. + */ + private function getValidParams(array $overrides = []) { + return array_merge([ + 'status' => TRUE, + 'title' => $this->randomString(), + 'type' => 'page', + ], $overrides); + } + +} From 349ec8f965656e5636cea94b0926e53e60586c00 Mon Sep 17 00:00:00 2001 From: Oliver Davies <opdavies@gmail.com> Date: Tue, 20 Mar 2018 18:46:35 +0000 Subject: [PATCH 18/33] Add tdd_dublin_test sub-module --- .../config/optional/node.type.article.yml | 10 ++++++++++ .../config/optional}/node.type.page.yml | 0 .../tdd_dublin_test/tdd_dublin_test.info.yml | 6 ++++++ tests/src/Kernel/PageListTest.php | 15 +++++++++------ 4 files changed, 25 insertions(+), 6 deletions(-) create mode 100644 tests/modules/tdd_dublin_test/config/optional/node.type.article.yml rename {config/install => tests/modules/tdd_dublin_test/config/optional}/node.type.page.yml (100%) create mode 100644 tests/modules/tdd_dublin_test/tdd_dublin_test.info.yml diff --git a/tests/modules/tdd_dublin_test/config/optional/node.type.article.yml b/tests/modules/tdd_dublin_test/config/optional/node.type.article.yml new file mode 100644 index 0000000..1fd439c --- /dev/null +++ b/tests/modules/tdd_dublin_test/config/optional/node.type.article.yml @@ -0,0 +1,10 @@ +langcode: en +status: true +dependencies: { } +name: Article +type: article +description: 'Use <em>articles</em> for time-sensitive content like news, press releases or blog posts.' +help: '' +new_revision: true +preview_mode: 1 +display_submitted: true diff --git a/config/install/node.type.page.yml b/tests/modules/tdd_dublin_test/config/optional/node.type.page.yml similarity index 100% rename from config/install/node.type.page.yml rename to tests/modules/tdd_dublin_test/config/optional/node.type.page.yml diff --git a/tests/modules/tdd_dublin_test/tdd_dublin_test.info.yml b/tests/modules/tdd_dublin_test/tdd_dublin_test.info.yml new file mode 100644 index 0000000..1725970 --- /dev/null +++ b/tests/modules/tdd_dublin_test/tdd_dublin_test.info.yml @@ -0,0 +1,6 @@ +name: TDD Dublin Test +type: module +core: 8.x +dependencies: + - tdd_dublin:tdd_dublin +hidden: true diff --git a/tests/src/Kernel/PageListTest.php b/tests/src/Kernel/PageListTest.php index 9b34bd6..b3eb22f 100644 --- a/tests/src/Kernel/PageListTest.php +++ b/tests/src/Kernel/PageListTest.php @@ -18,6 +18,7 @@ class PageListTest extends KernelTestBase { 'node', 'system', 'tdd_dublin', + 'tdd_dublin_test', 'user', 'views', ]; @@ -57,11 +58,10 @@ class PageListTest extends KernelTestBase { // This makes it easier to test certain scenarios, and ensures that the // test is future-proofed and won't fail at a later date due to a change in // the presentation code. - $result = views_get_view_result('pages'); - - // $result contains an array of Drupal\views\ResultRow objects. We can use - // array_column to get the nid from each node and return them as an array. - $nids = array_column($result, 'nid'); + $nids = []; + foreach (views_get_view_result('pages') as $result) { + $nids[] = $result->nid; + } // Only node 1 matches the criteria of being a published page, so only that // node ID should be being returned from the view. assertEquals() can be @@ -89,7 +89,10 @@ class PageListTest extends KernelTestBase { Node::create($this->getValidParams(['title' => 'Page B']))->save(); // Get the result data from the view. - $nids = array_column(views_get_view_result('pages'), 'nid'); + $nids = []; + foreach (views_get_view_result('pages') as $result) { + $nids[] = $result->nid; + } // Compare the expected order based on the titles defined above to the // ordered results from the view. From 4238580d665f619a8a593fe67bb2aae581aa06a5 Mon Sep 17 00:00:00 2001 From: Oliver Davies <opdavies@gmail.com> Date: Tue, 20 Mar 2018 18:48:27 +0000 Subject: [PATCH 19/33] Remove extra lines --- tests/src/Kernel/PageListTest.php | 3 --- 1 file changed, 3 deletions(-) diff --git a/tests/src/Kernel/PageListTest.php b/tests/src/Kernel/PageListTest.php index b3eb22f..241ee58 100644 --- a/tests/src/Kernel/PageListTest.php +++ b/tests/src/Kernel/PageListTest.php @@ -4,7 +4,6 @@ namespace Drupal\Tests\tdd_dublin\Kernel; use Drupal\KernelTests\KernelTestBase; use Drupal\node\Entity\Node; -use Drupal\node\Entity\NodeType; /** * @group tdd_dublin @@ -42,8 +41,6 @@ class PageListTest extends KernelTestBase { * pages or content of different types should not be shown. */ public function testOnlyPublishedPagesAreShown() { - NodeType::create(['type' => 'article', 'name' => t('Article')]); - // This is a published page, so it should be visible. Node::create($this->getValidParams(['status' => TRUE]))->save(); From 238dd8fb689611644cb846c67057d2811610e71b Mon Sep 17 00:00:00 2001 From: Oliver Davies <opdavies@gmail.com> Date: Tue, 20 Mar 2018 19:26:28 +0000 Subject: [PATCH 20/33] Rename method --- tests/src/Kernel/PageListTest.php | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/tests/src/Kernel/PageListTest.php b/tests/src/Kernel/PageListTest.php index 241ee58..8bcd151 100644 --- a/tests/src/Kernel/PageListTest.php +++ b/tests/src/Kernel/PageListTest.php @@ -42,13 +42,13 @@ class PageListTest extends KernelTestBase { */ public function testOnlyPublishedPagesAreShown() { // This is a published page, so it should be visible. - Node::create($this->getValidParams(['status' => TRUE]))->save(); + Node::create($this->validParams(['status' => TRUE]))->save(); // This is an article, so it should not be visible. - Node::create($this->getValidParams(['type' => 'article']))->save(); + Node::create($this->validParams(['type' => 'article']))->save(); // This page is not published, so it should not be visible. - Node::create($this->getValidParams(['status' => FALSE]))->save(); + Node::create($this->validParams(['status' => FALSE]))->save(); // Rather than testing the rendered HTML, we are going to load the view // results programmatically and run assertions against the data it returns. @@ -80,10 +80,10 @@ class PageListTest extends KernelTestBase { // written against the expected order based on these titles. If they // weren't added, each title would be automatically generated so the // expected order would not be known beforehand. - Node::create($this->getValidParams(['title' => 'Page A']))->save(); - Node::create($this->getValidParams(['title' => 'Page D']))->save(); - Node::create($this->getValidParams(['title' => 'Page C']))->save(); - Node::create($this->getValidParams(['title' => 'Page B']))->save(); + Node::create($this->validParams(['title' => 'Page A']))->save(); + Node::create($this->validParams(['title' => 'Page D']))->save(); + Node::create($this->validParams(['title' => 'Page C']))->save(); + Node::create($this->validParams(['title' => 'Page B']))->save(); // Get the result data from the view. $nids = []; @@ -105,7 +105,7 @@ class PageListTest extends KernelTestBase { * @return array * The overridden parameters array, combined with the defaults. */ - private function getValidParams(array $overrides = []) { + private function validParams(array $overrides = []) { return array_merge([ 'status' => TRUE, 'title' => $this->randomString(), From 38314a0ed2b867dbfa9ec24f0823e2606ac031aa Mon Sep 17 00:00:00 2001 From: Oliver Davies <opdavies@gmail.com> Date: Mon, 2 Apr 2018 21:29:19 +0100 Subject: [PATCH 21/33] Use array_map --- tests/src/Kernel/PageListTest.php | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/tests/src/Kernel/PageListTest.php b/tests/src/Kernel/PageListTest.php index 8bcd151..8d59299 100644 --- a/tests/src/Kernel/PageListTest.php +++ b/tests/src/Kernel/PageListTest.php @@ -4,6 +4,7 @@ namespace Drupal\Tests\tdd_dublin\Kernel; use Drupal\KernelTests\KernelTestBase; use Drupal\node\Entity\Node; +use Drupal\views\ResultRow; /** * @group tdd_dublin @@ -55,10 +56,9 @@ class PageListTest extends KernelTestBase { // This makes it easier to test certain scenarios, and ensures that the // test is future-proofed and won't fail at a later date due to a change in // the presentation code. - $nids = []; - foreach (views_get_view_result('pages') as $result) { - $nids[] = $result->nid; - } + $nids = array_map(function (ResultRow $result) { + return $result->_entity->id(); + }, views_get_view_result('pages')); // Only node 1 matches the criteria of being a published page, so only that // node ID should be being returned from the view. assertEquals() can be @@ -86,10 +86,9 @@ class PageListTest extends KernelTestBase { Node::create($this->validParams(['title' => 'Page B']))->save(); // Get the result data from the view. - $nids = []; - foreach (views_get_view_result('pages') as $result) { - $nids[] = $result->nid; - } + $nids = array_map(function (ResultRow $result) { + return $result->_entity->id(); + }, views_get_view_result('pages')); // Compare the expected order based on the titles defined above to the // ordered results from the view. From 4ec57cdf2ec57f2c5c34b9b8cf6ce54e189f59a7 Mon Sep 17 00:00:00 2001 From: Oliver Davies <opdavies@gmail.com> Date: Tue, 3 Apr 2018 08:46:46 +0100 Subject: [PATCH 22/33] Add installation instructions --- README.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/README.md b/README.md index 4e61bed..11c464e 100644 --- a/README.md +++ b/README.md @@ -18,6 +18,15 @@ develop a module to the following acceptance criteria: - I want to see a list of all published pages at `/pages` - Ordered alphabetically by title +## Installation + +Within your Drupal 8 site: + +```bash +cd modules +git clone git@github.com:opdavies/drupal-tdd-dublin.git tdd_dublin +``` + ## Running the Tests These tests are functional tests based on the `BrowserTestBase` class so need From 442ec19bc11a0aa87916a9cfb1476e9ddcddf3d8 Mon Sep 17 00:00:00 2001 From: Oliver Davies <opdavies@gmail.com> Date: Thu, 19 Apr 2018 14:16:57 +0100 Subject: [PATCH 23/33] Use EntityKernelTestBase --- .../config/optional/node.type.article.yml | 10 ---------- .../config/optional/node.type.page.yml | 12 ------------ .../modules/tdd_dublin_test/tdd_dublin_test.info.yml | 6 ------ tests/src/Kernel/PageListTest.php | 9 +++------ 4 files changed, 3 insertions(+), 34 deletions(-) delete mode 100644 tests/modules/tdd_dublin_test/config/optional/node.type.article.yml delete mode 100644 tests/modules/tdd_dublin_test/config/optional/node.type.page.yml delete mode 100644 tests/modules/tdd_dublin_test/tdd_dublin_test.info.yml diff --git a/tests/modules/tdd_dublin_test/config/optional/node.type.article.yml b/tests/modules/tdd_dublin_test/config/optional/node.type.article.yml deleted file mode 100644 index 1fd439c..0000000 --- a/tests/modules/tdd_dublin_test/config/optional/node.type.article.yml +++ /dev/null @@ -1,10 +0,0 @@ -langcode: en -status: true -dependencies: { } -name: Article -type: article -description: 'Use <em>articles</em> for time-sensitive content like news, press releases or blog posts.' -help: '' -new_revision: true -preview_mode: 1 -display_submitted: true diff --git a/tests/modules/tdd_dublin_test/config/optional/node.type.page.yml b/tests/modules/tdd_dublin_test/config/optional/node.type.page.yml deleted file mode 100644 index a6ddd46..0000000 --- a/tests/modules/tdd_dublin_test/config/optional/node.type.page.yml +++ /dev/null @@ -1,12 +0,0 @@ -langcode: en -status: true -dependencies: { } -_core: - default_config_hash: KuyA4NHPXcmKAjRtwa0vQc2ZcyrUJy6IlS2TAyMNRbc -name: 'Basic page' -type: page -description: 'Use <em>basic pages</em> for your static content, such as an ''About us'' page.' -help: '' -new_revision: true -preview_mode: 1 -display_submitted: false diff --git a/tests/modules/tdd_dublin_test/tdd_dublin_test.info.yml b/tests/modules/tdd_dublin_test/tdd_dublin_test.info.yml deleted file mode 100644 index 1725970..0000000 --- a/tests/modules/tdd_dublin_test/tdd_dublin_test.info.yml +++ /dev/null @@ -1,6 +0,0 @@ -name: TDD Dublin Test -type: module -core: 8.x -dependencies: - - tdd_dublin:tdd_dublin -hidden: true diff --git a/tests/src/Kernel/PageListTest.php b/tests/src/Kernel/PageListTest.php index 8d59299..ab5f929 100644 --- a/tests/src/Kernel/PageListTest.php +++ b/tests/src/Kernel/PageListTest.php @@ -2,24 +2,21 @@ namespace Drupal\Tests\tdd_dublin\Kernel; -use Drupal\KernelTests\KernelTestBase; +use Drupal\KernelTests\Core\Entity\EntityKernelTestBase; use Drupal\node\Entity\Node; use Drupal\views\ResultRow; /** * @group tdd_dublin */ -class PageListTest extends KernelTestBase { +class PageListTest extends EntityKernelTestBase { /** * {@inheritdoc} */ - protected static $modules = [ + public static $modules = [ 'node', - 'system', 'tdd_dublin', - 'tdd_dublin_test', - 'user', 'views', ]; From 41bcbb50ab4fa41ec9108c4c8a6f37c20c5e4b58 Mon Sep 17 00:00:00 2001 From: Oliver Davies <opdavies@gmail.com> Date: Thu, 19 Apr 2018 23:29:38 +0100 Subject: [PATCH 24/33] Update README.md --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 11c464e..f13bd4b 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# TDD Dublin demo module +# TDD Example Drupal 8 Module for DrupalCamp Dublin A demo module to accompany my [TDD - Test Driven Drupal][0] talk at DrupalCamp Dublin 2017. @@ -24,7 +24,7 @@ Within your Drupal 8 site: ```bash cd modules -git clone git@github.com:opdavies/drupal-tdd-dublin.git tdd_dublin +git clone git@github.com:opdavies/drupal-module-tdd-dublin.git tdd_dublin ``` ## Running the Tests @@ -50,6 +50,6 @@ rather than all of the tests within the module. For example: vendor/bin/phpunit -c core modules/custom/tdd_dublin --filter=testOnlyPublishedPagesAreShown ``` -[0]: https://www.oliverdavies.uk/talks/tdd-test-driven-drupal +[0]: https://www.oliverdavi.es/talks/tdd-test-driven-drupal [1]: https://github.com/opdavies/tdd_dublin/commits/HEAD [2]: https://github.com/opdavies/tdd_dublin/tags From f8a864b6ccd62ed678894f9e6c9364ce379489ca Mon Sep 17 00:00:00 2001 From: Oliver Davies <opdavies@gmail.com> Date: Thu, 19 Apr 2018 14:25:42 +0100 Subject: [PATCH 25/33] Use the NodeCreationTrait, remove validParams --- tests/src/Kernel/PageListTest.php | 38 ++++++++++--------------------- 1 file changed, 12 insertions(+), 26 deletions(-) diff --git a/tests/src/Kernel/PageListTest.php b/tests/src/Kernel/PageListTest.php index ab5f929..d0fb281 100644 --- a/tests/src/Kernel/PageListTest.php +++ b/tests/src/Kernel/PageListTest.php @@ -4,6 +4,7 @@ namespace Drupal\Tests\tdd_dublin\Kernel; use Drupal\KernelTests\Core\Entity\EntityKernelTestBase; use Drupal\node\Entity\Node; +use Drupal\Tests\node\Traits\NodeCreationTrait; use Drupal\views\ResultRow; /** @@ -11,6 +12,8 @@ use Drupal\views\ResultRow; */ class PageListTest extends EntityKernelTestBase { + use NodeCreationTrait; + /** * {@inheritdoc} */ @@ -26,10 +29,10 @@ class PageListTest extends EntityKernelTestBase { protected function setUp() { parent::setUp(); - $this->installConfig(['tdd_dublin']); - $this->installEntitySchema('node'); $this->installEntitySchema('user'); + + $this->installConfig(['filter', 'tdd_dublin']); } /** @@ -40,13 +43,13 @@ class PageListTest extends EntityKernelTestBase { */ public function testOnlyPublishedPagesAreShown() { // This is a published page, so it should be visible. - Node::create($this->validParams(['status' => TRUE]))->save(); + $this->createNode(['status' => TRUE]); // This is an article, so it should not be visible. - Node::create($this->validParams(['type' => 'article']))->save(); + $this->createNode(['type' => 'article']); // This page is not published, so it should not be visible. - Node::create($this->validParams(['status' => FALSE]))->save(); + $this->createNode(['status' => FALSE]); // Rather than testing the rendered HTML, we are going to load the view // results programmatically and run assertions against the data it returns. @@ -77,10 +80,10 @@ class PageListTest extends EntityKernelTestBase { // written against the expected order based on these titles. If they // weren't added, each title would be automatically generated so the // expected order would not be known beforehand. - Node::create($this->validParams(['title' => 'Page A']))->save(); - Node::create($this->validParams(['title' => 'Page D']))->save(); - Node::create($this->validParams(['title' => 'Page C']))->save(); - Node::create($this->validParams(['title' => 'Page B']))->save(); + $this->createNode(['title' => 'Page A']); + $this->createNode(['title' => 'Page D']); + $this->createNode(['title' => 'Page C']); + $this->createNode(['title' => 'Page B']); // Get the result data from the view. $nids = array_map(function (ResultRow $result) { @@ -92,21 +95,4 @@ class PageListTest extends EntityKernelTestBase { $this->assertEquals([1, 4, 3, 2], $nids); } - /** - * Default parameters for creating test nodes. - * - * @param array $overrides - * An associative array of overridden values. - * - * @return array - * The overridden parameters array, combined with the defaults. - */ - private function validParams(array $overrides = []) { - return array_merge([ - 'status' => TRUE, - 'title' => $this->randomString(), - 'type' => 'page', - ], $overrides); - } - } From dccc8f1875736f7b6409368f20626c925082da33 Mon Sep 17 00:00:00 2001 From: Oliver Davies <opdavies@gmail.com> Date: Fri, 20 Apr 2018 00:10:28 +0100 Subject: [PATCH 26/33] Add node types explicitly --- tests/src/Kernel/PageListTest.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/src/Kernel/PageListTest.php b/tests/src/Kernel/PageListTest.php index d0fb281..6d8df53 100644 --- a/tests/src/Kernel/PageListTest.php +++ b/tests/src/Kernel/PageListTest.php @@ -43,13 +43,13 @@ class PageListTest extends EntityKernelTestBase { */ public function testOnlyPublishedPagesAreShown() { // This is a published page, so it should be visible. - $this->createNode(['status' => TRUE]); + $this->createNode(['type' => 'page', 'status' => TRUE]); // This is an article, so it should not be visible. $this->createNode(['type' => 'article']); // This page is not published, so it should not be visible. - $this->createNode(['status' => FALSE]); + $this->createNode(['type' => 'page', 'status' => FALSE]); // Rather than testing the rendered HTML, we are going to load the view // results programmatically and run assertions against the data it returns. From 5be880e496cf7949c70f16b09d1e7b795b29e5f0 Mon Sep 17 00:00:00 2001 From: Oliver Davies <opdavies@gmail.com> Date: Thu, 14 Jun 2018 09:52:58 +0100 Subject: [PATCH 27/33] Create composer.json --- composer.json | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 composer.json diff --git a/composer.json b/composer.json new file mode 100644 index 0000000..e57be22 --- /dev/null +++ b/composer.json @@ -0,0 +1,4 @@ +{ + "name": "drupal/tdd_dublin", + "type": "drupal-custom-module" +} From ccaa426a382a5ca2dac103bf0903db8722f5f07a Mon Sep 17 00:00:00 2001 From: Oliver Davies <oliver@oliverdavies.uk> Date: Fri, 7 Sep 2018 18:33:14 +0100 Subject: [PATCH 28/33] Change to tdd_blog --- README.md | 18 ++--- composer.json | 2 +- config/install/node.type.article.yml | 10 +++ ...ews.view.pages.yml => views.view.blog.yml} | 45 +++++++------ tdd_dublin.info.yml => tdd_blog.info.yml | 2 +- tests/src/Functional/PageListTest.php | 17 +++++ tests/src/Kernel/PageListTest.php | 67 ++++++++++--------- 7 files changed, 95 insertions(+), 66 deletions(-) create mode 100644 config/install/node.type.article.yml rename config/install/{views.view.pages.yml => views.view.blog.yml} (89%) rename tdd_dublin.info.yml => tdd_blog.info.yml (89%) create mode 100644 tests/src/Functional/PageListTest.php diff --git a/README.md b/README.md index f13bd4b..9fef7f8 100644 --- a/README.md +++ b/README.md @@ -15,8 +15,8 @@ This module will be used to demonstrate how to take a test-driven approach to develop a module to the following acceptance criteria: - As a site visitor -- I want to see a list of all published pages at `/pages` -- Ordered alphabetically by title +- I want to see a list of all published blog posts at `/blog` +- Ordered by post date, with the newest posts first ## Installation @@ -24,7 +24,7 @@ Within your Drupal 8 site: ```bash cd modules -git clone git@github.com:opdavies/drupal-module-tdd-dublin.git tdd_dublin +git clone git@github.com:opdavies/drupal-module-tdd-blog.git tdd_blog ``` ## Running the Tests @@ -37,19 +37,19 @@ Because of autoloading, you will either need to be inside Drupal's `core` subdir , or add `-c core` to the PHPUnit command when running the tests for them to execute successfully. This also assumes that the module is within a `modules/custom` directory and -named `tdd_dublin` as per the repository name. +named `tdd_blog` as per the repository name. ``` -vendor/bin/phpunit -c core modules/custom/tdd_dublin +vendor/bin/phpunit -c core modules/custom/tdd_blog ``` You can use PHPUnit's `--filter` option to specify a single test method to run, rather than all of the tests within the module. For example: ``` -vendor/bin/phpunit -c core modules/custom/tdd_dublin --filter=testOnlyPublishedPagesAreShown +vendor/bin/phpunit -c core modules/custom/tdd_blog --filter=testOnlyPublishedPagesAreShown ``` -[0]: https://www.oliverdavi.es/talks/tdd-test-driven-drupal -[1]: https://github.com/opdavies/tdd_dublin/commits/HEAD -[2]: https://github.com/opdavies/tdd_dublin/tags +[0]: https://www.oliverdavies.uk/talks/tdd-test-driven-drupal +[1]: https://github.com/opdavies/drupal-module-tdd-blog/commits/HEAD +[2]: https://github.com/opdavies/drupal-module-tdd-blog/tags diff --git a/composer.json b/composer.json index e57be22..aa7e974 100644 --- a/composer.json +++ b/composer.json @@ -1,4 +1,4 @@ { - "name": "drupal/tdd_dublin", + "name": "drupal/tdd_blog", "type": "drupal-custom-module" } diff --git a/config/install/node.type.article.yml b/config/install/node.type.article.yml new file mode 100644 index 0000000..57dcc0c --- /dev/null +++ b/config/install/node.type.article.yml @@ -0,0 +1,10 @@ +langcode: en +status: true +dependencies: { } +name: 'Basic page' +type: page +description: 'Use <em>basic pages</em> for your static content, such as an ''About us'' page.' +help: '' +new_revision: true +preview_mode: 1 +display_submitted: false diff --git a/config/install/views.view.pages.yml b/config/install/views.view.blog.yml similarity index 89% rename from config/install/views.view.pages.yml rename to config/install/views.view.blog.yml index 9834a6b..783846f 100644 --- a/config/install/views.view.pages.yml +++ b/config/install/views.view.blog.yml @@ -2,12 +2,12 @@ langcode: en status: true dependencies: config: - - node.type.page + - node.type.article module: - - node - - user -id: pages -label: pages + - node + - user +id: blog +label: Blog module: views description: '' tag: '' @@ -147,7 +147,7 @@ display: admin_label: '' operator: in value: - page: page + article: article group: 1 exposed: false expose: @@ -179,10 +179,10 @@ display: entity_field: type plugin_id: bundle sorts: - title: - id: title + created: + id: created table: node_field_data - field: title + field: created relationship: none group_type: group admin_label: '' @@ -190,9 +190,10 @@ display: exposed: false expose: label: '' + granularity: second entity_type: node - entity_field: title - plugin_id: standard + entity_field: created + plugin_id: date header: { } footer: { } empty: { } @@ -202,11 +203,11 @@ display: cache_metadata: max-age: -1 contexts: - - 'languages:language_content' - - 'languages:language_interface' - - url.query_args - - 'user.node_grants:view' - - user.permissions + - 'languages:language_content' + - 'languages:language_interface' + - url.query_args + - 'user.node_grants:view' + - user.permissions tags: { } page_1: display_plugin: page @@ -215,13 +216,13 @@ display: position: 1 display_options: display_extenders: { } - path: pages + path: blog cache_metadata: max-age: -1 contexts: - - 'languages:language_content' - - 'languages:language_interface' - - url.query_args - - 'user.node_grants:view' - - user.permissions + - 'languages:language_content' + - 'languages:language_interface' + - url.query_args + - 'user.node_grants:view' + - user.permissions tags: { } diff --git a/tdd_dublin.info.yml b/tdd_blog.info.yml similarity index 89% rename from tdd_dublin.info.yml rename to tdd_blog.info.yml index 448351b..f9453b1 100644 --- a/tdd_dublin.info.yml +++ b/tdd_blog.info.yml @@ -1,4 +1,4 @@ -name: 'TDD Dublin' +name: 'TDD Blog' description: 'A demo module for DrupalCamp Dublin to show test driven module development.' core: 8.x type: module diff --git a/tests/src/Functional/PageListTest.php b/tests/src/Functional/PageListTest.php new file mode 100644 index 0000000..9b74a9f --- /dev/null +++ b/tests/src/Functional/PageListTest.php @@ -0,0 +1,17 @@ +<?php + +namespace Drupal\Tests\tdd_blog\Functional; + +use Drupal\Tests\BrowserTestBase; + +class PageListTest extends BrowserTestBase { + + protected static $modules = ['tdd_blog']; + + public function testBlogPageExists() { + $this->drupalGet('blog'); + + $this->assertSession()->statusCodeEquals(200); + } + +} diff --git a/tests/src/Kernel/PageListTest.php b/tests/src/Kernel/PageListTest.php index 6d8df53..2e5cb48 100644 --- a/tests/src/Kernel/PageListTest.php +++ b/tests/src/Kernel/PageListTest.php @@ -1,14 +1,14 @@ <?php -namespace Drupal\Tests\tdd_dublin\Kernel; +namespace Drupal\Tests\tdd_blog\Kernel; +use Drupal\Core\Datetime\DrupalDateTime; use Drupal\KernelTests\Core\Entity\EntityKernelTestBase; -use Drupal\node\Entity\Node; use Drupal\Tests\node\Traits\NodeCreationTrait; use Drupal\views\ResultRow; /** - * @group tdd_dublin + * @group tdd_blog */ class PageListTest extends EntityKernelTestBase { @@ -19,7 +19,7 @@ class PageListTest extends EntityKernelTestBase { */ public static $modules = [ 'node', - 'tdd_dublin', + 'tdd_blog', 'views', ]; @@ -32,7 +32,7 @@ class PageListTest extends EntityKernelTestBase { $this->installEntitySchema('node'); $this->installEntitySchema('user'); - $this->installConfig(['filter', 'tdd_dublin']); + $this->installConfig(['filter', 'tdd_blog']); } /** @@ -41,58 +41,59 @@ class PageListTest extends EntityKernelTestBase { * Ensure that only published pages are returned by the view. Unpublished * pages or content of different types should not be shown. */ - public function testOnlyPublishedPagesAreShown() { - // This is a published page, so it should be visible. + public function testOnlyPublishedArticlesAreShown() { + // This is a published article, so it should be visible. $this->createNode(['type' => 'page', 'status' => TRUE]); - // This is an article, so it should not be visible. + // This is a page, so it should not be visible. $this->createNode(['type' => 'article']); - // This page is not published, so it should not be visible. - $this->createNode(['type' => 'page', 'status' => FALSE]); + // This article is not published, so it should not be visible. + $this->createNode(['type' => 'article', 'status' => FALSE]); // Rather than testing the rendered HTML, we are going to load the view // results programmatically and run assertions against the data it returns. // This makes it easier to test certain scenarios, and ensures that the // test is future-proofed and won't fail at a later date due to a change in // the presentation code. - $nids = array_map(function (ResultRow $result) { - return $result->_entity->id(); - }, views_get_view_result('pages')); + $nids = $this->getViewResults(); // Only node 1 matches the criteria of being a published page, so only that // node ID should be being returned from the view. assertEquals() can be // used to compare the expected result to what is being returned. - $this->assertEquals([1], $nids); + $this->assertEquals([2], $nids); } /** * Ensure that the results are ordered by title. */ - public function testResultsAreOrderedAlphabetically() { - // Create a number of nodes with different titles, specifying the title for - // each. These are intentionally not in alphabetical order so that when the - // assertion is written for the results to be in the expected order, it - // will fail, rather than them being in the expected order based on the - // default sort criteria based on the created timestamp. - // - // Also, the titles are added explicitly so that the assertion can be - // written against the expected order based on these titles. If they - // weren't added, each title would be automatically generated so the - // expected order would not be known beforehand. - $this->createNode(['title' => 'Page A']); - $this->createNode(['title' => 'Page D']); - $this->createNode(['title' => 'Page C']); - $this->createNode(['title' => 'Page B']); + public function testArticlesAreOrderedByDate() { + $this->createNode(['type' => 'article', 'created' => (new DrupalDateTime('+1 day'))->getTimestamp()]); + $this->createNode(['type' => 'article', 'created' => (new DrupalDateTime('+1 month'))->getTimestamp()]); + $this->createNode(['type' => 'article', 'created' => (new DrupalDateTime('+3 days'))->getTimestamp()]); + $this->createNode(['type' => 'article', 'created' => (new DrupalDateTime('+1 hour'))->getTimestamp()]); // Get the result data from the view. - $nids = array_map(function (ResultRow $result) { - return $result->_entity->id(); - }, views_get_view_result('pages')); + $nids = $this->getViewResults(); // Compare the expected order based on the titles defined above to the // ordered results from the view. - $this->assertEquals([1, 4, 3, 2], $nids); + $this->assertEquals([4, 1, 3, 2], $nids); + } + + /** + * Load the view and get the results. + * + * @param string $view + * (optional) The name of the view. Defaults to 'blog'. + * + * @return array + * An array of returned entity IDs. + */ + private function getViewResults($view = 'blog') { + return array_map(function (ResultRow $result) { + return $result->_entity->id(); + }, views_get_view_result($view)); } } From 772d3d31b07493cbf3464e8b6e4bf56895c85b74 Mon Sep 17 00:00:00 2001 From: Oliver Davies <oliver@oliverdavies.uk> Date: Sat, 2 Mar 2019 11:13:16 +0000 Subject: [PATCH 29/33] Update node.type.article.yml --- config/install/node.type.article.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/config/install/node.type.article.yml b/config/install/node.type.article.yml index 57dcc0c..1fd439c 100644 --- a/config/install/node.type.article.yml +++ b/config/install/node.type.article.yml @@ -1,10 +1,10 @@ langcode: en status: true dependencies: { } -name: 'Basic page' -type: page -description: 'Use <em>basic pages</em> for your static content, such as an ''About us'' page.' +name: Article +type: article +description: 'Use <em>articles</em> for time-sensitive content like news, press releases or blog posts.' help: '' new_revision: true preview_mode: 1 -display_submitted: false +display_submitted: true From 52f13fcac8707b7c456dd1b34b9e2bb7279e9fd5 Mon Sep 17 00:00:00 2001 From: Oliver Davies <oliver@oliverdavies.uk> Date: Sat, 7 Mar 2020 17:15:01 +0000 Subject: [PATCH 30/33] Add $defaultTheme Required for Drupal 9.0. See https://www.drupal.org/node/3083055. --- tests/src/Functional/PageListTest.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/src/Functional/PageListTest.php b/tests/src/Functional/PageListTest.php index 9b74a9f..cbe6ccd 100644 --- a/tests/src/Functional/PageListTest.php +++ b/tests/src/Functional/PageListTest.php @@ -8,6 +8,8 @@ class PageListTest extends BrowserTestBase { protected static $modules = ['tdd_blog']; + protected $defaultTheme = 'stark'; + public function testBlogPageExists() { $this->drupalGet('blog'); From dcab1aca9a8f68c65a87ffbc16bc137420dad9d7 Mon Sep 17 00:00:00 2001 From: Oliver Davies <oliver@oliverdavies.uk> Date: Sat, 7 Mar 2020 17:16:50 +0000 Subject: [PATCH 31/33] Use constant for the response code --- tests/src/Functional/PageListTest.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/src/Functional/PageListTest.php b/tests/src/Functional/PageListTest.php index cbe6ccd..6205de1 100644 --- a/tests/src/Functional/PageListTest.php +++ b/tests/src/Functional/PageListTest.php @@ -3,6 +3,7 @@ namespace Drupal\Tests\tdd_blog\Functional; use Drupal\Tests\BrowserTestBase; +use Symfony\Component\HttpFoundation\Response; class PageListTest extends BrowserTestBase { @@ -13,7 +14,7 @@ class PageListTest extends BrowserTestBase { public function testBlogPageExists() { $this->drupalGet('blog'); - $this->assertSession()->statusCodeEquals(200); + $this->assertSession()->statusCodeEquals(Response::HTTP_OK); } } From 8d0c16dd8e566cee1e0bc54b3d72bd27037d3e90 Mon Sep 17 00:00:00 2001 From: Oliver Davies <oliver@oliverdavies.uk> Date: Sat, 7 Mar 2020 17:17:32 +0000 Subject: [PATCH 32/33] Add core_version_requirement --- tdd_blog.info.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/tdd_blog.info.yml b/tdd_blog.info.yml index f9453b1..1cdb6c0 100644 --- a/tdd_blog.info.yml +++ b/tdd_blog.info.yml @@ -1,6 +1,7 @@ name: 'TDD Blog' description: 'A demo module for DrupalCamp Dublin to show test driven module development.' core: 8.x +core_version_requirement: ^8 || ^9 type: module dependencies: From bf1fce2a52f86ee5e50c4210dbe66ec080deaa13 Mon Sep 17 00:00:00 2001 From: Oliver Davies <oliver@oliverdavies.uk> Date: Sat, 7 Mar 2020 20:13:13 +0000 Subject: [PATCH 33/33] Update README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 9fef7f8..dc05439 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ -# TDD Example Drupal 8 Module for DrupalCamp Dublin +# TDD Example Drupal 8 Blog Module -A demo module to accompany my [TDD - Test Driven Drupal][0] talk at DrupalCamp +A demo module to accompany my [TDD - Test Driven Drupal][0] talk, originally for DrupalCamp Dublin 2017. In order to see my workflow of writing comments first, converting them into