From 09f0a6e204be415b52f9334e03586028d6ea0120 Mon Sep 17 00:00:00 2001 From: Nishant-Sehgal Date: Thu, 8 Oct 2020 13:21:18 +0530 Subject: [PATCH 1/4] Issue-1076 Updating cucumber-reporting version to 5.3.1 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 29f25f82b..2feeb882b 100755 --- a/pom.xml +++ b/pom.xml @@ -43,7 +43,7 @@ 5.2.9.RELEASE 2.3.4.RELEASE 0.7.9 - 3.8.0 + 5.3.1 From faa60053524c2769511508ec291af70149145c38 Mon Sep 17 00:00:00 2001 From: lzaltzberg Date: Fri, 9 Oct 2020 00:23:49 +0300 Subject: [PATCH 2/4] Issue #1306 Mock Jersey Servlet doesnt add query params to the requestURI --- .../java/com/intuit/karate/mock/servlet/MockHttpClient.java | 2 +- .../src/test/java/mock/jersey/HelloResource.java | 5 +++-- .../src/test/java/mock/jersey/hello-http.feature | 3 ++- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/karate-mock-servlet/src/main/java/com/intuit/karate/mock/servlet/MockHttpClient.java b/karate-mock-servlet/src/main/java/com/intuit/karate/mock/servlet/MockHttpClient.java index fd7fb332e..870162f1d 100644 --- a/karate-mock-servlet/src/main/java/com/intuit/karate/mock/servlet/MockHttpClient.java +++ b/karate-mock-servlet/src/main/java/com/intuit/karate/mock/servlet/MockHttpClient.java @@ -130,7 +130,7 @@ protected void buildParam(String name, Object... values) { for (Object o : values) { list.add(o == null ? null : o.toString()); } - requestBuilder.param(name, list.toArray(new String[]{})); + requestBuilder.queryParam(name, list.toArray(new String[]{})); } @Override diff --git a/karate-mock-servlet/src/test/java/mock/jersey/HelloResource.java b/karate-mock-servlet/src/test/java/mock/jersey/HelloResource.java index cceb76aa5..5a89e0ad4 100644 --- a/karate-mock-servlet/src/test/java/mock/jersey/HelloResource.java +++ b/karate-mock-servlet/src/test/java/mock/jersey/HelloResource.java @@ -27,6 +27,7 @@ import javax.ws.rs.POST; import javax.ws.rs.Path; import javax.ws.rs.Produces; +import javax.ws.rs.QueryParam; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -41,8 +42,8 @@ public class HelloResource { @GET @Produces("text/plain") - public String getHello() { - return "hello world"; + public String getHello(@QueryParam("hello") String hello) { + return hello + " world"; } @POST diff --git a/karate-mock-servlet/src/test/java/mock/jersey/hello-http.feature b/karate-mock-servlet/src/test/java/mock/jersey/hello-http.feature index fef874e6d..c03566590 100644 --- a/karate-mock-servlet/src/test/java/mock/jersey/hello-http.feature +++ b/karate-mock-servlet/src/test/java/mock/jersey/hello-http.feature @@ -4,9 +4,10 @@ Scenario: get hello When url demoBaseUrl And path 'hello' +And param hello = 'hey' When method get Then status 200 -And match response == 'hello world' +And match response == 'hey world' Scenario: post cat From 647572669be8112d5748accc283e5b9a6d5f1b09 Mon Sep 17 00:00:00 2001 From: Deepak Chaudhary Date: Sat, 10 Oct 2020 00:12:50 -0500 Subject: [PATCH 3/4] 1165 - initial commit --- .../karate/http/apache/ApacheHttpClient.java | 63 ++++++-------- .../http/apache/ApacheHttpClientTest.java | 83 +++++++++++++++++++ .../src/test/resources/karate-config.js | 3 + .../src/test/resources/karate-http.properties | 2 + .../java/com/intuit/karate/http/Cookie.java | 34 ++++++-- .../test/java/demo/cookies/cookies.feature | 64 ++++++++++++-- .../karate/http/jersey/JerseyHttpClient.java | 28 ++++++- 7 files changed, 224 insertions(+), 53 deletions(-) create mode 100644 karate-apache/src/test/java/com/intuit/karate/http/apache/ApacheHttpClientTest.java create mode 100755 karate-apache/src/test/resources/karate-config.js create mode 100644 karate-apache/src/test/resources/karate-http.properties diff --git a/karate-apache/src/main/java/com/intuit/karate/http/apache/ApacheHttpClient.java b/karate-apache/src/main/java/com/intuit/karate/http/apache/ApacheHttpClient.java index c1a94819a..348214b4c 100644 --- a/karate-apache/src/main/java/com/intuit/karate/http/apache/ApacheHttpClient.java +++ b/karate-apache/src/main/java/com/intuit/karate/http/apache/ApacheHttpClient.java @@ -26,37 +26,11 @@ import com.intuit.karate.Config; import com.intuit.karate.FileUtils; import com.intuit.karate.core.ScenarioContext; -import org.apache.http.conn.ssl.LenientSslConnectionSocketFactory; - -import static com.intuit.karate.http.Cookie.*; - -import com.intuit.karate.http.HttpClient; -import com.intuit.karate.http.HttpRequest; -import com.intuit.karate.http.HttpResponse; -import com.intuit.karate.http.HttpUtils; -import com.intuit.karate.http.MultiPartItem; -import com.intuit.karate.http.MultiValuedMap; -import java.io.IOException; - -import java.io.InputStream; -import java.net.InetAddress; -import java.net.InetSocketAddress; -import java.net.Proxy; -import java.net.ProxySelector; -import java.net.SocketAddress; -import java.net.URI; -import java.nio.charset.Charset; -import java.security.KeyStore; -import java.util.Arrays; -import java.util.Collections; -import java.util.List; -import java.util.Map.Entry; -import java.util.Objects; -import javax.net.ssl.SSLContext; - +import com.intuit.karate.http.*; import org.apache.http.Header; import org.apache.http.HttpEntity; import org.apache.http.HttpHost; +import org.apache.http.ParseException; import org.apache.http.auth.AuthScope; import org.apache.http.auth.UsernamePasswordCredentials; import org.apache.http.client.CookieStore; @@ -67,22 +41,28 @@ import org.apache.http.client.methods.RequestBuilder; import org.apache.http.client.utils.URIBuilder; import org.apache.http.config.SocketConfig; -import org.apache.http.conn.ssl.NoopHostnameVerifier; -import org.apache.http.conn.ssl.SSLConnectionSocketFactory; -import org.apache.http.conn.ssl.TrustAllStrategy; -import org.apache.http.conn.ssl.TrustSelfSignedStrategy; +import org.apache.http.conn.ssl.*; import org.apache.http.cookie.Cookie; -import org.apache.http.impl.client.BasicCookieStore; -import org.apache.http.impl.client.BasicCredentialsProvider; -import org.apache.http.impl.client.CloseableHttpClient; -import org.apache.http.impl.client.HttpClientBuilder; -import org.apache.http.impl.client.LaxRedirectStrategy; +import org.apache.http.impl.client.*; import org.apache.http.impl.conn.SystemDefaultRoutePlanner; import org.apache.http.impl.cookie.BasicClientCookie; import org.apache.http.protocol.BasicHttpContext; import org.apache.http.ssl.SSLContextBuilder; import org.apache.http.ssl.SSLContexts; +import javax.net.ssl.SSLContext; +import java.io.IOException; +import java.io.InputStream; +import java.net.*; +import java.nio.charset.Charset; +import java.security.KeyStore; +import java.time.ZonedDateTime; +import java.time.format.DateTimeParseException; +import java.util.*; +import java.util.Map.Entry; + +import static com.intuit.karate.http.Cookie.*; + /** * @author pthomas3 */ @@ -269,6 +249,15 @@ protected void buildCookie(com.intuit.karate.http.Cookie c) { case PATH: cookie.setPath(entry.getValue()); break; + case EXPIRES: + try { + cookie.setExpiryDate(Date.from(ZonedDateTime.parse(entry.getValue(), DTFMTR_RFC1123).toInstant())); + } + catch ( DateTimeParseException ex) + { + System.err.println("ex ->" + ex.getLocalizedMessage()); + } + break; } } if (cookie.getDomain() == null) { diff --git a/karate-apache/src/test/java/com/intuit/karate/http/apache/ApacheHttpClientTest.java b/karate-apache/src/test/java/com/intuit/karate/http/apache/ApacheHttpClientTest.java new file mode 100644 index 000000000..1fc56ac3d --- /dev/null +++ b/karate-apache/src/test/java/com/intuit/karate/http/apache/ApacheHttpClientTest.java @@ -0,0 +1,83 @@ +package com.intuit.karate.http.apache; + +import com.intuit.karate.CallContext; +import com.intuit.karate.Config; +import com.intuit.karate.core.FeatureContext; +import com.intuit.karate.core.ScenarioContext; +import com.intuit.karate.http.Cookie; +import org.apache.http.client.CookieStore; +import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.lang.reflect.Field; +import java.time.ZonedDateTime; +import java.util.LinkedHashMap; +import java.util.Map; + +import static com.intuit.karate.http.Cookie.*; +import static com.intuit.karate.http.HttpClient.construct; +import static org.junit.Assert.assertEquals; + +public class ApacheHttpClientTest { + + private static final Logger logger = LoggerFactory.getLogger(ApacheHttpClientTest.class); + + private ScenarioContext getContext() { + FeatureContext featureContext = FeatureContext.forEnv(); + CallContext callContext = new CallContext(null, true); + return new ScenarioContext(featureContext, callContext, null, null); + } + + private Config getConfig() { + return new Config(); + } + + private Map getCookieMapWithExpiredDate() { + ZonedDateTime currentDate = ZonedDateTime.now(); + Map cookieMap = new LinkedHashMap<>(); + cookieMap.put(NAME, "testCookie"); + cookieMap.put(VALUE, "tck"); + cookieMap.put(DOMAIN, ".com"); + cookieMap.put(PATH, "/"); + cookieMap.put(EXPIRES,currentDate.minusDays(1).format(DTFMTR_RFC1123)); + return cookieMap; + } + + private Map getCookieMapWithNonExpiredDate() { + ZonedDateTime currentDate = ZonedDateTime.now(); + Map cookieMap = new LinkedHashMap<>(); + cookieMap.put(NAME, "testCookie"); + cookieMap.put(VALUE, "tck"); + cookieMap.put(DOMAIN, ".com"); + cookieMap.put(PATH, "/"); + cookieMap.put(EXPIRES, currentDate.plusDays(1).format(DTFMTR_RFC1123)); + return cookieMap; + } + + @Test + public void testExpiredCookieIsRemoved() throws NoSuchFieldException, IllegalAccessException { + com.intuit.karate.http.Cookie c = new Cookie(getCookieMapWithExpiredDate()); + ApacheHttpClient httpClient = (ApacheHttpClient) construct(getConfig(), getContext()); + httpClient.buildCookie(c); + + Field cookieStoreField = httpClient.getClass().getDeclaredField("cookieStore"); + cookieStoreField.setAccessible(true); + CookieStore fieldValue = (CookieStore) cookieStoreField.get(httpClient); + assertEquals(0, fieldValue.getCookies().size()); + } + + @Test + public void testNonExpiredCookieIsPersisted() throws NoSuchFieldException, IllegalAccessException { + com.intuit.karate.http.Cookie c = new Cookie(getCookieMapWithNonExpiredDate()); + ApacheHttpClient httpClient = (ApacheHttpClient) construct(getConfig(), getContext()); + httpClient.buildCookie(c); + + Field cookieStoreField = httpClient.getClass().getDeclaredField("cookieStore"); + cookieStoreField.setAccessible(true); + CookieStore fieldValue = (CookieStore) cookieStoreField.get(httpClient); + assertEquals(1, fieldValue.getCookies().size()); + } +} + + diff --git a/karate-apache/src/test/resources/karate-config.js b/karate-apache/src/test/resources/karate-config.js new file mode 100755 index 000000000..dea6405ed --- /dev/null +++ b/karate-apache/src/test/resources/karate-config.js @@ -0,0 +1,3 @@ +function fn() { + return { someConfig: 'someValue' } +} \ No newline at end of file diff --git a/karate-apache/src/test/resources/karate-http.properties b/karate-apache/src/test/resources/karate-http.properties new file mode 100644 index 000000000..cd3832389 --- /dev/null +++ b/karate-apache/src/test/resources/karate-http.properties @@ -0,0 +1,2 @@ +client.class=com.intuit.karate.http.apache.ApacheHttpClient + diff --git a/karate-core/src/main/java/com/intuit/karate/http/Cookie.java b/karate-core/src/main/java/com/intuit/karate/http/Cookie.java index 1f3011999..d20d9ee25 100644 --- a/karate-core/src/main/java/com/intuit/karate/http/Cookie.java +++ b/karate-core/src/main/java/com/intuit/karate/http/Cookie.java @@ -23,11 +23,13 @@ */ package com.intuit.karate.http; -import java.util.ArrayList; -import java.util.Collections; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.time.ZonedDateTime; +import java.time.format.DateTimeFormatter; +import java.time.format.DateTimeFormatterBuilder; +import java.time.format.DateTimeParseException; +import java.util.*; /** * @@ -44,7 +46,10 @@ public class Cookie extends LinkedHashMap { public static final String MAX_AGE = "max-age"; public static final String SECURE = "secure"; public static final String PERSISTENT = "persistent"; - public static final String HTTP_ONLY = "http-only"; + public static final String HTTP_ONLY = "http-only"; + public static final DateTimeFormatter DT_FMT_V1 = DateTimeFormatter.ofPattern("EEE, dd-MMM-yy HH:mm:ss z"); + public static final DateTimeFormatter DT_FMT_V2 = DateTimeFormatter.ofPattern("EEE, dd MMM yyyy HH:mm:ss z"); + public static final DateTimeFormatter DTFMTR_RFC1123 = new DateTimeFormatterBuilder().appendOptional(DT_FMT_V1).appendOptional(DT_FMT_V2).toFormatter(); // cookies can be a map of maps, so some extra processing public static List toCookies(Map map) { @@ -82,6 +87,21 @@ public String getName() { public String getValue() { return get(VALUE); - } + } + + public boolean isCookieExpired() + { + String exprDat = get(EXPIRES); + Date expires = null; + if ( null != exprDat) { + try { + expires = Date.from(ZonedDateTime.parse(get(EXPIRES), DTFMTR_RFC1123).toInstant()); + } catch (DateTimeParseException ex) { + System.err.println("ex ->" + ex.getLocalizedMessage()); + } + } + return null != expires && !expires.after(new Date()); + + } } diff --git a/karate-demo/src/test/java/demo/cookies/cookies.feature b/karate-demo/src/test/java/demo/cookies/cookies.feature index 3aca80827..d5e0d5044 100644 --- a/karate-demo/src/test/java/demo/cookies/cookies.feature +++ b/karate-demo/src/test/java/demo/cookies/cookies.feature @@ -16,25 +16,25 @@ Scenario: one cookie, and it is sent automatically in the next request Then status 200 And match response == '#[1]' And match response[0] contains { name: 'foo', value: 'bar' } - + Given path 'search', 'cookies' And request {} When method post Then status 200 And match response == '#[1]' - And match response[0] contains { name: 'foo', value: 'bar' } - + And match response[0] contains { name: 'foo', value: 'bar' } + * print 'cookies: ', responseCookies # reset cookies * configure cookies = null - Given path 'search', 'cookies' + Given path 'search', 'cookies' When method get Then status 200 And match response == [] # modify cookies - Given path 'search', 'cookies' + Given path 'search', 'cookies' And cookie foo = 'blah' And request {} When method post @@ -43,15 +43,65 @@ Scenario: one cookie, and it is sent automatically in the next request Scenario: cookie as json Given path 'search', 'cookies' - And cookie foo = { value: 'bar' } + And cookie foo = { value: 'bar' } When method get Then status 200 And match response[0] contains { name: 'foo', value: 'bar' } Scenario: cookie returned has dots in the domain which violates RFC 2109 Given path 'search', 'cookies' - And cookie foo = { value: 'bar' } + And cookie foo = { value: 'bar' } + And param domain = '.abc.com' + When method get + Then status 200 + And match response[0] contains { name: 'foo', value: 'bar', domain: '.abc.com' } + +Scenario: cookie returned has dots in the domain which violates RFC 2109 + Given path 'search', 'cookies' + And cookie foo = { value: 'bar' } And param domain = '.abc.com' When method get Then status 200 And match response[0] contains { name: 'foo', value: 'bar', domain: '.abc.com' } + +@mock-servlet-todo +Scenario: expired cookie is not in response + * def prevDate = + """ + function() { + var SimpleDateFormat = Java.type('java.text.SimpleDateFormat'); + var Calendar = Java.type('java.util.Calendar'); + var currCalIns = Calendar.getInstance(); + currCalIns.add(java.util.Calendar.DATE, -1); + var sdf = new SimpleDateFormat("EEE, dd-MMM-yy HH:mm:ss z"); + return sdf.format(currCalIns.getTime()); + } + """ + * def date = prevDate() + Given path 'search', 'cookies' + And cookie foo = {value:'bar', expires: '#(date)'} + And param domain = '.abcdfdf.com' + When method get + Then status 200 + And match response == [] + +@mock-servlet-todo +Scenario: non-expired cookie is in response + * def futureDate = + """ + function() { + var SimpleDateFormat = Java.type('java.text.SimpleDateFormat'); + var Calendar = Java.type('java.util.Calendar'); + var currCalIns = Calendar.getInstance(); + currCalIns.add(java.util.Calendar.DATE, +1); + var sdf = new SimpleDateFormat("EEE, dd-MMM-yy HH:mm:ss z"); + return sdf.format(currCalIns.getTime()); + } + """ + * def date = futureDate() + Given path 'search', 'cookies' + And cookie foo = {value:'bar', expires:'#(date)', path:'/search'} + And param domain = '.abc.com' + When method get + Then status 200 + And match response[0] contains { name: 'foo', value: 'bar', domain: '.abc.com' } \ No newline at end of file diff --git a/karate-jersey/src/main/java/com/intuit/karate/http/jersey/JerseyHttpClient.java b/karate-jersey/src/main/java/com/intuit/karate/http/jersey/JerseyHttpClient.java index 568bb1483..394562f30 100644 --- a/karate-jersey/src/main/java/com/intuit/karate/http/jersey/JerseyHttpClient.java +++ b/karate-jersey/src/main/java/com/intuit/karate/http/jersey/JerseyHttpClient.java @@ -36,6 +36,10 @@ import java.io.InputStream; import java.nio.charset.Charset; import java.security.KeyStore; +import java.time.LocalDateTime; +import java.time.ZonedDateTime; +import java.time.format.DateTimeParseException; +import java.util.Date; import java.util.List; import java.util.Map.Entry; import javax.net.ssl.HttpsURLConnection; @@ -59,6 +63,7 @@ import org.glassfish.jersey.media.multipart.MultiPart; import org.glassfish.jersey.media.multipart.MultiPartFeature; import org.glassfish.jersey.media.multipart.file.StreamDataBodyPart; +import org.glassfish.jersey.message.internal.StringBuilderUtils; /** * @@ -144,8 +149,27 @@ public void buildHeader(String name, Object value, boolean replace) { @Override public void buildCookie(com.intuit.karate.http.Cookie c) { - Cookie cookie = new Cookie(c.getName(), c.getValue()); - builder.cookie(cookie); +// Date expires = null; +// +// for (Entry entry : c.entrySet()) { +// if (EXPIRES.equals(entry.getKey())) { +// try { +// expires = Date.from(ZonedDateTime.parse(entry.getValue(), DTFMTR_RFC1123).toInstant()); +// } catch (DateTimeParseException ex) { +// System.err.println("ex ->" + ex.getLocalizedMessage()); +// } +// } +// } +// if ( null == expires || expires.after(new Date())) { +// System.out.println(" ----> " + c.toString() + " -- " + expires); +// Cookie cookie = new Cookie(c.getName(), c.getValue()); +// builder.cookie(cookie); +// } + if ( !c.isCookieExpired() ) + { + Cookie cookie = new Cookie(c.getName(), c.getValue()); + builder.cookie(cookie); + } } private MediaType getMediaType(String mediaType) { From 0992955409f1cb70078492594e5ec05172532bc3 Mon Sep 17 00:00:00 2001 From: Deepak Chaudhary Date: Sat, 10 Oct 2020 00:19:39 -0500 Subject: [PATCH 4/4] 1165 - initial commit --- .../karate/http/apache/ApacheHttpClient.java | 2 +- .../karate/http/jersey/JerseyHttpClient.java | 17 +---------------- 2 files changed, 2 insertions(+), 17 deletions(-) diff --git a/karate-apache/src/main/java/com/intuit/karate/http/apache/ApacheHttpClient.java b/karate-apache/src/main/java/com/intuit/karate/http/apache/ApacheHttpClient.java index 348214b4c..ee7b8a745 100644 --- a/karate-apache/src/main/java/com/intuit/karate/http/apache/ApacheHttpClient.java +++ b/karate-apache/src/main/java/com/intuit/karate/http/apache/ApacheHttpClient.java @@ -249,7 +249,7 @@ protected void buildCookie(com.intuit.karate.http.Cookie c) { case PATH: cookie.setPath(entry.getValue()); break; - case EXPIRES: + case EXPIRES: // add expires field for cookie. try { cookie.setExpiryDate(Date.from(ZonedDateTime.parse(entry.getValue(), DTFMTR_RFC1123).toInstant())); } diff --git a/karate-jersey/src/main/java/com/intuit/karate/http/jersey/JerseyHttpClient.java b/karate-jersey/src/main/java/com/intuit/karate/http/jersey/JerseyHttpClient.java index 394562f30..8ad15b4e2 100644 --- a/karate-jersey/src/main/java/com/intuit/karate/http/jersey/JerseyHttpClient.java +++ b/karate-jersey/src/main/java/com/intuit/karate/http/jersey/JerseyHttpClient.java @@ -149,22 +149,7 @@ public void buildHeader(String name, Object value, boolean replace) { @Override public void buildCookie(com.intuit.karate.http.Cookie c) { -// Date expires = null; -// -// for (Entry entry : c.entrySet()) { -// if (EXPIRES.equals(entry.getKey())) { -// try { -// expires = Date.from(ZonedDateTime.parse(entry.getValue(), DTFMTR_RFC1123).toInstant()); -// } catch (DateTimeParseException ex) { -// System.err.println("ex ->" + ex.getLocalizedMessage()); -// } -// } -// } -// if ( null == expires || expires.after(new Date())) { -// System.out.println(" ----> " + c.toString() + " -- " + expires); -// Cookie cookie = new Cookie(c.getName(), c.getValue()); -// builder.cookie(cookie); -// } + // only add the cookie from request, if it isnt already expired. if ( !c.isCookieExpired() ) { Cookie cookie = new Cookie(c.getName(), c.getValue());