Skip to content

Commit

Permalink
fixed adaptXXX issue
Browse files Browse the repository at this point in the history
  • Loading branch information
mskacelik committed Oct 11, 2024
1 parent 57220e0 commit 089733d
Show file tree
Hide file tree
Showing 5 changed files with 260 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -214,7 +214,7 @@ private static void populateScalar(String className, String scalarName, String e
scalarMap.put(className, reference);

// looking up by name
scalarNameMap.put(scalarName, reference);
scalarNameMap.putIfAbsent(scalarName, reference);

//Currently, each scalar is formatted as String
formattedScalarMap.put(className, new Reference.Builder()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -989,7 +989,7 @@ private GraphQLInputObjectField createGraphQLInputObjectFieldFromField(Field fie

private GraphQLInputType createGraphQLInputType(Field field) {

GraphQLInputType graphQLInputType = getGraphQLInputType(field.getReference());
GraphQLInputType graphQLInputType = referenceGraphQLInputType(field);
Wrapper wrapper = dataFetcherFactory.unwrap(field, false);
// Field can have a wrapper, like List<String>
if (wrapper != null && wrapper.isCollectionOrArrayOrMap()) {
Expand Down Expand Up @@ -1047,6 +1047,11 @@ private GraphQLOutputType createGraphQLOutputType(Field field, boolean isBatch)
return graphQLOutputType;
}

private GraphQLInputType referenceGraphQLInputType(Field field) {
Reference reference = getCorrectFieldReference(field);
return getGraphQLInputType(reference);
}

private GraphQLOutputType referenceGraphQLOutputType(Field field) {
Reference reference = getCorrectFieldReference(field);
ReferenceType type = reference.getType();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@ private Object adaptInputTo(Field field, Object object) {
if (methodName != null && !methodName.isEmpty()) {
Class<?> mappingClass = classloadingService.loadClass(field.getReference().getClassName());
try {
if (methodName.equals(CONTRUCTOR_METHOD_NAME)) {
if (methodName.equals(CONSTRUCTOR_METHOD_NAME)) {
// Try with contructor
Constructor<?> constructor = mappingClass.getConstructor(object.getClass());
return constructor.newInstance(object);
Expand Down Expand Up @@ -503,5 +503,5 @@ public Type[] getActualTypeArguments() {
}
}

private static final String CONTRUCTOR_METHOD_NAME = "<init>";
private static final String CONSTRUCTOR_METHOD_NAME = "<init>";
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@
import java.util.stream.Collectors;

import jakarta.annotation.security.RolesAllowed;
import jakarta.json.bind.adapter.JsonbAdapter;
import jakarta.json.bind.annotation.JsonbTypeAdapter;

import org.eclipse.microprofile.graphql.GraphQLApi;
import org.eclipse.microprofile.graphql.NonNull;
Expand All @@ -35,12 +37,17 @@
import graphql.schema.GraphQLDirective;
import graphql.schema.GraphQLEnumType;
import graphql.schema.GraphQLFieldDefinition;
import graphql.schema.GraphQLInputObjectField;
import graphql.schema.GraphQLInputObjectType;
import graphql.schema.GraphQLObjectType;
import graphql.schema.GraphQLSchema;
import graphql.schema.GraphQLUnionType;
import io.smallrye.graphql.api.AdaptToScalar;
import io.smallrye.graphql.api.AdaptWith;
import io.smallrye.graphql.api.Adapter;
import io.smallrye.graphql.api.Directive;
import io.smallrye.graphql.api.OneOf;
import io.smallrye.graphql.api.Scalar;
import io.smallrye.graphql.api.federation.Key;
import io.smallrye.graphql.api.federation.Key.Keys;
import io.smallrye.graphql.execution.SchemaPrinter;
Expand Down Expand Up @@ -515,6 +522,115 @@ void nonNullWrapperTest() {

}

public static class ModelA {
@AdaptToScalar(Scalar.String.class)
private ModelB modelB;

@AdaptWith(CustomAdapter.class)
public Collection<Long> someField;

@JsonbTypeAdapter(CustomJsonbTypeAdapter.class)
public Float myOtherField;

public ModelA() {
}

public ModelB getModelB() {
return modelB;
}

public void setModelB(ModelB modelB) {
this.modelB = modelB;
}
}

public static class ModelB {
private String id;

public ModelB() {
}

// the `ModelB` object needs to have a constructor that takes a String (or Int / Date / etc.),
// or have a setter method for the String (or Int / Date / etc.),
// or have a fromString (or fromInt / fromDate - depending on the Scalar type) static method.
public static ModelB fromString(String id) {
ModelB modelB = new ModelB();
modelB.id = id;
return modelB;
}

@Override
public String toString() {
return id;
}

public String getId() {
return id;
}

public void setId(String id) {
this.id = id;
}
}

@GraphQLApi
public static class AdaptApi {
@Query
public ModelA getSomeString(ModelA modelA) {
return modelA;
}
}

public static class CustomAdapter implements Adapter<Long, String> {

@Override
public String to(Long o) throws Exception {
return String.valueOf(o);
}

@Override
public Long from(String a) throws Exception {
return Long.parseLong(a);
}
}

public static class CustomJsonbTypeAdapter implements JsonbAdapter<Float, String> {

@Override
public String adaptToJson(Float aFloat) throws Exception {
return String.valueOf(aFloat);
}

@Override
public Float adaptFromJson(String s) throws Exception {
return Float.valueOf(s);
}
}

@Test
public void adaptTest() {
GraphQLSchema graphQLSchema = createGraphQLSchema(ModelA.class, ModelB.class, AdaptApi.class, CustomAdapter.class,
CustomJsonbTypeAdapter.class);

GraphQLFieldDefinition modelAQuery = graphQLSchema.getQueryType().getField("someString");
assertNotNull(modelAQuery);

GraphQLInputObjectType modelAInput = graphQLSchema.getTypeAs("ModelAInput");
assertNotNull(modelAInput);
assertEquals(3, modelAInput.getFields().size());
GraphQLInputObjectField modelBField = modelAInput.getField("modelB");
assertNotNull(modelBField);
assertEquals(GraphQLString, modelBField.getType());

GraphQLInputObjectField someFieldField = modelAInput.getField("someField");
assertNotNull(someFieldField);
assertEquals("[String]", someFieldField.getType().toString());

GraphQLInputObjectField myOtherFieldField = modelAInput.getField("myOtherField");
assertNotNull(myOtherFieldField);
assertEquals(GraphQLString, myOtherFieldField.getType());
}

private void assertRolesAllowedDirective(GraphQLFieldDefinition field, String roleValue) {
assertNotNull(field);

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
package io.smallrye.graphql.tests.adapting;

import static org.assertj.core.api.Assertions.assertThat;

import java.net.URL;
import java.util.Collection;

import jakarta.json.bind.adapter.JsonbAdapter;
import jakarta.json.bind.annotation.JsonbTypeAdapter;

import org.eclipse.microprofile.graphql.GraphQLApi;
import org.eclipse.microprofile.graphql.Query;
import org.jboss.arquillian.container.test.api.Deployment;
import org.jboss.arquillian.container.test.api.RunAsClient;
import org.jboss.arquillian.junit.Arquillian;
import org.jboss.arquillian.test.api.ArquillianResource;
import org.jboss.shrinkwrap.api.ShrinkWrap;
import org.jboss.shrinkwrap.api.spec.WebArchive;
import org.junit.Test;
import org.junit.runner.RunWith;

import io.smallrye.graphql.api.AdaptToScalar;
import io.smallrye.graphql.api.AdaptWith;
import io.smallrye.graphql.api.Adapter;
import io.smallrye.graphql.api.Scalar;
import io.smallrye.graphql.tests.GraphQLAssured;

@RunWith(Arquillian.class)
@RunAsClient
public class AdaptTest {

@Deployment
public static WebArchive deployment() {
return ShrinkWrap.create(WebArchive.class, "adapt-test.war")
.addClasses(ModelA.class, ModelB.class, AdaptApi.class, CustomJsonbTypeAdapter.class, CustomAdapter.class);
}

@ArquillianResource
URL testingURL;

public static class ModelA {
@AdaptToScalar(Scalar.String.class)
private ModelB modelB;

@AdaptWith(CustomAdapter.class)
public Collection<Long> someField;

@JsonbTypeAdapter(CustomJsonbTypeAdapter.class)
public String myOtherField;

public ModelA() {
}

public ModelB getModelB() {
return modelB;
}

public void setModelB(ModelB modelB) {
this.modelB = modelB;
}
}

public static class ModelB {
private String id;

public ModelB() {
}

// the `ModelB` object needs to have a constructor that takes a String (or Int / Date / etc.),
// or have a setter method for the String (or Int / Date / etc.),
// or have a fromString (or fromInt / fromDate - depending on the Scalar type) static method.
public static ModelB fromString(String id) {
ModelB modelB = new ModelB();
modelB.id = id;
return modelB;
}

@Override
public String toString() {
return id;
}

public String getId() {
return id;
}

public void setId(String id) {
this.id = id;
}
}

@GraphQLApi
public static class AdaptApi {
@Query
public ModelA getSomeString(ModelA modelA) {
return modelA;
}
}

public static class CustomAdapter implements Adapter<Long, String> {

@Override
public String to(Long o) throws Exception {
return String.valueOf(o);
}

@Override
public Long from(String a) throws Exception {
return Long.parseLong(a);
}
}

public static class CustomJsonbTypeAdapter implements JsonbAdapter<String, Long> {

@Override
public Long adaptToJson(String s) throws Exception {
return Long.parseLong(s);
}

@Override
public String adaptFromJson(Long aLong) throws Exception {
return String.valueOf(aLong);
}
}

@Test
public void adaptTest() {
GraphQLAssured graphQLAssured = new GraphQLAssured(testingURL);
assertThat(graphQLAssured
.post("query { someString(modelA: { modelB: \"3\", someField: [\"5\",\"8\"], myOtherField: 4}) { modelB someField myOtherField }}"))
.containsIgnoringWhitespaces(
"{\"data\":{\"someString\":{\"modelB\":\"3\",\"someField\":[\"5\",\"8\"],\"myOtherField\": 4}}}")
.doesNotContain("error");
}
}

0 comments on commit 089733d

Please sign in to comment.