diff --git a/core/build.gradle.kts b/core/build.gradle.kts index 5012338..1a8afeb 100644 --- a/core/build.gradle.kts +++ b/core/build.gradle.kts @@ -53,6 +53,11 @@ micronaut { apiNameSuffix = "Client" alwaysUseGenerateHttpResponse = true additionalProperties.put("retryable", "true") +// https://github.com/micronaut-projects/micronaut-openapi/discussions/1783 + schemaMapping.put("EventType", "org.justserve.model.EventType") + importMapping.put("EventType", "org.justserve.model.EventType") + schemaMapping.put("ProjectLocationType", "org.justserve.model.ProjectLocationType") + importMapping.put("ProjectLocationType", "org.justserve.model.ProjectLocationType") } } processing { diff --git a/core/src/main/java/org/justserve/client/GraphQLClient.java b/core/src/main/java/org/justserve/client/GraphQLClient.java new file mode 100644 index 0000000..d96cad8 --- /dev/null +++ b/core/src/main/java/org/justserve/client/GraphQLClient.java @@ -0,0 +1,148 @@ +package org.justserve.client; + +import io.micronaut.http.annotation.Body; +import io.micronaut.http.annotation.Consumes; +import io.micronaut.http.annotation.Post; +import io.micronaut.http.annotation.Produces; +import io.micronaut.http.client.annotation.Client; +import io.micronaut.retry.annotation.Retryable; +import org.justserve.model.*; + +@Produces("application/json") +@Consumes("application/graphql-response+json; charset=utf-8") +@Retryable +@Client("justserve") +public interface GraphQLClient { + + @Post("/graphql") + @Consumes("application/graphql-response+json") + GraphQLResponse executeAddProjectAttachment(@Body GraphQLAddProjectAttachmentRequest request); + + @Post("/graphql") + @Consumes("application/graphql-response+json") + GraphQLResponse executeAddProjectOrganization(@Body GraphQLAddProjectOrganizationRequest request); + + @Post("/graphql") + @Consumes("application/graphql-response+json") + GraphQLResponse executeCombinedMutationUpdateProjectAddProjectTag(@Body GraphQLCombinedMutationUpdateProjectAddProjectTagRequest request); + + @Post("/graphql") + @Consumes("application/graphql-response+json") + GraphQLResponse executeCreateEvent(@Body GraphQLCreateEventRequest request); + + @Post("/graphql") + @Consumes("application/graphql-response+json") + GraphQLResponse executeCreateProject(@Body GraphQLCreateProjectRequest request); + + @Post("/graphql") + @Consumes("application/graphql-response+json") + GraphQLResponse executePublishProject(@Body GraphQLPublishProjectRequest request); + + @Post("/graphql") + @Consumes("application/graphql-response+json") + GraphQLResponse executeSearchOrganization(@Body GraphQLSearchOrganizationRequest request); + + @Post("/graphql") + @Consumes("application/graphql-response+json") + GraphQLResponse executeSetProjectLocation(@Body GraphQLSetProjectLocationRequest request); + + @Post("/graphql") + @Consumes("application/graphql-response+json") + GraphQLResponse executeUpdateProjectAttachment(@Body GraphQLUpdateProjectAttachmentRequest request); + + @Post("/graphql") + @Consumes("application/graphql-response+json") + GraphQLResponse executeUpdateProjectListing(@Body GraphQLUpdateProjectListingRequest request); + + @Post("/graphql") + @Consumes("application/graphql-response+json") + GraphQLResponse executeUpdateProject(@Body GraphQLUpdateProjectRequest request); + + default GraphQLResponse addProjectAttachment(GraphQLAddProjectAttachmentVariables variables) { + String fixedQuery = "mutation ($projectId: ID!, $attachmentId: ID!) {\n addProjectAttachment(projectId: $projectId, attachmentId: $attachmentId) {\n attachmentId\n }\n }"; + GraphQLAddProjectAttachmentRequest request = new GraphQLAddProjectAttachmentRequest(); + request.setQuery(fixedQuery); + request.setVariables(variables); + return this.executeAddProjectAttachment(request); + } + + default GraphQLResponse addProjectOrganization(GraphQLAddProjectOrganizationVariables variables) { + String fixedQuery = "mutation addProjectOrganization($organizationId: ID!, $projectId: ID!) {\n addProjectOrganization(organizationId: $organizationId, projectId: $projectId) {\n id\n organizations {\n id\n name\n }\n }\n }"; + GraphQLAddProjectOrganizationRequest request = new GraphQLAddProjectOrganizationRequest(); + request.setQuery(fixedQuery); + request.setVariables(variables); + return this.executeAddProjectOrganization(request); + } + + default GraphQLResponse combinedMutationUpdateProjectAddProjectTag(GraphQLCombinedMutationUpdateProjectAddProjectTagVariables variables) { + String fixedQuery = "mutation combinedMutation($projectId: ID!, $modify: UpdateProjectInput!) {\n updateProject(\n id: $projectId,\n modify: $modify\n ) {\n id\n wheelchairAccessible\n itemDonations\n indoors\n longDescription\n shortDescription\n sponsorUserId\n groupProjects\n }\n\n skill0: addProjectTag(\n projectId: $projectId\n tagId: 31\n ) {\n id\n tags {\n id\n tagType\n tagTypeId\n translations(languageId: 1) {\n description\n label\n languageId\n }\n }\n }\nskill1: addProjectTag(\n projectId: $projectId\n tagId: 46\n ) {\n id\n tags {\n id\n tagType\n tagTypeId\n translations(languageId: 1) {\n description\n label\n languageId\n }\n }\n }\n\n interest0: addProjectTag(\n projectId: $projectId\n tagId: 11\n ) {\n id\n tags {\n id\n tagType\n tagTypeId\n translations(languageId: 1) {\n description\n label\n languageId\n }\n }\n }\ninterest1: addProjectTag(\n projectId: $projectId\n tagId: 26\n ) {\n id\n tags {\n id\n tagType\n tagTypeId\n translations(languageId: 1) {\n description\n label\n languageId\n }\n }\n }\n }"; + GraphQLCombinedMutationUpdateProjectAddProjectTagRequest request = new GraphQLCombinedMutationUpdateProjectAddProjectTagRequest(); + request.setQuery(fixedQuery); + request.setVariables(variables); + return this.executeCombinedMutationUpdateProjectAddProjectTag(request); + } + + default GraphQLResponse createEvent(GraphQLCreateEventVariables variables) { + String fixedQuery = "mutation createEvent($projectId: ID!, $projectEvent: UpdateProjectEventInput!) {\n createEvent(\n projectId: $projectId\n projectEvent: $projectEvent\n ) {\n id\n projectId\n contactEmail\n contactName\n contactPhone\n start\n end\n groupCap\n groupLimit\n timezone\n totalVolunteersNeeded\n volunteerCap\n }\n }"; + GraphQLCreateEventRequest request = new GraphQLCreateEventRequest(); + request.setQuery(fixedQuery); + request.setVariables(variables); + return this.executeCreateEvent(request); + } + + default GraphQLResponse createProject(GraphQLCreateProjectVariables variables) { + String fixedQuery = "mutation createProject($title: String!, $eventType: ProjectType!, $locationType: ProjectLocationType!, $redirect: String) {\n createProject(\n title: $title\n eventType: $eventType\n locationType: $locationType\n redirect: $redirect\n ) {\n id\n title\n typeId\n locationTypeId\n externalVolunteerUrl\n statusId\n }\n }"; + GraphQLCreateProjectRequest request = new GraphQLCreateProjectRequest(); + request.setQuery(fixedQuery); + request.setVariables(variables); + return this.executeCreateProject(request); + } + + default GraphQLResponse publishProject(GraphQLPublishProjectVariables variables) { + String fixedQuery = "mutation ($projectId: ID!){\n publishProject(projectId: $projectId) {\n id\n statusId\n }\n }"; + GraphQLPublishProjectRequest request = new GraphQLPublishProjectRequest(); + request.setQuery(fixedQuery); + request.setVariables(variables); + return this.executePublishProject(request); + } + + default GraphQLResponse searchOrganization(GraphQLSearchOrganizationVariables variables) { + String fixedQuery = "\n query organization(\n $searchTerm: String!\n $includeAll: Boolean\n $activeOnly: Boolean\n ) {\n adminOrganizationSearchByTitle(\n activeOnly: $activeOnly\n includeAll: $includeAll\n title: $searchTerm\n ) {\n id\n name\n logo\n description\n contactName\n contactPhone\n contactEmail\n url\n location {\n displayCity\n displayState\n }\n }\n }\n "; + GraphQLSearchOrganizationRequest request = new GraphQLSearchOrganizationRequest(); + request.setQuery(fixedQuery); + request.setVariables(variables); + return this.executeSearchOrganization(request); + } + + default GraphQLResponse setProjectLocation(GraphQLSetProjectLocationVariables variables) { + String fixedQuery = "mutation setProjectLocation($projectId: ID!, $location: String, $locationData: LocationDataInput) {\n setProjectLocation(\n projectId: $projectId\n location: $location\n locationData: $locationData\n ) {\n displayAddress\n displayAddress2\n displayCity\n displayCountry\n displayCountryCode\n displayCounty\n displayNeighborhood\n displayPostalCode\n displayState\n id\n latitude\n locationDetails\n locationName\n longitude\n maxLatitude\n maxLongitude\n minLatitude\n minLongitude\n timezone\n civicGeography {\n state {\n code\n }\n }\n churchGeography {\n areaUnitId\n ccUnitId\n missionUnitId\n stakeUnitId\n }\n }\n }"; + GraphQLSetProjectLocationRequest request = new GraphQLSetProjectLocationRequest(); + request.setQuery(fixedQuery); + request.setVariables(variables); + return this.executeSetProjectLocation(request); + } + + default GraphQLResponse updateProjectAttachment(GraphQLUpdateProjectAttachmentVariables variables) { + String fixedQuery = "mutation ($attachmentId: ID!, $title: String!, $description: String!) {\n updateProjectAttachment(attachmentId: $attachmentId, title: $title, description: $description) {\n attachmentId\n }\n }"; + GraphQLUpdateProjectAttachmentRequest request = new GraphQLUpdateProjectAttachmentRequest(); + request.setQuery(fixedQuery); + request.setVariables(variables); + return this.executeUpdateProjectAttachment(request); + } + + default GraphQLResponse updateProjectListing(GraphQLUpdateProjectListingVariables variables) { + String fixedQuery = "mutation listing ($projectId: ID!, $unlisted: Boolean!) {\n updateProjectListing(projectId: $projectId, unlisted: $unlisted) {\n id\n unlisted\n }\n }"; + GraphQLUpdateProjectListingRequest request = new GraphQLUpdateProjectListingRequest(); + request.setQuery(fixedQuery); + request.setVariables(variables); + return this.executeUpdateProjectListing(request); + } + + default GraphQLResponse updateProject(GraphQLUpdateProjectVariables variables) { + String fixedQuery = "mutation ($projectId: ID!, $logo: String!) {\n updateProject(id: $projectId, modify: { logo: $logo }) {\n id\n logo\n }\n }"; + GraphQLUpdateProjectRequest request = new GraphQLUpdateProjectRequest(); + request.setQuery(fixedQuery); + request.setVariables(variables); + return this.executeUpdateProject(request); + } +} diff --git a/core/src/main/java/org/justserve/model/EventType.java b/core/src/main/java/org/justserve/model/EventType.java new file mode 100644 index 0000000..82d42df --- /dev/null +++ b/core/src/main/java/org/justserve/model/EventType.java @@ -0,0 +1,59 @@ +package org.justserve.model; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; +import io.micronaut.serde.annotation.Serdeable; +import jakarta.annotation.Generated; +import lombok.RequiredArgsConstructor; + +import java.util.Arrays; +import java.util.Map; +import java.util.function.Function; +import java.util.stream.Collectors; + +/** + * Gets or Sets EventType + */ +@RequiredArgsConstructor +@Serdeable +@Generated("io.micronaut.openapi.generator.JavaMicronautClientCodegen") +public enum EventType { +// None(0, "None"), + DTL(1, "DTL"), + Ongoing(2, "ONGOING"), + Recurring(3, "RECURRING"), + MultipleDTL(4, "MULTIPLE_DTL"); + + public static final Map VALUE_MAPPING = Map.copyOf(Arrays.stream(values()) + .collect(Collectors.toMap(v -> v.intValue, Function.identity()))); + + private final Integer intValue; + private final String stringValue; + + @Override + public String toString() { + return String.valueOf(intValue); + } + + @JsonValue + public String getStringValue() { + return stringValue; + } + + // 2. RECEIVING (Response): This catches the incoming data. + // It can handle the Integer '1' from GraphQL, or even a String if a REST endpoint sends one. + @JsonCreator + public static EventType fromValue(Object value) { + if (value instanceof Number) { + int intVal = ((Number) value).intValue(); + for (EventType type : values()) { + if (type.intValue == intVal) return type; + } + } else if (value instanceof String strVal) { + for (EventType type : values()) { + if (type.stringValue.equalsIgnoreCase(strVal)) return type; + } + } + throw new IllegalArgumentException("Unexpected value '" + value + "' for EventType"); + } +} \ No newline at end of file diff --git a/core/src/main/java/org/justserve/model/GraphQLRequest.java b/core/src/main/java/org/justserve/model/GraphQLRequest.java new file mode 100644 index 0000000..e9e44f2 --- /dev/null +++ b/core/src/main/java/org/justserve/model/GraphQLRequest.java @@ -0,0 +1,18 @@ +package org.justserve.model; + +import io.micronaut.serde.annotation.Serdeable; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Serdeable +@Data +@NoArgsConstructor +@AllArgsConstructor +public class GraphQLRequest { + + private String query; + + // This handles dynamic variable maps/objects + private Object variables; +} diff --git a/core/src/main/java/org/justserve/model/GraphQLResponse.java b/core/src/main/java/org/justserve/model/GraphQLResponse.java new file mode 100644 index 0000000..8f542a0 --- /dev/null +++ b/core/src/main/java/org/justserve/model/GraphQLResponse.java @@ -0,0 +1,23 @@ +package org.justserve.model; + +import io.micronaut.serde.annotation.Serdeable; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.List; + +@Serdeable +@Data +@NoArgsConstructor +@AllArgsConstructor +public class GraphQLResponse { + + private T data; + + private List errors; + + public boolean hasErrors() { + return errors != null && !errors.isEmpty(); + } +} diff --git a/core/src/main/java/org/justserve/model/ProjectLocationType.java b/core/src/main/java/org/justserve/model/ProjectLocationType.java new file mode 100644 index 0000000..049b598 --- /dev/null +++ b/core/src/main/java/org/justserve/model/ProjectLocationType.java @@ -0,0 +1,53 @@ +package org.justserve.model; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; +import io.micronaut.serde.annotation.Serdeable; +import jakarta.annotation.Generated; +import lombok.RequiredArgsConstructor; + +import java.util.Arrays; +import java.util.Map; +import java.util.function.Function; +import java.util.stream.Collectors; + +@RequiredArgsConstructor +@Serdeable +@Generated("io.micronaut.openapi.generator.JavaMicronautClientCodegen") +public enum ProjectLocationType { +// NONE(0, "NONE"), + SINGLE_LOCATION(1, "SINGLE_LOCATION"), + REGIONAL(3, "REGIONAL"), + REMOTE(4, "REMOTE"); + + public static final Map VALUE_MAPPING = Map.copyOf(Arrays.stream(values()) + .collect(Collectors.toMap(v -> v.intValue, Function.identity()))); + + private final Integer intValue; + private final String stringValue; + + @Override + public String toString() { + return String.valueOf(intValue); + } + + @JsonValue + public String getStringValue() { + return stringValue; + } + + @JsonCreator + public static ProjectLocationType fromValue(Object value) { + if (value instanceof Number) { + int intVal = ((Number) value).intValue(); + for (ProjectLocationType type : values()) { + if (type.intValue == intVal) return type; + } + } else if (value instanceof String strVal) { + for (ProjectLocationType type : values()) { + if (type.stringValue.equalsIgnoreCase(strVal)) return type; + } + } + throw new IllegalArgumentException("Unexpected value '" + value + "' for ProjectLocationType"); + } +} diff --git a/core/src/main/resources/application.yml b/core/src/main/resources/application.yml index 308c445..9bb0298 100644 --- a/core/src/main/resources/application.yml +++ b/core/src/main/resources/application.yml @@ -14,6 +14,10 @@ micronaut: enabled: true acquire-timeout: 30s max-connections: 100 + codec: + json: + additional-types: + - application/graphql-response+json justserve: token: ${:i-need-to-be-defined} jackson: diff --git a/core/src/main/resources/schema.yml b/core/src/main/resources/schema.yml index 0122c27..ae4333b 100644 --- a/core/src/main/resources/schema.yml +++ b/core/src/main/resources/schema.yml @@ -339,6 +339,183 @@ paths: components: schemas: + + GraphQLCreateEventData: + type: object + properties: + createEvent: + type: object + properties: + id: { type: string, format: uuid } + projectId: { type: string, format: uuid } + contactEmail: { type: string } + contactName: { type: string } + contactPhone: { type: string } + start: { type: string, format: date-time } + end: { type: string, format: date-time } + groupCap: { type: boolean } + groupLimit: { type: integer, format: int32 } + timezone: { type: string } + totalVolunteersNeeded: { type: integer, format: int32 } + volunteerCap: { type: boolean } + GraphQLSearchOrganizationData: + type: object + properties: + adminOrganizationSearchByTitle: + type: array + items: + type: object + properties: + id: { type: string, format: uuid } + name: { type: string } + logo: { type: string } + description: { type: string } + contactName: { type: string } + contactPhone: { type: string } + contactEmail: { type: string } + url: { type: string } + location: + type: object + properties: + displayCity: { type: string } + displayState: { type: string } + GraphQLUpdateProjectData: + type: object + properties: + updateProject: + type: object + properties: + id: { type: string, format: uuid } + logo: { type: string } + GraphQLSetProjectLocationData: + type: object + properties: + setProjectLocation: + type: object + properties: + displayAddress: { type: string } + displayAddress2: { type: string, nullable: true } + displayCity: { type: string } + displayCountry: { type: string } + displayCountryCode: { type: string } + displayCounty: { type: string } + displayNeighborhood: { type: string, nullable: true } + displayPostalCode: { type: string } + displayState: { type: string } + id: { type: string, format: uuid } + latitude: { type: number, format: double } + locationDetails: { type: string, nullable: true } + locationName: { type: string } + longitude: { type: number, format: double } + maxLatitude: { type: number, format: double } + maxLongitude: { type: number, format: double } + minLatitude: { type: number, format: double } + minLongitude: { type: number, format: double } + timezone: { type: string } + civicGeography: + type: object + properties: + state: + type: object + properties: + code: { type: string, nullable: true } + churchGeography: + type: object + properties: + areaUnitId: { type: string } + ccUnitId: { type: string } + missionUnitId: { type: string } + stakeUnitId: { type: string } + GraphQLAddProjectAttachmentData: + type: object + properties: + addProjectAttachment: + type: object + properties: + attachmentId: { type: string, format: uuid } + GraphQLAddProjectOrganizationData: + type: object + properties: + addProjectOrganization: + type: object + properties: + id: { type: string, format: uuid } + organizations: + type: array + items: + type: object + properties: + id: { type: string, format: uuid } + name: { type: string } + GraphQLCombinedMutationUpdateProjectAddProjectTagData: + type: object + properties: + updateProject: + type: object + properties: + id: { type: string, format: uuid } + wheelchairAccessible: { type: boolean } + itemDonations: { type: boolean } + indoors: { type: boolean } + longDescription: { type: string } + shortDescription: { type: string } + sponsorUserId: { type: string, format: uuid } + groupProjects: { type: boolean } + additionalProperties: + type: object + properties: + id: { type: string, format: uuid } + tags: + type: array + items: + type: object + properties: + id: { type: integer, format: int32 } + tagType: { type: string } + tagTypeId: { type: integer, format: int32 } + translations: + type: array + items: + type: object + properties: + description: { type: string, nullable: true } + label: { type: string } + languageId: { type: integer, format: int32 } + GraphQLCreateProjectData: + type: object + properties: + createProject: + type: object + properties: + id: { type: string, format: uuid } + title: { type: string } + typeId: { type: integer, format: int32 } + locationTypeId: { type: integer, format: int32 } + externalVolunteerUrl: { type: string, nullable: true } + statusId: { type: integer, format: int32 } + GraphQLPublishProjectData: + type: object + properties: + publishProject: + type: object + properties: + id: { type: string, format: uuid } + statusId: { type: integer, format: int32 } + GraphQLUpdateProjectAttachmentData: + type: object + properties: + updateProjectAttachment: + type: object + properties: + attachmentId: { type: string, format: uuid } + GraphQLUpdateProjectListingData: + type: object + properties: + updateProjectListing: + type: object + properties: + id: { type: string, format: uuid } + unlisted: { type: boolean } BoundaryUpdateRequest: type: object properties: @@ -1759,3 +1936,228 @@ components: linked: { type: boolean } logo: { type: string, nullable: true } additionalProperties: false + GraphQLAddProjectAttachmentRequest: + type: object + properties: + query: { type: string } + variables: { $ref: '#/components/schemas/GraphQLAddProjectAttachmentVariables' } + GraphQLAddProjectAttachmentVariables: + type: object + properties: + projectId: + type: string + format: uuid + attachmentId: + type: string + format: uuid + GraphQLAddProjectOrganizationRequest: + type: object + properties: + query: { type: string } + variables: { $ref: '#/components/schemas/GraphQLAddProjectOrganizationVariables' } + GraphQLAddProjectOrganizationVariables: + type: object + properties: + organizationId: + type: string + format: uuid + projectId: + type: string + format: uuid + GraphQLCombinedMutationUpdateProjectAddProjectTagRequest: + type: object + properties: + query: { type: string } + variables: { $ref: '#/components/schemas/GraphQLCombinedMutationUpdateProjectAddProjectTagVariables' } + GraphQLCombinedMutationUpdateProjectAddProjectTagVariables: + type: object + properties: + projectId: + type: string + format: uuid + modify: + type: object + properties: + indoors: + type: boolean + longDescription: + type: string + shortDescription: + type: string + sponsorUserId: + type: string + format: uuid + suitableAllAges: + type: boolean + groupProjects: + type: boolean + itemDonations: + type: boolean + wheelchairAccessible: + type: boolean + sponsorType: + type: string + GraphQLCreateEventRequest: + type: object + properties: + query: { type: string } + variables: { $ref: '#/components/schemas/GraphQLCreateEventVariables' } + GraphQLCreateEventVariables: + type: object + properties: + projectId: + type: string + format: uuid + projectEvent: + type: object + properties: + contactEmail: + type: string + contactName: + type: string + contactPhone: + type: string + end: + type: string + groupCap: + type: boolean + groupLimit: + type: integer + shiftTitle: + type: string + start: + type: string + timezone: + type: string + totalVolunteersNeeded: + type: integer + volunteerCap: + type: boolean + GraphQLCreateProjectRequest: + type: object + properties: + query: { type: string } + variables: { $ref: '#/components/schemas/GraphQLCreateProjectVariables' } + GraphQLCreateProjectVariables: + type: object + properties: + title: + type: string + eventType: + $ref: "EventType" + locationType: + $ref: "ProjectLocationType" + redirect: + type: string + GraphQLPublishProjectRequest: + type: object + properties: + query: { type: string } + variables: { $ref: '#/components/schemas/GraphQLPublishProjectVariables' } + GraphQLPublishProjectVariables: + type: object + properties: + projectId: + type: string + format: uuid + GraphQLSearchOrganizationRequest: + type: object + properties: + query: { type: string } + variables: { $ref: '#/components/schemas/GraphQLSearchOrganizationVariables' } + GraphQLSearchOrganizationVariables: + type: object + properties: + searchTerm: + type: string + includeAll: + type: boolean + GraphQLSetProjectLocationRequest: + type: object + properties: + query: { type: string } + variables: { $ref: '#/components/schemas/GraphQLSetProjectLocationVariables' } + GraphQLSetProjectLocationVariables: + type: object + properties: + projectId: + type: string + format: uuid + location: + type: string + locationData: + type: object + properties: + country: + type: string + countryCode: + type: string + state: + type: string + city: + type: string + county: + type: string + postal: + type: string + neighborhood: + type: string + latitude: + type: number + longitude: + type: number + address: + type: string + areaId: + type: string + ccId: + type: string + missionId: + type: string + stakeId: + type: string + locationDetails: + type: string + locationName: + type: string + GraphQLUpdateProjectAttachmentRequest: + type: object + properties: + query: { type: string } + variables: { $ref: '#/components/schemas/GraphQLUpdateProjectAttachmentVariables' } + GraphQLUpdateProjectAttachmentVariables: + type: object + properties: + attachmentId: + type: string + format: uuid + title: + type: string + description: + type: string + GraphQLUpdateProjectListingRequest: + type: object + properties: + query: { type: string } + variables: { $ref: '#/components/schemas/GraphQLUpdateProjectListingVariables' } + GraphQLUpdateProjectListingVariables: + type: object + properties: + projectId: + type: string + format: uuid + unlisted: + type: boolean + GraphQLUpdateProjectRequest: + type: object + properties: + query: { type: string } + variables: { $ref: '#/components/schemas/GraphQLUpdateProjectVariables' } + GraphQLUpdateProjectVariables: + type: object + properties: + projectId: + type: string + format: uuid + logo: + type: string diff --git a/core/src/test/groovy/org/justserve/GraphQLClientSpec.groovy b/core/src/test/groovy/org/justserve/GraphQLClientSpec.groovy new file mode 100644 index 0000000..02a2896 --- /dev/null +++ b/core/src/test/groovy/org/justserve/GraphQLClientSpec.groovy @@ -0,0 +1,36 @@ +package org.justserve + +import io.micronaut.test.extensions.spock.annotation.MicronautTest +import jakarta.inject.Inject +import org.justserve.client.GraphQLClient +import org.justserve.model.EventType +import org.justserve.model.GraphQLCreateProjectVariables +import org.justserve.model.ProjectLocationType +import spock.lang.Shared +import spock.lang.Specification + +@MicronautTest +class GraphQLClientSpec extends Specification { + + @Shared + @Inject + GraphQLClient client + + void "can create Project with EventType: #eventType, LocationType: #locationType, and Redirect: #redirect"(EventType eventType, ProjectLocationType locationType, String redirect) { + given: + GraphQLCreateProjectVariables args = new GraphQLCreateProjectVariables() + .setEventType(eventType) + .setLocationType(locationType) + .setTitle("this is my title") + .setRedirect(redirect) + + when: + client.createProject(args) + + then: + noExceptionThrown() + + where: + [eventType, locationType, redirect] << [EventType.values(), ProjectLocationType.values(), ["", null, "https://google.com"]].combinations() + } +}