package org.jeudego.pairgoth.test import com.republicate.kson.Json import org.jeudego.pairgoth.api.ApiHandler import org.jeudego.pairgoth.web.ApiServlet import org.jeudego.pairgoth.web.SSEServlet import org.jeudego.pairgoth.web.WebappManager import org.mockito.kotlin.argumentCaptor import org.mockito.kotlin.doAnswer import org.mockito.kotlin.doReturn import org.mockito.kotlin.eq import org.mockito.kotlin.mock import java.io.BufferedReader import java.io.File import java.io.IOException import java.io.PrintWriter import java.io.StringReader import java.io.StringWriter import java.util.* import java.util.regex.Pattern import java.util.zip.ZipEntry import java.util.zip.ZipException import java.util.zip.ZipFile import javax.servlet.http.HttpServletRequest import javax.servlet.http.HttpServletResponse // J2EE server basic mocking object TestAPI { fun Any?.toUnit() = Unit private val apiServlet = ApiServlet() private val sseServlet = SSEServlet() private fun testRequest(reqMethod: String, uri: String, accept: String = "application/json", payload: T? = null): String { WebappManager.properties["webapp.env"] = "test" // mock request val myHeaderNames = if (reqMethod == "GET") emptyList() else listOf("Content-Type") val selector = argumentCaptor() val subSelector = argumentCaptor() val reqPayload = argumentCaptor() val myReader = payload?.let { BufferedReader(StringReader(payload.toString())) } val req = mock { on { method } doReturn reqMethod on { requestURI } doReturn uri on { setAttribute(eq(ApiHandler.SELECTOR_KEY), selector.capture()) } doAnswer {} on { setAttribute(eq(ApiHandler.SUBSELECTOR_KEY), subSelector.capture()) } doAnswer {} on { setAttribute(eq(ApiHandler.PAYLOAD_KEY), reqPayload.capture()) } doAnswer {} on { getAttribute(ApiHandler.SELECTOR_KEY) } doAnswer { selector.allValues.lastOrNull() } on { getAttribute(ApiHandler.SUBSELECTOR_KEY) } doAnswer { subSelector.allValues.lastOrNull() } on { getAttribute(ApiHandler.PAYLOAD_KEY) } doAnswer { reqPayload.allValues.lastOrNull() } on { reader } doReturn myReader on { scheme } doReturn "http" on { localName } doReturn "pairgoth" on { localPort } doReturn 80 on { contextPath } doReturn "" on { contentType } doReturn if (reqMethod == "GET") null else when (payload) { is Json -> "application/json; charset=UTF-8" is String -> "application/xml; charset=UTF-8" else -> throw Error("unhandled case") } on { headerNames } doReturn Collections.enumeration(myHeaderNames) on { getHeader(eq("Accept")) } doReturn accept } // mock response val buffer = StringWriter() val errCode = argumentCaptor() val errMessage = argumentCaptor() val resp = mock { on { writer } doAnswer { PrintWriter(buffer) } on { sendError(errCode.capture(), errMessage.capture()) } doAnswer { throw Error("${errCode.lastValue} ${errMessage.lastValue}") } } when (reqMethod) { "GET" -> apiServlet.doGet(req, resp) "POST" -> apiServlet.doPost(req, resp) "PUT" -> apiServlet.doPut(req, resp) "DELETE" -> apiServlet.doDelete(req, resp) } return buffer.toString() ?: throw Error("no response payload") } fun get(uri: String): Json = Json.parse(testRequest("GET", uri)) ?: throw Error("no payload") fun getXml(uri: String): String = testRequest("GET", uri, "application/xml") fun post(uri: String, payload: T) = Json.parse(testRequest("POST", uri, payload = payload)) ?: throw Error("no payload") fun put(uri: String, payload: T) = Json.parse(testRequest("PUT", uri, payload = payload)) ?: throw Error("no payload") fun delete(uri: String, payload: T) = Json.parse(testRequest("DELETE", uri, payload = payload)) ?: throw Error("no payload") } // Get a list of resources fun getTestResources(path: String) = File("${System.getProperty("user.dir")}/src/test/resources/$path").listFiles()