Commit ff8fa899 authored by webchick's avatar webchick
Browse files

Issue #2053519 by dawehner, mondrake | RdeBoer: Fixed AJAX fails on View with 'AJAX: Yes'.

parent 89b5fea7
......@@ -17,6 +17,7 @@
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
/**
* Defines a controller to load a view via AJAX.
......@@ -94,12 +95,12 @@ public function ajaxView(Request $request) {
}
// Load the view.
$result = $this->storageController->load(array($name));
if (!$entity = reset($result)) {
if (!$entity = $this->storageController->load($name)) {
throw new NotFoundHttpException();
}
$view = $this->executableFactory->get($entity);
if ($view && $view->access($display_id)) {
$response->setView($view);
// Fix the current path for paging.
if (!empty($path)) {
$request->attributes->set('_system_path', $path);
......@@ -131,8 +132,11 @@ public function ajaxView(Request $request) {
$preview = $view->preview($display_id, $args);
$response->addCommand(new ReplaceCommand(".view-dom-id-$dom_id", drupal_render($preview)));
return $response;
}
else {
throw new AccessDeniedHttpException();
}
return $response;
}
else {
throw new NotFoundHttpException();
......
<?php
/**
* @file
* Contains \Drupal\views\Tests\ViewAjaxTest.
*/
namespace Drupal\views\Tests;
use Drupal\Component\Utility\Json;
/**
* Tests the ajax view functionality.
*/
class ViewAjaxTest extends ViewTestBase {
/**
* Views used by this test.
*
* @var array
*/
public static $testViews = array('test_ajax_view');
public static function getInfo() {
return array(
'name' => 'View: Ajax',
'description' => 'Tests the ajax view functionality.',
'group' => 'Views'
);
}
protected function setUp() {
parent::setUp();
$this->enableViewsTestModule();
}
/**
* Tests an ajax view.
*/
public function testAjaxView() {
$this->drupalGet('test_ajax_view');
$data = array();
$data['view_name'] = 'test_ajax_view';
$data['view_display_id'] = 'test_ajax_view';
$post = 'view_name=test_ajax_view&view_display_id=page_1';
$response = $this->curlExec(array(
CURLOPT_URL => url('views/ajax', array('absolute' => TRUE)),
CURLOPT_POST => TRUE,
CURLOPT_POSTFIELDS => $post,
CURLOPT_HTTPHEADER => array(
'Accept: application/json',
'Content-Type: application/x-www-form-urlencoded',
),
));
$data = Json::decode($response);
// Ensure that the view insert command is part of the result.
$this->assertEqual($data[1]['command'], 'insert');
$this->assertTrue(strpos($data[1]['selector'], '.view-dom-id-') === 0);
$this->drupalSetContent($data[1]['data']);
$result = $this->xpath('//div[contains(@class, "views-row")]');
$this->assertEqual(count($result), 2, 'Ensure that two items are renderd in the HTML.');
}
}
<?php
/**
* @file
* Contains \Drupal\views\Tests\Controller\ViewAjaxControllerTest.
*/
namespace Drupal\views\Tests\Controller {
use Drupal\Tests\UnitTestCase;
use Drupal\views\Ajax\ViewAjaxResponse;
use Drupal\views\Controller\ViewAjaxController;
use Symfony\Component\HttpFoundation\Request;
/**
* Tests the views ajax controller.
*
* @group Drupal
* @group Views
*
* @see \Drupal\views\Controller\ViewAjaxController
*/
class ViewAjaxControllerTest extends UnitTestCase {
/**
* The mocked view entity storage.
*
* @var \Drupal\Core\Entity\EntityStorageControllerInterface|\PHPUnit_Framework_MockObject_MockObject
*/
protected $viewStorage;
/**
* The mocked executable factory.
*
* @var \Drupal\views\ViewExecutableFactory|\PHPUnit_Framework_MockObject_MockObject
*/
protected $executableFactory;
/**
* The tested views ajax controller.
*
* @var \Drupal\views\Controller\ViewAjaxController
*/
protected $viewAjaxController;
public static function getInfo() {
return array(
'name' => 'View: Ajax controller',
'description' => 'Tests the views ajax controller.',
'group' => 'Views'
);
}
protected function setUp() {
$this->viewStorage = $this->getMock('Drupal\Core\Entity\EntityStorageControllerInterface');
$this->executableFactory = $this->getMockBuilder('Drupal\views\ViewExecutableFactory')
->disableOriginalConstructor()
->getMock();
$this->viewAjaxController = new ViewAjaxController($this->viewStorage, $this->executableFactory);
}
/**
* Tests missing view_name and view_display_id
*
* @expectedException \Symfony\Component\HttpKernel\Exception\NotFoundHttpException
*/
public function testMissingViewName() {
$request = new Request();
$this->viewAjaxController->ajaxView($request);
}
/**
* Tests with view_name and view_display_id but not existing view.
*
* @expectedException \Symfony\Component\HttpKernel\Exception\NotFoundHttpException
*/
public function testMissingView() {
$request = new Request();
$request->request->set('view_name', 'test_view');
$request->request->set('view_display_id', 'page_1');
$this->viewStorage->expects($this->once())
->method('load')
->with('test_view')
->will($this->returnValue(FALSE));
$this->viewAjaxController->ajaxView($request);
}
/**
* Tests a view without having access to it.
*
* @expectedException \Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException
*/
public function testAccessDeniedView() {
$request = new Request();
$request->request->set('view_name', 'test_view');
$request->request->set('view_display_id', 'page_1');
$view = $this->getMockBuilder('Drupal\views\Entity\View')
->disableOriginalConstructor()
->getMock();
$this->viewStorage->expects($this->once())
->method('load')
->with('test_view')
->will($this->returnValue($view));
$executable = $this->getMockBuilder('Drupal\views\ViewExecutable')
->disableOriginalConstructor()
->getMock();
$executable->expects($this->once())
->method('access')
->will($this->returnValue(FALSE));
$this->executableFactory->staticExpects($this->once())
->method('get')
->with($view)
->will($this->returnValue($executable));
$this->viewAjaxController->ajaxView($request);
}
/**
* Tests a valid view without arguments pagers etc.
*/
public function testAjaxView() {
$request = new Request();
$request->request->set('view_name', 'test_view');
$request->request->set('view_display_id', 'page_1');
list($view, $executable) = $this->setupValidMocks();
$response = $this->viewAjaxController->ajaxView($request);
$this->assertTrue($response instanceof ViewAjaxResponse);
$this->assertSame($response->getView(), $executable);
}
/**
* Sets up a bunch of valid mocks like the view entity and executable.
*/
protected function setupValidMocks() {
$view = $this->getMockBuilder('Drupal\views\Entity\View')
->disableOriginalConstructor()
->getMock();
$this->viewStorage->expects($this->once())
->method('load')
->with('test_view')
->will($this->returnValue($view));
$executable = $this->getMockBuilder('Drupal\views\ViewExecutable')
->disableOriginalConstructor()
->getMock();
$executable->expects($this->once())
->method('access')
->will($this->returnValue(TRUE));
$executable->expects($this->once())
->method('preview')
->will($this->returnValue(array('#markup' => 'View result')));
$this->executableFactory->staticExpects($this->once())
->method('get')
->with($view)
->will($this->returnValue($executable));
return array($view, $executable);
}
}
}
namespace {
// @todo Remove once drupal_get_destination is converted to autoloadable code.
if (!function_exists('drupal_static')) {
function drupal_static($key) {
return $key;
}
}
// @todo Remove once drupal_render is converted to autoloadable code.
if (!function_exists('drupal_render')) {
function drupal_render($array) {
return isset($array['#markup']) ? $array['#markup'] : (string) $array;
}
}
}
base_table: views_test_data
core: '8'
description: ''
status: '1'
display:
default:
display_options:
defaults:
fields: '0'
pager: '0'
pager_options: '0'
sorts: '0'
fields:
age:
field: age
id: age
relationship: none
table: views_test_data
plugin_id: numeric
provider: views_test_data
id:
field: id
id: id
relationship: none
table: views_test_data
plugin_id: numeric
provider: views_test_data
name:
field: name
id: name
relationship: none
table: views_test_data
plugin_id: string
provider: views_test_data
pager:
options:
offset: '0'
items_per_page: 2
type: mini
pager_options: { }
sorts:
id:
field: id
id: id
order: ASC
relationship: none
table: views_test_data
plugin_id: numeric
provider: views_test_data
use_ajax: 1
display_plugin: default
display_title: Master
id: default
position: '0'
page_1:
display_options:
path: test_ajax_view
display_plugin: page
display_title: Page
id: page_1
position: '1'
label: 'Test ajax view'
id: test_ajax_view
tag: ''
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment