Skip to content

Commit

Permalink
Merge pull request #955 from snicoll
Browse files Browse the repository at this point in the history
* gh-955:
  Polish "Raise the minimum support version of Spring Framework to 7.0"
  Raise the minimum support version of Spring Framework to 7.0

Closes gh-955
  • Loading branch information
wilkinsona committed Jan 30, 2025
2 parents db16f27 + 34c9366 commit 4fb5b87
Show file tree
Hide file tree
Showing 24 changed files with 100 additions and 114 deletions.
2 changes: 0 additions & 2 deletions docs/src/docs/asciidoc/documenting-your-api.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -802,8 +802,6 @@ Uses the static `parameterWithName` method on `org.springframework.restdocs.requ

The result is a snippet named `path-parameters.adoc` that contains a table describing the path parameters that are supported by the resource.

TIP: If you use MockMvc with Spring Framework 6.1 or earlier, to make the path parameters available for documentation, you must build the request by using one of the methods on `RestDocumentationRequestBuilders` rather than `MockMvcRequestBuilders`.

When documenting path parameters, the test fails if an undocumented path parameter is used in the request.
Similarly, the test also fails if a documented path parameter is not found in the request and the path parameter has not been marked as optional.

Expand Down
2 changes: 1 addition & 1 deletion docs/src/docs/asciidoc/getting-started.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ If you want to jump straight in, a number of https://github.com/spring-projects/
Spring REST Docs has the following minimum requirements:

* Java 17
* Spring Framework 6
* Spring Framework 7

Additionally, the `spring-restdocs-restassured` module requires REST Assured 5.2.

Expand Down
2 changes: 1 addition & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,4 @@ org.gradle.parallel=true

javaFormatVersion=0.0.43
jmustacheVersion=1.15
springFrameworkVersion=6.1.13
springFrameworkVersion=7.0.0-M1
7 changes: 0 additions & 7 deletions spring-restdocs-core/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -82,10 +82,3 @@ components.java.withVariantsFromConfiguration(configurations.testFixturesApiElem
components.java.withVariantsFromConfiguration(configurations.testFixturesRuntimeElements) {
skip()
}

compatibilityTest {
dependency("Spring Framework") { springFramework ->
springFramework.groupId = "org.springframework"
springFramework.versions = ["6.0.+", "6.2.+"]
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2014-2023 the original author or authors.
* Copyright 2014-2025 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -76,7 +76,7 @@ public String getContentAsString() {
@Override
public HttpHeaders getHeaders() {
HttpHeaders filteredHeaders = new HttpHeaders();
for (Entry<String, List<String>> header : this.delegate.getHeaders().entrySet()) {
for (Entry<String, List<String>> header : this.delegate.getHeaders().headerSet()) {
if (allowedHeader(header)) {
filteredHeaders.put(header.getKey(), header.getValue());
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2014-2022 the original author or authors.
* Copyright 2014-2025 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -132,7 +132,7 @@ private void writeHttpMethod(OperationRequest request, StringBuilder builder) {
}

private void writeHeaders(CliOperationRequest request, List<String> lines) {
for (Entry<String, List<String>> entry : request.getHeaders().entrySet()) {
for (Entry<String, List<String>> entry : request.getHeaders().headerSet()) {
for (String header : entry.getValue()) {
if (StringUtils.hasText(request.getContentAsString()) && HttpHeaders.CONTENT_TYPE.equals(entry.getKey())
&& MediaType.APPLICATION_FORM_URLENCODED.equals(request.getHeaders().getContentType())) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2014-2023 the original author or authors.
* Copyright 2014-2025 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -160,7 +160,7 @@ private void writeFormDataIfNecessary(OperationRequest request, List<String> lin

private void writeHeaders(OperationRequest request, List<String> lines) {
HttpHeaders headers = request.getHeaders();
for (Entry<String, List<String>> entry : headers.entrySet()) {
for (Entry<String, List<String>> entry : headers.headerSet()) {
if (entry.getKey().equals(HttpHeaders.CONTENT_TYPE)
&& headers.getContentType().isCompatibleWith(MediaType.APPLICATION_FORM_URLENCODED)) {
continue;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2014-2019 the original author or authors.
* Copyright 2014-2025 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -57,7 +57,7 @@ protected RequestHeadersSnippet(List<HeaderDescriptor> descriptors, Map<String,

@Override
protected Set<String> extractActualHeaders(Operation operation) {
return operation.getRequest().getHeaders().keySet();
return operation.getRequest().getHeaders().headerNames();
}

/**
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2014-2019 the original author or authors.
* Copyright 2014-2025 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -57,7 +57,7 @@ protected ResponseHeadersSnippet(List<HeaderDescriptor> descriptors, Map<String,

@Override
protected Set<String> extractActualHeaders(Operation operation) {
return operation.getResponse().getHeaders().keySet();
return operation.getResponse().getHeaders().headerNames();
}

/**
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2014-2024 the original author or authors.
* Copyright 2014-2025 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -91,7 +91,7 @@ private boolean includeParametersInUri(OperationRequest request) {
private List<Map<String, String>> getHeaders(OperationRequest request) {
List<Map<String, String>> headers = new ArrayList<>();

for (Entry<String, List<String>> header : request.getHeaders().entrySet()) {
for (Entry<String, List<String>> header : request.getHeaders().headerSet()) {
for (String value : header.getValue()) {
if (HttpHeaders.CONTENT_TYPE.equals(header.getKey()) && !request.getParts().isEmpty()) {
headers.add(header(header.getKey(), String.format("%s; boundary=%s", value, MULTIPART_BOUNDARY)));
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2014-2022 the original author or authors.
* Copyright 2014-2025 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -73,7 +73,7 @@ private String responseBody(OperationResponse response) {

private List<Map<String, String>> headers(OperationResponse response) {
List<Map<String, String>> headers = new ArrayList<>();
for (Entry<String, List<String>> header : response.getHeaders().entrySet()) {
for (Entry<String, List<String>> header : response.getHeaders().headerSet()) {
List<String> values = header.getValue();
for (String value : values) {
headers.add(header(header.getKey(), value));
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2014-2023 the original author or authors.
* Copyright 2014-2025 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -210,7 +210,7 @@ private RemoveHeadersByNamePatternModification(Pattern namePattern) {

@Override
public void applyTo(HttpHeaders headers) {
headers.keySet().removeIf((name) -> this.namePattern.matcher(name).matches());
headers.headerNames().removeIf((name) -> this.namePattern.matcher(name).matches());
}

}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2014-2023 the original author or authors.
* Copyright 2014-2025 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -147,7 +147,7 @@ public OperationResponse preprocess(OperationResponse response) {

private HttpHeaders modify(HttpHeaders headers) {
HttpHeaders modified = new HttpHeaders();
for (Entry<String, List<String>> header : headers.entrySet()) {
for (Entry<String, List<String>> header : headers.headerSet()) {
for (String value : header.getValue()) {
modified.add(header.getKey(), this.contentModifier.modify(value));
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2014-2023 the original author or authors.
* Copyright 2014-2025 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -210,7 +210,7 @@ public void customDefaultOperationRequestPreprocessor() {
headers.add("Foo", "value");
OperationRequest request = new OperationRequestFactory().create(URI.create("http://localhost:8080"),
HttpMethod.GET, null, headers, null, Collections.emptyList());
assertThat(preprocessor.preprocess(request).getHeaders()).doesNotContainKey("Foo");
assertThat(preprocessor.preprocess(request).getHeaders().headerNames()).doesNotContain("Foo");
}

@Test
Expand All @@ -224,7 +224,7 @@ public void customDefaultOperationResponsePreprocessor() {
HttpHeaders headers = new HttpHeaders();
headers.add("Foo", "value");
OperationResponse response = new OperationResponseFactory().create(HttpStatus.OK, headers, null);
assertThat(preprocessor.preprocess(response).getHeaders()).doesNotContainKey("Foo");
assertThat(preprocessor.preprocess(response).getHeaders().headerNames()).doesNotContain("Foo");
}

private RestDocumentationContext createContext() {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2014-2023 the original author or authors.
* Copyright 2014-2025 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -33,6 +33,7 @@
import org.springframework.restdocs.operation.OperationResponseFactory;

import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.entry;

/**
* Tests for {@link HeadersModifyingOperationPreprocessor}.
Expand All @@ -47,81 +48,91 @@ public class HeadersModifyingOperationPreprocessorTests {
@Test
public void addNewHeader() {
this.preprocessor.add("a", "alpha");
assertThat(this.preprocessor.preprocess(createRequest()).getHeaders()).containsEntry("a",
Arrays.asList("alpha"));
assertThat(this.preprocessor.preprocess(createResponse()).getHeaders()).containsEntry("a",
Arrays.asList("alpha"));
assertThat(this.preprocessor.preprocess(createRequest()).getHeaders().get("a"))
.isEqualTo(Arrays.asList("alpha"));
assertThat(this.preprocessor.preprocess(createResponse()).getHeaders().get("a"))
.isEqualTo(Arrays.asList("alpha"));
}

@Test
public void addValueToExistingHeader() {
this.preprocessor.add("a", "alpha");
assertThat(this.preprocessor.preprocess(createRequest((headers) -> headers.add("a", "apple"))).getHeaders())
.containsEntry("a", Arrays.asList("apple", "alpha"));
assertThat(this.preprocessor.preprocess(createResponse((headers) -> headers.add("a", "apple"))).getHeaders())
.containsEntry("a", Arrays.asList("apple", "alpha"));
assertThat(this.preprocessor.preprocess(createRequest((headers) -> headers.add("a", "apple")))
.getHeaders()
.headerSet()).contains(entry("a", Arrays.asList("apple", "alpha")));
assertThat(this.preprocessor.preprocess(createResponse((headers) -> headers.add("a", "apple")))
.getHeaders()
.headerSet()).contains(entry("a", Arrays.asList("apple", "alpha")));
}

@Test
public void setNewHeader() {
this.preprocessor.set("a", "alpha", "avocado");
assertThat(this.preprocessor.preprocess(createRequest()).getHeaders()).containsEntry("a",
Arrays.asList("alpha", "avocado"));
assertThat(this.preprocessor.preprocess(createResponse()).getHeaders()).containsEntry("a",
Arrays.asList("alpha", "avocado"));
assertThat(this.preprocessor.preprocess(createRequest()).getHeaders().headerSet())
.contains(entry("a", Arrays.asList("alpha", "avocado")));
assertThat(this.preprocessor.preprocess(createResponse()).getHeaders().headerSet())
.contains(entry("a", Arrays.asList("alpha", "avocado")));
}

@Test
public void setExistingHeader() {
this.preprocessor.set("a", "alpha", "avocado");
assertThat(this.preprocessor.preprocess(createRequest((headers) -> headers.add("a", "apple"))).getHeaders())
.containsEntry("a", Arrays.asList("alpha", "avocado"));
assertThat(this.preprocessor.preprocess(createResponse((headers) -> headers.add("a", "apple"))).getHeaders())
.containsEntry("a", Arrays.asList("alpha", "avocado"));
assertThat(this.preprocessor.preprocess(createRequest((headers) -> headers.add("a", "apple")))
.getHeaders()
.headerSet()).contains(entry("a", Arrays.asList("alpha", "avocado")));
assertThat(this.preprocessor.preprocess(createResponse((headers) -> headers.add("a", "apple")))
.getHeaders()
.headerSet()).contains(entry("a", Arrays.asList("alpha", "avocado")));
}

@Test
public void removeNonExistentHeader() {
this.preprocessor.remove("a");
assertThat(this.preprocessor.preprocess(createRequest()).getHeaders()).doesNotContainKey("a");
assertThat(this.preprocessor.preprocess(createResponse()).getHeaders()).doesNotContainKey("a");
assertThat(this.preprocessor.preprocess(createRequest()).getHeaders().headerNames()).doesNotContain("a");
assertThat(this.preprocessor.preprocess(createResponse()).getHeaders().headerNames()).doesNotContain("a");
}

@Test
public void removeHeader() {
this.preprocessor.remove("a");
assertThat(this.preprocessor.preprocess(createRequest((headers) -> headers.add("a", "apple"))).getHeaders())
.doesNotContainKey("a");
assertThat(this.preprocessor.preprocess(createResponse((headers) -> headers.add("a", "apple"))).getHeaders())
.doesNotContainKey("a");
assertThat(this.preprocessor.preprocess(createRequest((headers) -> headers.add("a", "apple")))
.getHeaders()
.headerNames()).doesNotContain("a");
assertThat(this.preprocessor.preprocess(createResponse((headers) -> headers.add("a", "apple")))
.getHeaders()
.headerNames()).doesNotContain("a");
}

@Test
public void removeHeaderValueForNonExistentHeader() {
this.preprocessor.remove("a", "apple");
assertThat(this.preprocessor.preprocess(createRequest()).getHeaders()).doesNotContainKey("a");
assertThat(this.preprocessor.preprocess(createResponse()).getHeaders()).doesNotContainKey("a");
assertThat(this.preprocessor.preprocess(createRequest()).getHeaders().headerNames()).doesNotContain("a");
assertThat(this.preprocessor.preprocess(createResponse()).getHeaders().headerNames()).doesNotContain("a");
}

@Test
public void removeHeaderValueWithMultipleValues() {
this.preprocessor.remove("a", "apple");
assertThat(
this.preprocessor.preprocess(createRequest((headers) -> headers.addAll("a", List.of("apple", "alpha"))))
.getHeaders())
.containsEntry("a", Arrays.asList("alpha"));
.getHeaders()
.headerSet())
.contains(entry("a", Arrays.asList("alpha")));
assertThat(this.preprocessor
.preprocess(createResponse((headers) -> headers.addAll("a", List.of("apple", "alpha"))))
.getHeaders()).containsEntry("a", Arrays.asList("alpha"));
.getHeaders()
.headerSet()).contains(entry("a", Arrays.asList("alpha")));
}

@Test
public void removeHeaderValueWithSingleValueRemovesEntryEntirely() {
this.preprocessor.remove("a", "apple");
assertThat(this.preprocessor.preprocess(createRequest((headers) -> headers.add("a", "apple"))).getHeaders())
.doesNotContainKey("a");
assertThat(this.preprocessor.preprocess(createResponse((headers) -> headers.add("a", "apple"))).getHeaders())
.doesNotContainKey("a");
assertThat(this.preprocessor.preprocess(createRequest((headers) -> headers.add("a", "apple")))
.getHeaders()
.headerNames()).doesNotContain("a");
assertThat(this.preprocessor.preprocess(createResponse((headers) -> headers.add("a", "apple")))
.getHeaders()
.headerNames()).doesNotContain("a");
}

@Test
Expand All @@ -133,10 +144,10 @@ public void removeHeadersByNamePattern() {
headers.add("bravo", "bravo");
};
this.preprocessor.removeMatching("^a.*");
assertThat(this.preprocessor.preprocess(createRequest(headersCustomizer)).getHeaders()).containsOnlyKeys("Host",
"bravo");
assertThat(this.preprocessor.preprocess(createResponse(headersCustomizer)).getHeaders())
.containsOnlyKeys("bravo");
assertThat(this.preprocessor.preprocess(createRequest(headersCustomizer)).getHeaders().headerNames())
.containsOnly("Host", "bravo");
assertThat(this.preprocessor.preprocess(createResponse(headersCustomizer)).getHeaders().headerNames())
.containsOnly("bravo");
}

private OperationRequest createRequest() {
Expand Down
7 changes: 0 additions & 7 deletions spring-restdocs-mockmvc/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,3 @@ dependencies {
testImplementation("org.hamcrest:hamcrest-library")
testImplementation("org.mockito:mockito-core")
}

compatibilityTest {
dependency("Spring Framework") { springFramework ->
springFramework.groupId = "org.springframework"
springFramework.versions = ["6.0.+", "6.2.+"]
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2014-2022 the original author or authors.
* Copyright 2014-2025 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -68,7 +68,7 @@ private HttpHeaders extractHeaders(MockHttpServletResponse response) {
}
}

if (response.getCookies() != null && !headers.containsKey(HttpHeaders.SET_COOKIE)) {
if (response.getCookies() != null && !headers.containsHeader(HttpHeaders.SET_COOKIE)) {
for (Cookie cookie : response.getCookies()) {
headers.add(HttpHeaders.SET_COOKIE, generateSetCookieHeader(cookie));
}
Expand Down
Loading

0 comments on commit 4fb5b87

Please sign in to comment.