Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
96.67% |
29 / 30 |
|
85.71% |
6 / 7 |
CRAP | |
0.00% |
0 / 1 |
JsonSchemaValidator | |
96.67% |
29 / 30 |
|
85.71% |
6 / 7 |
14 | |
0.00% |
0 / 1 |
__construct | |
100.00% |
2 / 2 |
|
100.00% |
1 / 1 |
4 | |||
areSchemasSupported | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
getSchemaBuilder | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
validateStrictly | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
validatePermissively | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
validate | |
100.00% |
23 / 23 |
|
100.00% |
1 / 1 |
5 | |||
getSchemaVersion | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 |
1 | <?php |
2 | |
3 | namespace MediaWiki\Extension\CommunityConfiguration\Validation; |
4 | |
5 | use InvalidArgumentException; |
6 | use JsonSchema\Validator; |
7 | use MediaWiki\Extension\CommunityConfiguration\Schema\JsonSchema; |
8 | use MediaWiki\Extension\CommunityConfiguration\Schema\JsonSchemaBuilder; |
9 | use MediaWiki\Extension\CommunityConfiguration\Schema\JsonSchemaReader; |
10 | use MediaWiki\Extension\CommunityConfiguration\Schema\SchemaBuilder; |
11 | use Status; |
12 | use StatusValue; |
13 | |
14 | /** |
15 | * JSON Schema validator. |
16 | */ |
17 | class JsonSchemaValidator implements IValidator { |
18 | |
19 | private JsonSchemaReader $jsonSchema; |
20 | private JsonSchemaBuilder $jsonSchemaBuilder; |
21 | |
22 | /** |
23 | * @param JsonSchema|string $classNameOrClassInstance JsonSchema derived class name (instance only allowed in tests) |
24 | */ |
25 | public function __construct( $classNameOrClassInstance ) { |
26 | // @codeCoverageIgnoreStart |
27 | if ( is_object( $classNameOrClassInstance ) ) { |
28 | if ( !defined( 'MW_PHPUNIT_TEST' ) ) { |
29 | throw new InvalidArgumentException( |
30 | 'JsonSchema should never be instantiated in production code' |
31 | ); |
32 | } |
33 | if ( !( $classNameOrClassInstance instanceof JsonSchema ) ) { |
34 | throw new InvalidArgumentException( |
35 | get_class( $classNameOrClassInstance ) . ' must be instance of ' . JsonSchema::class |
36 | ); |
37 | } |
38 | } |
39 | // @codeCoverageIgnoreEnd |
40 | |
41 | $this->jsonSchema = new JsonSchemaReader( $classNameOrClassInstance ); |
42 | $this->jsonSchemaBuilder = new JsonSchemaBuilder( $this->jsonSchema ); |
43 | } |
44 | |
45 | /** |
46 | * @inheritDoc |
47 | */ |
48 | public function areSchemasSupported(): bool { |
49 | return true; |
50 | } |
51 | |
52 | /** |
53 | * @inheritDoc |
54 | */ |
55 | public function getSchemaBuilder(): SchemaBuilder { |
56 | return $this->jsonSchemaBuilder; |
57 | } |
58 | |
59 | /** |
60 | * @inheritDoc |
61 | */ |
62 | public function validateStrictly( $config ): StatusValue { |
63 | return $this->validate( $config, false ); |
64 | } |
65 | |
66 | /** |
67 | * @inheritDoc |
68 | */ |
69 | public function validatePermissively( $config ): StatusValue { |
70 | return $this->validate( $config, true ); |
71 | } |
72 | |
73 | /** |
74 | * @param mixed $config |
75 | * @param bool $modeForReading |
76 | * @return StatusValue |
77 | */ |
78 | private function validate( $config, bool $modeForReading ): StatusValue { |
79 | $validator = new Validator(); |
80 | |
81 | $validator->validate( |
82 | $config, |
83 | $this->jsonSchemaBuilder->getRootSchema() |
84 | ); |
85 | if ( $validator->isValid() ) { |
86 | return Status::newGood(); |
87 | } |
88 | $status = new Status(); |
89 | foreach ( $validator->getErrors() as $error ) { |
90 | if ( $modeForReading && in_array( $error['constraint'], [ 'required', 'additionalProp', 'enum' ] ) ) { |
91 | $status->warning( |
92 | 'communityconfiguration-schema-validation-error', |
93 | $error['property'], |
94 | $error['message'], |
95 | $error |
96 | ); |
97 | } else { |
98 | $status->fatal( |
99 | 'communityconfiguration-schema-validation-error', |
100 | $error['property'], |
101 | $error['message'], |
102 | $error |
103 | ); |
104 | } |
105 | } |
106 | |
107 | return $status; |
108 | } |
109 | |
110 | /** |
111 | * @inheritDoc |
112 | */ |
113 | public function getSchemaVersion(): ?string { |
114 | return $this->jsonSchema->getVersion(); |
115 | } |
116 | } |