Loading src/Controller/ProjectBrowserEndpointController.php +6 −7 Original line number Diff line number Diff line Loading @@ -3,7 +3,6 @@ namespace Drupal\project_browser\Controller; use Drupal\Component\Serialization\Json; use Drupal\Component\Utility\Xss; use Drupal\Core\Cache\CacheableResponseInterface; use Drupal\Core\Controller\ControllerBase; use Drupal\project_browser\EnabledSourceHandler; Loading Loading @@ -117,27 +116,27 @@ class ProjectBrowserEndpointController extends ControllerBase { $title = $request->query->get('search'); if ($title) { $query['search'] = Xss::filter($title); $query['search'] = $title; } $categories = $request->query->get('categories'); if ($categories) { $query['categories'] = Xss::filter($categories); $query['categories'] = $categories; } $maintenance_status = $request->query->get('maintenance_status'); if ($maintenance_status) { $query['maintenance_status'] = Xss::filter($maintenance_status); $query['maintenance_status'] = $maintenance_status; } $development_status = $request->query->get('development_status'); if ($development_status) { $query['development_status'] = Xss::filter($development_status); $query['development_status'] = $development_status; } $security_advisory_coverage = $request->query->get('security_advisory_coverage'); if ($security_advisory_coverage) { $query['security_advisory_coverage'] = Xss::filter($security_advisory_coverage); $query['security_advisory_coverage'] = $security_advisory_coverage; } // Cache only exact query, down to the page number. Loading Loading @@ -167,7 +166,7 @@ class ProjectBrowserEndpointController extends ControllerBase { return new JsonResponse([], Response::HTTP_ACCEPTED); } $project = Xss::filter($request->query->get('project')); $project = $request->query->get('project'); if ($project) { $cache_key = 'project_browser:releases:' . $project; if ($releases = $this->cacheBin->get($cache_key)) { Loading tests/fixtures/projects_fixture.json +2 −2 Original line number Diff line number Diff line Loading @@ -1096,7 +1096,7 @@ } }, { "title": "Unwritten", "title": "Unwritten&:/", "author": "Natasha Bedingfield", "maintenance_status": "19370", "development_status": "9994", Loading Loading @@ -1139,7 +1139,7 @@ } }, { "title": "Vitamin C", "title": "Vitamin&C;$?", "author": "Orange Juice", "maintenance_status": "19370", "development_status": "9994", Loading tests/src/FunctionalJavascript/ProjectBrowserUiTest.php +63 −6 Original line number Diff line number Diff line Loading @@ -124,7 +124,7 @@ class ProjectBrowserUiTest extends WebDriverTestBase { 'Jazz', 'Eggman', 'Tooth Fairy', 'Vitamin C', 'Vitamin&C;$?', 'Cream cheese on a bagel', 'No Scrubs', 'Soup', Loading Loading @@ -254,12 +254,12 @@ class ProjectBrowserUiTest extends WebDriverTestBase { $this->assertEquals('Obsolete', $second_filter_element->getText()); $this->assertProjectsVisible([ 'Tooth Fairy', 'Vitamin C', 'Vitamin&C;$?', 'Pinky and the Brain', 'Soup', 'Quiznos', 'Ruh roh', 'Unwritten', 'Unwritten&:/', ]); // Click the Unsupported filter. Loading Loading @@ -336,8 +336,8 @@ class ProjectBrowserUiTest extends WebDriverTestBase { $this->click('.grid--2 .dropdown > button'); $this->click('.dropdown-content #pb-sort > li:nth-child(3)'); $this->assertProjectsVisible([ 'Vitamin C', 'Unwritten', 'Vitamin&C;$?', 'Unwritten&:/', 'Tooth Fairy', 'Soup', 'Ruh roh', Loading @@ -358,7 +358,7 @@ class ProjectBrowserUiTest extends WebDriverTestBase { 'Jazz', 'Eggman', 'Tooth Fairy', 'Vitamin C', 'Vitamin&C;$?', 'Cream cheese on a bagel', 'Pinky and the Brain', 'Ice Ice', Loading Loading @@ -390,4 +390,61 @@ class ProjectBrowserUiTest extends WebDriverTestBase { ]); } /** * Tests search with strings that need URI encoding. */ public function testSearchForSpecialChar(): void { $assert_session = $this->assertSession(); $page = $this->getSession()->getPage(); // Clear filters. $this->drupalGet('admin/modules/browse'); $page->clickLink('Clear filters'); $search_field = $page->find('css', '#pb-text'); // Fill in the search field. $search_field->setValue('&'); $this->assertProjectsVisible([ 'Vitamin&C;$?', 'Unwritten&:/', ]); // Fill in the search field. $search_field->setValue(''); $search_field->setValue('n&'); $this->assertProjectsVisible([ 'Vitamin&C;$?', 'Unwritten&:/', ]); $search_field->setValue(''); $search_field->setValue('$'); $this->assertProjectsVisible([ 'Vitamin&C;$?', ]); $search_field->setValue(''); $search_field->setValue('?'); $this->assertProjectsVisible([ 'Vitamin&C;$?', ]); $search_field->setValue(''); $search_field->setValue('/'); $this->assertProjectsVisible([ 'Unwritten&:/', ]); $search_field->setValue(''); $search_field->setValue(':'); $this->assertProjectsVisible([ 'Unwritten&:/', ]); $search_field->setValue(''); $search_field->setValue(';'); $this->assertProjectsVisible([ 'Vitamin&C;$?', ]); } } Loading
src/Controller/ProjectBrowserEndpointController.php +6 −7 Original line number Diff line number Diff line Loading @@ -3,7 +3,6 @@ namespace Drupal\project_browser\Controller; use Drupal\Component\Serialization\Json; use Drupal\Component\Utility\Xss; use Drupal\Core\Cache\CacheableResponseInterface; use Drupal\Core\Controller\ControllerBase; use Drupal\project_browser\EnabledSourceHandler; Loading Loading @@ -117,27 +116,27 @@ class ProjectBrowserEndpointController extends ControllerBase { $title = $request->query->get('search'); if ($title) { $query['search'] = Xss::filter($title); $query['search'] = $title; } $categories = $request->query->get('categories'); if ($categories) { $query['categories'] = Xss::filter($categories); $query['categories'] = $categories; } $maintenance_status = $request->query->get('maintenance_status'); if ($maintenance_status) { $query['maintenance_status'] = Xss::filter($maintenance_status); $query['maintenance_status'] = $maintenance_status; } $development_status = $request->query->get('development_status'); if ($development_status) { $query['development_status'] = Xss::filter($development_status); $query['development_status'] = $development_status; } $security_advisory_coverage = $request->query->get('security_advisory_coverage'); if ($security_advisory_coverage) { $query['security_advisory_coverage'] = Xss::filter($security_advisory_coverage); $query['security_advisory_coverage'] = $security_advisory_coverage; } // Cache only exact query, down to the page number. Loading Loading @@ -167,7 +166,7 @@ class ProjectBrowserEndpointController extends ControllerBase { return new JsonResponse([], Response::HTTP_ACCEPTED); } $project = Xss::filter($request->query->get('project')); $project = $request->query->get('project'); if ($project) { $cache_key = 'project_browser:releases:' . $project; if ($releases = $this->cacheBin->get($cache_key)) { Loading
tests/fixtures/projects_fixture.json +2 −2 Original line number Diff line number Diff line Loading @@ -1096,7 +1096,7 @@ } }, { "title": "Unwritten", "title": "Unwritten&:/", "author": "Natasha Bedingfield", "maintenance_status": "19370", "development_status": "9994", Loading Loading @@ -1139,7 +1139,7 @@ } }, { "title": "Vitamin C", "title": "Vitamin&C;$?", "author": "Orange Juice", "maintenance_status": "19370", "development_status": "9994", Loading
tests/src/FunctionalJavascript/ProjectBrowserUiTest.php +63 −6 Original line number Diff line number Diff line Loading @@ -124,7 +124,7 @@ class ProjectBrowserUiTest extends WebDriverTestBase { 'Jazz', 'Eggman', 'Tooth Fairy', 'Vitamin C', 'Vitamin&C;$?', 'Cream cheese on a bagel', 'No Scrubs', 'Soup', Loading Loading @@ -254,12 +254,12 @@ class ProjectBrowserUiTest extends WebDriverTestBase { $this->assertEquals('Obsolete', $second_filter_element->getText()); $this->assertProjectsVisible([ 'Tooth Fairy', 'Vitamin C', 'Vitamin&C;$?', 'Pinky and the Brain', 'Soup', 'Quiznos', 'Ruh roh', 'Unwritten', 'Unwritten&:/', ]); // Click the Unsupported filter. Loading Loading @@ -336,8 +336,8 @@ class ProjectBrowserUiTest extends WebDriverTestBase { $this->click('.grid--2 .dropdown > button'); $this->click('.dropdown-content #pb-sort > li:nth-child(3)'); $this->assertProjectsVisible([ 'Vitamin C', 'Unwritten', 'Vitamin&C;$?', 'Unwritten&:/', 'Tooth Fairy', 'Soup', 'Ruh roh', Loading @@ -358,7 +358,7 @@ class ProjectBrowserUiTest extends WebDriverTestBase { 'Jazz', 'Eggman', 'Tooth Fairy', 'Vitamin C', 'Vitamin&C;$?', 'Cream cheese on a bagel', 'Pinky and the Brain', 'Ice Ice', Loading Loading @@ -390,4 +390,61 @@ class ProjectBrowserUiTest extends WebDriverTestBase { ]); } /** * Tests search with strings that need URI encoding. */ public function testSearchForSpecialChar(): void { $assert_session = $this->assertSession(); $page = $this->getSession()->getPage(); // Clear filters. $this->drupalGet('admin/modules/browse'); $page->clickLink('Clear filters'); $search_field = $page->find('css', '#pb-text'); // Fill in the search field. $search_field->setValue('&'); $this->assertProjectsVisible([ 'Vitamin&C;$?', 'Unwritten&:/', ]); // Fill in the search field. $search_field->setValue(''); $search_field->setValue('n&'); $this->assertProjectsVisible([ 'Vitamin&C;$?', 'Unwritten&:/', ]); $search_field->setValue(''); $search_field->setValue('$'); $this->assertProjectsVisible([ 'Vitamin&C;$?', ]); $search_field->setValue(''); $search_field->setValue('?'); $this->assertProjectsVisible([ 'Vitamin&C;$?', ]); $search_field->setValue(''); $search_field->setValue('/'); $this->assertProjectsVisible([ 'Unwritten&:/', ]); $search_field->setValue(''); $search_field->setValue(':'); $this->assertProjectsVisible([ 'Unwritten&:/', ]); $search_field->setValue(''); $search_field->setValue(';'); $this->assertProjectsVisible([ 'Vitamin&C;$?', ]); } }