Drupal 8.0.0 beta 12. More info: https://www.drupal.org/node/2514176

This commit is contained in:
Pantheon Automation 2015-08-17 17:00:26 -07:00 committed by Greg Anderson
commit 9921556621
13277 changed files with 1459781 additions and 0 deletions

View file

@ -0,0 +1,6 @@
name: 'Aggregator module tests'
type: module
description: 'Support module for aggregator related testing.'
package: Testing
version: VERSION
core: 8.x

View file

@ -0,0 +1,17 @@
aggregator_test.feed:
path: '/aggregator/test-feed/{use_last_modified}/{use_etag}'
defaults:
_controller: '\Drupal\aggregator_test\Controller\AggregatorTestRssController::testFeed'
_title: 'Test feed static last modified date'
use_last_modified: FALSE
use_etag: FALSE
requirements:
_access: 'TRUE'
aggregator_test.redirect:
path: '/aggregator/redirect'
defaults:
_controller: '\Drupal\aggregator_test\Controller\AggregatorTestRssController::testRedirect'
_title: 'Test feed with a redirect'
requirements:
_access: 'TRUE'

View file

@ -0,0 +1,20 @@
<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
<title>Example Feed</title>
<link href="http://example.org/" />
<updated>2003-12-13T18:30:02Z</updated>
<author>
<name>John Doe</name>
</author>
<id>urn:uuid:60a76c80-d399-11d9-b93C-0003939e0af6</id>
<entry>
<title>Atom-Powered Robots Run Amok</title>
<link href="http://example.org/2003/12/13/atom03" />
<id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a</id>
<updated>2003-12-13T18:30:02Z</updated>
<summary>Some text.</summary>
</entry>
</feed>

View file

@ -0,0 +1,62 @@
<?xml version="1.0" encoding="UTF-8"?>
<rss version="0.91">
<channel>
<title>Example</title>
<link>http://example.com</link>
<description>Example updates</description>
<language>en-us</language>
<copyright>Copyright 2000, Example team.</copyright>
<managingEditor>editor@example.com</managingEditor>
<webMaster>webmaster@example.com</webMaster>
<image>
<title>Example</title>
<url>http://example.com/images/druplicon.png</url>
<link>http://example.com</link>
<width>88</width>
<height>100</height>
<description>Example updates</description>
</image>
<item>
<title>First example feed item title</title>
<link>http://example.com/example-turns-one</link>
<description>First example feed item description.</description>
</item>
<item>
<title>Second example feed item title. This title is extremely long so that it exceeds the 255 character limit for titles in feed item storage. In fact it's so long that this sentence isn't long enough so I'm rambling a bit to make it longer, nearly there now. Ah now it's long enough so I'll shut up.</title>
<link>http://example.com/example-turns-two</link>
<description>Second example feed item description.</description>
</item>
<item>
<title>Long link feed item title.</title>
<link>http://example.com/tomorrow/and/tomorrow/and/tomorrow/creeps/in/this/petty/pace/from/day/to/day/to/the/last/syllable/of/recorded/time/and/all/our/yesterdays/have/lighted/fools/the/way/to/dusty/death/out/out/brief/candle/life/is/but/a/walking/shadow/a/poor/player/that/struts/and/frets/his/hour/upon/the/stage/and/is/heard/no/more/it/is/a/tale/told/by/an/idiot/full/of/sound/and/fury/signifying/nothing</link>
<description>Long link feed item description.</description>
</item>
<item>
<title>Long author feed item title.</title>
<link>http://example.com/long/author</link>
<author>I wanted to get out and walk eastward toward the park through the soft twilight, but each time I tried to go I became entangled in some wild, strident argument which pulled me back, as if with ropes, into my chair. Yet high over the city our line of yellow windows must have contributed their share of human secrecy to the casual watcher in the darkening streets, and I was him too, looking up and wondering. I was within and without, simultaneously enchanted and repelled by the inexhaustible variety of life.</author>
<description>Long author feed item description.</description>
</item>
<item>
<title></title>
<link>http://example.com/empty/title</link>
<description>This is an item with an empty title.</description>
</item>
<item>
<title>Empty description feed item title.</title>
<link>http://example.com/empty/description</link>
<description></description>
</item>
<item>
<title>Empty link feed item title.</title>
<link></link>
<description>This is an item with an empty link.</description>
</item>
<item>
<title>Empty author feed item title.</title>
<link>http://example.com/empty/author</link>
<author></author>
<description>We've tested items with no author, but what about an empty author tag?</description>
</item>
</channel>
</rss>

View file

@ -0,0 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?>
<rss version="0.91">
<channel>
<title>Example with Entities</title>
<link>http://example.com</link>
<description>Example RSS Feed With HTML Entities in Title</description>
<language>en-us</language>
<item>
<title>Quote&quot; Amp&amp;</title>
<link>http://example.com/example-turns-one</link>
<description>Some text.</description>
</item>
</channel>
</rss>

View file

@ -0,0 +1,2 @@
items:
dummy_length: 5

View file

@ -0,0 +1,13 @@
# Schema for the configuration files of the Aggregator Test module.
aggregator_test.settings:
type: config_object
label: 'Aggregator test settings'
mapping:
items:
type: mapping
label: 'Items'
mapping:
dummy_length:
type: integer
label: 'Dummy length'

View file

@ -0,0 +1,81 @@
<?php
/**
* @file
* Contains \Drupal\aggregator_test\Controller\AggregatorTestRssController.
*/
namespace Drupal\aggregator_test\Controller;
use Drupal\Component\Datetime\DateTimePlus;
use Drupal\Core\Controller\ControllerBase;
use Drupal\Component\Utility\Crypt;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\Request;
/**
* Controller for the aggregator_test module.
*/
class AggregatorTestRssController extends ControllerBase {
/**
* Generates a test feed and simulates last-modified and etags.
*
* @param bool $use_last_modified
* Set TRUE to send a last modified header.
* @param bool $use_etag
* Set TRUE to send an etag.
* @param \Symfony\Component\HttpFoundation\Request $request
* Information about the current HTTP request.
*
* @return \Symfony\Component\HttpFoundation\Response
* A feed that forces cache validation.
*/
public function testFeed($use_last_modified, $use_etag, Request $request) {
$response = new Response();
$last_modified = strtotime('Sun, 19 Nov 1978 05:00:00 GMT');
$etag = Crypt::hashBase64($last_modified);
$if_modified_since = strtotime($request->server->get('HTTP_IF_MODIFIED_SINCE'));
$if_none_match = stripslashes($request->server->get('HTTP_IF_NONE_MATCH'));
// Send appropriate response. We respond with a 304 not modified on either
// etag or on last modified.
if ($use_last_modified) {
$response->headers->set('Last-Modified', gmdate(DateTimePlus::RFC7231, $last_modified));
}
if ($use_etag) {
$response->headers->set('ETag', $etag);
}
// Return 304 not modified if either last modified or etag match.
if ($last_modified == $if_modified_since || $etag == $if_none_match) {
$response->setStatusCode(304);
return $response;
}
// The following headers force validation of cache.
$response->headers->set('Expires', 'Sun, 19 Nov 1978 05:00:00 GMT');
$response->headers->set('Cache-Control', 'must-revalidate');
$response->headers->set('Content-Type', 'application/rss+xml; charset=utf-8');
// Read actual feed from file.
$file_name = drupal_get_path('module', 'aggregator_test') . '/aggregator_test_rss091.xml';
$handle = fopen($file_name, 'r');
$feed = fread($handle, filesize($file_name));
fclose($handle);
$response->setContent($feed);
return $response;
}
/**
* Generates a rest redirect to the test feed.
*
* @return \Symfony\Component\HttpFoundation\RedirectResponse
* A response that redirects users to the test feed.
*/
public function testRedirect() {
return $this->redirect('aggregator_test.feed', [], [], 301);
}
}

View file

@ -0,0 +1,36 @@
<?php
/**
* @file
* Contains \Drupal\aggregator_test\Plugin\aggregator\fetcher\TestFetcher.
*/
namespace Drupal\aggregator_test\Plugin\aggregator\fetcher;
use Drupal\aggregator\Plugin\FetcherInterface;
use Drupal\aggregator\Plugin\aggregator\fetcher\DefaultFetcher;
use Drupal\aggregator\FeedInterface;
/**
* Defines a test fetcher implementation.
*
* Uses http_client class to download the feed.
*
* @AggregatorFetcher(
* id = "aggregator_test_fetcher",
* title = @Translation("Test fetcher"),
* description = @Translation("Dummy fetcher for testing purposes.")
* )
*/
class TestFetcher extends DefaultFetcher implements FetcherInterface {
/**
* Implements \Drupal\aggregator\Plugin\FetcherInterface::fetch().
*/
public function fetch(FeedInterface $feed) {
if ($feed->label() == 'Do not fetch') {
return FALSE;
}
return parent::fetch($feed);
}
}

View file

@ -0,0 +1,35 @@
<?php
/**
* @file
* Contains \Drupal\aggregator_test\Plugin\aggregator\parser\TestParser.
*/
namespace Drupal\aggregator_test\Plugin\aggregator\parser;
use Drupal\aggregator\Plugin\ParserInterface;
use Drupal\aggregator\FeedInterface;
use Drupal\aggregator\Plugin\aggregator\parser\DefaultParser;
/**
* Defines a Test parser implementation.
*
* Parses RSS, Atom and RDF feeds.
*
* @AggregatorParser(
* id = "aggregator_test_parser",
* title = @Translation("Test parser"),
* description = @Translation("Dummy parser for testing purposes.")
* )
*/
class TestParser extends DefaultParser implements ParserInterface {
/**
* Implements \Drupal\aggregator\Plugin\ParserInterface::parse().
*
* @todo Actually test this.
*/
public function parse(FeedInterface $feed) {
return parent::parse($feed);
}
}

View file

@ -0,0 +1,153 @@
<?php
/**
* @file
* Contains \Drupal\aggregator_test\Plugin\aggregator\processor\TestProcessor.
*/
namespace Drupal\aggregator_test\Plugin\aggregator\processor;
use Drupal\aggregator\Plugin\AggregatorPluginSettingsBase;
use Drupal\aggregator\Plugin\ProcessorInterface;
use Drupal\aggregator\FeedInterface;
use Drupal\Core\Config\ConfigFactoryInterface;
use Drupal\Core\Form\ConfigFormBaseTrait;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
/**
* Defines a default processor implementation.
*
* Creates lightweight records from feed items.
*
* @AggregatorProcessor(
* id = "aggregator_test_processor",
* title = @Translation("Test processor"),
* description = @Translation("Test generic processor functionality.")
* )
*/
class TestProcessor extends AggregatorPluginSettingsBase implements ProcessorInterface, ContainerFactoryPluginInterface {
use ConfigFormBaseTrait;
/**
* Contains the configuration object factory.
*
* @var \Drupal\Core\Config\ConfigFactoryInterface
*/
protected $configFactory;
/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
return new static(
$configuration,
$plugin_id,
$plugin_definition,
$container->get('config.factory')
);
}
/**
* Constructs a TestProcessor object.
*
* @param array $configuration
* A configuration array containing information about the plugin instance.
* @param string $plugin_id
* The plugin_id for the plugin instance.
* @param mixed $plugin_definition
* The plugin implementation definition.
* @param \Drupal\Core\Config\ConfigFactoryInterface $config
* The configuration factory object.
*/
public function __construct(array $configuration, $plugin_id, $plugin_definition, ConfigFactoryInterface $config) {
$this->configFactory = $config;
parent::__construct($configuration + $this->getConfiguration(), $plugin_id, $plugin_definition);
}
/**
* {@inheritdoc}
*/
protected function getEditableConfigNames() {
return ['aggregator_test.settings'];
}
/**
* {@inheritdoc}
*/
public function buildConfigurationForm(array $form, FormStateInterface $form_state) {
$processors = $this->config('aggregator.settings')->get('processors');
$info = $this->getPluginDefinition();
$form['processors'][$info['id']] = array(
'#type' => 'details',
'#title' => t('Test processor settings'),
'#description' => $info['description'],
'#open' => in_array($info['id'], $processors),
);
// Add some dummy settings to verify settingsForm is called.
$form['processors'][$info['id']]['dummy_length'] = array(
'#title' => t('Dummy length setting'),
'#type' => 'number',
'#min' => 1,
'#max' => 1000,
'#default_value' => $this->configuration['items']['dummy_length'],
);
return $form;
}
/**
* {@inheritdoc}
*/
public function submitConfigurationForm(array &$form, FormStateInterface $form_state) {
$this->configuration['items']['dummy_length'] = $form_state->getValue('dummy_length');
$this->setConfiguration($this->configuration);
}
/**
* {@inheritdoc}
*/
public function process(FeedInterface $feed) {
foreach ($feed->items as &$item) {
// Prepend our test string.
$item['title'] = 'testProcessor' . $item['title'];
}
}
/**
* {@inheritdoc}
*/
public function delete(FeedInterface $feed) {
// Append a random number, just to change the feed description.
$feed->description->value .= rand(0, 10);
}
/**
* {@inheritdoc}
*/
public function postProcess(FeedInterface $feed) {
// Double the refresh rate.
$feed->refresh->value *= 2;
$feed->save();
}
/**
* {@inheritdoc}
*/
public function getConfiguration() {
return $this->configFactory->get('aggregator_test.settings')->get();
}
/**
* {@inheritdoc}
*/
public function setConfiguration(array $configuration) {
$config = $this->config('aggregator_test.settings');
foreach ($configuration as $key => $value) {
$config->set($key, $value);
}
$config->save();
}
}

View file

@ -0,0 +1,9 @@
name: 'Aggregator test views'
type: module
description: 'Provides default views for views aggregator tests.'
package: Testing
version: VERSION
core: 8.x
dependencies:
- aggregator
- views

View file

@ -0,0 +1,190 @@
langcode: en
status: true
dependencies:
module:
- aggregator
id: test_aggregator_items
label: test_aggregator_items
module: views
description: ''
tag: ''
base_table: aggregator_item
base_field: iid
core: 8.x
display:
default:
display_plugin: default
id: default
display_title: Master
position: null
display_options:
access:
type: none
cache:
type: tag
query:
type: views_query
exposed_form:
type: basic
pager:
type: full
style:
type: default
row:
type: fields
fields:
iid:
table: aggregator_item
field: iid
id: iid
plugin_id: field
entity_type: aggregator_item
entity_field: iid
title:
table: aggregator_item
field: title
id: title
plugin_id: field
type: aggregator_title
alter:
alter_text: false
text: ''
make_link: false
path: ''
absolute: false
external: false
replace_spaces: false
path_case: none
trim_whitespace: false
alt: ''
rel: ''
link_class: ''
prefix: ''
suffix: ''
target: ''
nl2br: false
max_length: 0
word_boundary: true
ellipsis: true
more_link: false
more_link_text: ''
more_link_path: ''
strip_tags: false
trim: false
preserve_tags: ''
html: false
entity_type: aggregator_item
entity_field: title
timestamp:
table: aggregator_item
field: timestamp
id: timestamp
plugin_id: date
entity_type: aggregator_item
entity_field: timestamp
author:
table: aggregator_item
field: author
id: author
plugin_id: field
alter:
alter_text: false
text: ''
make_link: false
path: ''
absolute: false
external: false
replace_spaces: false
path_case: none
trim_whitespace: false
alt: ''
rel: ''
link_class: ''
prefix: ''
suffix: ''
target: ''
nl2br: false
max_length: 0
word_boundary: true
ellipsis: true
more_link: false
more_link_text: ''
more_link_path: ''
strip_tags: false
trim: false
preserve_tags: ''
html: false
entity_type: aggregator_item
entity_field: author
description:
id: description
table: aggregator_item
field: description
relationship: none
group_type: group
admin_label: ''
label: Body
exclude: false
alter:
alter_text: false
text: ''
make_link: false
path: ''
absolute: false
external: false
replace_spaces: false
path_case: none
trim_whitespace: false
alt: ''
rel: ''
link_class: ''
prefix: ''
suffix: ''
target: ''
nl2br: false
max_length: 0
word_boundary: true
ellipsis: true
more_link: false
more_link_text: ''
more_link_path: ''
strip_tags: false
trim: false
preserve_tags: ''
html: false
element_type: ''
element_class: ''
element_label_type: ''
element_label_class: ''
element_label_colon: true
element_wrapper_type: ''
element_wrapper_class: ''
element_default_classes: true
empty: ''
hide_empty: false
empty_zero: false
hide_alter_empty: true
plugin_id: field
entity_type: aggregator_item
entity_field: description
filters: { }
sorts:
iid:
id: iid
table: aggregator_item
field: iid
plugin_id: standard
entity_type: aggregator_item
entity_field: iid
order: 'ASC'
feed_1:
display_plugin: feed
id: feed_1
display_title: Feed
position: null
display_options:
path: test-aggregator-items-feed
row:
type: aggregator_rss
options:
view_mode: default

View file

