/**
* This Source Code Form is subject to the terms of the Mozilla Public License,
* v. 2.0. If a copy of the MPL was not distributed with this file, You can
* obtain one at http://mozilla.org/MPL/2.0/. OpenMRS is also distributed under
* the terms of the Healthcare Disclaimer located at http://openmrs.org/license.
*
* Copyright (C) OpenMRS Inc. OpenMRS is a registered trademark and the OpenMRS
* graphic logo is a trademark of OpenMRS Inc.
*/
package org.openmrs.module.webservices.rest.web.resource.impl;
/**
* The contents of this file are subject to the OpenMRS Public License
* Version 1.0 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://license.openmrs.org
*
* Software distributed under the License is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
* License for the specific language governing rights and limitations
* under the License.
*
* Copyright (C) OpenMRS, LLC. All Rights Reserved.
*/
import org.junit.Assert;
import org.junit.Test;
import org.openmrs.api.context.Context;
import org.openmrs.module.webservices.rest.SimpleObject;
import org.openmrs.module.webservices.rest.web.Hyperlink;
import org.openmrs.module.webservices.rest.web.api.RestService;
import org.openmrs.module.webservices.rest.web.representation.Representation;
import org.openmrs.web.test.BaseModuleWebContextSensitiveTest;
import java.lang.reflect.ParameterizedType;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Locale;
/**
* Is designed to be extended by classes testing BaseDelegatingResource.
* <p>
* Typically aside from implementing abstract methods of this class, you will want to override
* {@link #validateRefRepresentation()}, {@link #validateDefaultRepresentation()} and
* {@link #validateFullRepresentation()}.
*
* @param <R> resource
* @param <T> object
*/
public abstract class BaseDelegatingResourceTest<R extends BaseDelegatingResource<T>, T> extends BaseModuleWebContextSensitiveTest {
private T object;
private R resource;
private SimpleObject representation;
/**
* Creates an instance of an object that will be used to test the resource.
*
* @return the new object
*/
public abstract T newObject();
/**
* Needs to be implemented in order to validate the display property in each representation.
* <p>
* It is called by {@link #asRepresentation_shouldReturnValidDefaultRepresentation()},
* {@link #asRepresentation_shouldReturnValidFullRepresentation()} and
* {@link #asRepresentation_shouldReturnValidRefRepresentation()} to test precisely each
* representation.
*
* @return the display property
*/
public abstract String getDisplayProperty();
/**
* Needs to be implemented in order to validate the uuid property in each representation.
* <p>
* It is called by {@link #asRepresentation_shouldReturnValidDefaultRepresentation()},
* {@link #asRepresentation_shouldReturnValidFullRepresentation()} and
* {@link #asRepresentation_shouldReturnValidRefRepresentation()}.
*
* @return the uuid property
*/
public abstract String getUuidProperty();
/**
* Validates RefRepresentation of the object returned by the resource.
* <p>
* Tests the value of the uuid and display property and the presence of a self link in the links
* property.
*
* @throws Exception
*/
public void validateRefRepresentation() throws Exception {
assertPropEquals("uuid", getUuidProperty());
assertPropEquals("display", getDisplayProperty());
assertPropPresent("links");
assertPropNotPresent("resourceVersion");
@SuppressWarnings("unchecked")
List<Hyperlink> links = (List<Hyperlink>) getRepresentation().get("links");
boolean self = false;
for (Hyperlink link : links) {
if (link.getRel().equals("self")) {
Assert.assertNotNull(link.getUri());
self = true;
break;
}
}
Assert.assertTrue(self);
}
/**
* Validates DefaultRepresentation of the object returned by the resource.
* <p>
* Tests the value of the uuid property and the presence of the links property.
*
* @throws Exception
*/
public void validateDefaultRepresentation() throws Exception {
assertPropEquals("uuid", getUuidProperty());
assertPropPresent("links");
assertPropPresent("resourceVersion");
}
/**
* Validates FullRepresentation of the object returned by the resource.
* <p>
* Tests the value of the uuid property and the presence of the links property.
*
* @throws Exception
*/
public void validateFullRepresentation() throws Exception {
assertPropEquals("uuid", getUuidProperty());
assertPropPresent("links");
assertPropPresent("resourceVersion");
}
/**
* Instantiates BaseDelegatingResource.
*
* @return the new resource
*/
public R newResource() {
ParameterizedType t = (ParameterizedType) getClass().getGenericSuperclass();
@SuppressWarnings("unchecked")
Class<T> clazz = (Class<T>) t.getActualTypeArguments()[1];
return (R) Context.getService(RestService.class).getResourceBySupportedClass(clazz);
}
/**
* Returns an instance of an object to test the resource.
*
* @return the object
*/
public T getObject() {
if (object == null) {
object = newObject();
}
Assert.assertNotNull("newObject must not return null", object);
return object;
}
/**
* Returns a created representation.
*
* @return the representation
*/
public SimpleObject getRepresentation() {
Assert.assertNotNull("representation must not be null", representation);
return representation;
}
/**
* Returns an instantiated resource.
*
* @return the resource
*/
public R getResource() {
if (resource == null) {
resource = newResource();
}
Assert.assertNotNull("newResource must not return null", resource);
return resource;
}
/**
* Creates {@link Representation#REF}.
* <p>
* Calls {@link BaseDelegatingResource#asRepresentation(Object, Representation)} on the resource
* with the given object.
*
* @return the representation
* @throws Exception
*/
public SimpleObject newRefRepresentation() throws Exception {
return getResource().asRepresentation(getObject(), Representation.REF);
}
/**
* Creates {@link Representation#DEFAULT}.
* <p>
* Calls {@link BaseDelegatingResource#asRepresentation(Object, Representation)} on the resource
* with the given object.
*
* @return the representation
* @throws Exception
*/
public SimpleObject newDefaultRepresentation() throws Exception {
return getResource().asRepresentation(getObject(), Representation.DEFAULT);
}
/**
* Creates {@link Representation#FULL}.
* <p>
* Calls {@link BaseDelegatingResource#asRepresentation(Object, Representation)} on the resource
* with the given object.
*
* @return the representation
* @throws Exception
*/
public SimpleObject getFullRepresentation() throws Exception {
return getResource().asRepresentation(getObject(), Representation.FULL);
}
/**
* Equivalent to:
* <p>
* <code>
* Assert.assertEquals(property, value, getRepresentation().get(property));
* </code>
* <p>
* Performs data conversion like formatting a date for your convenience.
*
* @param property
* @param value
*/
public void assertPropEquals(String property, Object value) {
if (value instanceof Date) {
value = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ").format((Date) value);
} else if (value instanceof Locale) {
value = value.toString();
}
Assert.assertEquals(property, value, getRepresentation().get(property));
}
/**
* Equivalent to:
* <p>
* <code>
* Assert.assertTrue(getRepresentation().containsKey(property));
* </code>
*
* @param property
*/
public void assertPropPresent(String property) {
Assert.assertTrue(getRepresentation().containsKey(property));
}
/**
* Equivalent to:
* <p>
* <code>
* Assert.assertFalse(getRepresentation().containsKey(property));
* </code>
*/
public void assertPropNotPresent(String property) {
Assert.assertFalse(getRepresentation().containsKey(property));
}
/**
* Tests {@link Representation#REF}
*
* @throws Exception
*/
@Test
public void asRepresentation_shouldReturnValidRefRepresentation() throws Exception {
representation = newRefRepresentation();
validateRefRepresentation();
}
/**
* Tests {@link Representation#DEFAULT}
*
* @throws Exception
*/
@Test
public void asRepresentation_shouldReturnValidDefaultRepresentation() throws Exception {
representation = newDefaultRepresentation();
validateDefaultRepresentation();
}
/**
* Tests {@link Representation#FULL}
*
* @throws Exception
*/
@Test
public void asRepresentation_shouldReturnValidFullRepresentation() throws Exception {
representation = getFullRepresentation();
validateFullRepresentation();
}
protected String findSelfLink(SimpleObject object) {
List<Hyperlink> links = (List<Hyperlink>) object.get("links");
for (Hyperlink link : links) {
if (link.getRel().equals("self")) {
return link.getUri();
}
}
return null;
}
}