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 = <<parseComment($comment); $this->assertOpenApiLogEntryContains('Only one @OA\Contact() allowed for @OA\Info() multiple found in:'); $annotations[0]->validate(); } public function testKey() { $comment = <<parseComment($comment); $this->assertEquals('{"headers":{"X-CSRF-Token":{"description":"Token to prevent Cross Site Request Forgery"}}}', json_encode($annotations[0])); } public function testConflictingKey() { $comment = <<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 = <<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 { }