Skip to content

Commit

Permalink
Merge pull request #212 from catalyst/issue-209-MOODLE_35_STABLE
Browse files Browse the repository at this point in the history
issue #209: allow different HTTP methods for http_post_action_step
  • Loading branch information
dmitriim authored Oct 17, 2023
2 parents 321535c + 4055bf0 commit dd9e5ed
Show file tree
Hide file tree
Showing 4 changed files with 89 additions and 11 deletions.
31 changes: 25 additions & 6 deletions classes/steps/actions/http_post_action_step.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.

/**
* HTTP Post action step class.
* HTTP action step class.
*
* @package tool_trigger
* @copyright Matt Porritt <[email protected]>
Expand All @@ -25,7 +25,7 @@
namespace tool_trigger\steps\actions;

/**
* HTTP Post action step class.
* HTTP action step class.
*
* @package tool_trigger
* @copyright Matt Porritt <[email protected]>
Expand All @@ -35,9 +35,22 @@ class http_post_action_step extends base_action_step {

use \tool_trigger\helper\datafield_manager;

/**
* Supported HTTP methods.
*/
const SUPPORTED_HTTP_METHODS = [
'POST' => 'POST',
'GET' => 'GET',
'PUT' => 'PUT',
'DELETE' => 'DELETE',
'PATCH' => 'PATCH',
];

protected $url;
protected $httpmethod;
protected $headers;
protected $params;
private $httphandler = null;

/**
* The fields supplied by this step.
Expand All @@ -52,6 +65,7 @@ class http_post_action_step extends base_action_step {

protected function init() {
$this->url = $this->data['url'];
$this->httpmethod = !empty($this->data['httpmethod']) ? $this->data['httpmethod'] : 'POST';
$this->headers = $this->data['httpheaders'];
$this->params = $this->data['httpparams'];
$this->jsonencode = $this->data['jsonencode'];
Expand Down Expand Up @@ -81,8 +95,6 @@ public static function get_step_desc() {
return get_string('httppostactionstepdesc', 'tool_trigger');
}

private $httphandler = null;

/**
* Kinda hacky... unit testing requires us to specify a different http handler for guzzle to use.
* That's really the only reason we need this method!
Expand Down Expand Up @@ -143,7 +155,7 @@ public function execute($step, $trigger, $event, $stepresults) {
$params = json_encode($output);
}

$request = new \GuzzleHttp\Psr7\Request('POST', $url, $headers, $params);
$request = new \GuzzleHttp\Psr7\Request($this->httpmethod, $url, $headers, $params);
$client = $this->get_http_client();

try {
Expand All @@ -159,7 +171,9 @@ public function execute($step, $trigger, $event, $stepresults) {
if ($response->getStatusCode() != $this->expectedresponse) {
// If we weren't expecting this response, throw an exception.
// The error will be caught and rerun.
throw new \invalid_response_exception("HTTP Response code expected was {$this->expectedresponse}, received {$response->getStatusCode()}");
throw new \invalid_response_exception(
"HTTP Response code expected was {$this->expectedresponse}, received {$response->getStatusCode()}"
);
}

return array(true, $stepresults);
Expand All @@ -180,6 +194,11 @@ public function form_definition_extra($form, $mform, $customdata) {
$mform->addRule('url', get_string('required'), 'required');
$mform->addHelpButton('url', 'httpostactionurl', 'tool_trigger');

// HTTP method.
$mform->addElement('select', 'httpmethod', get_string ('httpostmethod', 'tool_trigger'), self::SUPPORTED_HTTP_METHODS);
$mform->setType('httpmethod', PARAM_TEXT);
$mform->addHelpButton('httpmethod', 'httpostmethod', 'tool_trigger');

// Headers.
$attributes = array('cols' => '50', 'rows' => '2');
$mform->addElement('textarea', 'httpheaders', get_string ('httpostactionheaders', 'tool_trigger'), $attributes);
Expand Down
4 changes: 3 additions & 1 deletion lang/en/tool_trigger.php
Original file line number Diff line number Diff line change
Expand Up @@ -120,11 +120,13 @@
$string['historysettingsdesc'] = 'These settings provide control over how the history of a workflow is stored.';
$string['httpostactionurl'] = 'URL';
$string['httpostactionurl_help'] = 'The URL to post the data to.';
$string['httpostmethod'] = 'HTTP method';
$string['httpostmethod_help'] = 'HTTP method for the given request.';
$string['httpostactionheaders'] = 'Headers';
$string['httpostactionheaders_help'] = 'The requests headers to send.';
$string['httpostactionparams'] = 'Parameters';
$string['httpostactionparams_help'] = 'The parameters to send with the request.';
$string['httppostactionstepname'] = 'HTTP Post';
$string['httppostactionstepname'] = 'HTTP request';
$string['httppostactionstepdesc'] = 'A step to allow Moodle workflows to send data to a HTTP/S endpoint.';
$string['importmodaltitle'] = 'Import workflow from file';
$string['importworkflow'] = 'Import a workflow';
Expand Down
61 changes: 59 additions & 2 deletions tests/http_post_action_step_test.php
Original file line number Diff line number Diff line change
Expand Up @@ -62,12 +62,65 @@ private function make_mock_http_handler($response) {
return $stack;
}

/**
* Test supported HTTP methods.
*/
public function test_supported_http_methods() {
$expected = [
'POST' => 'POST',
'GET' => 'GET',
'PUT' => 'PUT',
'DELETE' => 'DELETE',
'PATCH' => 'PATCH',
];
$this->assertSame($expected, \tool_trigger\steps\actions\http_post_action_step::SUPPORTED_HTTP_METHODS);
}

/**
* Test that POST method is set as default if no httpmethod set for the step class.
* This is to make sure that steps created before httpmethod was introduced will get it by default.
*/
public function test_if_httpmethod_is_not_set_post_method_set_as_default() {
$stepsettings = [
'url' => 'http://http_post_action_step.example.com',
'httpheaders' => 'My-Special-Header: {headervalue}',
'httpparams' => '',
'jsonencode' => '0'
];

$step = new \tool_trigger\steps\actions\http_post_action_step(json_encode($stepsettings));

$reflector = new \ReflectionClass(\tool_trigger\steps\actions\http_post_action_step::class);
$property = $reflector->getProperty('httpmethod');
$property->setAccessible(true);

$this->assertEquals('POST', $property->getValue($step));
}

/**
* Data provider for all supported HTTP methods.
* @return array[]
*/
public function http_methods_data_provider(): array {
return [
['POST'],
['GET'],
['PUT'],
['DELETE'],
['PATCH'],
];
}

/**
* Simple test, with a successful response
*
* @dataProvider http_methods_data_provider
* @param string $httpmethod
*/
public function test_execute_200() {
public function test_execute_200(string $httpmethod) {
$stepsettings = [
'url' => 'http://http_post_action_step.example.com',
'httpmethod' => $httpmethod,
'httpheaders' => 'My-Special-Header: {headervalue}',
'httpparams' => '',
'jsonencode' => '0'
Expand All @@ -89,10 +142,14 @@ public function test_execute_200() {
/**
* Test that we properly handle a 404 response. Guzzle will throw an exception in this
* case, but the action step should catch the exception and handle it.
*
* @dataProvider http_methods_data_provider
* @param string $httpmethod
*/
public function test_execute_404() {
public function test_execute_404(string $httpmethod) {
$stepsettings = [
'url' => 'http://http_post_action_step.example.com/badurl',
'httpmethod' => $httpmethod,
'httpheaders' => 'My-Special-Header: {headervalue}',
'httpparams' => '',
'jsonencode' => '0',
Expand Down
4 changes: 2 additions & 2 deletions version.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@
defined('MOODLE_INTERNAL') || die();

$plugin->component = 'tool_trigger';
$plugin->release = 2021030408;
$plugin->version = 2021030408;
$plugin->release = 2021030409;
$plugin->version = 2021030409;
$plugin->requires = 2016052300;
$plugin->supported = [35, 310];
$plugin->maturity = MATURITY_STABLE;
Expand Down

0 comments on commit dd9e5ed

Please sign in to comment.