Skip to content

Commit 5e2f1b9

Browse files
committed
POST requests added to spec generation and OpenAPIDocs
1 parent bca8e0e commit 5e2f1b9

8 files changed

Lines changed: 1438 additions & 53 deletions

File tree

Annotations/AnnotationGenerator.php

Lines changed: 590 additions & 19 deletions
Large diffs are not rendered by default.

config/ParameterExamples.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -157,8 +157,8 @@
157157
'format:string' => 'html',
158158
'visits:array<int,VisitDescriptor>' => [
159159
[
160-
'idVisit' => 12345,
161-
'idSite' => 1,
160+
'idvisit' => 12345,
161+
'idsite' => 1,
162162
],
163163
],
164164
'segment:string' => 'countryCode==NZ',

tests/Resources/MockAnnotationGenerator.php

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,4 +110,29 @@ public function shouldUseParameterLevelExample(array $typesMap, string $example)
110110
{
111111
return parent::shouldUseParameterLevelExample($typesMap, $example);
112112
}
113+
114+
public function isComplexParameter(array $param): bool
115+
{
116+
return parent::isComplexParameter($param);
117+
}
118+
119+
public function buildRequestBodyAnnotation(array $bodyParams): array
120+
{
121+
return parent::buildRequestBodyAnnotation($bodyParams);
122+
}
123+
124+
public function expandTypeAliases(string $type): string
125+
{
126+
return parent::expandTypeAliases($type);
127+
}
128+
129+
public function resolveEffectiveParameterType(array $paramMetadata, array $paramDocInfo): string
130+
{
131+
return parent::resolveEffectiveParameterType($paramMetadata, $paramDocInfo);
132+
}
133+
134+
public function setCurrentTypeAliases(array $aliases): void
135+
{
136+
$this->currentTypeAliases = $aliases;
137+
}
113138
}

tests/Unit/AnnotationGeneratorTest.php

Lines changed: 155 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -396,6 +396,20 @@ public function testGetParamInfoFromDocBlock(): void
396396
$this->assertEquals($expected, $this->annotationGenerator->getParamInfoFromDocBlock(self::EXAMPLE_API_METHOD_DOC_BLOCK1));
397397
}
398398

399+
public function testGetParamInfoFromDocBlockPreservesRawAliasTypes(): void
400+
{
401+
$docBlock = <<<'DOC'
402+
/**
403+
* @param array<int, VisitDescriptor> $visits Data subject visit descriptors to export.
404+
*/
405+
DOC;
406+
407+
$this->assertSame(
408+
'array<int, VisitDescriptor>',
409+
$this->annotationGenerator->getParamInfoFromDocBlock($docBlock)['visits']['type']
410+
);
411+
}
412+
399413
public function testGetResponseInfoFromDocBlock(): void
400414
{
401415
// TODO - Update to use resource file and/or dataprovider to test more than one comment block
@@ -1410,9 +1424,148 @@ public function testBuildSchemaObjectArrays(): void
14101424
$this->expectNotToPerformAssertions();
14111425
}
14121426

1427+
public function testIsComplexParameterKeepsScalarArraysInQuery(): void
1428+
{
1429+
$annotationGenerator = new MockAnnotationGenerator(new DocumentationGenerator());
1430+
1431+
$this->assertFalse($annotationGenerator->isComplexParameter([
1432+
'types' => ['string' => null, 'array' => 'string'],
1433+
'_docType' => 'string|array<int,string>',
1434+
'_configExample' => ['running', 'finished'],
1435+
]));
1436+
}
1437+
1438+
public function testIsComplexParameterPromotesNestedArrayShapesToBody(): void
1439+
{
1440+
$annotationGenerator = new MockAnnotationGenerator(new DocumentationGenerator());
1441+
1442+
$this->assertTrue($annotationGenerator->isComplexParameter([
1443+
'types' => ['array' => 'string'],
1444+
'_docType' => 'array<int,VisitDescriptor>',
1445+
'_configExample' => [
1446+
[
1447+
'idsite' => 1,
1448+
'idvisit' => 2,
1449+
],
1450+
],
1451+
]));
1452+
}
1453+
1454+
public function testBuildRequestBodyAnnotationUsesWrappedFormEncodedSchema(): void
1455+
{
1456+
$annotationGenerator = new MockAnnotationGenerator(new DocumentationGenerator());
1457+
1458+
$requestBody = $annotationGenerator->buildRequestBodyAnnotation([
1459+
[
1460+
'name' => 'visits',
1461+
'description' => 'Visit descriptors.',
1462+
'required' => 'true',
1463+
'types' => ['array' => 'string'],
1464+
'_docType' => 'array<int,array{idsite:int,idvisit:int}>',
1465+
'_configExample' => [
1466+
[
1467+
'idsite' => 1,
1468+
'idvisit' => 12345,
1469+
],
1470+
],
1471+
],
1472+
]);
1473+
$lines = $annotationGenerator->buildLinesForAnnotationObject('@OA\Post', [
1474+
'path="/index.php"',
1475+
'operationId="PrivacyManager.exportDataSubjects"',
1476+
'tags={"PrivacyManager"}',
1477+
'description=""',
1478+
$requestBody,
1479+
]);
1480+
$annotation = implode("\n", $lines);
1481+
1482+
$this->assertStringContainsString('@OA\RequestBody(', $annotation);
1483+
$this->assertStringContainsString('mediaType="application/x-www-form-urlencoded"', $annotation);
1484+
$this->assertStringContainsString('property="visits"', $annotation);
1485+
$this->assertStringContainsString('property="idsite"', $annotation);
1486+
$this->assertStringContainsString('property="idvisit"', $annotation);
1487+
$this->assertStringContainsString('required={"visits"}', $annotation);
1488+
$this->assertStringContainsString('example={"visits":{{"idsite":1,"idvisit":12345}}}', $annotation);
1489+
}
1490+
1491+
public function testExpandTypeAliasesExpandsNamedArrayShapeAliases(): void
1492+
{
1493+
$annotationGenerator = new MockAnnotationGenerator(new DocumentationGenerator());
1494+
$annotationGenerator->setCurrentTypeAliases([
1495+
'VisitDescriptor' => 'array{idsite: int, idvisit: int}',
1496+
]);
1497+
1498+
$this->assertSame(
1499+
'array<int,array{idsite: int, idvisit: int}>',
1500+
$annotationGenerator->expandTypeAliases('array<int,VisitDescriptor>')
1501+
);
1502+
}
1503+
1504+
public function testResolveEffectiveParameterTypePreservesAliasCasingFromDocBlock(): void
1505+
{
1506+
$annotationGenerator = new MockAnnotationGenerator(new DocumentationGenerator());
1507+
1508+
$this->assertSame(
1509+
'array<int, VisitDescriptor>',
1510+
$annotationGenerator->resolveEffectiveParameterType(
1511+
['type' => 'string'],
1512+
['type' => 'array<int, VisitDescriptor>']
1513+
)
1514+
);
1515+
}
1516+
14131517
public function testCompileOperationLines(): void
14141518
{
1415-
// TODO - compileOperationLines method
1416-
$this->expectNotToPerformAssertions();
1519+
$lines = $this->annotationGenerator->compileOperationLines(
1520+
'/index.php?module=API&method=PrivacyManager.exportDataSubjects',
1521+
'PrivacyManager.exportDataSubjects',
1522+
'PrivacyManager',
1523+
[
1524+
'refs' => [],
1525+
'custom' => [
1526+
[
1527+
'name' => 'idSite',
1528+
'types' => ['integer' => null],
1529+
'description' => 'Site ID',
1530+
'required' => 'true',
1531+
'default' => NoDefaultValue::class,
1532+
'example' => '1',
1533+
],
1534+
[
1535+
'name' => 'visits',
1536+
'types' => ['array' => 'string'],
1537+
'description' => 'Visit descriptors.',
1538+
'required' => 'true',
1539+
'default' => NoDefaultValue::class,
1540+
'example' => '',
1541+
'_docType' => 'array<int,array{idsite:int,idvisit:int}>',
1542+
'_configExample' => [
1543+
[
1544+
'idsite' => 1,
1545+
'idvisit' => 12345,
1546+
],
1547+
],
1548+
'_isComplex' => true,
1549+
],
1550+
],
1551+
],
1552+
[
1553+
[
1554+
'code' => 200,
1555+
'description' => 'OK',
1556+
'schema' => ['@OA\Schema' => ['type="array"']],
1557+
],
1558+
],
1559+
'',
1560+
true
1561+
);
1562+
$annotation = implode("\n", $lines);
1563+
1564+
$this->assertStringContainsString('@OA\Post(', $annotation);
1565+
$this->assertStringContainsString('name="idSite"', $annotation);
1566+
$this->assertStringContainsString('in="query"', $annotation);
1567+
$this->assertStringContainsString('@OA\RequestBody(', $annotation);
1568+
$this->assertStringNotContainsString('name="visits"', $annotation);
1569+
$this->assertStringContainsString('property="visits"', $annotation);
14171570
}
14181571
}

vue/dist/OpenApiDocs.css

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)