Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add tests for containsHeaderString #1238

Merged
merged 8 commits into from
Mar 28, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2012, 2019 Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0, which is available at
Expand Down Expand Up @@ -207,7 +207,8 @@ public default boolean hasProperty(String name) {
* (missing comma), or the value {@code no - store} (whitespace within value).
*
* @param name the message header.
* @param valueSeparatorRegex Separates the header value into single values. {@code null} does not split.
* @param valueSeparatorRegex Regular expression that separates the header value into single values.
* {@code null} does not split.
* @param valuePredicate value must fulfil this predicate.
* @return {@code true} if and only if a header with the given name exists, having either a whitespace-trimmed value
* matching the predicate, or having at least one whitespace-trimmed single value in a token-separated list of single values.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2012, 2019 Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0, which is available at
Expand Down Expand Up @@ -99,7 +99,8 @@ public interface ClientResponseContext {
* (missing comma), or the value {@code no - store} (whitespace within value).
*
* @param name the message header.
* @param valueSeparatorRegex Separates the header value into single values. {@code null} does not split.
* @param valueSeparatorRegex Regular expression that separates the header value into single values.
* {@code null} does not split.
* @param valuePredicate value must fulfil this predicate.
* @return {@code true} if and only if a header with the given name exists, having either a whitespace-trimmed value
* matching the predicate, or having at least one whitespace-trimmed single value in a token-separated list of single values.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2012, 2019 Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0, which is available at
Expand Down Expand Up @@ -239,7 +239,7 @@ public default boolean hasProperty(String name) {
* (missing comma), or the value {@code no - store} (whitespace within value).
*
* @param name the message header.
* @param valueSeparatorRegex Separates the header value into single values. {@code null} does not split.
* @param valueSeparatorRegex Regular expression that separates the header value into single values. {@code null} does not split.
* @param valuePredicate value must fulfil this predicate.
* @return {@code true} if and only if a header with the given name exists, having either a whitespace-trimmed value
* matching the predicate, or having at least one whitespace-trimmed single value in a token-separated list of single values.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2012, 2019 Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0, which is available at
Expand Down Expand Up @@ -129,7 +129,7 @@ public interface ContainerResponseContext {
* (missing comma), or the value {@code no - store} (whitespace within value).
*
* @param name the message header.
* @param valueSeparatorRegex Separates the header value into single values. {@code null} does not split.
* @param valueSeparatorRegex Regular expression that separates the header value into single values. {@code null} does not split.
* @param valuePredicate value must fulfil this predicate.
* @return {@code true} if and only if a header with the given name exists, having either a whitespace-trimmed value
* matching the predicate, or having at least one whitespace-trimmed single value in a token-separated list of single values.
Expand Down
5 changes: 3 additions & 2 deletions jaxrs-api/src/main/java/jakarta/ws/rs/core/HttpHeaders.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2010, 2020 Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2010 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0, which is available at
Expand Down Expand Up @@ -75,7 +75,8 @@ public interface HttpHeaders {
* (missing comma), or the value {@code no - store} (whitespace within value).
*
* @param name the message header.
* @param valueSeparatorRegex Separates the header value into single values. {@code null} does not split.
* @param valueSeparatorRegex Regular expression that separates the header value into single values.
* {@code null} does not split.
* @param valuePredicate value must fulfil this predicate.
* @return {@code true} if and only if a header with the given name exists, having either a whitespace-trimmed value
* matching the predicate, or having at least one whitespace-trimmed single value in a token-separated list of single values.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2012, 2021 Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0, which is available at
Expand All @@ -17,6 +17,7 @@
package ee.jakarta.tck.ws.rs.api.client.clientrequestcontext;

import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.junit.jupiter.api.Assertions.assertFalse;

import java.io.ByteArrayInputStream;
import java.lang.annotation.Annotation;
Expand Down Expand Up @@ -860,6 +861,46 @@ protected void checkFilterContext(ClientRequestContext context)
assertContains(entity, "Accept");
}

/*
* @testName: containsHeaderStringTest
*
* @assertion_ids: JAXRS:JAVADOC:1353; JAXRS:JAVADOC:1354;
*
* @test_Strategy: Check if the specified header contains a specified value.
*
* ClientRequestFilter.abortWith
*/
@Test
public void containsHeaderStringTest() throws Fault {
ContextProvider provider = new ContextProvider() {
@Override
protected void checkFilterContext(ClientRequestContext context) throws Fault {
assertTrue(context.containsHeaderString("header1", "value"::equals));
assertTrue(context.containsHeaderString("HEADER1", ",", "value2"::equals));
//Incorrect separator character
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IMHO a TCK test should only test for the existence of a given rule, not for the absence of particular bugs.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this test is valid since it confirms that the value of the separator character parameter is actually used and taken into consideration by the impl.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"Incorrect separator character" does not imply that. Checking for correct pickup of separator is implied in line 879 already.

Copy link
Contributor Author

@jim-krueger jim-krueger Mar 24, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Line 879 only proves that the line separator parameter can be included in the invocation, but not that it is actually used by the impl. The impl could be ignoring that parameter and accepting any separator character as valid. This is why the "incorrect separator character" test is good. It tests that the impl is using the the separator parameter and that it is checking it specifically and not just allowing any separator.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder if instead there could be a test that actively checks usage of the separator, and positively comments about that.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see your point, I'm just not sure there is a way to ensure that the separator parameter is actually being used without having at lease one test that expects failure in that respect.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To me the test makes sense. If you split with the wrong separator (so you don't really split) then the assertion is false.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That is correct, but just because using the wrong separator fails the test does not imply that using the correct separator passes the test.

assertFalse(context.containsHeaderString("header1", ";", "value2"::equals));
//Shouldn't find first value when separator character is incorrect
assertFalse(context.containsHeaderString("header1", ";", "Value1"::equalsIgnoreCase));
//Test regular expression
assertTrue(context.containsHeaderString("header1", ";|,", "VALUE2"::equalsIgnoreCase));
//White space in value not trimmed
assertFalse(context.containsHeaderString("header1", "whitespace"::equals));
//Multiple character separator
assertTrue(context.containsHeaderString("header2", ";;", "Value5"::equalsIgnoreCase));
Response r = Response.ok().build();
jim-krueger marked this conversation as resolved.
Show resolved Hide resolved
context.abortWith(r);
}
};
Invocation invocation = buildBuilder(provider)
.header("header1", "value")
.header("header1", "value1 , value2")
.header("header1", "Value3,white space ")
.header("header2", "Value4;;Value5")
.buildGet();
Response response = invoke(invocation);
}


/*
* @testName: getHeaderStringTest
*
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2012, 2021 Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0, which is available at
Expand All @@ -16,6 +16,7 @@

package ee.jakarta.tck.ws.rs.api.client.clientresponsecontext;

import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;

import java.io.BufferedReader;
Expand Down Expand Up @@ -426,6 +427,47 @@ protected void checkFilterContext(ClientRequestContext requestContext,
invokeWithResponseAndAssertStatus(response, Status.OK, in);
}

/*
* @testName: containsHeaderStringTest
*
* @assertion_ids: JAXRS:JAVADOC:1355; JAXRS:JAVADOC:1356;
*
* @test_Strategy: Check if the specified header contains a specified value.
*
* ClientRequestFilter.abortWith
*/
@Test
public void containsHeaderStringTest() throws Fault {

ContextProvider in = new ContextProvider() {
@Override
protected void checkFilterContext(ClientRequestContext requestContext,
ClientResponseContext responseContext) throws Fault {
assertTrue(responseContext.containsHeaderString("header1", "value"::equals));
assertTrue(responseContext.containsHeaderString("HEADER1", ",", "value2"::equals));
//Incorrect separator character
assertFalse(responseContext.containsHeaderString("header1", ";", "value2"::equals));
//Shouldn't find first value when separator character is incorrect
assertFalse(responseContext.containsHeaderString("header1", ";", "Value1"::equalsIgnoreCase));
//Test regular expression
assertTrue(responseContext.containsHeaderString("header1", ";|,", "VALUE2"::equalsIgnoreCase));
//White space in value not trimmed
assertFalse(responseContext.containsHeaderString("header1", "whitespace"::equalsIgnoreCase));
//Multiple character separator
assertTrue(responseContext.containsHeaderString("header2", ";;", "Value5"::equalsIgnoreCase));
}
};
Response response = Response.ok()
.header("header1", "value")
.header("header1", "value1 , value2")
.header("header1", "Value3,white space ")
.header("header2", "Value4;;Value5")
.build();
invokeWithResponseAndAssertStatus(response, Status.OK, in);
}



/*
* @testName: getLanguageTest
*
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2012, 2018 Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0, which is available at
Expand All @@ -17,5 +17,5 @@
package ee.jakarta.tck.ws.rs.ee.rs.container.requestcontext;

public enum ContextOperation {
ABORTWITH, GETACCEPTABLELANGUAGES, GETACCEPTABLELANGUAGESISREADONLY, GETACCEPTABLEMEDIATYPES, GETACCEPTABLEMEDIATYPESISREADONLY, GETCOOKIES, GETCOOKIESISREADONLY, GETDATE, GETENTITYSTREAM, GETHEADERS, GETHEADERSISMUTABLE, GETHEADERSTRING2, GETLANGUAGE, GETLENGTH, GETMEDIATYPE, GETMETHOD, GETPROPERTY, GETPROPERTYNAMES, GETPROPERTYNAMESISREADONLY, GETREQUEST, GETSECURITYCONTEXT, GETURIINFO, HASENTITY, REMOVEPROPERTY, SETENTITYSTREAM, SETMETHOD, SETPROPERTY, SETPROPERTYNULL, SETPROPERTYCONTEXT, SETREQUESTURI1, SETREQUESTURI2, SETSECURITYCONTEXT;
ABORTWITH, GETACCEPTABLELANGUAGES, GETACCEPTABLELANGUAGESISREADONLY, GETACCEPTABLEMEDIATYPES, GETACCEPTABLEMEDIATYPESISREADONLY, GETCOOKIES, GETCOOKIESISREADONLY, GETDATE, GETENTITYSTREAM, CONTAINSHEADERSTRING, GETHEADERS, GETHEADERSISMUTABLE, GETHEADERSTRING2, GETLANGUAGE, GETLENGTH, GETMEDIATYPE, GETMETHOD, GETPROPERTY, GETPROPERTYNAMES, GETPROPERTYNAMESISREADONLY, GETREQUEST, GETSECURITYCONTEXT, GETURIINFO, HASENTITY, REMOVEPROPERTY, SETENTITYSTREAM, SETMETHOD, SETPROPERTY, SETPROPERTYNULL, SETPROPERTYCONTEXT, SETREQUESTURI1, SETREQUESTURI2, SETSECURITYCONTEXT;
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2012, 2022 Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0, which is available at
Expand Down Expand Up @@ -333,6 +333,34 @@ public void getEntityStreamTest() throws Fault {
ContextOperation.GETENTITYSTREAM);
}

/*
* @testName: containsHeaderStringTest
*
* @assertion_ids: JAXRS:JAVADOC:JAXRS:JAVADOC:1359; JAXRS:JAVADOC:1360
*
* @test_Strategy: Check if the specified header contains a specified value.
*
* Filter method called before a request has been dispatched to a resource.
* Throws IOException.
*/
@Test
@Tag("servlet")
public void containsHeaderStringTest() throws Fault {
setProperty(Property.REQUEST_HEADERS,
"Accept:text/*, text/html, text/html;level=1, */*");
setProperty(Property.REQUEST_HEADERS,
"Content-Type:application/xml;charset=utf8");
setProperty(Property.REQUEST_HEADERS,
"Header3:value1 ;; Value2 ;;value 3");
setProperty(Property.SEARCH_STRING, "Test1");
setProperty(Property.SEARCH_STRING, "Test2");
setProperty(Property.SEARCH_STRING, "Test3");
setProperty(Property.SEARCH_STRING, "Test4");
setProperty(Property.SEARCH_STRING, "Test5");

invokeRequestAndCheckResponse(ContextOperation.CONTAINSHEADERSTRING);
}

/*
* @testName: getHeadersTest
*
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2012, 2020 Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0, which is available at
Expand Down Expand Up @@ -140,6 +140,37 @@ public void getEntityStream() throws IOException {
abortWithEntity(entity);
}

public void containsHeaderString() {
StringBuffer sb = new StringBuffer();
sb.append("containsHeaderString= ");

try {
assertTrue(requestContext.containsHeaderString("accept", "text/html"::equals));
sb.append("Test1: accept contains text/html; ");

//Verify Predicate and separator character usage
assertTrue(requestContext.containsHeaderString("Accept", ",", "Text/html;Level=1"::equalsIgnoreCase));
sb.append("Test2: accept contains text/html;level=1; ");

//Verify incorrect separator character fails
assertTrue(!(requestContext.containsHeaderString("Accept", ";", "text/html;level=1"::equals)));
sb.append("Test3: Incorrect separator character fails as expected; ");

//Verify white space in value not trimmed and double character separator
assertTrue(!(requestContext.containsHeaderString("header3", ";;", "value3"::equals)));
sb.append("Test4: White space not trimmed from value as expected; ");

//Verify white space in front and back of value trimmed
assertTrue(requestContext.containsHeaderString("HEADER3", ";;", "value2"::equalsIgnoreCase));
sb.append("Test5: White space trimmed around value as expected; ");
} catch (Throwable ex) {
sb.append("Unexpected exception thrown in containsHeaderString: "
+ ex.getMessage());
ex.printStackTrace();
}
abortWithEntity(sb.toString());
}

public void getHeaders() {
MultivaluedMap<String, String> headers = requestContext.getHeaders();
StringBuilder sb = new StringBuilder();
Expand All @@ -149,7 +180,7 @@ public void getHeaders() {
}
abortWithEntity(sb.toString());
}

jim-krueger marked this conversation as resolved.
Show resolved Hide resolved
public void getHeadersIsMutable() {
String key = "KEY";
MultivaluedMap<String, String> headers = requestContext.getHeaders();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2012, 2018 Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0, which is available at
Expand All @@ -17,7 +17,7 @@
package ee.jakarta.tck.ws.rs.ee.rs.container.responsecontext;

public enum ContextOperation {
GETALLOWEDMETHODS, GETCOOKIES, GETCOOKIESISREADONLY, GETDATE, GETENTITY, GETENTITYANNOTATIONS, GETENTITYANNOTATIONSONENTITY, GETENTITYCLASS, GETENTITYSTREAM, GETENTITYTAG, GETENTITYTYPE, GETHEADERS, GETHEADERSISMUTABLE, GETHEADERSTRINGOPERATION, GETHEADERSTRINGHEADER, GETLANGUAGE, GETLASTMODIFIED, GETLENGTH, GETLINK, GETLINKBUILDER, GETLINKS, GETLOCATION, GETMEDIATYPE, GETSTATUS, GETSTATUSINFO, GETSTRINGHEADERS, HASENTITY, HASLINK, SETENTITY, SETENTITYSTREAM, SETSTATUS, SETSTATUSINFO,
GETALLOWEDMETHODS, GETCOOKIES, GETCOOKIESISREADONLY, GETDATE, GETENTITY, GETENTITYANNOTATIONS, GETENTITYANNOTATIONSONENTITY, GETENTITYCLASS, GETENTITYSTREAM, GETENTITYTAG, GETENTITYTYPE, CONTAINSHEADERSTRING, GETHEADERS, GETHEADERSISMUTABLE, GETHEADERSTRINGOPERATION, GETHEADERSTRINGHEADER, GETLANGUAGE, GETLASTMODIFIED, GETLENGTH, GETLINK, GETLINKBUILDER, GETLINKS, GETLOCATION, GETMEDIATYPE, GETSTATUS, GETSTATUSINFO, GETSTRINGHEADERS, HASENTITY, HASLINK, SETENTITY, SETENTITYSTREAM, SETSTATUS, SETSTATUSINFO,

// just helping methods, pass
SETSTRINGBEANRUNTIME, SETORIGINALRUNTIME
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2012, 2020 Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0, which is available at
Expand Down Expand Up @@ -445,6 +445,25 @@ public void getEntityTypeInputStreamTest() throws Fault {
invokeRequestAndCheckResponse(ContextOperation.GETENTITYTYPE);
}

/*
* @testName: getHeadersTest
*
* @assertion_ids: JAXRS:JAVADOC:1357; JAXRS:JAVADOC:1358;
*
* @test_Strategy: Get the mutable response headers multivalued map.
*
* Filter method called after a response has been provided for a request.
* Throws IOException.
*/
@Test
public void containsHeaderStringTest() throws Fault {
String header = "Test";
for (int i = 1; i != 6; i++)
setProperty(Property.UNORDERED_SEARCH_STRING, header + i);
setProperty(Property.CONTENT, header);
invokeRequestAndCheckResponse(ContextOperation.CONTAINSHEADERSTRING);
}

/*
* @testName: getHeadersTest
*
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2012, 2020 Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0, which is available at
Expand Down Expand Up @@ -179,6 +179,17 @@ public Response setEntityStream() {
return response;
}

@POST
@Path("containsheaderstring")
public Response containsHeaderString(String header) {
ResponseBuilder builder = createResponseWithHeader();
builder = builder.header("Accept", "text/html, text/html;level=1, */*");
builder = builder.header("Content-Type", "application/xml;charset=utf8");
builder = builder.header("Header3", "value1 ;; Value2 ;;value 3");
Response response = builder.build();
return response;
}

@POST
@Path("getheaders")
public Response getHeaders(String header) {
Expand Down
Loading