Skip to content

Commit 9449951

Browse files
server/item: Add various tests
1 parent 5a201c6 commit 9449951

1 file changed

Lines changed: 274 additions & 0 deletions

File tree

server/src/item.rs

Lines changed: 274 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -213,3 +213,277 @@ impl Item {
213213
Ok(())
214214
}
215215
}
216+
217+
#[cfg(test)]
218+
mod tests {
219+
use std::sync::Arc;
220+
221+
use oo7::dbus;
222+
223+
use super::*;
224+
225+
/// Helper to create a peer-to-peer connection pair using Unix socket
226+
async fn create_p2p_connection() -> (zbus::Connection, zbus::Connection) {
227+
let guid = zbus::Guid::generate();
228+
let (p0, p1) = tokio::net::UnixStream::pair().unwrap();
229+
230+
let (client_conn, server_conn) = tokio::try_join!(
231+
zbus::connection::Builder::unix_stream(p0).p2p().build(),
232+
zbus::connection::Builder::unix_stream(p1)
233+
.server(guid)
234+
.unwrap()
235+
.p2p()
236+
.build(),
237+
)
238+
.unwrap();
239+
240+
(server_conn, client_conn)
241+
}
242+
243+
#[tokio::test]
244+
async fn label_property() {
245+
let (server_conn, client_conn) = create_p2p_connection().await;
246+
247+
let _server = Service::run_with_connection(
248+
server_conn,
249+
Some(oo7::Secret::from("test-password-long-enough")),
250+
)
251+
.await
252+
.unwrap();
253+
254+
tokio::time::sleep(tokio::time::Duration::from_millis(50)).await;
255+
256+
let service_api = dbus::api::Service::new(&client_conn).await.unwrap();
257+
let (_aes_key, session) = service_api.open_session(None).await.unwrap();
258+
let session = Arc::new(session);
259+
260+
let collections = service_api.collections().await.unwrap();
261+
let secret = oo7::Secret::text("test-secret");
262+
let attributes = &[("app", "test")];
263+
let dbus_secret = dbus::api::DBusSecret::new(session, secret);
264+
265+
let item = collections[0]
266+
.create_item("Original Label", attributes, &dbus_secret, false, None)
267+
.await
268+
.unwrap();
269+
270+
// Get label
271+
let label = item.label().await.unwrap();
272+
assert_eq!(label, "Original Label");
273+
274+
// Set label
275+
item.set_label("New Label").await.unwrap();
276+
277+
// Verify new label
278+
let label = item.label().await.unwrap();
279+
assert_eq!(label, "New Label");
280+
}
281+
282+
#[tokio::test]
283+
async fn attributes_property() {
284+
let (server_conn, client_conn) = create_p2p_connection().await;
285+
286+
let _server = Service::run_with_connection(
287+
server_conn,
288+
Some(oo7::Secret::from("test-password-long-enough")),
289+
)
290+
.await
291+
.unwrap();
292+
293+
tokio::time::sleep(tokio::time::Duration::from_millis(50)).await;
294+
295+
let service_api = dbus::api::Service::new(&client_conn).await.unwrap();
296+
let (_aes_key, session) = service_api.open_session(None).await.unwrap();
297+
let session = Arc::new(session);
298+
299+
let collections = service_api.collections().await.unwrap();
300+
let secret = oo7::Secret::text("test-secret");
301+
let attributes = &[("app", "firefox"), ("username", "user@example.com")];
302+
let dbus_secret = dbus::api::DBusSecret::new(session, secret);
303+
304+
let item = collections[0]
305+
.create_item("Test Item", attributes, &dbus_secret, false, None)
306+
.await
307+
.unwrap();
308+
309+
// Get attributes
310+
let attrs = item.attributes().await.unwrap();
311+
assert_eq!(attrs.get("app").unwrap(), "firefox");
312+
assert_eq!(attrs.get("username").unwrap(), "user@example.com");
313+
314+
// Set new attributes
315+
item.set_attributes(&[("app", "chrome"), ("username", "newuser@example.com")])
316+
.await
317+
.unwrap();
318+
319+
// Verify new attributes
320+
let attrs = item.attributes().await.unwrap();
321+
assert_eq!(attrs.get("app").unwrap(), "chrome");
322+
assert_eq!(attrs.get("username").unwrap(), "newuser@example.com");
323+
}
324+
325+
#[tokio::test]
326+
async fn timestamps() {
327+
let (server_conn, client_conn) = create_p2p_connection().await;
328+
329+
let _server = Service::run_with_connection(
330+
server_conn,
331+
Some(oo7::Secret::from("test-password-long-enough")),
332+
)
333+
.await
334+
.unwrap();
335+
336+
tokio::time::sleep(tokio::time::Duration::from_millis(50)).await;
337+
338+
let service_api = dbus::api::Service::new(&client_conn).await.unwrap();
339+
let (_aes_key, session) = service_api.open_session(None).await.unwrap();
340+
let session = Arc::new(session);
341+
342+
let collections = service_api.collections().await.unwrap();
343+
let secret = oo7::Secret::text("test-secret");
344+
let attributes = &[("app", "test")];
345+
let dbus_secret = dbus::api::DBusSecret::new(session, secret);
346+
347+
let item = collections[0]
348+
.create_item("Test Item", attributes, &dbus_secret, false, None)
349+
.await
350+
.unwrap();
351+
352+
// Get created timestamp
353+
let created = item.created().await.unwrap();
354+
assert!(created.as_secs() > 0, "Created timestamp should be set");
355+
356+
// Get modified timestamp
357+
let modified = item.modified().await.unwrap();
358+
assert!(modified.as_secs() > 0, "Modified timestamp should be set");
359+
360+
// Created and modified should be close (within a second for new item)
361+
let diff = if created > modified {
362+
created.as_secs() - modified.as_secs()
363+
} else {
364+
modified.as_secs() - created.as_secs()
365+
};
366+
assert!(diff <= 1, "Created and modified should be within 1 second");
367+
}
368+
369+
#[tokio::test]
370+
async fn secret_retrieval_plain() {
371+
let (server_conn, client_conn) = create_p2p_connection().await;
372+
373+
let _server = Service::run_with_connection(
374+
server_conn,
375+
Some(oo7::Secret::from("test-password-long-enough")),
376+
)
377+
.await
378+
.unwrap();
379+
380+
tokio::time::sleep(tokio::time::Duration::from_millis(50)).await;
381+
382+
let service_api = dbus::api::Service::new(&client_conn).await.unwrap();
383+
let (_aes_key, session) = service_api.open_session(None).await.unwrap();
384+
let session = Arc::new(session);
385+
386+
let collections = service_api.collections().await.unwrap();
387+
let secret = oo7::Secret::text("my-secret-password");
388+
let attributes = &[("app", "test")];
389+
let dbus_secret = dbus::api::DBusSecret::new(Arc::clone(&session), secret.clone());
390+
391+
let item = collections[0]
392+
.create_item("Test Item", attributes, &dbus_secret, false, None)
393+
.await
394+
.unwrap();
395+
396+
// Retrieve secret
397+
let retrieved_secret = item.secret(&session).await.unwrap();
398+
assert_eq!(retrieved_secret.value(), secret.as_bytes());
399+
}
400+
401+
#[tokio::test]
402+
async fn secret_retrieval_encrypted() {
403+
let (server_conn, client_conn) = create_p2p_connection().await;
404+
405+
let _server = Service::run_with_connection(
406+
server_conn,
407+
Some(oo7::Secret::from("test-password-long-enough")),
408+
)
409+
.await
410+
.unwrap();
411+
412+
tokio::time::sleep(tokio::time::Duration::from_millis(50)).await;
413+
414+
let service_api = dbus::api::Service::new(&client_conn).await.unwrap();
415+
416+
// Open encrypted session
417+
let client_private_key = oo7::Key::generate_private_key().unwrap();
418+
let client_public_key = oo7::Key::generate_public_key(&client_private_key).unwrap();
419+
420+
let (server_public_key_opt, session) = service_api
421+
.open_session(Some(client_public_key))
422+
.await
423+
.unwrap();
424+
425+
let server_public_key = server_public_key_opt.unwrap();
426+
let aes_key = oo7::Key::generate_aes_key(&client_private_key, &server_public_key).unwrap();
427+
let session = Arc::new(session);
428+
429+
let collections = service_api.collections().await.unwrap();
430+
let secret = oo7::Secret::text("my-encrypted-secret");
431+
let attributes = &[("app", "test")];
432+
let dbus_secret =
433+
dbus::api::DBusSecret::new_encrypted(Arc::clone(&session), secret.clone(), &aes_key)
434+
.unwrap();
435+
436+
let item = collections[0]
437+
.create_item("Test Item", attributes, &dbus_secret, false, None)
438+
.await
439+
.unwrap();
440+
441+
// Retrieve secret
442+
let retrieved_secret = item.secret(&session).await.unwrap();
443+
assert_eq!(
444+
retrieved_secret
445+
.decrypt(Some(&Arc::new(client_private_key)))
446+
.unwrap(),
447+
secret
448+
);
449+
}
450+
451+
#[tokio::test]
452+
async fn delete_item() {
453+
let (server_conn, client_conn) = create_p2p_connection().await;
454+
455+
let _server = Service::run_with_connection(
456+
server_conn,
457+
Some(oo7::Secret::from("test-password-long-enough")),
458+
)
459+
.await
460+
.unwrap();
461+
462+
tokio::time::sleep(tokio::time::Duration::from_millis(50)).await;
463+
464+
let service_api = dbus::api::Service::new(&client_conn).await.unwrap();
465+
let (_aes_key, session) = service_api.open_session(None).await.unwrap();
466+
let session = Arc::new(session);
467+
468+
let collections = service_api.collections().await.unwrap();
469+
let secret = oo7::Secret::text("test-secret");
470+
let attributes = &[("app", "test")];
471+
let dbus_secret = dbus::api::DBusSecret::new(session, secret);
472+
473+
let item = collections[0]
474+
.create_item("Test Item", attributes, &dbus_secret, false, None)
475+
.await
476+
.unwrap();
477+
478+
// Verify item exists
479+
let items = collections[0].items().await.unwrap();
480+
assert_eq!(items.len(), 1);
481+
482+
// Delete item
483+
item.delete(None).await.unwrap();
484+
485+
// Verify item is deleted
486+
let items = collections[0].items().await.unwrap();
487+
assert_eq!(items.len(), 0, "Item should be deleted from collection");
488+
}
489+
}

0 commit comments

Comments
 (0)