refactor(test): move existing gpodder_sqlite tests into a separate crate

This refactor allows new implementations of the store contract to reuse
the same tests, ensuring all implementations support the same behavior.
This commit is contained in:
Jef Roosens 2026-05-06 20:38:04 +02:00
parent 8954104954
commit 8498fe9661
Signed by: Jef Roosens
GPG key ID: 21FD3D77D56BAF49
10 changed files with 89 additions and 89 deletions

View file

@ -27,3 +27,4 @@ features = [
[dev-dependencies]
criterion = "0.5.1"
gpodder_test = { path = "../gpodder_test" }

View file

@ -249,3 +249,32 @@ impl gpodder::GpodderAuthStore for SqliteRepository {
}
}
}
#[cfg(test)]
mod tests {
use crate::SqliteRepository;
#[test]
fn test_create_user() {
let store = SqliteRepository::in_memory().unwrap();
gpodder_test::auth::test_create_user(store);
}
#[test]
fn test_remove_session() {
let store = SqliteRepository::in_memory().unwrap();
gpodder_test::auth::test_remove_session(store);
}
#[test]
fn test_refresh_session() {
let store = SqliteRepository::in_memory().unwrap();
gpodder_test::auth::test_refresh_session(store);
}
#[test]
fn test_remove_old_sessions() {
let store = SqliteRepository::in_memory().unwrap();
gpodder_test::auth::test_remove_old_sessions(store);
}
}

View file

@ -297,3 +297,14 @@ impl gpodder::GpodderDeviceStore for SqliteRepository {
.map_err(AuthErr::from)
}
}
#[cfg(test)]
mod tests {
use crate::SqliteRepository;
#[test]
fn test_insert_devices() {
let store = SqliteRepository::in_memory().unwrap();
gpodder_test::device::test_insert_devices(store);
}
}

View file

@ -1,158 +0,0 @@
mod common;
use chrono::{SubsecRound, TimeDelta};
use gpodder::{GpodderAuthStore, Session};
use gpodder_sqlite::SqliteRepository;
#[test]
fn test_create_user() {
let store = SqliteRepository::in_memory().unwrap();
let user = store.get_user("test1");
assert!(user.is_ok());
assert_eq!(user.unwrap(), None);
let new_user = store.insert_user("test1", "dummyhash");
assert!(new_user.is_ok());
let new_user = new_user.unwrap();
assert_eq!(new_user.username, "test1");
assert_eq!(new_user.password_hash, "dummyhash");
let user = store.get_user("test1");
assert!(user.is_ok());
assert_eq!(user.unwrap(), Some(new_user));
}
#[test]
fn test_create_session() {
let (path, store, users) = common::setup();
let session = store.get_session(123).expect("operation shouldn't fail");
assert_eq!(session, None);
let new_session = Session {
id: 123,
user_agent: None,
last_seen: chrono::Utc::now().trunc_subsecs(0),
user: users[0].clone(),
};
store
.insert_session(&new_session)
.expect("insert session shouldn't fail");
let session = store.get_session(123).expect("operation shouldn't fail");
assert_eq!(session, Some(new_session));
common::teardown(path);
}
#[test]
fn test_remove_session() {
let (path, store, users) = common::setup();
let new_session = Session {
id: 123,
user_agent: None,
last_seen: chrono::Utc::now().trunc_subsecs(0),
user: users[0].clone(),
};
store
.insert_session(&new_session)
.expect("insert session shouldn't fail");
assert!(
store
.get_session(123)
.expect("get session shouldn't fail")
.is_some()
);
store.remove_session(123).expect("remove shouldn't fail");
assert!(
store
.get_session(123)
.expect("get session shouldn't fail")
.is_none()
);
common::teardown(path);
}
#[test]
fn test_refresh_session() {
let (path, store, users) = common::setup();
let mut new_session = Session {
id: 123,
user_agent: None,
last_seen: chrono::Utc::now().trunc_subsecs(0) - TimeDelta::seconds(10),
user: users[0].clone(),
};
store
.insert_session(&new_session)
.expect("insert session shouldn't fail");
store
.refresh_session(&new_session, chrono::Utc::now().trunc_subsecs(0))
.expect("refresh session shouldn't fail");
new_session.last_seen = chrono::Utc::now().trunc_subsecs(0);
assert_eq!(
store.get_session(123).expect("get session shouldn't fail"),
Some(new_session)
);
common::teardown(path);
}
#[test]
fn test_remove_old_sessions() {
let (path, store, users) = common::setup();
let now = chrono::Utc::now().trunc_subsecs(0);
let timestamps = [
now,
now - TimeDelta::seconds(1),
now - TimeDelta::seconds(2),
];
for (i, ts) in timestamps.into_iter().enumerate() {
store
.insert_session(&Session {
id: i as i64,
user_agent: None,
last_seen: ts,
user: users[0].clone(),
})
.expect("insert shouldn't fail");
}
assert_eq!(
store
.remove_old_sessions(now)
.expect("remove old sessions shouldn't fail"),
2
);
assert!(matches!(store.get_session(1), Ok(None)));
assert!(matches!(store.get_session(2), Ok(None)));
assert_eq!(
store.get_session(0).expect("get session shouldn't fail"),
Some(Session {
id: 0,
user_agent: None,
last_seen: now,
user: users[0].clone(),
})
);
common::teardown(path);
}

View file

@ -1,30 +0,0 @@
use gpodder::{GpodderAuthStore, User};
use gpodder_sqlite::SqliteRepository;
use rand::{Rng, distributions::Alphanumeric};
use std::path::PathBuf;
pub fn setup() -> (PathBuf, SqliteRepository, Vec<User>) {
let fname: String = rand::thread_rng()
.sample_iter(Alphanumeric)
.take(10)
.map(char::from)
.collect();
let path = std::env::temp_dir().join(fname);
let store = SqliteRepository::from_path(&path).unwrap();
let mut users = Vec::new();
for i in 0..4 {
let username = format!("test{}", i + 1);
let password_hash = format!("dummyhash{}", i + 1);
users.push(store.insert_user(&username, &password_hash).unwrap());
}
(path, store, users)
}
pub fn teardown(path: PathBuf) {
let _ = std::fs::remove_file(path);
}

View file

@ -1,43 +0,0 @@
mod common;
use gpodder::{DevicePatch, DeviceType, GpodderDeviceStore};
#[test]
fn test_insert_devices() {
let (path, store, users) = common::setup();
store.devices_for_user(&users[0]).unwrap();
store
.update_device_info(
&users[0],
"device1",
DevicePatch {
caption: Some("caption1".to_string()),
r#type: Some(DeviceType::Other),
},
)
.expect("update info shouldn't fail");
store
.update_device_info(
&users[1],
"device2",
DevicePatch {
caption: Some("caption2".to_string()),
r#type: Some(DeviceType::Laptop),
},
)
.expect("update info shouldn't fail");
let devices = store.devices_for_user(&users[0]);
assert!(matches!(devices, Ok(_)));
let devices = devices.unwrap();
assert_eq!(devices.len(), 1);
assert_eq!(devices[0].caption, "caption1");
assert_eq!(devices[0].r#type, DeviceType::Other);
common::teardown(path);
}