MDL-78192 external: allow nullable non-scalar params and results

This commit is contained in:
Petr Skoda
2023-06-23 11:12:08 +02:00
parent 3cd84747cb
commit 16729b7f02
7 changed files with 117 additions and 12 deletions
+95 -1
View File
@@ -82,6 +82,52 @@ class external_api_test extends \advanced_testcase {
$this->assertSame('someid', key($result));
$this->assertSame(6, $result['someid']);
$this->assertSame('aaa', $result['text']);
// Missing required value (an exception is thrown).
$testdata = [];
try {
external_api::clean_returnvalue($description, $testdata);
$this->fail('Exception expected');
} catch (\moodle_exception $ex) {
$this->assertInstanceOf(\invalid_response_exception::class, $ex);
$this->assertSame('Invalid response value detected (Error in response - '
. 'Missing following required key in a single structure: text)', $ex->getMessage());
}
// Test nullable external_value may optionally return data.
$description = new external_function_parameters([
'value' => new external_value(PARAM_INT, '', VALUE_REQUIRED, null, NULL_ALLOWED)
]);
$testdata = ['value' => null];
$cleanedvalue = external_api::clean_returnvalue($description, $testdata);
$this->assertSame($testdata, $cleanedvalue);
$testdata = ['value' => 1];
$cleanedvalue = external_api::clean_returnvalue($description, $testdata);
$this->assertSame($testdata, $cleanedvalue);
// Test nullable external_single_structure may optionally return data.
$description = new external_function_parameters([
'value' => new external_single_structure(['value2' => new external_value(PARAM_INT)],
'', VALUE_REQUIRED, null, NULL_ALLOWED)
]);
$testdata = ['value' => null];
$cleanedvalue = external_api::clean_returnvalue($description, $testdata);
$this->assertSame($testdata, $cleanedvalue);
$testdata = ['value' => ['value2' => 1]];
$cleanedvalue = external_api::clean_returnvalue($description, $testdata);
$this->assertSame($testdata, $cleanedvalue);
// Test nullable external_multiple_structure may optionally return data.
$description = new external_function_parameters([
'value' => new external_multiple_structure(
new external_value(PARAM_INT), '', VALUE_REQUIRED, null, NULL_ALLOWED)
]);
$testdata = ['value' => null];
$cleanedvalue = external_api::clean_returnvalue($description, $testdata);
$this->assertSame($testdata, $cleanedvalue);
$testdata = ['value' => [1]];
$cleanedvalue = external_api::clean_returnvalue($description, $testdata);
$this->assertSame($testdata, $cleanedvalue);
}
/**
@@ -162,8 +208,56 @@ class external_api_test extends \advanced_testcase {
$singlestructure['object'] = $object;
$singlestructure['value2'] = 'Some text';
$testdata = [$singlestructure];
$this->expectException('invalid_response_exception');
try {
external_api::clean_returnvalue($returndesc, $testdata);
$this->fail('Exception expected');
} catch (\moodle_exception $ex) {
$this->assertInstanceOf(\invalid_response_exception::class, $ex);
$this->assertSame('Invalid response value detected (object => Invalid response value detected '
. '(Error in response - Missing following required key in a single structure: value1): Error in response - '
. 'Missing following required key in a single structure: value1)', $ex->getMessage());
}
// Fail if no data provided when value required.
$testdata = null;
try {
external_api::clean_returnvalue($returndesc, $testdata);
$this->fail('Exception expected');
} catch (\moodle_exception $ex) {
$this->assertInstanceOf(\invalid_response_exception::class, $ex);
$this->assertSame('Invalid response value detected (Only arrays accepted. The bad value is: \'\')',
$ex->getMessage());
}
// Test nullable external_multiple_structure may optionally return data.
$returndesc = new external_multiple_structure(
new external_value(PARAM_INT),
'', VALUE_REQUIRED, null, NULL_ALLOWED);
$testdata = null;
$cleanedvalue = external_api::clean_returnvalue($returndesc, $testdata);
$this->assertSame($testdata, $cleanedvalue);
$testdata = [1];
$cleanedvalue = external_api::clean_returnvalue($returndesc, $testdata);
$this->assertSame($testdata, $cleanedvalue);
// Test nullable external_single_structure may optionally return data.
$returndesc = new external_single_structure(['value' => new external_value(PARAM_INT)],
'', VALUE_REQUIRED, null, NULL_ALLOWED);
$testdata = null;
$cleanedvalue = external_api::clean_returnvalue($returndesc, $testdata);
$this->assertSame($testdata, $cleanedvalue);
$testdata = ['value' => 1];
$cleanedvalue = external_api::clean_returnvalue($returndesc, $testdata);
$this->assertSame($testdata, $cleanedvalue);
// Test nullable external_value may optionally return data.
$returndesc = new external_value(PARAM_INT, '', VALUE_REQUIRED, null, NULL_ALLOWED);
$testdata = null;
$cleanedvalue = external_api::clean_returnvalue($returndesc, $testdata);
$this->assertSame($testdata, $cleanedvalue);
$testdata = 1;
$cleanedvalue = external_api::clean_returnvalue($returndesc, $testdata);
$this->assertSame($testdata, $cleanedvalue);
}
/**