diff --git a/server/src/main/kotlin/suwayomi/tachidesk/graphql/server/JavalinGraphQLRequestParser.kt b/server/src/main/kotlin/suwayomi/tachidesk/graphql/server/JavalinGraphQLRequestParser.kt index a6114abe4..d55d047ef 100644 --- a/server/src/main/kotlin/suwayomi/tachidesk/graphql/server/JavalinGraphQLRequestParser.kt +++ b/server/src/main/kotlin/suwayomi/tachidesk/graphql/server/JavalinGraphQLRequestParser.kt @@ -21,7 +21,7 @@ class JavalinGraphQLRequestParser : GraphQLRequestParser { @Suppress("PARAMETER_NAME_CHANGED_ON_OVERRIDE", "UNCHECKED_CAST") override suspend fun parseRequest(context: Context): GraphQLServerRequest? { return try { - val formParam = context.formParam("operation") + val formParam = context.formParam("operations") ?: return context.bodyAsClass(GraphQLServerRequest::class.java) val request = context.jsonMapper().fromJsonString( @@ -35,18 +35,12 @@ class JavalinGraphQLRequestParser : GraphQLRequestParser { ) }.orEmpty() - val filesMap = map.keys - .sortedBy { it.toIntOrNull() } - .map { context.uploadedFile(it) } - - val mapItems = map.flatMap { (index, variables) -> - val indexInt = index.toIntOrNull() ?: return@flatMap emptyList() - val file = filesMap.getOrNull(indexInt) + val mapItems = map.flatMap { (key, variables) -> + val file = context.uploadedFile(key) variables.map { fullVariable -> val variable = fullVariable.removePrefix("variables.").substringBefore('.') val listIndex = fullVariable.substringAfterLast('.').toIntOrNull() MapItem( - indexInt, variable, listIndex, file @@ -74,7 +68,6 @@ class JavalinGraphQLRequestParser : GraphQLRequestParser { } data class MapItem( - val index: Int, val variable: String, val listIndex: Int?, val file: UploadedFile? diff --git a/server/src/test/kotlin/suwayomi/tachidesk/graphql/RequestParserTest.kt b/server/src/test/kotlin/suwayomi/tachidesk/graphql/RequestParserTest.kt new file mode 100644 index 000000000..ece905fc1 --- /dev/null +++ b/server/src/test/kotlin/suwayomi/tachidesk/graphql/RequestParserTest.kt @@ -0,0 +1,60 @@ +package suwayomi.tachidesk.graphql + +import com.expediagroup.graphql.server.types.GraphQLRequest +import io.javalin.http.Context +import io.javalin.http.UploadedFile +import io.javalin.plugin.json.JSON_MAPPER_KEY +import io.javalin.plugin.json.JavalinJackson +import io.javalin.plugin.json.JsonMapper +import io.mockk.every +import io.mockk.mockk +import kotlinx.coroutines.test.runTest +import org.junit.jupiter.api.Test +import suwayomi.tachidesk.graphql.server.JavalinGraphQLRequestParser +import java.io.ByteArrayInputStream +import kotlin.test.assertIs +import kotlin.test.assertNotNull + +class RequestParserTest { + private val ctx = mockk(relaxed = true) + private val requestParser = JavalinGraphQLRequestParser() + + @Test + fun testZero() = runTest { + every { ctx.appAttribute(JSON_MAPPER_KEY) } returns (JavalinJackson(JavalinJackson.defaultMapper())) + every { ctx.formParam("operations") } returns """{ "query": "mutation (${'$'}file: Upload!) { singleUpload(file: ${'$'}file) { id } }", "variables": { "file": null } }""" + every { ctx.formParam("map") } returns """{ "0": ["variables.file"] }""" + every { ctx.uploadedFile("0") } returns UploadedFile(ByteArrayInputStream(byteArrayOf()), "", "", "", 0) + val test = requestParser.parseRequest(ctx) + assertIs(test) + assertNotNull(test.variables?.get("file")) + println("File: " + test.variables?.get("file")) + } + + @Test + fun testTest() = runTest { + every { ctx.appAttribute(JSON_MAPPER_KEY) } returns (JavalinJackson(JavalinJackson.defaultMapper())) + every { ctx.formParam("operations") } returns """{ "query": "mutation (${'$'}file: Upload!) { singleUpload(file: ${'$'}file) { id } }", "variables": { "file": null } }""" + every { ctx.formParam("map") } returns """{ "test": ["variables.file"] }""" + every { ctx.uploadedFile("test") } returns UploadedFile(ByteArrayInputStream(byteArrayOf()), "", "", "", 0) + val test = requestParser.parseRequest(ctx) + assertIs(test) + assertNotNull(test.variables?.get("file")) + println("File: " + test.variables?.get("file")) + } + + @Test + fun testList() = runTest { + every { ctx.appAttribute(JSON_MAPPER_KEY) } returns (JavalinJackson(JavalinJackson.defaultMapper())) + every { ctx.formParam("operations") } returns """{ "query": "mutation (${'$'}files: [Upload!]!) { singleUpload(files: ${'$'}files) { id } }", "variables": { "files": [null, null] } }""" + every { ctx.formParam("map") } returns """{ "test": ["variables.files.0"], "test2": ["variables.files.1"] }""" + every { ctx.uploadedFile("test") } returns UploadedFile(ByteArrayInputStream(byteArrayOf()), "", "", "", 0) + every { ctx.uploadedFile("test2") } returns UploadedFile(ByteArrayInputStream(byteArrayOf()), "", "", "", 0) + val test = requestParser.parseRequest(ctx) + assertIs(test) + val files = test.variables?.get("files") + assertIs>(files) + assert(files.all { it is UploadedFile }) + println("Files: $files") + } +}