143 lines
		
	
	
		
			4.7 KiB
		
	
	
	
		
			PHP
		
	
	
		
		
			
		
	
	
			143 lines
		
	
	
		
			4.7 KiB
		
	
	
	
		
			PHP
		
	
	
|  | <?php declare(strict_types=1); | ||
|  | 
 | ||
|  | /** | ||
|  |  * @license Apache 2.0 | ||
|  |  */ | ||
|  | 
 | ||
|  | namespace OpenApi\Tests\Annotations; | ||
|  | 
 | ||
|  | use OpenApi\Annotations\Get; | ||
|  | use OpenApi\Annotations\Parameter; | ||
|  | use OpenApi\Annotations\Schema; | ||
|  | use OpenApi\Tests\OpenApiTestCase; | ||
|  | 
 | ||
|  | class AbstractAnnotationTest extends OpenApiTestCase | ||
|  | { | ||
|  |     public function testVendorFields() | ||
|  |     { | ||
|  |         $annotations = $this->parseComment('@OA\Get(x={"internal-id": 123})'); | ||
|  |         $output = $annotations[0]->jsonSerialize(); | ||
|  |         $prefixedProperty = 'x-internal-id'; | ||
|  |         $this->assertSame(123, $output->$prefixedProperty); | ||
|  |     } | ||
|  | 
 | ||
|  |     public function testInvalidField() | ||
|  |     { | ||
|  |         $this->assertOpenApiLogEntryContains('Unexpected field "doesnot" for @OA\Get(), expecting'); | ||
|  |         $this->parseComment('@OA\Get(doesnot="exist")'); | ||
|  |     } | ||
|  | 
 | ||
|  |     public function testUmergedAnnotation() | ||
|  |     { | ||
|  |         $openapi = $this->createOpenApiWithInfo(); | ||
|  |         $openapi->merge($this->parseComment('@OA\Items()')); | ||
|  |         $this->assertOpenApiLogEntryContains('Unexpected @OA\Items(), expected to be inside @OA\\'); | ||
|  |         $openapi->validate(); | ||
|  |     } | ||
|  | 
 | ||
|  |     public function testConflictedNesting() | ||
|  |     { | ||
|  |         $comment = <<<END | ||
|  | @OA\Info( | ||
|  |     title="Info only has one contact field..", | ||
|  |     version="test", | ||
|  |     @OA\Contact(name="first"), | ||
|  |     @OA\Contact(name="second") | ||
|  | ) | ||
|  | END; | ||
|  |         $annotations = $this->parseComment($comment); | ||
|  |         $this->assertOpenApiLogEntryContains('Only one @OA\Contact() allowed for @OA\Info() multiple found in:'); | ||
|  |         $annotations[0]->validate(); | ||
|  |     } | ||
|  | 
 | ||
|  |     public function testKey() | ||
|  |     { | ||
|  |         $comment = <<<END | ||
|  | @OA\Response( | ||
|  |     @OA\Header(header="X-CSRF-Token",description="Token to prevent Cross Site Request Forgery") | ||
|  | ) | ||
|  | END; | ||
|  |         $annotations = $this->parseComment($comment); | ||
|  |         $this->assertEquals('{"headers":{"X-CSRF-Token":{"description":"Token to prevent Cross Site Request Forgery"}}}', json_encode($annotations[0])); | ||
|  |     } | ||
|  | 
 | ||
|  |     public function testConflictingKey() | ||
|  |     { | ||
|  |         $comment = <<<END | ||
|  | @OA\Response( | ||
|  |     description="The headers in response must have unique header values", | ||
|  |     @OA\Header(header="X-CSRF-Token", @OA\Schema(type="string"), description="first"), | ||
|  |     @OA\Header(header="X-CSRF-Token", @OA\Schema(type="string"), description="second") | ||
|  | ) | ||
|  | END; | ||
|  |         $annotations = $this->parseComment($comment); | ||
|  |         $this->assertOpenApiLogEntryContains('Multiple @OA\Header() with the same header="X-CSRF-Token":'); | ||
|  |         $annotations[0]->validate(); | ||
|  |     } | ||
|  | 
 | ||
|  |     public function testRequiredFields() | ||
|  |     { | ||
|  |         $annotations = $this->parseComment('@OA\Info()'); | ||
|  |         $info = $annotations[0]; | ||
|  |         $this->assertOpenApiLogEntryContains('Missing required field "title" for @OA\Info() in '); | ||
|  |         $this->assertOpenApiLogEntryContains('Missing required field "version" for @OA\Info() in '); | ||
|  |         $info->validate(); | ||
|  |     } | ||
|  | 
 | ||
|  |     public function testTypeValidation() | ||
|  |     { | ||
|  |         $comment = <<<END | ||
|  | @OA\Parameter( | ||
|  |     name=123, | ||
|  |     in="dunno", | ||
|  |     required="maybe", | ||
|  |     @OA\Schema( | ||
|  |       type="strig", | ||
|  |     ) | ||
|  | ) | ||
|  | END; | ||
|  |         $annotations = $this->parseComment($comment); | ||
|  |         $parameter = $annotations[0]; | ||
|  |         $this->assertOpenApiLogEntryContains('@OA\Parameter(name=123,in="dunno")->name is a "integer", expecting a "string" in '); | ||
|  |         $this->assertOpenApiLogEntryContains('@OA\Parameter(name=123,in="dunno")->in "dunno" is invalid, expecting "query", "header", "path", "cookie" in '); | ||
|  |         $this->assertOpenApiLogEntryContains('@OA\Parameter(name=123,in="dunno")->required is a "string", expecting a "boolean" in '); | ||
|  | //        $this->assertOpenApiLogEntryStartsWith('@OA\Parameter(name=123,in="dunno")->maximum is a "string", expecting a "number" in ');
 | ||
|  | //        $this->assertOpenApiLogEntryStartsWith('@OA\Parameter(name=123,in="dunno")->type must be "string", "number", "integer", "boolean", "array", "file" when @OA\Parameter()->in != "body" in ');
 | ||
|  |         $parameter->validate(); | ||
|  |     } | ||
|  | 
 | ||
|  |     public function nestedMatches() | ||
|  |     { | ||
|  |         $parameterMatch = (object) ['key' => Parameter::class, 'value' => ['parameters']]; | ||
|  | 
 | ||
|  |         return [ | ||
|  |             'unknown' => [self::class, null], | ||
|  |             'simple-match' => [Parameter::class, $parameterMatch], | ||
|  |             'invalid-annotation' => [Schema::class, null], | ||
|  |             'sub-annotation' => [SubParameter::class, $parameterMatch], | ||
|  |             'sub-sub-annotation' => [SubSubParameter::class, $parameterMatch], | ||
|  |             'sub-invalid' => [SubSchema::class, null], | ||
|  |         ]; | ||
|  |     } | ||
|  | 
 | ||
|  |     /** | ||
|  |      * @dataProvider nestedMatches | ||
|  |      */ | ||
|  |     public function testMatchNested($class, $expected) | ||
|  |     { | ||
|  |         $this->assertEquals($expected, Get::matchNested($class)); | ||
|  |     } | ||
|  | } | ||
|  | 
 | ||
|  | class SubSchema extends Schema | ||
|  | { | ||
|  | } | ||
|  | 
 | ||
|  | class SubParameter extends Parameter | ||
|  | { | ||
|  | } | ||
|  | 
 | ||
|  | class SubSubParameter extends SubParameter | ||
|  | { | ||
|  | } |