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}