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

9
gpodder_test/Cargo.toml Normal file
View file

@ -0,0 +1,9 @@
[package]
name = "gpodder_test"
version.workspace = true
edition.workspace = true
[dependencies]
gpodder = { path = "../gpodder" }
chrono.workspace = true

119
gpodder_test/src/auth.rs Normal file
View file

@ -0,0 +1,119 @@
use chrono::{SubsecRound, TimeDelta};
use gpodder::{GpodderAuthStore, Session};
pub fn test_create_user(store: impl GpodderAuthStore) {
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));
}
pub fn test_remove_session(store: impl GpodderAuthStore) {
let users = super::create_test_users(&store);
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()
);
}
pub fn test_refresh_session(store: impl GpodderAuthStore) {
let users = super::create_test_users(&store);
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)
);
}
pub fn test_remove_old_sessions(store: impl GpodderAuthStore) {
let users = super::create_test_users(&store);
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(),
})
);
}

View file

@ -0,0 +1,35 @@
use gpodder::{DevicePatch, DeviceType, GpodderStore};
pub fn test_insert_devices(store: impl GpodderStore) {
let users = super::create_test_users(&store);
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]).unwrap();
assert_eq!(devices.len(), 1);
assert_eq!(devices[0].caption, "caption1");
assert_eq!(devices[0].r#type, DeviceType::Other);
}

17
gpodder_test/src/lib.rs Normal file
View file

@ -0,0 +1,17 @@
use gpodder::{GpodderAuthStore, User};
pub mod auth;
pub mod device;
fn create_test_users(store: &impl GpodderAuthStore) -> Vec<User> {
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());
}
users
}