Improve test coverage
This commit is contained in:
@@ -41,6 +41,11 @@ import java.util.UUID;
|
||||
* @author Rob Winch
|
||||
*/
|
||||
public final class MapSession implements Session {
|
||||
/**
|
||||
* Default {@link #setMaxInactiveInterval(int)} (30 minutes)
|
||||
*/
|
||||
public static final int DEFAULT_MAX_INACTIVE_INTERVAL_SECONDS = 1800;
|
||||
|
||||
private String id = UUID.randomUUID().toString();
|
||||
private Map<String, Object> sessionAttrs = new HashMap<String, Object>();
|
||||
private long creationTime = System.currentTimeMillis();
|
||||
@@ -49,7 +54,7 @@ public final class MapSession implements Session {
|
||||
/**
|
||||
* Defaults to 30 minutes
|
||||
*/
|
||||
private int maxInactiveInterval = 1800;
|
||||
private int maxInactiveInterval = DEFAULT_MAX_INACTIVE_INTERVAL_SECONDS;
|
||||
|
||||
/**
|
||||
* Creates a new instance
|
||||
|
||||
@@ -92,218 +92,228 @@ import java.util.concurrent.TimeUnit;
|
||||
* @author Rob Winch
|
||||
*/
|
||||
public class RedisOperationsSessionRepository implements SessionRepository<RedisOperationsSessionRepository.RedisSession> {
|
||||
/**
|
||||
* The prefix for each key of the Redis Hash representing a single session. The suffix is the unique session id.
|
||||
*/
|
||||
private final String BOUNDED_HASH_KEY_PREFIX = "spring-security-sessions:";
|
||||
/**
|
||||
* The prefix for each key of the Redis Hash representing a single session. The suffix is the unique session id.
|
||||
*/
|
||||
static final String BOUNDED_HASH_KEY_PREFIX = "spring-security-sessions:";
|
||||
|
||||
/**
|
||||
* The key in the Hash representing {@link org.springframework.session.Session#getCreationTime()}
|
||||
*/
|
||||
private final String CREATION_TIME_ATTR = "creationTime";
|
||||
/**
|
||||
* The key in the Hash representing {@link org.springframework.session.Session#getCreationTime()}
|
||||
*/
|
||||
static final String CREATION_TIME_ATTR = "creationTime";
|
||||
|
||||
/**
|
||||
* The key in the Hash representing {@link org.springframework.session.Session#getMaxInactiveInterval()}
|
||||
*/
|
||||
private final String MAX_INACTIVE_ATTR = "maxInactiveInterval";
|
||||
/**
|
||||
* The key in the Hash representing {@link org.springframework.session.Session#getMaxInactiveInterval()}
|
||||
*/
|
||||
static final String MAX_INACTIVE_ATTR = "maxInactiveInterval";
|
||||
|
||||
/**
|
||||
* The key in the Hash representing {@link org.springframework.session.Session#getLastAccessedTime()}
|
||||
*/
|
||||
private final String LAST_ACCESSED_ATTR = "lastAccessedTime";
|
||||
/**
|
||||
* The key in the Hash representing {@link org.springframework.session.Session#getLastAccessedTime()}
|
||||
*/
|
||||
static final String LAST_ACCESSED_ATTR = "lastAccessedTime";
|
||||
|
||||
/**
|
||||
* The prefix of the key for used for session attributes. The suffix is the name of the session attribute. For
|
||||
* example, if the session contained an attribute named attributeName, then there would be an entry in the hash named
|
||||
* sessionAttr:attributeName that mapped to its value.
|
||||
*/
|
||||
private final String SESSION_ATTR_PREFIX = "sessionAttr:";
|
||||
/**
|
||||
* The prefix of the key for used for session attributes. The suffix is the name of the session attribute. For
|
||||
* example, if the session contained an attribute named attributeName, then there would be an entry in the hash named
|
||||
* sessionAttr:attributeName that mapped to its value.
|
||||
*/
|
||||
static final String SESSION_ATTR_PREFIX = "sessionAttr:";
|
||||
|
||||
private final RedisOperations<String,Session> redisOperations;
|
||||
private final RedisOperations<String,Session> redisOperations;
|
||||
|
||||
/**
|
||||
* If non-null, this value is used to override {@link RedisSession#setDefaultMaxInactiveInterval(int)}.
|
||||
*/
|
||||
private Integer defaultMaxInactiveInterval;
|
||||
/**
|
||||
* If non-null, this value is used to override {@link RedisSession#setDefaultMaxInactiveInterval(int)}.
|
||||
*/
|
||||
private Integer defaultMaxInactiveInterval;
|
||||
|
||||
/**
|
||||
* Creates a new instance. For an example, refer to the class level javadoc.
|
||||
*
|
||||
* @param redisOperations The {@link RedisOperations} to use. Cannot be null.
|
||||
*/
|
||||
public RedisOperationsSessionRepository(RedisOperations<String, Session> redisOperations) {
|
||||
Assert.notNull(redisOperations, "RedisOperations cannot be null");
|
||||
this.redisOperations = redisOperations;
|
||||
}
|
||||
/**
|
||||
* Creates a new instance. For an example, refer to the class level javadoc.
|
||||
*
|
||||
* @param redisOperations The {@link RedisOperations} to use. Cannot be null.
|
||||
*/
|
||||
public RedisOperationsSessionRepository(RedisOperations<String, Session> redisOperations) {
|
||||
Assert.notNull(redisOperations, "RedisOperations cannot be null");
|
||||
this.redisOperations = redisOperations;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the maximum inactive interval in seconds between requests before newly created sessions will be
|
||||
* invalidated. A negative time indicates that the session will never timeout. The default is 1800 (30 minutes).
|
||||
*
|
||||
* @param defaultMaxInactiveInterval the number of seconds that the {@link Session} should be kept alive between
|
||||
* client requests.
|
||||
*/
|
||||
public void setDefaultMaxInactiveInterval(int defaultMaxInactiveInterval) {
|
||||
this.defaultMaxInactiveInterval = defaultMaxInactiveInterval;
|
||||
}
|
||||
/**
|
||||
* Sets the maximum inactive interval in seconds between requests before newly created sessions will be
|
||||
* invalidated. A negative time indicates that the session will never timeout. The default is 1800 (30 minutes).
|
||||
*
|
||||
* @param defaultMaxInactiveInterval the number of seconds that the {@link Session} should be kept alive between
|
||||
* client requests.
|
||||
*/
|
||||
public void setDefaultMaxInactiveInterval(int defaultMaxInactiveInterval) {
|
||||
this.defaultMaxInactiveInterval = defaultMaxInactiveInterval;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void save(RedisSession session) {
|
||||
session.saveDelta();
|
||||
}
|
||||
@Override
|
||||
public void save(RedisSession session) {
|
||||
session.saveDelta();
|
||||
}
|
||||
|
||||
@Override
|
||||
public RedisSession getSession(String id) {
|
||||
Map<Object, Object> entries = getSessionBoundHashOperations(id).entries();
|
||||
if(entries.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
MapSession loaded = new MapSession();
|
||||
loaded.setId(id);
|
||||
for(Map.Entry<Object,Object> entry : entries.entrySet()) {
|
||||
String key = (String) entry.getKey();
|
||||
if(CREATION_TIME_ATTR.equals(key)) {
|
||||
loaded.setCreationTime((Long) entry.getValue());
|
||||
} else if(MAX_INACTIVE_ATTR.equals(key)) {
|
||||
loaded.setMaxInactiveInterval((Integer) entry.getValue());
|
||||
} else if(LAST_ACCESSED_ATTR.equals(key)) {
|
||||
loaded.setLastAccessedTime((Long) entry.getValue());
|
||||
} else if(key.startsWith(SESSION_ATTR_PREFIX)) {
|
||||
loaded.setAttribute(key.substring(SESSION_ATTR_PREFIX.length()), entry.getValue());
|
||||
}
|
||||
}
|
||||
return new RedisSession(loaded);
|
||||
}
|
||||
@Override
|
||||
public RedisSession getSession(String id) {
|
||||
Map<Object, Object> entries = getSessionBoundHashOperations(id).entries();
|
||||
if(entries.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
MapSession loaded = new MapSession();
|
||||
loaded.setId(id);
|
||||
for(Map.Entry<Object,Object> entry : entries.entrySet()) {
|
||||
String key = (String) entry.getKey();
|
||||
if(CREATION_TIME_ATTR.equals(key)) {
|
||||
loaded.setCreationTime((Long) entry.getValue());
|
||||
} else if(MAX_INACTIVE_ATTR.equals(key)) {
|
||||
loaded.setMaxInactiveInterval((Integer) entry.getValue());
|
||||
} else if(LAST_ACCESSED_ATTR.equals(key)) {
|
||||
loaded.setLastAccessedTime((Long) entry.getValue());
|
||||
} else if(key.startsWith(SESSION_ATTR_PREFIX)) {
|
||||
loaded.setAttribute(key.substring(SESSION_ATTR_PREFIX.length()), entry.getValue());
|
||||
}
|
||||
}
|
||||
return new RedisSession(loaded);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void delete(String sessionId) {
|
||||
String key = getKey(sessionId);
|
||||
this.redisOperations.delete(key);
|
||||
}
|
||||
@Override
|
||||
public void delete(String sessionId) {
|
||||
String key = getKey(sessionId);
|
||||
this.redisOperations.delete(key);
|
||||
}
|
||||
|
||||
@Override
|
||||
public RedisSession createSession() {
|
||||
RedisSession redisSession = new RedisSession();
|
||||
if(defaultMaxInactiveInterval != null) {
|
||||
redisSession.setMaxInactiveInterval(defaultMaxInactiveInterval);
|
||||
}
|
||||
return redisSession;
|
||||
}
|
||||
@Override
|
||||
public RedisSession createSession() {
|
||||
RedisSession redisSession = new RedisSession();
|
||||
if(defaultMaxInactiveInterval != null) {
|
||||
redisSession.setMaxInactiveInterval(defaultMaxInactiveInterval);
|
||||
}
|
||||
return redisSession;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the Hash key for this session by prefixing it appropriately.
|
||||
*
|
||||
* @param sessionId the session id
|
||||
* @return the Hash key for this session by prefixing it appropriately.
|
||||
*/
|
||||
private String getKey(String sessionId) {
|
||||
return BOUNDED_HASH_KEY_PREFIX + sessionId;
|
||||
}
|
||||
/**
|
||||
* Gets the Hash key for this session by prefixing it appropriately.
|
||||
*
|
||||
* @param sessionId the session id
|
||||
* @return the Hash key for this session by prefixing it appropriately.
|
||||
*/
|
||||
static String getKey(String sessionId) {
|
||||
return BOUNDED_HASH_KEY_PREFIX + sessionId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the {@link BoundHashOperations} to operate on a {@link Session}
|
||||
* @param sessionId the id of the {@link Session} to work with
|
||||
* @return the {@link BoundHashOperations} to operate on a {@link Session}
|
||||
*/
|
||||
private BoundHashOperations<String, Object, Object> getSessionBoundHashOperations(String sessionId) {
|
||||
String key = getKey(sessionId);
|
||||
return this.redisOperations.boundHashOps(key);
|
||||
}
|
||||
/**
|
||||
* Gets the key for the specified session attribute
|
||||
*
|
||||
* @param attributeName
|
||||
* @return
|
||||
*/
|
||||
static String getSessionAttrNameKey(String attributeName) {
|
||||
return SESSION_ATTR_PREFIX + attributeName;
|
||||
}
|
||||
|
||||
/**
|
||||
* A custom implementation of {@link Session} that uses a {@link MapSession} as the basis for its mapping. It keeps
|
||||
* track of any attributes that have changed. When
|
||||
* {@link org.springframework.session.data.redis.RedisOperationsSessionRepository.RedisSession#saveDelta()} is invoked
|
||||
* all the attributes that have been changed will be persisted.
|
||||
*
|
||||
* @since 1.0
|
||||
* @author Rob Winch
|
||||
*/
|
||||
class RedisSession implements Session {
|
||||
private final MapSession cached;
|
||||
private Map<String, Object> delta = new HashMap<String,Object>();
|
||||
/**
|
||||
* Gets the {@link BoundHashOperations} to operate on a {@link Session}
|
||||
* @param sessionId the id of the {@link Session} to work with
|
||||
* @return the {@link BoundHashOperations} to operate on a {@link Session}
|
||||
*/
|
||||
private BoundHashOperations<String, Object, Object> getSessionBoundHashOperations(String sessionId) {
|
||||
String key = getKey(sessionId);
|
||||
return this.redisOperations.boundHashOps(key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new instance ensuring to mark all of the new attributes to be persisted in the next save operation.
|
||||
*/
|
||||
private RedisSession() {
|
||||
this(new MapSession());
|
||||
delta.put(CREATION_TIME_ATTR, getCreationTime());
|
||||
delta.put(MAX_INACTIVE_ATTR, getMaxInactiveInterval());
|
||||
delta.put(LAST_ACCESSED_ATTR, getLastAccessedTime());
|
||||
}
|
||||
/**
|
||||
* A custom implementation of {@link Session} that uses a {@link MapSession} as the basis for its mapping. It keeps
|
||||
* track of any attributes that have changed. When
|
||||
* {@link org.springframework.session.data.redis.RedisOperationsSessionRepository.RedisSession#saveDelta()} is invoked
|
||||
* all the attributes that have been changed will be persisted.
|
||||
*
|
||||
* @since 1.0
|
||||
* @author Rob Winch
|
||||
*/
|
||||
class RedisSession implements Session {
|
||||
private final MapSession cached;
|
||||
private Map<String, Object> delta = new HashMap<String,Object>();
|
||||
|
||||
/**
|
||||
* Creates a new instance from the provided {@link MapSession}
|
||||
*
|
||||
* @param cached the {@MapSession} that represents the persisted session that was retrieved. Cannot be null.
|
||||
*/
|
||||
private RedisSession(MapSession cached) {
|
||||
Assert.notNull("MapSession cannot be null");
|
||||
this.cached = cached;
|
||||
}
|
||||
/**
|
||||
* Creates a new instance ensuring to mark all of the new attributes to be persisted in the next save operation.
|
||||
*/
|
||||
RedisSession() {
|
||||
this(new MapSession());
|
||||
delta.put(CREATION_TIME_ATTR, getCreationTime());
|
||||
delta.put(MAX_INACTIVE_ATTR, getMaxInactiveInterval());
|
||||
delta.put(LAST_ACCESSED_ATTR, getLastAccessedTime());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setLastAccessedTime(long lastAccessedTime) {
|
||||
cached.setLastAccessedTime(lastAccessedTime);
|
||||
delta.put(LAST_ACCESSED_ATTR, getLastAccessedTime());
|
||||
}
|
||||
/**
|
||||
* Creates a new instance from the provided {@link MapSession}
|
||||
*
|
||||
* @param cached the {@MapSession} that represents the persisted session that was retrieved. Cannot be null.
|
||||
*/
|
||||
RedisSession(MapSession cached) {
|
||||
Assert.notNull("MapSession cannot be null");
|
||||
this.cached = cached;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getCreationTime() {
|
||||
return cached.getCreationTime();
|
||||
}
|
||||
@Override
|
||||
public void setLastAccessedTime(long lastAccessedTime) {
|
||||
cached.setLastAccessedTime(lastAccessedTime);
|
||||
delta.put(LAST_ACCESSED_ATTR, getLastAccessedTime());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getId() {
|
||||
return cached.getId();
|
||||
}
|
||||
@Override
|
||||
public long getCreationTime() {
|
||||
return cached.getCreationTime();
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getLastAccessedTime() {
|
||||
return cached.getLastAccessedTime();
|
||||
}
|
||||
@Override
|
||||
public String getId() {
|
||||
return cached.getId();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setMaxInactiveInterval(int interval) {
|
||||
cached.setMaxInactiveInterval(interval);
|
||||
delta.put(MAX_INACTIVE_ATTR, getMaxInactiveInterval());
|
||||
}
|
||||
@Override
|
||||
public long getLastAccessedTime() {
|
||||
return cached.getLastAccessedTime();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMaxInactiveInterval() {
|
||||
return cached.getMaxInactiveInterval();
|
||||
}
|
||||
@Override
|
||||
public void setMaxInactiveInterval(int interval) {
|
||||
cached.setMaxInactiveInterval(interval);
|
||||
delta.put(MAX_INACTIVE_ATTR, getMaxInactiveInterval());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getAttribute(String attributeName) {
|
||||
return cached.getAttribute(attributeName);
|
||||
}
|
||||
@Override
|
||||
public int getMaxInactiveInterval() {
|
||||
return cached.getMaxInactiveInterval();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<String> getAttributeNames() {
|
||||
return cached.getAttributeNames();
|
||||
}
|
||||
@Override
|
||||
public Object getAttribute(String attributeName) {
|
||||
return cached.getAttribute(attributeName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setAttribute(String attributeName, Object attributeValue) {
|
||||
cached.setAttribute(attributeName, attributeValue);
|
||||
delta.put(SESSION_ATTR_PREFIX + attributeName, attributeValue);
|
||||
}
|
||||
@Override
|
||||
public Set<String> getAttributeNames() {
|
||||
return cached.getAttributeNames();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeAttribute(String attributeName) {
|
||||
cached.removeAttribute(attributeName);
|
||||
delta.put(SESSION_ATTR_PREFIX + attributeName, null);
|
||||
}
|
||||
@Override
|
||||
public void setAttribute(String attributeName, Object attributeValue) {
|
||||
cached.setAttribute(attributeName, attributeValue);
|
||||
delta.put(getSessionAttrNameKey(attributeName), attributeValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* Saves any attributes that have been changed and updates the expiration of this session.
|
||||
*/
|
||||
private void saveDelta() {
|
||||
getSessionBoundHashOperations(getId()).putAll(delta);
|
||||
getSessionBoundHashOperations(getId()).expire(getMaxInactiveInterval(), TimeUnit.SECONDS);
|
||||
delta.clear();
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public void removeAttribute(String attributeName) {
|
||||
cached.removeAttribute(attributeName);
|
||||
delta.put(getSessionAttrNameKey(attributeName), null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Saves any attributes that have been changed and updates the expiration of this session.
|
||||
*/
|
||||
private void saveDelta() {
|
||||
getSessionBoundHashOperations(getId()).putAll(delta);
|
||||
getSessionBoundHashOperations(getId()).expire(getMaxInactiveInterval(), TimeUnit.SECONDS);
|
||||
delta = new HashMap<String,Object>(delta.size());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,39 +1,170 @@
|
||||
package org.springframework.session.data.redis;
|
||||
|
||||
import static org.fest.assertions.Assertions.*;
|
||||
import static org.fest.assertions.Assertions.assertThat;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
import static org.springframework.session.data.redis.RedisOperationsSessionRepository.*;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import org.mockito.Captor;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.runners.MockitoJUnitRunner;
|
||||
import org.springframework.data.redis.core.BoundHashOperations;
|
||||
import org.springframework.data.redis.core.RedisOperations;
|
||||
import org.springframework.session.MapSession;
|
||||
import org.springframework.session.Session;
|
||||
import org.springframework.session.data.redis.RedisOperationsSessionRepository.RedisSession;
|
||||
|
||||
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
public class RedisOperationsSessionRepositoryTests {
|
||||
@Mock
|
||||
RedisOperations redisOperations;
|
||||
@Mock
|
||||
RedisOperations<String,Session> redisOperations;
|
||||
@Mock
|
||||
BoundHashOperations<String, Object, Object> boundHashOperations;
|
||||
@Captor
|
||||
ArgumentCaptor<Map<String,Object>> delta;
|
||||
|
||||
private RedisOperationsSessionRepository redisRepository;
|
||||
private RedisOperationsSessionRepository redisRepository;
|
||||
|
||||
@Before
|
||||
public void setup() {
|
||||
this.redisRepository = new RedisOperationsSessionRepository(redisOperations);
|
||||
}
|
||||
@Before
|
||||
public void setup() {
|
||||
this.redisRepository = new RedisOperationsSessionRepository(redisOperations);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void createSessionDefaultMaxInactiveInterval() throws Exception {
|
||||
Session session = redisRepository.createSession();
|
||||
assertThat(session.getMaxInactiveInterval()).isEqualTo(new MapSession().getMaxInactiveInterval());
|
||||
}
|
||||
@Test
|
||||
public void createSessionDefaultMaxInactiveInterval() throws Exception {
|
||||
Session session = redisRepository.createSession();
|
||||
assertThat(session.getMaxInactiveInterval()).isEqualTo(new MapSession().getMaxInactiveInterval());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void createSessionCustomMaxInactiveInterval() throws Exception {
|
||||
int interval = 1;
|
||||
redisRepository.setDefaultMaxInactiveInterval(interval);
|
||||
Session session = redisRepository.createSession();
|
||||
assertThat(session.getMaxInactiveInterval()).isEqualTo(interval);
|
||||
}
|
||||
@Test
|
||||
public void createSessionCustomMaxInactiveInterval() throws Exception {
|
||||
int interval = 1;
|
||||
redisRepository.setDefaultMaxInactiveInterval(interval);
|
||||
Session session = redisRepository.createSession();
|
||||
assertThat(session.getMaxInactiveInterval()).isEqualTo(interval);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void saveNewSession() {
|
||||
RedisSession session = redisRepository.createSession();
|
||||
when(redisOperations.boundHashOps(getKey(session.getId()))).thenReturn(boundHashOperations);
|
||||
|
||||
redisRepository.save(session);
|
||||
|
||||
Map<String,Object> delta = getDelta();
|
||||
assertThat(delta.size()).isEqualTo(3);
|
||||
Object creationTime = delta.get(CREATION_TIME_ATTR);
|
||||
assertThat(creationTime).isInstanceOf(Long.class);
|
||||
assertThat(delta.get(MAX_INACTIVE_ATTR)).isEqualTo(MapSession.DEFAULT_MAX_INACTIVE_INTERVAL_SECONDS);
|
||||
assertThat(delta.get(LAST_ACCESSED_ATTR)).isEqualTo(creationTime);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void saveLastAccessChanged() {
|
||||
RedisSession session = redisRepository.new RedisSession(new MapSession());
|
||||
session.setLastAccessedTime(12345678L);
|
||||
when(redisOperations.boundHashOps(getKey(session.getId()))).thenReturn(boundHashOperations);
|
||||
|
||||
redisRepository.save(session);
|
||||
|
||||
assertThat(getDelta()).isEqualTo(map(LAST_ACCESSED_ATTR, session.getLastAccessedTime()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void saveSetAttribute() {
|
||||
String attrName = "attrName";
|
||||
RedisSession session = redisRepository.new RedisSession(new MapSession());
|
||||
session.setAttribute(attrName, "attrValue");
|
||||
when(redisOperations.boundHashOps(getKey(session.getId()))).thenReturn(boundHashOperations);
|
||||
|
||||
redisRepository.save(session);
|
||||
|
||||
assertThat(getDelta()).isEqualTo(map(getSessionAttrNameKey(attrName), session.getAttribute(attrName)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void saveRemoveAttribute() {
|
||||
String attrName = "attrName";
|
||||
RedisSession session = redisRepository.new RedisSession(new MapSession());
|
||||
session.removeAttribute(attrName);
|
||||
when(redisOperations.boundHashOps(getKey(session.getId()))).thenReturn(boundHashOperations);
|
||||
|
||||
redisRepository.save(session);
|
||||
|
||||
assertThat(getDelta()).isEqualTo(map(getSessionAttrNameKey(attrName), null));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void redisSessionGetAttributes() {
|
||||
String attrName = "attrName";
|
||||
RedisSession session = redisRepository.new RedisSession(new MapSession());
|
||||
assertThat(session.getAttributeNames()).isEmpty();
|
||||
session.setAttribute(attrName, "attrValue");
|
||||
assertThat(session.getAttributeNames()).containsOnly(attrName);
|
||||
session.removeAttribute(attrName);
|
||||
assertThat(session.getAttributeNames()).isEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void delete() {
|
||||
String id = "abc";
|
||||
redisRepository.delete(id);
|
||||
verify(redisOperations).delete(getKey(id));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getSessionNotFound() {
|
||||
String id = "abc";
|
||||
when(redisOperations.boundHashOps(getKey(id))).thenReturn(boundHashOperations);
|
||||
when(boundHashOperations.entries()).thenReturn(map());
|
||||
|
||||
assertThat(redisRepository.getSession(id)).isNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getSessionFound() {
|
||||
String attrName = "attrName";
|
||||
MapSession expected = new MapSession();
|
||||
expected.setAttribute(attrName, "attrValue");
|
||||
when(redisOperations.boundHashOps(getKey(expected.getId()))).thenReturn(boundHashOperations);
|
||||
Map map = map(
|
||||
getSessionAttrNameKey(attrName), expected.getAttribute(attrName),
|
||||
CREATION_TIME_ATTR, expected.getCreationTime(),
|
||||
MAX_INACTIVE_ATTR, expected.getMaxInactiveInterval(),
|
||||
LAST_ACCESSED_ATTR, expected.getLastAccessedTime());
|
||||
when(boundHashOperations.entries()).thenReturn(map);
|
||||
|
||||
RedisSession session = redisRepository.getSession(expected.getId());
|
||||
assertThat(session.getId()).isEqualTo(expected.getId());
|
||||
assertThat(session.getAttributeNames()).isEqualTo(expected.getAttributeNames());
|
||||
assertThat(session.getAttribute(attrName)).isEqualTo(expected.getAttribute(attrName));
|
||||
assertThat(session.getCreationTime()).isEqualTo(expected.getCreationTime());
|
||||
assertThat(session.getMaxInactiveInterval()).isEqualTo(expected.getMaxInactiveInterval());
|
||||
assertThat(session.getLastAccessedTime()).isEqualTo(expected.getLastAccessedTime());
|
||||
|
||||
}
|
||||
|
||||
private Map map(Object...objects) {
|
||||
Map<String,Object> result = new HashMap<String,Object>();
|
||||
if(objects == null) {
|
||||
return result;
|
||||
}
|
||||
for(int i = 0; i < objects.length; i += 2) {
|
||||
result.put((String)objects[i], objects[i+1]);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private Map<String,Object> getDelta() {
|
||||
verify(boundHashOperations).putAll(delta.capture());
|
||||
return delta.getValue();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,524 @@
|
||||
package org.springframework.session.web;
|
||||
|
||||
import java.io.PrintWriter;
|
||||
import java.util.Locale;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.runners.MockitoJUnitRunner;
|
||||
|
||||
import javax.servlet.ServletOutputStream;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import static org.fest.assertions.Assertions.assertThat;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
public class OnCommittedResponseWrapperTests {
|
||||
@Mock
|
||||
HttpServletResponse delegate;
|
||||
@Mock
|
||||
PrintWriter writer;
|
||||
@Mock
|
||||
ServletOutputStream out;
|
||||
|
||||
HttpServletResponse response;
|
||||
|
||||
boolean committed;
|
||||
|
||||
@Before
|
||||
public void setup() throws Exception {
|
||||
response = new OnCommittedResponseWrapper(delegate) {
|
||||
@Override
|
||||
protected void onResponseCommitted() {
|
||||
committed = true;
|
||||
}
|
||||
};
|
||||
when(delegate.getWriter()).thenReturn(writer);
|
||||
when(delegate.getOutputStream()).thenReturn(out);
|
||||
}
|
||||
|
||||
|
||||
// --- printwriter
|
||||
|
||||
@Test
|
||||
public void printWriterHashCode() throws Exception {
|
||||
int expected = writer.hashCode();
|
||||
|
||||
assertThat(response.getWriter().hashCode()).isEqualTo(expected);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void printWriterCheckError() throws Exception {
|
||||
boolean expected = true;
|
||||
when(writer.checkError()).thenReturn(expected);
|
||||
|
||||
assertThat(response.getWriter().checkError()).isEqualTo(expected);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void printWriterWriteInt() throws Exception {
|
||||
int expected = 1;
|
||||
|
||||
response.getWriter().write(expected);
|
||||
|
||||
verify(writer).write(expected);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void printWriterWriteCharIntInt() throws Exception {
|
||||
char[] buff = new char[0];
|
||||
int off = 2;
|
||||
int len = 3;
|
||||
|
||||
response.getWriter().write(buff,off,len);
|
||||
|
||||
verify(writer).write(buff,off,len);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void printWriterWriteChar() throws Exception {
|
||||
char[] buff = new char[0];
|
||||
|
||||
response.getWriter().write(buff);
|
||||
|
||||
verify(writer).write(buff);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void printWriterWriteStringIntInt() throws Exception {
|
||||
String s = "";
|
||||
int off = 2;
|
||||
int len = 3;
|
||||
|
||||
response.getWriter().write(s,off,len);
|
||||
|
||||
verify(writer).write(s,off,len);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void printWriterWriteString() throws Exception {
|
||||
String s = "";
|
||||
|
||||
response.getWriter().write(s);
|
||||
|
||||
verify(writer).write(s);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void printWriterPrintBoolean() throws Exception {
|
||||
boolean b = true;
|
||||
|
||||
response.getWriter().print(b);
|
||||
|
||||
verify(writer).print(b);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void printWriterPrintChar() throws Exception {
|
||||
char c = 1;
|
||||
|
||||
response.getWriter().print(c);
|
||||
|
||||
verify(writer).print(c);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void printWriterPrintInt() throws Exception {
|
||||
int i = 1;
|
||||
|
||||
response.getWriter().print(i);
|
||||
|
||||
verify(writer).print(i);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void printWriterPrintLong() throws Exception {
|
||||
long l = 1;
|
||||
|
||||
response.getWriter().print(l);
|
||||
|
||||
verify(writer).print(l);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void printWriterPrintFloat() throws Exception {
|
||||
float f = 1;
|
||||
|
||||
response.getWriter().print(f);
|
||||
|
||||
verify(writer).print(f);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void printWriterPrintDouble() throws Exception {
|
||||
double x = 1;
|
||||
|
||||
response.getWriter().print(x);
|
||||
|
||||
verify(writer).print(x);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void printWriterPrintCharArray() throws Exception {
|
||||
char[] x = new char[0];
|
||||
|
||||
response.getWriter().print(x);
|
||||
|
||||
verify(writer).print(x);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void printWriterPrintString() throws Exception {
|
||||
String x = "1";
|
||||
|
||||
response.getWriter().print(x);
|
||||
|
||||
verify(writer).print(x);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void printWriterPrintObject() throws Exception {
|
||||
Object x = "1";
|
||||
|
||||
response.getWriter().print(x);
|
||||
|
||||
verify(writer).print(x);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void printWriterPrintln() throws Exception {
|
||||
response.getWriter().println();
|
||||
|
||||
verify(writer).println();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void printWriterPrintlnBoolean() throws Exception {
|
||||
boolean b = true;
|
||||
|
||||
response.getWriter().println(b);
|
||||
|
||||
verify(writer).println(b);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void printWriterPrintlnChar() throws Exception {
|
||||
char c = 1;
|
||||
|
||||
response.getWriter().println(c);
|
||||
|
||||
verify(writer).println(c);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void printWriterPrintlnInt() throws Exception {
|
||||
int i = 1;
|
||||
|
||||
response.getWriter().println(i);
|
||||
|
||||
verify(writer).println(i);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void printWriterPrintlnLong() throws Exception {
|
||||
long l = 1;
|
||||
|
||||
response.getWriter().println(l);
|
||||
|
||||
verify(writer).println(l);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void printWriterPrintlnFloat() throws Exception {
|
||||
float f = 1;
|
||||
|
||||
response.getWriter().println(f);
|
||||
|
||||
verify(writer).println(f);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void printWriterPrintlnDouble() throws Exception {
|
||||
double x = 1;
|
||||
|
||||
response.getWriter().println(x);
|
||||
|
||||
verify(writer).println(x);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void printWriterPrintlnCharArray() throws Exception {
|
||||
char[] x = new char[0];
|
||||
|
||||
response.getWriter().println(x);
|
||||
|
||||
verify(writer).println(x);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void printWriterPrintlnString() throws Exception {
|
||||
String x = "1";
|
||||
|
||||
response.getWriter().println(x);
|
||||
|
||||
verify(writer).println(x);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void printWriterPrintlnObject() throws Exception {
|
||||
Object x = "1";
|
||||
|
||||
response.getWriter().println(x);
|
||||
|
||||
verify(writer).println(x);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void printWriterPrintfStringObjectVargs() throws Exception {
|
||||
String format = "format";
|
||||
Object[] args = new Object[] { "1" };
|
||||
|
||||
response.getWriter().printf(format, args);
|
||||
|
||||
verify(writer).printf(format, args);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void printWriterPrintfLocaleStringObjectVargs() throws Exception {
|
||||
Locale l = Locale.US;
|
||||
String format = "format";
|
||||
Object[] args = new Object[] { "1" };
|
||||
|
||||
response.getWriter().printf(l, format, args);
|
||||
|
||||
verify(writer).printf(l, format, args);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void printWriterFormatStringObjectVargs() throws Exception {
|
||||
String format = "format";
|
||||
Object[] args = new Object[] { "1" };
|
||||
|
||||
response.getWriter().format(format, args);
|
||||
|
||||
verify(writer).format(format, args);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void printWriterFormatLocaleStringObjectVargs() throws Exception {
|
||||
Locale l = Locale.US;
|
||||
String format = "format";
|
||||
Object[] args = new Object[] { "1" };
|
||||
|
||||
response.getWriter().format(l, format, args);
|
||||
|
||||
verify(writer).format(l, format, args);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void printWriterAppendCharSequence() throws Exception {
|
||||
String x = "a";
|
||||
|
||||
response.getWriter().append(x);
|
||||
|
||||
verify(writer).append(x);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void printWriterAppendCharSequenceIntInt() throws Exception {
|
||||
String x = "abcdef";
|
||||
int start = 1;
|
||||
int end = 3;
|
||||
|
||||
response.getWriter().append(x, start, end);
|
||||
|
||||
verify(writer).append(x, start, end);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void printWriterAppendChar() throws Exception {
|
||||
char x = 1;
|
||||
|
||||
response.getWriter().append(x);
|
||||
|
||||
verify(writer).append(x);
|
||||
}
|
||||
|
||||
// servletoutputstream
|
||||
|
||||
|
||||
@Test
|
||||
public void outputStreamHashCode() throws Exception {
|
||||
int expected = out.hashCode();
|
||||
|
||||
assertThat(response.getOutputStream().hashCode()).isEqualTo(expected);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void outputStreamWriteInt() throws Exception {
|
||||
int expected = 1;
|
||||
|
||||
response.getOutputStream().write(expected);
|
||||
|
||||
verify(out).write(expected);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void outputStreamWriteByte() throws Exception {
|
||||
byte[] expected = new byte[0];
|
||||
|
||||
response.getOutputStream().write(expected);
|
||||
|
||||
verify(out).write(expected);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void outputStreamWriteByteIntInt() throws Exception {
|
||||
int start = 1;
|
||||
int end = 2;
|
||||
byte[] expected = new byte[0];
|
||||
|
||||
response.getOutputStream().write(expected, start, end);
|
||||
|
||||
verify(out).write(expected, start, end);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void outputStreamPrintBoolean() throws Exception {
|
||||
boolean b = true;
|
||||
|
||||
response.getOutputStream().print(b);
|
||||
|
||||
verify(out).print(b);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void outputStreamPrintChar() throws Exception {
|
||||
char c = 1;
|
||||
|
||||
response.getOutputStream().print(c);
|
||||
|
||||
verify(out).print(c);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void outputStreamPrintInt() throws Exception {
|
||||
int i = 1;
|
||||
|
||||
response.getOutputStream().print(i);
|
||||
|
||||
verify(out).print(i);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void outputStreamPrintLong() throws Exception {
|
||||
long l = 1;
|
||||
|
||||
response.getOutputStream().print(l);
|
||||
|
||||
verify(out).print(l);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void outputStreamPrintFloat() throws Exception {
|
||||
float f = 1;
|
||||
|
||||
response.getOutputStream().print(f);
|
||||
|
||||
verify(out).print(f);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void outputStreamPrintDouble() throws Exception {
|
||||
double x = 1;
|
||||
|
||||
response.getOutputStream().print(x);
|
||||
|
||||
verify(out).print(x);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void outputStreamPrintString() throws Exception {
|
||||
String x = "1";
|
||||
|
||||
response.getOutputStream().print(x);
|
||||
|
||||
verify(out).print(x);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void outputStreamPrintln() throws Exception {
|
||||
response.getOutputStream().println();
|
||||
|
||||
verify(out).println();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void outputStreamPrintlnBoolean() throws Exception {
|
||||
boolean b = true;
|
||||
|
||||
response.getOutputStream().println(b);
|
||||
|
||||
verify(out).println(b);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void outputStreamPrintlnChar() throws Exception {
|
||||
char c = 1;
|
||||
|
||||
response.getOutputStream().println(c);
|
||||
|
||||
verify(out).println(c);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void outputStreamPrintlnInt() throws Exception {
|
||||
int i = 1;
|
||||
|
||||
response.getOutputStream().println(i);
|
||||
|
||||
verify(out).println(i);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void outputStreamPrintlnLong() throws Exception {
|
||||
long l = 1;
|
||||
|
||||
response.getOutputStream().println(l);
|
||||
|
||||
verify(out).println(l);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void outputStreamPrintlnFloat() throws Exception {
|
||||
float f = 1;
|
||||
|
||||
response.getOutputStream().println(f);
|
||||
|
||||
verify(out).println(f);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void outputStreamPrintlnDouble() throws Exception {
|
||||
double x = 1;
|
||||
|
||||
response.getOutputStream().println(x);
|
||||
|
||||
verify(out).println(x);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void outputStreamPrintlnString() throws Exception {
|
||||
String x = "1";
|
||||
|
||||
response.getOutputStream().println(x);
|
||||
|
||||
verify(out).println(x);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user