Polish "Add WebFlux Support"

Closes gh-683
This commit is contained in:
Vedran Pavic
2017-07-21 15:29:51 +02:00
parent 5abbe66b1d
commit 9120151692
6 changed files with 285 additions and 200 deletions

View File

@@ -7,14 +7,14 @@ dependencies {
optional "io.projectreactor:reactor-core"
optional "javax.servlet:javax.servlet-api"
optional "org.springframework.security:spring-security-core"
optional "org.springframework.security:spring-security-web"
optional "org.springframework:spring-context"
optional "org.springframework:spring-jdbc"
optional "org.springframework:spring-messaging"
optional "org.springframework:spring-web"
optional "org.springframework:spring-webflux"
optional "org.springframework:spring-websocket"
optional "org.springframework.security:spring-security-core"
optional "org.springframework.security:spring-security-web"
testCompile "io.projectreactor:reactor-test"
testCompile "junit:junit"

View File

@@ -16,6 +16,14 @@
package org.springframework.session.web.server.session;
import java.time.Clock;
import java.time.Instant;
import java.time.ZoneOffset;
import java.util.List;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import org.springframework.session.ReactorSessionRepository;
import org.springframework.session.Session;
import org.springframework.util.Assert;
@@ -25,33 +33,39 @@ import org.springframework.web.server.session.CookieWebSessionIdResolver;
import org.springframework.web.server.session.WebSessionIdResolver;
import org.springframework.web.server.session.WebSessionManager;
import org.springframework.web.server.session.WebSessionStore;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import java.time.Clock;
import java.time.Instant;
import java.time.ZoneId;
import java.util.List;
/**
* The {@link WebSessionManager} implementation backed by
* {@link ReactorSessionRepository}.
*
* @author Rob Winch
* @since 2.0
*/
public class SpringSessionWebSessionManager implements WebSessionManager {
private final SpringSessionWebSessionStore<? extends Session> sessionStore;
private WebSessionIdResolver sessionIdResolver = new CookieWebSessionIdResolver();
private Clock clock = Clock.system(ZoneId.of("GMT"));
private Clock clock = Clock.system(ZoneOffset.UTC);
public SpringSessionWebSessionManager(ReactorSessionRepository<? extends Session> sessionRepository) {
sessionStore
= new SpringSessionWebSessionStore<>(sessionRepository);
public SpringSessionWebSessionManager(
ReactorSessionRepository<? extends Session> sessionRepository) {
this.sessionStore = new SpringSessionWebSessionStore<>(sessionRepository);
}
/**
* Return the configured {@link WebSessionIdResolver}.
* @return the configured {@link WebSessionIdResolver}
*/
private WebSessionIdResolver getSessionIdResolver() {
return this.sessionIdResolver;
}
/**
* Configure the id resolution strategy.
* <p>By default an instance of {@link CookieWebSessionIdResolver}.
* <p>
* By default an instance of {@link CookieWebSessionIdResolver}.
* @param sessionIdResolver the resolver to use
*/
public void setSessionIdResolver(WebSessionIdResolver sessionIdResolver) {
@@ -59,27 +73,31 @@ public class SpringSessionWebSessionManager implements WebSessionManager {
this.sessionIdResolver = sessionIdResolver;
}
/**
* Return the configured {@link WebSessionIdResolver}.
*/
private WebSessionIdResolver getSessionIdResolver() {
return this.sessionIdResolver;
}
/**
* Return the configured {@link WebSessionStore}.
* @return the configured {@link WebSessionStore}
*/
private WebSessionStore getSessionStore() {
return this.sessionStore;
}
/**
* Configure the {@link Clock} to use to set lastAccessTime on every created
* session and to calculate if it is expired.
* <p>This may be useful to align to different timezone or to set the clock
* back in a test, e.g. {@code Clock.offset(clock, Duration.ofMinutes(-31))}
* in order to simulate session expiration.
* <p>By default this is {@code Clock.system(ZoneId.of("GMT"))}.
* Return the configured clock for session {@code lastAccessTime} calculations.
* @return the configured clock for session {@code lastAccessTime} calculations
*/
private Clock getClock() {
return this.clock;
}
/**
* Configure the {@link Clock} to use to set lastAccessTime on every created session
* and to calculate if it is expired.
* <p>
* This may be useful to align to different timezone or to set the clock back in a
* test, e.g. {@code Clock.offset(clock, Duration.ofMinutes(-31))} in order to
* simulate session expiration.
* <p>
* By default this is {@code Clock.system(ZoneOffset.UTC)}.
* @param clock the clock to use
*/
public void setClock(Clock clock) {
@@ -87,15 +105,9 @@ public class SpringSessionWebSessionManager implements WebSessionManager {
this.clock = clock;
}
/**
* Return the configured clock for session lastAccessTime calculations.
*/
private Clock getClock() {
return this.clock;
}
@Override
public Mono<WebSession> getSession(ServerWebExchange exchange) {
// @formatter:off
return Mono.defer(() ->
retrieveSession(exchange)
.flatMap(session -> removeSessionIfExpired(exchange, session))
@@ -105,16 +117,20 @@ public class SpringSessionWebSessionManager implements WebSessionManager {
})
.switchIfEmpty(createSession(exchange))
.doOnNext(session -> exchange.getResponse().beforeCommit(session::save)));
// @formatter:on
}
private Mono<WebSession> retrieveSession(ServerWebExchange exchange) {
// @formatter:off
return Flux.fromIterable(getSessionIdResolver().resolveSessionIds(exchange))
.concatMap(this.sessionStore::retrieveSession)
.cast(WebSession.class)
.next();
// @formatter:on
}
private Mono<WebSession> removeSessionIfExpired(ServerWebExchange exchange, WebSession session) {
private Mono<WebSession> removeSessionIfExpired(ServerWebExchange exchange,
WebSession session) {
if (session.isExpired()) {
this.sessionIdResolver.expireSession(exchange);
return this.sessionStore.removeSession(session.getId()).then(Mono.empty());
@@ -125,10 +141,10 @@ public class SpringSessionWebSessionManager implements WebSessionManager {
private Mono<Void> saveSession(ServerWebExchange exchange, WebSession session) {
if (session.isExpired()) {
return Mono.error(new IllegalStateException(
"Sessions are checked for expiration and have their " +
"lastAccessTime updated when first accessed during request processing. " +
"However this session is expired meaning that maxIdleTime elapsed " +
"before the call to session.save()."));
"Sessions are checked for expiration and have their "
+ "lastAccessTime updated when first accessed during request processing. "
+ "However this session is expired meaning that maxIdleTime elapsed "
+ "before the call to session.save()."));
}
if (!session.isStarted()) {
@@ -153,4 +169,5 @@ public class SpringSessionWebSessionManager implements WebSessionManager {
private Mono<WebSession> createSession(ServerWebExchange exchange) {
return this.sessionStore.createSession();
}
}

View File

@@ -16,25 +16,39 @@
package org.springframework.session.web.server.session;
import java.time.Duration;
import java.time.Instant;
import java.util.AbstractCollection;
import java.util.AbstractMap;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.atomic.AtomicReference;
import java.util.function.Supplier;
import reactor.core.publisher.Mono;
import org.springframework.lang.Nullable;
import org.springframework.session.ReactorSessionRepository;
import org.springframework.session.Session;
import org.springframework.util.Assert;
import org.springframework.web.server.WebSession;
import org.springframework.web.server.session.WebSessionStore;
import reactor.core.publisher.Mono;
import java.time.Duration;
import java.time.Instant;
import java.util.*;
import java.util.concurrent.atomic.AtomicReference;
import java.util.function.Supplier;
/**
* The {@link WebSessionStore} implementation that provides the {@link WebSession}
* implementation backed by a {@link Session} returned by the
* {@link ReactorSessionRepository}.
*
* @param <S> the {@link Session} type
* @author Rob Winch
* @since 2.0
*/
class SpringSessionWebSessionStore<S extends Session> implements WebSessionStore {
private final ReactorSessionRepository<S> sessions;
SpringSessionWebSessionStore(ReactorSessionRepository<S> sessions) {
@@ -48,6 +62,7 @@ class SpringSessionWebSessionStore<S extends Session> implements WebSessionStore
public Mono<WebSession> setLastAccessedTime(WebSession session,
Instant lastAccessedTime) {
@SuppressWarnings("unchecked")
SpringSessionWebSession springSessionWebSession = (SpringSessionWebSession) session;
springSessionWebSession.session.setLastAccessedTime(lastAccessedTime);
return Mono.just(session);
@@ -80,92 +95,17 @@ class SpringSessionWebSessionStore<S extends Session> implements WebSessionStore
@Override
public Mono<Void> removeSession(String sessionId) {
return sessions.delete(sessionId);
}
private class SpringSessionWebSession implements WebSession {
private final S session;
private final Map<String, Object> attributes;
private AtomicReference<State> state = new AtomicReference<>();
private volatile transient Supplier<Mono<Void>> saveOperation = Mono::empty;
SpringSessionWebSession(S session, State state) {
Assert.notNull(session, "session cannot be null");
this.session = session;
this.attributes = new SpringSessionMap(session);
this.state.set(state);
}
@Override
public String getId() {
return session.getId();
}
@Override
public Mono<Void> changeSessionId() {
return Mono.defer(() -> {
session.changeSessionId();
return save();
});
}
@Override
public Map<String, Object> getAttributes() {
return this.attributes;
}
@Override
public void start() {
this.state.compareAndSet(State.NEW, State.STARTED);
}
@Override
public boolean isStarted() {
State value = this.state.get();
return (State.STARTED.equals(value)
|| (State.NEW.equals(value) && !getAttributes().isEmpty()));
}
@Override
public Mono<Void> save() {
return this.saveOperation.get();
}
@Override
public boolean isExpired() {
return this.session.isExpired();
}
@Override
public Instant getCreationTime() {
return this.session.getCreationTime();
}
@Override
public Instant getLastAccessTime() {
return this.session.getLastAccessedTime();
}
@Override
public void setMaxIdleTime(Duration maxIdleTime) {
this.session.setMaxInactiveInterval(maxIdleTime);
}
@Override
public Duration getMaxIdleTime() {
return this.session.getMaxInactiveInterval();
}
return this.sessions.delete(sessionId);
}
private enum State {
NEW, STARTED
}
static class SpringSessionMap implements Map<String, Object> {
private static class SpringSessionMap implements Map<String, Object> {
private final Session session;
private final Collection<Object> values = new SessionValues();
SpringSessionMap(Session session) {
@@ -243,7 +183,7 @@ class SpringSessionWebSessionStore<S extends Session> implements WebSessionStore
@Override
public Collection<Object> values() {
return values;
return this.values;
}
@Override
@@ -258,21 +198,24 @@ class SpringSessionWebSessionStore<S extends Session> implements WebSessionStore
}
private class SessionValues extends AbstractCollection<Object> {
public Iterator<Object> iterator() {
return new Iterator<Object>() {
private Iterator<Entry<String, Object>> i = entrySet().iterator();
public boolean hasNext() {
return i.hasNext();
return this.i.hasNext();
}
public Object next() {
return i.next().getValue();
return this.i.next().getValue();
}
public void remove() {
i.remove();
this.i.remove();
}
};
}
@@ -291,6 +234,91 @@ class SpringSessionWebSessionStore<S extends Session> implements WebSessionStore
public boolean contains(Object v) {
return SpringSessionMap.this.containsValue(v);
}
}
}
/**
* Adapts Spring Session's {@link Session} to a {@link WebSession}.
*/
private class SpringSessionWebSession implements WebSession {
private final S session;
private final Map<String, Object> attributes;
private AtomicReference<State> state = new AtomicReference<>();
private volatile transient Supplier<Mono<Void>> saveOperation = Mono::empty;
SpringSessionWebSession(S session, State state) {
Assert.notNull(session, "session cannot be null");
this.session = session;
this.attributes = new SpringSessionMap(session);
this.state.set(state);
}
@Override
public String getId() {
return this.session.getId();
}
@Override
public Mono<Void> changeSessionId() {
return Mono.defer(() -> {
this.session.changeSessionId();
return save();
});
}
@Override
public Map<String, Object> getAttributes() {
return this.attributes;
}
@Override
public void start() {
this.state.compareAndSet(State.NEW, State.STARTED);
}
@Override
public boolean isStarted() {
State value = this.state.get();
return (State.STARTED.equals(value)
|| (State.NEW.equals(value) && !getAttributes().isEmpty()));
}
@Override
public Mono<Void> save() {
return this.saveOperation.get();
}
@Override
public boolean isExpired() {
return this.session.isExpired();
}
@Override
public Instant getCreationTime() {
return this.session.getCreationTime();
}
@Override
public Instant getLastAccessTime() {
return this.session.getLastAccessedTime();
}
@Override
public Duration getMaxIdleTime() {
return this.session.getMaxInactiveInterval();
}
@Override
public void setMaxIdleTime(Duration maxIdleTime) {
this.session.setMaxInactiveInterval(maxIdleTime);
}
}
}

View File

@@ -1,8 +1,23 @@
/*
* Copyright 2014-2017 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.
*/
/**
* @author Rob Winch
* @since 5.0
* Spring Session reactive web support.
*/
@NonNullApi
package org.springframework.session.web.server.session;
import org.springframework.lang.NonNullApi;
import org.springframework.lang.NonNullApi;

View File

@@ -16,11 +16,18 @@
package org.springframework.session.web.server.session;
import java.time.Duration;
import java.util.Arrays;
import java.util.Collections;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnitRunner;
import reactor.core.publisher.Mono;
import reactor.test.StepVerifier;
import org.springframework.http.HttpCookie;
import org.springframework.mock.http.server.reactive.MockServerHttpRequest;
import org.springframework.session.ReactorSessionRepository;
@@ -28,49 +35,45 @@ import org.springframework.session.Session;
import org.springframework.web.server.ServerWebExchange;
import org.springframework.web.server.WebSession;
import org.springframework.web.server.session.WebSessionIdResolver;
import reactor.core.publisher.Mono;
import reactor.test.StepVerifier;
import java.time.Duration;
import java.util.Arrays;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.times;
import static org.mockito.BDDMockito.given;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
/**
* Tests for {@link SpringSessionWebSessionManager}.
*
* @author Rob Winch
* @since 5.0
*/
@RunWith(MockitoJUnitRunner.class)
public class SpringSessionWebSessionManagerTests<S extends Session> {
@Mock
ReactorSessionRepository<S> sessions;
@Mock
WebSessionIdResolver resolver;
private ReactorSessionRepository<S> sessions;
@Mock
S createSession;
private WebSessionIdResolver resolver;
@Mock
S findByIdSession;
private S createSession;
Mono<S> createSessionMono;
@Mock
private S findByIdSession;
ServerWebExchange exchange = MockServerHttpRequest.get("/").toExchange();
private Mono<S> createSessionMono;
private ServerWebExchange exchange = MockServerHttpRequest.get("/").toExchange();
SpringSessionWebSessionManager manager;
private SpringSessionWebSessionManager manager;
@Before
public void setup() {
when(this.createSession.getId()).thenReturn("createSession-id");
when(this.findByIdSession.getId()).thenReturn("findByIdSession-id");
given(this.createSession.getId()).willReturn("createSession-id");
given(this.findByIdSession.getId()).willReturn("findByIdSession-id");
this.createSessionMono = Mono.just(this.createSession);
when(this.sessions.createSession()).thenReturn(createSessionMono);
given(this.sessions.createSession()).willReturn(this.createSessionMono);
this.manager = new SpringSessionWebSessionManager(this.sessions);
this.manager.setSessionIdResolver(this.resolver);
}
@@ -78,11 +81,13 @@ public class SpringSessionWebSessionManagerTests<S extends Session> {
@Test
public void getSessionWhenDefaultSessionIdResolverFoundSessionUsed() {
String findByIdSessionId = this.findByIdSession.getId();
this.exchange = MockServerHttpRequest.get("/").cookie(new HttpCookie("SESSION", findByIdSessionId)).toExchange();
this.exchange = MockServerHttpRequest.get("/")
.cookie(new HttpCookie("SESSION", findByIdSessionId)).toExchange();
this.manager = new SpringSessionWebSessionManager(this.sessions);
when(this.sessions.findById(findByIdSessionId)).thenReturn(Mono.just(findByIdSession));
given(this.sessions.findById(findByIdSessionId))
.willReturn(Mono.just(this.findByIdSession));
WebSession webSession = this.manager.getSession(exchange).block();
WebSession webSession = this.manager.getSession(this.exchange).block();
assertThat(webSession.getId()).isEqualTo(findByIdSessionId);
verify(this.sessions).findById(findByIdSessionId);
@@ -90,7 +95,7 @@ public class SpringSessionWebSessionManagerTests<S extends Session> {
@Test
public void getSessionWhenNewThenCreateSessionInvoked() {
WebSession webSession = this.manager.getSession(exchange).block();
WebSession webSession = this.manager.getSession(this.exchange).block();
assertThat(webSession.getId()).isEqualTo(this.createSession.getId());
verify(this.sessions).createSession();
@@ -101,7 +106,7 @@ public class SpringSessionWebSessionManagerTests<S extends Session> {
String attrName = "attrName";
String attrValue = "attrValue";
WebSession webSession = this.manager.getSession(exchange).block();
WebSession webSession = this.manager.getSession(this.exchange).block();
webSession.getAttributes().put(attrName, attrValue);
verify(this.createSession).setAttribute(attrName, attrValue);
@@ -111,29 +116,31 @@ public class SpringSessionWebSessionManagerTests<S extends Session> {
public void getSessionWhenInvalidIdThenCreateSessionInvoked() {
String invalidId = "invalid";
String createSessionId = this.createSession.getId();
when(this.sessions.findById(any())).thenReturn(Mono.empty());
when(this.resolver.resolveSessionIds(exchange)).thenReturn(Arrays.asList(invalidId));
given(this.sessions.findById(any())).willReturn(Mono.empty());
given(this.resolver.resolveSessionIds(this.exchange))
.willReturn(Collections.singletonList(invalidId));
WebSession webSession = this.manager.getSession(exchange).block();
WebSession webSession = this.manager.getSession(this.exchange).block();
assertThat(webSession.getId()).isEqualTo(createSessionId);
verify(this.sessions).findById(invalidId);
Mono<String> mono = Mono.just("toTest");
StepVerifier
.create(mono)
.expectNoEvent(Duration.ZERO);
StepVerifier.create(mono).expectNoEvent(Duration.ZERO);
}
@Test
public void getSessionWhenValidIdThenFoundSessionUsed() {
String findByIdSessionId = this.findByIdSession.getId();
when(this.sessions.findById(findByIdSessionId)).thenReturn(Mono.just(findByIdSession));
when(this.resolver.resolveSessionIds(exchange)).thenReturn(Arrays.asList(findByIdSessionId));
given(this.sessions.findById(findByIdSessionId))
.willReturn(Mono.just(this.findByIdSession));
given(this.resolver.resolveSessionIds(this.exchange))
.willReturn(Arrays.asList(findByIdSessionId));
WebSession webSession = this.manager.getSession(exchange).block();
WebSession webSession = this.manager.getSession(this.exchange).block();
assertThat(webSession.getId()).isEqualTo(findByIdSessionId);
verify(this.sessions).findById(findByIdSessionId);
}
}
}

View File

@@ -16,51 +16,59 @@
package org.springframework.session.web.server.session;
import java.util.AbstractMap;
import java.util.Collections;
import java.util.Map;
import java.util.Set;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnitRunner;
import reactor.core.publisher.Mono;
import org.springframework.session.ReactorSessionRepository;
import org.springframework.session.Session;
import org.springframework.web.server.WebSession;
import reactor.core.publisher.Mono;
import java.util.AbstractMap;
import java.util.Collections;
import java.util.Map;
import java.util.Set;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.BDDMockito.given;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
/**
* Tests for {@link SpringSessionWebSessionStore}.
*
* @author Rob Winch
* @since 5.0
*/
@RunWith(MockitoJUnitRunner.class)
public class SpringSessionWebSessionStoreTests<S extends Session> {
@Mock
ReactorSessionRepository<S> sessionRepository;
private ReactorSessionRepository<S> sessionRepository;
@Mock
S createSession;
private S createSession;
@Mock
S findByIdSession;
SpringSessionWebSessionStore<S> webSessionStore;
private S findByIdSession;
private SpringSessionWebSessionStore<S> webSessionStore;
@Before
public void setup() {
this.webSessionStore = new SpringSessionWebSessionStore<>(sessionRepository);
when(this.sessionRepository.findById(any())).thenReturn(Mono.just(findByIdSession));
when(this.sessionRepository.createSession()).thenReturn(Mono.just(createSession));
this.webSessionStore = new SpringSessionWebSessionStore<>(this.sessionRepository);
given(this.sessionRepository.findById(any()))
.willReturn(Mono.just(this.findByIdSession));
given(this.sessionRepository.createSession())
.willReturn(Mono.just(this.createSession));
}
@Test(expected = IllegalArgumentException.class)
public void constructorWhenNullRepositoryThenThrowsIllegalArgumentException() {
new SpringSessionWebSessionStore<S>((ReactorSessionRepository<S>) null);
new SpringSessionWebSessionStore<S>(null);
}
@Test
@@ -72,7 +80,8 @@ public class SpringSessionWebSessionStoreTests<S extends Session> {
@Test
public void createSessionWhenAddAttributeThenStarted() {
when(createSession.getAttributeNames()).thenReturn(Collections.singleton("a"));
given(this.createSession.getAttributeNames())
.willReturn(Collections.singleton("a"));
WebSession createdWebSession = this.webSessionStore.createSession().block();
assertThat(createdWebSession.isStarted()).isTrue();
@@ -86,7 +95,8 @@ public class SpringSessionWebSessionStoreTests<S extends Session> {
assertThat(attributes.size()).isEqualTo(0);
when(this.createSession.getAttributeNames()).thenReturn(Collections.singleton("a"));
given(this.createSession.getAttributeNames())
.willReturn(Collections.singleton("a"));
assertThat(attributes.size()).isEqualTo(1);
}
@@ -99,7 +109,8 @@ public class SpringSessionWebSessionStoreTests<S extends Session> {
assertThat(attributes.isEmpty()).isTrue();
when(this.createSession.getAttributeNames()).thenReturn(Collections.singleton("a"));
given(this.createSession.getAttributeNames())
.willReturn(Collections.singleton("a"));
assertThat(attributes.isEmpty()).isFalse();
}
@@ -124,7 +135,8 @@ public class SpringSessionWebSessionStoreTests<S extends Session> {
@Test
public void createSessionWhenGetAttributesAndContainsKeyAndFoundThenTrue() {
when(this.createSession.getAttributeNames()).thenReturn(Collections.singleton("a"));
given(this.createSession.getAttributeNames())
.willReturn(Collections.singleton("a"));
WebSession createdWebSession = this.webSessionStore.createSession().block();
Map<String, Object> attributes = createdWebSession.getAttributes();
@@ -139,7 +151,7 @@ public class SpringSessionWebSessionStoreTests<S extends Session> {
Map<String, Object> attributes = createdWebSession.getAttributes();
attributes.put("a", "b");
verify(createSession).setAttribute("a", "b");
verify(this.createSession).setAttribute("a", "b");
}
@Test
@@ -149,7 +161,7 @@ public class SpringSessionWebSessionStoreTests<S extends Session> {
Map<String, Object> attributes = createdWebSession.getAttributes();
attributes.put("a", null);
verify(createSession).setAttribute("a", null);
verify(this.createSession).setAttribute("a", null);
}
@Test
@@ -159,7 +171,7 @@ public class SpringSessionWebSessionStoreTests<S extends Session> {
Map<String, Object> attributes = createdWebSession.getAttributes();
attributes.remove("a");
verify(createSession).removeAttribute("a");
verify(this.createSession).removeAttribute("a");
}
@Test
@@ -167,25 +179,27 @@ public class SpringSessionWebSessionStoreTests<S extends Session> {
WebSession createdWebSession = this.webSessionStore.createSession().block();
Map<String, Object> attributes = createdWebSession.getAttributes();
attributes.putAll(Collections.singletonMap("a","b"));
attributes.putAll(Collections.singletonMap("a", "b"));
verify(createSession).setAttribute("a", "b");
verify(this.createSession).setAttribute("a", "b");
}
@Test
public void createSessionWhenGetAttributesAndClearThenDelegatesToCreateSession() {
when(this.createSession.getAttributeNames()).thenReturn(Collections.singleton("a"));
given(this.createSession.getAttributeNames())
.willReturn(Collections.singleton("a"));
WebSession createdWebSession = this.webSessionStore.createSession().block();
Map<String, Object> attributes = createdWebSession.getAttributes();
attributes.clear();
verify(createSession).removeAttribute("a");
verify(this.createSession).removeAttribute("a");
}
@Test
public void createSessionWhenGetAttributesAndKeySetThenDelegatesToCreateSession() {
when(this.createSession.getAttributeNames()).thenReturn(Collections.singleton("a"));
given(this.createSession.getAttributeNames())
.willReturn(Collections.singleton("a"));
WebSession createdWebSession = this.webSessionStore.createSession().block();
Map<String, Object> attributes = createdWebSession.getAttributes();
@@ -195,8 +209,9 @@ public class SpringSessionWebSessionStoreTests<S extends Session> {
@Test
public void createSessionWhenGetAttributesAndValuesThenDelegatesToCreateSession() {
when(this.createSession.getAttributeNames()).thenReturn(Collections.singleton("a"));
when(this.createSession.getAttribute("a")).thenReturn("b");
given(this.createSession.getAttributeNames())
.willReturn(Collections.singleton("a"));
given(this.createSession.getAttribute("a")).willReturn("b");
WebSession createdWebSession = this.webSessionStore.createSession().block();
Map<String, Object> attributes = createdWebSession.getAttributes();
@@ -207,20 +222,22 @@ public class SpringSessionWebSessionStoreTests<S extends Session> {
@Test
public void createSessionWhenGetAttributesAndEntrySetThenDelegatesToCreateSession() {
String attrName = "attrName";
when(createSession.getAttributeNames()).thenReturn(Collections.singleton(attrName));
given(this.createSession.getAttributeNames())
.willReturn(Collections.singleton(attrName));
String attrValue = "attrValue";
when(createSession.getAttribute(attrName)).thenReturn(attrValue);
given(this.createSession.getAttribute(attrName)).willReturn(attrValue);
WebSession createdWebSession = this.webSessionStore.createSession().block();
Map<String, Object> attributes = createdWebSession.getAttributes();
Set<Map.Entry<String, Object>> entries = attributes.entrySet();
assertThat(entries).containsExactly(new AbstractMap.SimpleEntry<String, Object>(attrName, attrValue));
assertThat(entries)
.containsExactly(new AbstractMap.SimpleEntry<>(attrName, attrValue));
}
@Test
public void storeSessionWhenInvokedThenSessionSaved() {
when(this.sessionRepository.save(this.createSession)).thenReturn(Mono.empty());
given(this.sessionRepository.save(this.createSession)).willReturn(Mono.empty());
WebSession createdSession = this.webSessionStore.createSession().block();
this.webSessionStore.storeSession(createdSession).block();
@@ -239,10 +256,11 @@ public class SpringSessionWebSessionStoreTests<S extends Session> {
@Test
public void removeSessionWhenInvokedThenSessionSaved() {
String sessionId = "session-id";
when(this.sessionRepository.delete(sessionId)).thenReturn(Mono.empty());
given(this.sessionRepository.delete(sessionId)).willReturn(Mono.empty());
this.webSessionStore.removeSession(sessionId).block();
verify(this.sessionRepository).delete(sessionId);
}
}
}