package de.bitdroid.jaxrs2retrofit.integration;
import com.squareup.javapoet.ClassName;
import org.glassfish.hk2.api.Factory;
import org.glassfish.hk2.api.InjectionResolver;
import org.glassfish.hk2.api.ServiceLocator;
import org.glassfish.hk2.api.TypeLiteral;
import org.glassfish.hk2.utilities.binding.AbstractBinder;
import org.glassfish.jersey.server.ResourceConfig;
import org.glassfish.jersey.server.internal.inject.AbstractValueFactoryProvider;
import org.glassfish.jersey.server.internal.inject.MultivaluedParameterExtractorProvider;
import org.glassfish.jersey.server.internal.inject.ParamInjectionResolver;
import org.glassfish.jersey.server.model.Parameter;
import org.glassfish.jersey.server.spi.internal.ValueFactoryProvider;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;
import javax.inject.Inject;
import javax.inject.Singleton;
import javax.validation.constraints.Size;
import de.bitdroid.jaxrs2retrofit.converter.AnnotatedParam;
import de.bitdroid.jaxrs2retrofit.converter.IgnoreConverter;
import de.bitdroid.jaxrs2retrofit.converter.ParamConverter;
import de.bitdroid.jaxrs2retrofit.converter.ParamConverterManager;
import de.bitdroid.jaxrs2retrofit.integration.resources.CustomAnnotation;
import de.bitdroid.jaxrs2retrofit.integration.resources.CustomAnnotationResource;
import mockit.Mocked;
import mockit.integration.junit4.JMockit;
import retrofit.http.Header;
/**
* Tests that the {@link de.bitdroid.jaxrs2retrofit.integration.resources.CustomAnnotation} is correctly converted
* to some other value.
*/
@RunWith(JMockit.class)
public final class CustomAnnotationTest extends AbstractResourceTest<CustomAnnotationResource> {
@Mocked private CustomAnnotationResource resource;
public CustomAnnotationTest() {
super(CustomAnnotationResource.class);
}
@Test
@SuppressWarnings("unchecked")
public void testDropParam() throws Exception {
clientClass.getDeclaredMethod("dropParameter");
}
@Test
@SuppressWarnings("unchecked")
public void testParamToHeaderConversion() throws Exception {
Method headerMethod = clientClass.getDeclaredMethod("convertAnnotation", String.class);
Annotation[][] annotations = headerMethod.getParameterAnnotations();
Assert.assertEquals(1, annotations.length);
Assert.assertEquals(1, annotations[0].length);
Assert.assertEquals(Header.class, annotations[0][0].annotationType());
}
@Test
@SuppressWarnings("unchecked")
public void testDropAnnotation() throws Exception {
clientClass.getDeclaredMethod("dropAnnotation", String.class);
}
@Override
protected CustomAnnotationResource getMockedResource() {
return resource;
}
@Override
protected ParamConverterManager getParamConverterManager() {
ParamConverterManager manager = super.getParamConverterManager();
manager.registerConverter(ClassName.get(Size.class), new IgnoreConverter());
manager.registerConverter(
ClassName.get(CustomAnnotation.class),
new ParamConverter() {
@Override
public AnnotatedParam convert(AnnotatedParam param) {
Map<String, Object> args = new HashMap<>();
args.put("value", "\"myHeader\"");
return new AnnotatedParam(
ClassName.get(String.class),
ClassName.get(Header.class),
args);
}
});
return manager;
}
@Override
protected ResourceConfig getResourceConfig() {
ResourceConfig config = super.getResourceConfig();
config.register(new CustomAnnotationBinder());
return config;
}
public static final class CustomAnnotationResolver extends ParamInjectionResolver<CustomAnnotation> {
public CustomAnnotationResolver() {
super(CustomAnnotationProvider.class);
}
}
public static final class CustomAnnotationProvider extends AbstractValueFactoryProvider {
@Inject
protected CustomAnnotationProvider(
MultivaluedParameterExtractorProvider mpep,
ServiceLocator locator) {
super(mpep, locator, Parameter.Source.UNKNOWN);
}
@Override
protected Factory<String> createValueFactory(Parameter parameter) {
return new Factory<String>() {
@Override
public String provide() {
return "hello world";
}
@Override
public void dispose(String instance) { }
};
}
}
public static final class CustomAnnotationBinder extends AbstractBinder {
@Override
protected void configure() {
bind(CustomAnnotationProvider.class)
.to(ValueFactoryProvider.class)
.in(Singleton.class);
bind(CustomAnnotationResolver.class)
.to(new TypeLiteral<InjectionResolver<CustomAnnotation>>() {
})
.in(Singleton.class);
}
}
}