001/* 002 * Copyright 2002-2018 the original author or authors. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * https://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016 017package org.springframework.mock.web.server; 018 019import reactor.core.publisher.Mono; 020 021import org.springframework.http.codec.ServerCodecConfigurer; 022import org.springframework.lang.Nullable; 023import org.springframework.mock.http.server.reactive.MockServerHttpRequest; 024import org.springframework.mock.http.server.reactive.MockServerHttpResponse; 025import org.springframework.web.server.WebSession; 026import org.springframework.web.server.adapter.DefaultServerWebExchange; 027import org.springframework.web.server.i18n.AcceptHeaderLocaleContextResolver; 028import org.springframework.web.server.session.DefaultWebSessionManager; 029import org.springframework.web.server.session.WebSessionManager; 030 031/** 032 * Extension of {@link DefaultServerWebExchange} for use in tests, along with 033 * {@link MockServerHttpRequest} and {@link MockServerHttpResponse}. 034 * 035 * <p>See static factory methods to create an instance. 036 * 037 * @author Rossen Stoyanchev 038 * @since 5.0 039 */ 040public final class MockServerWebExchange extends DefaultServerWebExchange { 041 042 private MockServerWebExchange(MockServerHttpRequest request, WebSessionManager sessionManager) { 043 super(request, new MockServerHttpResponse(), sessionManager, 044 ServerCodecConfigurer.create(), new AcceptHeaderLocaleContextResolver()); 045 } 046 047 048 @Override 049 public MockServerHttpResponse getResponse() { 050 return (MockServerHttpResponse) super.getResponse(); 051 } 052 053 054 /** 055 * Create a {@link MockServerWebExchange} from the given mock request. 056 * @param request the request to use. 057 * @return the exchange 058 */ 059 public static MockServerWebExchange from(MockServerHttpRequest request) { 060 return builder(request).build(); 061 } 062 063 /** 064 * Variant of {@link #from(MockServerHttpRequest)} with a mock request builder. 065 * @param requestBuilder the builder for the mock request. 066 * @return the exchange 067 */ 068 public static MockServerWebExchange from(MockServerHttpRequest.BaseBuilder<?> requestBuilder) { 069 return builder(requestBuilder).build(); 070 } 071 072 /** 073 * Create a {@link Builder} starting with the given mock request. 074 * @param request the request to use. 075 * @return the exchange builder 076 * @since 5.1 077 */ 078 public static MockServerWebExchange.Builder builder(MockServerHttpRequest request) { 079 return new MockServerWebExchange.Builder(request); 080 } 081 082 /** 083 * Variant of {@link #builder(MockServerHttpRequest)} with a mock request builder. 084 * @param requestBuilder the builder for the mock request. 085 * @return the exchange builder 086 * @since 5.1 087 */ 088 public static MockServerWebExchange.Builder builder(MockServerHttpRequest.BaseBuilder<?> requestBuilder) { 089 return new MockServerWebExchange.Builder(requestBuilder.build()); 090 } 091 092 093 /** 094 * Builder for a {@link MockServerWebExchange}. 095 * @since 5.1 096 */ 097 public static class Builder { 098 099 private final MockServerHttpRequest request; 100 101 @Nullable 102 private WebSessionManager sessionManager; 103 104 public Builder(MockServerHttpRequest request) { 105 this.request = request; 106 } 107 108 /** 109 * Set the session to use for the exchange. 110 * <p>This method is mutually exclusive with 111 * {@link #sessionManager(WebSessionManager)}. 112 * @param session the session to use 113 * @see MockWebSession 114 */ 115 public Builder session(WebSession session) { 116 this.sessionManager = exchange -> Mono.just(session); 117 return this; 118 } 119 120 /** 121 * Provide a {@code WebSessionManager} instance to use with the exchange. 122 * <p>This is mutually exclusive with {@link #session(WebSession)}. 123 * @param sessionManager the session manager to use 124 */ 125 public Builder sessionManager(WebSessionManager sessionManager) { 126 this.sessionManager = sessionManager; 127 return this; 128 } 129 130 /** 131 * Build the {@code MockServerWebExchange} instance. 132 */ 133 public MockServerWebExchange build() { 134 return new MockServerWebExchange(this.request, 135 this.sessionManager != null ? this.sessionManager : new DefaultWebSessionManager()); 136 } 137 } 138 139}