Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
fix(search): validate comment ownership in format hook
Make sure comment has an owner before trying to render an icon
- Loading branch information
1 parent
4f305de
commit b39bbc2
Showing
6 changed files
with
278 additions
and
37 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
<?php | ||
|
||
namespace Elgg; | ||
|
||
trait HookTesting { | ||
|
||
/** | ||
* @return TestableHook | ||
*/ | ||
public function registerTestingHook($name, $type, $handler, $priority = 500) { | ||
|
||
$hook = new TestableHook(); | ||
$hook->name = $name; | ||
$hook->type = $type; | ||
$hook->handler = $handler; | ||
$hook->priority = $priority; | ||
|
||
return $hook->register($this); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,158 @@ | ||
<?php | ||
|
||
namespace Elgg; | ||
|
||
class TestableHook { | ||
|
||
/** | ||
* @var string | ||
*/ | ||
public $name; | ||
|
||
/** | ||
* @var string | ||
*/ | ||
public $type; | ||
|
||
/** | ||
* @var callable | ||
*/ | ||
public $handler; | ||
|
||
/** | ||
* @var int | ||
*/ | ||
public $priority = 500; | ||
|
||
/** | ||
* @var BaseTestCase | ||
*/ | ||
protected $test_case; | ||
|
||
/** | ||
* @var int | ||
*/ | ||
protected $calls = 0; | ||
|
||
/** | ||
* @var Hook | ||
*/ | ||
protected $before_state; | ||
|
||
/** | ||
* @var mixed | ||
*/ | ||
protected $result; | ||
|
||
/** | ||
* @var Hook | ||
*/ | ||
protected $after_state; | ||
|
||
/** | ||
* Register a new testing hook handler | ||
* | ||
* @param BaseTestCase $test_case Test case | ||
* | ||
* @return TestableHook | ||
*/ | ||
public function register(BaseTestCase $test_case) { | ||
$this->test_case = $test_case; | ||
|
||
elgg_register_plugin_hook_handler($this->name, $this->type, [$this, 'handler'], $this->priority); | ||
|
||
return $this; | ||
} | ||
|
||
/** | ||
* Unregister handler | ||
* @return void | ||
*/ | ||
public function unregister() { | ||
elgg_unregister_plugin_hook_handler($this->name, $this->type, [$this, 'handler']); | ||
} | ||
|
||
/** | ||
* Handler hook call | ||
* | ||
* @param Hook $hook Hook | ||
* | ||
* @return mixed | ||
*/ | ||
public function handler(\Elgg\Hook $hook) { | ||
$this->calls++; | ||
$this->before_state = $hook; | ||
|
||
list($success, $return, $hook) = _elgg_services()->handlers->call($this->handler, $hook, [ | ||
$this->name, | ||
$this->type, | ||
$hook->getValue(), | ||
$hook->getParams(), | ||
]); | ||
|
||
$this->after_state = $hook; | ||
|
||
if ($return !== null) { | ||
$this->result = $return; | ||
} else { | ||
$this->result = $hook->getValue(); | ||
} | ||
|
||
return $return; | ||
} | ||
|
||
/** | ||
* @return mixed | ||
*/ | ||
public function getResult() { | ||
return $this->result; | ||
} | ||
|
||
/** | ||
* Assert that hook was called expected number of times | ||
* | ||
* @param int $expected Expectation | ||
*/ | ||
public function assertNumberOfCalls($expected) { | ||
$this->test_case->assertEquals($expected, $this->calls); | ||
} | ||
|
||
/** | ||
* Assert that before hook handler is called the named parameter had a specific value | ||
* | ||
* @param string $name Name | ||
* @param mixed $value Value | ||
*/ | ||
public function assertParamBefore($name, $value) { | ||
$this->test_case->assertEquals($this->before_state->getParam($name), $value); | ||
} | ||
|
||
/** | ||
* Assert that before hook handler is called the named parameter has a specific | ||
* | ||
* @param string $name Name | ||
* @param mixed $value Value | ||
*/ | ||
public function assertParamAfter($name, $value) { | ||
$this->test_case->assertEquals($this->after_state->getParam($name), $value); | ||
} | ||
|
||
/** | ||
* Assert hook value before the handler was called | ||
* | ||
* @param mixed $value Value | ||
*/ | ||
public function assertValueBefore($value) { | ||
$this->test_case->assertEquals($this->before_state->getValue(), $value); | ||
} | ||
|
||
/** | ||
* Assert hook value after the handler was called | ||
* | ||
* @param mixed $value Value | ||
*/ | ||
public function assertValueAfter($value) { | ||
$this->test_case->assertEquals($this->after_state->getValue(), $value); | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
58 changes: 58 additions & 0 deletions
58
mod/search/tests/phpunit/unit/Elgg/Search/FormatCommentEntityHookTest.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
<?php | ||
|
||
namespace Elgg\Search; | ||
use Elgg\IntegratedUnitTestCase; | ||
|
||
/** | ||
* @group Search | ||
* @group Hooks | ||
*/ | ||
class FormatCommentEntityHookTest extends IntegratedUnitTestCase { | ||
|
||
public function up() { | ||
_elgg_services()->hooks->backup(); | ||
} | ||
|
||
public function down() { | ||
_elgg_services()->hooks->restore(); | ||
} | ||
|
||
public function testCommentVolatileDataIsPopulated() { | ||
$hook = $this->registerTestingHook('search:format', 'entity', FormatComentEntityHook::class); | ||
|
||
$object = $this->createObject([], [ | ||
'title' => 'Container', | ||
]); | ||
$comment = $this->createObject([ | ||
'subtype' => 'comment', | ||
'owner_guid' => 0, | ||
'container_guid' => $object->guid, | ||
], [ | ||
'title' => 'Comment', | ||
]); | ||
|
||
$search = new Search([ | ||
'query' => 'comment', | ||
'search_type' => 'entities', | ||
'entity_type' => 'object', | ||
'entity_subtype' => 'comment', | ||
]); | ||
|
||
$formatter = new Formatter($comment, $search); | ||
$formatter->format(); | ||
|
||
$hook->assertNumberOfCalls(1); | ||
|
||
$comment = $hook->getResult(); | ||
|
||
$this->assertEmpty($comment->getVolatileData('search_matched_icon')); | ||
|
||
$this->assertEquals( | ||
elgg_echo('search:comment_on', ['Container']), | ||
$comment->getVolatileData('search_matched_title') | ||
); | ||
|
||
$hook->unregister(); | ||
|
||
} | ||
} |