diff --git a/CLAUDE.md b/CLAUDE.md index 130054dec..3cdfb1a51 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -57,8 +57,6 @@ mise r sakila # Start example database (Sakila) mise r jooq # Regenerate jOOQ classes from database mise r rebuild # Rebuild specific module while server is running -# For quick builds without tests/javadocs, use Maven profiles: -mvn clean install -Pquick ``` ## Testing & Important Files @@ -73,6 +71,7 @@ mvn clean install -Pquick 2. **Check pom.xml** before adding any dependencies - use what's already available 3. **Write tests** using JUnit 5 and AssertJ for all new functionality 4. **Follow the framework patterns** already established in the codebase +5. **Never use `-Pquick`, `-DskipTests`, or `-Dmaven.test.skip`** when building with tests. ## Common Tasks - **Schema changes**: Update .graphqls files → run `mvn graphitron:generate-code` diff --git a/graphitron-codegen-parent/graphitron-java-codegen/src/main/java/no/sikt/graphitron/validation/ProcessedDefinitionsValidator.java b/graphitron-codegen-parent/graphitron-java-codegen/src/main/java/no/sikt/graphitron/validation/ProcessedDefinitionsValidator.java index e4e830d10..1303c857b 100644 --- a/graphitron-codegen-parent/graphitron-java-codegen/src/main/java/no/sikt/graphitron/validation/ProcessedDefinitionsValidator.java +++ b/graphitron-codegen-parent/graphitron-java-codegen/src/main/java/no/sikt/graphitron/validation/ProcessedDefinitionsValidator.java @@ -4,6 +4,7 @@ import no.sikt.graphitron.definitions.fields.*; import no.sikt.graphitron.definitions.fields.containedtypes.FieldReference; import no.sikt.graphitron.definitions.fields.containedtypes.MutationType; +import no.sikt.graphitron.definitions.helpers.CodeReferenceWrapper; import no.sikt.graphitron.definitions.helpers.ServiceWrapper; import no.sikt.graphitron.definitions.interfaces.FieldSpecification; import no.sikt.graphitron.definitions.interfaces.GenerationField; @@ -15,6 +16,7 @@ import no.sikt.graphitron.definitions.objects.ObjectDefinition; import no.sikt.graphitron.definitions.objects.RecordObjectDefinition; import no.sikt.graphitron.definitions.sql.SQLCondition; +import no.sikt.graphitron.generators.codebuilding.VariablePrefix; import no.sikt.graphitron.generators.context.InputParser; import no.sikt.graphitron.mappings.ReflectionHelpers; import no.sikt.graphitron.mappings.TableReflection; @@ -86,6 +88,8 @@ public void validateDirectiveUsage() { validateInputFields(); validateExternalMappingReferences(); validateServiceMethods(); + validateServiceInputTypes(); + validateServiceMethodParameterTypes(); validateMutationDirectives(); validateMutationRequiredFields(); validateRecursiveRecordInputs(); @@ -765,16 +769,191 @@ private void validateExternalMappingReferences() { } private void validateServiceMethods() { - var referenceSet = GeneratorConfig.getExternalReferences(); allFields .stream() .filter(ObjectField::isGenerated) .filter(ObjectField::hasServiceReference) .map(GenerationSourceField::getExternalMethod) - .map(ServiceWrapper::getReference) - .filter(referenceSet::contains) - .filter(it -> referenceSet.getMethodsFrom(it).stream().findFirst().isEmpty()) - .forEach(it -> addErrorMessage("Service reference with name '%s' does not contain a method named '%s'.", referenceSet.getClassFrom(it), it.getMethodName())); + .filter(it -> GeneratorConfig.getExternalReferences().contains(it.getReference())) + .filter(it -> getAllOverloads(it).isEmpty()) + .forEach(it -> addErrorMessage("Service reference with name '%s' does not contain a method named '%s'.", GeneratorConfig.getExternalReferences().getClassFrom(it.getReference()), it.getReference().getMethodName())); + } + + private void validateServiceInputTypes() { + allFields + .stream() + .filter(ObjectField::isGenerated) + .filter(ObjectField::hasServiceReference) + .forEach(field -> field.getNonReservedArguments() + .stream() + .filter(schema::isInputType) + .filter(arg -> !schema.hasRecord(arg)) + .forEach(arg -> addErrorMessage( + "Input type '%s' is used as an argument on service field '%s.%s', but has neither the @table nor the @record directive. " + + "Input types on @service operations must have one of these directives.", + arg.getTypeName(), + field.getContainerTypeName(), + field.getName() + )) + ); + } + + private void validateServiceMethodParameterTypes() { + allFields + .stream() + .filter(ObjectField::isGenerated) + .filter(ObjectField::hasServiceReference) + .filter(field -> field.getNonReservedArguments() + .stream() + .filter(schema::isInputType) + .allMatch(schema::hasRecord)) + .forEach(this::checkServiceParameterTypes); + } + + private void checkServiceParameterTypes(ObjectField field) { + var serviceWrapper = field.getExternalMethod(); + var method = serviceWrapper.getMethod(); + if (method == null) { + return; // Method not resolved — handled by validateServiceMethods() + } + + var parser = new InputParser(field, schema); + var resolverKeyOffset = field.isRootField() ? 0 : 1; + + if (hasParameterCountMismatch(field, serviceWrapper, method, parser, resolverKeyOffset)) return; + + validateRecordParameterTypes(field, serviceWrapper, method, parser, resolverKeyOffset); + } + + private boolean hasParameterCountMismatch(ObjectField field, CodeReferenceWrapper serviceWrapper, + Method method, InputParser parser, int resolverKeyOffset) { + var expectedParamCount = resolverKeyOffset + parser.getMethodInputNames(true, true, true).size(); + if (method.getParameterTypes().length == expectedParamCount) { + return false; + } + var overloads = getAllOverloads(serviceWrapper); + if (overloads.stream().noneMatch(o -> o.getParameterTypes().length == expectedParamCount)) { + addErrorMessage( + "Service field '%s.%s' maps to %d method parameter(s) but there is no overload of '%s' with that parameter count. Available overloads:\n%s", + field.getContainerTypeName(), + field.getName(), + expectedParamCount, + serviceWrapper.getMethodName(), + formatOverloads(overloads, serviceWrapper.getMethodName()) + ); + } + return true; + } + + private void validateRecordParameterTypes(ObjectField field, CodeReferenceWrapper serviceWrapper, + Method method, InputParser parser, int resolverKeyOffset) { + var allMethodInputs = parser.getMethodInputNames(false, false, false); + + for (var entry : parser.getRecords().entrySet()) { + var varName = entry.getKey(); + var inputField = entry.getValue(); + + var posInInputs = allMethodInputs.indexOf(VariablePrefix.inputPrefix(varName)); + if (posInInputs < 0) { + continue; + } + var methodParamIndex = resolverKeyOffset + posInInputs; + + var inputDef = schema.getInputType(inputField); + if (inputDef == null || !inputDef.hasRecordReference()) { + continue; + } + var inputClass = inputDef.getRecordReference(); + if (inputClass == null) { + continue; + } + + var inputIsListed = inputField.isIterableWrapped(); + if (!isParameterCompatible(method, methodParamIndex, inputClass, inputIsListed)) { + var overloads = getAllOverloads(serviceWrapper); + if (overloads.stream().noneMatch(o -> isParameterCompatible(o, methodParamIndex, inputClass, inputIsListed))) { + addErrorMessage( + "Argument '%s' on service field '%s.%s' has input type '%s' which maps to '%s', " + + "but there is no overload of '%s' that accepts this. Available overloads:\n%s", + inputField.getName(), + field.getContainerTypeName(), + field.getName(), + inputField.getTypeName(), + formatExpectedType(inputClass, inputIsListed), + serviceWrapper.getMethodName(), + formatOverloads(overloads, serviceWrapper.getMethodName()) + ); + } + } + } + } + + private boolean isParameterCompatible(Method method, int paramIndex, Class inputClass, boolean inputIsListed) { + var paramTypes = method.getParameterTypes(); + if (paramIndex >= paramTypes.length) { + return false; + } + if (inputIsListed != List.class.isAssignableFrom(paramTypes[paramIndex])) { + return false; + } + var effectiveType = getEffectiveParameterType(method, paramIndex, inputIsListed); + return effectiveType != null && effectiveType.isAssignableFrom(inputClass); + } + + private String formatExpectedType(Class inputClass, boolean isListed) { + return isListed ? "List<" + inputClass.getSimpleName() + ">" : inputClass.getSimpleName(); + } + + private List getAllOverloads(CodeReferenceWrapper serviceWrapper) { + return GeneratorConfig.getExternalReferences().getMethodsFrom(serviceWrapper.getReference()); + } + + private Class getEffectiveParameterType(Method method, int paramIndex, boolean isListed) { + var paramTypes = method.getParameterTypes(); + if (paramIndex >= paramTypes.length) { + return null; + } + if (!isListed) { + return paramTypes[paramIndex]; + } + var genericTypes = method.getGenericParameterTypes(); + if (paramIndex < genericTypes.length + && genericTypes[paramIndex] instanceof ParameterizedType pt + && pt.getActualTypeArguments().length > 0 + && pt.getActualTypeArguments()[0] instanceof Class elementType) { + return elementType; + } + return null; + } + + private String formatOverloads(List overloads, String methodName) { + if (overloads.isEmpty()) { + return " (no overloads found)"; + } + return overloads.stream() + .map(m -> " " + formatMethodSignature(m, methodName)) + .collect(Collectors.joining("\n")); + } + + private String formatMethodSignature(Method method, String methodName) { + var params = Arrays.stream(method.getGenericParameterTypes()) + .map(this::formatTypeName) + .collect(Collectors.joining(", ")); + return methodName + "(" + params + ")"; + } + + private String formatTypeName(Type type) { + if (type instanceof ParameterizedType pt) { + var raw = ((Class) pt.getRawType()).getSimpleName(); + var args = Arrays.stream(pt.getActualTypeArguments()) + .map(this::formatTypeName) + .collect(Collectors.joining(", ")); + return raw + "<" + args + ">"; + } + if (type instanceof Class cls) { + return cls.getSimpleName(); + } + return type.getTypeName(); } private void validateUnionFieldsTable() { diff --git a/graphitron-codegen-parent/graphitron-java-codegen/src/test/java/no/sikt/graphitron/codereferences/services/JavaRecordInputFetchService.java b/graphitron-codegen-parent/graphitron-java-codegen/src/test/java/no/sikt/graphitron/codereferences/services/JavaRecordInputFetchService.java index e4f756aab..33a05cc9f 100644 --- a/graphitron-codegen-parent/graphitron-java-codegen/src/test/java/no/sikt/graphitron/codereferences/services/JavaRecordInputFetchService.java +++ b/graphitron-codegen-parent/graphitron-java-codegen/src/test/java/no/sikt/graphitron/codereferences/services/JavaRecordInputFetchService.java @@ -1,6 +1,7 @@ package no.sikt.graphitron.codereferences.services; import no.sikt.graphitron.codereferences.dummyreferences.DummyRecord; +import no.sikt.graphitron.codereferences.records.CustomerJavaRecord; import no.sikt.graphitron.jooq.generated.testdata.public_.tables.records.CustomerRecord; import org.jooq.DSLContext; @@ -12,7 +13,7 @@ public class JavaRecordInputFetchService { public JavaRecordInputFetchService(DSLContext context) {} - public CustomerRecord customer(String id, DummyRecord record) { + public CustomerRecord customer(CustomerJavaRecord record) { return null; } diff --git a/graphitron-codegen-parent/graphitron-java-codegen/src/test/java/no/sikt/graphitron/codereferences/services/MapperFetchService.java b/graphitron-codegen-parent/graphitron-java-codegen/src/test/java/no/sikt/graphitron/codereferences/services/MapperFetchService.java index 15758fbbc..ca8aa4762 100644 --- a/graphitron-codegen-parent/graphitron-java-codegen/src/test/java/no/sikt/graphitron/codereferences/services/MapperFetchService.java +++ b/graphitron-codegen-parent/graphitron-java-codegen/src/test/java/no/sikt/graphitron/codereferences/services/MapperFetchService.java @@ -6,6 +6,7 @@ import org.jooq.DSLContext; import java.util.List; +import java.util.Set; /** * Fake service for mapper tests. Does not need to return meaningful values as only the generated result is tested. @@ -21,7 +22,7 @@ public List customerJavaQuery() { return null; } - public CustomerJavaRecord fetchCustomerDetails() { + public CustomerJavaRecord fetchCustomerDetails(Set resolverKeys) { return null; } diff --git a/graphitron-codegen-parent/graphitron-java-codegen/src/test/java/no/sikt/graphitron/codereferences/services/TypeMismatchService.java b/graphitron-codegen-parent/graphitron-java-codegen/src/test/java/no/sikt/graphitron/codereferences/services/TypeMismatchService.java new file mode 100644 index 000000000..ae92f116f --- /dev/null +++ b/graphitron-codegen-parent/graphitron-java-codegen/src/test/java/no/sikt/graphitron/codereferences/services/TypeMismatchService.java @@ -0,0 +1,45 @@ +package no.sikt.graphitron.codereferences.services; + +import no.sikt.graphitron.jooq.generated.testdata.public_.tables.records.AddressRecord; +import no.sikt.graphitron.jooq.generated.testdata.public_.tables.records.CustomerRecord; + +import java.util.List; + +/** + * Test service for validating parameter type mismatch detection. + * Methods have unambiguous parameter types (no overloads sharing the same name). + */ +public class TypeMismatchService { + public String check(CustomerRecord record) { + return null; + } + + public String checkNested(CustomerRecord customer, AddressRecord address) { + return null; + } + + public String checkNested(CustomerRecord customer, AddressRecord address, CustomerRecord customer2) { + return null; + } + + public String checkNestedWrongCount(CustomerRecord customer, AddressRecord address, CustomerRecord customer2) { + return null; + } + + public String checkString(String wrongType) { + return null; + } + + public String checkList(List records) { + return null; + } + + public String checkIncorrect(List wrongType) { + return null; + } + + public String checkAllInputFeatures(CustomerRecord input, String order, int first, String after, String ctx1, String ctx2) { + return null; + } + +} diff --git a/graphitron-codegen-parent/graphitron-java-codegen/src/test/java/no/sikt/graphitron/validation/UnknownTest.java b/graphitron-codegen-parent/graphitron-java-codegen/src/test/java/no/sikt/graphitron/validation/UnknownTest.java index 8072968b9..91d117848 100644 --- a/graphitron-codegen-parent/graphitron-java-codegen/src/test/java/no/sikt/graphitron/validation/UnknownTest.java +++ b/graphitron-codegen-parent/graphitron-java-codegen/src/test/java/no/sikt/graphitron/validation/UnknownTest.java @@ -327,10 +327,104 @@ void javaRecordInputJooqRecordOutput() { assertNoWarnings(); } + @Test + @DisplayName("Service input type missing @table or @record directive") + void serviceInputMissingDirective() { + assertErrorsContain("serviceInputMissingDirective", + "Input type 'TestInput' is used as an argument on service field 'Query.test', but has neither the @table nor the @record directive."); + } + + @Test + @DisplayName("Service input type with @record maps to incompatible class") + void serviceInputTypeMismatch() { + assertErrorsContain("serviceInputTypeMismatch", + "on service field 'Query.test'", + "has input type 'TestInput' which maps to 'CustomerJavaRecord'", + "but there is no overload of 'check' that accepts this", + "check(CustomerRecord)"); + } + + @Test + @DisplayName("Service input type with @table maps to incompatible class") + void serviceInputTableTypeMismatch() { + assertErrorsContain("serviceInputTableTypeMismatch", + "on service field 'Query.test'", + "has input type 'TestInput' which maps to 'CustomerRecord'", + "but there is no overload of 'checkString' that accepts this", + "checkString(String)"); + } + + @Test + @DisplayName("Service input type with valid @table directive does not produce false positive") + void serviceInputValidRecord() { + getProcessedSchema("serviceInputValidRecord"); + assertNoWarnings(); + } + + @Test + @DisplayName("Nested @table input with another @table field does not produce false positive") + void serviceInputNestedTableWithRecord() { + getProcessedSchema("serviceInputNestedTableWithRecord"); + assertNoWarnings(); + } + + @Test + @DisplayName("Nested @table input with extra method parameter triggers count mismatch") + void serviceInputCountMismatch() { + assertErrorsContain("serviceInputCountMismatch", + "Service field 'Query.test' maps to 2 method parameter(s)", + "but there is no overload of 'checkNestedWrongCount' with that parameter count", + "checkNestedWrongCount(CustomerRecord, AddressRecord, CustomerRecord)"); + } + + @Test + @DisplayName("Listed @table input with valid service method does not produce false positive") + void serviceInputListedTable() { + getProcessedSchema("serviceInputListedTable"); + assertNoWarnings(); + } + + @Test + @DisplayName("Listed @table input with incompatible service method element type") + void serviceInputListedTableTypeMismatch() { + assertErrorsContain("serviceInputListedTableTypeMismatch", + "on service field 'Query.test'", + "has input type 'TestInput' which maps to 'List'", + "but there is no overload of 'checkIncorrect' that accepts this", + "checkIncorrect(List)"); + } + + @Test + @DisplayName("Listed input but service method expects non-list parameter") + void serviceInputListedNonListParam() { + assertErrorsContain("serviceInputListedNonListParam", + "on service field 'Query.test'", + "has input type 'TestInput' which maps to 'List'", + "but there is no overload of 'check' that accepts this", + "check(CustomerRecord)"); + } + + @Test + @DisplayName("Non-listed input but service method expects list parameter") + void serviceInputNonListedListParam() { + assertErrorsContain("serviceInputNonListedListParam", + "on service field 'Query.test'", + "has input type 'TestInput' which maps to 'CustomerRecord'", + "but there is no overload of 'checkList' that accepts this", + "checkList(List)"); + } + @Test @DisplayName("Service field on table type returning Java record should not validate record fields against table") void tableObjectWithServiceField() { getProcessedSchema("tableObjectWithServiceField", Set.of(CUSTOMER_TABLE)); assertNoWarnings(); } + + @Test + @DisplayName("Service input with ordering, pagination, and context arguments does not produce false positive") + void serviceInputCountWithAllFeatures() { + getProcessedSchema("serviceInputCountWithAllFeatures", Set.of(CUSTOMER_TABLE, PAGE_INFO)); + assertNoWarnings(); + } } diff --git a/graphitron-codegen-parent/graphitron-java-codegen/src/test/resources/validation/unknown/serviceInputCountMismatch/schema.graphqls b/graphitron-codegen-parent/graphitron-java-codegen/src/test/resources/validation/unknown/serviceInputCountMismatch/schema.graphqls new file mode 100644 index 000000000..75ba272e2 --- /dev/null +++ b/graphitron-codegen-parent/graphitron-java-codegen/src/test/resources/validation/unknown/serviceInputCountMismatch/schema.graphqls @@ -0,0 +1,12 @@ +type Query { + test(input: CustomerInput): String @service(service: {className: "no.sikt.graphitron.codereferences.services.TypeMismatchService", method: "checkNestedWrongCount"}) +} + +input CustomerInput @table(name: "CUSTOMER") { + customerId: Int @field(name: "CUSTOMER_ID") + address: AddressInput +} + +input AddressInput @table(name: "ADDRESS") { + addressId: Int @field(name: "ADDRESS_ID") +} \ No newline at end of file diff --git a/graphitron-codegen-parent/graphitron-java-codegen/src/test/resources/validation/unknown/serviceInputCountWithAllFeatures/schema.graphqls b/graphitron-codegen-parent/graphitron-java-codegen/src/test/resources/validation/unknown/serviceInputCountWithAllFeatures/schema.graphqls new file mode 100644 index 000000000..1a6a9c02f --- /dev/null +++ b/graphitron-codegen-parent/graphitron-java-codegen/src/test/resources/validation/unknown/serviceInputCountWithAllFeatures/schema.graphqls @@ -0,0 +1,35 @@ +type Query { + test(input: TestInput, orderBy: TestOrderByInput @orderBy, first: Int = 100, after: String): TestConnection @service(service: {className: "no.sikt.graphitron.codereferences.services.TypeMismatchService", method: "checkAllInputFeatures"}, contextArguments: ["ctx1", "ctx2"]) +} + +input TestInput @table(name: "CUSTOMER") { + customerId: Int @field(name: "CUSTOMER_ID") +} + +type TestConnection { + edges: [TestEdge] + pageInfo: PageInfo +} + +type TestEdge { + cursor: String + node: TestNode +} + +type TestNode @table(name: "CUSTOMER") { + customerId: Int @field(name: "CUSTOMER_ID") +} + +input TestOrderByInput { + orderByField: TestOrderByField! + direction: OrderDirection! +} + +enum TestOrderByField { + NAME @index(name: "idx_last_name") +} + +enum OrderDirection { + ASC + DESC +} diff --git a/graphitron-codegen-parent/graphitron-java-codegen/src/test/resources/validation/unknown/serviceInputListedNonListParam/schema.graphqls b/graphitron-codegen-parent/graphitron-java-codegen/src/test/resources/validation/unknown/serviceInputListedNonListParam/schema.graphqls new file mode 100644 index 000000000..573ff1775 --- /dev/null +++ b/graphitron-codegen-parent/graphitron-java-codegen/src/test/resources/validation/unknown/serviceInputListedNonListParam/schema.graphqls @@ -0,0 +1,7 @@ +type Query { + test(input: [TestInput]): String @service(service: {className: "no.sikt.graphitron.codereferences.services.TypeMismatchService", method: "check"}) +} + +input TestInput @table(name: "CUSTOMER") { + customerId: ID @field(name: "CUSTOMER_ID") +} diff --git a/graphitron-codegen-parent/graphitron-java-codegen/src/test/resources/validation/unknown/serviceInputListedTable/schema.graphqls b/graphitron-codegen-parent/graphitron-java-codegen/src/test/resources/validation/unknown/serviceInputListedTable/schema.graphqls new file mode 100644 index 000000000..d4dfffeef --- /dev/null +++ b/graphitron-codegen-parent/graphitron-java-codegen/src/test/resources/validation/unknown/serviceInputListedTable/schema.graphqls @@ -0,0 +1,7 @@ +type Query { + test(input: [TestInput]): String @service(service: {className: "no.sikt.graphitron.codereferences.services.TypeMismatchService", method: "checkList"}) +} + +input TestInput @table(name: "CUSTOMER") { + customerId: Int @field(name: "CUSTOMER_ID") +} diff --git a/graphitron-codegen-parent/graphitron-java-codegen/src/test/resources/validation/unknown/serviceInputListedTableTypeMismatch/schema.graphqls b/graphitron-codegen-parent/graphitron-java-codegen/src/test/resources/validation/unknown/serviceInputListedTableTypeMismatch/schema.graphqls new file mode 100644 index 000000000..f18d61bae --- /dev/null +++ b/graphitron-codegen-parent/graphitron-java-codegen/src/test/resources/validation/unknown/serviceInputListedTableTypeMismatch/schema.graphqls @@ -0,0 +1,7 @@ +type Query { + test(input: [TestInput]): String @service(service: {className: "no.sikt.graphitron.codereferences.services.TypeMismatchService", method: "checkIncorrect"}) +} + +input TestInput @table(name: "CUSTOMER") { + customerId: Int @field(name: "CUSTOMER_ID") +} diff --git a/graphitron-codegen-parent/graphitron-java-codegen/src/test/resources/validation/unknown/serviceInputMissingDirective/schema.graphqls b/graphitron-codegen-parent/graphitron-java-codegen/src/test/resources/validation/unknown/serviceInputMissingDirective/schema.graphqls new file mode 100644 index 000000000..500382837 --- /dev/null +++ b/graphitron-codegen-parent/graphitron-java-codegen/src/test/resources/validation/unknown/serviceInputMissingDirective/schema.graphqls @@ -0,0 +1,7 @@ +type Query { + test(input: TestInput): String @service(service: {className: "no.sikt.graphitron.codereferences.services.ResolverFetchService", method: "query"}) +} + +input TestInput { + value: String +} diff --git a/graphitron-codegen-parent/graphitron-java-codegen/src/test/resources/validation/unknown/serviceInputNestedTableWithRecord/schema.graphqls b/graphitron-codegen-parent/graphitron-java-codegen/src/test/resources/validation/unknown/serviceInputNestedTableWithRecord/schema.graphqls new file mode 100644 index 000000000..c630d71fb --- /dev/null +++ b/graphitron-codegen-parent/graphitron-java-codegen/src/test/resources/validation/unknown/serviceInputNestedTableWithRecord/schema.graphqls @@ -0,0 +1,12 @@ +type Query { + test(input: CustomerInput): String @service(service: {className: "no.sikt.graphitron.codereferences.services.TypeMismatchService", method: "checkNested"}) +} + +input CustomerInput @table(name: "CUSTOMER") { + customerId: Int @field(name: "CUSTOMER_ID") + address: AddressInput +} + +input AddressInput @table(name: "ADDRESS") { + addressId: Int @field(name: "ADDRESS_ID") +} diff --git a/graphitron-codegen-parent/graphitron-java-codegen/src/test/resources/validation/unknown/serviceInputNonListedListParam/schema.graphqls b/graphitron-codegen-parent/graphitron-java-codegen/src/test/resources/validation/unknown/serviceInputNonListedListParam/schema.graphqls new file mode 100644 index 000000000..77cfd81f5 --- /dev/null +++ b/graphitron-codegen-parent/graphitron-java-codegen/src/test/resources/validation/unknown/serviceInputNonListedListParam/schema.graphqls @@ -0,0 +1,7 @@ +type Query { + test(input: TestInput): String @service(service: {className: "no.sikt.graphitron.codereferences.services.TypeMismatchService", method: "checkList"}) +} + +input TestInput @table(name: "CUSTOMER") { + customerId: ID @field(name: "CUSTOMER_ID") +} diff --git a/graphitron-codegen-parent/graphitron-java-codegen/src/test/resources/validation/unknown/serviceInputTableTypeMismatch/schema.graphqls b/graphitron-codegen-parent/graphitron-java-codegen/src/test/resources/validation/unknown/serviceInputTableTypeMismatch/schema.graphqls new file mode 100644 index 000000000..d1bf73b0f --- /dev/null +++ b/graphitron-codegen-parent/graphitron-java-codegen/src/test/resources/validation/unknown/serviceInputTableTypeMismatch/schema.graphqls @@ -0,0 +1,7 @@ +type Query { + test(input: TestInput): String @service(service: {className: "no.sikt.graphitron.codereferences.services.TypeMismatchService", method: "checkString"}) +} + +input TestInput @table(name: "CUSTOMER") { + customerId: Int @field(name: "CUSTOMER_ID") +} diff --git a/graphitron-codegen-parent/graphitron-java-codegen/src/test/resources/validation/unknown/serviceInputTypeMismatch/schema.graphqls b/graphitron-codegen-parent/graphitron-java-codegen/src/test/resources/validation/unknown/serviceInputTypeMismatch/schema.graphqls new file mode 100644 index 000000000..ca30d6153 --- /dev/null +++ b/graphitron-codegen-parent/graphitron-java-codegen/src/test/resources/validation/unknown/serviceInputTypeMismatch/schema.graphqls @@ -0,0 +1,7 @@ +type Query { + test(input: TestInput): String @service(service: {className: "no.sikt.graphitron.codereferences.services.TypeMismatchService", method: "check"}) +} + +input TestInput @record(record: {className: "no.sikt.graphitron.codereferences.records.CustomerJavaRecord"}) { + someID: String +} diff --git a/graphitron-codegen-parent/graphitron-java-codegen/src/test/resources/validation/unknown/serviceInputValidRecord/schema.graphqls b/graphitron-codegen-parent/graphitron-java-codegen/src/test/resources/validation/unknown/serviceInputValidRecord/schema.graphqls new file mode 100644 index 000000000..deb4e6086 --- /dev/null +++ b/graphitron-codegen-parent/graphitron-java-codegen/src/test/resources/validation/unknown/serviceInputValidRecord/schema.graphqls @@ -0,0 +1,7 @@ +type Query { + test(input: TestInput): String @service(service: {className: "no.sikt.graphitron.codereferences.services.TypeMismatchService", method: "check"}) +} + +input TestInput @table(name: "CUSTOMER") { + customerId: Int @field(name: "CUSTOMER_ID") +}