Compare commits

...

33 commits

Author SHA1 Message Date
bf1fce2a52 Update README.md 2020-03-07 20:15:32 +00:00
8d0c16dd8e Add core_version_requirement 2020-03-07 17:17:32 +00:00
dcab1aca9a Use constant for the response code 2020-03-07 17:16:50 +00:00
52f13fcac8 Add $defaultTheme
Required for Drupal 9.0.

See https://www.drupal.org/node/3083055.
2020-03-07 17:15:23 +00:00
772d3d31b0
Update node.type.article.yml 2019-03-02 11:13:16 +00:00
ccaa426a38 Change to tdd_blog 2018-09-07 18:33:14 +01:00
Oliver Davies
5be880e496
Create composer.json 2018-06-14 09:52:58 +01:00
Oliver Davies
dccc8f1875 Add node types explicitly 2018-04-20 00:10:28 +01:00
Oliver Davies
f8a864b6cc Use the NodeCreationTrait, remove validParams 2018-04-19 23:46:19 +01:00
Oliver Davies
41bcbb50ab
Update README.md 2018-04-19 23:29:38 +01:00
Oliver Davies
442ec19bc1 Use EntityKernelTestBase 2018-04-19 14:18:10 +01:00
Oliver Davies
4ec57cdf2e Add installation instructions 2018-04-03 08:46:46 +01:00
Oliver Davies
38314a0ed2 Use array_map 2018-04-02 21:29:19 +01:00
Oliver Davies
238dd8fb68 Rename method 2018-03-20 19:26:28 +00:00
Oliver Davies
4238580d66 Remove extra lines 2018-03-20 18:58:02 +00:00
Oliver Davies
349ec8f965 Add tdd_dublin_test sub-module 2018-03-20 18:58:02 +00:00
81cb121a99 Change tests to kernel tests
Fixes 
2017-11-21 10:06:09 +00:00
ab524316b6 Rename file 2017-11-21 00:51:00 +00:00
eb5465c5a6 Update README 2017-11-07 01:10:11 +00:00
af09babd7a Add comments 2017-10-30 10:44:40 +00:00
5574c5ee9a Update README 2017-10-30 10:44:36 +00:00
5ead634ab2 Add dependencies section 2017-10-30 10:44:27 +00:00
66389b7a21 Update README 2017-10-30 10:44:17 +00:00
81af444a97 Update sort criteria
Remove the default "Authored on" sort criteria and replace it
with a "Content: Title" sort to order the items alphabetically.
2017-10-30 10:44:16 +00:00
461e66bf53 Assert expected node order 2017-10-30 10:44:16 +00:00
992390b803 Retrieve the data from the view 2017-10-30 10:44:16 +00:00
fc8eb51bdf 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.
2017-10-30 10:44:16 +00:00
569d4a80dc Add results order test 2017-10-30 10:44:16 +00:00
f6d572211f Add type condition to the view 2017-10-30 10:44:16 +00:00
744556a681 Compare the expected nids with the view result 2017-10-30 10:44:16 +00:00
88a0399f39 Get the result of the view 2017-10-30 10:44:15 +00:00
a104767e10 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.
2017-10-30 10:44:15 +00:00
f713d225bf Add correct nodes test 2017-10-30 10:44:15 +00:00
9 changed files with 212 additions and 56 deletions

1
.gitignore vendored Normal file
View file

@ -0,0 +1 @@
composer.lock

View file

@ -1,16 +1,31 @@
# TDD Dublin demo module
# 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
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
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
Within your Drupal 8 site:
```bash
cd modules
git clone git@github.com:opdavies/drupal-module-tdd-blog.git tdd_blog
```
## Running the Tests
@ -18,23 +33,23 @@ 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.
named `tdd_blog` as per the repository name.
```
cd core
../vendor/bin/phpunit ../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 ../modules/custom/tdd_dublin --filter=testOnlyPublishedPagesAreShown
vendor/bin/phpunit -c core modules/custom/tdd_blog --filter=testOnlyPublishedPagesAreShown
```
[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

4
composer.json Normal file
View file

@ -0,0 +1,4 @@
{
"name": "drupal/tdd_blog",
"type": "drupal-custom-module"
}

View file

@ -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

View file

@ -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

View file

@ -1,11 +1,13 @@
langcode: en
status: true
dependencies:
config:
- node.type.article
module:
- node
- user
id: pages
label: pages
- node
- user
id: blog
label: Blog
module: views
description: ''
tag: ''
@ -136,22 +138,62 @@ display:
expose:
operator: ''
group: 1
type:
id: type
table: node_field_data
field: type
relationship: none
group_type: group
admin_label: ''
operator: in
value:
article: article
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
table: node_field_data
field: created
order: DESC
entity_type: node
entity_field: created
plugin_id: date
relationship: none
group_type: group
admin_label: ''
order: ASC
exposed: false
expose:
label: ''
granularity: second
entity_type: node
entity_field: created
plugin_id: date
header: { }
footer: { }
empty: { }
@ -161,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
@ -174,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: { }

View file

@ -1,6 +1,7 @@
name: 'TDD Dublin'
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:

View file

@ -1,24 +1,20 @@
<?php
namespace Drupal\Tests\tdd_dublin\Functional;
namespace Drupal\Tests\tdd_blog\Functional;
use Drupal\Tests\BrowserTestBase;
use Symfony\Component\HttpFoundation\Response;
class PageListTest extends BrowserTestBase {
/**
* {@inheritdoc}
*/
protected static $modules = ['tdd_dublin'];
protected static $modules = ['tdd_blog'];
/**
* 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);
protected $defaultTheme = 'stark';
public function testBlogPageExists() {
$this->drupalGet('blog');
$this->assertSession()->statusCodeEquals(Response::HTTP_OK);
}
}

View file

@ -0,0 +1,99 @@
<?php
namespace Drupal\Tests\tdd_blog\Kernel;
use Drupal\Core\Datetime\DrupalDateTime;
use Drupal\KernelTests\Core\Entity\EntityKernelTestBase;
use Drupal\Tests\node\Traits\NodeCreationTrait;
use Drupal\views\ResultRow;
/**
* @group tdd_blog
*/
class PageListTest extends EntityKernelTestBase {
use NodeCreationTrait;
/**
* {@inheritdoc}
*/
public static $modules = [
'node',
'tdd_blog',
'views',
];
/**
* {@inheritdoc}
*/
protected function setUp() {
parent::setUp();
$this->installEntitySchema('node');
$this->installEntitySchema('user');
$this->installConfig(['filter', 'tdd_blog']);
}
/**
* 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 testOnlyPublishedArticlesAreShown() {
// This is a published article, so it should be visible.
$this->createNode(['type' => 'page', 'status' => TRUE]);
// This is a page, so it should not be visible.
$this->createNode(['type' => 'article']);
// 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 = $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([2], $nids);
}
/**
* Ensure that the results are ordered by title.
*/
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 = $this->getViewResults();
// Compare the expected order based on the titles defined above to the
// ordered results from the view.
$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));
}
}