From 714fb6d95731b7e222542dad1bb0f71d3bd15118 Mon Sep 17 00:00:00 2001 From: arcuri82 Date: Wed, 17 Jun 2026 21:14:18 +0200 Subject: [PATCH 1/4] refactoring for AuthWriter --- .../evomaster/core/output/auth/AuthWriter.kt | 114 ++++++++++++++++++ .../core/output/auth/CookieWriter.kt | 108 +---------------- .../evomaster/core/output/auth/TokenWriter.kt | 2 +- 3 files changed, 116 insertions(+), 108 deletions(-) create mode 100644 core/src/main/kotlin/org/evomaster/core/output/auth/AuthWriter.kt diff --git a/core/src/main/kotlin/org/evomaster/core/output/auth/AuthWriter.kt b/core/src/main/kotlin/org/evomaster/core/output/auth/AuthWriter.kt new file mode 100644 index 0000000000..52fa49e649 --- /dev/null +++ b/core/src/main/kotlin/org/evomaster/core/output/auth/AuthWriter.kt @@ -0,0 +1,114 @@ +package org.evomaster.core.output.auth + +import org.evomaster.core.output.Lines +import org.evomaster.core.output.OutputFormat +import org.evomaster.core.output.service.HttpWsTestCaseWriter +import org.evomaster.core.problem.httpws.auth.EndpointCallLogin +import org.evomaster.core.problem.rest.data.ContentType + +object AuthWriter { + + fun addCallCommand( + lines: Lines, + k: EndpointCallLogin, + testCaseWriter: HttpWsTestCaseWriter, + format: OutputFormat, + baseUrlOfSut: String, + targetVariable: String + ) { + + if(format.isJavaScript()) { + callEndpoint(lines, k, format, baseUrlOfSut) + } + + if(format.isPython()) { + lines.add("headers = {}") + } + + val contentType = k.contentType + if(contentType != null) { + when { + format.isJavaOrKotlin() -> lines.add(".contentType(\"${contentType.defaultValue}\")") + format.isJavaScript() -> lines.add(".set(\"content-type\", \"${contentType.defaultValue}\")") + format.isPython() -> { + lines.add("headers[\"content-type\"] = \"${contentType.defaultValue}\"") + } + } + + when (contentType) { + ContentType.X_WWW_FORM_URLENCODED -> { + val send = testCaseWriter.sendBodyCommand() + when { + format.isPython() -> lines.add("body = \"${k.payload}\"") + else -> lines.add(".$send(\"${k.payload}\")") + } + } + + ContentType.JSON -> { + testCaseWriter.printSendJsonBody(k.payload!!, lines) + } + + else -> { + throw IllegalStateException("Currently not supporting yet ${k.contentType} in login") + } + } + } + + for(header in k.headers) { + when { + format.isJavaOrKotlin() -> lines.add(".header(\"${header.name}\", \"${header.value}\")") + format.isJavaScript() -> lines.add(".set(\"${header.name}\", \"${header.value}\")") + format.isPython() -> { + lines.add("headers[\"${header.name}\"] = \"${header.value}\"") + } + } + } + + if (format.isJavaScript()){ + // disable redirections + lines.add(".redirects(0)") + } + + /* + For RestAssure, the call to "post" must be last, which is in opposite of what + needed in used libraries for Python and JS + */ + if(format.isJavaOrKotlin()) { + callEndpoint(lines, k, format, baseUrlOfSut) + } + + if (format.isPython()) { + lines.add("$targetVariable = requests \\") + lines.indent(2) + callEndpoint(lines, k, format, baseUrlOfSut) + lines.append(", ") + lines.indented { + lines.add("headers=headers, data=body, allow_redirects=False, verify=False)") + } + lines.deindent(2) + } + } + + private fun callEndpoint( + lines: Lines, + k: EndpointCallLogin, + format: OutputFormat, + baseUrlOfSut: String + ) { + val verb = k.verb.name.lowercase() + lines.add(".$verb(") + if (k.externalEndpointURL != null) { + lines.append("\"${k.externalEndpointURL}\"") + } else { + when { + format.isJava() || format.isJavaScript() -> lines.append("$baseUrlOfSut + \"") + format.isPython() -> lines.append("self.$baseUrlOfSut + \"") + else -> lines.append("\"\${$baseUrlOfSut}") + } + lines.append("${k.endpoint}\"") + } + if (!format.isPython()) { + lines.append(")") + } + } +} \ No newline at end of file diff --git a/core/src/main/kotlin/org/evomaster/core/output/auth/CookieWriter.kt b/core/src/main/kotlin/org/evomaster/core/output/auth/CookieWriter.kt index 9a726e13dc..f9a4304a3a 100644 --- a/core/src/main/kotlin/org/evomaster/core/output/auth/CookieWriter.kt +++ b/core/src/main/kotlin/org/evomaster/core/output/auth/CookieWriter.kt @@ -69,7 +69,7 @@ object CookieWriter { else -> cookiesName(k) } - addCallCommand(lines, k, testCaseWriter, format, baseUrlOfSut, targetCookieVariable) + AuthWriter.addCallCommand(lines, k, testCaseWriter, format, baseUrlOfSut, targetCookieVariable) when { format.isJavaOrKotlin() -> lines.add(".then().extract().cookies()") @@ -98,110 +98,4 @@ object CookieWriter { } } } - - - - fun addCallCommand( - lines: Lines, - k: EndpointCallLogin, - testCaseWriter: HttpWsTestCaseWriter, - format: OutputFormat, - baseUrlOfSut: String, - targetVariable: String - ) { - - if(format.isJavaScript()) { - callEndpoint(lines, k, format, baseUrlOfSut) - } - - if(format.isPython()) { - lines.add("headers = {}") - } - - val contentType = k.contentType - if(contentType != null) { - when { - format.isJavaOrKotlin() -> lines.add(".contentType(\"${contentType.defaultValue}\")") - format.isJavaScript() -> lines.add(".set(\"content-type\", \"${contentType.defaultValue}\")") - format.isPython() -> { - lines.add("headers[\"content-type\"] = \"${contentType.defaultValue}\"") - } - } - - when (contentType) { - ContentType.X_WWW_FORM_URLENCODED -> { - val send = testCaseWriter.sendBodyCommand() - when { - format.isPython() -> lines.add("body = \"${k.payload}\"") - else -> lines.add(".$send(\"${k.payload}\")") - } - } - - ContentType.JSON -> { - testCaseWriter.printSendJsonBody(k.payload!!, lines) - } - - else -> { - throw IllegalStateException("Currently not supporting yet ${k.contentType} in login") - } - } - } - - for(header in k.headers) { - when { - format.isJavaOrKotlin() -> lines.add(".header(\"${header.name}\", \"${header.value}\")") - format.isJavaScript() -> lines.add(".set(\"${header.name}\", \"${header.value}\")") - format.isPython() -> { - lines.add("headers[\"${header.name}\"] = \"${header.value}\"") - } - } - } - - if (format.isJavaScript()){ - // disable redirections - lines.add(".redirects(0)") - } - - /* - For RestAssure, the call to "post" must be last, which is in opposite of what - needed in used libraries for Python and JS - */ - if(format.isJavaOrKotlin()) { - callEndpoint(lines, k, format, baseUrlOfSut) - } - - if (format.isPython()) { - lines.add("$targetVariable = requests \\") - lines.indent(2) - callEndpoint(lines, k, format, baseUrlOfSut) - lines.append(", ") - lines.indented { - lines.add("headers=headers, data=body, allow_redirects=False, verify=False)") - } - lines.deindent(2) - } - } - - private fun callEndpoint( - lines: Lines, - k: EndpointCallLogin, - format: OutputFormat, - baseUrlOfSut: String - ) { - val verb = k.verb.name.lowercase() - lines.add(".$verb(") - if (k.externalEndpointURL != null) { - lines.append("\"${k.externalEndpointURL}\"") - } else { - when { - format.isJava() || format.isJavaScript() -> lines.append("$baseUrlOfSut + \"") - format.isPython() -> lines.append("self.$baseUrlOfSut + \"") - else -> lines.append("\"\${$baseUrlOfSut}") - } - lines.append("${k.endpoint}\"") - } - if (!format.isPython()) { - lines.append(")") - } - } } diff --git a/core/src/main/kotlin/org/evomaster/core/output/auth/TokenWriter.kt b/core/src/main/kotlin/org/evomaster/core/output/auth/TokenWriter.kt index ec2df92b7e..f5b8242c72 100644 --- a/core/src/main/kotlin/org/evomaster/core/output/auth/TokenWriter.kt +++ b/core/src/main/kotlin/org/evomaster/core/output/auth/TokenWriter.kt @@ -69,7 +69,7 @@ object TokenWriter { lines.indent(2) } - CookieWriter.addCallCommand(lines,k,testCaseWriter,format,baseUrlOfSut, responseName(k)) + AuthWriter.addCallCommand(lines,k,testCaseWriter,format,baseUrlOfSut, responseName(k)) var path = token.extractSelector.substring(1).replace("/",".") From 02768ae56a9a5c2cf37eda6b29e24024db1266ef Mon Sep 17 00:00:00 2001 From: arcuri82 Date: Thu, 18 Jun 2026 21:24:42 +0200 Subject: [PATCH 2/4] refactoring/cleaning --- .../evomaster/core/output/auth/AuthWriter.kt | 6 +- .../core/output/auth/CookieWriter.kt | 2 +- .../evomaster/core/output/auth/TokenWriter.kt | 2 +- .../core/problem/httpws/auth/AuthUtils.kt | 8 +- .../problem/httpws/auth/CallToEndpoint.kt | 84 +++++++++ .../problem/httpws/auth/EndpointCallLogin.kt | 160 ++++++------------ .../httpws/auth/HttpWsAuthenticationInfo.kt | 2 +- .../core/output/CookieLoginGetUrlTest.kt | 7 +- 8 files changed, 148 insertions(+), 123 deletions(-) create mode 100644 core/src/main/kotlin/org/evomaster/core/problem/httpws/auth/CallToEndpoint.kt diff --git a/core/src/main/kotlin/org/evomaster/core/output/auth/AuthWriter.kt b/core/src/main/kotlin/org/evomaster/core/output/auth/AuthWriter.kt index 52fa49e649..f4683b8a52 100644 --- a/core/src/main/kotlin/org/evomaster/core/output/auth/AuthWriter.kt +++ b/core/src/main/kotlin/org/evomaster/core/output/auth/AuthWriter.kt @@ -3,14 +3,14 @@ package org.evomaster.core.output.auth import org.evomaster.core.output.Lines import org.evomaster.core.output.OutputFormat import org.evomaster.core.output.service.HttpWsTestCaseWriter -import org.evomaster.core.problem.httpws.auth.EndpointCallLogin +import org.evomaster.core.problem.httpws.auth.CallToEndpoint import org.evomaster.core.problem.rest.data.ContentType object AuthWriter { fun addCallCommand( lines: Lines, - k: EndpointCallLogin, + k: CallToEndpoint, testCaseWriter: HttpWsTestCaseWriter, format: OutputFormat, baseUrlOfSut: String, @@ -91,7 +91,7 @@ object AuthWriter { private fun callEndpoint( lines: Lines, - k: EndpointCallLogin, + k: CallToEndpoint, format: OutputFormat, baseUrlOfSut: String ) { diff --git a/core/src/main/kotlin/org/evomaster/core/output/auth/CookieWriter.kt b/core/src/main/kotlin/org/evomaster/core/output/auth/CookieWriter.kt index f9a4304a3a..ee289f5319 100644 --- a/core/src/main/kotlin/org/evomaster/core/output/auth/CookieWriter.kt +++ b/core/src/main/kotlin/org/evomaster/core/output/auth/CookieWriter.kt @@ -69,7 +69,7 @@ object CookieWriter { else -> cookiesName(k) } - AuthWriter.addCallCommand(lines, k, testCaseWriter, format, baseUrlOfSut, targetCookieVariable) + AuthWriter.addCallCommand(lines, k.call, testCaseWriter, format, baseUrlOfSut, targetCookieVariable) when { format.isJavaOrKotlin() -> lines.add(".then().extract().cookies()") diff --git a/core/src/main/kotlin/org/evomaster/core/output/auth/TokenWriter.kt b/core/src/main/kotlin/org/evomaster/core/output/auth/TokenWriter.kt index f5b8242c72..26908db043 100644 --- a/core/src/main/kotlin/org/evomaster/core/output/auth/TokenWriter.kt +++ b/core/src/main/kotlin/org/evomaster/core/output/auth/TokenWriter.kt @@ -69,7 +69,7 @@ object TokenWriter { lines.indent(2) } - AuthWriter.addCallCommand(lines,k,testCaseWriter,format,baseUrlOfSut, responseName(k)) + AuthWriter.addCallCommand(lines,k.call,testCaseWriter,format,baseUrlOfSut, responseName(k)) var path = token.extractSelector.substring(1).replace("/",".") diff --git a/core/src/main/kotlin/org/evomaster/core/problem/httpws/auth/AuthUtils.kt b/core/src/main/kotlin/org/evomaster/core/problem/httpws/auth/AuthUtils.kt index cb8afa5e8d..e4db52fb83 100644 --- a/core/src/main/kotlin/org/evomaster/core/problem/httpws/auth/AuthUtils.kt +++ b/core/src/main/kotlin/org/evomaster/core/problem/httpws/auth/AuthUtils.kt @@ -46,7 +46,7 @@ object AuthUtils { } val data = tl.token ?: throw IllegalArgumentException("Token based login requires token definition") - val response = makeCall(client, tl, baseUrl) + val response = makeCall(client, tl.name, tl.call, baseUrl) ?: continue var token = when(data.extractFrom){ @@ -113,7 +113,7 @@ object AuthUtils { } - val response = makeCall(client, cl, baseUrl) + val response = makeCall(client, cl.name, cl.call, baseUrl) ?: continue response.close() @@ -130,7 +130,7 @@ object AuthUtils { - private fun makeCall(client: Client, x: EndpointCallLogin, baseUrl: String) : Response?{ + private fun makeCall(client: Client, name: String, x: CallToEndpoint, baseUrl: String) : Response?{ val mediaType = when (x.contentType) { ContentType.X_WWW_FORM_URLENCODED -> MediaType.APPLICATION_FORM_URLENCODED_TYPE @@ -171,7 +171,7 @@ object AuthUtils { val response = try { invocation.invoke() } catch (e: Exception) { - log.warn("Failed to login for ${x.name}: $e") + log.warn("Failed to login for ${name}: $e") return null } diff --git a/core/src/main/kotlin/org/evomaster/core/problem/httpws/auth/CallToEndpoint.kt b/core/src/main/kotlin/org/evomaster/core/problem/httpws/auth/CallToEndpoint.kt new file mode 100644 index 0000000000..c7f966af6c --- /dev/null +++ b/core/src/main/kotlin/org/evomaster/core/problem/httpws/auth/CallToEndpoint.kt @@ -0,0 +1,84 @@ +package org.evomaster.core.problem.httpws.auth + +import org.evomaster.core.Lazy +import org.evomaster.core.problem.rest.data.ContentType +import org.evomaster.core.problem.rest.data.HttpVerb +import java.net.MalformedURLException +import java.net.URL + +class CallToEndpoint( + /** + * The endpoint path (eg "/v1/api/data") where to execute the call. + * It assumes it is on same server of API. + * If not, rather use externalEndpointURL + */ + val endpoint: String?, + + /** + * If the endpoint is on a different server, here can rather specify the full URL for it. + */ + val externalEndpointURL: String?, + + /** + * The raw payload to send, as a string, if any + */ + val payload: String?, + + + val headers: List, + + /** + * The verb used to make the call to the endpoint. + * Most of the time, for auth this will be a POST. + */ + val verb: HttpVerb, + + /** + * Specify the format in which the payload is sent to the endpoint. + * A common example is "application/json" + */ + val contentType: ContentType?, +) { + + init{ + if (endpoint == null && externalEndpointURL == null) { + throw IllegalArgumentException("Either 'endpoint' or 'externalEndpointURL' should be specified") + } + if (endpoint != null && externalEndpointURL != null) { + throw IllegalArgumentException("Cannot have both 'endpoint' and 'externalEndpointURL' specified. It is ambiguous.") + } + if (endpoint != null && !endpoint.startsWith("/")) { + throw IllegalArgumentException( + "Endpoint definition must start with a /. It is not a full URL." + + " For example: '/login'" + ) + } + if (externalEndpointURL != null) { + try { + //FIXME should not use URL for validation, as Java URL is not standard compliant + URL(externalEndpointURL) + } catch (e: MalformedURLException) { + throw IllegalArgumentException("'externalEndpointURL' is not a valid URL: ${e.message}") + } + } + if( (payload != null && contentType==null) || (payload==null && contentType!=null)) { + throw IllegalArgumentException("Payload and contentType must be both specified, or none specified") + } + } + + + fun getUrl(baseUrl: String): String { + val s = baseUrl.trim() + if (externalEndpointURL != null) return externalEndpointURL + + if (!s.startsWith("http://", true) && !s.startsWith("https://")) { + throw IllegalArgumentException("baseUrl should use HTTP(S): $baseUrl") + } + Lazy.assert { endpoint != null && endpoint.startsWith("/") } + return if (s.endsWith("/")) { + s.substring(0, s.length - 1) + endpoint + } else { + s + endpoint + } + } +} \ No newline at end of file diff --git a/core/src/main/kotlin/org/evomaster/core/problem/httpws/auth/EndpointCallLogin.kt b/core/src/main/kotlin/org/evomaster/core/problem/httpws/auth/EndpointCallLogin.kt index bf0e705f5a..7e9226b682 100644 --- a/core/src/main/kotlin/org/evomaster/core/problem/httpws/auth/EndpointCallLogin.kt +++ b/core/src/main/kotlin/org/evomaster/core/problem/httpws/auth/EndpointCallLogin.kt @@ -18,112 +18,69 @@ class EndpointCallLogin( */ val name: String, - /** - * The endpoint path (eg "/login") where to execute the login. - * It assumes it is on same server of API. - * If not, rather use externalEndpointURL - */ - val endpoint: String?, - - /** - * If the login endpoint is on a different server, here can rather specify the full URL for it. - */ - val externalEndpointURL: String?, - - /** - * The raw payload to send, as a string, if any - */ - val payload: String?, - - val headers: List, - - /** - * The verb used to connect to the login endpoint. - * Most of the time, this will be a POST. - */ - val verb: HttpVerb, - - /** - * Specify the format in which the payload is sent to the login endpoint. - * A common example is "application/json" - */ - val contentType: ContentType?, + val call: CallToEndpoint, val token: TokenHandling? = null ) { init { - if(name.isBlank()){ + if (name.isBlank()) { throw IllegalArgumentException("Empty name") } - if (endpoint == null && externalEndpointURL == null) { - throw IllegalArgumentException("Either 'endpoint' or 'externalEndpointURL' should be specified") - } - if (endpoint != null && externalEndpointURL != null) { - throw IllegalArgumentException("Cannot have both 'endpoint' and 'externalEndpointURL' specified. It is ambiguous.") - } - if (endpoint != null && !endpoint.startsWith("/")) { - throw IllegalArgumentException( - "Login endpoint definition must start with a /. It is not a full URL." + - " For example: '/login'" - ) - } - if (externalEndpointURL != null) { - try { - URL(externalEndpointURL) - } catch (e: MalformedURLException) { - throw IllegalArgumentException("'externalEndpointURL' is not a valid URL: ${e.message}") - } - } - if( (payload != null && contentType==null) || (payload==null && contentType!=null)) { - throw IllegalArgumentException("Payload and contentType must be both specified, or none specified") - } } companion object { fun fromDto(name: String, dto: LoginEndpoint, externalEndpointURL: String? = null) = EndpointCallLogin( name = name, - endpoint = dto.endpoint, - externalEndpointURL = if(externalEndpointURL != null){ - if(externalEndpointURL.startsWith("http")){ - externalEndpointURL - } else if(dto.externalEndpointURL == null){ - /* - if we are doing a partial replacement with hostname:port, but there is no - origin URL, then there is nothing to do. - */ - null - } else { - val tokens = externalEndpointURL.split(":") - if(tokens.size != 2){ - throw ConfigProblemException("Invalid hostname:port pair -> $externalEndpointURL") - } - val hostname = tokens[0] - val port = try{ - tokens[1].toInt() - } catch (e: NumberFormatException){ - throw ConfigProblemException("Invalid port number in hostname:port pair " + - "-> $externalEndpointURL -> ${e.message}") - } - - val builder = try{ - URIBuilder(dto.externalEndpointURL) - } catch (e: MalformedURLException){ - throw ConfigProblemException("Invalid dto.externalEndpointURL -> ${e.message}") + call = CallToEndpoint( + endpoint = dto.endpoint, + externalEndpointURL = if (externalEndpointURL != null) { + if (externalEndpointURL.startsWith("http")) { + externalEndpointURL + } else if (dto.externalEndpointURL == null) { + /* + if we are doing a partial replacement with hostname:port, but there is no + origin URL, then there is nothing to do. + */ + null + } else { + val tokens = externalEndpointURL.split(":") + if (tokens.size != 2) { + throw ConfigProblemException("Invalid hostname:port pair -> $externalEndpointURL") + } + val hostname = tokens[0] + val port = try { + tokens[1].toInt() + } catch (e: NumberFormatException) { + throw ConfigProblemException( + "Invalid port number in hostname:port pair " + + "-> $externalEndpointURL -> ${e.message}" + ) + } + + val builder = try { + URIBuilder(dto.externalEndpointURL) + } catch (e: MalformedURLException) { + throw ConfigProblemException("Invalid dto.externalEndpointURL -> ${e.message}") + } + builder.setHost(hostname) + builder.setPort(port) + builder.build().toString() } - builder.setHost(hostname) - builder.setPort(port) - builder.build().toString() - } - } else { - dto.externalEndpointURL - }, - payload = dto.payloadRaw ?: - dto.payloadUserPwd?.let { computePayload(it, ContentType.from(dto.contentType)) }, - headers = dto.headers?.map { AuthenticationHeader(it.name, it.value) } ?: emptyList(), - verb = HttpVerb.valueOf(dto.verb.toString()), - contentType = dto.contentType?.let { ContentType.from(it)}, - token = if (dto.expectCookies!=null && dto.expectCookies) null else computeTokenHandling(dto.token) + } else { + dto.externalEndpointURL + }, + payload = dto.payloadRaw ?: dto.payloadUserPwd?.let { + computePayload( + it, + ContentType.from(dto.contentType) + ) + }, + headers = dto.headers?.map { AuthenticationHeader(it.name, it.value) } ?: emptyList(), + verb = HttpVerb.valueOf(dto.verb.toString()), + contentType = dto.contentType?.let { ContentType.from(it) } + ), + token = if (dto.expectCookies != null && dto.expectCookies) null else computeTokenHandling(dto.token) ) private fun computeTokenHandling(dto: com.webfuzzing.commons.auth.TokenHandling) = TokenHandling( @@ -153,21 +110,4 @@ class EndpointCallLogin( } fun expectsCookie() = token == null - - fun getUrl(baseUrl: String): String { - val s = baseUrl.trim() - if (externalEndpointURL != null) return externalEndpointURL - - if (!s.startsWith("http://", true) && !s.startsWith("https://")) { - throw IllegalArgumentException("baseUrl should use HTTP(S): $baseUrl") - } - Lazy.assert { endpoint != null && endpoint.startsWith("/") } - return if (s.endsWith("/")) { - s.substring(0, s.length - 1) + endpoint - } else { - s + endpoint - } - } - - } \ No newline at end of file diff --git a/core/src/main/kotlin/org/evomaster/core/problem/httpws/auth/HttpWsAuthenticationInfo.kt b/core/src/main/kotlin/org/evomaster/core/problem/httpws/auth/HttpWsAuthenticationInfo.kt index 94f621e526..318c0a0e2b 100644 --- a/core/src/main/kotlin/org/evomaster/core/problem/httpws/auth/HttpWsAuthenticationInfo.kt +++ b/core/src/main/kotlin/org/evomaster/core/problem/httpws/auth/HttpWsAuthenticationInfo.kt @@ -81,7 +81,7 @@ open class HttpWsAuthenticationInfo( */ fun excludeAuthCheck(action: Action) : Boolean{ if (action is RestCallAction && endpointCallLogin != null){ - return action.getName() == "POST:${endpointCallLogin.endpoint}" + return action.getName() == "POST:${endpointCallLogin.call.endpoint}" } return false } diff --git a/core/src/test/kotlin/org/evomaster/core/output/CookieLoginGetUrlTest.kt b/core/src/test/kotlin/org/evomaster/core/output/CookieLoginGetUrlTest.kt index 08a6be2185..cc2550a447 100644 --- a/core/src/test/kotlin/org/evomaster/core/output/CookieLoginGetUrlTest.kt +++ b/core/src/test/kotlin/org/evomaster/core/output/CookieLoginGetUrlTest.kt @@ -1,5 +1,6 @@ package org.evomaster.core.output +import org.evomaster.core.problem.httpws.auth.CallToEndpoint import org.evomaster.core.problem.httpws.auth.EndpointCallLogin import org.evomaster.core.problem.rest.data.ContentType import org.evomaster.core.problem.rest.data.HttpVerb @@ -10,10 +11,10 @@ class CookieLoginGetUrlTest { @Test fun testCombineUrl() { - val urlWithFS = EndpointCallLogin("foo","/login",null, "payload", listOf(), HttpVerb.POST, ContentType.JSON) + val urlWithFS = EndpointCallLogin("foo", CallToEndpoint("/login",null, "payload", listOf(), HttpVerb.POST, ContentType.JSON)) val expected = "http://localhost:8080/login" - assertEquals(expected, urlWithFS.getUrl("http://localhost:8080")) - assertEquals(expected, urlWithFS.getUrl("http://localhost:8080/")) + assertEquals(expected, urlWithFS.call.getUrl("http://localhost:8080")) + assertEquals(expected, urlWithFS.call.getUrl("http://localhost:8080/")) } } From 99d81cacd16e9eb8acec54fe3db6c43b8b525716 Mon Sep 17 00:00:00 2001 From: arcuri82 Date: Thu, 18 Jun 2026 21:37:17 +0200 Subject: [PATCH 3/4] some documentation --- .../evomaster/core/output/auth/AuthWriter.kt | 21 ++++++++++++++++--- .../core/output/auth/CookieWriter.kt | 3 +-- .../evomaster/core/output/auth/TokenWriter.kt | 2 +- 3 files changed, 20 insertions(+), 6 deletions(-) diff --git a/core/src/main/kotlin/org/evomaster/core/output/auth/AuthWriter.kt b/core/src/main/kotlin/org/evomaster/core/output/auth/AuthWriter.kt index f4683b8a52..f0f01d394e 100644 --- a/core/src/main/kotlin/org/evomaster/core/output/auth/AuthWriter.kt +++ b/core/src/main/kotlin/org/evomaster/core/output/auth/AuthWriter.kt @@ -8,13 +8,24 @@ import org.evomaster.core.problem.rest.data.ContentType object AuthWriter { - fun addCallCommand( + /** + * Add lines related to make the call (eg setup of body payload), without the opening function (eg, 'given()' for + * RestAssured). + * Python is treated specially, as before the opening function we need to setup some variables. + * The opening function is then + * + * @param lines Current lines buffer + * @param k The endpoint to call + * @param targetVariable Only used for languages like Python. If present, in the generated code the result of call + * is saved to this variable. + */ + fun addBodyOfCallCommand( lines: Lines, k: CallToEndpoint, testCaseWriter: HttpWsTestCaseWriter, format: OutputFormat, baseUrlOfSut: String, - targetVariable: String + targetVariable: String? ) { if(format.isJavaScript()) { @@ -78,7 +89,11 @@ object AuthWriter { } if (format.isPython()) { - lines.add("$targetVariable = requests \\") + if(targetVariable != null){ + lines.add("$targetVariable = requests \\") + } else { + lines.add("requests \\") + } lines.indent(2) callEndpoint(lines, k, format, baseUrlOfSut) lines.append(", ") diff --git a/core/src/main/kotlin/org/evomaster/core/output/auth/CookieWriter.kt b/core/src/main/kotlin/org/evomaster/core/output/auth/CookieWriter.kt index ee289f5319..4193276bc6 100644 --- a/core/src/main/kotlin/org/evomaster/core/output/auth/CookieWriter.kt +++ b/core/src/main/kotlin/org/evomaster/core/output/auth/CookieWriter.kt @@ -6,7 +6,6 @@ import org.evomaster.core.output.TestWriterUtils import org.evomaster.core.output.service.HttpWsTestCaseWriter import org.evomaster.core.problem.httpws.HttpWsAction import org.evomaster.core.problem.httpws.auth.EndpointCallLogin -import org.evomaster.core.problem.rest.data.ContentType import org.evomaster.core.search.EvaluatedIndividual import org.evomaster.core.search.Individual @@ -69,7 +68,7 @@ object CookieWriter { else -> cookiesName(k) } - AuthWriter.addCallCommand(lines, k.call, testCaseWriter, format, baseUrlOfSut, targetCookieVariable) + AuthWriter.addBodyOfCallCommand(lines, k.call, testCaseWriter, format, baseUrlOfSut, targetCookieVariable) when { format.isJavaOrKotlin() -> lines.add(".then().extract().cookies()") diff --git a/core/src/main/kotlin/org/evomaster/core/output/auth/TokenWriter.kt b/core/src/main/kotlin/org/evomaster/core/output/auth/TokenWriter.kt index 26908db043..5500c0df83 100644 --- a/core/src/main/kotlin/org/evomaster/core/output/auth/TokenWriter.kt +++ b/core/src/main/kotlin/org/evomaster/core/output/auth/TokenWriter.kt @@ -69,7 +69,7 @@ object TokenWriter { lines.indent(2) } - AuthWriter.addCallCommand(lines,k.call,testCaseWriter,format,baseUrlOfSut, responseName(k)) + AuthWriter.addBodyOfCallCommand(lines,k.call,testCaseWriter,format,baseUrlOfSut, responseName(k)) var path = token.extractSelector.substring(1).replace("/",".") From 40a3fa6ff80fd9e946463af8e5cdbb22db454b77 Mon Sep 17 00:00:00 2001 From: arcuri82 Date: Thu, 18 Jun 2026 21:55:56 +0200 Subject: [PATCH 4/4] clarification --- .../main/kotlin/org/evomaster/core/output/auth/AuthWriter.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/main/kotlin/org/evomaster/core/output/auth/AuthWriter.kt b/core/src/main/kotlin/org/evomaster/core/output/auth/AuthWriter.kt index f0f01d394e..6bc5ce2200 100644 --- a/core/src/main/kotlin/org/evomaster/core/output/auth/AuthWriter.kt +++ b/core/src/main/kotlin/org/evomaster/core/output/auth/AuthWriter.kt @@ -12,7 +12,7 @@ object AuthWriter { * Add lines related to make the call (eg setup of body payload), without the opening function (eg, 'given()' for * RestAssured). * Python is treated specially, as before the opening function we need to setup some variables. - * The opening function is then + * The opening function is then added here in this function. * * @param lines Current lines buffer * @param k The endpoint to call