@ -0,0 +1,70 @@
<?php
/**
* @file
* Contains \Drupal\Tests\aggregator\Unit\Menu\AggregatorLocalTasksTest.
*/
namespace Drupal\Tests\aggregator\Unit\Menu;
use Drupal\Tests\Core\Menu\LocalTaskIntegrationTestBase;
/**
* Tests existence of aggregator local tasks.
*
* @group aggregator
*/
class AggregatorLocalTasksTest extends LocalTaskIntegrationTestBase {
/**
* {@inheritdoc}
*/
protected function setUp() {
$this->directoryList = array('aggregator' => 'core/modules/aggregator');
parent::setUp();
}
/**
* Tests local task existence.
*
* @dataProvider getAggregatorAdminRoutes
*/
public function testAggregatorAdminLocalTasks($route) {
$this->assertLocalTasks($route, array(
0 => array('aggregator.admin_overview', 'aggregator.admin_settings'),
));
}
/**
* Provides a list of routes to test.
*/
public function getAggregatorAdminRoutes() {
return array(
array('aggregator.admin_overview'),
array('aggregator.admin_settings'),
);
}
/**
* Checks aggregator source tasks.
*
* @dataProvider getAggregatorSourceRoutes
*/
public function testAggregatorSourceLocalTasks($route) {
$this->assertLocalTasks($route, array(
0 => array('entity.aggregator_feed.canonical', 'entity.aggregator_feed.edit_form', 'entity.aggregator_feed.delete_form'),
));
;
}
/**
* Provides a list of source routes to test.
*/
public function getAggregatorSourceRoutes() {
return array(
array('entity.aggregator_feed.canonical'),
array('entity.aggregator_feed.edit_form'),
);
}
}

View file

@ -0,0 +1,120 @@
<?php
/**
* @file
* Contains \Drupal\Tests\aggregator\Unit\Plugin\AggregatorPluginSettingsBaseTest.
*/
namespace Drupal\Tests\aggregator\Unit\Plugin {
use Drupal\aggregator\Form\SettingsForm;
use Drupal\Core\Form\FormState;
use Drupal\Tests\UnitTestCase;
/**
* Tests settings configuration of individual aggregator plugins.
*
* @group aggregator
*/
class AggregatorPluginSettingsBaseTest extends UnitTestCase {
/**
* The aggregator settings form object under test.
*
* @var \Drupal\aggregator\Form\SettingsForm
*/
protected $settingsForm;
/**
* The stubbed config factory object.
*
* @var \PHPUnit_Framework_MockObject_MockBuilder
*/
protected $configFactory;
/**
* The stubbed aggregator plugin managers array.
*
* @var array
*/
protected $managers;
/**
* {@inheritdoc}
*/
protected function setUp() {
$this->configFactory = $this->getConfigFactoryStub(
array(
'aggregator.settings' => array(
'processors' => array('aggregator_test'),
),
'aggregator_test.settings' => array(),
)
);
foreach (array('fetcher', 'parser', 'processor') as $type) {
$this->managers[$type] = $this->getMockBuilder('Drupal\aggregator\Plugin\AggregatorPluginManager')
->disableOriginalConstructor()
->getMock();
$this->managers[$type]->expects($this->once())
->method('getDefinitions')
->will($this->returnValue(array('aggregator_test' => array('title' => '', 'description' => ''))));
}
$this->settingsForm = new SettingsForm(
$this->configFactory,
$this->managers['fetcher'],
$this->managers['parser'],
$this->managers['processor'],
$this->getStringTranslationStub()
);
}
/**
* Test for AggregatorPluginSettingsBase.
*
* Ensure that the settings form calls build, validate and submit methods on
* plugins that extend AggregatorPluginSettingsBase.
*/
public function testSettingsForm() {
// Emulate a form state of a submitted form.
$form_state = (new FormState())->setValues([
'dummy_length' => '',
'aggregator_allowed_html_tags' => '',
]);
$test_processor = $this->getMock(
'Drupal\aggregator_test\Plugin\aggregator\processor\TestProcessor',
array('buildConfigurationForm', 'validateConfigurationForm', 'submitConfigurationForm'),
array(array(), 'aggregator_test', array('description' => ''), $this->configFactory)
);
$test_processor->expects($this->at(0))
->method('buildConfigurationForm')
->with($this->anything(), $form_state)
->will($this->returnArgument(0));
$test_processor->expects($this->at(1))
->method('validateConfigurationForm')
->with($this->anything(), $form_state);
$test_processor->expects($this->at(2))
->method('submitConfigurationForm')
->with($this->anything(), $form_state);
$this->managers['processor']->expects($this->once())
->method('createInstance')
->with($this->equalTo('aggregator_test'))
->will($this->returnValue($test_processor));
$form = $this->settingsForm->buildForm(array(), $form_state);
$this->settingsForm->validateForm($form, $form_state);
$this->settingsForm->submitForm($form, $form_state);
}
}
}
namespace {
// @todo Delete after https://www.drupal.org/node/1858196 is in.
if (!function_exists('drupal_set_message')) {
function drupal_set_message() {}
}
}