Add builder to MockServerWebExchange

Issue: SPR-16772
This commit is contained in:
Rossen Stoyanchev
2018-05-10 09:59:02 -04:00
parent d82b0e37df
commit eef592d901
9 changed files with 242 additions and 185 deletions

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2017 the original author or authors.
* Copyright 2002-2018 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.
@@ -15,15 +15,20 @@
*/
package org.springframework.mock.web.test.server;
import reactor.core.publisher.Mono;
import org.springframework.http.codec.ServerCodecConfigurer;
import org.springframework.lang.Nullable;
import org.springframework.mock.http.server.reactive.test.MockServerHttpRequest;
import org.springframework.mock.http.server.reactive.test.MockServerHttpResponse;
import org.springframework.web.server.WebSession;
import org.springframework.web.server.adapter.DefaultServerWebExchange;
import org.springframework.web.server.i18n.AcceptHeaderLocaleContextResolver;
import org.springframework.web.server.session.DefaultWebSessionManager;
import org.springframework.web.server.session.WebSessionManager;
/**
* Variant of {@link DefaultServerWebExchange} for use in tests with
* Extension of {@link DefaultServerWebExchange} for use in tests, along with
* {@link MockServerHttpRequest} and {@link MockServerHttpResponse}.
*
* <p>See static factory methods to create an instance.
@@ -34,8 +39,8 @@ import org.springframework.web.server.session.DefaultWebSessionManager;
public final class MockServerWebExchange extends DefaultServerWebExchange {
private MockServerWebExchange(MockServerHttpRequest request) {
super(request, new MockServerHttpResponse(), new DefaultWebSessionManager(),
private MockServerWebExchange(MockServerHttpRequest request, WebSessionManager sessionManager) {
super(request, new MockServerHttpResponse(), sessionManager,
ServerCodecConfigurer.create(), new AcceptHeaderLocaleContextResolver());
}
@@ -47,22 +52,88 @@ public final class MockServerWebExchange extends DefaultServerWebExchange {
/**
* Create a {@link MockServerWebExchange} from the given request.
* Create a {@link MockServerWebExchange} from the given mock request.
* @param request the request to use.
* @return the exchange
*/
public static MockServerWebExchange from(MockServerHttpRequest request) {
return new MockServerWebExchange(request);
return builder(request).build();
}
/**
* A variant of {@link #from(MockServerHttpRequest)} that accepts a request
* builder. Internally invokes the {@code build()} to build the request.
* @param requestBuilder the builder for the request.
* Variant of {@link #from(MockServerHttpRequest)} with a mock request builder.
* @param requestBuilder the builder for the mock request.
* @return the exchange
*/
public static MockServerWebExchange from(MockServerHttpRequest.BaseBuilder<?> requestBuilder) {
return new MockServerWebExchange(requestBuilder.build());
return builder(requestBuilder).build();
}
/**
* Create a {@link Builder} starting with the given mock request.
* @param request the request to use.
* @return the exchange builder
* @since 5.1
*/
public static MockServerWebExchange.Builder builder(MockServerHttpRequest request) {
return new MockServerWebExchange.Builder(request);
}
/**
* Variant of {@link #builder(MockServerHttpRequest)} with a mock request builder.
* @param requestBuilder the builder for the mock request.
* @return the exchange builder
* @since 5.1
*/
public static MockServerWebExchange.Builder builder(MockServerHttpRequest.BaseBuilder<?> requestBuilder) {
return new MockServerWebExchange.Builder(requestBuilder.build());
}
/**
* Builder for a {@link MockServerWebExchange}.
* @since 5.1
*/
public static class Builder {
private final MockServerHttpRequest request;
@Nullable
private WebSessionManager sessionManager;
public Builder(MockServerHttpRequest request) {
this.request = request;
}
/**
* Set the session to use for the exchange.
* <p>This is mutually exclusive with {@link #sessionManager(WebSessionManager)}.
* @param session the session to use
*/
public Builder session(WebSession session) {
this.sessionManager = exchange -> Mono.just(session);
return this;
}
/**
* Provide a {@code WebSessionManager} instance to use with the exchange.
* <p>This is mutually exclusive with {@link #session(WebSession)}.
* @param sessionManager the session manager to use
*/
public Builder sessionManager(WebSessionManager sessionManager) {
this.sessionManager = sessionManager;
return this;
}
/**
* Build the {@code MockServerWebExchange} instance.
*/
public MockServerWebExchange build() {
return new MockServerWebExchange(this.request,
this.sessionManager != null ? this.sessionManager : new DefaultWebSessionManager());
}
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2017 the original author or authors.
* Copyright 2002-2018 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.
@@ -17,6 +17,7 @@ package org.springframework.web.server.session;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import org.junit.Before;
import org.junit.Test;
@@ -33,14 +34,10 @@ import org.springframework.web.server.WebSession;
import org.springframework.web.server.adapter.DefaultServerWebExchange;
import org.springframework.web.server.i18n.AcceptHeaderLocaleContextResolver;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.*;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import static org.mockito.Mockito.*;
/**
* Unit tests for {@link DefaultWebSessionManager}.
@@ -50,15 +47,15 @@ import static org.mockito.Mockito.when;
@RunWith(MockitoJUnitRunner.class)
public class DefaultWebSessionManagerTests {
private DefaultWebSessionManager manager;
private DefaultWebSessionManager sessionManager;
private ServerWebExchange exchange;
@Mock
private WebSessionIdResolver idResolver;
private WebSessionIdResolver sessionIdResolver;
@Mock
private WebSessionStore store;
private WebSessionStore sessionStore;
@Mock
private WebSession createSession;
@@ -69,78 +66,75 @@ public class DefaultWebSessionManagerTests {
@Before
public void setUp() throws Exception {
when(this.store.createWebSession()).thenReturn(Mono.just(this.createSession));
when(this.createSession.save()).thenReturn(Mono.empty());
when(this.createSession.getId()).thenReturn("create-session-id");
when(this.updateSession.getId()).thenReturn("update-session-id");
this.manager = new DefaultWebSessionManager();
this.manager.setSessionIdResolver(this.idResolver);
this.manager.setSessionStore(this.store);
when(this.sessionStore.createWebSession()).thenReturn(Mono.just(this.createSession));
when(this.sessionStore.retrieveSession(this.updateSession.getId())).thenReturn(Mono.just(this.updateSession));
this.sessionManager = new DefaultWebSessionManager();
this.sessionManager.setSessionIdResolver(this.sessionIdResolver);
this.sessionManager.setSessionStore(this.sessionStore);
MockServerHttpRequest request = MockServerHttpRequest.get("/path").build();
MockServerHttpResponse response = new MockServerHttpResponse();
this.exchange = new DefaultServerWebExchange(request, response, this.manager,
this.exchange = new DefaultServerWebExchange(request, response, this.sessionManager,
ServerCodecConfigurer.create(), new AcceptHeaderLocaleContextResolver());
}
@Test
public void getSessionSaveWhenCreatedAndNotStartedThenNotSaved() throws Exception {
when(this.idResolver.resolveSessionIds(this.exchange)).thenReturn(Collections.emptyList());
WebSession session = this.manager.getSession(this.exchange).block();
public void getSessionSaveWhenCreatedAndNotStartedThenNotSaved() {
when(this.sessionIdResolver.resolveSessionIds(this.exchange)).thenReturn(Collections.emptyList());
WebSession session = this.sessionManager.getSession(this.exchange).block();
this.exchange.getResponse().setComplete().block();
assertSame(this.createSession, session);
assertFalse(session.isStarted());
assertFalse(session.isExpired());
verify(this.createSession, never()).save();
verify(this.idResolver, never()).setSessionId(any(), any());
verify(this.sessionIdResolver, never()).setSessionId(any(), any());
}
@Test
public void getSessionSaveWhenCreatedAndStartedThenSavesAndSetsId() throws Exception {
when(this.idResolver.resolveSessionIds(this.exchange)).thenReturn(Collections.emptyList());
WebSession session = this.manager.getSession(this.exchange).block();
public void getSessionSaveWhenCreatedAndStartedThenSavesAndSetsId() {
when(this.sessionIdResolver.resolveSessionIds(this.exchange)).thenReturn(Collections.emptyList());
WebSession session = this.sessionManager.getSession(this.exchange).block();
assertSame(this.createSession, session);
String sessionId = this.createSession.getId();
when(this.createSession.isStarted()).thenReturn(true);
this.exchange.getResponse().setComplete().block();
String id = session.getId();
verify(this.store).createWebSession();
verify(this.createSession).save();
verify(this.idResolver).setSessionId(any(), eq(id));
}
@Test
public void exchangeWhenResponseSetCompleteThenSavesAndSetsId() throws Exception {
when(this.idResolver.resolveSessionIds(this.exchange)).thenReturn(Collections.emptyList());
String id = this.createSession.getId();
WebSession session = this.manager.getSession(this.exchange).block();
when(this.createSession.isStarted()).thenReturn(true);
this.exchange.getResponse().setComplete().block();
verify(this.idResolver).setSessionId(any(), eq(id));
verify(this.sessionStore).createWebSession();
verify(this.sessionIdResolver).setSessionId(any(), eq(sessionId));
verify(this.createSession).save();
}
@Test
public void existingSession() throws Exception {
String id = this.updateSession.getId();
when(this.store.retrieveSession(id)).thenReturn(Mono.just(this.updateSession));
when(this.idResolver.resolveSessionIds(this.exchange)).thenReturn(Collections.singletonList(id));
public void existingSession() {
WebSession actual = this.manager.getSession(this.exchange).block();
String sessionId = this.updateSession.getId();
when(this.sessionIdResolver.resolveSessionIds(this.exchange)).thenReturn(Collections.singletonList(sessionId));
WebSession actual = this.sessionManager.getSession(this.exchange).block();
assertNotNull(actual);
assertEquals(id, actual.getId());
assertEquals(sessionId, actual.getId());
}
@Test
public void multipleSessionIds() throws Exception {
WebSession existing = this.updateSession;
String id = existing.getId();
when(this.store.retrieveSession(any())).thenReturn(Mono.empty());
when(this.store.retrieveSession(id)).thenReturn(Mono.just(existing));
when(this.idResolver.resolveSessionIds(this.exchange)).thenReturn(Arrays.asList("neither-this", "nor-that", id));
public void multipleSessionIds() {
List<String> ids = Arrays.asList("not-this", "not-that", this.updateSession.getId());
when(this.sessionStore.retrieveSession("not-this")).thenReturn(Mono.empty());
when(this.sessionStore.retrieveSession("not-that")).thenReturn(Mono.empty());
when(this.sessionIdResolver.resolveSessionIds(this.exchange)).thenReturn(ids);
WebSession actual = this.sessionManager.getSession(this.exchange).block();
WebSession actual = this.manager.getSession(this.exchange).block();
assertNotNull(actual);
assertEquals(existing.getId(), actual.getId());
assertEquals(this.updateSession.getId(), actual.getId());
}
}

View File

@@ -55,7 +55,7 @@ public class InMemoryWebSessionStoreTests {
}
@Test
public void retrieveExpiredSession() throws Exception {
public void retrieveExpiredSession() {
WebSession session = this.store.createWebSession().block();
assertNotNull(session);
session.getAttributes().put("foo", "bar");
@@ -73,7 +73,7 @@ public class InMemoryWebSessionStoreTests {
}
@Test
public void lastAccessTimeIsUpdatedOnRetrieve() throws Exception {
public void lastAccessTimeIsUpdatedOnRetrieve() {
WebSession session1 = this.store.createWebSession().block();
assertNotNull(session1);
String id = session1.getId();
@@ -91,7 +91,7 @@ public class InMemoryWebSessionStoreTests {
}
@Test
public void expirationChecks() throws Exception {
public void expirationChecks() {
// Create 3 sessions
WebSession session1 = this.store.createWebSession().block();
assertNotNull(session1);
@@ -131,6 +131,4 @@ public class InMemoryWebSessionStoreTests {
assertNotNull(this.store.retrieveSession(session5.getId()).block());
}
}

View File

@@ -1,47 +0,0 @@
/*
* Copyright 2002-2016 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.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.web.server.session;
import reactor.core.publisher.Mono;
import org.springframework.web.server.ServerWebExchange;
import org.springframework.web.server.WebSession;
/**
* Mock implementation of {@link WebSessionManager}.
*
* @author Rossen Stoyanchev
*/
public class MockWebSessionManager implements WebSessionManager {
private final Mono<WebSession> session;
public MockWebSessionManager(WebSession session) {
this(Mono.just(session));
}
public MockWebSessionManager(Mono<WebSession> session) {
this.session = session;
}
@Override
public Mono<WebSession> getSession(ServerWebExchange exchange) {
return this.session;
}
}