BryanDavis has uploaded a new change for review.
https://gerrit.wikimedia.org/r/234194
Change subject: API: Force 'required' to use bools in nested elements
......................................................................
API: Force 'required' to use bools in nested elements
Fix formatversion=1 api output to treat 'required' values as booleans in
schema elements that are nested (array and object types).
Bug: T97487
Change-Id: Iba26be02949224f80d590e9b84492b099981aa1d
---
M includes/ApiJsonSchema.php
A tests/ApiJsonSchemaTest.php
2 files changed, 188 insertions(+), 4 deletions(-)
git pull ssh://gerrit.wikimedia.org:29418/mediawiki/extensions/EventLogging
refs/changes/94/234194/1
diff --git a/includes/ApiJsonSchema.php b/includes/ApiJsonSchema.php
index ab4dea2..f6a6d49 100644
--- a/includes/ApiJsonSchema.php
+++ b/includes/ApiJsonSchema.php
@@ -129,16 +129,39 @@
$this->markCacheable( $rev );
$schema = $content->getJsonData( true );
+ static::addOutputMetadata( $schema );
$result = $this->getResult();
$result->addValue( null, 'title', $title->getText() );
foreach ( $schema as $k => &$v ) {
- if ( $k === 'properties' ) {
- foreach ( $v as &$properties ) {
- $properties[ApiResult::META_BC_BOOLS] =
array( 'required' );
+ $result->addValue( null, $k, $v );
+ }
+ }
+
+ /**
+ * Add ApiResult metadata to the given array.
+ *
+ * Items in 'properties' or 'items' collections will be annotated so
that
+ * the API knows that their 'required' values should be output as
+ * booleans.
+ *
+ * @param array &$typeDescription
+ */
+ public static function addOutputMetadata( array &$typeDescription ) {
+ foreach ( $typeDescription as $key => &$value ) {
+ if ( $key === 'properties' || $key === 'items' ) {
+ foreach ( $value as &$type ) {
+ $type[ApiResult::META_BC_BOOLS] =
array( 'required' );
+
+ if ( $type['type'] === 'object' ) {
+ // Objects contain additional
properties
+ static::addOutputMetadata(
$type );
+
+ } elseif ( $type['type'] === 'array' ) {
+ static::addOutputMetadata(
$type );
+ }
}
}
- $result->addValue( null, $k, $v );
}
}
}
diff --git a/tests/ApiJsonSchemaTest.php b/tests/ApiJsonSchemaTest.php
new file mode 100644
index 0000000..2faedc2
--- /dev/null
+++ b/tests/ApiJsonSchemaTest.php
@@ -0,0 +1,161 @@
+<?php
+/**
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file
+ * @ingroup Extensions
+ *
+ * @author Bryan Davis <[email protected]>
+ * @copyright © 2015 Bryan Davis and Wikimedia Foundation.
+ */
+
+/**
+ * @group EventLogging
+ * @covers ApiJsonSchema
+ */
+class ApiJsonSchemaTest extends MediaWikiTestCase {
+
+ public function testAddOutputMetadata() {
+ $schema = array(
+ 'description' => 'test',
+ 'properties' => array(
+ 'n' => array(
+ 'type' => 'number',
+ 'required' => false,
+ 'description' => 'number',
+ ),
+ 'i' => array(
+ 'type' => 'integer',
+ 'required' => false,
+ 'description' => 'integer',
+ ),
+ 'a' => array(
+ 'type' => 'array',
+ 'required' => false,
+ 'description' => 'array',
+ 'items' => array(
+ array(
+ 'type' => 'object',
+ 'required' => false,
+ 'description' =>
'object',
+ 'properties' => array(
+ 'n' => array(
+ 'type'
=> 'number',
+
'required' => false,
+
'description' => 'number',
+ ),
+ 'i' => array(
+ 'type'
=> 'integer',
+
'required' => false,
+
'description' => 'integer',
+ ),
+ ),
+ ),
+ ),
+ ),
+ 'o' => array(
+ 'type' => 'object',
+ 'required' => false,
+ 'description' => 'object',
+ 'properties' => array(
+ 'oo' => array(
+ 'type' => 'object',
+ 'required' => false,
+ 'description' =>
'object',
+ 'properties' => array(
+ 'n' => array(
+ 'type'
=> 'number',
+
'required' => false,
+
'description' => 'number',
+ ),
+ 'i' => array(
+ 'type'
=> 'integer',
+
'required' => false,
+
'description' => 'integer',
+ ),
+ ),
+ )
+ ),
+ ),
+ ),
+ );
+
+ ApiJsonSchema::addOutputMetadata( $schema );
+
+ $this->assertArrayHasKey( '_BC_bools',
+ $schema['properties']['n']
+ );
+ $this->assertArrayHasKey( '_BC_bools',
+ $schema['properties']['i']
+ );
+ $this->assertArrayHasKey( '_BC_bools',
+ $schema['properties']['a']
+ );
+ $this->assertArrayHasKey( '_BC_bools',
+ $schema['properties']['a']['items'][0]
+);
+ $this->assertArrayHasKey( '_BC_bools',
+
$schema['properties']['a']['items'][0]['properties']['n']
+ );
+ $this->assertArrayHasKey( '_BC_bools',
+
$schema['properties']['a']['items'][0]['properties']['i']
+ );
+ $this->assertArrayHasKey( '_BC_bools',
+ $schema['properties']['o']
+ );
+ $this->assertArrayHasKey( '_BC_bools',
+ $schema['properties']['o']['properties']['oo']
+ );
+ $this->assertArrayHasKey( '_BC_bools',
+
$schema['properties']['o']['properties']['oo']['properties']['n']
+ );
+ $this->assertArrayHasKey( '_BC_bools',
+
$schema['properties']['o']['properties']['oo']['properties']['i']
+ );
+
+ // make sure there are no extra '_BC_bools' keys
+ $bcBoolCount = 0;
+ $this->visitAllRecursive( $schema,
+ function ( $v, $k ) use ( &$bcBoolCount ) {
+ if ( $k === '_BC_bools' ) {
+ $bcBoolCount = $bcBoolCount + 1;
+ }
+ }
+ );
+ $this->assertSame( 10, $bcBoolCount );
+ }
+
+ /**
+ * Visit all the elements of an array recursively.
+ *
+ * Works like array_walk_recursive() except that elements which are
arrays
+ * are visited as well rather than stepping into them and ignoring the
+ * array itself.
+ *
+ * @param array &$a Array to visit
+ * @param Callable $callback Function to call for each element. Will be
+ * passed two arguments: $value and $key (goofy order taken from
+ * array_walk_recursive())
+ */
+ protected function visitAllRecursive( array &$a, $callback ) {
+ foreach ( $a as $key => $value ) {
+ $callback( $value, $key );
+ if ( is_array( $value ) ) {
+ $this->visitAllRecursive( $value, $callback );
+ }
+ }
+ }
+}
--
To view, visit https://gerrit.wikimedia.org/r/234194
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: Iba26be02949224f80d590e9b84492b099981aa1d
Gerrit-PatchSet: 1
Gerrit-Project: mediawiki/extensions/EventLogging
Gerrit-Branch: master
Gerrit-Owner: BryanDavis <[email protected]>
_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits