Improve WebSession related tests
Add missing DefaultWebSessionManagerTests .block(). Previously session.save() was invoked, but we did not ensure it was completed. This commit makes it block on session.save() Fix existingSessionIsExpired. This test is actually broken and is testing a new session is created because the session id returned by the idResolver does not match the existing WebSession. This commit ensures that the id of the WebSession found by idResolver matches the existing WebSession. DefaultWebSessionManagerTests use Mockito. To ensure we test with independence from InMemoryWebSessionStore we use Mockito for the DefaultWebessionManager collaborators. Add test for response.setComplete(). We want to ensure that when the response is completed, it saves the WebSession and writes it to the response using idResolver
This commit is contained in:
parent
167ddc7cfc
commit
b7280472d6
|
@ -19,17 +19,17 @@ import java.time.Clock;
|
||||||
import java.time.Duration;
|
import java.time.Duration;
|
||||||
import java.time.Instant;
|
import java.time.Instant;
|
||||||
import java.time.ZoneId;
|
import java.time.ZoneId;
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
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.core.publisher.Mono;
|
||||||
|
|
||||||
import org.springframework.http.codec.ServerCodecConfigurer;
|
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.MockServerHttpRequest;
|
||||||
import org.springframework.mock.http.server.reactive.test.MockServerHttpResponse;
|
import org.springframework.mock.http.server.reactive.test.MockServerHttpResponse;
|
||||||
import org.springframework.util.IdGenerator;
|
import org.springframework.util.IdGenerator;
|
||||||
|
@ -43,13 +43,18 @@ import static org.junit.Assert.assertEquals;
|
||||||
import static org.junit.Assert.assertFalse;
|
import static org.junit.Assert.assertFalse;
|
||||||
import static org.junit.Assert.assertNotNull;
|
import static org.junit.Assert.assertNotNull;
|
||||||
import static org.junit.Assert.assertNotSame;
|
import static org.junit.Assert.assertNotSame;
|
||||||
import static org.junit.Assert.assertNull;
|
import static org.mockito.ArgumentMatchers.any;
|
||||||
import static org.junit.Assert.assertSame;
|
import static org.mockito.ArgumentMatchers.eq;
|
||||||
|
import static org.mockito.Mockito.never;
|
||||||
|
import static org.mockito.Mockito.verify;
|
||||||
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Unit tests for {@link DefaultWebSessionManager}.
|
* Unit tests for {@link DefaultWebSessionManager}.
|
||||||
* @author Rossen Stoyanchev
|
* @author Rossen Stoyanchev
|
||||||
|
* @author Rob Winch
|
||||||
*/
|
*/
|
||||||
|
@RunWith(MockitoJUnitRunner.class)
|
||||||
public class DefaultWebSessionManagerTests {
|
public class DefaultWebSessionManagerTests {
|
||||||
|
|
||||||
private static final Clock CLOCK = Clock.system(ZoneId.of("GMT"));
|
private static final Clock CLOCK = Clock.system(ZoneId.of("GMT"));
|
||||||
|
@ -59,16 +64,19 @@ public class DefaultWebSessionManagerTests {
|
||||||
|
|
||||||
private DefaultWebSessionManager manager;
|
private DefaultWebSessionManager manager;
|
||||||
|
|
||||||
private TestWebSessionIdResolver idResolver;
|
|
||||||
|
|
||||||
private ServerWebExchange exchange;
|
private ServerWebExchange exchange;
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
private WebSessionIdResolver idResolver;
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
private WebSessionStore store;
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void setUp() throws Exception {
|
public void setUp() throws Exception {
|
||||||
this.manager = new DefaultWebSessionManager();
|
this.manager = new DefaultWebSessionManager();
|
||||||
this.idResolver = new TestWebSessionIdResolver();
|
|
||||||
this.manager.setSessionIdResolver(this.idResolver);
|
this.manager.setSessionIdResolver(this.idResolver);
|
||||||
|
this.manager.setSessionStore(this.store);
|
||||||
|
|
||||||
MockServerHttpRequest request = MockServerHttpRequest.get("/path").build();
|
MockServerHttpRequest request = MockServerHttpRequest.get("/path").build();
|
||||||
MockServerHttpResponse response = new MockServerHttpResponse();
|
MockServerHttpResponse response = new MockServerHttpResponse();
|
||||||
|
@ -79,45 +87,60 @@ public class DefaultWebSessionManagerTests {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void getSessionWithoutStarting() throws Exception {
|
public void getSessionWithoutStarting() throws Exception {
|
||||||
this.idResolver.setIdsToResolve(Collections.emptyList());
|
when(this.idResolver.resolveSessionIds(this.exchange)).thenReturn(Collections.emptyList());
|
||||||
WebSession session = this.manager.getSession(this.exchange).block();
|
WebSession session = this.manager.getSession(this.exchange).block();
|
||||||
session.save();
|
session.save().block();
|
||||||
|
|
||||||
assertFalse(session.isStarted());
|
assertFalse(session.isStarted());
|
||||||
assertFalse(session.isExpired());
|
assertFalse(session.isExpired());
|
||||||
assertNull(this.idResolver.getSavedId());
|
verify(this.store, never()).storeSession(any());
|
||||||
assertNull(this.manager.getSessionStore().retrieveSession(session.getId()).block());
|
verify(this.idResolver, never()).setSessionId(any(), any());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void startSessionExplicitly() throws Exception {
|
public void startSessionExplicitly() throws Exception {
|
||||||
this.idResolver.setIdsToResolve(Collections.emptyList());
|
when(this.idResolver.resolveSessionIds(this.exchange)).thenReturn(Collections.emptyList());
|
||||||
|
when(this.store.storeSession(any())).thenReturn(Mono.empty());
|
||||||
WebSession session = this.manager.getSession(this.exchange).block();
|
WebSession session = this.manager.getSession(this.exchange).block();
|
||||||
session.start();
|
session.start();
|
||||||
session.save();
|
session.save().block();
|
||||||
|
|
||||||
String id = session.getId();
|
String id = session.getId();
|
||||||
assertNotNull(this.idResolver.getSavedId());
|
verify(this.store).storeSession(any());
|
||||||
assertEquals(id, this.idResolver.getSavedId());
|
verify(this.idResolver).setSessionId(any(), eq(id));
|
||||||
assertSame(session, this.manager.getSessionStore().retrieveSession(id).block());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void startSessionImplicitly() throws Exception {
|
public void startSessionImplicitly() throws Exception {
|
||||||
this.idResolver.setIdsToResolve(Collections.emptyList());
|
when(this.idResolver.resolveSessionIds(this.exchange)).thenReturn(Collections.emptyList());
|
||||||
|
when(this.store.storeSession(any())).thenReturn(Mono.empty());
|
||||||
WebSession session = this.manager.getSession(this.exchange).block();
|
WebSession session = this.manager.getSession(this.exchange).block();
|
||||||
session.getAttributes().put("foo", "bar");
|
session.getAttributes().put("foo", "bar");
|
||||||
session.save();
|
session.save().block();
|
||||||
|
|
||||||
assertNotNull(this.idResolver.getSavedId());
|
verify(this.idResolver).setSessionId(any(), any());
|
||||||
|
verify(this.store).storeSession(any());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void exchangeWhenResponseSetCompleteThenSavesAndSetsId() throws Exception {
|
||||||
|
when(this.idResolver.resolveSessionIds(this.exchange)).thenReturn(Collections.emptyList());
|
||||||
|
when(this.store.storeSession(any())).thenReturn(Mono.empty());
|
||||||
|
WebSession session = this.manager.getSession(this.exchange).block();
|
||||||
|
String id = session.getId();
|
||||||
|
session.getAttributes().put("foo", "bar");
|
||||||
|
this.exchange.getResponse().setComplete().block();
|
||||||
|
|
||||||
|
verify(this.idResolver).setSessionId(any(), eq(id));
|
||||||
|
verify(this.store).storeSession(any());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void existingSession() throws Exception {
|
public void existingSession() throws Exception {
|
||||||
DefaultWebSession existing = createDefaultWebSession();
|
DefaultWebSession existing = createDefaultWebSession();
|
||||||
String id = existing.getId();
|
String id = existing.getId();
|
||||||
this.manager.getSessionStore().storeSession(existing);
|
when(this.store.retrieveSession(id)).thenReturn(Mono.just(existing));
|
||||||
this.idResolver.setIdsToResolve(Collections.singletonList(id));
|
when(this.idResolver.resolveSessionIds(this.exchange)).thenReturn(Collections.singletonList(id));
|
||||||
|
|
||||||
WebSession actual = this.manager.getSession(this.exchange).block();
|
WebSession actual = this.manager.getSession(this.exchange).block();
|
||||||
assertNotNull(actual);
|
assertNotNull(actual);
|
||||||
|
@ -130,19 +153,23 @@ public class DefaultWebSessionManagerTests {
|
||||||
existing.start();
|
existing.start();
|
||||||
Instant lastAccessTime = Instant.now(CLOCK).minus(Duration.ofMinutes(31));
|
Instant lastAccessTime = Instant.now(CLOCK).minus(Duration.ofMinutes(31));
|
||||||
existing = new DefaultWebSession(existing, lastAccessTime, s -> Mono.empty());
|
existing = new DefaultWebSession(existing, lastAccessTime, s -> Mono.empty());
|
||||||
this.manager.getSessionStore().storeSession(existing);
|
when(this.store.retrieveSession(existing.getId())).thenReturn(Mono.just(existing));
|
||||||
this.idResolver.setIdsToResolve(Collections.singletonList("1"));
|
when(this.store.removeSession(existing.getId())).thenReturn(Mono.empty());
|
||||||
|
when(this.idResolver.resolveSessionIds(this.exchange)).thenReturn(Collections.singletonList(existing.getId()));
|
||||||
|
|
||||||
WebSession actual = this.manager.getSession(this.exchange).block();
|
WebSession actual = this.manager.getSession(this.exchange).block();
|
||||||
assertNotSame(existing, actual);
|
assertNotSame(existing, actual);
|
||||||
|
verify(this.store).removeSession(existing.getId());
|
||||||
|
verify(this.idResolver).expireSession(any());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void multipleSessionIds() throws Exception {
|
public void multipleSessionIds() throws Exception {
|
||||||
DefaultWebSession existing = createDefaultWebSession();
|
DefaultWebSession existing = createDefaultWebSession();
|
||||||
String id = existing.getId();
|
String id = existing.getId();
|
||||||
this.manager.getSessionStore().storeSession(existing);
|
when(this.store.retrieveSession(any())).thenReturn(Mono.empty());
|
||||||
this.idResolver.setIdsToResolve(Arrays.asList("neither-this", "nor-that", id));
|
when(this.store.retrieveSession(id)).thenReturn(Mono.just(existing));
|
||||||
|
when(this.idResolver.resolveSessionIds(this.exchange)).thenReturn(Arrays.asList("neither-this", "nor-that", id));
|
||||||
|
|
||||||
WebSession actual = this.manager.getSession(this.exchange).block();
|
WebSession actual = this.manager.getSession(this.exchange).block();
|
||||||
assertNotNull(actual);
|
assertNotNull(actual);
|
||||||
|
@ -152,39 +179,4 @@ public class DefaultWebSessionManagerTests {
|
||||||
private DefaultWebSession createDefaultWebSession() {
|
private DefaultWebSession createDefaultWebSession() {
|
||||||
return new DefaultWebSession(idGenerator, CLOCK, (s, session) -> Mono.empty(), s -> Mono.empty());
|
return new DefaultWebSession(idGenerator, CLOCK, (s, session) -> Mono.empty(), s -> Mono.empty());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private static class TestWebSessionIdResolver implements WebSessionIdResolver {
|
|
||||||
|
|
||||||
private List<String> idsToResolve = new ArrayList<>();
|
|
||||||
|
|
||||||
@Nullable
|
|
||||||
private String id = null;
|
|
||||||
|
|
||||||
|
|
||||||
public void setIdsToResolve(List<String> idsToResolve) {
|
|
||||||
this.idsToResolve = idsToResolve;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nullable
|
|
||||||
public String getSavedId() {
|
|
||||||
return this.id;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<String> resolveSessionIds(ServerWebExchange exchange) {
|
|
||||||
return this.idsToResolve;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setSessionId(ServerWebExchange exchange, String sessionId) {
|
|
||||||
this.id = sessionId;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void expireSession(ServerWebExchange exchange) {
|
|
||||||
this.id = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue