package ca.uhn.fhir.jaxrs.server.util;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import java.util.List;
import org.junit.Before;
import org.junit.FixMethodOrder;
import org.junit.Test;
import org.junit.runners.MethodSorters;
import ca.uhn.fhir.jaxrs.server.test.TestJaxRsDummyPatientProvider;
import ca.uhn.fhir.model.dstu2.resource.Parameters;
import ca.uhn.fhir.model.dstu2.resource.Patient;
import ca.uhn.fhir.model.primitive.IdDt;
import ca.uhn.fhir.model.primitive.StringDt;
import ca.uhn.fhir.rest.annotation.IdParam;
import ca.uhn.fhir.rest.annotation.Operation;
import ca.uhn.fhir.rest.annotation.OperationParam;
import ca.uhn.fhir.rest.annotation.RequiredParam;
import ca.uhn.fhir.rest.annotation.ResourceParam;
import ca.uhn.fhir.rest.annotation.Search;
import ca.uhn.fhir.rest.annotation.Update;
import ca.uhn.fhir.rest.api.MethodOutcome;
import ca.uhn.fhir.rest.api.RestOperationTypeEnum;
import ca.uhn.fhir.rest.param.StringParam;
import ca.uhn.fhir.rest.server.exceptions.NotImplementedOperationException;
@FixMethodOrder(MethodSorters.DEFAULT)
public class JaxRsMethodBindingsTest {
@Before
public void setUp() {
JaxRsMethodBindings.getClassBindings().clear();
}
@Test(expected = NotImplementedOperationException.class)
public void testFindMethodsForProviderNotDefinedMappingMethods() {
new TestJaxRsDummyPatientProvider().getBindings().getBinding(RestOperationTypeEnum.UPDATE, "");
}
@Test
public void testFindMethodsForProviderWithMethods() {
class TestFindPatientProvider extends TestJaxRsDummyPatientProvider {
@Search
public List<Patient> search(@RequiredParam(name = Patient.SP_NAME) final StringParam name) {
return null;
}
}
new TestFindPatientProvider();
assertEquals(TestFindPatientProvider.class, new TestFindPatientProvider().getBindings().getBinding(RestOperationTypeEnum.SEARCH_TYPE, "").getMethod().getDeclaringClass());
}
@Test
public void testFindMethodsFor2ProvidersWithMethods() {
class TestFindPatientProvider extends TestJaxRsDummyPatientProvider {
@Search
public List<Patient> search(@RequiredParam(name = Patient.SP_NAME) final StringParam name) {
return null;
}
}
class TestUpdatePatientProvider extends TestJaxRsDummyPatientProvider {
@Update
public MethodOutcome update(@IdParam final IdDt theId, @ResourceParam final Patient patient) {
return null;
}
}
assertEquals(TestFindPatientProvider.class, new TestFindPatientProvider().getBindings().getBinding(RestOperationTypeEnum.SEARCH_TYPE, "").getMethod().getDeclaringClass());
assertEquals(TestUpdatePatientProvider.class, new TestUpdatePatientProvider().getBindings().getBinding(RestOperationTypeEnum.UPDATE, "").getMethod().getDeclaringClass());
}
@Test
public void testFindMethodsWithDoubleMethodsDeclaration() {
class TestDoubleSearchProvider extends TestJaxRsDummyPatientProvider {
@Search
public List<Patient> search1(@RequiredParam(name = Patient.SP_NAME) final StringParam name) {
return null;
}
@Search
public List<Patient> search2(@RequiredParam(name = Patient.SP_NAME) final StringParam name) {
return null;
}
}
try {
new TestDoubleSearchProvider();
fail();
} catch(IllegalArgumentException e) {
assertTrue(e.getMessage().contains("search1"));
assertTrue(e.getMessage().contains("search2"));
}
}
@Test
public void testFindMethodsWithMultipleMethods() {
class TestFindPatientProvider extends TestJaxRsDummyPatientProvider {
@Search
public List<Patient> search(@RequiredParam(name = Patient.SP_NAME) final StringParam name) {
return null;
}
@Update
public MethodOutcome update(@IdParam final IdDt theId, @ResourceParam final Patient patient) {
return null;
}
@Operation(name = "firstMethod", idempotent = true, returnParameters = { @OperationParam(name = "return", type = StringDt.class) })
public Parameters firstMethod(@OperationParam(name = "dummy") StringDt dummyInput) {
return null;
}
@Operation(name = "secondMethod", returnParameters = { @OperationParam(name = "return", type = StringDt.class) })
public Parameters secondMethod(@OperationParam(name = "dummy") StringDt dummyInput) {
return null;
}
}
JaxRsMethodBindings bindings = new TestFindPatientProvider().getBindings();
assertEquals("search", bindings.getBinding(RestOperationTypeEnum.SEARCH_TYPE, "").getMethod().getName());
assertEquals("update", bindings.getBinding(RestOperationTypeEnum.UPDATE, "").getMethod().getName());
assertEquals("firstMethod", bindings.getBinding(RestOperationTypeEnum.EXTENDED_OPERATION_TYPE, "$firstMethod").getMethod().getName());
assertEquals("secondMethod", bindings.getBinding(RestOperationTypeEnum.EXTENDED_OPERATION_TYPE, "$secondMethod").getMethod().getName());
try {
bindings.getBinding(RestOperationTypeEnum.EXTENDED_OPERATION_TYPE, "$thirdMethod");
fail();
} catch(NotImplementedOperationException e){
}
}
}