diff --git a/cli/build.gradle.kts b/cli/build.gradle.kts index 956538c..b6db6cd 100644 --- a/cli/build.gradle.kts +++ b/cli/build.gradle.kts @@ -21,20 +21,20 @@ dependencies { annotationProcessor("io.micronaut.serde:micronaut-serde-processor") annotationProcessor("io.micronaut.validation:micronaut-validation") implementation("io.micronaut.validation:micronaut-validation") + implementation("io.micronaut.reactor:micronaut-reactor") implementation("info.picocli:picocli") - implementation("info.picocli:picocli-jansi-graalvm:1.2.0") - implementation("org.fusesource.jansi:jansi:2.4.2") - implementation("info.picocli:picocli-shell-jline3:4.7.6") - implementation("org.jline:jline:3.30.5") + implementation("info.picocli:picocli-jansi-graalvm:${project.properties["jansiGraalvmVersion"]}") + implementation("org.fusesource.jansi:jansi:${project.properties["jansiVersion"]}") + implementation("info.picocli:picocli-shell-jline3:${project.properties["picocliShellVersion"]}") + implementation("org.jline:jline:${project.properties["jlineVersion"]}") implementation("io.micronaut.picocli:micronaut-picocli") - implementation("org.simplejavamail:simple-java-mail:8.12.6") + implementation("org.simplejavamail:simple-java-mail:${project.properties["simpleJavaMailVersion"]}") implementation("io.micronaut.serde:micronaut-serde-jackson") implementation("io.micronaut:micronaut-http-client") - implementation("org.simplejavamail:simple-java-mail:8.12.6") - implementation("org.jsoup:jsoup:1.21.2") + implementation("org.jsoup:jsoup:${project.properties["jsoupVersion"]}") implementation(project(":core")) - testImplementation("net.datafaker:datafaker:2.5.1") - testImplementation("org.apache.commons:commons-lang3:3.20.0") + testImplementation("net.datafaker:datafaker:${project.properties["datafakerVersion"]}") + testImplementation("org.apache.commons:commons-lang3:${project.properties["commonsLangVersion"]}") testImplementation(project(path = ":core", configuration = "testArchives")) compileOnly("org.projectlombok:lombok") runtimeOnly("ch.qos.logback:logback-classic") diff --git a/cli/src/main/java/org/justserve/command/AssignOrgToProject.java b/cli/src/main/java/org/justserve/command/AssignOrgToProject.java index d7e2a73..89d09f0 100644 --- a/cli/src/main/java/org/justserve/command/AssignOrgToProject.java +++ b/cli/src/main/java/org/justserve/command/AssignOrgToProject.java @@ -1,7 +1,5 @@ package org.justserve.command; -import io.micronaut.http.HttpResponse; -import io.micronaut.http.HttpStatus; import io.micronaut.http.client.exceptions.HttpClientResponseException; import jakarta.inject.Inject; import jakarta.inject.Provider; @@ -39,16 +37,9 @@ public void run() { try { log.atTrace().log("Assigning organization {} to project {}", orgId, projectId); - HttpResponse response = client.assignOrganizationToProject(projectId, orgId); - if (response.status() == HttpStatus.OK) { - printNormal("Successfully assigned organization %s to project %s", orgId, projectId); - log.atTrace().log("received api response status: {}", response.status()); - } else { - printError("Failed to assign organization " + orgId + " to project " + projectId + - ". Expected HTTP Status 'OK', but got " + response.status()); - log.atError().log("Failed to assign organization {} to project {}. Expected HTTP Status 'OK', but got {}", - orgId, projectId, response.status()); - } + client.assignOrganizationToProject(projectId, orgId).block(); + printNormal("Successfully assigned organization %s to project %s", orgId, projectId); + log.atTrace().log("Successfully assigned organization to project"); } catch (HttpClientResponseException e) { printError("Failed to assign organization %s to project %s. (%s: %s)", orgId, projectId, e.getStatus().getCode(), e.getMessage()); diff --git a/cli/src/main/java/org/justserve/command/ConsoleOutput.java b/cli/src/main/java/org/justserve/command/ConsoleOutput.java index 7c47ac3..66c96e6 100644 --- a/cli/src/main/java/org/justserve/command/ConsoleOutput.java +++ b/cli/src/main/java/org/justserve/command/ConsoleOutput.java @@ -1,27 +1,6 @@ package org.justserve.command; public interface ConsoleOutput { - ConsoleOutput NOOP = new ConsoleOutput() { - @Override - public void out(String message) { } - - @Override - public void err(String message) { } - - @Override - public void warning(String message) { } - - @Override - public boolean showStacktrace() { - return false; - } - - @Override - public boolean verbose() { - return false; - } - - }; void out(String message); diff --git a/cli/src/main/java/org/justserve/command/GetTempPassword.java b/cli/src/main/java/org/justserve/command/GetTempPassword.java index 82f6b97..c2084bf 100644 --- a/cli/src/main/java/org/justserve/command/GetTempPassword.java +++ b/cli/src/main/java/org/justserve/command/GetTempPassword.java @@ -1,6 +1,5 @@ package org.justserve.command; -import io.micronaut.http.HttpResponse; import io.micronaut.http.client.exceptions.HttpClientResponseException; import jakarta.inject.Inject; import jakarta.inject.Provider; @@ -30,10 +29,10 @@ public void run() { if (isTokenInvalid()) { return; } - HttpResponse response; + String response; try { UserClient userClient = userClientProvider.get(); - response = userClient.getTempPassword(new UserHashRequestByEmail(email)); + response = userClient.getTempPassword(new UserHashRequestByEmail(email)).block(); } catch (HttpClientResponseException e) { String errorMessage = "Received an unexpected response from JustServe:" + String.format("%n%d (%s)", e.getResponse().status().getCode(), e.reason()); @@ -41,7 +40,7 @@ public void run() { return; } if (response != null) { - printNormal(response.body().replace("\"", "").trim()); + printNormal(response.replace("\"", "").trim()); } else { printError("An unexpected error occurred. Response from JustServe was null."); } diff --git a/cli/src/main/java/org/justserve/command/MakeOrgAdmin.java b/cli/src/main/java/org/justserve/command/MakeOrgAdmin.java index 9fe10dd..71eb846 100644 --- a/cli/src/main/java/org/justserve/command/MakeOrgAdmin.java +++ b/cli/src/main/java/org/justserve/command/MakeOrgAdmin.java @@ -1,7 +1,6 @@ package org.justserve.command; import io.micronaut.core.annotation.Nullable; -import io.micronaut.http.HttpResponse; import io.micronaut.http.client.exceptions.HttpClientResponseException; import jakarta.inject.Inject; import jakarta.inject.Provider; @@ -10,6 +9,7 @@ import lombok.extern.slf4j.Slf4j; import org.justserve.client.BoundaryPermissionClient; import org.justserve.client.DynamicRoutingClient; +import org.justserve.model.DynamicRoutingDataResponse; import picocli.CommandLine; import picocli.CommandLine.Command; import picocli.CommandLine.Option; @@ -47,16 +47,19 @@ public void run() { // since we allow submitting orgId's and orgUrl, convert any slugs to orgId's Map orgUuidMap = Arrays.stream(orgs).distinct().parallel() .map(org -> { - if (org instanceof OrgId) { - return new AbstractMap.SimpleEntry<>(org, ((OrgId) org).getId()); + if (org instanceof OrgId orgId) { + return new AbstractMap.SimpleEntry<>(org, orgId.getId()); } + DynamicRoutingDataResponse response; try { - return new AbstractMap.SimpleEntry<>(org, dynamicRoutingClient - .getOrgIdFromSlug(((OrgSlug) org).getSlug()).body().getId()); - } catch (NullPointerException noOrgFound) { + response = dynamicRoutingClient.getOrgIdFromSlug(((OrgSlug) org).getSlug()).block(); + assert response != null; + return new AbstractMap.SimpleEntry<>(org, response.getId()); + } catch (HttpClientResponseException | NullPointerException noOrgFound) { err(String.format("The org '%s' is not found on JustServe", ((OrgSlug) org).getSlug())); return null; - } + } + }) .filter(Objects::nonNull) .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue)); @@ -67,13 +70,12 @@ public void run() { orgUuidMap.entrySet().stream().parallel().forEach(entry -> { Org org = entry.getKey(); UUID orgId = entry.getValue(); - String orgIdentifier = org instanceof OrgSlug ? ((OrgSlug) org).getSlug() + " (" + orgId + ")" : orgId.toString(); + String orgIdentifier = org instanceof OrgSlug orgSlug ? orgSlug.getSlug() + " (" + orgId + ")" : orgId.toString(); log.atTrace().log("Making user {} an admin for org {}", user, orgIdentifier); try { log.atTrace().log("sending request to make user {} an admin for org {}.", user, orgIdentifier); - HttpResponse response = boundaryPermissionClient.makeAdminForOrg(orgId, user); - log.atTrace().log("received api response status: {}", response.status()); + boundaryPermissionClient.makeAdminForOrg(orgId, user).block(); log.atDebug().log("Successfully made user {} an admin for org {}.", user, orgIdentifier); successfulReassignments.put(org, orgId); } catch (HttpClientResponseException e) { diff --git a/cli/src/main/java/org/justserve/command/UnReassignProjects.java b/cli/src/main/java/org/justserve/command/UnReassignProjects.java index b1c58c4..bb28a9f 100644 --- a/cli/src/main/java/org/justserve/command/UnReassignProjects.java +++ b/cli/src/main/java/org/justserve/command/UnReassignProjects.java @@ -83,15 +83,16 @@ public void run() { for (UUID projectId : projectIds) { GetProjectRequest getProjectRequest = new GetProjectRequest(); Project project; + String failedToGetError = ("Failed to get project '" + projectName + "' (" + projectId + ")"); try { - project = client.getProject(projectId, " ", getProjectRequest).body(); + project = client.getProject(projectId, " ", getProjectRequest).block(); } catch (HttpClientResponseException | NullPointerException e) { - printError("Failed to get project " + projectName + " (" + projectId + ")"); + printError(failedToGetError); log.atError().setCause(e).log("Error getting project"); continue; } if (null == project) { - printError("Failed to get project '" + projectName + "' (" + projectId + ")"); + printError(failedToGetError); log.atError().log("Project {} not found", projectId); continue; } @@ -106,24 +107,13 @@ public void run() { } ReassignProjectRequest reassignProjectRequest = new ReassignProjectRequest(userID, project.getProjectOwnerUserId()); log.atTrace().log("Reassigning project {} ({}) to user {}", projectName, projectId, userID); - HttpResponse reassignResponse = null; try { - reassignResponse = client.reassignProject(projectId, reassignProjectRequest); + client.reassignProject(projectId, reassignProjectRequest).block(); + successCount ++; } catch (HttpClientResponseException e) { printError("Failed to reassign project " + projectName + " (" + projectId + ") to user " + userID); log.atError().setCause(e).log("Error response from API: {}", e.getResponse().body()); } - if (null != reassignResponse && reassignResponse.status() == HttpStatus.OK) { - printNormal("Successfully reassigned project %s (%s) to user %s", projectName, projectId, userID); - log.atTrace().log("received api response status: {}", reassignResponse.status()); - successCount++; - continue; - } - String reason = reassignResponse == null ? "response is null" : reassignResponse.status().toString(); - printError("Failed to reassign project " + projectName + " (" + projectId + ") to user " + userID + - ". Expected HTTP Status 'OK', but got " + reason); - log.atError().log("Failed to reassign project {} ({}) to user {}. Expected HTTP Status 'OK', but got {}", - projectName, projectId, userID, reason); } } printNormal("Successfully reassigned %d projects to user %s", successCount, userID); diff --git a/cli/src/main/java/org/justserve/util/JustServePrinter.java b/cli/src/main/java/org/justserve/util/JustServePrinter.java index 80624a2..4289006 100644 --- a/cli/src/main/java/org/justserve/util/JustServePrinter.java +++ b/cli/src/main/java/org/justserve/util/JustServePrinter.java @@ -12,17 +12,17 @@ */ public final class JustServePrinter { - private final static Ansi blue = ansi().fgRgb(0, 158, 185); - private final static Ansi orange = ansi().fgRgb(255, 140, 0); // OG color is 239, 94, 57 - private final static Ansi red = ansi().fgRgb(233, 59, 84); // I definitely eyeballed this one - private final static Ansi yellow = ansi().fgRgb(225, 188, 33); - - private final static Ansi normalStyle = ansi().reset(); - private final static Ansi titleStyle = blue.bold(); - private final static Ansi emphasisStyle = orange.bold(); - private final static Ansi warningStyle = yellow; - private final static Ansi errorTitleStyle = red.bold(); - private final static Ansi errorInfoStyle = ansi().reset(); + private static final Ansi blue = ansi().fgRgb(0, 158, 185); + private static final Ansi orange = ansi().fgRgb(255, 140, 0); // OG color is 239, 94, 57 + private static final Ansi red = ansi().fgRgb(233, 59, 84); // I definitely eyeballed this one + private static final Ansi yellow = ansi().fgRgb(225, 188, 33); + + private static final Ansi normalStyle = ansi().reset(); + private static final Ansi titleStyle = blue.bold(); + private static final Ansi emphasisStyle = orange.bold(); + private static final Ansi warningStyle = yellow; + private static final Ansi errorTitleStyle = red.bold(); + private static final Ansi errorInfoStyle = ansi().reset(); /** diff --git a/cli/src/test/groovy/org/justserve/cli/command/AssignOrgToProjectSpec.groovy b/cli/src/test/groovy/org/justserve/cli/command/AssignOrgToProjectSpec.groovy index 9c59f0b..f1f0f31 100644 --- a/cli/src/test/groovy/org/justserve/cli/command/AssignOrgToProjectSpec.groovy +++ b/cli/src/test/groovy/org/justserve/cli/command/AssignOrgToProjectSpec.groovy @@ -13,7 +13,7 @@ class AssignOrgToProjectSpec extends BaseCommandSpec { def "can assign an organization to a project"() { given: def orgSearchResponse = authOrgClient.searchByLocation(createSearchRequestForElkGrove()) - UUID orgId = orgSearchResponse.body().organizations.first().id + UUID orgId = orgSearchResponse.block().organizations.first().id ProjectCard project = searchResults.first() def args = ["assignOrgToProject", "-p", project.getId().toString(), "-o", orgId.toString()] diff --git a/cli/src/test/groovy/org/justserve/cli/command/GetTempPasswordSpec.groovy b/cli/src/test/groovy/org/justserve/cli/command/GetTempPasswordSpec.groovy index c2b83bb..b37690c 100644 --- a/cli/src/test/groovy/org/justserve/cli/command/GetTempPasswordSpec.groovy +++ b/cli/src/test/groovy/org/justserve/cli/command/GetTempPasswordSpec.groovy @@ -13,7 +13,13 @@ import static org.spockframework.runtime.model.parallel.ExecutionMode.SAME_THREA class GetTempPasswordSpec extends BaseCommandSpec { @Unroll("getting temp password with '#flag' and '#email' #expectation") - def "commands to query temporary password should behave as expected with or without authentication"() { + def "commands to query temporary password should behave as expected with or without authentication"( + String flag, + String email, + ApplicationContext context, + String expectedOutput, + String expectedError + ) { when: def (outputStream, errorStream) = executeCommand(context as ApplicationContext, ["getTempPassword", flag, email] as String[]) diff --git a/cli/src/test/groovy/org/justserve/cli/command/MakeOrgAdminSpec.groovy b/cli/src/test/groovy/org/justserve/cli/command/MakeOrgAdminSpec.groovy index 06a5820..996d2e9 100644 --- a/cli/src/test/groovy/org/justserve/cli/command/MakeOrgAdminSpec.groovy +++ b/cli/src/test/groovy/org/justserve/cli/command/MakeOrgAdminSpec.groovy @@ -3,7 +3,6 @@ package org.justserve.cli.command import io.micronaut.context.ApplicationContext import spock.lang.Shared -//@Execution(SAME_THREAD) class MakeOrgAdminSpec extends BaseCommandSpec { @Shared @@ -13,47 +12,49 @@ class MakeOrgAdminSpec extends BaseCommandSpec { List sharedOrgs def setupSpec() { - sharedUserID = createUser().body().id + sharedUserID = createUser().id sharedOrgs = createTestOrgs(3) } - def "can make a user an admin to #orgCount org(s) using the #orgFlag and #userFlag flags #title"() { + @SuppressWarnings("GroovyAssignabilityCheck") + def "can make a user an admin to #orgCount org(s) using the #orgFlag and #userFlag flags as an authorized user"(String orgFlag, Integer orgCount, String userFlag) { given: def orgs = sharedOrgs.take(orgCount).join(",") when: - def (outputStream, errorStream) = executeCommand(context as ApplicationContext, ["makeOrgAdmin", orgFlag, orgs, userFlag, sharedUserID] as String[]) + def (outputStream, errorStream) = executeCommand(ctx as ApplicationContext, ["makeOrgAdmin", orgFlag, orgs, userFlag, sharedUserID] as String[]) then: - if (context == noAuthCtx) { - verifyAll { - errorStream.matches(tokenNotSetRegex) - outputStream.matches(blankRegex) - } - return - } verifyAll { (outputStream as String).contains("successfully reassigned ${orgCount} orgs to user ${sharedUserID}") errorStream.matches(blankRegex) } where: - orgFlag | orgCount | userFlag | context | title | _ - "-o" | 3 | "-u" | ctx | "as an authorized user successfully makes the changes" | _ - "--org" | 3 | "-u" | ctx | "as an authorized user successfully makes the changes" | _ - "-o" | 3 | "--user" | ctx | "as an authorized user successfully makes the changes" | _ - "-o" | 3 | "-u" | noAuthCtx | "as unauthorized user and fails prior to making any api call" | _ - "--org" | 3 | "-u" | noAuthCtx | "as unauthorized user and fails prior to making any api call" | _ - "-o" | 3 | "--user" | noAuthCtx | "as unauthorized user and fails prior to making any api call" | _ - "-o" | 1 | "-u" | noAuthCtx | "as unauthorized user and fails prior to making any api call" | _ - "--org" | 1 | "-u" | noAuthCtx | "as unauthorized user and fails prior to making any api call" | _ - "-o" | 1 | "--user" | noAuthCtx | "as unauthorized user and fails prior to making any api call" | _ - "-o" | 1 | "-u" | ctx | "as an authorized user successfully makes the changes" | _ - "--org" | 1 | "-u" | ctx | "as an authorized user successfully makes the changes" | _ - "-o" | 1 | "--user" | ctx | "as an authorized user successfully makes the changes" | _ + [orgFlag, orgCount, userFlag] << [["-o", "--org"], [3, 1], ["-u", "--user"]].combinations() + } + + @SuppressWarnings("GroovyAssignabilityCheck") + def "fails to make a user an admin to #orgCount org(s) when unauthorized"(String orgFlag, Integer orgCount, String userFlag) { + given: + def orgs = sharedOrgs.take(orgCount).join(",") + + when: + def (outputStream, errorStream) = executeCommand(noAuthCtx as ApplicationContext, ["makeOrgAdmin", orgFlag, orgs, userFlag, sharedUserID] as String[]) + + then: + verifyAll { + errorStream.matches(tokenNotSetRegex) + outputStream.matches(blankRegex) + } + + where: + [orgFlag, orgCount, userFlag] << [["-o", "--org"], [3, 1], ["-u", "--user"]].combinations() } - def "can make a user an admin to #orgCount where at least one org ID does not exist on JustServe"() { + @SuppressWarnings("GroovyAssignabilityCheck") + def "can make a user an admin to #orgCount where at least one org ID does not exist on JustServe using the #orgFlag and #userFlag flags"( + String orgFlag, Integer orgCount, String userFlag) { given: String orgs def fakeId = faker.internet().uuid().toString() @@ -64,7 +65,7 @@ class MakeOrgAdminSpec extends BaseCommandSpec { } when: - def (outputStream, errorStream) = executeCommand(context as ApplicationContext, ["makeOrgAdmin", orgFlag, orgs, userFlag, sharedUserID] as String[]) + def (outputStream, errorStream) = executeCommand(ctx as ApplicationContext, ["makeOrgAdmin", orgFlag, orgs, userFlag, sharedUserID] as String[]) then: verifyAll { @@ -73,28 +74,23 @@ class MakeOrgAdminSpec extends BaseCommandSpec { } where: - orgFlag | orgCount | userFlag | context | title | _ - "-o" | 3 | "-u" | ctx | "as an authorized user successfully makes the changes" | _ - "--org" | 3 | "-u" | ctx | "as an authorized user successfully makes the changes" | _ - "-o" | 3 | "--user" | ctx | "as an authorized user successfully makes the changes" | _ - "-o" | 1 | "-u" | ctx | "as an authorized user successfully makes the changes" | _ - "--org" | 1 | "-u" | ctx | "as an authorized user successfully makes the changes" | _ - "-o" | 1 | "--user" | ctx | "as an authorized user successfully makes the changes" | _ + [orgFlag, orgCount, userFlag] << [["-o", "--org"], [3, 1], ["-u", "--user"]].combinations() } - def "can make a user an admin to #orgCount where at least one org Slug does not exist on JustServe"() { + @SuppressWarnings("GroovyAssignabilityCheck") + def "can make a user an admin to #orgCount where at least one org Slug does not exist on JustServe using the #orgFlag and #userFlag flags"(String orgFlag, Integer orgCount, String userFlag) { given: String orgs def fakeSlug = faker.internet().slug().toString() if (orgCount == 1) { orgs = fakeSlug } else { - orgs = authOrgClient.searchByLocation(createSearchRequestForElkGrove()).body().getOrganizations().url.take(orgCount - 1).join(",") + "," + fakeSlug + orgs = authOrgClient.searchByLocation(createSearchRequestForElkGrove()).block().getOrganizations().url.take(orgCount - 1).join(",") + "," + fakeSlug } when: - def (outputStream, errorStream) = executeCommand(context as ApplicationContext, ["makeOrgAdmin", orgFlag, orgs, userFlag, sharedUserID] as String[]) + def (outputStream, errorStream) = executeCommand(ctx as ApplicationContext, ["makeOrgAdmin", orgFlag, orgs, userFlag, sharedUserID] as String[]) then: verifyAll { @@ -103,12 +99,6 @@ class MakeOrgAdminSpec extends BaseCommandSpec { } where: - orgFlag | orgCount | userFlag | context | title | _ - "-o" | 3 | "-u" | ctx | "as an authorized user successfully makes the changes" | _ - "--org" | 3 | "-u" | ctx | "as an authorized user successfully makes the changes" | _ - "-o" | 3 | "--user" | ctx | "as an authorized user successfully makes the changes" | _ - "-o" | 1 | "-u" | ctx | "as an authorized user successfully makes the changes" | _ - "--org" | 1 | "-u" | ctx | "as an authorized user successfully makes the changes" | _ - "-o" | 1 | "--user" | ctx | "as an authorized user successfully makes the changes" | _ + [orgFlag, orgCount, userFlag] << [["-o", "--org"], [3, 1], ["-u", "--user"]].combinations() } } diff --git a/cli/src/test/groovy/org/justserve/cli/command/UnReassignProjectsSpec.groovy b/cli/src/test/groovy/org/justserve/cli/command/UnReassignProjectsSpec.groovy index 75053a8..001b7e0 100644 --- a/cli/src/test/groovy/org/justserve/cli/command/UnReassignProjectsSpec.groovy +++ b/cli/src/test/groovy/org/justserve/cli/command/UnReassignProjectsSpec.groovy @@ -27,7 +27,7 @@ class UnReassignProjectsSpec extends BaseCommandSpec { def setupSpec() { testProjects = getProjectsByLocation(faker.location().toString()) def newReadOnlyUser = new TestUser(faker) - newReadOnlyUser.uuid = createUser().body().id + newReadOnlyUser.uuid = createUser().id testEmails = new HashMap<>() testEmails.put("forwarded-reassignment-email", [TestEmailGenerator.generateMockValidEmlContent(testProjects, readOnlyUser), readOnlyUser]) testEmails.put("automated-reassignment-email", [TestEmailGenerator.generateMockValidEmlContent(testProjects, newReadOnlyUser), newReadOnlyUser]) diff --git a/core/build.gradle.kts b/core/build.gradle.kts index 6327199..f0e2760 100644 --- a/core/build.gradle.kts +++ b/core/build.gradle.kts @@ -47,12 +47,12 @@ micronaut { client(file("src/main/resources/schema.yml")) { apiPackageName = "org.justserve.client" modelPackageName = "org.justserve.model" - useReactive = false + useReactive = true useAuth = false lombok.set(true) clientId = "justserve" apiNameSuffix = "Client" - alwaysUseGenerateHttpResponse = true + alwaysUseGenerateHttpResponse = false additionalProperties.put("retryable", "true") // https://github.com/micronaut-projects/micronaut-openapi/discussions/1783 schemaMapping.put("EventType", "org.justserve.model.EventType") diff --git a/core/src/main/java/org/justserve/client/BoundaryPermissionClient.java b/core/src/main/java/org/justserve/client/BoundaryPermissionClient.java index bcc54c1..e45d9b7 100644 --- a/core/src/main/java/org/justserve/client/BoundaryPermissionClient.java +++ b/core/src/main/java/org/justserve/client/BoundaryPermissionClient.java @@ -6,6 +6,7 @@ import io.micronaut.http.client.annotation.Client; import io.micronaut.retry.annotation.Retryable; import jakarta.validation.constraints.NotNull; +import reactor.core.publisher.Mono; import java.util.UUID; @@ -25,7 +26,7 @@ public interface BoundaryPermissionClient { */ @Retryable @Put("/api/v1/boundaries/rep/{userId}/org/{orgId}") - HttpResponse makeAdminForOrg( + Mono> makeAdminForOrg( @PathVariable("orgId") @NotNull UUID orgId, @PathVariable("userId") @NotNull UUID userId ); diff --git a/core/src/main/java/org/justserve/client/GraphQLClient.java b/core/src/main/java/org/justserve/client/GraphQLClient.java index bb4b268..39afdf3 100644 --- a/core/src/main/java/org/justserve/client/GraphQLClient.java +++ b/core/src/main/java/org/justserve/client/GraphQLClient.java @@ -8,6 +8,7 @@ import io.micronaut.retry.annotation.Retryable; import org.justserve.model.*; import org.justserve.model.graph.*; +import reactor.core.publisher.Mono; import java.util.ArrayList; import java.util.List; @@ -19,45 +20,45 @@ public interface GraphQLClient { @Post - GraphQLResponse createEvent(@Body CreateEventMutation request); + Mono> createEvent(@Body CreateEventMutation request); @Post - GraphQLResponse createEvents(@Body CreateEventsMutation request); + Mono> createEvents(@Body CreateEventsMutation request); @Post - GraphQLResponse createRecurringEvents(@Body CreateRecurringEventsMutation request); + Mono> createRecurringEvents(@Body CreateRecurringEventsMutation request); @Post - GraphQLResponse executeAddProjectAttachment(@Body GraphQLAddProjectAttachmentRequest request); + Mono> executeAddProjectAttachment(@Body GraphQLAddProjectAttachmentRequest request); @Post - GraphQLResponse executeAddProjectOrganization(@Body GraphQLAddProjectOrganizationRequest request); + Mono> executeAddProjectOrganization(@Body GraphQLAddProjectOrganizationRequest request); @Post - GraphQLResponse executeCombinedMutationUpdateProjectAddProjectTag(@Body GraphQLCombinedMutationUpdateProjectAddProjectTagRequest request); + Mono> executeCombinedMutationUpdateProjectAddProjectTag(@Body GraphQLCombinedMutationUpdateProjectAddProjectTagRequest request); @Post - GraphQLResponse executeCreateProject(@Body GraphQLCreateProjectRequest request); + Mono> executeCreateProject(@Body GraphQLCreateProjectRequest request); @Post - GraphQLResponse executePublishProject(@Body GraphQLPublishProjectRequest request); + Mono> executePublishProject(@Body GraphQLPublishProjectRequest request); @Post - GraphQLResponse executeSearchOrganization(@Body GraphQLSearchOrganizationRequest request); + Mono> executeSearchOrganization(@Body GraphQLSearchOrganizationRequest request); @Post - GraphQLResponse executeSetProjectLocation(@Body GraphQLSetProjectLocationRequest request); + Mono> executeSetProjectLocation(@Body GraphQLSetProjectLocationRequest request); @Post - GraphQLResponse executeUpdateProjectAttachment(@Body GraphQLUpdateProjectAttachmentRequest request); + Mono> executeUpdateProjectAttachment(@Body GraphQLUpdateProjectAttachmentRequest request); @Post - GraphQLResponse executeUpdateProjectListing(@Body GraphQLUpdateProjectListingRequest request); + Mono> executeUpdateProjectListing(@Body GraphQLUpdateProjectListingRequest request); @Post - GraphQLResponse executeUpdateProject(@Body GraphQLUpdateProjectRequest request); + Mono> executeUpdateProject(@Body GraphQLUpdateProjectRequest request); - default GraphQLResponse addProjectAttachment(GraphQLAddProjectAttachmentVariables variables) { + default Mono> 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); @@ -65,7 +66,7 @@ default GraphQLResponse addProjectAttachment(Gr return this.executeAddProjectAttachment(request); } - default GraphQLResponse addProjectOrganization(GraphQLAddProjectOrganizationVariables variables) { + default Mono> 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); @@ -73,7 +74,7 @@ default GraphQLResponse addProjectOrganizatio return this.executeAddProjectOrganization(request); } - default GraphQLResponse combinedMutationUpdateProjectAddProjectTag(GraphQLCombinedMutationUpdateProjectAddProjectTagVariables variables) { + default Mono> 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); @@ -81,7 +82,7 @@ default GraphQLResponse c return this.executeCombinedMutationUpdateProjectAddProjectTag(request); } - default GraphQLResponse createProject(GraphQLCreateProjectVariables variables) { + default Mono> 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); @@ -89,7 +90,7 @@ default GraphQLResponse createProject(GraphQLCreatePro return this.executeCreateProject(request); } - default GraphQLResponse publishProject(GraphQLPublishProjectVariables variables) { + default Mono> 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); @@ -97,7 +98,7 @@ default GraphQLResponse publishProject(GraphQLPublish return this.executePublishProject(request); } - default GraphQLResponse searchOrganization(GraphQLSearchOrganizationVariables variables) { + default Mono> 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); @@ -105,7 +106,7 @@ default GraphQLResponse searchOrganization(GraphQ return this.executeSearchOrganization(request); } - default GraphQLResponse setProjectLocation(GraphQLSetProjectLocationVariables variables) { + default Mono> 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); @@ -113,7 +114,7 @@ default GraphQLResponse setProjectLocation(GraphQ return this.executeSetProjectLocation(request); } - default GraphQLResponse updateProjectAttachment(GraphQLUpdateProjectAttachmentVariables variables) { + default Mono> 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); @@ -121,7 +122,7 @@ default GraphQLResponse updateProjectAttachm return this.executeUpdateProjectAttachment(request); } - default GraphQLResponse updateProjectListing(GraphQLUpdateProjectListingVariables variables) { + default Mono> 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); @@ -129,7 +130,7 @@ default GraphQLResponse updateProjectListing(Gr return this.executeUpdateProjectListing(request); } - default GraphQLResponse updateProject(GraphQLUpdateProjectVariables variables) { + default Mono> updateProject(GraphQLUpdateProjectVariables variables) { String mutationFormat = "mutation ($projectId: ID!, $logo: String!) {\n updateProject(id: $projectId, modify: { logo: $logo }) {\n %s\n }\n }"; List responseFields = new ArrayList<>(); diff --git a/core/src/main/java/org/justserve/client/ProjectClient.java b/core/src/main/java/org/justserve/client/ProjectClient.java new file mode 100644 index 0000000..aa3c2ba --- /dev/null +++ b/core/src/main/java/org/justserve/client/ProjectClient.java @@ -0,0 +1,76 @@ +package org.justserve.client; + +import io.micronaut.http.HttpResponse; +import io.micronaut.http.annotation.*; +import io.micronaut.core.annotation.*; +import io.micronaut.http.client.annotation.Client; +import org.justserve.model.*; +import reactor.core.publisher.Mono; + +import java.util.UUID; +import io.micronaut.retry.annotation.Retryable; +import jakarta.annotation.Generated; +import jakarta.validation.Valid; +import jakarta.validation.constraints.*; + +@Generated("io.micronaut.openapi.generator.JavaMicronautClientCodegen") +@Retryable +@Client("justserve") +public interface ProjectClient { + + /** + * Assigns an organization to a project. + * + * @param id ID of the project (required) + * @param organizationId ID of the organization to assign (required) + * + * @return OK (status code 200) + */ + @Put("/api/v1/projects/{id}/organization/{organizationId}/assign") + Mono> assignOrganizationToProject( + @PathVariable("id") @NotNull UUID id, + @PathVariable("organizationId") @NotNull UUID organizationId + ); + + /** + * Get project details for a given project + * + * @param id (required) + * @param locale (required) + * @param getProjectRequest (optional) + * + * @return OK (status code 200) + */ + @Post("/api/v1/projects/{id}/{locale}") + Mono<@Valid Project> getProject( + @PathVariable("id") @NotNull UUID id, + @PathVariable("locale") @NotNull String locale, + @Body @Nullable @Valid GetProjectRequest getProjectRequest + ); + + /** + * Reassigns multiple projects to a new user. + * + * @param projectId ID of the project to be reassigned (required) + * @param reassignProjectRequest (optional) + * + * @return OK (status code 200) + */ + @Put("/api/v1/projects/{projectId}/users/reassignAndDelete") + Mono> reassignProject( + @PathVariable("projectId") @NotNull UUID projectId, + @Body @Nullable @Valid ReassignProjectRequest reassignProjectRequest + ); + + /** + * search active projects + * + * @param projectSearchRequest (optional) + * + * @return OK (status code 200) + */ + @Post("/api/v2/projects/search") + Mono<@Valid ProjectSearchResponse> searchProjects( + @Body @Nullable @Valid ProjectSearchRequest projectSearchRequest + ); +} \ No newline at end of file diff --git a/core/src/main/java/org/justserve/model/GetProjectRequest.java b/core/src/main/java/org/justserve/model/GetProjectRequest.java new file mode 100644 index 0000000..3169847 --- /dev/null +++ b/core/src/main/java/org/justserve/model/GetProjectRequest.java @@ -0,0 +1,37 @@ +package org.justserve.model; + +import lombok.AllArgsConstructor; +import lombok.NoArgsConstructor; +import lombok.Data; +import lombok.experimental.Accessors; +import com.fasterxml.jackson.annotation.*; +import io.micronaut.serde.annotation.Serdeable; +import io.micronaut.core.annotation.Nullable; + +/** + * GetProjectRequest + */ +@Accessors(chain = true) +@NoArgsConstructor +@AllArgsConstructor +@Data +@Serdeable +public class GetProjectRequest { + + @Nullable + @JsonInclude(JsonInclude.Include.USE_DEFAULTS) + private String latitude; + + @Nullable + @JsonInclude(JsonInclude.Include.USE_DEFAULTS) + private String longitude; + + @Nullable + @JsonInclude(JsonInclude.Include.USE_DEFAULTS) + private String postalCode; + + @Nullable + @JsonInclude(JsonInclude.Include.USE_DEFAULTS) + private String lang; + +} \ No newline at end of file diff --git a/core/src/main/java/org/justserve/model/ReassignProjectRequest.java b/core/src/main/java/org/justserve/model/ReassignProjectRequest.java new file mode 100644 index 0000000..58d68ca --- /dev/null +++ b/core/src/main/java/org/justserve/model/ReassignProjectRequest.java @@ -0,0 +1,44 @@ +package org.justserve.model; + +import java.util.UUID; +import lombok.AllArgsConstructor; +import lombok.NoArgsConstructor; +import lombok.Data; +import lombok.experimental.Accessors; +import com.fasterxml.jackson.annotation.*; +import io.micronaut.serde.annotation.Serdeable; +import io.micronaut.core.annotation.Nullable; +import jakarta.annotation.Generated; + +/** + * ReassignProjectRequest + */ +@Accessors(chain = true) +@NoArgsConstructor +@AllArgsConstructor +@Data + +@Serdeable +@Generated("io.micronaut.openapi.generator.JavaMicronautClientCodegen") +public class ReassignProjectRequest { + + public static final String JSON_PROPERTY_ASSIGN_ID = "assignId"; + public static final String JSON_PROPERTY_DELETE_ID = "deleteId"; + + /** + * UUID of the new owner of the project + */ + @Nullable + @JsonProperty(JSON_PROPERTY_ASSIGN_ID) + @JsonInclude(JsonInclude.Include.USE_DEFAULTS) + private UUID assignId; + + /** + * UUID of the previous owner of the project + */ + @Nullable + @JsonProperty(JSON_PROPERTY_DELETE_ID) + @JsonInclude(JsonInclude.Include.USE_DEFAULTS) + private UUID deleteId; + +} \ No newline at end of file diff --git a/core/src/main/resources/schema.yml b/core/src/main/resources/schema.yml index 1767582..16ed23d 100644 --- a/core/src/main/resources/schema.yml +++ b/core/src/main/resources/schema.yml @@ -71,108 +71,6 @@ paths: 200: description: OK content: { application/json: { schema: { type: array, items: { $ref: '#/components/schemas/UserSlimSearchResult' } } } } - /api/v2/projects/search: - post: - tags: [ Project ] - description: search active projects - operationId: searchProjects - requestBody: - content: - application/json: - schema: - $ref: '#/components/schemas/ProjectSearchRequest' - responses: - '200': - description: OK - content: - application/json: - schema: - $ref: '#/components/schemas/ProjectSearchResponse' - /api/v1/projects/{id}/{locale}: - post: - tags: [ Project ] - description: Get project details for a given project - operationId: getProject - parameters: - - name: id - in: path - required: true - schema: { type: string, format: uuid } - - name: locale - in: path - required: true - schema: { type: string } - requestBody: - content: - application/json: - schema: - type: object - properties: - latitude: - type: string - longitude: - type: string - postalCode: - type: string - lang: - type: string - responses: - '200': - description: OK - content: - application/json: - schema: - $ref: '#/components/schemas/Project' - /api/v1/projects/{projectId}/users/reassignAndDelete: - put: - tags: [ Project ] - description: Reassigns multiple projects to a new user. - operationId: reassignProject - parameters: - - name: projectId - in: path - description: ID of the project to be reassigned - required: true - schema: { type: string, format: uuid } - requestBody: - content: - application/json: - schema: - type: object - properties: - assignId: { type: string, format: UUID, description: "UUID of the new owner of the project" } - deleteId: { type: string, format: UUID, description: "UUID of the previous owner of the project" } - additionalProperties: false - responses: - '200': - description: OK - content: - application/json: - schema: - type: null - /api/v1/projects/{id}/organization/{organizationId}/assign: - put: - tags: [ Project ] - description: Assigns an organization to a project. - operationId: assignOrganizationToProject - parameters: - - name: id - in: path - description: ID of the project - required: true - schema: { type: string, format: uuid } - - name: organizationId - in: path - description: ID of the organization to assign - required: true - schema: { type: string, format: uuid } - responses: - '200': - description: OK - content: - application/json: - schema: - type: null /api/v1/users: post: description: Register a new user on JustServe @@ -1301,32 +1199,6 @@ components: geoCodeOverride: type: boolean timezone: {} - required: - - mapId - - fullDisplayAddress - - address - - suite - - city - - civicCityId - - neighborhood - - county - - state - - postal - - country - - countryCode - - locationVisibilityId - - missionId - - ccId - - stakeId - - areaId - - latitude - - longitude - - maxLatitude - - minLatitude - - maxLongitude - - minLongitude - - geoCodeOverride - - timezone ownerLog: type: array items: {} @@ -1381,19 +1253,6 @@ components: type: number assignedOn: type: string - required: - - submitterUserId - - firstName - - lastName - - email - - phone - - postal - - applicantPostal - - applicantCity - - applicantCountry - - applicantCountryCode - - assignmentLevel - - assignedOn contact: type: object properties: @@ -1415,11 +1274,6 @@ components: type: string userId: type: string - required: - - name - - email - - phone - - userId representative: type: object properties: @@ -1446,18 +1300,6 @@ components: linked: type: boolean logo: {} - required: - - authorization - - organizationAuthorization - - name - - description - - url - - internalUrl - - organizationId - - reviewedBy - - reviewedOn - - linked - - logo suitableAllAges: type: boolean groupProject: @@ -1595,31 +1437,6 @@ components: timezone: type: string required: - - mapId - - fullDisplayAddress - - address - - suite - - city - - civicCityId - - neighborhood - - county - - state - - postal - - country - - countryCode - - locationVisibilityId - - missionId - - ccId - - stakeId - - areaId - - latitude - - longitude - - maxLatitude - - minLatitude - - maxLongitude - - minLongitude - - geoCodeOverride - - timezone interested: type: array items: {} @@ -1642,20 +1459,6 @@ components: type: array items: {} required: - - id - - start - - renewDate - - end - - schedule - - scheduleLanguage - - specialDirections - - specialDirectionsLanguage - - locationName - - locationLink - - location - - interested - - contacts - - boundaries recurring: {} lastChangeReason: {} escalated: {} @@ -1699,80 +1502,6 @@ components: type: number underReview: type: boolean - required: - - id - - projectOwners - - projectOwnerLocation - - ownerLog - - projectType - - status - - publishDate - - language - - country - - title - - shortDescription - - longDescription - - logo - - attachments - - attachmentInfo - - applicant - - contact - - sponsor - - representative - - organization - - suitableAllAges - - groupProject - - volunteerRemotely - - itemDonations - - wheelchairAccessible - - indoors - - forYouthGroups - - volunteerFromAnywhere - - regionSelected - - temporaryFakeDistanceScore - - fakeDistanceScoreUpdate - - skills - - interests - - tools - - projectSkills - - projectInterests - - projectTools - - externalVolunteerURL - - isExternalProject - - isUnlistedProject - - archivedProject - - isActive - - externalVolunteerCount - - externalVolunteers - - allEventsFilled - - daysOfWeek - - timesOfDay - - waiverURL - - dtl - - onGoing - - recurring - - lastChangeReason - - escalated - - created - - updated - - createdBy - - deleted - - deletedOn - - deletedBy - - firstStartDateTimeOffset - - lastEndDateTimeOffset - - cbfName - - cblName - - updatedBy - - ubfName - - ublName - - volunteerCentersData - - relativityScore - - projectOwnerName - - projectOwnerLastName - - projectOwnerUserId - - projectLocationType - - underReview UserResultBounded: type: object properties: diff --git a/core/src/test/groovy/org/justserve/BoundaryPermissionSpec.groovy b/core/src/test/groovy/org/justserve/BoundaryPermissionSpec.groovy index fb5a37e..596b38b 100644 --- a/core/src/test/groovy/org/justserve/BoundaryPermissionSpec.groovy +++ b/core/src/test/groovy/org/justserve/BoundaryPermissionSpec.groovy @@ -1,12 +1,12 @@ package org.justserve -import io.micronaut.http.HttpResponse import io.micronaut.http.client.exceptions.HttpClientResponseException import io.micronaut.test.extensions.spock.annotation.MicronautTest import org.justserve.client.BoundaryPermissionClient import spock.lang.Shared -import static io.micronaut.http.HttpStatus.INTERNAL_SERVER_ERROR +import static io.micronaut.http.HttpStatus.FORBIDDEN +import static io.micronaut.http.HttpStatus.UNAUTHORIZED @MicronautTest class BoundaryPermissionSpec extends JustServeSpec { @@ -19,29 +19,33 @@ class BoundaryPermissionSpec extends JustServeSpec { authBoundaryPermissionClient = ctx.getBean(BoundaryPermissionClient) } - def "can reassign organizations #title"() { + def "successfully reassign organization admin"() { given: - UUID userID = createUser().body().id + UUID userID = createUser().getId() + UUID orgID = createOrg() when: - HttpResponse response = authBoundaryPermissionClient.makeAdminForOrg(orgID, userID) + authBoundaryPermissionClient.makeAdminForOrg(orgID, userID).block() + + then: + noExceptionThrown() + } + + def "fail to reassign organization admin #title"() { + given: + UUID userID = createUser().getId() + + when: + client.makeAdminForOrg(orgID, userID).block() then: - if (!expectedError) { - verifyAll { - null == response.body() - authOrgClient.getOrgOwners(orgID).body().stream().anyMatch { user -> (user.id == userID) } - } - return - } def exception = thrown(HttpClientResponseException) exception.status == expectedError where: - client | expectedError | title | orgID | _ - authBoundaryPermissionClient | null | "with a good OrgID as an admin and the request succeeds" | createOrg() | _ - noAuthBoundaryPermissionClient | INTERNAL_SERVER_ERROR | "with a bad OrgID as an admin and the request fails" | UUID.fromString(faker.internet().uuid().toString()) | _ -// noAuthBoundaryPermissionClient | UNAUTHORIZED | "as an unauthorized user and the request fails" | createOrg() | _ + client | expectedError | orgID | title + noAuthBoundaryPermissionClient | UNAUTHORIZED | createOrg() | "as an unauthorized user" + authBoundaryPermissionClient | FORBIDDEN | UUID.randomUUID() | "with a non-existent OrgID" } diff --git a/core/src/test/groovy/org/justserve/DynamicRoutingClientSpec.groovy b/core/src/test/groovy/org/justserve/DynamicRoutingClientSpec.groovy index e4e274d..3d5f492 100644 --- a/core/src/test/groovy/org/justserve/DynamicRoutingClientSpec.groovy +++ b/core/src/test/groovy/org/justserve/DynamicRoutingClientSpec.groovy @@ -1,10 +1,9 @@ package org.justserve -import io.micronaut.http.HttpResponse -import io.micronaut.http.HttpStatus + +import io.micronaut.http.client.exceptions.HttpClientResponseException import io.micronaut.test.extensions.spock.annotation.MicronautTest import org.justserve.client.DynamicRoutingClient -import org.justserve.model.DynamicRoutingDataResponse import spock.lang.Shared @MicronautTest @@ -20,23 +19,28 @@ class DynamicRoutingClientSpec extends JustServeSpec { def setupSpec() { noAuthClient = noAuthCtx.getBean(DynamicRoutingClient) authClient = ctx.getBean(DynamicRoutingClient) - realOrgSlug = authOrgClient.searchByLocation(createSearchRequestForElkGrove()).body().getOrganizations().url.first().toString() + realOrgSlug = authOrgClient.searchByLocation(createSearchRequestForElkGrove()).block().getOrganizations().first().getUrl() } - def "get orgId for #url"() { + def "can query orgId for #url"(DynamicRoutingClient client, String url) { when: - HttpResponse response = client.getOrgIdFromSlug(url) + client.getOrgIdFromSlug(url).block() + + then: + noExceptionThrown() + + where: + [url, client] << [[realOrgSlug], [authClient, noAuthClient]].combinations() + } + + def "attempting to query the orgId for #url fails as expected"(DynamicRoutingClient client, String url) { + when: + client.getOrgIdFromSlug(url).block() + then: - response.status() == expectedStatus - if (expectedStatus == HttpStatus.OK) { - response.body().id != null - } + thrown(HttpClientResponseException) where: - url | expectedStatus | client - realOrgSlug | HttpStatus.OK | authClient - realOrgSlug | HttpStatus.OK | noAuthClient - "1234" | HttpStatus.NOT_FOUND | authClient - "1234" | HttpStatus.NOT_FOUND | noAuthClient + [url, client] << [["thisisafakeurl"], [authClient, noAuthClient]].combinations() } } diff --git a/core/src/test/groovy/org/justserve/GraphQLClientSpec.groovy b/core/src/test/groovy/org/justserve/GraphQLClientSpec.groovy index d667a60..e041961 100644 --- a/core/src/test/groovy/org/justserve/GraphQLClientSpec.groovy +++ b/core/src/test/groovy/org/justserve/GraphQLClientSpec.groovy @@ -32,7 +32,7 @@ class GraphQLClientSpec extends Specification { .setTitle("Test Project - ${type.name()}") .setEventType(type) .setLocationType(ProjectLocationType.SINGLE_LOCATION) - ) + ).block() projectIds[type] = project.getData().getCreateProject().getId() } } @@ -47,7 +47,7 @@ class GraphQLClientSpec extends Specification { .setRedirect(redirect) when: - client.createProject(args) + client.createProject(args).block() then: noExceptionThrown() @@ -73,7 +73,7 @@ class GraphQLClientSpec extends Specification { def vars = new CreateEventVariables().setProjectId(projectIds[eventType]).setProjectEvent(event) when: - client.createEvent(new CreateEventMutation(vars)) + client.createEvent(new CreateEventMutation(vars)).block() then: noExceptionThrown() @@ -91,7 +91,7 @@ class GraphQLClientSpec extends Specification { def vars = new CreateEventVariables().setProjectId(projectIds[eventType]).setProjectEvent(event) when: - client.createEvent(new CreateEventMutation(vars)) + client.createEvent(new CreateEventMutation(vars)).block() then: noExceptionThrown() @@ -110,7 +110,7 @@ class GraphQLClientSpec extends Specification { def vars = new CreateEventVariables().setProjectId(projectIds[eventType]).setProjectEvent(event) when: - client.createEvent(new CreateEventMutation(vars)) + client.createEvent(new CreateEventMutation(vars)).block() then: noExceptionThrown() @@ -129,7 +129,7 @@ class GraphQLClientSpec extends Specification { def vars = new CreateEventVariables().setProjectId(projectIds[eventType]).setProjectEvent(event) when: - client.createEvent(new CreateEventMutation(vars)) + client.createEvent(new CreateEventMutation(vars)).block() then: noExceptionThrown() @@ -149,7 +149,7 @@ class GraphQLClientSpec extends Specification { def vars = new CreateEventVariables().setProjectId(projectIds[eventType]).setProjectEvent(event) when: - client.createEvent(new CreateEventMutation(vars)) + client.createEvent(new CreateEventMutation(vars)).block() then: noExceptionThrown() @@ -168,7 +168,7 @@ class GraphQLClientSpec extends Specification { def vars = new CreateEventVariables().setProjectId(projectIds[eventType]).setProjectEvent(event) when: - client.createEvent(new CreateEventMutation(vars)) + client.createEvent(new CreateEventMutation(vars)).block() then: noExceptionThrown() @@ -189,7 +189,7 @@ class GraphQLClientSpec extends Specification { def vars = new CreateEventVariables().setProjectId(projectIds[eventType]).setProjectEvent(event) when: - client.createEvent(new CreateEventMutation(vars)) + client.createEvent(new CreateEventMutation(vars)).block() then: noExceptionThrown() @@ -205,7 +205,7 @@ class GraphQLClientSpec extends Specification { def vars = new CreateEventVariables().setProjectId(projectIds[eventType]).setProjectEvent(event) when: - client.createEvent(new CreateEventMutation(vars)) + client.createEvent(new CreateEventMutation(vars)).block() then: thrown(HttpClientResponseException) @@ -223,8 +223,8 @@ class GraphQLClientSpec extends Specification { def secondVars = new CreateEventVariables().setProjectId(projectIds[eventType]).setProjectEvent(secondEvent) when: - client.createEvent(new CreateEventMutation(firstVars)) - client.createEvent(new CreateEventMutation(secondVars)) + client.createEvent(new CreateEventMutation(firstVars)).block() + client.createEvent(new CreateEventMutation(secondVars)).block() then: thrown(HttpClientResponseException) @@ -242,8 +242,8 @@ class GraphQLClientSpec extends Specification { def secondVars = new CreateEventVariables().setProjectId(projectIds[eventType]).setProjectEvent(secondEvent) when: - client.createEvent(new CreateEventMutation(firstVars)) - client.createEvent(new CreateEventMutation(secondVars)) + client.createEvent(new CreateEventMutation(firstVars)).block() + client.createEvent(new CreateEventMutation(secondVars)).block() then: noExceptionThrown() @@ -261,7 +261,7 @@ class GraphQLClientSpec extends Specification { def mutation = new CreateEventsMutation(vars) when: - def response = client.createEvents(mutation) + def response = client.createEvents(mutation).block() then: noExceptionThrown() @@ -278,7 +278,7 @@ class GraphQLClientSpec extends Specification { def mutation = new CreateRecurringEventsMutation(vars) when: - def response = client.createRecurringEvents(mutation) + def response = client.createRecurringEvents(mutation).block() then: noExceptionThrown() @@ -352,7 +352,7 @@ class GraphQLClientSpec extends Specification { def mutation = new CreateRecurringEventsMutation(vars) when: - def response = client.createRecurringEvents(mutation) + def response = client.createRecurringEvents(mutation).block() then: noExceptionThrown() @@ -368,7 +368,7 @@ class GraphQLClientSpec extends Specification { .setIncludeAll(includesAll) when: - GraphQLResponse response = client.searchOrganization(inputData) + GraphQLResponse response = client.searchOrganization(inputData).block() then: noExceptionThrown() diff --git a/core/src/test/groovy/org/justserve/GraphQLErrorClientFilterSpec.groovy b/core/src/test/groovy/org/justserve/GraphQLErrorClientFilterSpec.groovy index d4c47e5..b68fe72 100644 --- a/core/src/test/groovy/org/justserve/GraphQLErrorClientFilterSpec.groovy +++ b/core/src/test/groovy/org/justserve/GraphQLErrorClientFilterSpec.groovy @@ -21,9 +21,6 @@ class GraphQLErrorClientFilterSpec extends Specification { @Inject GraphQLClient client - @Shared - Faker faker = new Faker() - @SuppressWarnings("GroovyAssignabilityCheck") void "can create Project with EventType: #eventType, LocationType: #locationType, and Redirect: #redirect"(EventType eventType, ProjectLocationType locationType, String redirect) { given: @@ -34,14 +31,19 @@ class GraphQLErrorClientFilterSpec extends Specification { .setRedirect(redirect) when: - def response = client.createProject(args) + def response = client.createProject(args).block() then: noExceptionThrown() when: "create an incompatible event" response.getData().getCreateProject() - client.createRecurringEvents(new CreateRecurringEventsMutation(new CreateRecurringEventsVariables(response.getData().getCreateProject().getId(), new ProjectRecurringTime().setEndTime("whenever")))) + client.createRecurringEvents( + new CreateRecurringEventsMutation( + new CreateRecurringEventsVariables( + response.getData().getCreateProject().getId(), + new ProjectRecurringTime().setEndTime("whenever")))) + .block() then: HttpClientResponseException error = thrown(HttpClientResponseException) diff --git a/core/src/test/groovy/org/justserve/ImageClientSpec.groovy b/core/src/test/groovy/org/justserve/ImageClientSpec.groovy index 1155c99..5ce8177 100644 --- a/core/src/test/groovy/org/justserve/ImageClientSpec.groovy +++ b/core/src/test/groovy/org/justserve/ImageClientSpec.groovy @@ -24,7 +24,7 @@ class ImageClientSpec extends JustServeSpec { def imageUpload = new ImageUploadRequest(faker.image().base64JPG().split(",")[1], 256, 256, false, 0, 0) when: - client.uploadImage(imageUpload) + client.uploadImage(imageUpload).block() then: noExceptionThrown() @@ -40,12 +40,11 @@ class ImageClientSpec extends JustServeSpec { def imageUpload = new ImageUploadRequest(faker.image().base64JPG().split(",")[1], 256, 256, false, 0, 0) when: - def response = client.uploadImage(imageUpload) + def response = client.uploadImage(imageUpload).block() then: if (!expectedStatus) { - response.status() == HttpStatus.CREATED - response.body() != null + response != null return } def exception = thrown(HttpClientResponseException) diff --git a/core/src/test/groovy/org/justserve/JustServeSpec.groovy b/core/src/test/groovy/org/justserve/JustServeSpec.groovy index 545c706..cc98c30 100644 --- a/core/src/test/groovy/org/justserve/JustServeSpec.groovy +++ b/core/src/test/groovy/org/justserve/JustServeSpec.groovy @@ -2,7 +2,6 @@ package org.justserve import io.micronaut.context.ApplicationContext import io.micronaut.context.env.Environment -import io.micronaut.http.HttpResponse import io.micronaut.http.HttpStatus import io.micronaut.http.client.exceptions.HttpClientResponseException import io.micronaut.http.client.multipart.MultipartBody @@ -89,21 +88,24 @@ class JustServeSpec extends Specification { readOnlyUser = new TestUser(new Faker(Locale.of("en-us"))) projectClient = ctx.getBean(ProjectClient) String customRandomEmail = RandomStringUtils.insecure().nextAlphanumeric(20) + "@fake.com" - readOnlyUser.uuid = createUserFromFaker(noAuthUserClient, readOnlyUser, customRandomEmail).body().getId() + readOnlyUser.uuid = createUserFromFaker(noAuthUserClient, readOnlyUser, customRandomEmail).getId() readOnlyUser.email = customRandomEmail searchResults = getProjectsByLocation(faker.location().toString()) } void cleanupSpec() { [noAuthCtx, ctx].each { context -> - try { context?.stop() } catch (Exception ignored) {} + try { + context?.stop() + } catch (Exception ignored) { + } } } - HttpResponse createUser(UserClient client = noAuthUserClient) { - HttpResponse response = null + CreateUser200Response createUser(UserClient client = noAuthUserClient) { + CreateUser200Response response = null def tries = 0 - while ((null == response || ![HttpStatus.OK, HttpStatus.CREATED].contains(response.status())) && tries < 5) { + while (null == response && tries < 5) { try { // A new user is generated on each loop iteration to avoid collisions response = createUserFromFaker(client, new TestUser(new Faker(Locale.of("en-us")))) @@ -118,7 +120,7 @@ class JustServeSpec extends Specification { } @Retryable - private static HttpResponse createUserFromFaker(UserClient client, TestUser user, String uniqueEmailInput = null) { + private static CreateUser200Response createUserFromFaker(UserClient client, TestUser user, String uniqueEmailInput = null) { String email = uniqueEmailInput ?: RandomStringUtils.insecure().nextAlphanumeric(20) + "@fake.com" MultipartBody requestBody = MultipartBody.builder() .addPart("firstName", user.firstName) @@ -131,7 +133,7 @@ class JustServeSpec extends Specification { .addPart("country", user.country) .addPart("termsChecked", "true") .build() - client.createUser(requestBody) + client.createUser(requestBody).block() } List getProjectsByLocation(String location) { @@ -142,7 +144,7 @@ class JustServeSpec extends Specification { return projectClient.searchProjects(new ProjectSearchRequest().setPage(Integer.valueOf(page)) .setSize(size).setKeywords(keyword).setLocation(location).setRadiusType(MILES).setVolunteerFromAnywhere(false) .setIncludeOrgInfo(true).setLanguage(locale).setBrowserLocale(locale).setPublishedOnly(false) - .setIncludeFilledProjects(true).setDisasterRecoveryProjectsOnly(false).setTimesOfDay(null)).body().getItems() + .setIncludeFilledProjects(true).setDisasterRecoveryProjectsOnly(false).setTimesOfDay(null)).block().getItems() } @@ -163,8 +165,8 @@ class JustServeSpec extends Specification { .setUrl(getUniqueSlug()) .setVolunteerCenterInfo(null) .setWebsite(faker.internet().url()) - authOrgClient.createOrganization(orgRequest) - return authDynamicRoutingClient.getOrgIdFromSlug(orgRequest.url).body().id + authOrgClient.createOrganization(orgRequest).block() + return authDynamicRoutingClient.getOrgIdFromSlug(orgRequest.url).block().id } /** @@ -192,8 +194,8 @@ class JustServeSpec extends Specification { * @return The file name of the uploaded image. */ String getUploadedImageFileName() { - HttpResponse profileImage = authImageClient.uploadImage(new ImageUploadRequest(faker.image().base64JPG().split(",")[1], 256, 256, false, 0, 0)) - return profileImage.body().displayFileName + ImageUploadResponse profileImage = authImageClient.uploadImage(new ImageUploadRequest(faker.image().base64JPG().split(",")[1], 256, 256, false, 0, 0)).block() + return profileImage.displayFileName } /** @@ -204,9 +206,14 @@ class JustServeSpec extends Specification { String urlSlug = null while (null == urlSlug) { def potentialSlug = faker.word().noun() + System.currentTimeMillis() - def response = authDynamicRoutingClient.getOrgIdFromSlug(potentialSlug) - if (response.status() == HttpStatus.NOT_FOUND) { - urlSlug = potentialSlug + try { + authDynamicRoutingClient.getOrgIdFromSlug(potentialSlug).block() + } catch (HttpClientResponseException e) { + if (e.status == HttpStatus.NOT_FOUND) { + urlSlug = potentialSlug + } else { + throw e + } } } return urlSlug diff --git a/core/src/test/groovy/org/justserve/OrganizationClientSpec.groovy b/core/src/test/groovy/org/justserve/OrganizationClientSpec.groovy index fb3a3a3..b86e6d6 100644 --- a/core/src/test/groovy/org/justserve/OrganizationClientSpec.groovy +++ b/core/src/test/groovy/org/justserve/OrganizationClientSpec.groovy @@ -25,36 +25,34 @@ class OrganizationClientSpec extends JustServeSpec { def "using searchByLocation() should work when using #title"() { when: def search = createSearchRequestForElkGrove() - def response = client.searchByLocation(search) + def response = client.searchByLocation(search).block() then: - response.status() == expectedStatus - if (expectedStatus == HttpStatus.OK) { - response.body() != null - response.body().organizations.size() > 0 - } + response != null + response.organizations.size() > 0 + where: - expectedStatus | client | title - HttpStatus.OK | authOrgClient | "auth client" - HttpStatus.OK | noAuthClient | "no auth client" + client | title + authOrgClient | "auth client" + noAuthClient | "no auth client" } def "get admins for a given org with no error"() { given: def search = createSearchRequestForElkGrove() - UUID orgID = client.searchByLocation(search).body().organizations.first.id + UUID orgID = client.searchByLocation(search).block().organizations.first.id when: - client.getOrgOwners(orgID) + client.getOrgOwners(orgID).block() then: noExceptionThrown() where: - expectedStatus | client | title - HttpStatus.OK | authOrgClient | "auth client" - HttpStatus.OK | noAuthClient | "no auth client" + client | title + authOrgClient | "auth client" + noAuthClient | "no auth client" } def "create an org with no error"() { @@ -72,7 +70,7 @@ class OrganizationClientSpec extends JustServeSpec { .setVolunteerCenterInfo(null) .setWebsite(faker.internet().url()) when: - authOrgClient.createOrganization(orgRequest) + authOrgClient.createOrganization(orgRequest).block() then: noExceptionThrown() @@ -90,19 +88,13 @@ class OrganizationClientSpec extends JustServeSpec { .setUrl(getUniqueSlug()) when: - def response = client.createOrganization(orgCreationRequest) + client.createOrganization(orgCreationRequest).block() then: - if (expectedStatus == HttpStatus.CREATED) { - null == response - return - } - def exception = thrown(HttpClientResponseException) - exception.status == expectedStatus + thrown(HttpClientResponseException) where: expectedStatus | client | title - HttpStatus.CREATED | authOrgClient | "auth client" HttpStatus.CREATED | noAuthClient | "no auth client" } diff --git a/core/src/test/groovy/org/justserve/ProjectClientSpec.groovy b/core/src/test/groovy/org/justserve/ProjectClientSpec.groovy index bce1a6d..4e42d90 100644 --- a/core/src/test/groovy/org/justserve/ProjectClientSpec.groovy +++ b/core/src/test/groovy/org/justserve/ProjectClientSpec.groovy @@ -1,10 +1,8 @@ package org.justserve -import io.micronaut.http.HttpResponse import io.micronaut.test.extensions.spock.annotation.MicronautTest import org.justserve.model.* -import static io.micronaut.http.HttpStatus.OK import static org.justserve.model.DistanceType.MILES @MicronautTest @@ -15,12 +13,12 @@ class ProjectClientSpec extends JustServeSpec { GetProjectRequest projectRequest = new GetProjectRequest() def response = projectClient - .getProject((project as ProjectCard).getId(), "en-US", projectRequest) + .getProject((project as ProjectCard).getId(), "en-US", projectRequest).block() then: verifyAll { - response.body() != null - response.body().getProjectOwnerUserId() != null + response != null + response.getProjectOwnerUserId() != null } @@ -33,22 +31,18 @@ class ProjectClientSpec extends JustServeSpec { given: GetProjectRequest projectRequest = new GetProjectRequest() String locale = new Random().nextBoolean() ? " " : "en-US" - UUID currentOwner = projectClient.getProject((project as ProjectCard).getId(), locale, projectRequest) - .body().getProjectOwnerUserId() + UUID currentOwner = projectClient.getProject((project as ProjectCard).getId(), locale, projectRequest).block() + .getProjectOwnerUserId() ReassignProjectRequest reassignProjectRequest = new ReassignProjectRequest(readOnlyUser.uuid, currentOwner) when: - def response = projectClient.reassignProject((project as ProjectCard).getId(), reassignProjectRequest) + projectClient.reassignProject((project as ProjectCard).getId(), reassignProjectRequest).block() then: noExceptionThrown() verifyAll { - if (response.status() != OK) { - println "Warning: response status ${response.status()} != OK" - } else { - projectClient.getProject((project as ProjectCard).getId(), "en-US", projectRequest) - .body().getProjectOwnerUserId() == readOnlyUser.uuid - } + projectClient.getProject((project as ProjectCard).getId(), "en-US", projectRequest).block() + .getProjectOwnerUserId() == readOnlyUser.uuid } where: @@ -64,32 +58,30 @@ class ProjectClientSpec extends JustServeSpec { .setPublishedOnly(false).setIncludeFilledProjects(true).setDisasterRecoveryProjectsOnly(false).setTimesOfDay(null) when: - HttpResponse response = projectClient.searchProjects(request) + ProjectSearchResponse response = projectClient.searchProjects(request).block() then: verifyAll { - response.status == OK - response.body() != null - response.body().items != null + response != null + response.items != null } } void "can assign an organization to a project"() { given: - def orgSearchResponse = authOrgClient.searchByLocation(createSearchRequestForElkGrove()) - UUID orgId = orgSearchResponse.body().organizations.first().id + def orgSearchResponse = authOrgClient.searchByLocation(createSearchRequestForElkGrove()).block() + UUID orgId = orgSearchResponse.organizations.first().id ProjectCard project = searchResults.first() when: - def response = projectClient.assignOrganizationToProject(project.getId(), orgId) + projectClient.assignOrganizationToProject(project.getId(), orgId).block() then: - verifyAll { - response.status == OK - } + noExceptionThrown() + and: "validate that the reassignment worked - this is testing the underlying tech, not our codebase" - def updatedProject = projectClient.getProject(project.getId(), "en-US", new GetProjectRequest()).body() + def updatedProject = projectClient.getProject(project.getId(), "en-US", new GetProjectRequest()).block() verifyAll { updatedProject.organization.organizationId == orgId } diff --git a/core/src/test/groovy/org/justserve/UserClientSpec.groovy b/core/src/test/groovy/org/justserve/UserClientSpec.groovy index be848e5..757f39b 100644 --- a/core/src/test/groovy/org/justserve/UserClientSpec.groovy +++ b/core/src/test/groovy/org/justserve/UserClientSpec.groovy @@ -32,7 +32,7 @@ class UserClientSpec extends JustServeSpec { .addPart("termsChecked", "true") .build() when: - client.createUser(requestBody) + client.createUser(requestBody).block() then: noExceptionThrown() @@ -45,10 +45,10 @@ class UserClientSpec extends JustServeSpec { def "can get admin context for a user as an admin"(UserClient client) { when: - def response = client.getAdminContext(readOnlyUser.uuid) + def response = client.getAdminContext(readOnlyUser.uuid).block() then: - response.body() != null + response != null where: client | _ @@ -57,7 +57,7 @@ class UserClientSpec extends JustServeSpec { def "cannot get admin context for a user if not an admin"(UserClient client) { when: - client.getAdminContext(readOnlyUser.uuid) + client.getAdminContext(readOnlyUser.uuid).block() then: def exception = thrown(HttpClientResponseException) @@ -70,7 +70,7 @@ class UserClientSpec extends JustServeSpec { def "can get tempPassword for a user as an admin"(UserClient client) { when: - client.getTempPassword(new UserHashRequestByEmail(readOnlyUser.email)) + client.getTempPassword(new UserHashRequestByEmail(readOnlyUser.email)).block() then: noExceptionThrown() @@ -82,7 +82,7 @@ class UserClientSpec extends JustServeSpec { def "cannot get tempPassword for a user if not an admin"(UserClient client) { when: - client.getTempPassword(new UserHashRequestByEmail(readOnlyUser.email)) + client.getTempPassword(new UserHashRequestByEmail(readOnlyUser.email)).block() then: def exception = thrown(HttpClientResponseException) @@ -95,7 +95,7 @@ class UserClientSpec extends JustServeSpec { def "can get all user information for a user as an admin"(UserClient client) { when: - client.getAllUserInformation(readOnlyUser.uuid, true, true, 1) + client.getAllUserInformation(readOnlyUser.uuid, true, true, 1).block() then: noExceptionThrown() diff --git a/core/src/test/resources/application-test.yaml b/core/src/test/resources/application-test.yaml index 0a25b6f..43b2a31 100644 --- a/core/src/test/resources/application-test.yaml +++ b/core/src/test/resources/application-test.yaml @@ -7,4 +7,4 @@ justserve: token: ${:i-need-to-be-defined} logger: levels: - io.micronaut.http.client: DEBUG + io.micronaut.http.client: DEBUG \ No newline at end of file diff --git a/gradle.properties b/gradle.properties index 4d88273..63b2315 100644 --- a/gradle.properties +++ b/gradle.properties @@ -9,3 +9,8 @@ jsoupVersion=1.21.2 datafakerVersion=2.5.1 commonsLang3Version=3.20.0 micronautOpenapiSpecVersion=6.20.0 +jansiGraalvmVersion=1.2.0 +jansiVersion=2.4.2 +picocliShellVersion=4.7.6 +jlineVersion=3.30.5 +commonsLangVersion=3.20.0 \ No newline at end of file