diff --git a/api/src/main/java/org/eclipse/microprofile/openapi/models/Components.java b/api/src/main/java/org/eclipse/microprofile/openapi/models/Components.java index 174af0d4..6f8ab497 100644 --- a/api/src/main/java/org/eclipse/microprofile/openapi/models/Components.java +++ b/api/src/main/java/org/eclipse/microprofile/openapi/models/Components.java @@ -483,4 +483,53 @@ default Components callbacks(Map callbacks) { */ void removeCallback(String key); + /** + * Returns the pathItems property of this Components instance. Path items listed here can be referenced from + * elsewhere in the OpenAPI document. + * + * @return a copy Map (potentially immutable) of path items + */ + Map getPathItems(); + + /** + * Sets the pathItems property of this Components instance. Path items listed here can be referenced from elsewhere + * in the OpenAPI document. + * + * @param pathItems + * a map of path items + */ + void setPathItems(Map pathItems); + + /** + * Sets the pathItems property of this Components instance. Path items listed here can be referenced from elsewhere + * in the OpenAPI document. + * + * @param pathItems + * a map of path items + * @return the current Schema instance + */ + default Components pathItems(Map pathItems) { + setPathItems(pathItems); + return this; + } + + /** + * Adds a path item. + * + * @param name + * name of the path item to add + * @param pathItem + * the path item to add + * @return the current Schema instance + */ + Components addPathItem(String name, PathItem pathItem); + + /** + * Removes a path item. + * + * @param name + * name of the path item to remove + */ + void removePathItem(String name); + } \ No newline at end of file diff --git a/tck/src/main/java/org/eclipse/microprofile/openapi/reader/MyOASModelReaderImpl.java b/tck/src/main/java/org/eclipse/microprofile/openapi/reader/MyOASModelReaderImpl.java index 82cb3168..2087ed21 100644 --- a/tck/src/main/java/org/eclipse/microprofile/openapi/reader/MyOASModelReaderImpl.java +++ b/tck/src/main/java/org/eclipse/microprofile/openapi/reader/MyOASModelReaderImpl.java @@ -264,7 +264,19 @@ public OpenAPI buildModel() { .schema(OASFactory.createSchema() .ref("#/components/schemas/Flight"))))))))) .addCallback("availabilityCallbackRef", OASFactory.createCallback() - .ref("#/components/callbacks/availabilityCallback"))) + .ref("#/components/callbacks/availabilityCallback")) + .pathItems(new HashMap<>()) + .addPathItem("idCrud", OASFactory.createPathItem() + .DELETE(OASFactory.createOperation() + .responses(OASFactory.createAPIResponses() + .addAPIResponse("202", OASFactory.createAPIResponse() + .content(OASFactory.createContent()) + .description("Delete item")))) + .addParameter(OASFactory.createParameter() + .name("id") + .in(In.PATH) + .description("The item parameter") + .required(true)))) .tags(new ArrayList()) .addTag(OASFactory.createObject(Tag.class) .name("Get Airlines") diff --git a/tck/src/main/java/org/eclipse/microprofile/openapi/tck/ModelConstructionTest.java b/tck/src/main/java/org/eclipse/microprofile/openapi/tck/ModelConstructionTest.java index f62faa42..ae674fe9 100644 --- a/tck/src/main/java/org/eclipse/microprofile/openapi/tck/ModelConstructionTest.java +++ b/tck/src/main/java/org/eclipse/microprofile/openapi/tck/ModelConstructionTest.java @@ -393,6 +393,27 @@ public void componentsTest() { SecurityScheme otherSecuritySchemeValue = createConstructibleInstance(SecurityScheme.class); checkMapImmutable(c, Components::getSecuritySchemes, "otherSecurityScheme", otherSecuritySchemeValue); checkNullValueInAdd(c::getSecuritySchemes, c::addSecurityScheme, "someSecurityScheme", securitySchemeValue); + + final String pathItemKey = "myPathItem"; + final PathItem pathItemValue = createConstructibleInstance(PathItem.class); + checkSameObject(c, c.addPathItem(pathItemKey, pathItemValue)); + checkMapEntry(c.getPathItems(), pathItemKey, pathItemValue); + assertEquals(c.getPathItems().size(), 1, "The map is expected to contain one entry."); + c.removePathItem(pathItemKey); + assertEquals(c.getPathItems().size(), 0, "The map is expected to be empty."); + + final String pathItemKey2 = "myPathItem2"; + final PathItem pathItemValue2 = createConstructibleInstance(PathItem.class); + c.setPathItems(Collections.singletonMap(pathItemKey2, pathItemValue2)); + checkMapEntry(c.getPathItems(), pathItemKey2, pathItemValue2); + assertEquals(c.getPathItems().size(), 1, "The map is expected to contain one entry."); + checkSameObject(c, c.addPathItem(pathItemKey, pathItemValue)); + checkMapEntry(c.getPathItems(), pathItemKey, pathItemValue); + assertEquals(c.getPathItems().size(), 2, "The map is expected to contain two entries."); + + PathItem otherPathItemValue = createConstructibleInstance(PathItem.class); + checkMapImmutable(c, Components::getPathItems, "otherPathItem", otherPathItemValue); + checkNullValueInAdd(c::getPathItems, c::addPathItem, "somePathItem", pathItemValue); } @Test @@ -1779,14 +1800,14 @@ private void processReference(Reference r) { r.setRef(myRef1); assertEquals(r.getRef(), myRef1, "The return value of getRef() is expected to be equal to the value that was set."); + // Check that the short name ref value can be set using the setter method and that the getter method returns the // expanded value. - if (!(r instanceof PathItem)) { - final String shortName = "myRef2"; - final String myRef2 = createReference(r, shortName); - r.setRef(shortName); - assertEquals(r.getRef(), myRef2, "The return value of getRef() is expected to be a fully expanded name."); - } + final String shortName2 = "myRef2"; + final String myRef2 = createReference(r, shortName2); + r.setRef(shortName2); + assertEquals(r.getRef(), myRef2, "The return value of getRef() is expected to be a fully expanded name."); + // Check that the ref value can be set using the builder method and that the getter method returns the same // value. final String myRef3 = createReference(r, "myRef3"); @@ -1794,15 +1815,14 @@ private void processReference(Reference r) { assertSame(self, r, "The return value of ref() is expected to return the current instance."); assertEquals(r.getRef(), myRef3, "The return value of getRef() is expected to be equal to the value that was set."); + // Check that the short name ref value can be set using the builder method and that the getter method returns // the expanded value. - if (!(r instanceof PathItem)) { - final String shortName = "myRef4"; - final String myRef4 = createReference(r, shortName); - final Reference self2 = r.ref(shortName); - assertSame(self2, r, "The return value of ref() is expected to return the current instance."); - assertEquals(r.getRef(), myRef4, "The return value of getRef() is expected to be a fully expanded name."); - } + final String shortName4 = "myRef4"; + final String myRef4 = createReference(r, shortName4); + final Reference self2 = r.ref(shortName4); + assertSame(self2, r, "The return value of ref() is expected to return the current instance."); + assertEquals(r.getRef(), myRef4, "The return value of getRef() is expected to be a fully expanded name."); } private void processConstructibleProperty(Constructible o, Property p, Class enclosingInterface) { @@ -1896,7 +1916,7 @@ private String createReference(Reference r, String v) { } else if (r instanceof Parameter) { sb.append("#/components/parameters/"); } else if (r instanceof PathItem) { - sb.append("http://www.abc.def.ghi/"); + sb.append("#/components/pathItems/"); } else if (r instanceof RequestBody) { sb.append("#/components/requestBodies/"); } else if (r instanceof Schema) { diff --git a/tck/src/main/java/org/eclipse/microprofile/openapi/tck/ModelReaderAppTest.java b/tck/src/main/java/org/eclipse/microprofile/openapi/tck/ModelReaderAppTest.java index 2717e1e5..5d421f6f 100644 --- a/tck/src/main/java/org/eclipse/microprofile/openapi/tck/ModelReaderAppTest.java +++ b/tck/src/main/java/org/eclipse/microprofile/openapi/tck/ModelReaderAppTest.java @@ -325,6 +325,7 @@ public void testComponents(String type) { vr.body("components.headers.Request-Limit", notNullValue()); vr.body("components.securitySchemes.httpTestScheme", notNullValue()); vr.body("components.links.UserName", notNullValue()); + vr.body("components.pathItems.idCrud", notNullValue()); } @Test(dataProvider = "formatProvider") @@ -368,6 +369,22 @@ public void testHeaderInComponents(String type) { vr.body(maxRate + ".allowEmptyValue", equalTo(true)); } + @Test(dataProvider = "formatProvider") + public void testPathItemWithRef(String type) { + ValidatableResponse vr = callEndpoint(type); + + // Referencing path item + String refpath = "paths.'/refpath/{id}'"; + vr.body(refpath + ".$ref", equalTo("#/components/pathItems/idCrud")); + vr.body(refpath + ".get.responses.'200'", notNullValue()); + + // Referenced path item + String idCrud = "components.pathItems.idCrud"; + vr.body(idCrud, notNullValue()); + vr.body(idCrud + ".parameters[0].description", equalTo("The item parameter")); + vr.body(idCrud + ".delete.responses.'202'.description", equalTo("Delete item")); + } + @Test(dataProvider = "formatProvider") public void testContentInAPIResponse(String type) { ValidatableResponse vr = callEndpoint(type); diff --git a/tck/src/main/java/org/eclipse/microprofile/openapi/tck/StaticDocumentTest.java b/tck/src/main/java/org/eclipse/microprofile/openapi/tck/StaticDocumentTest.java index 3d47f946..350160bf 100644 --- a/tck/src/main/java/org/eclipse/microprofile/openapi/tck/StaticDocumentTest.java +++ b/tck/src/main/java/org/eclipse/microprofile/openapi/tck/StaticDocumentTest.java @@ -140,5 +140,14 @@ public void testStaticDocument(String type) { equalTo("#/components/schemas/Booking")); vr.body(webhookDelete + ".responses.'204'.description", equalTo("Indicates that the deletion event was processed successfully")); + + String idCrud = "components.pathItems.idCrud"; + vr.body(idCrud, notNullValue()); + vr.body(idCrud + ".parameters[0].description", equalTo("The item parameter")); + vr.body(idCrud + ".delete.responses.'202'.description", equalTo("Delete item")); + + String refpath = "paths.'/refpath/{id}'"; + vr.body(refpath + ".$ref", equalTo("#/components/pathItems/idCrud")); + vr.body(refpath + ".get.responses.'200'", notNullValue()); } } diff --git a/tck/src/main/resources/simpleapi.yaml b/tck/src/main/resources/simpleapi.yaml index 77086d95..b38c11d3 100644 --- a/tck/src/main/resources/simpleapi.yaml +++ b/tck/src/main/resources/simpleapi.yaml @@ -120,6 +120,15 @@ paths: responses: '200': description: trace operation tested + /refpath/{id}: + $ref: '#/components/pathItems/idCrud' + get: + responses: + '200': + content: + 'application/json': + schema: + $ref: '#/components/schemas/InventoryItem' webhooks: bookingEvent: put: @@ -186,3 +195,15 @@ components: examples: - 408-867-5309 type: object + pathItems: + idCrud: + delete: + responses: + '202': + content: [] + description: Delete item + parameters: + - name: id + in: path + description: The item parameter + required: true