Skip to content

Commit

Permalink
RESTWS-963: Add a swagger autogeneration util to scan resource handle…
Browse files Browse the repository at this point in the history
…rs and generate the swagger spec
  • Loading branch information
mherman22 committed Jan 31, 2025
1 parent ef50052 commit fb399b3
Show file tree
Hide file tree
Showing 8 changed files with 926 additions and 30 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -9,49 +9,50 @@
*/
package org.openmrs.module.unrelatedtest.rest.resource;

import io.swagger.models.Model;
import org.openmrs.module.unrelatedtest.UnrelatedGenericChild;
import org.openmrs.module.webservices.rest.doc.SwaggerSpecificationCreatorTest;
import org.openmrs.module.webservices.rest.web.RestConstants;
import org.openmrs.module.webservices.rest.web.annotation.Resource;
import org.openmrs.module.webservices.rest.web.representation.Representation;
import org.openmrs.module.webservices.rest.web.resource.impl.DelegatingResourceDescription;
import org.openmrs.module.webservices.rest.web.response.ResourceDoesNotSupportOperationException;
import org.openmrs.module.webservices.rest.web.v1_0.test.GenericChildResource;

/**
* A test resource that is unrelated to the main webservices package.
*
*
* @see SwaggerSpecificationCreatorTest#testUnrelatedResourceDefinitions()
*/
@Resource(name = RestConstants.VERSION_1 + "/unrelated", supportedClass = UnrelatedGenericChild.class, supportedOpenmrsVersions = { "1.9.* - 9.*" })
public class UnrelatedGenericChildResource extends GenericChildResource {

public static boolean getGETCalled = false;

public static boolean getCREATECalled = false;

public static boolean getUPDATECalled = false;

/*******************************
* TEST METHOD IMPLEMENTATIONS * These methods are the ones we want to test against. There
* implementaion is unimportant, they just set flags so we can assert the methods were called
* correctly by the reflector.
*/

@Override
public Model getGETModel(Representation rep) {
public DelegatingResourceDescription getRepresentationDescription(Representation rep) {
getGETCalled = true;
return super.getGETModel(rep);
return super.getRepresentationDescription(rep);
}

@Override
public Model getCREATEModel(Representation rep) {
public DelegatingResourceDescription getCreatableProperties() {
getCREATECalled = true;
return super.getCREATEModel(rep);
return super.getCreatableProperties();
}

@Override
public Model getUPDATEModel(Representation rep) {
public DelegatingResourceDescription getUpdatableProperties() throws ResourceDoesNotSupportOperationException {
getUPDATECalled = true;
return super.getUPDATEModel(rep);
return super.getUpdatableProperties();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,18 @@
import io.swagger.jackson.ModelResolver;
import io.swagger.models.Info;
import io.swagger.models.Model;
import io.swagger.models.ModelImpl;
import io.swagger.models.Operation;
import io.swagger.models.Path;
import io.swagger.models.Scheme;
import io.swagger.models.Swagger;
import io.swagger.models.auth.BasicAuthDefinition;
import io.swagger.models.parameters.Parameter;
import io.swagger.models.properties.ArrayProperty;
import io.swagger.models.properties.DateProperty;
import io.swagger.models.properties.Property;
import io.swagger.models.properties.RefProperty;
import io.swagger.models.properties.StringProperty;
import io.swagger.util.Json;
import org.dbunit.database.DatabaseConnection;
import org.junit.Assert;
Expand All @@ -30,9 +36,14 @@
import org.openmrs.Patient;
import org.openmrs.api.context.Context;
import org.openmrs.module.unrelatedtest.rest.resource.UnrelatedGenericChildResource;
import org.openmrs.module.webservices.docs.swagger.SwaggerGenerationUtil;
import org.openmrs.module.webservices.docs.swagger.SwaggerSpecificationCreator;
import org.openmrs.module.webservices.rest.web.RestConstants;
import org.openmrs.module.webservices.rest.web.api.RestService;
import org.openmrs.module.webservices.rest.web.representation.Representation;
import org.openmrs.module.webservices.rest.web.v1_0.resource.openmrs1_8.ObsResource1_8;
import org.openmrs.module.webservices.rest.web.v1_0.resource.openmrs1_8.PatientResource1_8;
import org.openmrs.module.webservices.rest.web.v1_0.resource.openmrs1_8.PersonResource1_8;
import org.openmrs.web.test.BaseModuleWebContextSensitiveTest;

import java.lang.reflect.Field;
Expand All @@ -49,6 +60,7 @@
import static junit.framework.TestCase.assertFalse;
import static junit.framework.TestCase.assertNotNull;
import static junit.framework.TestCase.assertTrue;
import static org.junit.Assert.assertEquals;

public class SwaggerSpecificationCreatorTest extends BaseModuleWebContextSensitiveTest {

Expand Down Expand Up @@ -270,7 +282,7 @@ public void createOnlySubresourceDefinitions() {
assertFalse(json.contains("SystemsettingSubdetailsUpdate"));
assertTrue(json.contains("SystemsettingSubdetailsCreate"));
}

/**
* Ensure that resources not directly related to the webservices.rest package are successfully
* defined in the swagger documentation.
Expand All @@ -281,24 +293,82 @@ public void testUnrelatedResourceDefinitions() {
UnrelatedGenericChildResource.getGETCalled = false;
UnrelatedGenericChildResource.getCREATECalled = false;
UnrelatedGenericChildResource.getUPDATECalled = false;

// make sure to reset the cache for multiple tests in the same run
if (SwaggerSpecificationCreator.isCached()) {
SwaggerSpecificationCreator.clearCache();
}

SwaggerSpecificationCreator ssc = new SwaggerSpecificationCreator();
ssc.getJSON();

// check our custom methods were called
assertTrue(UnrelatedGenericChildResource.getGETCalled);
assertTrue(UnrelatedGenericChildResource.getCREATECalled);
assertTrue(UnrelatedGenericChildResource.getUPDATECalled);

// assert the definition is now in the swagger object
Swagger swagger = ssc.getSwagger();
assertTrue(swagger.getDefinitions().containsKey("UnrelatedGet"));
assertTrue(swagger.getDefinitions().containsKey("UnrelatedUpdate"));
assertTrue(swagger.getDefinitions().containsKey("UnrelatedCreate"));
}

@Test
public void generateGETModel_shouldCheckForOpenMRSResource() {
Model model = SwaggerGenerationUtil.generateGETModel(new ObsResource1_8(), Representation.DEFAULT);
Assert.assertTrue(model instanceof ModelImpl);

Map<String, Property> propertyMap = model.getProperties();
Assert.assertTrue(propertyMap.containsKey("location"));
Assert.assertTrue(propertyMap.containsKey("person"));
Assert.assertTrue(propertyMap.containsKey("obsDatetime"));
Assert.assertTrue(propertyMap.containsKey("accessionNumber"));

Assert.assertTrue(propertyMap.get("location") instanceof RefProperty);
Assert.assertTrue(propertyMap.get("person") instanceof RefProperty);
Assert.assertTrue(propertyMap.get("obsDatetime") instanceof DateProperty);
Assert.assertTrue(propertyMap.get("accessionNumber") instanceof StringProperty);

Property property = propertyMap.get("encounter");
Assert.assertTrue(property instanceof RefProperty);
RefProperty stringProperty = (RefProperty) property;
assertEquals("#/definitions/EncounterGet", stringProperty.get$ref());
}

@Test
public void generateGETModel_shouldReturnAnArrayPropertyWithRefPropertyWhenFieldIsASet() {
Model model = SwaggerGenerationUtil.generateGETModel(new PersonResource1_8(), Representation.DEFAULT);
Assert.assertTrue(model instanceof ModelImpl);

Map<String, Property> propertyMap = model.getProperties();
System.out.println(propertyMap);
Assert.assertTrue(propertyMap.containsKey("attributes"));

Property property = propertyMap.get("attributes");
Assert.assertTrue(property instanceof ArrayProperty);
ArrayProperty arrayProperty = (ArrayProperty) property;
Assert.assertTrue(arrayProperty.getItems() instanceof RefProperty);

RefProperty refProperty = (RefProperty) arrayProperty.getItems();
assertEquals("#/definitions/PersonAttributeGet", refProperty.get$ref());
}

@Test
public void generateGETModelPatient_shouldReturnAnArrayPropertyWithRefPropertyWhenFieldIsASet() {
Model model = SwaggerGenerationUtil.generateGETModel(new PatientResource1_8(), Representation.DEFAULT);
Assert.assertTrue(model instanceof ModelImpl);

Map<String, Property> propertyMap = model.getProperties();
System.out.println(propertyMap);
Assert.assertTrue(propertyMap.containsKey("identifiers"));

Property property = propertyMap.get("identifiers");
Assert.assertTrue(property instanceof ArrayProperty);
ArrayProperty arrayProperty = (ArrayProperty) property;
Assert.assertTrue(arrayProperty.getItems() instanceof RefProperty);

RefProperty refProperty = (RefProperty) arrayProperty.getItems();
assertEquals("#/definitions/PatientIdentifierGet", refProperty.get$ref());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,12 @@ public void purge(SubDetails delegate, RequestContext context) throws ResponseEx
public DelegatingResourceDescription getRepresentationDescription(Representation rep) {
return new DelegatingResourceDescription();
}


@Override
public DelegatingResourceDescription getCreatableProperties() throws ResourceDoesNotSupportOperationException {
return new DelegatingResourceDescription();
}

@Override
public SubDetails newDelegate() {
return new SubDetails();
Expand Down
Loading

0 comments on commit fb399b3

Please sign in to comment.