Skip to content

Commit 0ef0788

Browse files
committed
add some tests
1 parent 1ead950 commit 0ef0788

File tree

1 file changed

+211
-3
lines changed

1 file changed

+211
-3
lines changed

src/lib.rs

Lines changed: 211 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,29 @@ impl RedisSessionStore {
7777
self
7878
}
7979

80+
async fn ids(&self) -> Result<Vec<String>> {
81+
Ok(self.connection().await?.keys(self.prefix_key("*")).await?)
82+
}
83+
84+
/// returns the number of sessions in this store
85+
pub async fn count(&self) -> Result<usize> {
86+
if self.prefix.is_none() {
87+
let mut connection = self.connection().await?;
88+
Ok(redis::cmd("DBSIZE").query_async(&mut connection).await?)
89+
} else {
90+
Ok(self.ids().await?.len())
91+
}
92+
}
93+
94+
#[cfg(test)]
95+
async fn ttl_for_session(&self, session: &Session) -> Result<usize> {
96+
Ok(self
97+
.connection()
98+
.await?
99+
.ttl(self.prefix_key(session.id()))
100+
.await?)
101+
}
102+
80103
fn prefix_key(&self, key: impl AsRef<str>) -> String {
81104
if let Some(ref prefix) = self.prefix {
82105
format!("{}{}", prefix, key.as_ref())
@@ -95,15 +118,15 @@ impl SessionStore for RedisSessionStore {
95118
async fn load_session(&self, cookie_value: String) -> Option<Session> {
96119
let id = Session::id_from_cookie_value(&cookie_value).ok()?;
97120
let mut connection = self.connection().await.ok()?;
98-
let record: Option<String> = connection.get(id).await.ok()?;
121+
let record: Option<String> = connection.get(self.prefix_key(id)).await.ok()?;
99122
match record {
100123
Some(value) => serde_json::from_str(&value).ok()?,
101124
None => None,
102125
}
103126
}
104127

105128
async fn store_session(&self, session: Session) -> Option<String> {
106-
let id = session.id();
129+
let id = self.prefix_key(session.id());
107130
let string = serde_json::to_string(&session).ok()?;
108131

109132
let mut connection = self.connection().await.ok()?;
@@ -128,7 +151,192 @@ impl SessionStore for RedisSessionStore {
128151
}
129152

130153
async fn clear_store(&self) -> Result {
131-
self.connection().await?.del(self.prefix_key("*")).await?;
154+
let mut connection = self.connection().await?;
155+
156+
if self.prefix.is_none() {
157+
let _: () = redis::cmd("FLUSHDB").query_async(&mut connection).await?;
158+
} else {
159+
let ids = self.ids().await?;
160+
if !ids.is_empty() {
161+
connection.del(ids).await?;
162+
}
163+
}
164+
Ok(())
165+
}
166+
}
167+
168+
#[cfg(test)]
169+
mod tests {
170+
use super::*;
171+
use async_std::task;
172+
use std::time::Duration;
173+
174+
async fn test_store() -> RedisSessionStore {
175+
let store = RedisSessionStore::new("redis://127.0.0.1").unwrap();
176+
store.clear_store().await.unwrap();
177+
store
178+
}
179+
180+
#[async_std::test]
181+
async fn creating_a_new_session_with_no_expiry() -> Result {
182+
let store = test_store().await;
183+
let session = Session::new();
184+
session.insert("key".into(), "value".into());
185+
let cloned = session.clone();
186+
let cookie_value = store.store_session(session).await.unwrap();
187+
188+
let loaded_session = store.load_session(cookie_value).await.unwrap();
189+
assert_eq!(cloned.id(), loaded_session.id());
190+
assert_eq!("value", loaded_session.get("key").unwrap());
191+
192+
assert!(!loaded_session.is_expired());
193+
Ok(())
194+
}
195+
196+
#[async_std::test]
197+
async fn updating_a_session() -> Result {
198+
let store = test_store().await;
199+
let session = Session::new();
200+
201+
session.insert("key".into(), "value".into());
202+
let cookie_value = store.store_session(session).await.unwrap();
203+
204+
let session = store.load_session(cookie_value.clone()).await.unwrap();
205+
session.insert("key".into(), "other value".into());
206+
assert_eq!(None, store.store_session(session).await);
207+
208+
let session = store.load_session(cookie_value.clone()).await.unwrap();
209+
assert_eq!(session.get("key").unwrap(), "other value");
210+
211+
assert_eq!(1, store.count().await.unwrap());
212+
Ok(())
213+
}
214+
215+
#[async_std::test]
216+
async fn updating_a_session_extending_expiry() -> Result {
217+
let store = test_store().await;
218+
let mut session = Session::new();
219+
session.expire_in(Duration::from_secs(5));
220+
let original_expires = session.expiry().unwrap().clone();
221+
let cookie_value = store.store_session(session).await.unwrap();
222+
223+
let mut session = store.load_session(cookie_value.clone()).await.unwrap();
224+
let ttl = store.ttl_for_session(&session).await?;
225+
assert!(ttl > 3 && ttl < 5);
226+
227+
assert_eq!(session.expiry().unwrap(), &original_expires);
228+
session.expire_in(Duration::from_secs(10));
229+
let new_expires = session.expiry().unwrap().clone();
230+
store.store_session(session).await;
231+
232+
let session = store.load_session(cookie_value.clone()).await.unwrap();
233+
let ttl = store.ttl_for_session(&session).await?;
234+
assert!(ttl > 8 && ttl < 10);
235+
assert_eq!(session.expiry().unwrap(), &new_expires);
236+
237+
assert_eq!(1, store.count().await.unwrap());
238+
239+
task::sleep(Duration::from_secs(10)).await;
240+
assert_eq!(0, store.count().await.unwrap());
241+
242+
Ok(())
243+
}
244+
245+
#[async_std::test]
246+
async fn creating_a_new_session_with_expiry() -> Result {
247+
let store = test_store().await;
248+
let mut session = Session::new();
249+
session.expire_in(Duration::from_secs(3));
250+
session.insert("key".into(), "value".into());
251+
let cloned = session.clone();
252+
253+
let cookie_value = store.store_session(session).await.unwrap();
254+
255+
assert!(store.ttl_for_session(&cloned).await? > 1);
256+
257+
let loaded_session = store.load_session(cookie_value.clone()).await.unwrap();
258+
assert_eq!(cloned.id(), loaded_session.id());
259+
assert_eq!("value", loaded_session.get("key").unwrap());
260+
261+
assert!(!loaded_session.is_expired());
262+
263+
task::sleep(Duration::from_secs(2)).await;
264+
assert_eq!(None, store.load_session(cookie_value).await);
265+
266+
Ok(())
267+
}
268+
269+
#[async_std::test]
270+
async fn destroying_a_single_session() -> Result {
271+
let store = test_store().await;
272+
for _ in 0..3i8 {
273+
store.store_session(Session::new()).await;
274+
}
275+
276+
let cookie = store.store_session(Session::new()).await.unwrap();
277+
assert_eq!(4, store.count().await?);
278+
let session = store.load_session(cookie.clone()).await.unwrap();
279+
store.destroy_session(session.clone()).await.unwrap();
280+
assert_eq!(None, store.load_session(cookie).await);
281+
assert_eq!(3, store.count().await?);
282+
283+
// attempting to destroy the session again is not an error
284+
assert!(store.destroy_session(session).await.is_ok());
285+
Ok(())
286+
}
287+
288+
#[async_std::test]
289+
async fn clearing_the_whole_store() -> Result {
290+
let store = test_store().await;
291+
for _ in 0..3i8 {
292+
store.store_session(Session::new()).await;
293+
}
294+
295+
assert_eq!(3, store.count().await?);
296+
store.clear_store().await.unwrap();
297+
assert_eq!(0, store.count().await?);
298+
299+
Ok(())
300+
}
301+
302+
#[async_std::test]
303+
async fn prefixes() -> Result {
304+
test_store().await; // clear the db
305+
306+
let store = RedisSessionStore::new("redis://127.0.0.1")?.with_prefix("sessions/");
307+
store.clear_store().await?;
308+
309+
for _ in 0..3i8 {
310+
store.store_session(Session::new()).await;
311+
}
312+
313+
let session = Session::new();
314+
315+
session.insert("key".into(), "value".into());
316+
let cookie_value = store.store_session(session).await.unwrap();
317+
318+
let session = store.load_session(cookie_value.clone()).await.unwrap();
319+
session.insert("key".into(), "other value".into());
320+
assert_eq!(None, store.store_session(session).await);
321+
322+
let session = store.load_session(cookie_value.clone()).await.unwrap();
323+
assert_eq!(session.get("key").unwrap(), "other value");
324+
325+
assert_eq!(4, store.count().await.unwrap());
326+
327+
let other_store =
328+
RedisSessionStore::new("redis://127.0.0.1")?.with_prefix("other-namespace/");
329+
330+
assert_eq!(0, other_store.count().await.unwrap());
331+
for _ in 0..3i8 {
332+
other_store.store_session(Session::new()).await;
333+
}
334+
335+
other_store.clear_store().await?;
336+
337+
assert_eq!(0, other_store.count().await?);
338+
assert_eq!(4, store.count().await?);
339+
132340
Ok(())
133341
}
134342
}

0 commit comments

Comments
 (0)